From f275f3287f644293d102c07be4306a6b81cf2642 Mon Sep 17 00:00:00 2001 From: Giovanni Sollazzo Date: Wed, 5 Jul 2023 09:36:35 +0200 Subject: [PATCH 001/268] New Adapter: AIDEM (#2824) Co-authored-by: AndreaC <67786179+darkstarac@users.noreply.github.com> Co-authored-by: Andrea Tumbarello Co-authored-by: darkstar --- adapters/aidem/aidem.go | 102 ++++++++++++ adapters/aidem/aidem_test.go | 30 ++++ .../aidemtest/exemplary/multi-format.json | 119 ++++++++++++++ .../exemplary/multi-imps-multi-bid.json | 154 ++++++++++++++++++ .../exemplary/multi-imps-single-bid.json | 131 +++++++++++++++ .../aidem/aidemtest/exemplary/no-bid.json | 58 +++++++ .../aidemtest/exemplary/optional-params.json | 60 +++++++ .../aidemtest/exemplary/simple-banner.json | 97 +++++++++++ .../aidemtest/exemplary/simple-video.json | 103 ++++++++++++ ...valid-req-400-status-code-bad-request.json | 97 +++++++++++ ...nvalid-res-200-status-code-empty-bids.json | 102 ++++++++++++ .../invalid-resp-multi-imp-type.json | 151 +++++++++++++++++ ...valid-req-200-bid-response-from-aidem.json | 141 ++++++++++++++++ .../valid-req-204-response-from-aidem.json | 66 ++++++++ adapters/aidem/params_test.go | 57 +++++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_aidem.go | 8 + static/bidder-info/aidem.yaml | 19 +++ static/bidder-params/aidem.json | 29 ++++ 20 files changed, 1528 insertions(+) create mode 100644 adapters/aidem/aidem.go create mode 100644 adapters/aidem/aidem_test.go create mode 100644 adapters/aidem/aidemtest/exemplary/multi-format.json create mode 100644 adapters/aidem/aidemtest/exemplary/multi-imps-multi-bid.json create mode 100644 adapters/aidem/aidemtest/exemplary/multi-imps-single-bid.json create mode 100644 adapters/aidem/aidemtest/exemplary/no-bid.json create mode 100644 adapters/aidem/aidemtest/exemplary/optional-params.json create mode 100644 adapters/aidem/aidemtest/exemplary/simple-banner.json create mode 100644 adapters/aidem/aidemtest/exemplary/simple-video.json create mode 100644 adapters/aidem/aidemtest/supplemental/invalid-req-400-status-code-bad-request.json create mode 100644 adapters/aidem/aidemtest/supplemental/invalid-res-200-status-code-empty-bids.json create mode 100644 adapters/aidem/aidemtest/supplemental/invalid-resp-multi-imp-type.json create mode 100644 adapters/aidem/aidemtest/supplemental/valid-req-200-bid-response-from-aidem.json create mode 100644 adapters/aidem/aidemtest/supplemental/valid-req-204-response-from-aidem.json create mode 100644 adapters/aidem/params_test.go create mode 100644 openrtb_ext/imp_aidem.go create mode 100644 static/bidder-info/aidem.yaml create mode 100644 static/bidder-params/aidem.json diff --git a/adapters/aidem/aidem.go b/adapters/aidem/aidem.go new file mode 100644 index 00000000000..9748f32c957 --- /dev/null +++ b/adapters/aidem/aidem.go @@ -0,0 +1,102 @@ +package aidem + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/openrtb_ext" +) + +type adapter struct { + endpoint string +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + + reqJson, err := json.Marshal(request) + if err != nil { + return nil, []error{err} + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + + return []*adapters.RequestData{{ + Method: "POST", + Uri: a.endpoint, + Body: reqJson, + Headers: headers, + }}, nil +} + +func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + var errs []error + + if adapters.IsResponseStatusCodeNoContent(response) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(response); err != nil { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), + }} + } + + var bidResp openrtb2.BidResponse + if err := json.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{&errortypes.BadServerResponse{ + Message: fmt.Sprintf("JSON parsing error: %v", err), + }} + } + + if len(bidResp.SeatBid) == 0 { + return nil, []error{&errortypes.BadServerResponse{ + Message: "Empty SeatBid array", + }} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(bidResp.SeatBid[0].Bid)) + + for _, seatBid := range bidResp.SeatBid { + for i := range seatBid.Bid { + bidType, err := getMediaTypeForBid(seatBid.Bid[i]) + if err != nil { + errs = append(errs, err) + } else { + b := &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + } + } + return bidResponse, errs +} + +// Builder builds a new instance of the AIDEM adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + return &adapter{ + endpoint: config.Endpoint, + }, nil +} + +func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupAudio: + return openrtb_ext.BidTypeAudio, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + return "", fmt.Errorf("Unable to fetch mediaType in multi-format: %s", bid.ImpID) + } +} diff --git a/adapters/aidem/aidem_test.go b/adapters/aidem/aidem_test.go new file mode 100644 index 00000000000..03bcc7e0fb5 --- /dev/null +++ b/adapters/aidem/aidem_test.go @@ -0,0 +1,30 @@ +package aidem + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderAidem, config.Adapter{ + Endpoint: "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request", + }, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "aidemtest", bidder) +} + +func TestEndpointTemplateMalformed(t *testing.T) { + _, buildErr := Builder(openrtb_ext.BidderAidem, config.Adapter{ + Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + assert.Nil(t, buildErr) +} diff --git a/adapters/aidem/aidemtest/exemplary/multi-format.json b/adapters/aidem/aidemtest/exemplary/multi-format.json new file mode 100644 index 00000000000..0c940d4ba59 --- /dev/null +++ b/adapters/aidem/aidemtest/exemplary/multi-format.json @@ -0,0 +1,119 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 320, + "h": 50 + } + ] + }, + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 320, + "h": 480 + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 320, + "h": 50 + } + ] + }, + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 320, + "h": 480 + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "aax", + "bid": [ + { + "id": "test-bid-id", + "impid": "1", + "price": 1.50, + "adm": "some-test-ad", + "crid": "test-crid", + "h": 50, + "w": 320, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "1", + "price": 1.50, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 320, + "h": 50, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/aidem/aidemtest/exemplary/multi-imps-multi-bid.json b/adapters/aidem/aidemtest/exemplary/multi-imps-multi-bid.json new file mode 100644 index 00000000000..5c2b36948f7 --- /dev/null +++ b/adapters/aidem/aidemtest/exemplary/multi-imps-multi-bid.json @@ -0,0 +1,154 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 320, + "h": 50 + } + ] + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + }, + { + "id": "2", + "banner": { + "format": [ + { + "w": 300, + "h": 50 + } + ] + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 320, + "h": 50 + } + ] + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + }, + { + "id": "2", + "banner": { + "format": [ + { + "w": 300, + "h": 50 + } + ] + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "aax", + "bid": [ + { + "id": "test-bid-id", + "impid": "1", + "price": 1.50, + "adm": "some-test-ad", + "crid": "test-crid", + "h": 50, + "w": 320, + "mtype": 1 + }, + { + "id": "test-bid-id-2", + "impid": "2", + "price": 1.10, + "adm": "some-test-ad-2", + "crid": "test-crid-2", + "h": 50, + "w": 300, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "1", + "price": 1.50, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 320, + "h": 50, + "mtype": 1 + }, + "type": "banner" + }, + { + "bid": { + "id": "test-bid-id-2", + "impid": "2", + "price": 1.10, + "adm": "some-test-ad-2", + "crid": "test-crid-2", + "w": 300, + "h": 50, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/aidem/aidemtest/exemplary/multi-imps-single-bid.json b/adapters/aidem/aidemtest/exemplary/multi-imps-single-bid.json new file mode 100644 index 00000000000..9eae7101a90 --- /dev/null +++ b/adapters/aidem/aidemtest/exemplary/multi-imps-single-bid.json @@ -0,0 +1,131 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 320, + "h": 50 + } + ] + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + }, + { + "id": "2", + "banner": { + "format": [ + { + "w": 300, + "h": 50 + } + ] + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 320, + "h": 50 + } + ] + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + }, + { + "id": "2", + "banner": { + "format": [ + { + "w": 300, + "h": 50 + } + ] + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "aax", + "bid": [ + { + "id": "test-bid-id", + "impid": "1", + "price": 1.50, + "adm": "some-test-ad", + "crid": "test-crid", + "h": 50, + "w": 320, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "1", + "price": 1.50, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 320, + "h": 50, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/aidem/aidemtest/exemplary/no-bid.json b/adapters/aidem/aidemtest/exemplary/no-bid.json new file mode 100644 index 00000000000..7418425f10b --- /dev/null +++ b/adapters/aidem/aidemtest/exemplary/no-bid.json @@ -0,0 +1,58 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ] + } + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/aidem/aidemtest/exemplary/optional-params.json b/adapters/aidem/aidemtest/exemplary/optional-params.json new file mode 100644 index 00000000000..69511fb595c --- /dev/null +++ b/adapters/aidem/aidemtest/exemplary/optional-params.json @@ -0,0 +1,60 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234", + "placementId": "ext" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234", + "placementId": "ext" + } + } + } + ] + } + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/aidem/aidemtest/exemplary/simple-banner.json b/adapters/aidem/aidemtest/exemplary/simple-banner.json new file mode 100644 index 00000000000..73db297ee42 --- /dev/null +++ b/adapters/aidem/aidemtest/exemplary/simple-banner.json @@ -0,0 +1,97 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 320, + "h": 50 + } + ] + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 320, + "h": 50 + } + ] + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "aax", + "bid": [ + { + "id": "test-bid-id", + "impid": "1", + "price": 1.50, + "adm": "some-test-ad", + "crid": "test-crid", + "h": 50, + "w": 320, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "1", + "price": 1.50, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 320, + "h": 50, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/aidem/aidemtest/exemplary/simple-video.json b/adapters/aidem/aidemtest/exemplary/simple-video.json new file mode 100644 index 00000000000..0daaffaa8cf --- /dev/null +++ b/adapters/aidem/aidemtest/exemplary/simple-video.json @@ -0,0 +1,103 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "1", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 320, + "h": 480 + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "1", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 320, + "h": 480 + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "aax", + "bid": [ + { + "id": "test-bid-id", + "impid": "1", + "price": 2.50, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 320, + "h": 480, + "mtype": 2 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "1", + "price": 2.50, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 320, + "h": 480, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/aidem/aidemtest/supplemental/invalid-req-400-status-code-bad-request.json b/adapters/aidem/aidemtest/supplemental/invalid-req-400-status-code-bad-request.json new file mode 100644 index 00000000000..3dea13ef7c9 --- /dev/null +++ b/adapters/aidem/aidemtest/supplemental/invalid-req-400-status-code-bad-request.json @@ -0,0 +1,97 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "tmax": 1000, + "user": { + "buyeruid": "0000-000-000-0000" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request", + "body": { + "id": "some-request-id", + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ], + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "user": { + "buyeruid": "0000-000-000-0000" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 400 + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/aidem/aidemtest/supplemental/invalid-res-200-status-code-empty-bids.json b/adapters/aidem/aidemtest/supplemental/invalid-res-200-status-code-empty-bids.json new file mode 100644 index 00000000000..dd64125f467 --- /dev/null +++ b/adapters/aidem/aidemtest/supplemental/invalid-res-200-status-code-empty-bids.json @@ -0,0 +1,102 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "tmax": 1000, + "user": { + "buyeruid": "0000-000-000-0000" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request", + "body": { + "id": "some-request-id", + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ], + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "user": { + "buyeruid": "0000-000-000-0000" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "tid", + "seatbid": [], + "bidid": "bid01" + } + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Empty SeatBid array", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/aidem/aidemtest/supplemental/invalid-resp-multi-imp-type.json b/adapters/aidem/aidemtest/supplemental/invalid-resp-multi-imp-type.json new file mode 100644 index 00000000000..95f97d31f72 --- /dev/null +++ b/adapters/aidem/aidemtest/supplemental/invalid-resp-multi-imp-type.json @@ -0,0 +1,151 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "native": { + "ver": "1.1", + "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}" + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ], + "site": { + "domain": "www.example.com", + "page": "http://www.example.com", + "publisher": { + "domain": "example.com" + }, + "ext": { + "amp": 0 + } + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + }, + "at": 1, + "tmax": 5000, + "cur": [ + "USD" + ], + "regs": { + "ext": { + "gdpr": 0 + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "native": { + "ver": "1.1", + "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}" + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ], + "site": { + "domain": "www.example.com", + "page": "http://www.example.com", + "publisher": { + "domain": "example.com" + }, + "ext": { + "amp": 0 + } + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + }, + "at": 1, + "tmax": 5000, + "cur": [ + "USD" + ], + "regs": { + "ext": { + "gdpr": 0 + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "tid", + "seatbid": [ + { + "seat": "aax", + "bid": [ + { + "id": "randomid", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300 + } + ] + } + ], + "bidid": "bid01" + } + } + } + ], + "expectedBidResponses": [{"currency":"USD","bids":[]}], + "expectedMakeBidsErrors": [ + { + "value": "Unable to fetch mediaType in multi-format: test-imp-id", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/aidem/aidemtest/supplemental/valid-req-200-bid-response-from-aidem.json b/adapters/aidem/aidemtest/supplemental/valid-req-200-bid-response-from-aidem.json new file mode 100644 index 00000000000..cbd534cd91c --- /dev/null +++ b/adapters/aidem/aidemtest/supplemental/valid-req-200-bid-response-from-aidem.json @@ -0,0 +1,141 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ], + "site": { + "domain": "www.example.com", + "page": "http://www.example.com", + "publisher": { + "domain": "example.com" + }, + "ext": { + "amp": 0 + } + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + }, + "at": 1, + "tmax": 5000, + "cur": [ + "USD" + ], + "regs": { + "ext": { + "gdpr": 0 + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + } + } + ], + "site": { + "domain": "www.example.com", + "page": "http://www.example.com", + "publisher": { + "domain": "example.com" + }, + "ext": { + "amp": 0 + } + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + }, + "at": 1, + "tmax": 5000, + "cur": [ + "USD" + ], + "regs": { + "ext": { + "gdpr": 0 + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "tid", + "seatbid": [ + { + "seat": "aax", + "bid": [ + { + "id": "randomid", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + } + ] + } + ], + "bidid": "bid01" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/aidem/aidemtest/supplemental/valid-req-204-response-from-aidem.json b/adapters/aidem/aidemtest/supplemental/valid-req-204-response-from-aidem.json new file mode 100644 index 00000000000..ddd4e5a7735 --- /dev/null +++ b/adapters/aidem/aidemtest/supplemental/valid-req-204-response-from-aidem.json @@ -0,0 +1,66 @@ +{ + "mockBidRequest": { + "app": { + "bundle": "com.example.app" + }, + "id": "req-id", + "device": { + "ifa": "9d8fe0a9-c0dd-4482-b16b-5709b00c608d", + "ip": "1.1.1.1", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36" + }, + "imp": [ + { + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + }, + "banner": { + "w": 320, + "h": 50 + }, + "id": "imp-id" + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request", + "body": { + "app": { + "bundle": "com.example.app" + }, + "id": "req-id", + "device": { + "ifa": "9d8fe0a9-c0dd-4482-b16b-5709b00c608d", + "ip": "1.1.1.1", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36" + }, + "imp": [ + { + "ext": { + "bidder": { + "siteId": "TCID", + "publisherId": "1234" + } + }, + "banner": { + "w": 320, + "h": 50 + }, + "id": "imp-id" + } + ] + } + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/aidem/params_test.go b/adapters/aidem/params_test.go new file mode 100644 index 00000000000..36190c0bc9f --- /dev/null +++ b/adapters/aidem/params_test.go @@ -0,0 +1,57 @@ +package aidem + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/openrtb_ext" +) + +// This file actually intends to test static/bidder-params/aidem.json TODO: MUST BE CREATED +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderAidem, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected aidem params: %s", validParam) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderAidem, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{"siteId":"123", "publisherId":"1234"}`, + `{"siteId":"123", "publisherId":"1234", "placementId":"12345"}`, + `{"siteId":"123", "publisherId":"1234", "rateLimit":1}`, + `{"siteId":"123", "publisherId":"1234", "placementId":"12345", "rateLimit":1}`, +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `4.2`, + `[]`, + `{}`, + `{"siteId":"", "publisherId":""}`, + `{"siteId":"only siteId is present"}`, + `{"publisherId":"only publisherId is present"}`, + `{"ssiteId":"123","ppublisherId":"123"}`, + `{"aid":123, "placementId":"123", "siteId":"321"}`, +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 171600c0260..3c6f8d32575 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -28,6 +28,7 @@ import ( "github.com/prebid/prebid-server/adapters/adview" "github.com/prebid/prebid-server/adapters/adxcg" "github.com/prebid/prebid-server/adapters/adyoulike" + "github.com/prebid/prebid-server/adapters/aidem" "github.com/prebid/prebid-server/adapters/aja" "github.com/prebid/prebid-server/adapters/algorix" "github.com/prebid/prebid-server/adapters/amx" @@ -212,6 +213,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderAdView: adview.Builder, openrtb_ext.BidderAdxcg: adxcg.Builder, openrtb_ext.BidderAdyoulike: adyoulike.Builder, + openrtb_ext.BidderAidem: aidem.Builder, openrtb_ext.BidderAJA: aja.Builder, openrtb_ext.BidderAlgorix: algorix.Builder, openrtb_ext.BidderAMX: amx.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 03056123423..e6be30d7400 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -114,6 +114,7 @@ const ( BidderAdView BidderName = "adview" BidderAdxcg BidderName = "adxcg" BidderAdyoulike BidderName = "adyoulike" + BidderAidem BidderName = "aidem" BidderAJA BidderName = "aja" BidderAlgorix BidderName = "algorix" BidderAMX BidderName = "amx" @@ -310,6 +311,7 @@ func CoreBidderNames() []BidderName { BidderAdView, BidderAdxcg, BidderAdyoulike, + BidderAidem, BidderAJA, BidderAlgorix, BidderAMX, diff --git a/openrtb_ext/imp_aidem.go b/openrtb_ext/imp_aidem.go new file mode 100644 index 00000000000..59457f1eb4a --- /dev/null +++ b/openrtb_ext/imp_aidem.go @@ -0,0 +1,8 @@ +package openrtb_ext + +type ImpExtFoo struct { + SiteID string `json:"siteId"` + PublisherID string `json:"publisherId"` + PlacementID string `json:"placementId"` + RateLimit string `json:"rateLimit"` +} diff --git a/static/bidder-info/aidem.yaml b/static/bidder-info/aidem.yaml new file mode 100644 index 00000000000..35ea898aa8a --- /dev/null +++ b/static/bidder-info/aidem.yaml @@ -0,0 +1,19 @@ +endpoint: "https://zero.aidemsrv.com/ortb/v2.6/bid/request" +maintainer: + email: prebid@aidem.com +modifyingVastXmlAllowed: true +capabilities: + app: + mediaTypes: + - banner + - video + - native + site: + mediaTypes: + - banner + - video + - native +userSync: + redirect: + url: https://gum.aidemsrv.com/prebid_sync?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}} + userMacro: "$UID" diff --git a/static/bidder-params/aidem.json b/static/bidder-params/aidem.json new file mode 100644 index 00000000000..221e5ff7a92 --- /dev/null +++ b/static/bidder-params/aidem.json @@ -0,0 +1,29 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "AIDEM Adapter Params", + "description": "A schema which validates params accepted by the AIDEM adapter", + "type": "object", + "properties": { + "siteId": { + "type": "string", + "minLength": 1, + "description": "Unique site ID" + }, + "publisherId": { + "type": "string", + "minLength": 1, + "description": "Unique publisher ID" + }, + "placementId": { + "type": "string", + "minLength": 1, + "description": "Unique publisher ttag ID" + }, + "rateLimit": { + "type": "number", + "minimum": 0, + "maximum": 1 + } + }, + "required": ["siteId", "publisherId"] +} \ No newline at end of file From 684ad6e4277240232f52ee4e53baf94db1a76bc6 Mon Sep 17 00:00:00 2001 From: Jozef Bartek <31618107+jbartek25@users.noreply.github.com> Date: Wed, 5 Jul 2023 09:57:46 +0200 Subject: [PATCH 002/268] Improve Digital adapter: Set currency in bid response (#2886) --- adapters/improvedigital/improvedigital.go | 1 + .../supplemental/foreign-currency.json | 89 +++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 adapters/improvedigital/improvedigitaltest/supplemental/foreign-currency.json diff --git a/adapters/improvedigital/improvedigital.go b/adapters/improvedigital/improvedigital.go index 4c64451f247..b934ac753a0 100644 --- a/adapters/improvedigital/improvedigital.go +++ b/adapters/improvedigital/improvedigital.go @@ -140,6 +140,7 @@ func (a *ImprovedigitalAdapter) MakeBids(internalRequest *openrtb2.BidRequest, e } bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(seatBid.Bid)) + bidResponse.Currency = bidResp.Cur for i := range seatBid.Bid { bid := seatBid.Bid[i] diff --git a/adapters/improvedigital/improvedigitaltest/supplemental/foreign-currency.json b/adapters/improvedigital/improvedigitaltest/supplemental/foreign-currency.json new file mode 100644 index 00000000000..633e8b6b0aa --- /dev/null +++ b/adapters/improvedigital/improvedigitaltest/supplemental/foreign-currency.json @@ -0,0 +1,89 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "cur": ["EUR"], + "site": { + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "placementId": 13245 + } + } + }] + }, + + "httpCalls": [{ + "expectedRequest": { + "uri": "http://localhost/pbs", + "body": { + "id": "test-request-id", + "cur": ["EUR"], + "site": { + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "placementId": 13245 + } + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "EUR", + "seatbid": [{ + "seat": "improvedigital", + "bid": [{ + "id": "randomid", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300 + }] + }] + } + } + }], + + "expectedBidResponses": [{ + "currency": "EUR", + "bids": [{ + "bid": { + "id": "randomid", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "12345678", + "cid": "987", + "crid": "12345678", + "w": 300, + "h": 250 + }, + "type": "banner" + }] + }] +} From 278ed420e25b124419707d33505480c9baea250b Mon Sep 17 00:00:00 2001 From: Max Dupuis <118775839+maxime-dupuis@users.noreply.github.com> Date: Wed, 5 Jul 2023 04:16:44 -0400 Subject: [PATCH 003/268] Sharethrough: Support multiformat bid request impression (#2866) --- adapters/sharethrough/sharethrough.go | 60 ++- .../supplemental/multiformat-impression.json | 362 ++++++++++++++++++ 2 files changed, 413 insertions(+), 9 deletions(-) create mode 100644 adapters/sharethrough/sharethroughtest/supplemental/multiformat-impression.json diff --git a/adapters/sharethrough/sharethrough.go b/adapters/sharethrough/sharethrough.go index f797bfe43d9..009ce0aa1d5 100644 --- a/adapters/sharethrough/sharethrough.go +++ b/adapters/sharethrough/sharethrough.go @@ -83,21 +83,29 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E requestCopy.BCat = append(requestCopy.BCat, strImpParams.BCat...) requestCopy.BAdv = append(requestCopy.BAdv, strImpParams.BAdv...) - requestCopy.Imp = []openrtb2.Imp{imp} - - requestJSON, err := json.Marshal(requestCopy) + impressionsByMediaType, err := splitImpressionsByMediaType(&imp) if err != nil { errors = append(errors, err) continue } - requestData := &adapters.RequestData{ - Method: "POST", - Uri: a.endpoint, - Body: requestJSON, - Headers: headers, + for _, impression := range impressionsByMediaType { + requestCopy.Imp = []openrtb2.Imp{impression} + + requestJSON, err := json.Marshal(requestCopy) + if err != nil { + errors = append(errors, err) + continue + } + + requestData := &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: requestJSON, + Headers: headers, + } + requests = append(requests, requestData) } - requests = append(requests, requestData) } return requests, errors @@ -150,6 +158,40 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R return bidderResponse, errors } +func splitImpressionsByMediaType(impression *openrtb2.Imp) ([]openrtb2.Imp, error) { + if impression.Banner == nil && impression.Video == nil && impression.Native == nil { + return nil, &errortypes.BadInput{Message: "Invalid MediaType. Sharethrough only supports Banner, Video and Native."} + } + + if impression.Audio != nil { + impression.Audio = nil + } + + impressions := make([]openrtb2.Imp, 0, 3) + + if impression.Banner != nil { + impCopy := *impression + impCopy.Video = nil + impCopy.Native = nil + impressions = append(impressions, impCopy) + } + + if impression.Video != nil { + impCopy := *impression + impCopy.Banner = nil + impCopy.Native = nil + impressions = append(impressions, impCopy) + } + + if impression.Native != nil { + impression.Banner = nil + impression.Video = nil + impressions = append(impressions, *impression) + } + + return impressions, nil +} + func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { if bid.Ext != nil { diff --git a/adapters/sharethrough/sharethroughtest/supplemental/multiformat-impression.json b/adapters/sharethrough/sharethroughtest/supplemental/multiformat-impression.json new file mode 100644 index 00000000000..fcebf79acc8 --- /dev/null +++ b/adapters/sharethrough/sharethroughtest/supplemental/multiformat-impression.json @@ -0,0 +1,362 @@ +{ + "mockBidRequest": { + "id": "parent-id", + "tmax": 3000, + "imp": [ + { + "id": "impression-id", + "ext": { + "bidder": { + "pkey": "pkey1" + } + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "video": { + "w": 640, + "h": 480, + "mimes": [ + "video/mp4" + ], + "placement": 1 + }, + "native": { + "ver": "1.2", + "request": "placeholder request" + }, + "audio": { + "mimes": [ + "audio/mp4" + ], + "protocols": [ + 1, + 2 + ] + } + } + ], + "site": { + "publisher": { + "id": "1" + }, + "page": "https://some-site.com", + "ref": "https://some-site.com" + }, + "device": { + "w": 1200, + "h": 900 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://whatever.url", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "body": { + "id": "parent-id", + "tmax": 3000, + "imp": [ + { + "id": "impression-id", + "tagid": "pkey1", + "ext": { + "bidder": { + "pkey": "pkey1" + } + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + } + } + ], + "site": { + "publisher": { + "id": "1" + }, + "page": "https://some-site.com", + "ref": "https://some-site.com" + }, + "device": { + "w": 1200, + "h": 900 + }, + "source": { + "ext": { + "version": "", + "str": "10.0" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "parent-id", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "parent-id", + "impid": "impression-id", + "crid": "some-creative-id", + "adm": "
Ad
", + "price": 20, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ] + } + } + }, + { + "expectedRequest": { + "uri": "http://whatever.url", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "body": { + "id": "parent-id", + "tmax": 3000, + "imp": [ + { + "id": "impression-id", + "tagid": "pkey1", + "ext": { + "bidder": { + "pkey": "pkey1" + } + }, + "video": { + "w": 640, + "h": 480, + "mimes": [ + "video/mp4" + ], + "placement": 1 + } + } + ], + "site": { + "publisher": { + "id": "1" + }, + "page": "https://some-site.com", + "ref": "https://some-site.com" + }, + "device": { + "w": 1200, + "h": 900 + }, + "source": { + "ext": { + "version": "", + "str": "10.0" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "parent-id", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "parent-id", + "impid": "impression-id", + "crid": "some-creative-id", + "adm": "TAG", + "price": 20, + "w": 640, + "h": 480, + "ext": { + "prebid": { + "type": "video" + } + } + } + ] + } + ] + } + } + }, + { + "expectedRequest": { + "uri": "http://whatever.url", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "body": { + "id": "parent-id", + "tmax": 3000, + "imp": [ + { + "id": "impression-id", + "tagid": "pkey1", + "ext": { + "bidder": { + "pkey": "pkey1" + } + }, + "native": { + "ver": "1.2", + "request": "placeholder request" + } + } + ], + "site": { + "publisher": { + "id": "1" + }, + "page": "https://some-site.com", + "ref": "https://some-site.com" + }, + "device": { + "w": 1200, + "h": 900 + }, + "source": { + "ext": { + "version": "", + "str": "10.0" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "parent-id", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "parent-id", + "impid": "impression-id", + "crid": "some-creative-id", + "adm": "
Ad
", + "price": 20, + "w": 640, + "h": 480, + "ext": { + "prebid": { + "type": "native" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "parent-id", + "impid": "impression-id", + "crid": "some-creative-id", + "adm": "
Ad
", + "price": 20, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + }, + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "parent-id", + "impid": "impression-id", + "crid": "some-creative-id", + "adm": "TAG", + "price": 20, + "w": 640, + "h": 480, + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + }, + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "parent-id", + "impid": "impression-id", + "crid": "some-creative-id", + "adm": "
Ad
", + "price": 20, + "w": 640, + "h": 480, + "ext": { + "prebid": { + "type": "native" + } + } + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file From 14ae771de5b1f34b8a203278dec0aa532e030460 Mon Sep 17 00:00:00 2001 From: Patrick Loughrey Date: Wed, 5 Jul 2023 04:33:08 -0400 Subject: [PATCH 004/268] Triplelift Bid Adapter: Adding GPP Support (#2887) --- static/bidder-info/triplelift.yaml | 8 +++++--- static/bidder-info/triplelift_native.yaml | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/static/bidder-info/triplelift.yaml b/static/bidder-info/triplelift.yaml index 45811c0c868..605bcc71e6e 100644 --- a/static/bidder-info/triplelift.yaml +++ b/static/bidder-info/triplelift.yaml @@ -16,9 +16,11 @@ userSync: # Contact this bidder directly at the email address above to ask about enabling user sync. # iframe: - url: "https://eb2.3lift.com/sync?gdpr={{.GDPR}}&cmp_cs={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir={{.RedirectURL}}" + url: "https://eb2.3lift.com/sync?gdpr={{.GDPR}}&cmp_cs={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" userMacro: $UID redirect: - url: "https://eb2.3lift.com/getuid?gdpr={{.GDPR}}&cmp_cs={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir={{.RedirectURL}}" + url: "https://eb2.3lift.com/getuid?gdpr={{.GDPR}}&cmp_cs={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" userMacro: "$UID" -endpointCompression: "GZIP" \ No newline at end of file +endpointCompression: "GZIP" +openrtb: + gpp-supported: true \ No newline at end of file diff --git a/static/bidder-info/triplelift_native.yaml b/static/bidder-info/triplelift_native.yaml index 85ebd1a52cc..ff93b544c4c 100644 --- a/static/bidder-info/triplelift_native.yaml +++ b/static/bidder-info/triplelift_native.yaml @@ -16,8 +16,10 @@ userSync: # Contact this bidder directly at the email address above to ask about enabling user sync. # iframe: - url: "https://eb2.3lift.com/sync?gdpr={{.GDPR}}&cmp_cs={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir={{.RedirectURL}}" + url: "https://eb2.3lift.com/sync?gdpr={{.GDPR}}&cmp_cs={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" userMacro: $UID redirect: - url: "https://eb2.3lift.com/getuid?gdpr={{.GDPR}}&cmp_cs={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir={{.RedirectURL}}" - userMacro: "$UID" \ No newline at end of file + url: "https://eb2.3lift.com/getuid?gdpr={{.GDPR}}&cmp_cs={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}" + userMacro: "$UID" +openrtb: + gpp-supported: true \ No newline at end of file From 230213dceac479e5fb785af6e9d3bb3ac2c5a5d5 Mon Sep 17 00:00:00 2001 From: radubarbos Date: Wed, 5 Jul 2023 12:01:18 +0300 Subject: [PATCH 005/268] YahooAdvertising rebranding to Yahoo Ads. (#2872) Co-authored-by: oath-jac --- .../params_test.go | 16 ++++++++-------- .../yahooAds.go} | 12 ++++++------ .../yahooAds_test.go} | 14 +++++++------- .../exemplary/simple-app-banner.json | 2 +- .../exemplary/simple-banner.json | 2 +- .../yahooAdstest}/exemplary/simple-video.json | 2 +- .../supplemental/empty-banner-format.json | 0 .../supplemental/invalid-banner-height.json | 0 .../supplemental/invalid-banner-width.json | 0 .../non-supported-requests-bids-ignored.json | 2 +- .../supplemental/required-nobidder-info.json | 0 .../supplemental/server-error.json | 0 .../server-response-wrong-impid.json | 2 +- .../simple-banner-gpp-overwrite.json | 2 +- .../supplemental/simple-banner-gpp.json | 2 +- ...nner-ignore-width-when-height-missing.json | 2 +- exchange/adapter_builders.go | 7 ++++--- exchange/adapter_util.go | 2 +- exchange/adapter_util_test.go | 8 ++++---- openrtb_ext/bidders.go | 2 ++ openrtb_ext/bidders_validate_test.go | 2 +- openrtb_ext/imp_yahooAds.go | 7 +++++++ static/bidder-info/yahooAds.yaml | 18 ++++++++++++++++++ static/bidder-params/yahooAds.json | 19 +++++++++++++++++++ 24 files changed, 85 insertions(+), 38 deletions(-) rename adapters/{yahooAdvertising => yahooAds}/params_test.go (63%) rename adapters/{yahooAdvertising/yahooAdvertising.go => yahooAds/yahooAds.go} (93%) rename adapters/{yahooAdvertising/yahooAdvertising_test.go => yahooAds/yahooAds_test.go} (51%) rename adapters/{yahooAdvertising/yahooAdvertisingtest => yahooAds/yahooAdstest}/exemplary/simple-app-banner.json (98%) rename adapters/{yahooAdvertising/yahooAdvertisingtest => yahooAds/yahooAdstest}/exemplary/simple-banner.json (98%) rename adapters/{yahooAdvertising/yahooAdvertisingtest => yahooAds/yahooAdstest}/exemplary/simple-video.json (98%) rename adapters/{yahooAdvertising/yahooAdvertisingtest => yahooAds/yahooAdstest}/supplemental/empty-banner-format.json (100%) rename adapters/{yahooAdvertising/yahooAdvertisingtest => yahooAds/yahooAdstest}/supplemental/invalid-banner-height.json (100%) rename adapters/{yahooAdvertising/yahooAdvertisingtest => yahooAds/yahooAdstest}/supplemental/invalid-banner-width.json (100%) rename adapters/{yahooAdvertising/yahooAdvertisingtest => yahooAds/yahooAdstest}/supplemental/non-supported-requests-bids-ignored.json (98%) rename adapters/{yahooAdvertising/yahooAdvertisingtest => yahooAds/yahooAdstest}/supplemental/required-nobidder-info.json (100%) rename adapters/{yahooAdvertising/yahooAdvertisingtest => yahooAds/yahooAdstest}/supplemental/server-error.json (100%) rename adapters/{yahooAdvertising/yahooAdvertisingtest => yahooAds/yahooAdstest}/supplemental/server-response-wrong-impid.json (98%) rename adapters/{yahooAdvertising/yahooAdvertisingtest => yahooAds/yahooAdstest}/supplemental/simple-banner-gpp-overwrite.json (98%) rename adapters/{yahooAdvertising/yahooAdvertisingtest => yahooAds/yahooAdstest}/supplemental/simple-banner-gpp.json (98%) rename adapters/{yahooAdvertising/yahooAdvertisingtest => yahooAds/yahooAdstest}/supplemental/simple-banner-ignore-width-when-height-missing.json (98%) create mode 100644 openrtb_ext/imp_yahooAds.go create mode 100644 static/bidder-info/yahooAds.yaml create mode 100644 static/bidder-params/yahooAds.json diff --git a/adapters/yahooAdvertising/params_test.go b/adapters/yahooAds/params_test.go similarity index 63% rename from adapters/yahooAdvertising/params_test.go rename to adapters/yahooAds/params_test.go index 10d504cb291..c0deaaa32c9 100644 --- a/adapters/yahooAdvertising/params_test.go +++ b/adapters/yahooAds/params_test.go @@ -1,4 +1,4 @@ -package yahooAdvertising +package yahooAds import ( "encoding/json" @@ -7,11 +7,11 @@ import ( "github.com/prebid/prebid-server/openrtb_ext" ) -// This file actually intends to test static/bidder-params/yahooAdvertising.json +// This file actually intends to test static/bidder-params/yahooAds.json // -// These also validate the format of the external API: request.imp[i].ext.yahooAdvertising +// These also validate the format of the external API: request.imp[i].ext.yahooAds -// TestValidParams makes sure that the yahooAdvertising schema accepts all imp.ext fields which we intend to support. +// TestValidParams makes sure that the yahooAds schema accepts all imp.ext fields which we intend to support. func TestValidParams(t *testing.T) { validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") if err != nil { @@ -19,13 +19,13 @@ func TestValidParams(t *testing.T) { } for _, validParam := range validParams { - if err := validator.Validate(openrtb_ext.BidderYahooAdvertising, json.RawMessage(validParam)); err != nil { - t.Errorf("Schema rejected yahooAdvertising params: %s", validParam) + if err := validator.Validate(openrtb_ext.BidderYahooAds, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected yahooAds params: %s", validParam) } } } -// TestInvalidParams makes sure that the yahooAdvertising schema rejects all the imp.ext fields we don't support. +// TestInvalidParams makes sure that the yahooAds schema rejects all the imp.ext fields we don't support. func TestInvalidParams(t *testing.T) { validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") if err != nil { @@ -33,7 +33,7 @@ func TestInvalidParams(t *testing.T) { } for _, invalidParam := range invalidParams { - if err := validator.Validate(openrtb_ext.BidderYahooAdvertising, json.RawMessage(invalidParam)); err == nil { + if err := validator.Validate(openrtb_ext.BidderYahooAds, json.RawMessage(invalidParam)); err == nil { t.Errorf("Schema allowed unexpected params: %s", invalidParam) } } diff --git a/adapters/yahooAdvertising/yahooAdvertising.go b/adapters/yahooAds/yahooAds.go similarity index 93% rename from adapters/yahooAdvertising/yahooAdvertising.go rename to adapters/yahooAds/yahooAds.go index d476adb4e8e..3597d0e359c 100644 --- a/adapters/yahooAdvertising/yahooAdvertising.go +++ b/adapters/yahooAds/yahooAds.go @@ -1,4 +1,4 @@ -package yahooAdvertising +package yahooAds import ( "encoding/json" @@ -41,8 +41,8 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E continue } - var yahooAdvertisingExt openrtb_ext.ExtImpYahooAdvertising - err = json.Unmarshal(bidderExt.Bidder, &yahooAdvertisingExt) + var yahooAdsExt openrtb_ext.ExtImpYahooAds + err = json.Unmarshal(bidderExt.Bidder, &yahooAdsExt) if err != nil { err = &errortypes.BadInput{ Message: fmt.Sprintf("imp #%d: %s", idx, err.Error()), @@ -64,7 +64,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E reqCopy.App = &appCopy } - if err := changeRequestForBidService(&reqCopy, &yahooAdvertisingExt); err != nil { + if err := changeRequestForBidService(&reqCopy, &yahooAdsExt); err != nil { errors = append(errors, err) continue } @@ -150,7 +150,7 @@ func getImpInfo(impId string, imps []openrtb2.Imp) (bool, openrtb_ext.BidType) { return exists, mediaType } -func changeRequestForBidService(request *openrtb2.BidRequest, extension *openrtb_ext.ExtImpYahooAdvertising) error { +func changeRequestForBidService(request *openrtb2.BidRequest, extension *openrtb_ext.ExtImpYahooAds) error { /* Always override the tag ID and (site ID or app ID) of the request */ request.Imp[0].TagID = extension.Pos if request.Site != nil { @@ -218,7 +218,7 @@ func validateBanner(banner *openrtb2.Banner) error { return nil } -// Builder builds a new instance of the YahooAdvertising adapter for the given bidder with the given config. +// Builder builds a new instance of the YahooAds adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { bidder := &adapter{ URI: config.Endpoint, diff --git a/adapters/yahooAdvertising/yahooAdvertising_test.go b/adapters/yahooAds/yahooAds_test.go similarity index 51% rename from adapters/yahooAdvertising/yahooAdvertising_test.go rename to adapters/yahooAds/yahooAds_test.go index e701c3335c1..924eabd5ec1 100644 --- a/adapters/yahooAdvertising/yahooAdvertising_test.go +++ b/adapters/yahooAds/yahooAds_test.go @@ -1,4 +1,4 @@ -package yahooAdvertising +package yahooAds import ( "testing" @@ -10,8 +10,8 @@ import ( "github.com/prebid/prebid-server/openrtb_ext" ) -func TestYahooAdvertisingBidderEndpointConfig(t *testing.T) { - bidder, buildErr := Builder(openrtb_ext.BidderYahooAdvertising, config.Adapter{ +func TestYahooAdsBidderEndpointConfig(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderYahooAds, config.Adapter{ Endpoint: "http://localhost/bid", }, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) @@ -19,17 +19,17 @@ func TestYahooAdvertisingBidderEndpointConfig(t *testing.T) { t.Fatalf("Builder returned unexpected error %v", buildErr) } - bidderYahooAdvertising := bidder.(*adapter) + bidderYahooAds := bidder.(*adapter) - assert.Equal(t, "http://localhost/bid", bidderYahooAdvertising.URI) + assert.Equal(t, "http://localhost/bid", bidderYahooAds.URI) } func TestJsonSamples(t *testing.T) { - bidder, buildErr := Builder(openrtb_ext.BidderYahooAdvertising, config.Adapter{}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + bidder, buildErr := Builder(openrtb_ext.BidderYahooAds, config.Adapter{}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) if buildErr != nil { t.Fatalf("Builder returned unexpected error %v", buildErr) } - adapterstest.RunJSONBidderTest(t, "yahooAdvertisingtest", bidder) + adapterstest.RunJSONBidderTest(t, "yahooAdstest", bidder) } diff --git a/adapters/yahooAdvertising/yahooAdvertisingtest/exemplary/simple-app-banner.json b/adapters/yahooAds/yahooAdstest/exemplary/simple-app-banner.json similarity index 98% rename from adapters/yahooAdvertising/yahooAdvertisingtest/exemplary/simple-app-banner.json rename to adapters/yahooAds/yahooAdstest/exemplary/simple-app-banner.json index d5e77c71d3d..7ad41161915 100644 --- a/adapters/yahooAdvertising/yahooAdvertisingtest/exemplary/simple-app-banner.json +++ b/adapters/yahooAds/yahooAdstest/exemplary/simple-app-banner.json @@ -77,7 +77,7 @@ "id": "test-request-id", "seatbid": [ { - "seat": "yahooAdvertising", + "seat": "yahooAds", "bid": [{ "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", diff --git a/adapters/yahooAdvertising/yahooAdvertisingtest/exemplary/simple-banner.json b/adapters/yahooAds/yahooAdstest/exemplary/simple-banner.json similarity index 98% rename from adapters/yahooAdvertising/yahooAdvertisingtest/exemplary/simple-banner.json rename to adapters/yahooAds/yahooAdstest/exemplary/simple-banner.json index d08bdf06019..7036664d4ad 100644 --- a/adapters/yahooAdvertising/yahooAdvertisingtest/exemplary/simple-banner.json +++ b/adapters/yahooAds/yahooAdstest/exemplary/simple-banner.json @@ -77,7 +77,7 @@ "id": "test-request-id", "seatbid": [ { - "seat": "yahooAdvertising", + "seat": "yahooAds", "bid": [{ "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", diff --git a/adapters/yahooAdvertising/yahooAdvertisingtest/exemplary/simple-video.json b/adapters/yahooAds/yahooAdstest/exemplary/simple-video.json similarity index 98% rename from adapters/yahooAdvertising/yahooAdvertisingtest/exemplary/simple-video.json rename to adapters/yahooAds/yahooAdstest/exemplary/simple-video.json index ea95ec40306..ebf7af93d53 100644 --- a/adapters/yahooAdvertising/yahooAdvertisingtest/exemplary/simple-video.json +++ b/adapters/yahooAds/yahooAdstest/exemplary/simple-video.json @@ -92,7 +92,7 @@ "id": "test-request-id", "seatbid": [ { - "seat": "yahooAdvertising", + "seat": "yahooAds", "bid": [{ "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", diff --git a/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/empty-banner-format.json b/adapters/yahooAds/yahooAdstest/supplemental/empty-banner-format.json similarity index 100% rename from adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/empty-banner-format.json rename to adapters/yahooAds/yahooAdstest/supplemental/empty-banner-format.json diff --git a/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/invalid-banner-height.json b/adapters/yahooAds/yahooAdstest/supplemental/invalid-banner-height.json similarity index 100% rename from adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/invalid-banner-height.json rename to adapters/yahooAds/yahooAdstest/supplemental/invalid-banner-height.json diff --git a/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/invalid-banner-width.json b/adapters/yahooAds/yahooAdstest/supplemental/invalid-banner-width.json similarity index 100% rename from adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/invalid-banner-width.json rename to adapters/yahooAds/yahooAdstest/supplemental/invalid-banner-width.json diff --git a/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/non-supported-requests-bids-ignored.json b/adapters/yahooAds/yahooAdstest/supplemental/non-supported-requests-bids-ignored.json similarity index 98% rename from adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/non-supported-requests-bids-ignored.json rename to adapters/yahooAds/yahooAdstest/supplemental/non-supported-requests-bids-ignored.json index a44020daf3f..c0d77fa496b 100644 --- a/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/non-supported-requests-bids-ignored.json +++ b/adapters/yahooAds/yahooAdstest/supplemental/non-supported-requests-bids-ignored.json @@ -74,7 +74,7 @@ "id": "test-request-id", "seatbid": [ { - "seat": "yahooAdvertising", + "seat": "yahooAds", "bid": [{ "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", diff --git a/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/required-nobidder-info.json b/adapters/yahooAds/yahooAdstest/supplemental/required-nobidder-info.json similarity index 100% rename from adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/required-nobidder-info.json rename to adapters/yahooAds/yahooAdstest/supplemental/required-nobidder-info.json diff --git a/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/server-error.json b/adapters/yahooAds/yahooAdstest/supplemental/server-error.json similarity index 100% rename from adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/server-error.json rename to adapters/yahooAds/yahooAdstest/supplemental/server-error.json diff --git a/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/server-response-wrong-impid.json b/adapters/yahooAds/yahooAdstest/supplemental/server-response-wrong-impid.json similarity index 98% rename from adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/server-response-wrong-impid.json rename to adapters/yahooAds/yahooAdstest/supplemental/server-response-wrong-impid.json index 1fcf61e12b7..f40819497a8 100644 --- a/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/server-response-wrong-impid.json +++ b/adapters/yahooAds/yahooAdstest/supplemental/server-response-wrong-impid.json @@ -76,7 +76,7 @@ "id": "test-request-id", "seatbid": [ { - "seat": "yahooAdvertising", + "seat": "yahooAds", "bid": [{ "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "wrong", diff --git a/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/simple-banner-gpp-overwrite.json b/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-gpp-overwrite.json similarity index 98% rename from adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/simple-banner-gpp-overwrite.json rename to adapters/yahooAds/yahooAdstest/supplemental/simple-banner-gpp-overwrite.json index 190f96bf0a6..94c895b996d 100644 --- a/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/simple-banner-gpp-overwrite.json +++ b/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-gpp-overwrite.json @@ -92,7 +92,7 @@ "id": "test-request-id", "seatbid": [ { - "seat": "yahooAdvertising", + "seat": "yahooAds", "bid": [{ "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", diff --git a/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/simple-banner-gpp.json b/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-gpp.json similarity index 98% rename from adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/simple-banner-gpp.json rename to adapters/yahooAds/yahooAdstest/supplemental/simple-banner-gpp.json index 81c89f55c3d..3d5aff6c531 100644 --- a/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/simple-banner-gpp.json +++ b/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-gpp.json @@ -87,7 +87,7 @@ "id": "test-request-id", "seatbid": [ { - "seat": "yahooAdvertising", + "seat": "yahooAds", "bid": [{ "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", diff --git a/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/simple-banner-ignore-width-when-height-missing.json b/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-ignore-width-when-height-missing.json similarity index 98% rename from adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/simple-banner-ignore-width-when-height-missing.json rename to adapters/yahooAds/yahooAdstest/supplemental/simple-banner-ignore-width-when-height-missing.json index 353d5e29e71..1206005970c 100644 --- a/adapters/yahooAdvertising/yahooAdvertisingtest/supplemental/simple-banner-ignore-width-when-height-missing.json +++ b/adapters/yahooAds/yahooAdstest/supplemental/simple-banner-ignore-width-when-height-missing.json @@ -78,7 +78,7 @@ "id": "test-request-id", "seatbid": [ { - "seat": "yahooAdvertising", + "seat": "yahooAds", "bid": [{ "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 3c6f8d32575..3818a16a03a 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -170,7 +170,7 @@ import ( "github.com/prebid/prebid-server/adapters/visx" "github.com/prebid/prebid-server/adapters/vrtcal" "github.com/prebid/prebid-server/adapters/xeworks" - "github.com/prebid/prebid-server/adapters/yahooAdvertising" + "github.com/prebid/prebid-server/adapters/yahooAds" "github.com/prebid/prebid-server/adapters/yeahmobi" "github.com/prebid/prebid-server/adapters/yieldlab" "github.com/prebid/prebid-server/adapters/yieldmo" @@ -369,8 +369,9 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderVisx: visx.Builder, openrtb_ext.BidderVrtcal: vrtcal.Builder, openrtb_ext.BidderXeworks: xeworks.Builder, - openrtb_ext.BidderYahooAdvertising: yahooAdvertising.Builder, - openrtb_ext.BidderYahooSSP: yahooAdvertising.Builder, + openrtb_ext.BidderYahooAds: yahooAds.Builder, + openrtb_ext.BidderYahooAdvertising: yahooAds.Builder, + openrtb_ext.BidderYahooSSP: yahooAds.Builder, openrtb_ext.BidderYeahmobi: yeahmobi.Builder, openrtb_ext.BidderYieldlab: yieldlab.Builder, openrtb_ext.BidderYieldmo: yieldmo.Builder, diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index d8f683b35d2..ad1866a63c8 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -88,7 +88,7 @@ func GetDisabledBiddersErrorMessages(infos config.BidderInfos) map[string]string "lifestreet": `Bidder "lifestreet" is no longer available in Prebid Server. Please update your configuration.`, "adagio": `Bidder "adagio" is no longer available in Prebid Server. Please update your configuration.`, "somoaudience": `Bidder "somoaudience" is no longer available in Prebid Server. Please update your configuration.`, - "yssp": `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahooAdvertising" in your configuration.`, + "yssp": `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahooAds" in your configuration.`, "andbeyondmedia": `Bidder "andbeyondmedia" is no longer available in Prebid Server. If you're looking to use the AndBeyond.Media SSP adapter, please rename it to "beyondmedia" in your configuration.`, "oftmedia": `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`, "groupm": `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`, diff --git a/exchange/adapter_util_test.go b/exchange/adapter_util_test.go index 9d2a5c3cd5f..2dd0fd04ab7 100644 --- a/exchange/adapter_util_test.go +++ b/exchange/adapter_util_test.go @@ -210,7 +210,7 @@ func TestGetDisabledBiddersErrorMessages(t *testing.T) { "lifestreet": `Bidder "lifestreet" is no longer available in Prebid Server. Please update your configuration.`, "adagio": `Bidder "adagio" is no longer available in Prebid Server. Please update your configuration.`, "somoaudience": `Bidder "somoaudience" is no longer available in Prebid Server. Please update your configuration.`, - "yssp": `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahooAdvertising" in your configuration.`, + "yssp": `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahooAds" in your configuration.`, "andbeyondmedia": `Bidder "andbeyondmedia" is no longer available in Prebid Server. If you're looking to use the AndBeyond.Media SSP adapter, please rename it to "beyondmedia" in your configuration.`, "oftmedia": `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`, "groupm": `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`, @@ -224,7 +224,7 @@ func TestGetDisabledBiddersErrorMessages(t *testing.T) { "lifestreet": `Bidder "lifestreet" is no longer available in Prebid Server. Please update your configuration.`, "adagio": `Bidder "adagio" is no longer available in Prebid Server. Please update your configuration.`, "somoaudience": `Bidder "somoaudience" is no longer available in Prebid Server. Please update your configuration.`, - "yssp": `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahooAdvertising" in your configuration.`, + "yssp": `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahooAds" in your configuration.`, "andbeyondmedia": `Bidder "andbeyondmedia" is no longer available in Prebid Server. If you're looking to use the AndBeyond.Media SSP adapter, please rename it to "beyondmedia" in your configuration.`, "oftmedia": `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`, "groupm": `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`, @@ -238,7 +238,7 @@ func TestGetDisabledBiddersErrorMessages(t *testing.T) { "lifestreet": `Bidder "lifestreet" is no longer available in Prebid Server. Please update your configuration.`, "adagio": `Bidder "adagio" is no longer available in Prebid Server. Please update your configuration.`, "somoaudience": `Bidder "somoaudience" is no longer available in Prebid Server. Please update your configuration.`, - "yssp": `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahooAdvertising" in your configuration.`, + "yssp": `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahooAds" in your configuration.`, "appnexus": `Bidder "appnexus" has been disabled on this instance of Prebid Server. Please work with the PBS host to enable this bidder again.`, "andbeyondmedia": `Bidder "andbeyondmedia" is no longer available in Prebid Server. If you're looking to use the AndBeyond.Media SSP adapter, please rename it to "beyondmedia" in your configuration.`, "oftmedia": `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`, @@ -253,7 +253,7 @@ func TestGetDisabledBiddersErrorMessages(t *testing.T) { "lifestreet": `Bidder "lifestreet" is no longer available in Prebid Server. Please update your configuration.`, "adagio": `Bidder "adagio" is no longer available in Prebid Server. Please update your configuration.`, "somoaudience": `Bidder "somoaudience" is no longer available in Prebid Server. Please update your configuration.`, - "yssp": `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahooAdvertising" in your configuration.`, + "yssp": `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahooAds" in your configuration.`, "appnexus": `Bidder "appnexus" has been disabled on this instance of Prebid Server. Please work with the PBS host to enable this bidder again.`, "andbeyondmedia": `Bidder "andbeyondmedia" is no longer available in Prebid Server. If you're looking to use the AndBeyond.Media SSP adapter, please rename it to "beyondmedia" in your configuration.`, "oftmedia": `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index e6be30d7400..9906d12e1b8 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -270,6 +270,7 @@ const ( BidderVisx BidderName = "visx" BidderVrtcal BidderName = "vrtcal" BidderXeworks BidderName = "xeworks" + BidderYahooAds BidderName = "yahooAds" BidderYahooAdvertising BidderName = "yahooAdvertising" BidderYahooSSP BidderName = "yahoossp" BidderYeahmobi BidderName = "yeahmobi" @@ -467,6 +468,7 @@ func CoreBidderNames() []BidderName { BidderVisx, BidderVrtcal, BidderXeworks, + BidderYahooAds, BidderYahooAdvertising, BidderYahooSSP, BidderYeahmobi, diff --git a/openrtb_ext/bidders_validate_test.go b/openrtb_ext/bidders_validate_test.go index 530f260c761..87a8c96d6f8 100644 --- a/openrtb_ext/bidders_validate_test.go +++ b/openrtb_ext/bidders_validate_test.go @@ -50,7 +50,7 @@ func TestBidderUniquenessGatekeeping(t *testing.T) { // - Exclude duplicates of adapters for the same bidder, as it's unlikely a publisher will use both. var bidders []string for _, bidder := range CoreBidderNames() { - if bidder != BidderTripleliftNative && bidder != BidderAdkernelAdn && bidder != BidderFreewheelSSPOld { + if bidder != BidderTripleliftNative && bidder != BidderAdkernelAdn && bidder != BidderFreewheelSSPOld && bidder != BidderYahooAdvertising { bidders = append(bidders, string(bidder)) } } diff --git a/openrtb_ext/imp_yahooAds.go b/openrtb_ext/imp_yahooAds.go new file mode 100644 index 00000000000..36a4a0f618b --- /dev/null +++ b/openrtb_ext/imp_yahooAds.go @@ -0,0 +1,7 @@ +package openrtb_ext + +// ExtImpYahooAds defines the contract for bidrequest.imp[i].ext.prebid.bidder.yahooAds +type ExtImpYahooAds struct { + Dcn string `json:"dcn"` + Pos string `json:"pos"` +} diff --git a/static/bidder-info/yahooAds.yaml b/static/bidder-info/yahooAds.yaml new file mode 100644 index 00000000000..a2581387152 --- /dev/null +++ b/static/bidder-info/yahooAds.yaml @@ -0,0 +1,18 @@ +endpoint: "https://s2shb.ssp.yahoo.com/admax/bid/partners/PBS" +maintainer: + email: "hb-fe-tech@yahooinc.com" +gvlVendorID: 25 +capabilities: + app: + mediaTypes: + - banner + - video + site: + mediaTypes: + - banner + - video +userSync: + # yahooAds supports user syncing, but requires configuration by the host. contact this + # bidder directly at the email address in this file to ask about enabling user sync. + supports: + - redirect \ No newline at end of file diff --git a/static/bidder-params/yahooAds.json b/static/bidder-params/yahooAds.json new file mode 100644 index 00000000000..77e7107350c --- /dev/null +++ b/static/bidder-params/yahooAds.json @@ -0,0 +1,19 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "YahooAds Adapter Params", + "description": "A schema which validates params accepted by the YahooAds adapter", + "type": "object", + "properties": { + "dcn": { + "type": "string", + "minLength": 1, + "description": "Site ID provided by One Mobile" + }, + "pos": { + "type": "string", + "minLength": 1, + "description": "Placement ID" + } + }, + "required": ["dcn", "pos"] +} From c8ab53d3f1e699ea9a7722e49edf1478d007d016 Mon Sep 17 00:00:00 2001 From: ccorbo Date: Wed, 5 Jul 2023 10:26:09 -0400 Subject: [PATCH 006/268] IX: MultiImp Implementation (#2779) Co-authored-by: Chris Corbo Co-authored-by: Oronno Mamun --- adapters/ix/ix.go | 199 +++++++++------ adapters/ix/ix_test.go | 10 +- .../multi-imp-multi-size-requests.json | 211 ++++++++++++++++ ...-requests.json => multi-imp-requests.json} | 167 +++++++------ .../ix/ixtest/exemplary/multiple-siteIds.json | 224 +++++++++++++++++ .../exemplary/simple-banner-multi-size.json | 110 ++------ .../ix/ixtest/exemplary/structured-pod.json | 236 ++++++++++++++++++ .../multi-imp-requests-error.json | 189 ++++++++++++++ adapters/ix/ixtest/supplemental/sid.json | 184 ++++++++++++++ adapters/ix/params_test.go | 1 + openrtb_ext/imp_ix.go | 1 + static/bidder-info/mediafuse.yaml | 4 +- static/bidder-params/ix.json | 5 + 13 files changed, 1289 insertions(+), 252 deletions(-) create mode 100644 adapters/ix/ixtest/exemplary/multi-imp-multi-size-requests.json rename adapters/ix/ixtest/exemplary/{max-requests.json => multi-imp-requests.json} (69%) create mode 100644 adapters/ix/ixtest/exemplary/multiple-siteIds.json create mode 100644 adapters/ix/ixtest/exemplary/structured-pod.json create mode 100644 adapters/ix/ixtest/supplemental/multi-imp-requests-error.json create mode 100644 adapters/ix/ixtest/supplemental/sid.json diff --git a/adapters/ix/ix.go b/adapters/ix/ix.go index b17d913f42d..919f58da3b8 100644 --- a/adapters/ix/ix.go +++ b/adapters/ix/ix.go @@ -7,6 +7,7 @@ import ( "sort" "strings" + "github.com/golang/glog" "github.com/prebid/prebid-server/adapters" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" @@ -19,8 +20,7 @@ import ( ) type IxAdapter struct { - URI string - maxRequests int + URI string } type ExtRequest struct { @@ -30,108 +30,128 @@ type ExtRequest struct { } type IxDiag struct { - PbsV string `json:"pbsv,omitempty"` - PbjsV string `json:"pbjsv,omitempty"` + PbsV string `json:"pbsv,omitempty"` + PbjsV string `json:"pbjsv,omitempty"` + MultipleSiteIds string `json:"multipleSiteIds,omitempty"` } func (a *IxAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - nImp := len(request.Imp) - if nImp > a.maxRequests { - request.Imp = request.Imp[:a.maxRequests] - nImp = a.maxRequests - } - + requests := make([]*adapters.RequestData, 0, len(request.Imp)) errs := make([]error, 0) - if err := BuildIxDiag(request); err != nil { - errs = append(errs, err) - } - - // Multi-size banner imps are split into single-size requests. - // The first size imp requests are added to the first slice. - // Additional size requests are added to the second slice and are merged with the first at the end. - // Preallocate the max possible size to avoid reallocating arrays. - requests := make([]*adapters.RequestData, 0, a.maxRequests) - multiSizeRequests := make([]*adapters.RequestData, 0, a.maxRequests-nImp) - headers := http.Header{ "Content-Type": {"application/json;charset=utf-8"}, "Accept": {"application/json"}} - imps := request.Imp - for iImp := range imps { - request.Imp = imps[iImp : iImp+1] - if request.Site != nil { - if err := setSitePublisherId(request, iImp); err != nil { - errs = append(errs, err) - continue - } + uniqueSiteIDs := make(map[string]struct{}) + filteredImps := make([]openrtb2.Imp, 0, len(request.Imp)) + requestCopy := *request + + ixDiag := &IxDiag{} + + for _, imp := range requestCopy.Imp { + var err error + ixExt, err := unmarshalToIxExt(&imp) + + if err != nil { + errs = append(errs, err) + continue } - if request.Imp[0].Banner != nil { - banner := *request.Imp[0].Banner - request.Imp[0].Banner = &banner - formats := getBannerFormats(&banner) - for iFmt := range formats { - banner.Format = formats[iFmt : iFmt+1] - banner.W = openrtb2.Int64Ptr(banner.Format[0].W) - banner.H = openrtb2.Int64Ptr(banner.Format[0].H) - if requestData, err := createRequestData(a, request, &headers); err == nil { - if iFmt == 0 { - requests = append(requests, requestData) - } else { - multiSizeRequests = append(multiSizeRequests, requestData) - } - } else { - errs = append(errs, err) - } - if len(multiSizeRequests) == cap(multiSizeRequests) { - break - } + if err = parseSiteId(ixExt, uniqueSiteIDs); err != nil { + errs = append(errs, err) + continue + } + + if err := moveSid(&imp, ixExt); err != nil { + errs = append(errs, err) + } + + if imp.Banner != nil { + bannerCopy := *imp.Banner + + if len(bannerCopy.Format) == 0 && bannerCopy.W != nil && bannerCopy.H != nil { + bannerCopy.Format = []openrtb2.Format{{W: *bannerCopy.W, H: *bannerCopy.H}} } - } else if requestData, err := createRequestData(a, request, &headers); err == nil { + + if len(bannerCopy.Format) == 1 { + bannerCopy.W = openrtb2.Int64Ptr(bannerCopy.Format[0].W) + bannerCopy.H = openrtb2.Int64Ptr(bannerCopy.Format[0].H) + } + imp.Banner = &bannerCopy + } + filteredImps = append(filteredImps, imp) + } + requestCopy.Imp = filteredImps + + setSitePublisherId(&requestCopy, uniqueSiteIDs, ixDiag) + + err := setIxDiagIntoExtRequest(&requestCopy, ixDiag) + if err != nil { + errs = append(errs, err) + } + + if len(requestCopy.Imp) != 0 { + if requestData, err := createRequestData(a, &requestCopy, &headers); err == nil { requests = append(requests, requestData) } else { errs = append(errs, err) } } - request.Imp = imps - return append(requests, multiSizeRequests...), errs + return requests, errs } -func setSitePublisherId(request *openrtb2.BidRequest, iImp int) error { - if iImp == 0 { - // first impression - create a site and pub copy - site := *request.Site +func setSitePublisherId(requestCopy *openrtb2.BidRequest, uniqueSiteIDs map[string]struct{}, ixDiag *IxDiag) { + if requestCopy.Site != nil { + site := *requestCopy.Site if site.Publisher == nil { site.Publisher = &openrtb2.Publisher{} } else { publisher := *site.Publisher site.Publisher = &publisher } - request.Site = &site + + siteIDs := make([]string, 0, len(uniqueSiteIDs)) + for key := range uniqueSiteIDs { + siteIDs = append(siteIDs, key) + } + if len(siteIDs) == 1 { + site.Publisher.ID = siteIDs[0] + } + if len(siteIDs) > 1 { + // Sorting siteIDs for predictable output as Go maps don't guarantee order + sort.Strings(siteIDs) + multipleSiteIDs := strings.Join(siteIDs, ", ") + glog.Warningf("Multiple SiteIDs found. %s", multipleSiteIDs) + ixDiag.MultipleSiteIds = multipleSiteIDs + } + requestCopy.Site = &site } +} +func unmarshalToIxExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpIx, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(request.Imp[0].Ext, &bidderExt); err != nil { - return err + if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + return nil, err } var ixExt openrtb_ext.ExtImpIx if err := json.Unmarshal(bidderExt.Bidder, &ixExt); err != nil { - return err + return nil, err } - request.Site.Publisher.ID = ixExt.SiteId - return nil + return &ixExt, nil } -func getBannerFormats(banner *openrtb2.Banner) []openrtb2.Format { - if len(banner.Format) == 0 && banner.W != nil && banner.H != nil { - banner.Format = []openrtb2.Format{{W: *banner.W, H: *banner.H}} +func parseSiteId(ixExt *openrtb_ext.ExtImpIx, uniqueSiteIDs map[string]struct{}) error { + if ixExt == nil { + return fmt.Errorf("Nil Ix Ext") + } + if ixExt.SiteId != "" { + uniqueSiteIDs[ixExt.SiteId] = struct{}{} } - return banner.Format + return nil } func createRequestData(a *IxAdapter, request *openrtb2.BidRequest, headers *http.Header) (*adapters.RequestData, error) { @@ -180,7 +200,8 @@ func (a *IxAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalReque } } - bidderResponse := adapters.NewBidderResponseWithBidsCapacity(5) + // capacity 0 will make channel unbuffered + bidderResponse := adapters.NewBidderResponseWithBidsCapacity(0) bidderResponse.Currency = bidResponse.Cur var errs []error @@ -275,8 +296,7 @@ func getMediaTypeForBid(bid openrtb2.Bid, impMediaTypeReq map[string]openrtb_ext // Builder builds a new instance of the Ix adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { bidder := &IxAdapter{ - URI: config.Endpoint, - maxRequests: 20, + URI: config.Endpoint, } return bidder, nil } @@ -328,29 +348,33 @@ func marshalJsonWithoutUnicode(v interface{}) (string, error) { return strings.TrimSuffix(sb.String(), "\n"), nil } -func BuildIxDiag(request *openrtb2.BidRequest) error { +func setIxDiagIntoExtRequest(request *openrtb2.BidRequest, ixDiag *IxDiag) error { extRequest := &ExtRequest{} if request.Ext != nil { if err := json.Unmarshal(request.Ext, &extRequest); err != nil { return err } } - ixdiag := &IxDiag{} if extRequest.Prebid != nil && extRequest.Prebid.Channel != nil { - ixdiag.PbjsV = extRequest.Prebid.Channel.Version + ixDiag.PbjsV = extRequest.Prebid.Channel.Version } - // Slice commit hash out of version if strings.Contains(version.Ver, "-") { - ixdiag.PbsV = version.Ver[:strings.Index(version.Ver, "-")] + ixDiag.PbsV = version.Ver[:strings.Index(version.Ver, "-")] } else if version.Ver != "" { - ixdiag.PbsV = version.Ver + ixDiag.PbsV = version.Ver } // Only set request.ext if ixDiag is not empty - if *ixdiag != (IxDiag{}) { - extRequest.IxDiag = ixdiag + if *ixDiag != (IxDiag{}) { + extRequest := &ExtRequest{} + if request.Ext != nil { + if err := json.Unmarshal(request.Ext, &extRequest); err != nil { + return err + } + } + extRequest.IxDiag = ixDiag extRequestJson, err := json.Marshal(extRequest) if err != nil { return err @@ -359,3 +383,24 @@ func BuildIxDiag(request *openrtb2.BidRequest) error { } return nil } + +// moves sid from imp[].ext.bidder.sid to imp[].ext.sid +func moveSid(imp *openrtb2.Imp, ixExt *openrtb_ext.ExtImpIx) error { + if ixExt == nil { + return fmt.Errorf("Nil Ix Ext") + } + + if ixExt.Sid != "" { + var m map[string]interface{} + if err := json.Unmarshal(imp.Ext, &m); err != nil { + return err + } + m["sid"] = ixExt.Sid + ext, err := json.Marshal(m) + if err != nil { + return err + } + imp.Ext = ext + } + return nil +} diff --git a/adapters/ix/ix_test.go b/adapters/ix/ix_test.go index 0f6b856dce4..a64e3d0c661 100644 --- a/adapters/ix/ix_test.go +++ b/adapters/ix/ix_test.go @@ -19,8 +19,6 @@ const endpoint string = "http://host/endpoint" func TestJsonSamples(t *testing.T) { if bidder, err := Builder(openrtb_ext.BidderIx, config.Adapter{Endpoint: endpoint}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}); err == nil { - ixBidder := bidder.(*IxAdapter) - ixBidder.maxRequests = 2 adapterstest.RunJSONBidderTest(t, "ixtest", bidder) } else { t.Fatalf("Builder returned unexpected error %v", err) @@ -44,7 +42,7 @@ func TestIxMakeBidsWithCategoryDuration(t *testing.T) { `{ "prebid": {}, "bidder": { - "siteID": 123456 + "siteID": "123456" } }`, )}, @@ -106,7 +104,6 @@ func TestIxMakeBidsWithCategoryDuration(t *testing.T) { func TestIxMakeRequestWithGppString(t *testing.T) { bidder := &IxAdapter{} - bidder.maxRequests = 2 testGppString := "DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN" @@ -124,7 +121,7 @@ func TestIxMakeRequestWithGppString(t *testing.T) { `{ "prebid": {}, "bidder": { - "siteID": 123456 + "siteId": "123456" } }`, )}, @@ -256,7 +253,8 @@ func TestBuildIxDiag(t *testing.T) { for _, test := range testCases { t.Run(test.description, func(t *testing.T) { version.Ver = test.pbsVersion - err := BuildIxDiag(test.request) + ixDiag := &IxDiag{} + err := setIxDiagIntoExtRequest(test.request, ixDiag) if test.expectError { assert.NotNil(t, err) } else { diff --git a/adapters/ix/ixtest/exemplary/multi-imp-multi-size-requests.json b/adapters/ix/ixtest/exemplary/multi-imp-multi-size-requests.json new file mode 100644 index 00000000000..4decdaf985d --- /dev/null +++ b/adapters/ix/ixtest/exemplary/multi-imp-multi-size-requests.json @@ -0,0 +1,211 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } + }, + { + "id": "test-imp-id-2", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } + }, + { + "id": "test-imp-id-3", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } + } + ], + "site": { + "page": "https://www.example.com/" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://host/endpoint", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } + }, + { + "id": "test-imp-id-2", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } + }, + { + "id": "test-imp-id-3", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ], + "w": 300, + "h": 600 + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } + } + ], + "site": { + "page": "https://www.example.com/", + "publisher": { + "id": "569749" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id-1", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "https://advertiser.example.com" + ], + "cid": "958", + "crid": "29681110", + "h": 600, + "w": 300, + "ext": { + "ix": {} + } + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id-1", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": [ + "https://advertiser.example.com" + ], + "cid": "958", + "crid": "29681110", + "w": 300, + "h": 600, + "ext": { + "ix": {} + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/ix/ixtest/exemplary/max-requests.json b/adapters/ix/ixtest/exemplary/multi-imp-requests.json similarity index 69% rename from adapters/ix/ixtest/exemplary/max-requests.json rename to adapters/ix/ixtest/exemplary/multi-imp-requests.json index 46d9ec5d6b7..d8d00aeea69 100644 --- a/adapters/ix/ixtest/exemplary/max-requests.json +++ b/adapters/ix/ixtest/exemplary/multi-imp-requests.json @@ -9,10 +9,6 @@ { "w": 300, "h": 250 - }, - { - "w": 300, - "h": 600 } ] }, @@ -62,6 +58,38 @@ "siteId": "569749" } } + }, + { + "id": "test-imp-id-4", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } + }, + { + "id": "test-imp-id-5", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } } ] }, @@ -89,49 +117,7 @@ "siteId": "569749" } } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "958", - "bid": [ - { - "id": "7706636740145184841", - "impid": "test-imp-id-1", - "price": 0.5, - "adid": "29681110", - "adm": "some-test-ad", - "adomain": [ - "https://advertiser.example.com" - ], - "cid": "958", - "crid": "29681110", - "h": 250, - "w": 300, - "ext": { - "ix": {} - } - } - ] - } - ], - "bidid": "5778926625248726496", - "cur": "USD" - } - } - }, - { - "expectedRequest": { - "uri": "http://host/endpoint", - "body": { - "id": "test-request-id", - "imp": [ + }, { "id": "test-imp-id-2", "video": { @@ -156,6 +142,60 @@ "siteId": "569749" } } + }, + { + "banner": { + "format": [ + { + "h": 600, + "w": 300 + } + ], + "h": 600, + "w": 300 + }, + "ext": { + "bidder": { + "siteId": "569749" + } + }, + "id": "test-imp-id-3" + }, + { + "id": "test-imp-id-4", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } + }, + { + "id": "test-imp-id-5", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } } ] } @@ -170,7 +210,7 @@ "bid": [ { "id": "7706636740145184841", - "impid": "test-imp-id-2", + "impid": "test-imp-id-1", "price": 0.5, "adid": "29681110", "adm": "some-test-ad", @@ -181,9 +221,6 @@ "crid": "29681110", "h": 250, "w": 300, - "cat": [ - "IAB9-1" - ], "ext": { "ix": {} } @@ -222,34 +259,6 @@ "type": "banner" } ] - }, - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "7706636740145184841", - "impid": "test-imp-id-2", - "price": 0.5, - "adm": "some-test-ad", - "adid": "29681110", - "adomain": [ - "https://advertiser.example.com" - ], - "cid": "958", - "crid": "29681110", - "w": 300, - "h": 250, - "cat": [ - "IAB9-1" - ], - "ext": { - "ix": {} - } - }, - "type": "video" - } - ] } ] } diff --git a/adapters/ix/ixtest/exemplary/multiple-siteIds.json b/adapters/ix/ixtest/exemplary/multiple-siteIds.json new file mode 100644 index 00000000000..7f4227ac4b2 --- /dev/null +++ b/adapters/ix/ixtest/exemplary/multiple-siteIds.json @@ -0,0 +1,224 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } + }, + { + "id": "test-imp-id-2", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "siteId": "569750" + } + } + }, + { + "id": "test-imp-id-3", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "siteId": "569751" + } + } + } + ], + "site": { + "page": "https://www.example.com/" + }, + "ext": { + "prebid": { + "channel": { + "name": "web", + "version": "7.0.0" + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://host/endpoint", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } + }, + { + "id": "test-imp-id-2", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "siteId": "569750" + } + } + }, + { + "banner": { + "format": [ + { + "h": 600, + "w": 300 + } + ], + "h": 600, + "w": 300 + }, + "ext": { + "bidder": { + "siteId": "569751" + } + }, + "id": "test-imp-id-3" + } + ], + "site": { + "page": "https://www.example.com/", + "publisher": { + } + }, + "ext": { + "ixdiag": { + "multipleSiteIds": "569749, 569750, 569751", + "pbjsv": "7.0.0" + }, + "prebid": { + "channel": { + "name": "web", + "version": "7.0.0" + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id-1", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "https://advertiser.example.com" + ], + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": { + "ix": {} + } + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id-1", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": [ + "https://advertiser.example.com" + ], + "cid": "958", + "crid": "29681110", + "w": 300, + "h": 250, + "ext": { + "ix": {} + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/ix/ixtest/exemplary/simple-banner-multi-size.json b/adapters/ix/ixtest/exemplary/simple-banner-multi-size.json index 5e0a311a91b..15dc3ecbb0c 100644 --- a/adapters/ix/ixtest/exemplary/simple-banner-multi-size.json +++ b/adapters/ix/ixtest/exemplary/simple-banner-multi-size.json @@ -13,6 +13,10 @@ { "w": 300, "h": 600 + }, + { + "w": 600, + "h": 800 } ] }, @@ -22,7 +26,10 @@ } } } - ] + ], + "site": { + "page": "https://www.example.com/" + } }, "httpCalls": [ { @@ -38,70 +45,16 @@ { "w": 300, "h": 250 - } - ], - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "siteId": "569749" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "958", - "bid": [ - { - "id": "7706636740145184841", - "impid": "test-imp-id", - "price": 0.5, - "adid": "29681110", - "adm": "some-test-ad", - "adomain": [ - "https://advertiser.example.com" - ], - "cid": "958", - "crid": "29681110", - "h": 250, - "w": 300, - "ext": { - "ix": {} - } - } - ] - } - ], - "bidid": "5778926625248726496", - "cur": "USD" - } - } - }, - { - "expectedRequest": { - "uri": "http://host/endpoint", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ + }, { "w": 300, "h": 600 + }, + { + "w": 600, + "h": 800 } - ], - "w": 300, - "h": 600 + ] }, "ext": { "bidder": { @@ -109,7 +62,13 @@ } } } - ] + ], + "site": { + "page": "https://www.example.com/", + "publisher": { + "id": "569749" + } + } } }, "mockResponse": { @@ -131,7 +90,7 @@ ], "cid": "958", "crid": "29681110", - "h": 600, + "h": 250, "w": 300, "ext": { "ix": {} @@ -171,31 +130,6 @@ "type": "banner" } ] - }, - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "7706636740145184841", - "impid": "test-imp-id", - "price": 0.5, - "adm": "some-test-ad", - "adid": "29681110", - "adomain": [ - "https://advertiser.example.com" - ], - "cid": "958", - "crid": "29681110", - "w": 300, - "h": 600, - "ext": { - "ix": {} - } - }, - "type": "banner" - } - ] } ] } diff --git a/adapters/ix/ixtest/exemplary/structured-pod.json b/adapters/ix/ixtest/exemplary/structured-pod.json new file mode 100644 index 00000000000..a5ca9895554 --- /dev/null +++ b/adapters/ix/ixtest/exemplary/structured-pod.json @@ -0,0 +1,236 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id-1", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560, + "podid": "1", + "slotinpod": 1, + "podseq": 1 + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } + }, + { + "id": "test-imp-id-2", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560, + "podid": "1", + "slotinpod": -1, + "podseq": 1 + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://host/endpoint", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id-1", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560, + "podid": "1", + "slotinpod": 1, + "podseq": 1 + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } + }, + { + "id": "test-imp-id-2", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560, + "podid": "1", + "slotinpod": -1, + "podseq": 1 + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id-1", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "https://advertiser.example.com" + ], + "cid": "958", + "crid": "29681110", + "h": 560, + "w": 940, + "dur": 30, + "ext": { + "ix": {} + } + } + ] + }, + { + "seat": "958", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id-2", + "price": 0.75, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "https://advertiser.example.com" + ], + "cid": "958", + "crid": "29681110", + "h": 560, + "w": 940, + "dur": 30, + "ext": { + "ix": {} + } + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id-1", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": [ + "https://advertiser.example.com" + ], + "cid": "958", + "crid": "29681110", + "h": 560, + "w": 940, + "dur": 30, + "ext": { + "ix": {} + } + }, + "type": "video" + }, + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id-2", + "price": 0.75, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": [ + "https://advertiser.example.com" + ], + "cid": "958", + "crid": "29681110", + "h": 560, + "w": 940, + "dur": 30, + "ext": { + "ix": {} + } + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/ix/ixtest/supplemental/multi-imp-requests-error.json b/adapters/ix/ixtest/supplemental/multi-imp-requests-error.json new file mode 100644 index 00000000000..223e863284c --- /dev/null +++ b/adapters/ix/ixtest/supplemental/multi-imp-requests-error.json @@ -0,0 +1,189 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "siteId": "569749", + "sid": 12345 + } + } + }, + { + "id": "test-imp-id-2", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } + }, + { + "id": "test-imp-id-3", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://host/endpoint", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id-2", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } + }, + { + "id": "test-imp-id-3", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ], + "w": 300, + "h": 600 + }, + "ext": { + "bidder": { + "siteId": "569749" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id-1", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "https://advertiser.example.com" + ], + "cid": "958", + "crid": "29681110", + "h": 600, + "w": 300, + "ext": { + "ix": {} + } + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id-1", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": [ + "https://advertiser.example.com" + ], + "cid": "958", + "crid": "29681110", + "w": 300, + "h": 600, + "ext": { + "ix": {} + } + }, + "type": "banner" + } + ] + } + ], + "expectedMakeRequestsErrors": [ + { + "value": "json: cannot unmarshal number into Go struct field ExtImpIx.sid of type string", + "comparison": "literal" + } + ] +} diff --git a/adapters/ix/ixtest/supplemental/sid.json b/adapters/ix/ixtest/supplemental/sid.json new file mode 100644 index 00000000000..c2156b6b20d --- /dev/null +++ b/adapters/ix/ixtest/supplemental/sid.json @@ -0,0 +1,184 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id-1", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "siteId": "569749", + "sid": "1234" + } + } + }, + { + "id": "test-imp-id-2", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "siteId": "569750", + "sid": "5678" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://host/endpoint", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id-1", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "siteId": "569749", + "sid": "1234" + }, + "sid": "1234" + } + }, + { + "id": "test-imp-id-2", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "siteId": "569750", + "sid": "5678" + }, + "sid": "5678" + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id-1", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "https://advertiser.example.com" + ], + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": { + "ix": {} + } + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id-1", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": [ + "https://advertiser.example.com" + ], + "cid": "958", + "crid": "29681110", + "w": 300, + "h": 250, + "ext": { + "ix": {} + } + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/ix/params_test.go b/adapters/ix/params_test.go index 9246a43a725..8ba937c12f4 100644 --- a/adapters/ix/params_test.go +++ b/adapters/ix/params_test.go @@ -38,6 +38,7 @@ var validParams = []string{ `{"siteID":"12345"}`, `{"siteId":"123456"}`, `{"siteid":"1234567", "size": [640,480]}`, + `{"siteId":"123456", "sid":"12345"}`, } var invalidParams = []string{ diff --git a/openrtb_ext/imp_ix.go b/openrtb_ext/imp_ix.go index 9f977fb0dcd..40c3f51867f 100644 --- a/openrtb_ext/imp_ix.go +++ b/openrtb_ext/imp_ix.go @@ -4,4 +4,5 @@ package openrtb_ext type ExtImpIx struct { SiteId string `json:"siteId"` Size []int `json:"size"` + Sid string `json:"sid"` } diff --git a/static/bidder-info/mediafuse.yaml b/static/bidder-info/mediafuse.yaml index b78b21e16ea..be19cc6c68a 100644 --- a/static/bidder-info/mediafuse.yaml +++ b/static/bidder-info/mediafuse.yaml @@ -12,5 +12,5 @@ capabilities: - banner - video - native -userSync: - key: "adnxs" +# userSync: +# key: "adnxs" diff --git a/static/bidder-params/ix.json b/static/bidder-params/ix.json index a7a5cb7308a..172690cca32 100644 --- a/static/bidder-params/ix.json +++ b/static/bidder-params/ix.json @@ -27,6 +27,11 @@ "minItems": 2, "maxItems": 2, "description": "An array of two integer containing the dimension" + }, + "sid": { + "type": "string", + "minLength": 1, + "description": "Slot ID" } }, "oneOf": [ From e08433340e6ad7b96ca33f454eeed72478e7b801 Mon Sep 17 00:00:00 2001 From: Veronika Solovei Date: Wed, 5 Jul 2023 11:06:27 -0700 Subject: [PATCH 007/268] Exchange unit test fix (#2868) --- exchange/exchange_test.go | 4 ++-- exchange/utils_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go index 946a8587354..8306849a762 100644 --- a/exchange/exchange_test.go +++ b/exchange/exchange_test.go @@ -2085,7 +2085,7 @@ func getTestBuildRequest(t *testing.T) *openrtb2.BidRequest { H: 600, }}, }, - Ext: json.RawMessage(`{"ext_field":"value}"}`), + Ext: json.RawMessage(`{"prebid":{"bidder":{"appnexus": {"placementId": 1}}}}`), }, { Video: &openrtb2.Video{ MIMEs: []string{"video/mp4"}, @@ -2094,7 +2094,7 @@ func getTestBuildRequest(t *testing.T) *openrtb2.BidRequest { W: 300, H: 600, }, - Ext: json.RawMessage(`{"ext_field":"value}"}`), + Ext: json.RawMessage(`{"prebid":{"bidder":{"appnexus": {"placementId": 1}}}}`), }}, } } diff --git a/exchange/utils_test.go b/exchange/utils_test.go index 8bb82fe412f..d1b6622f910 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -505,7 +505,7 @@ func TestCleanOpenRTBRequestsWithFPD(t *testing.T) { App: &openrtb2.App{Name: "fpdApnApp"}, User: &openrtb2.User{Keywords: "fpdApnUser"}, } - fpd[openrtb_ext.BidderName("appnexus")] = &apnFpd + fpd[openrtb_ext.BidderName("rubicon")] = &apnFpd brightrollFpd := firstpartydata.ResolvedFirstPartyData{ Site: &openrtb2.Site{Name: "fpdBrightrollSite"}, From f1787d4a1da2dc632de7e4afaec9ff71734e146f Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Thu, 6 Jul 2023 13:02:52 +0530 Subject: [PATCH 008/268] Semgrep rules for adapters (#2833) --- .semgrep/adapter/builder-struct-name.go | 124 ++++++++++++++++ .semgrep/adapter/builder-struct-name.yml | 58 ++++++++ .semgrep/adapter/type-bid-assignment.go | 181 +++++++++++++++++++++++ .semgrep/adapter/type-bid-assignment.yml | 64 ++++++++ 4 files changed, 427 insertions(+) create mode 100644 .semgrep/adapter/builder-struct-name.go create mode 100644 .semgrep/adapter/builder-struct-name.yml create mode 100644 .semgrep/adapter/type-bid-assignment.go create mode 100644 .semgrep/adapter/type-bid-assignment.yml diff --git a/.semgrep/adapter/builder-struct-name.go b/.semgrep/adapter/builder-struct-name.go new file mode 100644 index 00000000000..37a938ca748 --- /dev/null +++ b/.semgrep/adapter/builder-struct-name.go @@ -0,0 +1,124 @@ +/* + builder-struct-name tests + https://semgrep.dev/docs/writing-rules/testing-rules + "ruleid" prefix in comment indicates patterns that should be flagged by semgrep + "ok" prefix in comment indidcates patterns that should not be flagged by the semgrep +*/ + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + foo1 := foo{} + // ruleid: builder-struct-name-check + return &fooadapter{foo: foo1}, nil +} + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + // ruleid: builder-struct-name-check + return &adapterbar{}, nil +} + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + // ruleid: builder-struct-name-check + return &fooadapterbar{}, nil +} + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + // ruleid: builder-struct-name-check + return &FooAdapter{}, nil +} + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + // ruleid: builder-struct-name-check + return &AdapterBar{}, nil +} + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + // ruleid: builder-struct-name-check + return &AdapterBar{}, nil +} + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + // ruleid: builder-struct-name-check + return &FooAdapterBar{}, nil +} + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + foo2 := foo{} + //ruleid: builder-struct-name-check + adpt1 := Adapter{foo: foo2} + return &adpt1, nil +} + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + //ruleid: builder-struct-name-check + builder := &Adapter{foo{}} + return builder, nil +} + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + foo3 := foo{} + if foo3.bar == "" { + foo3.bar = "bar" + } + //ruleid: builder-struct-name-check + adpt2 := Adapter{} + adpt2.foo = foo3 + return &adpt2, nil +} + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + //ruleid: builder-struct-name-check + return &foo{}, nil +} + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + //ruleid: builder-struct-name-check + var obj Adapter + obj.Foo = "foo" + if obj.Bar == "" { + obj.Bar = "bar" + } + return &obj, nil +} + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + //ruleid: builder-struct-name-check + var obj *FooAdapterBar + obj.Foo = "foo" + if obj.Bar == "" { + obj.Bar = "bar" + } + return obj, nil +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + // ok: builder-struct-name-check + return &adapter{endpoint: "www.foo.com"}, nil +} + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + builder := &adapter{} + builder.endpoint = "www.foo.com" + // ok: builder-struct-name-check + return builder, nil +} + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + builder := adapter{} + builder.endpoint = "www.foo.com" + // ok: builder-struct-name-check + return &builder, nil +} + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + var builder adapter + builder.endpoint = "www.foo.com" + // ok: builder-struct-name-check + return &builder, nil +} + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + var builder *adapter + builder.endpoint = "www.foo.com" + // ok: builder-struct-name-check + return builder, nil +} \ No newline at end of file diff --git a/.semgrep/adapter/builder-struct-name.yml b/.semgrep/adapter/builder-struct-name.yml new file mode 100644 index 00000000000..c80e8e12b52 --- /dev/null +++ b/.semgrep/adapter/builder-struct-name.yml @@ -0,0 +1,58 @@ +rules: + - id: builder-struct-name-check + languages: + - go + message: | + You can call this simply "adapter", the `$BUILDER` identification is already supplied by the package name. As you have it, referencing your adapter from outside the package would be `$BUILDER.$BUILDER` which looks a little redundant. See example below: + + ``` + package foo + + type adapter struct { + endpoint string + } + + func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + return &adapter{endpoint: "https://www.foo.com"}, nil + } + ``` + severity: WARNING + patterns: + - pattern-either: + - pattern-inside: > + func Builder($BIDDER_NAME openrtb_ext.BidderName, $CONFIG config.Adapter, $SERVER config.Server) (adapters.Bidder, error) { + ... + $BUILDER_OBJ := &$BUILDER{...} + ... + return $BUILDER_OBJ, nil + } + - pattern-inside: > + func Builder($BIDDER_NAME openrtb_ext.BidderName, $CONFIG config.Adapter, $SERVER config.Server) (adapters.Bidder, error) { + ... + $BUILDER_OBJ := $BUILDER{...} + ... + return &$BUILDER_OBJ, nil + } + - pattern-inside: > + func Builder($BIDDER_NAME openrtb_ext.BidderName, $CONFIG config.Adapter, $SERVER config.Server) (adapters.Bidder, error) { + ... + return &$BUILDER{...}, ... + } + - pattern-inside: > + func Builder($BIDDER_NAME openrtb_ext.BidderName, $CONFIG config.Adapter, $SERVER config.Server) (adapters.Bidder, error) { + ... + var $BUILDER_OBJ $BUILDER + ... + return &$BUILDER_OBJ, ... + } + - pattern-inside: > + func Builder($BIDDER_NAME openrtb_ext.BidderName, $CONFIG config.Adapter, $SERVER config.Server) (adapters.Bidder, error) { + ... + var $BUILDER_OBJ *$BUILDER + ... + return $BUILDER_OBJ, ... + } + - focus-metavariable: $BUILDER + - metavariable-regex: + metavariable: $BUILDER + regex: (?!adapter$) diff --git a/.semgrep/adapter/type-bid-assignment.go b/.semgrep/adapter/type-bid-assignment.go new file mode 100644 index 00000000000..fb29a4912d5 --- /dev/null +++ b/.semgrep/adapter/type-bid-assignment.go @@ -0,0 +1,181 @@ +/* + type-bid-assignment tests + https://semgrep.dev/docs/writing-rules/testing-rules + "ruleid" prefix in comment indicates patterns that should be flagged by semgrep + "ok" prefix in comment indidcates patterns that should not be flagged by the semgrep +*/ + +func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + var bidResp openrtb2.BidResponse + + if err := json.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{err} + } + + for _, seatBid := range bidResp.SeatBid { + for _, sb := range seatBid.Bid { + bidType, err := getMediaTypeForImp(seatBid.Bid[i], internalRequest.Imp) + if err != nil { + errs = append(errs, err) + } else { + b := &adapters.TypedBid{ + // ruleid: type-bid-assignment-check + Bid: &sb, + BidType: bidType, + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + } + } +} + +func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + var bidResp openrtb2.BidResponse + + if err := json.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{err} + } + + for _, seatBid := range bidResp.SeatBid { + for _, sb := range seatBid.Bid { + sbcopy := sb + bidType, err := getMediaTypeForImp(seatBid.Bid[i], internalRequest.Imp) + if err != nil { + errs = append(errs, err) + } else { + b := &adapters.TypedBid{ + // ok: type-bid-assignment-check + Bid: &sbcopy, + BidType: bidType, + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + } + } +} + +func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + var bidResp openrtb2.BidResponse + + if err := json.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{err} + } + + for _, seatBid := range bidResp.SeatBid { + for _, sb := range seatBid.Bid { + bidType, err := getMediaTypeForImp(seatBid.Bid[i], internalRequest.Imp) + if err != nil { + return nil, err + } + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + // ruleid: type-bid-assignment-check + Bid: &sb, + BidType: bidType, + }) + + } + } +} + +func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + var bidResp openrtb2.BidResponse + + if err := json.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{err} + } + + for _, seatBid := range bidResp.SeatBid { + for _, sb := range seatBid.Bid { + bidType, err := getMediaTypeForImp(seatBid.Bid[i], internalRequest.Imp) + if err != nil { + return nil, err + } + // ruleid: type-bid-assignment-check + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{Bid: &sb, BidType: bidType}) + } + } +} + +func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + var bidResp openrtb2.BidResponse + + if err := json.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{err} + } + + var errors []error + for _, seatBid := range bidResp.SeatBid { + for _, bid := range seatBid.Bid { + var t adapters.TypedBid + // ruleid: type-bid-assignment-check + t.Bid = &bid + bidResponse.Bids = append(bidResponse.Bids, &t) + } + } + return bidResponse, errors +} + +func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + var bidResp openrtb2.BidResponse + + if err := json.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{err} + } + + var errors []error + for _, seatBid := range bidResp.SeatBid { + for _, bid := range seatBid.Bid { + var t adapters.TypedBid + t = adapters.TypedBid{ + // ruleid: type-bid-assignment-check + Bid: &bid, + } + + bidResponse.Bids = append(bidResponse.Bids, &t) + } + } + return bidResponse, errors +} + +func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + var bidResp openrtb2.BidResponse + + if err := json.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{err} + } + + for _, seatBid := range bidResp.SeatBid { + for idx, _ := range seatBid.Bid { + bidType, err := getMediaTypeForImp(seatBid.Bid[i], internalRequest.Imp) + if err != nil { + errs = append(errs, err) + } else { + b := &adapters.TypedBid{ + // ok: type-bid-assignment-check + Bid: &seatBid.Bid[idx], + BidType: bidType, + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + } + } +} + +func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + var bidResp openrtb2.BidResponse + + if err := json.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{err} + } + + for _, seatBid := range bidResp.SeatBid { + for idx := range seatBid.Bid { + bidType, err := getMediaTypeForImp(seatBid.Bid[i], internalRequest.Imp) + if err != nil { + return nil, err + } + // ok: type-bid-assignment-check + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{Bid: &seatBid.Bid[idx], BidType: bidType}) + } + } +} diff --git a/.semgrep/adapter/type-bid-assignment.yml b/.semgrep/adapter/type-bid-assignment.yml new file mode 100644 index 00000000000..95fb6811227 --- /dev/null +++ b/.semgrep/adapter/type-bid-assignment.yml @@ -0,0 +1,64 @@ +rules: + - id: type-bid-assignment-check + languages: + - go + message: > + Found incorrect assignment made to $KEY. $BID variable receives a new value in each iteration of range loop. Assigning the address of $BID `(&$BID)` to $KEY will result in a pointer that always points to the same memory address with the value of the last iteration. + This can lead to unexpected behavior or incorrect results. Refer https://go.dev/play/p/9ZS1f-5h4qS + + Consider using an index variable in the seatBids.Bid loop as shown below + + ``` + for _, seatBid := range response.SeatBid { + for i := range seatBids.Bid { + ... + responseBid := &adapters.TypedBid{ + Bid: &seatBids.Bid[i], + ... + } + ... + ... + } + } + ``` + severity: ERROR + patterns: + - pattern-either: + - pattern: > + for _, $BID := range ... { + ... + ... := &adapters.TypedBid{ + $KEY: &$BID, + ... + } + ... + } + - pattern: > + for _, $BID := range ... { + ... + ... = adapters.TypedBid{ + $KEY: &$BID, + ... + } + ... + } + - pattern: > + for _, $BID := range ... { + ... + ... = append(..., &adapters.TypedBid{ + $KEY: &$BID, + ... + }) + ... + } + - pattern: > + for _, $BID := range ... { + var $TYPEBID_OBJ adapters.TypedBid + ... + $TYPEBID_OBJ.$KEY = &$BID + ... + } + - focus-metavariable: $KEY + - metavariable-regex: + metavariable: $KEY + regex: Bid From a3118ea5963ae37b7340f585ee49576c7c0ee1f3 Mon Sep 17 00:00:00 2001 From: Brian Sardo <1168933+bsardo@users.noreply.github.com> Date: Thu, 6 Jul 2023 16:27:20 -0400 Subject: [PATCH 009/268] IX: Remove glog statement (#2909) --- adapters/ix/ix.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/adapters/ix/ix.go b/adapters/ix/ix.go index 919f58da3b8..796fefbbff0 100644 --- a/adapters/ix/ix.go +++ b/adapters/ix/ix.go @@ -7,7 +7,6 @@ import ( "sort" "strings" - "github.com/golang/glog" "github.com/prebid/prebid-server/adapters" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" @@ -123,7 +122,6 @@ func setSitePublisherId(requestCopy *openrtb2.BidRequest, uniqueSiteIDs map[stri // Sorting siteIDs for predictable output as Go maps don't guarantee order sort.Strings(siteIDs) multipleSiteIDs := strings.Join(siteIDs, ", ") - glog.Warningf("Multiple SiteIDs found. %s", multipleSiteIDs) ixDiag.MultipleSiteIds = multipleSiteIDs } requestCopy.Site = &site From 23fffa11d0b832ed226a1ded70e3dcfd799c500f Mon Sep 17 00:00:00 2001 From: Veronika Solovei Date: Thu, 6 Jul 2023 14:59:33 -0700 Subject: [PATCH 010/268] Activities framework (#2844) --- config/account.go | 2 +- config/activity.go | 3 +- config/config.go | 4 + endpoints/openrtb2/amp_auction.go | 9 + endpoints/openrtb2/auction.go | 11 + exchange/exchange.go | 2 + exchange/utils.go | 9 + exchange/utils_test.go | 70 +++++ privacy/activity.go | 3 + privacy/enforcer.go | 247 +++++++++++++++-- privacy/enforcer_test.go | 427 +++++++++++++++++++++++++++++- privacy/policyenforcer.go | 45 ++++ privacy/policyenforcer_test.go | 18 ++ 13 files changed, 812 insertions(+), 38 deletions(-) create mode 100644 privacy/policyenforcer.go create mode 100644 privacy/policyenforcer_test.go diff --git a/config/account.go b/config/account.go index 8beff9b6569..020402114de 100644 --- a/config/account.go +++ b/config/account.go @@ -40,7 +40,7 @@ type Account struct { Validations Validations `mapstructure:"validations" json:"validations"` DefaultBidLimit int `mapstructure:"default_bid_limit" json:"default_bid_limit"` BidAdjustments *openrtb_ext.ExtRequestPrebidBidAdjustments `mapstructure:"bidadjustments" json:"bidadjustments"` - Privacy AccountPrivacy `mapstructure:"privacy" json:"privacy"` + Privacy *AccountPrivacy `mapstructure:"privacy" json:"privacy"` } // CookieSync represents the account-level defaults for the cookie sync endpoint. diff --git a/config/activity.go b/config/activity.go index 987cbe84a2d..5bddc7c6405 100644 --- a/config/activity.go +++ b/config/activity.go @@ -8,16 +8,17 @@ type AllowActivities struct { TransmitUserFPD Activity `mapstructure:"transmitUfpd" json:"transmitUfpd"` TransmitPreciseGeo Activity `mapstructure:"transmitPreciseGeo" json:"transmitPreciseGeo"` TransmitUniqueRequestIds Activity `mapstructure:"transmitUniqueRequestIds" json:"transmitUniqueRequestIds"` + TransmitTids Activity `mapstructure:"transmitTid" json:"transmitTid"` } type Activity struct { Default *bool `mapstructure:"default" json:"default"` Rules []ActivityRule `mapstructure:"rules" json:"rules"` - Allow bool `mapstructure:"allow" json:"allow"` } type ActivityRule struct { Condition ActivityCondition `mapstructure:"condition" json:"condition"` + Allow bool `mapstructure:"allow" json:"allow"` } type ActivityCondition struct { diff --git a/config/config.go b/config/config.go index ee18c746e88..543d1afd912 100644 --- a/config/config.go +++ b/config/config.go @@ -155,6 +155,10 @@ func (cfg *Configuration) validate(v *viper.Viper) []error { cfg.TmaxAdjustments.Enabled = false } + if cfg.AccountDefaults.Privacy != nil { + glog.Warning("account_defaults.Privacy has no effect as the feature is under development.") + } + errs = cfg.Experiment.validate(errs) errs = cfg.BidderInfos.validate(errs) return errs diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index 73f4842ae83..8d328b7c51a 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "github.com/prebid/prebid-server/privacy" "net/http" "net/url" "strings" @@ -222,6 +223,13 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h tcf2Config := gdpr.NewTCF2Config(deps.cfg.GDPR.TCF2, account.GDPR) + activities, activitiesErr := privacy.NewActivityControl(account.Privacy) + if activitiesErr != nil { + errL = append(errL, activitiesErr) + writeError(errL, w, &labels) + return + } + secGPC := r.Header.Get("Sec-GPC") auctionRequest := &exchange.AuctionRequest{ @@ -239,6 +247,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h HookExecutor: hookExecutor, QueryParams: r.URL.Query(), TCF2Config: tcf2Config, + Activities: activities, } auctionResponse, err := deps.ex.HoldAuction(ctx, auctionRequest, nil) diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 216bff6eaf5..3f01967a4c2 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "github.com/prebid/prebid-server/privacy" "io" "io/ioutil" "net/http" @@ -191,6 +192,15 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http tcf2Config := gdpr.NewTCF2Config(deps.cfg.GDPR.TCF2, account.GDPR) + activities, activitiesErr := privacy.NewActivityControl(account.Privacy) + if activitiesErr != nil { + errL = append(errL, activitiesErr) + if errortypes.ContainsFatalError(errL) { + writeError(errL, w, &labels) + return + } + } + ctx := context.Background() timeout := deps.cfg.AuctionTimeouts.LimitAuctionTimeout(time.Duration(req.TMax) * time.Millisecond) @@ -236,6 +246,7 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http PubID: labels.PubID, HookExecutor: hookExecutor, TCF2Config: tcf2Config, + Activities: activities, } auctionResponse, err := deps.ex.HoldAuction(ctx, auctionRequest, nil) ao.RequestWrapper = req diff --git a/exchange/exchange.go b/exchange/exchange.go index 24ca193f989..07dce45a185 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "github.com/prebid/prebid-server/privacy" "math/rand" "net/url" "runtime/debug" @@ -195,6 +196,7 @@ type AuctionRequest struct { GlobalPrivacyControlHeader string ImpExtInfoMap map[string]ImpExtInfo TCF2Config gdpr.TCF2ConfigReader + Activities privacy.ActivityControl // LegacyLabels is included here for temporary compatibility with cleanOpenRTBRequests // in HoldAuction until we get to factoring it away. Do not use for anything new. diff --git a/exchange/utils.go b/exchange/utils.go index d43a4182451..5b29fd6292f 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -150,6 +150,15 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, for _, bidderRequest := range allBidderRequests { bidRequestAllowed := true + // fetchBids activity + fetchBidsActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityFetchBids, + privacy.ScopedName{Scope: privacy.ScopeTypeBidder, Name: bidderRequest.BidderName.String()}) + if fetchBidsActivityAllowed == privacy.ActivityDeny { + // skip the call to a bidder if fetchBids activity is not allowed + // do not add this bidder to allowedBidderRequests + continue + } + // CCPA privacyEnforcement.CCPA = ccpaEnforcer.ShouldEnforce(bidderRequest.BidderName.String()) diff --git a/exchange/utils_test.go b/exchange/utils_test.go index d1b6622f910..973edc53355 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -17,6 +17,7 @@ import ( "github.com/prebid/prebid-server/gdpr" "github.com/prebid/prebid-server/metrics" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/privacy" "github.com/prebid/prebid-server/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -4273,3 +4274,72 @@ func TestGetMediaTypeForBid(t *testing.T) { }) } } + +func TemporarilyDisabledTestCleanOpenRTBRequestsActivitiesFetchBids(t *testing.T) { + testCases := []struct { + name string + req *openrtb2.BidRequest + componentName string + allow bool + expectedReqNumber int + }{ + { + name: "request_with_one_bidder_allowed", + req: newBidRequest(t), + componentName: "appnexus", + allow: true, + expectedReqNumber: 1, + }, + { + name: "request_with_one_bidder_not_allowed", + req: newBidRequest(t), + componentName: "appnexus", + allow: false, + expectedReqNumber: 0, + }, + } + + for _, test := range testCases { + privacyConfig := getDefaultActivityConfig(test.componentName, test.allow) + activities, err := privacy.NewActivityControl(privacyConfig) + assert.NoError(t, err, "") + auctionReq := AuctionRequest{ + BidRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: test.req}, + UserSyncs: &emptyUsersync{}, + Activities: activities, + } + + bidderToSyncerKey := map[string]string{} + reqSplitter := &requestSplitter{ + bidderToSyncerKey: bidderToSyncerKey, + me: &metrics.MetricsEngineMock{}, + hostSChainNode: nil, + bidderInfo: config.BidderInfos{}, + } + + t.Run(test.name, func(t *testing.T) { + bidderRequests, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, nil, gdpr.SignalNo) + assert.Empty(t, errs) + assert.Len(t, bidderRequests, test.expectedReqNumber) + }) + } +} + +func getDefaultActivityConfig(componentName string, allow bool) *config.AccountPrivacy { + return &config.AccountPrivacy{ + AllowActivities: config.AllowActivities{ + FetchBids: config.Activity{ + Default: ptrutil.ToPtr(true), + Rules: []config.ActivityRule{ + { + Allow: allow, + Condition: config.ActivityCondition{ + ComponentName: []string{componentName}, + ComponentType: []string{"bidder"}, + }, + }, + }, + }, + }, + } +} diff --git a/privacy/activity.go b/privacy/activity.go index 7cdef17590c..6ca48ae0b93 100644 --- a/privacy/activity.go +++ b/privacy/activity.go @@ -11,6 +11,7 @@ const ( ActivityTransmitUserFPD ActivityTransmitPreciseGeo ActivityTransmitUniqueRequestIds + ActivityTransmitTids ) func (a Activity) String() string { @@ -29,6 +30,8 @@ func (a Activity) String() string { return "transmitPreciseGeo" case ActivityTransmitUniqueRequestIds: return "transmitUniqueRequestIds" + case ActivityTransmitTids: + return "transmitTid" } return "" diff --git a/privacy/enforcer.go b/privacy/enforcer.go index 0d5ecad5309..d63cd8de31f 100644 --- a/privacy/enforcer.go +++ b/privacy/enforcer.go @@ -1,43 +1,236 @@ package privacy -// PolicyEnforcer determines if personally identifiable information (PII) should be removed or anonymized per the policy. -type PolicyEnforcer interface { - // CanEnforce returns true when policy information is specifically provided by the publisher. - CanEnforce() bool +import ( + "fmt" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" + "strings" +) - // ShouldEnforce returns true when the OpenRTB request should have personally identifiable - // information (PII) removed or anonymized per the policy. - ShouldEnforce(bidder string) bool +type ActivityResult int + +const ( + ActivityAbstain ActivityResult = iota + ActivityAllow + ActivityDeny +) + +const ( + ScopeTypeBidder = "bidder" + ScopeTypeAnalytics = "analytics" + ScopeTypeRTD = "rtd" // real time data + ScopeTypeUserID = "userid" + ScopeTypeGeneral = "general" +) + +type ActivityControl struct { + plans map[Activity]ActivityPlan } -// NilPolicyEnforcer implements the PolicyEnforcer interface but will always return false. -type NilPolicyEnforcer struct{} +func NewActivityControl(privacyConf *config.AccountPrivacy) (ActivityControl, error) { + ac := ActivityControl{} + var err error -// CanEnforce is hardcoded to always return false. -func (NilPolicyEnforcer) CanEnforce() bool { - return false + if privacyConf == nil { + return ac, err + } else { + //temporarily disable Activities if they are specified at the account level + return ac, &errortypes.Warning{Message: "account.Privacy has no effect as the feature is under development."} + } + + plans := make(map[Activity]ActivityPlan) + + plans[ActivitySyncUser], err = buildEnforcementPlan(privacyConf.AllowActivities.SyncUser) + if err != nil { + return ac, err + } + plans[ActivityFetchBids], err = buildEnforcementPlan(privacyConf.AllowActivities.FetchBids) + if err != nil { + return ac, err + } + plans[ActivityEnrichUserFPD], err = buildEnforcementPlan(privacyConf.AllowActivities.EnrichUserFPD) + if err != nil { + return ac, err + } + plans[ActivityReportAnalytics], err = buildEnforcementPlan(privacyConf.AllowActivities.ReportAnalytics) + if err != nil { + return ac, err + } + plans[ActivityTransmitUserFPD], err = buildEnforcementPlan(privacyConf.AllowActivities.TransmitUserFPD) + if err != nil { + return ac, err + } + plans[ActivityTransmitPreciseGeo], err = buildEnforcementPlan(privacyConf.AllowActivities.TransmitPreciseGeo) + if err != nil { + return ac, err + } + plans[ActivityTransmitUniqueRequestIds], err = buildEnforcementPlan(privacyConf.AllowActivities.TransmitUniqueRequestIds) + if err != nil { + return ac, err + } + plans[ActivityTransmitTids], err = buildEnforcementPlan(privacyConf.AllowActivities.TransmitTids) + if err != nil { + return ac, err + } + + ac.plans = plans + + return ac, nil +} + +func buildEnforcementPlan(activity config.Activity) (ActivityPlan, error) { + ef := ActivityPlan{} + rules, err := activityRulesToEnforcementRules(activity.Rules) + if err != nil { + return ef, err + } + ef.defaultResult = activityDefaultToDefaultResult(activity.Default) + ef.rules = rules + return ef, nil } -// ShouldEnforce is hardcoded to always return false. -func (NilPolicyEnforcer) ShouldEnforce(bidder string) bool { - return false +func activityRulesToEnforcementRules(rules []config.ActivityRule) ([]ActivityRule, error) { + enfRules := make([]ActivityRule, 0) + for _, r := range rules { + cmpName, err := conditionToRuleComponentName(r.Condition.ComponentName) + if err != nil { + return nil, err + } + er := ComponentEnforcementRule{ + allowed: r.Allow, + componentName: cmpName, + componentType: r.Condition.ComponentType, + } + enfRules = append(enfRules, er) + } + return enfRules, nil } -// EnabledPolicyEnforcer decorates a PolicyEnforcer with an enabled flag. -type EnabledPolicyEnforcer struct { - Enabled bool - PolicyEnforcer PolicyEnforcer +func conditionToRuleComponentName(conditions []string) ([]ScopedName, error) { + sn := make([]ScopedName, 0) + for _, condition := range conditions { + scope, err := NewScopedName(condition) + if err != nil { + return sn, err + } + sn = append(sn, scope) + } + return sn, nil } -// CanEnforce returns true when the PolicyEnforcer can enforce. -func (p EnabledPolicyEnforcer) CanEnforce() bool { - return p.PolicyEnforcer.CanEnforce() +func activityDefaultToDefaultResult(activityDefault *bool) ActivityResult { + if activityDefault == nil { + // if default is unspecified, the hardcoded default-default is true. + return ActivityAllow + } else if *activityDefault { + return ActivityAllow + } + return ActivityDeny } -// ShouldEnforce returns true when the enforcer is enabled the PolicyEnforcer allows enforcement. -func (p EnabledPolicyEnforcer) ShouldEnforce(bidder string) bool { - if p.Enabled { - return p.PolicyEnforcer.ShouldEnforce(bidder) +func (e ActivityControl) Allow(activity Activity, target ScopedName) ActivityResult { + plan, planDefined := e.plans[activity] + + if !planDefined { + return ActivityAbstain } - return false + + return plan.Allow(target) +} + +type ActivityPlan struct { + defaultResult ActivityResult + rules []ActivityRule +} + +func (p ActivityPlan) Allow(target ScopedName) ActivityResult { + for _, rule := range p.rules { + result := rule.Allow(target) + if result == ActivityDeny || result == ActivityAllow { + return result + } + } + return p.defaultResult +} + +type ActivityRule interface { + Allow(target ScopedName) ActivityResult +} + +type ComponentEnforcementRule struct { + componentName []ScopedName + componentType []string + // include gppSectionId from 3.5 + // include geo from 3.5 + allowed bool +} + +func (r ComponentEnforcementRule) Allow(target ScopedName) ActivityResult { + if len(r.componentName) == 0 && len(r.componentType) == 0 { + return ActivityAbstain + } + + nameClauseExists := len(r.componentName) > 0 + typeClauseExists := len(r.componentType) > 0 + + componentNameFound := false + for _, scope := range r.componentName { + if strings.EqualFold(scope.Scope, target.Scope) && + (scope.Name == "*" || strings.EqualFold(scope.Name, target.Name)) { + componentNameFound = true + break + } + } + + componentTypeFound := false + for _, componentType := range r.componentType { + if strings.EqualFold(componentType, target.Scope) { + componentTypeFound = true + break + } + } + // behavior if rule matches: can be either true=allow or false=deny. result is abstain if the rule doesn't match + matchFound := (componentNameFound || !nameClauseExists) && (componentTypeFound || !typeClauseExists) + if matchFound { + if r.allowed { + return ActivityAllow + } else { + return ActivityDeny + } + } + return ActivityAbstain +} + +type ScopedName struct { + Scope string + Name string +} + +func NewScopedName(condition string) (ScopedName, error) { + if condition == "" { + return ScopedName{}, fmt.Errorf("unable to parse empty condition") + } + var scope, name string + split := strings.Split(condition, ".") + if len(split) == 2 { + s := strings.ToLower(split[0]) + if s == ScopeTypeBidder || s == ScopeTypeAnalytics || s == ScopeTypeUserID { + scope = s + } else if strings.Contains(s, ScopeTypeRTD) { + scope = ScopeTypeRTD + } else { + scope = ScopeTypeGeneral + } + name = split[1] + } else if len(split) == 1 { + scope = ScopeTypeBidder + name = split[0] + } else { + return ScopedName{}, fmt.Errorf("unable to parse condition: %s", condition) + } + + return ScopedName{ + Scope: scope, + Name: name, + }, nil } diff --git a/privacy/enforcer_test.go b/privacy/enforcer_test.go index b0c4032c714..e87a9eb2bff 100644 --- a/privacy/enforcer_test.go +++ b/privacy/enforcer_test.go @@ -1,18 +1,427 @@ package privacy import ( - "testing" - + "errors" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/util/ptrutil" "github.com/stretchr/testify/assert" + "testing" ) -func TestNilEnforcerCanEnforce(t *testing.T) { - nilEnforcer := &NilPolicyEnforcer{} - assert.False(t, nilEnforcer.CanEnforce()) +func TemporarilyDisabledTestNewActivityControl(t *testing.T) { + + testCases := []struct { + name string + privacyConf *config.AccountPrivacy + activityControl ActivityControl + err error + }{ + { + name: "privacy_config_is_nil", + privacyConf: nil, + activityControl: ActivityControl{plans: nil}, + err: nil, + }, + { + name: "privacy_config_is_specified_and_correct", + privacyConf: &config.AccountPrivacy{ + AllowActivities: config.AllowActivities{ + SyncUser: getDefaultActivityConfig(), + FetchBids: getDefaultActivityConfig(), + EnrichUserFPD: getDefaultActivityConfig(), + ReportAnalytics: getDefaultActivityConfig(), + TransmitUserFPD: getDefaultActivityConfig(), + TransmitPreciseGeo: getDefaultActivityConfig(), + TransmitUniqueRequestIds: getDefaultActivityConfig(), + TransmitTids: getDefaultActivityConfig(), + }, + }, + activityControl: ActivityControl{plans: map[Activity]ActivityPlan{ + ActivitySyncUser: getDefaultActivityPlan(), + ActivityFetchBids: getDefaultActivityPlan(), + ActivityEnrichUserFPD: getDefaultActivityPlan(), + ActivityReportAnalytics: getDefaultActivityPlan(), + ActivityTransmitUserFPD: getDefaultActivityPlan(), + ActivityTransmitPreciseGeo: getDefaultActivityPlan(), + ActivityTransmitUniqueRequestIds: getDefaultActivityPlan(), + ActivityTransmitTids: getDefaultActivityPlan(), + }}, + err: nil, + }, + { + name: "privacy_config_is_specified_and_SyncUser_is_incorrect", + privacyConf: &config.AccountPrivacy{ + AllowActivities: config.AllowActivities{ + SyncUser: getIncorrectActivityConfig(), + }, + }, + activityControl: ActivityControl{plans: nil}, + err: errors.New("unable to parse condition: bidder.bidderA.bidderB"), + }, + { + name: "privacy_config_is_specified_and_FetchBids_is_incorrect", + privacyConf: &config.AccountPrivacy{ + AllowActivities: config.AllowActivities{ + FetchBids: getIncorrectActivityConfig(), + }, + }, + activityControl: ActivityControl{plans: nil}, + err: errors.New("unable to parse condition: bidder.bidderA.bidderB"), + }, + { + name: "privacy_config_is_specified_and_EnrichUserFPD_is_incorrect", + privacyConf: &config.AccountPrivacy{ + AllowActivities: config.AllowActivities{ + EnrichUserFPD: getIncorrectActivityConfig(), + }, + }, + activityControl: ActivityControl{plans: nil}, + err: errors.New("unable to parse condition: bidder.bidderA.bidderB"), + }, + { + name: "privacy_config_is_specified_and_ReportAnalytics_is_incorrect", + privacyConf: &config.AccountPrivacy{ + AllowActivities: config.AllowActivities{ + ReportAnalytics: getIncorrectActivityConfig(), + }, + }, + activityControl: ActivityControl{plans: nil}, + err: errors.New("unable to parse condition: bidder.bidderA.bidderB"), + }, + { + name: "privacy_config_is_specified_and_TransmitUserFPD_is_incorrect", + privacyConf: &config.AccountPrivacy{ + AllowActivities: config.AllowActivities{ + TransmitUserFPD: getIncorrectActivityConfig(), + }, + }, + activityControl: ActivityControl{plans: nil}, + err: errors.New("unable to parse condition: bidder.bidderA.bidderB"), + }, + { + name: "privacy_config_is_specified_and_TransmitPreciseGeo_is_incorrect", + privacyConf: &config.AccountPrivacy{ + AllowActivities: config.AllowActivities{ + TransmitPreciseGeo: getIncorrectActivityConfig(), + }, + }, + activityControl: ActivityControl{plans: nil}, + err: errors.New("unable to parse condition: bidder.bidderA.bidderB"), + }, + { + name: "privacy_config_is_specified_and_TransmitUniqueRequestIds_is_incorrect", + privacyConf: &config.AccountPrivacy{ + AllowActivities: config.AllowActivities{ + TransmitUniqueRequestIds: getIncorrectActivityConfig(), + }, + }, + activityControl: ActivityControl{plans: nil}, + err: errors.New("unable to parse condition: bidder.bidderA.bidderB"), + }, + { + name: "privacy_config_is_specified_and_TransmitTids_is_incorrect", + privacyConf: &config.AccountPrivacy{ + AllowActivities: config.AllowActivities{ + TransmitTids: getIncorrectActivityConfig(), + }, + }, + activityControl: ActivityControl{plans: nil}, + err: errors.New("unable to parse condition: bidder.bidderA.bidderB"), + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + actualAC, actualErr := NewActivityControl(test.privacyConf) + if test.err == nil { + assert.Equal(t, test.activityControl, actualAC) + assert.NoError(t, actualErr) + } else { + assert.EqualError(t, actualErr, test.err.Error()) + } + }) + } +} + +func TestActivityDefaultToDefaultResult(t *testing.T) { + + testCases := []struct { + name string + activityDefault *bool + expectedResult ActivityResult + }{ + { + name: "activityDefault_is_nil", + activityDefault: nil, + expectedResult: ActivityAllow, + }, + { + name: "activityDefault_is_true", + activityDefault: ptrutil.ToPtr(true), + expectedResult: ActivityAllow, + }, + { + name: "activityDefault_is_false", + activityDefault: ptrutil.ToPtr(false), + expectedResult: ActivityDeny, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + actualResult := activityDefaultToDefaultResult(test.activityDefault) + assert.Equal(t, test.expectedResult, actualResult) + }) + } +} + +func TestAllowActivityControl(t *testing.T) { + + testCases := []struct { + name string + activityControl ActivityControl + activity Activity + target ScopedName + activityResult ActivityResult + }{ + { + name: "plans_is_nil", + activityControl: ActivityControl{plans: nil}, + activity: ActivityFetchBids, + target: ScopedName{Scope: "bidder", Name: "bidderA"}, + activityResult: ActivityAbstain, + }, + { + name: "activity_not_defined", + activityControl: ActivityControl{plans: map[Activity]ActivityPlan{ + ActivitySyncUser: getDefaultActivityPlan()}}, + activity: ActivityFetchBids, + target: ScopedName{Scope: "bidder", Name: "bidderA"}, + activityResult: ActivityAbstain, + }, + { + name: "activity_defined_but_not_found_default_returned", + activityControl: ActivityControl{plans: map[Activity]ActivityPlan{ + ActivityFetchBids: getDefaultActivityPlan()}}, + activity: ActivityFetchBids, + target: ScopedName{Scope: "bidder", Name: "bidderB"}, + activityResult: ActivityAllow, + }, + { + name: "activity_defined_and_allowed", + activityControl: ActivityControl{plans: map[Activity]ActivityPlan{ + ActivityFetchBids: getDefaultActivityPlan()}}, + activity: ActivityFetchBids, + target: ScopedName{Scope: "bidder", Name: "bidderA"}, + activityResult: ActivityAllow, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + actualResult := test.activityControl.Allow(test.activity, test.target) + assert.Equal(t, test.activityResult, actualResult) + + }) + } +} + +func TestAllowComponentEnforcementRule(t *testing.T) { + + testCases := []struct { + name string + componentRule ComponentEnforcementRule + target ScopedName + activityResult ActivityResult + }{ + { + name: "activity_is_allowed", + componentRule: ComponentEnforcementRule{ + allowed: true, + componentName: []ScopedName{ + {Scope: "bidder", Name: "bidderA"}, + }, + componentType: []string{"bidder"}, + }, + target: ScopedName{Scope: "bidder", Name: "bidderA"}, + activityResult: ActivityAllow, + }, + { + name: "activity_is_not_allowed", + componentRule: ComponentEnforcementRule{ + allowed: false, + componentName: []ScopedName{ + {Scope: "bidder", Name: "bidderA"}, + }, + componentType: []string{"bidder"}, + }, + target: ScopedName{Scope: "bidder", Name: "bidderA"}, + activityResult: ActivityDeny, + }, + { + name: "abstain_both_clauses_do_not_match", + componentRule: ComponentEnforcementRule{ + allowed: true, + componentName: []ScopedName{ + {Scope: "bidder", Name: "bidderA"}, + }, + componentType: []string{"bidder"}, + }, + target: ScopedName{Scope: "bidder", Name: "bidderB"}, + activityResult: ActivityAbstain, + }, + { + name: "activity_is_not_allowed_componentName_only", + componentRule: ComponentEnforcementRule{ + allowed: true, + componentName: []ScopedName{ + {Scope: "bidder", Name: "bidderA"}, + }, + }, + target: ScopedName{Scope: "bidder", Name: "bidderA"}, + activityResult: ActivityAllow, + }, + { + name: "activity_is_allowed_componentType_only", + componentRule: ComponentEnforcementRule{ + allowed: true, + componentType: []string{"bidder"}, + }, + target: ScopedName{Scope: "bidder", Name: "bidderB"}, + activityResult: ActivityAllow, + }, + { + name: "abstain_activity_no_componentType_and_no_componentName", + componentRule: ComponentEnforcementRule{ + allowed: true, + }, + target: ScopedName{Scope: "bidder", Name: "bidderB"}, + activityResult: ActivityAbstain, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + actualResult := test.componentRule.Allow(test.target) + assert.Equal(t, test.activityResult, actualResult) + + }) + } +} + +func TestNewScopedName(t *testing.T) { + + testCases := []struct { + name string + condition string + expectedScopeName ScopedName + err error + }{ + { + name: "condition_is_empty", + condition: "", + expectedScopeName: ScopedName{}, + err: errors.New("unable to parse empty condition"), + }, + { + name: "condition_is_incorrect", + condition: "bidder.bidderA.bidderB", + expectedScopeName: ScopedName{}, + err: errors.New("unable to parse condition: bidder.bidderA.bidderB"), + }, + { + name: "condition_is_scoped_to_bidder", + condition: "bidder.bidderA", + expectedScopeName: ScopedName{Scope: "bidder", Name: "bidderA"}, + err: nil, + }, + { + name: "condition_is_scoped_to_analytics", + condition: "analytics.bidderA", + expectedScopeName: ScopedName{Scope: "analytics", Name: "bidderA"}, + err: nil, + }, + { + name: "condition_is_scoped_to_userid", + condition: "userid.bidderA", + expectedScopeName: ScopedName{Scope: "userid", Name: "bidderA"}, + err: nil, + }, + { + name: "condition_is_bidder_name", + condition: "bidderA", + expectedScopeName: ScopedName{Scope: "bidder", Name: "bidderA"}, + err: nil, + }, + { + name: "condition_is_module_tag_rtd", + condition: "rtd.test", + expectedScopeName: ScopedName{Scope: "rtd", Name: "test"}, + err: nil, + }, + { + name: "condition_scope_defaults_to_genera", + condition: "test.test", + expectedScopeName: ScopedName{Scope: "general", Name: "test"}, + err: nil, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + actualSN, actualErr := NewScopedName(test.condition) + if test.err == nil { + assert.Equal(t, test.expectedScopeName, actualSN) + assert.NoError(t, actualErr) + } else { + assert.EqualError(t, actualErr, test.err.Error()) + } + }) + } +} + +// constants +func getDefaultActivityConfig() config.Activity { + return config.Activity{ + Default: ptrutil.ToPtr(true), + Rules: []config.ActivityRule{ + { + Allow: true, + Condition: config.ActivityCondition{ + ComponentName: []string{"bidderA"}, + ComponentType: []string{"bidder"}, + }, + }, + }, + } +} + +func getDefaultActivityPlan() ActivityPlan { + return ActivityPlan{ + defaultResult: ActivityAllow, + rules: []ActivityRule{ + ComponentEnforcementRule{ + allowed: true, + componentName: []ScopedName{ + {Scope: "bidder", Name: "bidderA"}, + }, + componentType: []string{"bidder"}, + }, + }, + } } -func TestNilEnforcerShouldEnforce(t *testing.T) { - nilEnforcer := &NilPolicyEnforcer{} - assert.False(t, nilEnforcer.ShouldEnforce("")) - assert.False(t, nilEnforcer.ShouldEnforce("anyBidder")) +func getIncorrectActivityConfig() config.Activity { + return config.Activity{ + Default: ptrutil.ToPtr(true), + Rules: []config.ActivityRule{ + { + Allow: true, + Condition: config.ActivityCondition{ + ComponentName: []string{"bidder.bidderA.bidderB"}, + ComponentType: []string{"bidder"}, + }, + }, + }, + } } diff --git a/privacy/policyenforcer.go b/privacy/policyenforcer.go new file mode 100644 index 00000000000..e70c0d3d190 --- /dev/null +++ b/privacy/policyenforcer.go @@ -0,0 +1,45 @@ +package privacy + +// NOTE: Reanme this package. Will eventually replace in its entirety with Activites. + +// PolicyEnforcer determines if personally identifiable information (PII) should be removed or anonymized per the policy. +type PolicyEnforcer interface { + // CanEnforce returns true when policy information is specifically provided by the publisher. + CanEnforce() bool + + // ShouldEnforce returns true when the OpenRTB request should have personally identifiable + // information (PII) removed or anonymized per the policy. + ShouldEnforce(bidder string) bool +} + +// NilPolicyEnforcer implements the PolicyEnforcer interface but will always return false. +type NilPolicyEnforcer struct{} + +// CanEnforce is hardcoded to always return false. +func (NilPolicyEnforcer) CanEnforce() bool { + return false +} + +// ShouldEnforce is hardcoded to always return false. +func (NilPolicyEnforcer) ShouldEnforce(bidder string) bool { + return false +} + +// EnabledPolicyEnforcer decorates a PolicyEnforcer with an enabled flag. +type EnabledPolicyEnforcer struct { + Enabled bool + PolicyEnforcer PolicyEnforcer +} + +// CanEnforce returns true when the PolicyEnforcer can enforce. +func (p EnabledPolicyEnforcer) CanEnforce() bool { + return p.PolicyEnforcer.CanEnforce() +} + +// ShouldEnforce returns true when the enforcer is enabled the PolicyEnforcer allows enforcement. +func (p EnabledPolicyEnforcer) ShouldEnforce(bidder string) bool { + if p.Enabled { + return p.PolicyEnforcer.ShouldEnforce(bidder) + } + return false +} diff --git a/privacy/policyenforcer_test.go b/privacy/policyenforcer_test.go new file mode 100644 index 00000000000..b0c4032c714 --- /dev/null +++ b/privacy/policyenforcer_test.go @@ -0,0 +1,18 @@ +package privacy + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNilEnforcerCanEnforce(t *testing.T) { + nilEnforcer := &NilPolicyEnforcer{} + assert.False(t, nilEnforcer.CanEnforce()) +} + +func TestNilEnforcerShouldEnforce(t *testing.T) { + nilEnforcer := &NilPolicyEnforcer{} + assert.False(t, nilEnforcer.ShouldEnforce("")) + assert.False(t, nilEnforcer.ShouldEnforce("anyBidder")) +} From ae0bb200b8f4f3756903b94373c33a781d5f3a36 Mon Sep 17 00:00:00 2001 From: Stephen Johnston Date: Fri, 7 Jul 2023 05:57:24 -0400 Subject: [PATCH 011/268] PWBID: Update Default Endpoint (#2903) --- adapters/pwbid/pwbid_test.go | 2 +- adapters/pwbid/pwbidtest/exemplary/banner.json | 4 ++-- adapters/pwbid/pwbidtest/exemplary/native.json | 4 ++-- adapters/pwbid/pwbidtest/exemplary/optional-params.json | 4 ++-- adapters/pwbid/pwbidtest/exemplary/video.json | 2 +- .../pwbidtest/supplemental/response-200-without-body.json | 2 +- adapters/pwbid/pwbidtest/supplemental/response-204.json | 2 +- adapters/pwbid/pwbidtest/supplemental/response-400.json | 2 +- adapters/pwbid/pwbidtest/supplemental/response-500.json | 2 +- static/bidder-info/pwbid.yaml | 4 ++-- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/adapters/pwbid/pwbid_test.go b/adapters/pwbid/pwbid_test.go index 21a4194249e..194e4bdea02 100644 --- a/adapters/pwbid/pwbid_test.go +++ b/adapters/pwbid/pwbid_test.go @@ -10,7 +10,7 @@ import ( func TestJsonSamples(t *testing.T) { bidder, buildErr := Builder(openrtb_ext.BidderPWBid, config.Adapter{ - Endpoint: "https://bid.pubwise.io/prebid"}, + Endpoint: "https://bidder.east2.pubwise.io/bid/pubwisedirect"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 842, DataCenter: "2"}) if buildErr != nil { diff --git a/adapters/pwbid/pwbidtest/exemplary/banner.json b/adapters/pwbid/pwbidtest/exemplary/banner.json index ba618cb8cf1..4cf93e1ab76 100644 --- a/adapters/pwbid/pwbidtest/exemplary/banner.json +++ b/adapters/pwbid/pwbidtest/exemplary/banner.json @@ -23,7 +23,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bid.pubwise.io/prebid", + "uri": "https://bidder.east2.pubwise.io/bid/pubwisedirect", "body": { "id": "test-request-id-banner", "imp": [ @@ -90,4 +90,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/adapters/pwbid/pwbidtest/exemplary/native.json b/adapters/pwbid/pwbidtest/exemplary/native.json index 907c16d467a..ff57752c5ea 100644 --- a/adapters/pwbid/pwbidtest/exemplary/native.json +++ b/adapters/pwbid/pwbidtest/exemplary/native.json @@ -18,7 +18,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bid.pubwise.io/prebid", + "uri": "https://bidder.east2.pubwise.io/bid/pubwisedirect", "body": { "id": "test-request-id-native", "imp": [ @@ -78,4 +78,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/adapters/pwbid/pwbidtest/exemplary/optional-params.json b/adapters/pwbid/pwbidtest/exemplary/optional-params.json index a080be90208..5ababb24bdc 100644 --- a/adapters/pwbid/pwbidtest/exemplary/optional-params.json +++ b/adapters/pwbid/pwbidtest/exemplary/optional-params.json @@ -25,7 +25,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bid.pubwise.io/prebid", + "uri": "https://bidder.east2.pubwise.io/bid/pubwisedirect", "body": { "id": "test-request-id-banner", "imp": [ @@ -94,4 +94,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/adapters/pwbid/pwbidtest/exemplary/video.json b/adapters/pwbid/pwbidtest/exemplary/video.json index b74c780d0a9..6257de632d4 100644 --- a/adapters/pwbid/pwbidtest/exemplary/video.json +++ b/adapters/pwbid/pwbidtest/exemplary/video.json @@ -20,7 +20,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bid.pubwise.io/prebid", + "uri": "https://bidder.east2.pubwise.io/bid/pubwisedirect", "body": { "id": "test-request-id", "imp": [ diff --git a/adapters/pwbid/pwbidtest/supplemental/response-200-without-body.json b/adapters/pwbid/pwbidtest/supplemental/response-200-without-body.json index 146ba93a27d..0d469893e0c 100644 --- a/adapters/pwbid/pwbidtest/supplemental/response-200-without-body.json +++ b/adapters/pwbid/pwbidtest/supplemental/response-200-without-body.json @@ -19,7 +19,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bid.pubwise.io/prebid", + "uri": "https://bidder.east2.pubwise.io/bid/pubwisedirect", "body": { "id": "test-request-id", "imp": [ diff --git a/adapters/pwbid/pwbidtest/supplemental/response-204.json b/adapters/pwbid/pwbidtest/supplemental/response-204.json index 5fff7ee32cc..4fc8961e0bb 100644 --- a/adapters/pwbid/pwbidtest/supplemental/response-204.json +++ b/adapters/pwbid/pwbidtest/supplemental/response-204.json @@ -19,7 +19,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bid.pubwise.io/prebid", + "uri": "https://bidder.east2.pubwise.io/bid/pubwisedirect", "body": { "id": "test-request-id", "imp": [ diff --git a/adapters/pwbid/pwbidtest/supplemental/response-400.json b/adapters/pwbid/pwbidtest/supplemental/response-400.json index d594e571243..a1517883243 100644 --- a/adapters/pwbid/pwbidtest/supplemental/response-400.json +++ b/adapters/pwbid/pwbidtest/supplemental/response-400.json @@ -19,7 +19,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bid.pubwise.io/prebid", + "uri": "https://bidder.east2.pubwise.io/bid/pubwisedirect", "body": { "id": "test-request-id", "imp": [ diff --git a/adapters/pwbid/pwbidtest/supplemental/response-500.json b/adapters/pwbid/pwbidtest/supplemental/response-500.json index fa3d4d063a8..c2b5649418b 100644 --- a/adapters/pwbid/pwbidtest/supplemental/response-500.json +++ b/adapters/pwbid/pwbidtest/supplemental/response-500.json @@ -19,7 +19,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bid.pubwise.io/prebid", + "uri": "https://bidder.east2.pubwise.io/bid/pubwisedirect", "body": { "id": "test-request-id", "imp": [ diff --git a/static/bidder-info/pwbid.yaml b/static/bidder-info/pwbid.yaml index ac6872738b4..a172ff39c83 100644 --- a/static/bidder-info/pwbid.yaml +++ b/static/bidder-info/pwbid.yaml @@ -1,4 +1,4 @@ -endpoint: "https://bid.pubwise.io/prebid" +endpoint: "https://bidder.east2.pubwise.io/bid/pubwisedirect" maintainer: email: info@pubwise.io gvlVendorID: 842 @@ -17,4 +17,4 @@ userSync: # PubWise supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. supports: - - redirect \ No newline at end of file + - redirect From a39f5ca6a19304e4388af058f3f2b4e28ae35ac3 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Mon, 10 Jul 2023 14:47:49 +0530 Subject: [PATCH 012/268] script to run semgrep tests against adapter PRs (#2907) authored by @onkarvhanumante --- .../workflows/helpers/pull-request-utils.js | 337 ++++++++++++++++++ .github/workflows/semgrep.yml | 74 ++++ .semgrep/adapter/builder-struct-name.yml | 2 +- 3 files changed, 412 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/helpers/pull-request-utils.js create mode 100644 .github/workflows/semgrep.yml diff --git a/.github/workflows/helpers/pull-request-utils.js b/.github/workflows/helpers/pull-request-utils.js new file mode 100644 index 00000000000..64ea538290f --- /dev/null +++ b/.github/workflows/helpers/pull-request-utils.js @@ -0,0 +1,337 @@ +const synchronizeEvent = "synchronize", + openedEvent = "opened", + completedStatus = "completed", + resultSize = 100 + +class diffHelper { + constructor(input) { + this.owner = input.context.repo.owner + this.repo = input.context.repo.repo + this.github = input.github + this.pullRequestNumber = input.context.payload.pull_request.number + this.pullRequestEvent = input.event + this.testName = input.testName + this.fileNameFilter = !input.fileNameFilter ? () => true : input.fileNameFilter + this.fileLineFilter = !input.fileLineFilter ? () => true : input.fileLineFilter + } + + /* + Checks whether the test defined by this.testName has been executed on the given commit + @param {string} commit - commit SHA to check for test execution + @returns {boolean} - returns true if the test has been executed on the commit, otherwise false + */ + async #isTestExecutedOnCommit(commit) { + const response = await this.github.rest.checks.listForRef({ + owner: this.owner, + repo: this.repo, + ref: commit, + }) + + return response.data.check_runs.some( + ({ status, name }) => status === completedStatus && name === this.testName + ) + } + + /* + Retrieves the line numbers of added or updated lines in the provided files + @param {Array} files - array of files containing their filename and patch + @returns {Object} - object mapping filenames to arrays of line numbers indicating the added or updated lines + */ + async #getDiffForFiles(files = []) { + let diff = {} + for (const { filename, patch } of files) { + if (this.fileNameFilter(filename)) { + const lines = patch.split("\n") + if (lines.length === 1) { + continue + } + + let lineNumber + for (const line of lines) { + // Check if line is diff header + // example: + // @@ -1,3 +1,3 @@ + // 1 var a + // 2 + // 3 - //test + // 3 +var b + // Here @@ -1,3 +1,3 @@ is diff header + if (line.match(/@@\s.*?@@/) != null) { + lineNumber = parseInt(line.match(/\+(\d+)/)[0]) + continue + } + + // "-" prefix indicates line was deleted. So do not consider deleted line + if (line.startsWith("-")) { + continue + } + + // "+"" prefix indicates line was added or updated. Include line number in diff details + if (line.startsWith("+") && this.fileLineFilter(line)) { + diff[filename] = diff[filename] || [] + diff[filename].push(lineNumber) + } + lineNumber++ + } + } + } + return diff + } + + /* + Retrieves a list of commits that have not been checked by the test defined by this.testName + @returns {Array} - array of commit SHAs that have not been checked by the test + */ + async #getNonScannedCommits() { + const { data } = await this.github.rest.pulls.listCommits({ + owner: this.owner, + repo: this.repo, + pull_number: this.pullRequestNumber, + per_page: resultSize, + }) + let nonScannedCommits = [] + + // API returns commits in ascending order. Loop in reverse to quickly retrieve unchecked commits + for (let i = data.length - 1; i >= 0; i--) { + const { sha, parents } = data[i] + + // Commit can be merged master commit. Such commit have multiple parents + // Do not consider such commit for building file diff + if (parents.length > 1) { + continue + } + + const isTestExecuted = await this.#isTestExecutedOnCommit(sha) + if (isTestExecuted) { + // Remaining commits have been tested in previous scans. Therefore, do not need to be considered again + break + } else { + nonScannedCommits.push(sha) + } + } + + // Reverse to return commits in ascending order. This is needed to build diff for commits in chronological order + return nonScannedCommits.reverse() + } + + /* + Filters the commit diff to include only the files that are part of the PR diff + @param {Array} commitDiff - array of line numbers representing lines added or updated in the commit + @param {Array} prDiff - array of line numbers representing lines added or updated in the pull request + @returns {Array} - filtered commit diff, including only the files that are part of the PR diff + */ + async #filterCommitDiff(commitDiff = [], prDiff = []) { + return commitDiff.filter((file) => prDiff.includes(file)) + } + + /* + Builds the diff for the pull request, including both the changes in the pull request and the changes in non-scanned commits + @returns {string} - json string representation of the pull request diff and the diff for non-scanned commits + */ + async buildDiff() { + const { data } = await this.github.rest.pulls.listFiles({ + owner: this.owner, + repo: this.repo, + pull_number: this.pullRequestNumber, + per_page: resultSize, + }) + + const pullRequestDiff = await this.#getDiffForFiles(data) + + const nonScannedCommitsDiff = + Object.keys(pullRequestDiff).length != 0 && this.pullRequestEvent === synchronizeEvent // The "synchronize" event implies that new commit are pushed after the pull request was opened + ? await this.getNonScannedCommitDiff(pullRequestDiff) + : {} + + const prDiffFiles = Object.keys(pullRequestDiff) + const pullRequest = { + hasChanges: prDiffFiles.length > 0, + files: prDiffFiles.join(" "), + diff: pullRequestDiff, + } + const uncheckedCommits = { diff: nonScannedCommitsDiff } + return JSON.stringify({ pullRequest, uncheckedCommits }) + } + + /* + Retrieves the diff for non-scanned commits by comparing their changes with the pull request diff + @param {Object} pullRequestDiff - The diff of files in the pull request + @returns {Object} - The diff of files in the non-scanned commits that are part of the pull request diff + */ + async getNonScannedCommitDiff(pullRequestDiff) { + let nonScannedCommitsDiff = {} + // Retrieves list of commits that have not been scanned by the PR check + const nonScannedCommits = await this.#getNonScannedCommits() + for (const commit of nonScannedCommits) { + const { data } = await this.github.rest.repos.getCommit({ + owner: this.owner, + repo: this.repo, + ref: commit, + }) + + const commitDiff = await this.#getDiffForFiles(data.files) + const files = Object.keys(commitDiff) + for (const file of files) { + // Consider scenario where the changes made to a file in the initial commit are completely undone by subsequent commits + // In such cases, the modifications from the initial commit should not be taken into account + // If the changes were entirely removed, there should be no entry for the file in the pullRequestStats + const filePRDiff = pullRequestDiff[file] + if (!filePRDiff) { + continue + } + + // Consider scenario where changes made in the commit were partially removed or modified by subsequent commits + // In such cases, include only those commit changes that are part of the pullRequestStats object + // This ensures that only the changes that are reflected in the pull request are considered + const changes = await this.#filterCommitDiff(commitDiff[file], filePRDiff) + + if (changes.length !== 0) { + // Check if nonScannedCommitsDiff[file] exists, if not assign an empty array to it + nonScannedCommitsDiff[file] = nonScannedCommitsDiff[file] || [] + // Combine the existing nonScannedCommitsDiff[file] array with the commit changes + // Remove any duplicate elements using the Set data structure + nonScannedCommitsDiff[file] = [ + ...new Set([...nonScannedCommitsDiff[file], ...changes]), + ] + } + } + } + return nonScannedCommitsDiff + } +} + +class semgrepHelper { + constructor(input) { + this.owner = input.context.repo.owner + this.repo = input.context.repo.repo + this.github = input.github + + this.pullRequestNumber = input.context.payload.pull_request.number + this.pullRequestEvent = input.event + + this.pullRequestDiff = input.diff.pullRequest.diff + this.newCommitsDiff = input.diff.uncheckedCommits.diff + + this.semgrepErrors = [] + this.semgrepWarnings = [] + input.semgrepResult.forEach((res) => { + res.severity === "High" ? this.semgrepErrors.push(res) : this.semgrepWarnings.push(res) + }) + + this.headSha = input.headSha + } + + /* + Retrieves the matching line number from the provided diff for a given file and range of lines + @param {Object} range - object containing the file, start line, and end line to find a match + @param {Object} diff - object containing file changes and corresponding line numbers + @returns {number|null} - line number that matches the range within the diff, or null if no match is found + */ + async #getMatchingLineFromDiff({ file, start, end }, diff) { + const fileDiff = diff[file] + if (!fileDiff) { + return null + } + if (fileDiff.includes(start)) { + return start + } + if (fileDiff.includes(end)) { + return end + } + return null + } + + /* + Splits the semgrep results into different categories based on the scan + @param {Array} semgrepResults - array of results reported by semgrep + @returns {Object} - object containing the categorized semgrep results i.e results reported in previous scans and new results found in the current scan + */ + async #splitSemgrepResultsByScan(semgrepResults = []) { + const result = { + nonDiff: [], // Errors or warnings found in files updated in pull request, but not part of sections that were modified in the pull request + previous: [], // Errors or warnings found in previous semgrep scans + current: [], // Errors or warnings found in current semgrep scan + } + + for (const se of semgrepResults) { + const prDiffLine = await this.#getMatchingLineFromDiff(se, this.pullRequestDiff) + if (!prDiffLine) { + result.nonDiff.push({ ...se }) + continue + } + + switch (this.pullRequestEvent) { + case openedEvent: + // "Opened" event implies that this is the first check + // Therefore, the error should be appended to the result.current + result.current.push({ ...se, line: prDiffLine }) + case synchronizeEvent: + const commitDiffLine = await this.#getMatchingLineFromDiff(se, this.newCommitsDiff) + // Check if error or warning is part of current commit diff + // If not then error or warning was reported in previous scans + commitDiffLine != null + ? result.current.push({ ...se, line: commitDiffLine }) + : result.previous.push({ + ...se, + line: prDiffLine, + }) + } + } + return result + } + + /* + Adds review comments based on the semgrep results to the current pull request + @returns {Object} - object containing the count of unaddressed comments from the previous scan and the count of new comments from the current scan + */ + async addReviewComments() { + let result = { + previousScan: { unAddressedComments: 0 }, + currentScan: { newComments: 0 }, + } + + if (this.semgrepErrors.length == 0 && this.semgrepWarnings.length == 0) { + return result + } + + const errors = await this.#splitSemgrepResultsByScan(this.semgrepErrors) + if (errors.previous.length == 0 && errors.current.length == 0) { + console.log("Semgrep did not find any errors in the current pull request changes") + } else { + for (const { message, file, line } of errors.current) { + await this.github.rest.pulls.createReviewComment({ + owner: this.owner, + repo: this.repo, + pull_number: this.pullRequestNumber, + commit_id: this.headSha, + body: message, + path: file, + line: line, + }) + } + result.currentScan.newComments = errors.current.length + if (this.pullRequestEvent == synchronizeEvent) { + result.previousScan.unAddressedComments = errors.previous.length + } + } + + const warnings = await this.#splitSemgrepResultsByScan(this.semgrepWarnings) + for (const { message, file, line } of warnings.current) { + await this.github.rest.pulls.createReviewComment({ + owner: this.owner, + repo: this.repo, + pull_number: this.pullRequestNumber, + commit_id: this.headSha, + body: "Consider this as a suggestion. " + message, + path: file, + line: line, + }) + } + return result + } +} + +module.exports = { + diffHelper: (input) => new diffHelper(input), + semgrepHelper: (input) => new semgrepHelper(input), +} diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml new file mode 100644 index 00000000000..87c5573e671 --- /dev/null +++ b/.github/workflows/semgrep.yml @@ -0,0 +1,74 @@ +name: Adapter semgrep checks +on: + pull_request: + paths: ["adapters/*/*.go"] +permissions: write-all +jobs: + semgrep-check: + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Calculate diff + id: calculate_diff + uses: actions/github-script@v6 + with: + result-encoding: string + script: | + const utils = require('./.github/workflows/helpers/pull-request-utils.js') + // consider only non-test Go files that are part of the adapter code + function fileNameFilter(filename) { + return filename.startsWith("adapters/") && filename.split("/").length > 2 && filename.endsWith(".go") && !filename.endsWith("_test.go") + } + const helper = utils.diffHelper({github, context, fileNameFilter, event: "${{github.event.action}}", testName: "${{github.job}}"}) + return await helper.buildDiff() + + - name: Should run semgrep + id: should_run_semgrep + run: | + hasChanges=$(echo '${{ steps.calculate_diff.outputs.result }}' | jq .pullRequest.hasChanges) + echo "hasChanges=${hasChanges}" >> $GITHUB_OUTPUT + + - name: Install semgrep + if: contains(steps.should_run_semgrep.outputs.hasChanges, 'true') + run: | + pip3 install semgrep==1.22.0 + semgrep --version + + - name: Run semgrep tests + id: run_semgrep_tests + if: contains(steps.should_run_semgrep.outputs.hasChanges, 'true') + run: | + unqouted_string=$(echo '${{ steps.calculate_diff.outputs.result }}' | jq .pullRequest.files | tr -d '"') + outputs=$(semgrep --gitlab-sast --config=.semgrep/adapter $unqouted_string | jq '[.vulnerabilities[] | {"file": .location.file, "severity": .severity, "start": .location.start_line, "end": .location.end_line, "message": (.message | gsub("\\n"; "\n"))}]' | jq -c | jq -R) + echo "semgrep_result=${outputs}" >> "$GITHUB_OUTPUT" + + - name: Add pull request comment + id: add_pull_request_comment + if: contains(steps.should_run_semgrep.outputs.hasChanges, 'true') + uses: actions/github-script@v6.4.1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + result-encoding: string + script: | + const utils = require('./.github/workflows/helpers/pull-request-utils.js') + const helper = utils.semgrepHelper({ + github, context, event: "${{github.event.action}}", + semgrepResult: JSON.parse(${{ steps.run_semgrep_tests.outputs.semgrep_result }}), + diff: ${{ steps.calculate_diff.outputs.result }}, headSha: "${{github.event.pull_request.head.sha}}" + }) + const { previousScan, currentScan } = await helper.addReviewComments() + return previousScan.unAddressedComments + currentScan.newComments + + - name: Adapter semgrep checks result + if: contains(steps.should_run_semgrep.outputs.hasChanges, 'true') + run: | + if [ "${{steps.add_pull_request_comment.outputs.result}}" -ne "0" ]; then + echo 'Semgrep has found "${{steps.add_pull_request_comment.outputs.result}}" errors' + exit 1 + else + echo 'Semgrep did not find any errors in the pull request changes' + fi diff --git a/.semgrep/adapter/builder-struct-name.yml b/.semgrep/adapter/builder-struct-name.yml index c80e8e12b52..bc876ae1809 100644 --- a/.semgrep/adapter/builder-struct-name.yml +++ b/.semgrep/adapter/builder-struct-name.yml @@ -16,7 +16,7 @@ rules: return &adapter{endpoint: "https://www.foo.com"}, nil } ``` - severity: WARNING + severity: ERROR patterns: - pattern-either: - pattern-inside: > From 613db4057f77590a4993eaaeed55a9ad1a305e13 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Mon, 10 Jul 2023 19:02:11 +0530 Subject: [PATCH 013/268] semgrep rule to detect undesirable package imports in adapter code (#2911) --- .semgrep/adapter/package-import.go | 47 +++++++++++++++++++++++++++++ .semgrep/adapter/package-import.yml | 13 ++++++++ 2 files changed, 60 insertions(+) create mode 100644 .semgrep/adapter/package-import.go create mode 100644 .semgrep/adapter/package-import.yml diff --git a/.semgrep/adapter/package-import.go b/.semgrep/adapter/package-import.go new file mode 100644 index 00000000000..a34ce8789cd --- /dev/null +++ b/.semgrep/adapter/package-import.go @@ -0,0 +1,47 @@ +import ( + // ok: package-import-check + "fmt" + // ok: package-import-check + "os" + // ruleid: package-import-check + "github.com/mitchellh/copystructure" + // ruleid: package-import-check + "github.com/golang/glog" +) + +import ( + // ok: package-import-check + "fmt" + // ruleid: package-import-check + cs "github.com/mitchellh/copystructure" + // ok: package-import-check + "os" + // ruleid: package-import-check + log "github.com/golang/glog" +) + +import ( + // ok: package-import-check + "fmt" + // ruleid: package-import-check + cs "github.com/mitchellh/copystructure/subpackage" + // ok: package-import-check + "os" + // ruleid: package-import-check + log "github.com/golang/glog/subpackage" +) + +// ruleid: package-import-check +import "github.com/golang/glog" + +// ruleid: package-import-check +import "github.com/mitchellh/copystructure" + +// ruleid: package-import-check +import log "github.com/golang/glog" + +// ruleid: package-import-check +import copy "github.com/mitchellh/copystructure" + +// ok: package-import-check +import "fmt" diff --git a/.semgrep/adapter/package-import.yml b/.semgrep/adapter/package-import.yml new file mode 100644 index 00000000000..5ed7b9fcb0c --- /dev/null +++ b/.semgrep/adapter/package-import.yml @@ -0,0 +1,13 @@ +rules: + - id: package-import-check + message: Importing "$PKG" package is not recommended in adapter code + languages: + - go + severity: ERROR + pattern-either: + - patterns: + - pattern: import "$PKG" + - focus-metavariable: $PKG + - metavariable-regex: + metavariable: $PKG + regex: (^github\.com/mitchellh/copystructure(/.*)?$|^github\.com/golang/glog(/.*)?$) \ No newline at end of file From 7790a4f92c32f21f4807435a919e8ac8b700b095 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Mon, 10 Jul 2023 19:19:44 +0530 Subject: [PATCH 014/268] update package-import message (#2913) authored by @onkarvhanumante --- .semgrep/adapter/package-import.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.semgrep/adapter/package-import.yml b/.semgrep/adapter/package-import.yml index 5ed7b9fcb0c..20de2d107da 100644 --- a/.semgrep/adapter/package-import.yml +++ b/.semgrep/adapter/package-import.yml @@ -1,6 +1,6 @@ rules: - id: package-import-check - message: Importing "$PKG" package is not recommended in adapter code + message: Usage of "$PKG" package is prohibited in adapter code languages: - go severity: ERROR From aeec25ba0bdd1dc6c1eb37aaf778cc9fca626a0f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jul 2023 13:38:23 -0400 Subject: [PATCH 015/268] Bump google.golang.org/grpc from 1.46.2 to 1.53.0 (#2905) --- go.mod | 8 ++++---- go.sum | 21 +++++++++------------ 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/go.mod b/go.mod index 3833ef3d9e5..e7a6f7e30d1 100644 --- a/go.mod +++ b/go.mod @@ -33,14 +33,14 @@ require ( github.com/yudai/gojsondiff v1.0.0 golang.org/x/net v0.7.0 golang.org/x/text v0.7.0 - google.golang.org/grpc v1.46.2 + google.golang.org/grpc v1.53.0 gopkg.in/evanphx/json-patch.v4 v4.12.0 gopkg.in/yaml.v3 v3.0.1 ) require ( github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/golang/protobuf v1.5.2 // indirect @@ -68,8 +68,8 @@ require ( github.com/yudai/pp v2.0.1+incompatible // indirect golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect golang.org/x/sys v0.5.0 // indirect - google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd // indirect - google.golang.org/protobuf v1.28.0 // indirect + google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect + google.golang.org/protobuf v1.28.1 // indirect gopkg.in/ini.v1 v1.66.4 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index e1226ab1f3c..1f76be7af31 100644 --- a/go.sum +++ b/go.sum @@ -86,8 +86,9 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chasex/glog v0.0.0-20160217080310-c62392af379c h1:eXqCBUHfmjbeDqcuvzjsd+bM6A+bnwo5N9FVbV6m5/s= github.com/chasex/glog v0.0.0-20160217080310-c62392af379c/go.mod h1:omJZNg0Qu76bxJd+ExohVo8uXzNcGOk2bv7vel460xk= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -125,7 +126,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -210,7 +210,7 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -392,8 +392,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/prebid/go-gdpr v1.11.0 h1:QbMjscuw3Ul0mDVWeMy5tP0Kii6lmTSSVhV6fm8rY9s= -github.com/prebid/go-gdpr v1.11.0/go.mod h1:mPZAdkRxn+iuSjaUuJAi9+0SppBOdM1PCzv/55UH3pY= github.com/prebid/go-gdpr v1.12.0 h1:OrjQ7Uc+lCRYaOirQ48jjG/PBMvZsKNAaRTgzxN6iZ0= github.com/prebid/go-gdpr v1.12.0/go.mod h1:mPZAdkRxn+iuSjaUuJAi9+0SppBOdM1PCzv/55UH3pY= github.com/prebid/go-gpp v0.1.1 h1:uTMJ+eHmKWL9WvDuxFT4LDoOeJW1yOsfWITqi49ZuY0= @@ -910,8 +908,8 @@ google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd h1:e0TwkXOdbnH/1x5rc5MZ/VYyiZ4v+RdVfrGMqEwT68I= -google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -942,9 +940,8 @@ google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.46.2 h1:u+MLGgVf7vRdjEYZ8wDFhAVNmhkbJ5hmrA1LMWK1CAQ= -google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -959,8 +956,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 5be19b4d4b4f906b11e3b39532039b75ec885cce Mon Sep 17 00:00:00 2001 From: Mansi Nahar Date: Wed, 12 Jul 2023 13:17:52 -0400 Subject: [PATCH 016/268] Update Go version to 1.20.5 (#2871) --- .devcontainer/devcontainer.json | 2 +- .github/workflows/validate-merge.yml | 2 +- .github/workflows/validate.yml | 2 +- Dockerfile | 4 ++-- README.md | 2 +- go.mod | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index f4ea099d9c8..ebf6f614df3 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,7 +6,7 @@ "dockerfile": "Dockerfile", "args": { // Update the VARIANT arg to pick a version of Go - "VARIANT": "1.19", + "VARIANT": "1.20", // Options "INSTALL_NODE": "false", "NODE_VERSION": "lts/*" diff --git a/.github/workflows/validate-merge.yml b/.github/workflows/validate-merge.yml index e85dc3de50c..07f1bacaa45 100644 --- a/.github/workflows/validate-merge.yml +++ b/.github/workflows/validate-merge.yml @@ -12,7 +12,7 @@ jobs: - name: Install Go uses: actions/setup-go@v4 with: - go-version: 1.19.2 + go-version: 1.20.5 - name: Checkout Merged Branch uses: actions/checkout@v3 diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 83b29709bd4..9047e1f468f 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -10,7 +10,7 @@ jobs: validate: strategy: matrix: - go-version: [1.18.x, 1.19.x] + go-version: [1.19.x, 1.20.x] os: [ubuntu-20.04] runs-on: ${{ matrix.os }} diff --git a/Dockerfile b/Dockerfile index 80269c908df..090d9a79954 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,8 +3,8 @@ RUN apt-get update && \ apt-get -y upgrade && \ apt-get install -y wget WORKDIR /tmp -RUN wget https://dl.google.com/go/go1.19.2.linux-amd64.tar.gz && \ - tar -xf go1.19.2.linux-amd64.tar.gz && \ +RUN wget https://dl.google.com/go/go1.20.5.linux-amd64.tar.gz && \ + tar -xf go1.20.5.linux-amd64.tar.gz && \ mv go /usr/local RUN mkdir -p /app/prebid-server/ WORKDIR /app/prebid-server/ diff --git a/README.md b/README.md index 95e0262b46f..9b657f35db6 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Please consider [registering your Prebid Server](https://docs.prebid.org/prebid- ## Installation -First install [Go](https://golang.org/doc/install) version 1.18 or newer. +First install [Go](https://golang.org/doc/install) version 1.19 or newer. Note that prebid-server is using [Go modules](https://blog.golang.org/using-go-modules). We officially support the most recent two major versions of the Go runtime. However, if you'd like to use a version <1.13 and are inside GOPATH `GO111MODULE` needs to be set to `GO111MODULE=on`. diff --git a/go.mod b/go.mod index e7a6f7e30d1..6731c177ecf 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/prebid/prebid-server -go 1.19 +go 1.20 require ( github.com/DATA-DOG/go-sqlmock v1.5.0 From 68a052d2e3b0ca0d7865fade2a97754f56359f29 Mon Sep 17 00:00:00 2001 From: mwang-sticky Date: Thu, 13 Jul 2023 13:56:03 +0800 Subject: [PATCH 017/268] freewheel adapter support gpp in user sync (#2915) --- static/bidder-info/freewheel-ssp.yaml | 2 +- static/bidder-info/freewheelssp.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/static/bidder-info/freewheel-ssp.yaml b/static/bidder-info/freewheel-ssp.yaml index f013445a820..0c0a11edfce 100644 --- a/static/bidder-info/freewheel-ssp.yaml +++ b/static/bidder-info/freewheel-ssp.yaml @@ -12,5 +12,5 @@ capabilities: - video userSync: iframe: - url: "https://ads.stickyadstv.com/pbs-user-sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}" + url: "https://ads.stickyadstv.com/pbs-user-sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&r={{.RedirectURL}}" userMacro: "{viewerid}" diff --git a/static/bidder-info/freewheelssp.yaml b/static/bidder-info/freewheelssp.yaml index 5cef0de13b3..8c9286cbbc0 100644 --- a/static/bidder-info/freewheelssp.yaml +++ b/static/bidder-info/freewheelssp.yaml @@ -12,5 +12,5 @@ capabilities: - video userSync: iframe: - url: "https://ads.stickyadstv.com/pbs-user-sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}" + url: "https://ads.stickyadstv.com/pbs-user-sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&r={{.RedirectURL}}" userMacro: "{viewerid}" \ No newline at end of file From 2b6612f7efd63ba457f1ebe25dd1cd0183bbc18b Mon Sep 17 00:00:00 2001 From: Denis Logachov Date: Fri, 14 Jul 2023 13:27:01 +0300 Subject: [PATCH 018/268] Adding gpp support to adkernel sync (#2922) authored by @ckbo3hrk --- static/bidder-info/adkernel.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/bidder-info/adkernel.yaml b/static/bidder-info/adkernel.yaml index 864ca71a088..1afbdc8d590 100644 --- a/static/bidder-info/adkernel.yaml +++ b/static/bidder-info/adkernel.yaml @@ -12,6 +12,6 @@ capabilities: - video userSync: redirect: - url: "https://sync.adkernel.com/user-sync?t=image&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}" + url: "https://sync.adkernel.com/user-sync?t=image&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&r={{.RedirectURL}}" userMacro: "{UID}" -endpointCompression: "GZIP" \ No newline at end of file +endpointCompression: "GZIP" From 8e7a6a014180ea226a789e8e50df81ace4892b99 Mon Sep 17 00:00:00 2001 From: gotham-ads <137912379+gotham-ads@users.noreply.github.com> Date: Mon, 17 Jul 2023 08:38:53 +0300 Subject: [PATCH 019/268] New Adapter: Gothamads (#2879) --- adapters/gothamads/gothamads.go | 170 +++++++++++++++ adapters/gothamads/gothamads_test.go | 28 +++ .../gothamadstest/exemplary/banner-app.json | 151 ++++++++++++++ .../gothamadstest/exemplary/banner-web.json | 194 ++++++++++++++++++ .../gothamadstest/exemplary/native-app.json | 147 +++++++++++++ .../gothamadstest/exemplary/native-web.json | 134 ++++++++++++ .../gothamadstest/exemplary/video-app.json | 160 +++++++++++++++ .../gothamadstest/exemplary/video-web.json | 158 ++++++++++++++ .../supplemental/bad_media_type.json | 134 ++++++++++++ .../supplemental/empty-seatbid-array.json | 129 ++++++++++++ .../invalid-bidder-ext-object.json | 33 +++ .../invalid-gotham-ext-object.json | 31 +++ .../supplemental/invalid-response.json | 111 ++++++++++ .../supplemental/status-code-bad-request.json | 92 +++++++++ .../supplemental/status-code-no-content.json | 75 +++++++ .../supplemental/status-code-other-error.json | 80 ++++++++ .../status-code-service-unavailable.json | 80 ++++++++ adapters/gothamads/params_test.go | 50 +++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_gothamads.go | 5 + static/bidder-info/gothamads.yaml | 14 ++ static/bidder-params/gothamads.json | 16 ++ 23 files changed, 1996 insertions(+) create mode 100644 adapters/gothamads/gothamads.go create mode 100644 adapters/gothamads/gothamads_test.go create mode 100644 adapters/gothamads/gothamadstest/exemplary/banner-app.json create mode 100644 adapters/gothamads/gothamadstest/exemplary/banner-web.json create mode 100644 adapters/gothamads/gothamadstest/exemplary/native-app.json create mode 100644 adapters/gothamads/gothamadstest/exemplary/native-web.json create mode 100644 adapters/gothamads/gothamadstest/exemplary/video-app.json create mode 100644 adapters/gothamads/gothamadstest/exemplary/video-web.json create mode 100644 adapters/gothamads/gothamadstest/supplemental/bad_media_type.json create mode 100644 adapters/gothamads/gothamadstest/supplemental/empty-seatbid-array.json create mode 100644 adapters/gothamads/gothamadstest/supplemental/invalid-bidder-ext-object.json create mode 100644 adapters/gothamads/gothamadstest/supplemental/invalid-gotham-ext-object.json create mode 100644 adapters/gothamads/gothamadstest/supplemental/invalid-response.json create mode 100644 adapters/gothamads/gothamadstest/supplemental/status-code-bad-request.json create mode 100644 adapters/gothamads/gothamadstest/supplemental/status-code-no-content.json create mode 100644 adapters/gothamads/gothamadstest/supplemental/status-code-other-error.json create mode 100644 adapters/gothamads/gothamadstest/supplemental/status-code-service-unavailable.json create mode 100644 adapters/gothamads/params_test.go create mode 100644 openrtb_ext/imp_gothamads.go create mode 100644 static/bidder-info/gothamads.yaml create mode 100644 static/bidder-params/gothamads.json diff --git a/adapters/gothamads/gothamads.go b/adapters/gothamads/gothamads.go new file mode 100644 index 00000000000..e486585c958 --- /dev/null +++ b/adapters/gothamads/gothamads.go @@ -0,0 +1,170 @@ +package gothamads + +import ( + "encoding/json" + "fmt" + "net/http" + "text/template" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/macros" + "github.com/prebid/prebid-server/openrtb_ext" +) + +type adapter struct { + endpoint *template.Template +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + template, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) + } + + bidder := &adapter{ + endpoint: template, + } + return bidder, nil +} + +func getHeaders(request *openrtb2.BidRequest) http.Header { + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + headers.Add("X-Openrtb-Version", "2.5") + + if request.Device != nil { + if len(request.Device.UA) > 0 { + headers.Add("User-Agent", request.Device.UA) + } + + if len(request.Device.IPv6) > 0 { + headers.Add("X-Forwarded-For", request.Device.IPv6) + } + + if len(request.Device.IP) > 0 { + headers.Add("X-Forwarded-For", request.Device.IP) + } + } + + return headers +} + +func (a *adapter) MakeRequests(openRTBRequest *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) (requestsToBidder []*adapters.RequestData, errs []error) { + impExt, err := getImpressionExt(&openRTBRequest.Imp[0]) + if err != nil { + return nil, []error{err} + } + + openRTBRequest.Imp[0].Ext = nil + + url, err := a.buildEndpointURL(impExt) + if err != nil { + return nil, []error{err} + } + + reqJSON, err := json.Marshal(openRTBRequest) + if err != nil { + return nil, []error{err} + } + + return []*adapters.RequestData{{ + Method: http.MethodPost, + Body: reqJSON, + Uri: url, + Headers: getHeaders(openRTBRequest), + }}, nil +} + +func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtGothamAds, error) { + var bidderExt adapters.ExtImpBidder + if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + return nil, &errortypes.BadInput{ + Message: err.Error(), + } + } + var gothamadsExt openrtb_ext.ExtGothamAds + if err := json.Unmarshal(bidderExt.Bidder, &gothamadsExt); err != nil { + return nil, &errortypes.BadInput{ + Message: err.Error(), + } + } + + return &gothamadsExt, nil +} + +func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtGothamAds) (string, error) { + endpointParams := macros.EndpointTemplateParams{AccountID: params.AccountID} + return macros.ResolveMacros(a.endpoint, endpointParams) +} + +func checkResponseStatusCodes(response *adapters.ResponseData) error { + if response.StatusCode == http.StatusServiceUnavailable { + return &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Something went wrong Status Code: [ %d ] ", response.StatusCode), + } + } + + return adapters.CheckResponseStatusCodeForErrors(response) +} + +func (a *adapter) MakeBids(openRTBRequest *openrtb2.BidRequest, requestToBidder *adapters.RequestData, bidderRawResponse *adapters.ResponseData) (bidderResponse *adapters.BidderResponse, errs []error) { + if adapters.IsResponseStatusCodeNoContent(bidderRawResponse) { + return nil, nil + } + + httpStatusError := checkResponseStatusCodes(bidderRawResponse) + if httpStatusError != nil { + return nil, []error{httpStatusError} + } + + responseBody := bidderRawResponse.Body + var bidResp openrtb2.BidResponse + if err := json.Unmarshal(responseBody, &bidResp); err != nil { + return nil, []error{&errortypes.BadServerResponse{ + Message: "Bad Server Response", + }} + } + + if len(bidResp.SeatBid) == 0 { + return nil, []error{&errortypes.BadServerResponse{ + Message: "Empty SeatBid array", + }} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(5) + var bidsArray []*adapters.TypedBid + + for _, sb := range bidResp.SeatBid { + for idx, bid := range sb.Bid { + bidType, err := getMediaTypeForImp(bid) + if err != nil { + return nil, []error{err} + } + + bidsArray = append(bidsArray, &adapters.TypedBid{ + Bid: &sb.Bid[idx], + BidType: bidType, + }) + } + } + + bidResponse.Bids = bidsArray + return bidResponse, nil +} + +func getMediaTypeForImp(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + return "", fmt.Errorf("unsupported MType %d", bid.MType) + } +} diff --git a/adapters/gothamads/gothamads_test.go b/adapters/gothamads/gothamads_test.go new file mode 100644 index 00000000000..82e34dde1b3 --- /dev/null +++ b/adapters/gothamads/gothamads_test.go @@ -0,0 +1,28 @@ +package gothamads + +import ( + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderGothamads, config.Adapter{ + Endpoint: "http://us-e-node1.gothamads.com/?pass={{.AccountID}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "gothamadstest", bidder) +} + +func TestEndpointTemplateMalformed(t *testing.T) { + _, buildErr := Builder(openrtb_ext.BidderGothamads, config.Adapter{ + Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + assert.Error(t, buildErr) +} diff --git a/adapters/gothamads/gothamadstest/exemplary/banner-app.json b/adapters/gothamads/gothamadstest/exemplary/banner-app.json new file mode 100644 index 00000000000..44966ea8888 --- /dev/null +++ b/adapters/gothamads/gothamadstest/exemplary/banner-app.json @@ -0,0 +1,151 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "1", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "accountId": "accountId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "1", + "banner": { + "w": 320, + "h": 50 + }, + "tagid": "ogTAGID" + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "1", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 320, + "h": 50, + "mtype": 1 + } + ], + "type": "banner", + "seat": "gothamAds" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "1", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 320, + "h": 50, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/gothamads/gothamadstest/exemplary/banner-web.json b/adapters/gothamads/gothamadstest/exemplary/banner-web.json new file mode 100644 index 00000000000..baac33a4f8c --- /dev/null +++ b/adapters/gothamads/gothamadstest/exemplary/banner-web.json @@ -0,0 +1,194 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "some-impression-id1", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "accountId": "accountId" + } + } + }, + { + "id": "some-impression-id2", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "accountId": "accountId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id1", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + } + }, + { + "id": "some-impression-id2", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "accountId": "accountId" + } + } + } + ], + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id1", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 320, + "h": 50, + "mtype": 1 + }, + { + "id": "a3ae1b4e2fc24a4fb45540082e98e162", + "impid": "some-impression-id2", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 320, + "h": 50, + "mtype": 1 + } + ], + "type": "banner", + "seat": "gothamads" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id1", + "price": 3.5, + "adm": "awesome-markup", + "crid": "20", + "adomain": [ + "awesome.com" + ], + "w": 320, + "h": 50, + "mtype": 1 + }, + "type": "banner" + }, + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e162", + "impid": "some-impression-id2", + "price": 3.5, + "adm": "awesome-markup", + "crid": "20", + "adomain": [ + "awesome.com" + ], + "w": 320, + "h": 50, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/gothamads/gothamadstest/exemplary/native-app.json b/adapters/gothamads/gothamadstest/exemplary/native-app.json new file mode 100644 index 00000000000..5c54d526699 --- /dev/null +++ b/adapters/gothamads/gothamadstest/exemplary/native-app.json @@ -0,0 +1,147 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "native": { + "ver": "1.1", + "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}" + }, + "ext": { + "bidder": { + "accountId": "accountId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "native": { + "ver": "1.1", + "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}" + }, + "tagid": "ogTAGID" + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "mtype": 4 + } + ], + "type": "native", + "seat": "gothamads" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "crid": "20", + "adomain": [ + "awesome.com" + ], + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/gothamads/gothamadstest/exemplary/native-web.json b/adapters/gothamads/gothamadstest/exemplary/native-web.json new file mode 100644 index 00000000000..a2f16e78606 --- /dev/null +++ b/adapters/gothamads/gothamadstest/exemplary/native-web.json @@ -0,0 +1,134 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ipv6": "2607:fb90:f27:4512:d800:cb23:a603:e245", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "native": { + "ver": "1.1", + "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}" + }, + "ext": { + "bidder": { + "accountId": "accountId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "2607:fb90:f27:4512:d800:cb23:a603:e245" + ] + }, + "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ipv6": "2607:fb90:f27:4512:d800:cb23:a603:e245", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "native": { + "ver": "1.1", + "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}" + } + } + ], + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "mtype": 4 + } + ], + "seat": "gothamads" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "crid": "20", + "adomain": [ + "awesome.com" + ], + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/gothamads/gothamadstest/exemplary/video-app.json b/adapters/gothamads/gothamadstest/exemplary/video-app.json new file mode 100644 index 00000000000..a08c5a032c1 --- /dev/null +++ b/adapters/gothamads/gothamadstest/exemplary/video-app.json @@ -0,0 +1,160 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "accountId": "accountId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + }, + "tagid": "ogTAGID" + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 1280, + "h": 720, + "mtype": 2 + } + ], + "seat": "gothamads" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "crid": "20", + "adomain": [ + "awesome.com" + ], + "w": 1280, + "h": 720, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/gothamads/gothamadstest/exemplary/video-web.json b/adapters/gothamads/gothamadstest/exemplary/video-web.json new file mode 100644 index 00000000000..64293e740ba --- /dev/null +++ b/adapters/gothamads/gothamadstest/exemplary/video-web.json @@ -0,0 +1,158 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "accountId": "accountId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + } + } + ], + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 1280, + "h": 720, + "ext": { + "prebid": { + "type": "video" + } + }, + "mtype": 2 + } + ], + "seat": "gothamads" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 1280, + "h": 720, + "ext": { + "prebid": { + "type": "video" + } + }, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/gothamads/gothamadstest/supplemental/bad_media_type.json b/adapters/gothamads/gothamadstest/supplemental/bad_media_type.json new file mode 100644 index 00000000000..349ea5da3f4 --- /dev/null +++ b/adapters/gothamads/gothamadstest/supplemental/bad_media_type.json @@ -0,0 +1,134 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "1", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "accountId": "accountId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "1", + "banner": { + "w": 320, + "h": 50 + }, + "tagid": "ogTAGID" + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "test-imp-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 320, + "h": 50 + } + ], + "mtype": 0, + "seat": "gothamads" + } + ], + "cur": "USD" + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "unsupported MType 0", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/gothamads/gothamadstest/supplemental/empty-seatbid-array.json b/adapters/gothamads/gothamadstest/supplemental/empty-seatbid-array.json new file mode 100644 index 00000000000..50eafd989af --- /dev/null +++ b/adapters/gothamads/gothamadstest/supplemental/empty-seatbid-array.json @@ -0,0 +1,129 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "accountId": "accountId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + }, + "tagid": "ogTAGID" + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [], + "cur": "USD" + } + } + } + ], + "mockResponse": { + "status": 200, + "body": "invalid response" + }, + "expectedMakeBidsErrors": [ + { + "value": "Empty SeatBid array", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/gothamads/gothamadstest/supplemental/invalid-bidder-ext-object.json b/adapters/gothamads/gothamadstest/supplemental/invalid-bidder-ext-object.json new file mode 100644 index 00000000000..e412d39ca2c --- /dev/null +++ b/adapters/gothamads/gothamadstest/supplemental/invalid-bidder-ext-object.json @@ -0,0 +1,33 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "json: cannot unmarshal string into Go value of type openrtb_ext.ExtGothamAds", + "comparison": "literal" + } + ], + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "some-impression-id", + "tagid": "my-adcode", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": "bidderExt" + } + } + ], + "site": { + "page": "test.com" + } + }, + "httpCalls": [] +} \ No newline at end of file diff --git a/adapters/gothamads/gothamadstest/supplemental/invalid-gotham-ext-object.json b/adapters/gothamads/gothamadstest/supplemental/invalid-gotham-ext-object.json new file mode 100644 index 00000000000..6075e2a4b3d --- /dev/null +++ b/adapters/gothamads/gothamadstest/supplemental/invalid-gotham-ext-object.json @@ -0,0 +1,31 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "comparison": "literal" + } + ], + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "some-impression-id", + "tagid": "my-adcode", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": "wrongExt" + } + ], + "site": { + "page": "test.com" + } + }, + "httpCalls": [] +} \ No newline at end of file diff --git a/adapters/gothamads/gothamadstest/supplemental/invalid-response.json b/adapters/gothamads/gothamadstest/supplemental/invalid-response.json new file mode 100644 index 00000000000..eb928b41551 --- /dev/null +++ b/adapters/gothamads/gothamadstest/supplemental/invalid-response.json @@ -0,0 +1,111 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "accountId": "accountId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 320, + "h": 50 + }, + "tagid": "ogTAGID" + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": "invalid response" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bad Server Response", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/gothamads/gothamadstest/supplemental/status-code-bad-request.json b/adapters/gothamads/gothamadstest/supplemental/status-code-bad-request.json new file mode 100644 index 00000000000..37c047edaa3 --- /dev/null +++ b/adapters/gothamads/gothamadstest/supplemental/status-code-bad-request.json @@ -0,0 +1,92 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "accountId": "accountId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "body": { + "id": "some-request-id", + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + }, + "tagid": "ogTAGID" + } + ], + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 400 + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/gothamads/gothamadstest/supplemental/status-code-no-content.json b/adapters/gothamads/gothamadstest/supplemental/status-code-no-content.json new file mode 100644 index 00000000000..76a3a4fc84d --- /dev/null +++ b/adapters/gothamads/gothamadstest/supplemental/status-code-no-content.json @@ -0,0 +1,75 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "accountId": "accountId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "body": { + "id": "some-request-id", + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + } + } + ], + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [] +} \ No newline at end of file diff --git a/adapters/gothamads/gothamadstest/supplemental/status-code-other-error.json b/adapters/gothamads/gothamadstest/supplemental/status-code-other-error.json new file mode 100644 index 00000000000..45a0f67f3e0 --- /dev/null +++ b/adapters/gothamads/gothamadstest/supplemental/status-code-other-error.json @@ -0,0 +1,80 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "accountId": "accountId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "body": { + "id": "some-request-id", + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + } + } + ], + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 306 + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 306. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/gothamads/gothamadstest/supplemental/status-code-service-unavailable.json b/adapters/gothamads/gothamadstest/supplemental/status-code-service-unavailable.json new file mode 100644 index 00000000000..97773cd0d53 --- /dev/null +++ b/adapters/gothamads/gothamadstest/supplemental/status-code-service-unavailable.json @@ -0,0 +1,80 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "accountId": "accountId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://us-e-node1.gothamads.com/?pass=accountId", + "body": { + "id": "some-request-id", + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + } + } + ], + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 503 + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Something went wrong Status Code: [ 503 ] ", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/gothamads/params_test.go b/adapters/gothamads/params_test.go new file mode 100644 index 00000000000..1290216d28e --- /dev/null +++ b/adapters/gothamads/params_test.go @@ -0,0 +1,50 @@ +package gothamads + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/openrtb_ext" +) + +var validParams = []string{ + `{"accountId": "hash"}`, +} + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderGothamads, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected Gothamads params: %s", validParam) + } + } +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `4.2`, + `[]`, + `{}`, + `{"adCode": "string", "seatCode": 5, "originalPublisherid": "string"}`, + `{ "accountid": "" }`, +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderGothamads, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 3818a16a03a..f83445256d6 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -85,6 +85,7 @@ import ( "github.com/prebid/prebid-server/adapters/gamma" "github.com/prebid/prebid-server/adapters/gamoshi" "github.com/prebid/prebid-server/adapters/globalsun" + "github.com/prebid/prebid-server/adapters/gothamads" "github.com/prebid/prebid-server/adapters/grid" "github.com/prebid/prebid-server/adapters/gumgum" "github.com/prebid/prebid-server/adapters/huaweiads" @@ -274,6 +275,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderGamma: gamma.Builder, openrtb_ext.BidderGamoshi: gamoshi.Builder, openrtb_ext.BidderGlobalsun: globalsun.Builder, + openrtb_ext.BidderGothamads: gothamads.Builder, openrtb_ext.BidderGrid: grid.Builder, openrtb_ext.BidderGumGum: gumgum.Builder, openrtb_ext.BidderHuaweiAds: huaweiads.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 9906d12e1b8..978af5e0118 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -175,6 +175,7 @@ const ( BidderGamma BidderName = "gamma" BidderGamoshi BidderName = "gamoshi" BidderGlobalsun BidderName = "globalsun" + BidderGothamads BidderName = "gothamads" BidderGrid BidderName = "grid" BidderGumGum BidderName = "gumgum" BidderHuaweiAds BidderName = "huaweiads" @@ -373,6 +374,7 @@ func CoreBidderNames() []BidderName { BidderGamma, BidderGamoshi, BidderGlobalsun, + BidderGothamads, BidderGrid, BidderGumGum, BidderHuaweiAds, diff --git a/openrtb_ext/imp_gothamads.go b/openrtb_ext/imp_gothamads.go new file mode 100644 index 00000000000..fb945fbba67 --- /dev/null +++ b/openrtb_ext/imp_gothamads.go @@ -0,0 +1,5 @@ +package openrtb_ext + +type ExtGothamAds struct { + AccountID string `json:"accountId"` +} diff --git a/static/bidder-info/gothamads.yaml b/static/bidder-info/gothamads.yaml new file mode 100644 index 00000000000..c9f4e66b484 --- /dev/null +++ b/static/bidder-info/gothamads.yaml @@ -0,0 +1,14 @@ +endpoint: "http://us-e-node1.gothamads.com/?pass={{.AccountID}}" +maintainer: + email: "support@gothamads.com" +capabilities: + app: + mediaTypes: + - banner + - video + - native + site: + mediaTypes: + - banner + - video + - native \ No newline at end of file diff --git a/static/bidder-params/gothamads.json b/static/bidder-params/gothamads.json new file mode 100644 index 00000000000..030d43eb311 --- /dev/null +++ b/static/bidder-params/gothamads.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Gothamads Adapter Params", + "description": "A schema which validates params accepted by the Gothamads adapter", + "type": "object", + "properties": { + "accountId": { + "type": "string", + "description": "Account id", + "minLength": 1 + } + }, + "required": [ + "accountId" + ] +} \ No newline at end of file From dd38898d3ffedb76b4ce7eeacced3f593ab68e4c Mon Sep 17 00:00:00 2001 From: balintvargha <122350182+balintvargha@users.noreply.github.com> Date: Mon, 17 Jul 2023 08:27:10 +0200 Subject: [PATCH 020/268] Adsinteractive: Usersync endpoint changed and GPP support added (#2926) Co-authored-by: Balint Vargha --- static/bidder-info/adsinteractive.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/bidder-info/adsinteractive.yaml b/static/bidder-info/adsinteractive.yaml index d430e63b2f0..095184725b8 100644 --- a/static/bidder-info/adsinteractive.yaml +++ b/static/bidder-info/adsinteractive.yaml @@ -12,6 +12,6 @@ capabilities: - banner userSync: redirect: - url: "https://bid.adsinteractive.com/getuid?{{.RedirectURL}}" + url: "https://sync.adsinteractive.com/getuid?{{.RedirectURL}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}" userMacro: "$AUID" From 66c4264c22b10fe7d5115ebde3949e8538fdd1e1 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Mon, 17 Jul 2023 13:11:07 +0530 Subject: [PATCH 021/268] refactor `requestBid` and `getAllBids` signature (#2874) Co-authored-by: @onkarvhanumante --- adapters/bidder.go | 6 --- endpoints/openrtb2/amp_auction.go | 3 -- endpoints/openrtb2/auction.go | 14 ------ endpoints/openrtb2/auction_test.go | 11 ----- endpoints/openrtb2/video_auction.go | 4 -- exchange/bidder.go | 25 ++++++---- exchange/bidder_test.go | 69 +++++++++++++++------------ exchange/bidder_validate_bids.go | 6 +-- exchange/bidder_validate_bids_test.go | 13 ++--- exchange/exchange.go | 54 ++++++++------------- exchange/exchange_test.go | 4 +- 11 files changed, 88 insertions(+), 121 deletions(-) diff --git a/adapters/bidder.go b/adapters/bidder.go index 28fb555d5ae..6e1630579f5 100644 --- a/adapters/bidder.go +++ b/adapters/bidder.go @@ -149,12 +149,6 @@ type ExtraRequestInfo struct { BidderRequestStartTime time.Time GlobalPrivacyControlHeader string CurrencyConversions currency.Conversions - MakeBidsTimeInfo MakeBidsTimeInfo -} - -type MakeBidsTimeInfo struct { - AfterMakeBidsStartTime time.Time - Durations []time.Duration } func NewExtraRequestInfo(c currency.Conversions) ExtraRequestInfo { diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index 8d328b7c51a..a37c6874d2e 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -284,9 +284,6 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h } labels, ao = sendAmpResponse(w, hookExecutor, auctionResponse, reqWrapper, account, labels, ao, errL) - if len(ao.Errors) == 0 { - recordResponsePreparationMetrics(auctionRequest.MakeBidsTimeInfo, deps.metricsEngine) - } } func rejectAmpRequest( diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 3f01967a4c2..c5aa88dd722 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -27,7 +27,6 @@ import ( nativeRequests "github.com/prebid/openrtb/v19/native1/request" "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/openrtb/v19/openrtb3" - "github.com/prebid/prebid-server/adapters" "github.com/prebid/prebid-server/bidadjustment" "github.com/prebid/prebid-server/hooks" "github.com/prebid/prebid-server/ortb" @@ -280,9 +279,6 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http glog.Errorf("Error setting seat non-bid: %v", err) } labels, ao = sendAuctionResponse(w, hookExecutor, response, req.BidRequest, account, labels, ao) - if len(ao.Errors) == 0 { - recordResponsePreparationMetrics(auctionRequest.MakeBidsTimeInfo, deps.metricsEngine) - } } // setSeatNonBidRaw is transitional function for setting SeatNonBid inside bidResponse.Ext @@ -2446,13 +2442,3 @@ func validateStoredBidRespAndImpExtBidders(bidderExts map[string]json.RawMessage func generateStoredBidResponseValidationError(impID string) error { return fmt.Errorf("request validation failed. Stored bid responses are specified for imp %s. Bidders specified in imp.ext should match with bidders specified in imp.ext.prebid.storedbidresponse", impID) } - -func recordResponsePreparationMetrics(mbti map[openrtb_ext.BidderName]adapters.MakeBidsTimeInfo, me metrics.MetricsEngine) { - for _, info := range mbti { - duration := time.Since(info.AfterMakeBidsStartTime) - for _, makeBidsDuration := range info.Durations { - duration += makeBidsDuration - } - me.RecordOverheadTime(metrics.MakeAuctionResponse, duration) - } -} diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index e277411b7ef..c6604fcf9c9 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -22,7 +22,6 @@ import ( "github.com/prebid/openrtb/v19/native1" nativeRequests "github.com/prebid/openrtb/v19/native1/request" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" "github.com/prebid/prebid-server/analytics" analyticsConf "github.com/prebid/prebid-server/analytics/config" "github.com/prebid/prebid-server/config" @@ -39,7 +38,6 @@ import ( "github.com/prebid/prebid-server/util/iputil" "github.com/prebid/prebid-server/util/ptrutil" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" ) const jsonFileExtension string = ".json" @@ -5658,15 +5656,6 @@ func (e mockStageExecutor) GetOutcomes() []hookexecution.StageOutcome { return e.outcomes } -func TestRecordResponsePreparationMetrics(t *testing.T) { - mbi := map[openrtb_ext.BidderName]adapters.MakeBidsTimeInfo{ - openrtb_ext.BidderAppnexus: {Durations: []time.Duration{10, 15}, AfterMakeBidsStartTime: time.Now()}, - } - mockMetricEngine := &metrics.MetricsEngineMock{} - mockMetricEngine.On("RecordOverheadTime", metrics.MakeAuctionResponse, mock.Anything) - recordResponsePreparationMetrics(mbi, mockMetricEngine) -} - func TestSetSeatNonBidRaw(t *testing.T) { type args struct { request *openrtb_ext.RequestWrapper diff --git a/endpoints/openrtb2/video_auction.go b/endpoints/openrtb2/video_auction.go index 9401f4da1f9..d3731062b55 100644 --- a/endpoints/openrtb2/video_auction.go +++ b/endpoints/openrtb2/video_auction.go @@ -363,10 +363,6 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re return } - if len(vo.Errors) == 0 { - recordResponsePreparationMetrics(auctionRequest.MakeBidsTimeInfo, deps.metricsEngine) - } - w.Header().Set("Content-Type", "application/json") w.Write(resp) diff --git a/exchange/bidder.go b/exchange/bidder.go index f5efcff3edd..27012ff4aa2 100644 --- a/exchange/bidder.go +++ b/exchange/bidder.go @@ -58,7 +58,7 @@ type AdaptedBidder interface { // // Any errors will be user-facing in the API. // Error messages should help publishers understand what might account for "bad" bids. - requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes, hookExecutor hookexecution.StageExecutor, ruleToAdjustments openrtb_ext.AdjustmentsByDealID) ([]*entities.PbsOrtbSeatBid, []error) + requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes, hookExecutor hookexecution.StageExecutor, ruleToAdjustments openrtb_ext.AdjustmentsByDealID) ([]*entities.PbsOrtbSeatBid, extraBidderRespInfo, []error) } // bidRequestOptions holds additional options for bid request execution to maintain clean code and reasonable number of parameters @@ -69,6 +69,16 @@ type bidRequestOptions struct { bidAdjustments map[string]float64 } +type extraBidderRespInfo struct { + respProcessingStartTime time.Time +} + +type extraAuctionResponseInfo struct { + fledge *openrtb_ext.Fledge + bidsFound bool + bidderResponseStartTime time.Time +} + const ImpIdReqBody = "Stored bid response for impression id: " // Possible values of compression types Prebid Server can support for bidder compression @@ -117,16 +127,17 @@ type bidderAdapterConfig struct { EndpointCompression string } -func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes, hookExecutor hookexecution.StageExecutor, ruleToAdjustments openrtb_ext.AdjustmentsByDealID) ([]*entities.PbsOrtbSeatBid, []error) { +func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes, hookExecutor hookexecution.StageExecutor, ruleToAdjustments openrtb_ext.AdjustmentsByDealID) ([]*entities.PbsOrtbSeatBid, extraBidderRespInfo, []error) { reject := hookExecutor.ExecuteBidderRequestStage(bidderRequest.BidRequest, string(bidderRequest.BidderName)) if reject != nil { - return nil, []error{reject} + return nil, extraBidderRespInfo{}, []error{reject} } var ( reqData []*adapters.RequestData errs []error responseChannel chan *httpCallInfo + extraRespInfo extraBidderRespInfo ) //check if real request exists for this bidder or it only has stored responses @@ -139,7 +150,7 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest Bidde if len(errs) == 0 { errs = append(errs, &errortypes.FailedToRequestBids{Message: "The adapter failed to generate any bid requests, but also failed to generate an error explaining why"}) } - return nil, errs + return nil, extraBidderRespInfo{}, errs } xPrebidHeader := version.BuildXPrebidHeaderForRequest(bidderRequest.BidRequest, version.Ver) @@ -231,7 +242,7 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest Bidde } if httpInfo.err == nil { - startTime := time.Now() + extraRespInfo.respProcessingStartTime = time.Now() bidResponse, moreErrs := bidder.Bidder.MakeBids(bidderRequest.BidRequest, httpInfo.request, httpInfo.response) errs = append(errs, moreErrs...) @@ -373,18 +384,16 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest Bidde errs = append(errs, err) } } - reqInfo.MakeBidsTimeInfo.Durations = append(reqInfo.MakeBidsTimeInfo.Durations, time.Since(startTime)) } else { errs = append(errs, httpInfo.err) } } - reqInfo.MakeBidsTimeInfo.AfterMakeBidsStartTime = time.Now() seatBids := make([]*entities.PbsOrtbSeatBid, 0, len(seatBidMap)) for _, seatBid := range seatBidMap { seatBids = append(seatBids, seatBid) } - return seatBids, errs + return seatBids, extraRespInfo, errs } func addNativeTypes(bid *openrtb2.Bid, request *openrtb2.BidRequest) (*nativeResponse.Response, []error) { diff --git a/exchange/bidder_test.go b/exchange/bidder_test.go index 87d04185cba..9d36808ce31 100644 --- a/exchange/bidder_test.go +++ b/exchange/bidder_test.go @@ -110,11 +110,10 @@ func TestSingleBidder(t *testing.T) { bidAdjustments: bidAdjustments, } extraInfo := &adapters.ExtraRequestInfo{} - seatBids, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), extraInfo, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) - assert.NotEmpty(t, extraInfo.MakeBidsTimeInfo.Durations) - assert.False(t, extraInfo.MakeBidsTimeInfo.AfterMakeBidsStartTime.IsZero()) + seatBids, extraBidderRespInfo, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), extraInfo, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) assert.Len(t, seatBids, 1) + assert.False(t, extraBidderRespInfo.respProcessingStartTime.IsZero()) seatBid := seatBids[0] // Make sure the goodSingleBidder was called with the expected arguments. @@ -236,10 +235,9 @@ func TestSingleBidderGzip(t *testing.T) { bidAdjustments: bidAdjustments, } extraInfo := &adapters.ExtraRequestInfo{} - seatBids, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), extraInfo, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) - assert.NotEmpty(t, extraInfo.MakeBidsTimeInfo.Durations) - assert.False(t, extraInfo.MakeBidsTimeInfo.AfterMakeBidsStartTime.IsZero()) + seatBids, extraBidderRespInfo, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), extraInfo, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) assert.Len(t, seatBids, 1) + assert.False(t, extraBidderRespInfo.respProcessingStartTime.IsZero()) seatBid := seatBids[0] // Make sure the goodSingleBidder was called with the expected arguments. @@ -339,7 +337,7 @@ func TestRequestBidRemovesSensitiveHeaders(t *testing.T) { bidAdjustments: bidAdjustments, } extraInfo := &adapters.ExtraRequestInfo{} - seatBids, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), extraInfo, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) + seatBids, extraBidderRespInfo, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), extraInfo, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) expectedHttpCalls := []*openrtb_ext.ExtHttpCall{ { Uri: server.URL, @@ -352,8 +350,7 @@ func TestRequestBidRemovesSensitiveHeaders(t *testing.T) { assert.Empty(t, errs) assert.Len(t, seatBids, 1) - assert.NotEmpty(t, extraInfo.MakeBidsTimeInfo.Durations) - assert.False(t, extraInfo.MakeBidsTimeInfo.AfterMakeBidsStartTime.IsZero()) + assert.False(t, extraBidderRespInfo.respProcessingStartTime.IsZero()) assert.ElementsMatch(t, seatBids[0].HttpCalls, expectedHttpCalls) } @@ -393,7 +390,7 @@ func TestSetGPCHeader(t *testing.T) { bidAdjustments: bidAdjustments, } extraInfo := &adapters.ExtraRequestInfo{GlobalPrivacyControlHeader: "1"} - seatBids, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), extraInfo, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) + seatBids, extraBidderRespInfo, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), extraInfo, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) expectedHttpCall := []*openrtb_ext.ExtHttpCall{ { @@ -407,8 +404,7 @@ func TestSetGPCHeader(t *testing.T) { assert.Empty(t, errs) assert.Len(t, seatBids, 1) - assert.NotEmpty(t, extraInfo.MakeBidsTimeInfo.Durations) - assert.False(t, extraInfo.MakeBidsTimeInfo.AfterMakeBidsStartTime.IsZero()) + assert.False(t, extraBidderRespInfo.respProcessingStartTime.IsZero()) assert.ElementsMatch(t, seatBids[0].HttpCalls, expectedHttpCall) } @@ -446,7 +442,7 @@ func TestSetGPCHeaderNil(t *testing.T) { bidAdjustments: bidAdjustments, } extraInfo := &adapters.ExtraRequestInfo{GlobalPrivacyControlHeader: "1"} - seatBids, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), extraInfo, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) + seatBids, extraBidderRespInfo, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), extraInfo, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) expectedHttpCall := []*openrtb_ext.ExtHttpCall{ { @@ -459,9 +455,8 @@ func TestSetGPCHeaderNil(t *testing.T) { } assert.Empty(t, errs) - assert.NotEmpty(t, extraInfo.MakeBidsTimeInfo.Durations) - assert.False(t, extraInfo.MakeBidsTimeInfo.AfterMakeBidsStartTime.IsZero()) assert.Len(t, seatBids, 1) + assert.False(t, extraBidderRespInfo.respProcessingStartTime.IsZero()) assert.ElementsMatch(t, seatBids[0].HttpCalls, expectedHttpCall) } @@ -518,7 +513,7 @@ func TestMultiBidder(t *testing.T) { addCallSignHeader: false, bidAdjustments: bidAdjustments, } - seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) + seatBids, extraBidderRespInfo, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) if len(seatBids) != 1 { t.Fatalf("SeatBid should exist, because bids exist.") @@ -530,6 +525,7 @@ func TestMultiBidder(t *testing.T) { if len(seatBids[0].Bids) != len(bidderImpl.httpResponses)*len(mockBidderResponse.Bids) { t.Errorf("Expected %d bids. Got %d", len(bidderImpl.httpResponses)*len(mockBidderResponse.Bids), len(seatBids[0].Bids)) } + assert.False(t, extraBidderRespInfo.respProcessingStartTime.IsZero()) } @@ -885,7 +881,7 @@ func TestMultiCurrencies(t *testing.T) { BidderName: openrtb_ext.BidderAppnexus, } bidAdjustments := map[string]float64{string(openrtb_ext.BidderAppnexus): 1} - seatBids, errs := bidder.requestBid( + seatBids, extraBidderRespInfo, errs := bidder.requestBid( context.Background(), bidderReq, currencyConverter.Rates(), @@ -903,6 +899,7 @@ func TestMultiCurrencies(t *testing.T) { ) assert.Len(t, seatBids, 1) seatBid := seatBids[0] + assert.False(t, extraBidderRespInfo.respProcessingStartTime.IsZero()) // Verify: resultLightBids := make([]bid, len(seatBid.Bids)) @@ -1045,7 +1042,7 @@ func TestMultiCurrencies_RateConverterNotSet(t *testing.T) { BidderName: "test", } bidAdjustments := map[string]float64{"test": 1} - seatBids, errs := bidder.requestBid( + seatBids, extraBidderRespInfo, errs := bidder.requestBid( context.Background(), bidderReq, currencyConverter.Rates(), @@ -1068,6 +1065,7 @@ func TestMultiCurrencies_RateConverterNotSet(t *testing.T) { assert.Equal(t, false, (seatBid == nil && tc.expectedBidsCount != 0), tc.description) assert.Equal(t, tc.expectedBidsCount, uint(len(seatBid.Bids)), tc.description) assert.ElementsMatch(t, tc.expectedBadCurrencyErrors, errs, tc.description) + assert.False(t, extraBidderRespInfo.respProcessingStartTime.IsZero()) } } @@ -1224,7 +1222,7 @@ func TestMultiCurrencies_RequestCurrencyPick(t *testing.T) { BidderName: "test", } bidAdjustments := map[string]float64{"test": 1} - seatBids, errs := bidder.requestBid( + seatBids, extraBidderRespInfo, errs := bidder.requestBid( context.Background(), bidderReq, currencyConverter.Rates(), @@ -1249,6 +1247,7 @@ func TestMultiCurrencies_RequestCurrencyPick(t *testing.T) { } else { assert.Nil(t, errs, tc.description) assert.Equal(t, tc.expectedPickedCurrency, seatBid.Currency, tc.description) + assert.False(t, extraBidderRespInfo.respProcessingStartTime.IsZero()) } } } @@ -1542,7 +1541,7 @@ func TestMobileNativeTypes(t *testing.T) { BidderName: "test", } bidAdjustments := map[string]float64{"test": 1.0} - seatBids, _ := bidder.requestBid( + seatBids, extraBidderRespInfo, _ := bidder.requestBid( context.Background(), bidderReq, currencyConverter.Rates(), @@ -1559,7 +1558,7 @@ func TestMobileNativeTypes(t *testing.T) { nil, ) assert.Len(t, seatBids, 1) - + assert.False(t, extraBidderRespInfo.respProcessingStartTime.IsZero()) var actualValue string for _, bid := range seatBids[0].Bids { actualValue = bid.Bid.AdM @@ -1662,7 +1661,7 @@ func TestRequestBidsStoredBidResponses(t *testing.T) { ImpReplaceImpId: tc.impReplaceImpId, } bidAdjustments := map[string]float64{string(openrtb_ext.BidderAppnexus): 1.0} - seatBids, _ := bidder.requestBid( + seatBids, extraBidderRespInfo, _ := bidder.requestBid( context.Background(), bidderReq, currencyConverter.Rates(), @@ -1679,6 +1678,7 @@ func TestRequestBidsStoredBidResponses(t *testing.T) { nil, ) assert.Len(t, seatBids, 1) + assert.False(t, extraBidderRespInfo.respProcessingStartTime.IsZero()) assert.Len(t, seatBids[0].Bids, len(tc.expectedBidIds), "Incorrect bids number for test case ", tc.description) for _, bid := range seatBids[0].Bids { @@ -1777,7 +1777,7 @@ func TestFledge(t *testing.T) { }, BidderName: "openx", } - seatBids, _ := bidder.requestBid( + seatBids, extraBidderRespInfo, _ := bidder.requestBid( context.Background(), bidderReq, currencyConverter.Rates(), @@ -1798,6 +1798,7 @@ func TestFledge(t *testing.T) { assert.Len(t, seatBids[0].FledgeAuctionConfigs, len(tc.expectedFledge)) assert.ElementsMatch(t, seatBids[0].FledgeAuctionConfigs, tc.expectedFledge) + assert.False(t, extraBidderRespInfo.respProcessingStartTime.IsZero()) } } @@ -1815,7 +1816,7 @@ func TestErrorReporting(t *testing.T) { addCallSignHeader: false, bidAdjustments: bidAdjustments, } - bids, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) + bids, extraBidderRespInfo, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) if bids != nil { t.Errorf("There should be no seatbid if no http requests are returned.") } @@ -1825,6 +1826,7 @@ func TestErrorReporting(t *testing.T) { if errs[0].Error() != "Invalid params on BidRequest." { t.Errorf(`Error message was mutated. Expected "%s", Got "%s"`, "Invalid params on BidRequest.", errs[0].Error()) } + assert.True(t, extraBidderRespInfo.respProcessingStartTime.IsZero()) } func TestSetAssetTypes(t *testing.T) { @@ -2049,7 +2051,7 @@ func TestCallRecordAdapterConnections(t *testing.T) { addCallSignHeader: false, bidAdjustments: bidAdjustments, } - _, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{PbsEntryPoint: metrics.ReqTypeORTB2Web}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) + _, _, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{PbsEntryPoint: metrics.ReqTypeORTB2Web}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) // Assert no errors assert.Equal(t, 0, len(errs), "bidder.requestBid returned errors %v \n", errs) @@ -2296,7 +2298,7 @@ func TestRequestBidsWithAdsCertsSigner(t *testing.T) { addCallSignHeader: true, bidAdjustments: bidAdjustments, } - _, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &MockSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) + _, _, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &MockSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) assert.Empty(t, errs, "no errors should be returned") } @@ -2510,7 +2512,7 @@ func TestExtraBid(t *testing.T) { bidAdjustments: bidAdjustments, } - seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &MockSigner{}, bidReqOptions, + seatBids, extraBidderRespInfo, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &MockSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{ Enabled: true, Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{ @@ -2528,6 +2530,7 @@ func TestExtraBid(t *testing.T) { return len(seatBids[i].Seat) < len(seatBids[j].Seat) }) assert.Equal(t, wantSeatBids, seatBids) + assert.False(t, extraBidderRespInfo.respProcessingStartTime.IsZero()) } func TestExtraBidWithAlternateBidderCodeDisabled(t *testing.T) { @@ -2624,7 +2627,7 @@ func TestExtraBidWithAlternateBidderCodeDisabled(t *testing.T) { bidAdjustments: bidAdjustments, } - seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &MockSigner{}, bidReqOptions, + seatBids, extraBidderRespInfo, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &MockSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{ Enabled: true, Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{ @@ -2639,6 +2642,7 @@ func TestExtraBidWithAlternateBidderCodeDisabled(t *testing.T) { assert.Equal(t, wantErrs, errs) assert.Len(t, seatBids, 2) assert.ElementsMatch(t, wantSeatBids, seatBids) + assert.False(t, extraBidderRespInfo.respProcessingStartTime.IsZero()) } func TestExtraBidWithBidAdjustments(t *testing.T) { @@ -2735,7 +2739,7 @@ func TestExtraBidWithBidAdjustments(t *testing.T) { bidAdjustments: bidAdjustments, } - seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &MockSigner{}, bidReqOptions, + seatBids, extraBidderRespInfo, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &MockSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{ Enabled: true, Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{ @@ -2753,6 +2757,7 @@ func TestExtraBidWithBidAdjustments(t *testing.T) { return len(seatBids[i].Seat) < len(seatBids[j].Seat) }) assert.Equal(t, wantSeatBids, seatBids) + assert.False(t, extraBidderRespInfo.respProcessingStartTime.IsZero()) } func TestExtraBidWithBidAdjustmentsUsingAdapterCode(t *testing.T) { @@ -2848,7 +2853,7 @@ func TestExtraBidWithBidAdjustmentsUsingAdapterCode(t *testing.T) { bidAdjustments: bidAdjustments, } - seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &MockSigner{}, bidReqOptions, + seatBids, extraBidderRespInfo, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &MockSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{ Enabled: true, Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{ @@ -2866,6 +2871,7 @@ func TestExtraBidWithBidAdjustmentsUsingAdapterCode(t *testing.T) { return len(seatBids[i].Seat) < len(seatBids[j].Seat) }) assert.Equal(t, wantSeatBids, seatBids) + assert.False(t, extraBidderRespInfo.respProcessingStartTime.IsZero()) } func TestExtraBidWithMultiCurrencies(t *testing.T) { @@ -2973,7 +2979,7 @@ func TestExtraBidWithMultiCurrencies(t *testing.T) { bidAdjustments: bidAdjustments, } - seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &MockSigner{}, bidReqOptions, + seatBids, extraBidderRespInfo, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &MockSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{ Enabled: true, Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{ @@ -2991,6 +2997,7 @@ func TestExtraBidWithMultiCurrencies(t *testing.T) { return len(seatBids[i].Seat) < len(seatBids[j].Seat) }) assert.Equal(t, wantSeatBids, seatBids) + assert.False(t, extraBidderRespInfo.respProcessingStartTime.IsZero()) } func TestGetBidType(t *testing.T) { diff --git a/exchange/bidder_validate_bids.go b/exchange/bidder_validate_bids.go index 8283a674dac..9b5771a3497 100644 --- a/exchange/bidder_validate_bids.go +++ b/exchange/bidder_validate_bids.go @@ -31,14 +31,14 @@ type validatedBidder struct { bidder AdaptedBidder } -func (v *validatedBidder) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes, hookExecutor hookexecution.StageExecutor, ruleToAdjustments openrtb_ext.AdjustmentsByDealID) ([]*entities.PbsOrtbSeatBid, []error) { - seatBids, errs := v.bidder.requestBid(ctx, bidderRequest, conversions, reqInfo, adsCertSigner, bidRequestOptions, alternateBidderCodes, hookExecutor, ruleToAdjustments) +func (v *validatedBidder) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes, hookExecutor hookexecution.StageExecutor, ruleToAdjustments openrtb_ext.AdjustmentsByDealID) ([]*entities.PbsOrtbSeatBid, extraBidderRespInfo, []error) { + seatBids, extraBidderRespInfo, errs := v.bidder.requestBid(ctx, bidderRequest, conversions, reqInfo, adsCertSigner, bidRequestOptions, alternateBidderCodes, hookExecutor, ruleToAdjustments) for _, seatBid := range seatBids { if validationErrors := removeInvalidBids(bidderRequest.BidRequest, seatBid); len(validationErrors) > 0 { errs = append(errs, validationErrors...) } } - return seatBids, errs + return seatBids, extraBidderRespInfo, errs } // validateBids will run some validation checks on the returned bids and excise any invalid bids diff --git a/exchange/bidder_validate_bids_test.go b/exchange/bidder_validate_bids_test.go index e7340e7d89b..ed6173b64ad 100644 --- a/exchange/bidder_validate_bids_test.go +++ b/exchange/bidder_validate_bids_test.go @@ -65,7 +65,7 @@ func TestAllValidBids(t *testing.T) { addCallSignHeader: false, bidAdjustments: bidAdjustments, } - seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currency.NewConstantRates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) + seatBids, _, errs := bidder.requestBid(context.Background(), bidderReq, currency.NewConstantRates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) assert.Len(t, seatBids, 1) assert.Len(t, seatBids[0].Bids, 4) assert.Len(t, errs, 0) @@ -135,7 +135,7 @@ func TestAllBadBids(t *testing.T) { addCallSignHeader: false, bidAdjustments: bidAdjustments, } - seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currency.NewConstantRates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) + seatBids, _, errs := bidder.requestBid(context.Background(), bidderReq, currency.NewConstantRates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) assert.Len(t, seatBids, 1) assert.Len(t, seatBids[0].Bids, 0) assert.Len(t, errs, 7) @@ -216,7 +216,7 @@ func TestMixedBids(t *testing.T) { addCallSignHeader: false, bidAdjustments: bidAdjustments, } - seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currency.NewConstantRates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) + seatBids, _, errs := bidder.requestBid(context.Background(), bidderReq, currency.NewConstantRates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) assert.Len(t, seatBids, 1) assert.Len(t, seatBids[0].Bids, 3) assert.Len(t, errs, 5) @@ -345,7 +345,7 @@ func TestCurrencyBids(t *testing.T) { addCallSignHeader: false, bidAdjustments: bidAdjustments, } - seatBids, errs := bidder.requestBid(context.Background(), bidderRequest, currency.NewConstantRates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) + seatBids, _, errs := bidder.requestBid(context.Background(), bidderRequest, currency.NewConstantRates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) assert.Len(t, seatBids, 1) assert.Len(t, seatBids[0].Bids, expectedValidBids) assert.Len(t, errs, expectedErrs) @@ -354,9 +354,10 @@ func TestCurrencyBids(t *testing.T) { type mockAdaptedBidder struct { bidResponse []*entities.PbsOrtbSeatBid + extraRespInfo extraBidderRespInfo errorResponse []error } -func (b *mockAdaptedBidder) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestMetadata bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes, executor hookexecution.StageExecutor, ruleToAdjustments openrtb_ext.AdjustmentsByDealID) ([]*entities.PbsOrtbSeatBid, []error) { - return b.bidResponse, b.errorResponse +func (b *mockAdaptedBidder) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestMetadata bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes, executor hookexecution.StageExecutor, ruleToAdjustments openrtb_ext.AdjustmentsByDealID) ([]*entities.PbsOrtbSeatBid, extraBidderRespInfo, []error) { + return b.bidResponse, b.extraRespInfo, b.errorResponse } diff --git a/exchange/exchange.go b/exchange/exchange.go index 07dce45a185..e1a9868db7a 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -89,15 +89,15 @@ type seatResponseExtra struct { Warnings []openrtb_ext.ExtBidderMessage // httpCalls is the list of debugging info. It should only be populated if the request.test == 1. // This will become response.ext.debug.httpcalls.{bidder} on the final Response. - HttpCalls []*openrtb_ext.ExtHttpCall - MakeBidsTimeInfo adapters.MakeBidsTimeInfo + HttpCalls []*openrtb_ext.ExtHttpCall } type bidResponseWrapper struct { - adapterSeatBids []*entities.PbsOrtbSeatBid - adapterExtra *seatResponseExtra - bidder openrtb_ext.BidderName - adapter openrtb_ext.BidderName + adapterSeatBids []*entities.PbsOrtbSeatBid + adapterExtra *seatResponseExtra + bidder openrtb_ext.BidderName + adapter openrtb_ext.BidderName + bidderResponseStartTime time.Time } type BidIDGenerator interface { @@ -210,8 +210,6 @@ type AuctionRequest struct { PubID string HookExecutor hookexecution.StageExecutor QueryParams url.Values - // map of bidder to store duration needed for the MakeBids() calls and start time after MakeBids() calls - MakeBidsTimeInfo map[openrtb_ext.BidderName]adapters.MakeBidsTimeInfo } // BidderRequest holds the bidder specific request and all other @@ -368,8 +366,10 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog } else if r.Account.AlternateBidderCodes != nil { alternateBidderCodes = *r.Account.AlternateBidderCodes } - adapterBids, adapterExtra, fledge, anyBidsReturned = e.getAllBids(auctionCtx, bidderRequests, bidAdjustmentFactors, conversions, accountDebugAllow, r.GlobalPrivacyControlHeader, debugLog.DebugOverride, alternateBidderCodes, requestExtLegacy.Prebid.Experiment, r.HookExecutor, r.StartTime, bidAdjustmentRules) - r.MakeBidsTimeInfo = buildMakeBidsTimeInfoMap(adapterExtra) + var extraRespInfo extraAuctionResponseInfo + adapterBids, adapterExtra, extraRespInfo = e.getAllBids(auctionCtx, bidderRequests, bidAdjustmentFactors, conversions, accountDebugAllow, r.GlobalPrivacyControlHeader, debugLog.DebugOverride, alternateBidderCodes, requestExtLegacy.Prebid.Experiment, r.HookExecutor, r.StartTime, bidAdjustmentRules) + fledge = extraRespInfo.fledge + anyBidsReturned = extraRespInfo.bidsFound } var ( @@ -504,14 +504,6 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog }, nil } -func buildMakeBidsTimeInfoMap(adapterExtra map[openrtb_ext.BidderName]*seatResponseExtra) map[openrtb_ext.BidderName]adapters.MakeBidsTimeInfo { - makeBidsInfoMap := make(map[openrtb_ext.BidderName]adapters.MakeBidsTimeInfo) - for bidderName, responseExtra := range adapterExtra { - makeBidsInfoMap[bidderName] = responseExtra.MakeBidsTimeInfo - } - return makeBidsInfoMap -} - func buildMultiBidMap(prebid *openrtb_ext.ExtRequestPrebid) map[string]openrtb_ext.ExtMultiBid { if prebid == nil || prebid.MultiBid == nil { return nil @@ -669,13 +661,12 @@ func (e *exchange) getAllBids( bidAdjustmentRules map[string][]openrtb_ext.Adjustment) ( map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid, map[openrtb_ext.BidderName]*seatResponseExtra, - *openrtb_ext.Fledge, - bool) { + extraAuctionResponseInfo) { // Set up pointers to the bid results adapterBids := make(map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid, len(bidderRequests)) adapterExtra := make(map[openrtb_ext.BidderName]*seatResponseExtra, len(bidderRequests)) chBids := make(chan *bidResponseWrapper, len(bidderRequests)) - bidsFound := false + extraRespInfo := extraAuctionResponseInfo{} e.me.RecordOverheadTime(metrics.MakeBidderRequests, time.Since(pbsRequestStartTime)) @@ -707,7 +698,8 @@ func (e *exchange) getAllBids( addCallSignHeader: isAdsCertEnabled(experiment, e.bidderInfo[string(bidderRequest.BidderName)]), bidAdjustments: bidAdjustments, } - seatBids, err := e.adapterMap[bidderRequest.BidderCoreName].requestBid(ctx, bidderRequest, conversions, &reqInfo, e.adsCertSigner, bidReqOptions, alternateBidderCodes, hookExecutor, bidAdjustmentRules) + seatBids, extraBidderRespInfo, err := e.adapterMap[bidderRequest.BidderCoreName].requestBid(ctx, bidderRequest, conversions, &reqInfo, e.adsCertSigner, bidReqOptions, alternateBidderCodes, hookExecutor, bidAdjustmentRules) + brw.bidderResponseStartTime = extraBidderRespInfo.respProcessingStartTime // Add in time reporting elapsed := time.Since(start) @@ -718,11 +710,6 @@ func (e *exchange) getAllBids( if len(seatBids) != 0 { ae.HttpCalls = seatBids[0].HttpCalls } - // SeatBidsPreparationStartTime is needed to calculate duration for openrtb response preparation time metric - // No metric needs to be logged for requests which error out - if err == nil { - ae.MakeBidsTimeInfo = reqInfo.MakeBidsTimeInfo - } // Timing statistics e.me.RecordAdapterTime(bidderRequest.BidderLabels, elapsed) bidderRequest.BidderLabels.AdapterBids = bidsToMetric(brw.adapterSeatBids) @@ -744,12 +731,13 @@ func (e *exchange) getAllBids( }, chBids) go bidderRunner(bidder, conversions) } - var fledge *openrtb_ext.Fledge // Wait for the bidders to do their thing for i := 0; i < len(bidderRequests); i++ { brw := <-chBids - + if !brw.bidderResponseStartTime.IsZero() { + extraRespInfo.bidderResponseStartTime = brw.bidderResponseStartTime + } //if bidder returned no bids back - remove bidder from further processing for _, seatBid := range brw.adapterSeatBids { if seatBid != nil { @@ -762,18 +750,18 @@ func (e *exchange) getAllBids( } } // collect fledgeAuctionConfigs separately from bids, as empty seatBids may be discarded - fledge = collectFledgeFromSeatBid(fledge, bidderName, brw.adapter, seatBid) + extraRespInfo.fledge = collectFledgeFromSeatBid(extraRespInfo.fledge, bidderName, brw.adapter, seatBid) } } //but we need to add all bidders data to adapterExtra to have metrics and other metadata adapterExtra[brw.bidder] = brw.adapterExtra - if !bidsFound && adapterBids[brw.bidder] != nil && len(adapterBids[brw.bidder].Bids) > 0 { - bidsFound = true + if !extraRespInfo.bidsFound && adapterBids[brw.bidder] != nil && len(adapterBids[brw.bidder].Bids) > 0 { + extraRespInfo.bidsFound = true } } - return adapterBids, adapterExtra, fledge, bidsFound + return adapterBids, adapterExtra, extraRespInfo } func collectFledgeFromSeatBid(fledge *openrtb_ext.Fledge, bidderName openrtb_ext.BidderName, adapterName openrtb_ext.BidderName, seatBid *entities.PbsOrtbSeatBid) *openrtb_ext.Fledge { diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go index 8306849a762..2a35ef57777 100644 --- a/exchange/exchange_test.go +++ b/exchange/exchange_test.go @@ -5271,7 +5271,7 @@ type validatingBidder struct { mockResponses map[string]bidderResponse } -func (b *validatingBidder) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes, executor hookexecution.StageExecutor, ruleToAdjustments openrtb_ext.AdjustmentsByDealID) (seatBids []*entities.PbsOrtbSeatBid, errs []error) { +func (b *validatingBidder) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes, executor hookexecution.StageExecutor, ruleToAdjustments openrtb_ext.AdjustmentsByDealID) (seatBids []*entities.PbsOrtbSeatBid, extaInfo extraBidderRespInfo, errs []error) { if expectedRequest, ok := b.expectations[string(bidderRequest.BidderName)]; ok { if expectedRequest != nil { if !reflect.DeepEqual(expectedRequest.BidAdjustments, bidRequestOptions.bidAdjustments) { @@ -5437,7 +5437,7 @@ func (e *emptyUsersync) HasAnyLiveSyncs() bool { type panicingAdapter struct{} -func (panicingAdapter) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestMetadata bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes, executor hookexecution.StageExecutor, ruleToAdjustments openrtb_ext.AdjustmentsByDealID) (posb []*entities.PbsOrtbSeatBid, errs []error) { +func (panicingAdapter) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestMetadata bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes, executor hookexecution.StageExecutor, ruleToAdjustments openrtb_ext.AdjustmentsByDealID) (posb []*entities.PbsOrtbSeatBid, extraInfo extraBidderRespInfo, errs []error) { panic("Panic! Panic! The world is ending!") } From fab30546bb2a590883dfb0504a1a65736305bb5d Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Mon, 17 Jul 2023 20:12:31 +0530 Subject: [PATCH 022/268] narrow down permission to pull request (#2933) Co-authored-by: oh0387 --- .github/workflows/semgrep.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml index 87c5573e671..978a3b0c53c 100644 --- a/.github/workflows/semgrep.yml +++ b/.github/workflows/semgrep.yml @@ -2,7 +2,8 @@ name: Adapter semgrep checks on: pull_request: paths: ["adapters/*/*.go"] -permissions: write-all +permissions: + pull-requests: write jobs: semgrep-check: runs-on: ubuntu-latest From 8aec25fb4663358940d8363328034fa037137fca Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Mon, 17 Jul 2023 20:56:43 +0530 Subject: [PATCH 023/268] use `pull_request_target` (#2934) Co-authored-by: oh0387 --- .github/workflows/semgrep.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml index 978a3b0c53c..a541dd9d861 100644 --- a/.github/workflows/semgrep.yml +++ b/.github/workflows/semgrep.yml @@ -1,6 +1,6 @@ name: Adapter semgrep checks on: - pull_request: + pull_request_target: paths: ["adapters/*/*.go"] permissions: pull-requests: write From be632e078f9764f377a99462341617f0e9dd2c45 Mon Sep 17 00:00:00 2001 From: guscarreon Date: Mon, 17 Jul 2023 13:15:14 -0400 Subject: [PATCH 024/268] GPP in the setuid endpoint (#2761) --- endpoints/setuid.go | 175 +++++++++-- endpoints/setuid_test.go | 618 ++++++++++++++++++++++++++++++++++++++- errortypes/errortypes.go | 3 +- errortypes/severity.go | 7 +- privacy/gpp/gpp.go | 7 +- 5 files changed, 781 insertions(+), 29 deletions(-) diff --git a/endpoints/setuid.go b/endpoints/setuid.go index a4d04749eae..0b832f6f324 100644 --- a/endpoints/setuid.go +++ b/endpoints/setuid.go @@ -3,6 +3,7 @@ package endpoints import ( "context" "errors" + "fmt" "net/http" "net/url" "strconv" @@ -10,14 +11,19 @@ import ( "time" "github.com/julienschmidt/httprouter" + gpplib "github.com/prebid/go-gpp" + gppConstants "github.com/prebid/go-gpp/constants" accountService "github.com/prebid/prebid-server/account" "github.com/prebid/prebid-server/analytics" "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/gdpr" "github.com/prebid/prebid-server/metrics" + gppPrivacy "github.com/prebid/prebid-server/privacy/gpp" "github.com/prebid/prebid-server/stored_requests" "github.com/prebid/prebid-server/usersync" "github.com/prebid/prebid-server/util/httputil" + stringutil "github.com/prebid/prebid-server/util/stringutil" ) const ( @@ -101,9 +107,23 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use return } + gdprRequestInfo, err := extractGDPRInfo(query) + if err != nil { + // Only exit if non-warning + if !errortypes.IsWarning(err) { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) + metricsEngine.RecordSetUid(metrics.SetUidBadRequest) + so.Errors = []error{err} + so.Status = http.StatusBadRequest + return + } + w.Write([]byte("Warning: " + err.Error())) + } + tcf2Cfg := tcf2CfgBuilder(cfg.GDPR.TCF2, account.GDPR) - if shouldReturn, status, body := preventSyncsGDPR(query.Get("gdpr"), query.Get("gdpr_consent"), gdprPermsBuilder, tcf2Cfg); shouldReturn { + if shouldReturn, status, body := preventSyncsGDPR(gdprRequestInfo, gdprPermsBuilder, tcf2Cfg); shouldReturn { w.WriteHeader(status) w.Write([]byte(body)) switch status { @@ -148,6 +168,138 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use }) } +// extractGDPRInfo looks for the GDPR consent string and GDPR signal in the GPP query params +// first and the 'gdpr' and 'gdpr_consent' query params second. If found in both, throws a +// warning. Can also throw a parsing or validation error +func extractGDPRInfo(query url.Values) (reqInfo gdpr.RequestInfo, err error) { + + reqInfo, err = parseGDPRFromGPP(query) + if err != nil { + return gdpr.RequestInfo{GDPRSignal: gdpr.SignalAmbiguous}, err + } + + legacySignal, legacyConsent, err := parseLegacyGDPRFields(query, reqInfo.GDPRSignal, reqInfo.Consent) + isWarning := errortypes.IsWarning(err) + + if err != nil && !isWarning { + return gdpr.RequestInfo{GDPRSignal: gdpr.SignalAmbiguous}, err + } + + // If no GDPR data in the GPP fields, use legacy instead + if reqInfo.Consent == "" && reqInfo.GDPRSignal == gdpr.SignalAmbiguous { + reqInfo.GDPRSignal = legacySignal + reqInfo.Consent = legacyConsent + } + + if reqInfo.Consent == "" && reqInfo.GDPRSignal == gdpr.SignalYes { + return gdpr.RequestInfo{GDPRSignal: gdpr.SignalAmbiguous}, errors.New("GDPR consent is required when gdpr signal equals 1") + } + + return reqInfo, err +} + +// parseGDPRFromGPP parses and validates the "gpp_sid" and "gpp" query fields. +func parseGDPRFromGPP(query url.Values) (gdpr.RequestInfo, error) { + var gdprSignal gdpr.Signal = gdpr.SignalAmbiguous + var gdprConsent string = "" + var err error + + gdprSignal, err = parseSignalFromGppSidStr(query.Get("gpp_sid")) + if err != nil { + return gdpr.RequestInfo{GDPRSignal: gdpr.SignalAmbiguous}, err + } + + gdprConsent, err = parseConsentFromGppStr(query.Get("gpp")) + if err != nil { + return gdpr.RequestInfo{GDPRSignal: gdpr.SignalAmbiguous}, err + } + + return gdpr.RequestInfo{ + Consent: gdprConsent, + GDPRSignal: gdprSignal, + }, nil +} + +// parseLegacyGDPRFields parses and validates the "gdpr" and "gdpr_consent" query fields which +// are considered deprecated in favor of the "gpp" and "gpp_sid". The parsed and validated GDPR +// values contained in "gpp" and "gpp_sid" are passed in the parameters gppGDPRSignal and +// gppGDPRConsent. If the GPP parameters come with non-default values, this function discards +// "gdpr" and "gdpr_consent" and returns a warning. +func parseLegacyGDPRFields(query url.Values, gppGDPRSignal gdpr.Signal, gppGDPRConsent string) (gdpr.Signal, string, error) { + var gdprSignal gdpr.Signal = gdpr.SignalAmbiguous + var gdprConsent string + var warning error + + if gdprQuerySignal := query.Get("gdpr"); len(gdprQuerySignal) > 0 { + if gppGDPRSignal == gdpr.SignalAmbiguous { + switch gdprQuerySignal { + case "0": + fallthrough + case "1": + if zeroOrOne, err := strconv.Atoi(gdprQuerySignal); err == nil { + gdprSignal = gdpr.Signal(zeroOrOne) + } + default: + return gdpr.SignalAmbiguous, "", errors.New("the gdpr query param must be either 0 or 1. You gave " + gdprQuerySignal) + } + } else { + warning = &errortypes.Warning{ + Message: "'gpp_sid' signal value will be used over the one found in the deprecated 'gdpr' field.", + WarningCode: errortypes.UnknownWarningCode, + } + } + } + + if gdprLegacyConsent := query.Get("gdpr_consent"); len(gdprLegacyConsent) > 0 { + if len(gppGDPRConsent) > 0 { + warning = &errortypes.Warning{ + Message: "'gpp' value will be used over the one found in the deprecated 'gdpr_consent' field.", + WarningCode: errortypes.UnknownWarningCode, + } + } else { + gdprConsent = gdprLegacyConsent + } + } + return gdprSignal, gdprConsent, warning +} + +func parseSignalFromGppSidStr(strSID string) (gdpr.Signal, error) { + gdprSignal := gdpr.SignalAmbiguous + + if len(strSID) > 0 { + gppSID, err := stringutil.StrToInt8Slice(strSID) + if err != nil { + return gdpr.SignalAmbiguous, fmt.Errorf("Error parsing gpp_sid %s", err.Error()) + } + + if len(gppSID) > 0 { + gdprSignal = gdpr.SignalNo + if gppPrivacy.IsSIDInList(gppSID, gppConstants.SectionTCFEU2) { + gdprSignal = gdpr.SignalYes + } + } + } + + return gdprSignal, nil +} + +func parseConsentFromGppStr(gppQueryValue string) (string, error) { + var gdprConsent string + + if len(gppQueryValue) > 0 { + gpp, err := gpplib.Parse(gppQueryValue) + if err != nil { + return "", err + } + + if i := gppPrivacy.IndexOfSID(gpp, gppConstants.SectionTCFEU2); i >= 0 { + gdprConsent = gpp.Sections[i].GetValue() + } + } + + return gdprConsent, nil +} + func getSyncer(query url.Values, syncersByKey map[string]usersync.Syncer) (usersync.Syncer, error) { key := query.Get("bidder") @@ -216,26 +368,7 @@ func checkChromeBrowserVersion(ua string, index int, chromeStrLength int) bool { return result } -func preventSyncsGDPR(gdprEnabled string, gdprConsent string, permsBuilder gdpr.PermissionsBuilder, tcf2Cfg gdpr.TCF2ConfigReader) (shouldReturn bool, status int, body string) { - if gdprEnabled != "" && gdprEnabled != "0" && gdprEnabled != "1" { - return true, http.StatusBadRequest, "the gdpr query param must be either 0 or 1. You gave " + gdprEnabled - } - - if gdprEnabled == "1" && gdprConsent == "" { - return true, http.StatusBadRequest, "gdpr_consent is required when gdpr=1" - } - - gdprSignal := gdpr.SignalAmbiguous - - if i, err := strconv.Atoi(gdprEnabled); err == nil { - gdprSignal = gdpr.Signal(i) - } - - gdprRequestInfo := gdpr.RequestInfo{ - Consent: gdprConsent, - GDPRSignal: gdprSignal, - } - +func preventSyncsGDPR(gdprRequestInfo gdpr.RequestInfo, permsBuilder gdpr.PermissionsBuilder, tcf2Cfg gdpr.TCF2ConfigReader) (shouldReturn bool, status int, body string) { perms := permsBuilder(tcf2Cfg, gdprRequestInfo) allowed, err := perms.HostCookiesAllowed(context.Background()) diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go index 609d85395fd..b927f339403 100644 --- a/endpoints/setuid_test.go +++ b/endpoints/setuid_test.go @@ -13,6 +13,7 @@ import ( "github.com/prebid/prebid-server/analytics" "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/gdpr" "github.com/prebid/prebid-server/metrics" "github.com/prebid/prebid-server/openrtb_ext" @@ -157,7 +158,7 @@ func TestSetUIDEndpoint(t *testing.T) { expectedSyncs: nil, gdprAllowsHostCookies: true, expectedStatusCode: http.StatusBadRequest, - expectedBody: "gdpr_consent is required when gdpr=1", + expectedBody: "GDPR consent is required when gdpr signal equals 1", description: "Return an error if GDPR is set to 1 but GDPR consent string is missing", }, { @@ -193,6 +194,28 @@ func TestSetUIDEndpoint(t *testing.T) { expectedHeaders: map[string]string{"Content-Type": "text/html", "Content-Length": "0"}, description: "Should set uid for a bidder that is allowed by the GDPR consent string", }, + { + uri: "/setuid?bidder=pubmatic&uid=123&gpp_sid=2,4&gpp=DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + syncersBidderNameToKey: map[string]string{"pubmatic": "pubmatic"}, + gdprAllowsHostCookies: true, + existingSyncs: nil, + expectedSyncs: map[string]string{"pubmatic": "123"}, + expectedStatusCode: http.StatusOK, + expectedHeaders: map[string]string{"Content-Type": "text/html", "Content-Length": "0"}, + description: "Sets uid for a bidder allowed by GDPR consent string in the GPP query field", + }, + { + uri: "/setuid?bidder=pubmatic&uid=123&gpp_sid=2,4&gpp=DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA" + + "gdpr=1&gdpr_consent=BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw", + syncersBidderNameToKey: map[string]string{"pubmatic": "pubmatic"}, + gdprAllowsHostCookies: true, + existingSyncs: nil, + expectedSyncs: map[string]string{"pubmatic": "123"}, + expectedStatusCode: http.StatusOK, + expectedBody: "Warning: 'gpp' value will be used over the one found in the deprecated 'gdpr_consent' field.", + expectedHeaders: map[string]string{"Content-Type": "text/plain; charset=utf-8"}, + description: "Sets uid for a bidder allowed by GDPR in GPP, throws warning because GDPR legacy values weren't used", + }, { uri: "/setuid?bidder=pubmatic&uid=123&gdpr=1&gdpr_consent=" + "malformed", @@ -288,6 +311,597 @@ func TestSetUIDEndpoint(t *testing.T) { } } +func TestParseSignalFromGPPSID(t *testing.T) { + type testOutput struct { + signal gdpr.Signal + err error + } + testCases := []struct { + desc string + strSID string + expected testOutput + }{ + { + desc: "Empty gpp_sid, expect gdpr.SignalAmbiguous", + strSID: "", + expected: testOutput{ + signal: gdpr.SignalAmbiguous, + err: nil, + }, + }, + { + desc: "Malformed gpp_sid, expect gdpr.SignalAmbiguous", + strSID: "malformed", + expected: testOutput{ + signal: gdpr.SignalAmbiguous, + err: errors.New(`Error parsing gpp_sid strconv.ParseInt: parsing "malformed": invalid syntax`), + }, + }, + { + desc: "Valid gpp_sid doesn't come with TCF2, expect gdpr.SignalNo", + strSID: "6", + expected: testOutput{ + signal: gdpr.SignalNo, + err: nil, + }, + }, + { + desc: "Valid gpp_sid comes with TCF2, expect gdpr.SignalYes", + strSID: "2", + expected: testOutput{ + signal: gdpr.SignalYes, + err: nil, + }, + }, + } + for _, tc := range testCases { + outSignal, outErr := parseSignalFromGppSidStr(tc.strSID) + + assert.Equal(t, tc.expected.signal, outSignal, tc.desc) + assert.Equal(t, tc.expected.err, outErr, tc.desc) + } +} + +func TestParseConsentFromGppStr(t *testing.T) { + type testOutput struct { + gdprConsent string + err error + } + testCases := []struct { + desc string + inGppQuery string + expected testOutput + }{ + { + desc: "Empty gpp field, expect empty GDPR consent", + inGppQuery: "", + expected: testOutput{ + gdprConsent: "", + err: nil, + }, + }, + { + desc: "Malformed gpp field value, expect empty GDPR consent and error", + inGppQuery: "malformed", + expected: testOutput{ + gdprConsent: "", + err: errors.New(`error parsing GPP header, base64 decoding: illegal base64 data at input byte 8`), + }, + }, + { + desc: "Valid gpp string comes with TCF2 in its gppConstants.SectionID's, expect non-empty GDPR consent", + inGppQuery: "DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + expected: testOutput{ + gdprConsent: "CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + err: nil, + }, + }, + { + desc: "Valid gpp string doesn't come with TCF2 in its gppConstants.SectionID's, expect blank GDPR consent", + inGppQuery: "DBABjw~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN", + expected: testOutput{ + gdprConsent: "", + err: nil, + }, + }, + } + for _, tc := range testCases { + outConsent, outErr := parseConsentFromGppStr(tc.inGppQuery) + + assert.Equal(t, tc.expected.gdprConsent, outConsent, tc.desc) + assert.Equal(t, tc.expected.err, outErr, tc.desc) + } +} + +func TestParseGDPRFromGPP(t *testing.T) { + type testOutput struct { + reqInfo gdpr.RequestInfo + err error + } + type aTest struct { + desc string + inUri string + expected testOutput + } + testGroups := []struct { + groupDesc string + testCases []aTest + }{ + { + groupDesc: "No gpp_sid nor gpp", + testCases: []aTest{ + { + desc: "Input URL is mising gpp_sid and gpp, expect signal ambiguous and no error", + inUri: "/setuid?bidder=pubmatic&uid=123", + expected: testOutput{ + reqInfo: gdpr.RequestInfo{GDPRSignal: gdpr.SignalAmbiguous}, + err: nil, + }, + }, + }, + }, + { + groupDesc: "gpp only", + testCases: []aTest{ + { + desc: "gpp is malformed, expect error", + inUri: "/setuid?gpp=malformed", + expected: testOutput{ + reqInfo: gdpr.RequestInfo{GDPRSignal: gdpr.SignalAmbiguous}, + err: errors.New("error parsing GPP header, base64 decoding: illegal base64 data at input byte 8"), + }, + }, + { + desc: "gpp with a valid TCF2 value. Expect valid consent string and no error", + inUri: "/setuid?gpp=DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + expected: testOutput{ + reqInfo: gdpr.RequestInfo{ + GDPRSignal: gdpr.SignalAmbiguous, + Consent: "CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + }, + err: nil, + }, + }, + { + desc: "gpp does not include TCF2 string. Expect empty consent string and no error", + inUri: "/setuid?gpp=DBABjw~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN", + expected: testOutput{ + reqInfo: gdpr.RequestInfo{ + GDPRSignal: gdpr.SignalAmbiguous, + Consent: "", + }, + err: nil, + }, + }, + }, + }, + { + groupDesc: "gpp_sid only", + testCases: []aTest{ + { + desc: "gpp_sid is malformed, expect error", + inUri: "/setuid?gpp_sid=malformed", + expected: testOutput{ + reqInfo: gdpr.RequestInfo{GDPRSignal: gdpr.SignalAmbiguous}, + err: errors.New("Error parsing gpp_sid strconv.ParseInt: parsing \"malformed\": invalid syntax"), + }, + }, + { + desc: "TCF2 found in gpp_sid list. Given that the consent string will be empty, expect an error", + inUri: "/setuid?gpp_sid=2,6", + expected: testOutput{ + reqInfo: gdpr.RequestInfo{GDPRSignal: gdpr.SignalYes}, + err: nil, + }, + }, + { + desc: "TCF2 not found in gpp_sid list. Expect SignalNo and no error", + inUri: "/setuid?gpp_sid=6,8", + expected: testOutput{ + reqInfo: gdpr.RequestInfo{GDPRSignal: gdpr.SignalNo}, + err: nil, + }, + }, + }, + }, + { + groupDesc: "both gpp_sid and gpp", + testCases: []aTest{ + { + desc: "TCF2 found in gpp_sid list and gpp has a valid GDPR string. Expect no error", + inUri: "/setuid?gpp_sid=2,6&gpp=DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + expected: testOutput{ + reqInfo: gdpr.RequestInfo{ + GDPRSignal: gdpr.SignalYes, + Consent: "CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + }, + err: nil, + }, + }, + }, + }, + } + for _, tgroup := range testGroups { + for _, tc := range tgroup.testCases { + // set test + testURL, err := url.Parse(tc.inUri) + assert.NoError(t, err, "%s - %s", tgroup.groupDesc, tc.desc) + + query := testURL.Query() + + // run + outReqInfo, outErr := parseGDPRFromGPP(query) + + // assertions + assert.Equal(t, tc.expected.reqInfo, outReqInfo, "%s - %s", tgroup.groupDesc, tc.desc) + assert.Equal(t, tc.expected.err, outErr, "%s - %s", tgroup.groupDesc, tc.desc) + } + } +} + +func TestParseLegacyGDPRFields(t *testing.T) { + type testInput struct { + uri string + gppGDPRSignal gdpr.Signal + gppGDPRConsent string + } + type testOutput struct { + signal gdpr.Signal + consent string + err error + } + testCases := []struct { + desc string + in testInput + expected testOutput + }{ + { + desc: `both "gdpr" and "gdpr_consent" missing from URI, expect SignalAmbiguous, blank consent and no error`, + in: testInput{ + uri: "/setuid?bidder=pubmatic&uid=123", + }, + expected: testOutput{ + signal: gdpr.SignalAmbiguous, + consent: "", + err: nil, + }, + }, + { + desc: `invalid "gdpr" value, expect SignalAmbiguous, blank consent and error`, + in: testInput{ + uri: "/setuid?gdpr=2", + gppGDPRSignal: gdpr.SignalAmbiguous, + }, + expected: testOutput{ + signal: gdpr.SignalAmbiguous, + consent: "", + err: errors.New("the gdpr query param must be either 0 or 1. You gave 2"), + }, + }, + { + desc: `valid "gdpr" value but valid GDPRSignal was previously parsed before, expect SignalAmbiguous, blank consent and a warning`, + in: testInput{ + uri: "/setuid?gdpr=1", + gppGDPRSignal: gdpr.SignalYes, + }, + expected: testOutput{ + signal: gdpr.SignalAmbiguous, + consent: "", + err: &errortypes.Warning{ + Message: "'gpp_sid' signal value will be used over the one found in the deprecated 'gdpr' field.", + WarningCode: errortypes.UnknownWarningCode, + }, + }, + }, + { + desc: `valid "gdpr_consent" value but valid GDPRSignal was previously parsed before, expect SignalAmbiguous, blank consent and a warning`, + in: testInput{ + uri: "/setuid?gdpr_consent=someConsent", + gppGDPRConsent: "CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + }, + expected: testOutput{ + signal: gdpr.SignalAmbiguous, + consent: "", + err: &errortypes.Warning{ + Message: "'gpp' value will be used over the one found in the deprecated 'gdpr_consent' field.", + WarningCode: errortypes.UnknownWarningCode, + }, + }, + }, + } + for _, tc := range testCases { + // set test + testURL, err := url.Parse(tc.in.uri) + assert.NoError(t, err, tc.desc) + + query := testURL.Query() + + // run + outSignal, outConsent, outErr := parseLegacyGDPRFields(query, tc.in.gppGDPRSignal, tc.in.gppGDPRConsent) + + // assertions + assert.Equal(t, tc.expected.signal, outSignal, tc.desc) + assert.Equal(t, tc.expected.consent, outConsent, tc.desc) + assert.Equal(t, tc.expected.err, outErr, tc.desc) + } +} + +func TestExtractGDPRInfo(t *testing.T) { + type testOutput struct { + requestInfo gdpr.RequestInfo + err error + } + type testCase struct { + desc string + inUri string + expected testOutput + } + testSuite := []struct { + sDesc string + tests []testCase + }{ + { + sDesc: "no gdpr nor gpp values in query", + tests: []testCase{ + { + desc: "expect blank consent, signalNo and nil error", + inUri: "/setuid?bidder=pubmatic&uid=123", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{ + Consent: "", + GDPRSignal: gdpr.SignalAmbiguous, + }, + err: nil, + }, + }, + }, + }, + { + sDesc: "missing gpp, gdpr only", + tests: []testCase{ + { + desc: "Invalid gdpr signal value in query, expect blank request info and error", + inUri: "/setuid?gdpr=2", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{GDPRSignal: gdpr.SignalAmbiguous}, + err: errors.New("the gdpr query param must be either 0 or 1. You gave 2"), + }, + }, + { + desc: "GDPR equals 0, blank consent, expect blank consent, signalNo and nil error", + inUri: "/setuid?gdpr=0", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{GDPRSignal: gdpr.SignalNo}, + err: nil, + }, + }, + { + desc: "GDPR equals 1, blank consent, expect blank request info and error", + inUri: "/setuid?gdpr=1", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{GDPRSignal: gdpr.SignalAmbiguous}, + err: errors.New("GDPR consent is required when gdpr signal equals 1"), + }, + }, + { + desc: "GDPR equals 0, non-blank consent, expect non-blank request info and nil error", + inUri: "/setuid?gdpr=0&gdpr_consent=someConsent", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{ + Consent: "someConsent", + GDPRSignal: gdpr.SignalNo, + }, + err: nil, + }, + }, + { + desc: "GDPR equals 1, non-blank consent, expect non-blank request info and nil error", + inUri: "/setuid?gdpr=1&gdpr_consent=someConsent", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{ + Consent: "someConsent", + GDPRSignal: gdpr.SignalYes, + }, + err: nil, + }, + }, + }, + }, + { + sDesc: "missing gdpr, gpp only", + tests: []testCase{ + { + desc: "Malformed GPP_SID string, expect blank request info and error", + inUri: "/setuid?gpp_sid=malformed", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{GDPRSignal: gdpr.SignalAmbiguous}, + err: errors.New("Error parsing gpp_sid strconv.ParseInt: parsing \"malformed\": invalid syntax"), + }, + }, + { + desc: "Valid GPP_SID string but invalid GPP string in query, expect blank request info and error", + inUri: "/setuid?gpp=malformed&gpp_sid=2", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{GDPRSignal: gdpr.SignalAmbiguous}, + err: errors.New("error parsing GPP header, base64 decoding: illegal base64 data at input byte 8"), + }, + }, + { + desc: "SectionTCFEU2 not found in GPP string, expect blank consent and signalAmbiguous", + inUri: "/setuid?gpp=DBABBgA~xlgWEYCZAA", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{ + Consent: "", + GDPRSignal: gdpr.SignalAmbiguous, + }, + err: nil, + }, + }, + { + desc: "No GPP string, nor SectionTCFEU2 found in SID list in query, expect blank consent and signalAmbiguous", + inUri: "/setuid?gpp_sid=3,6", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{ + Consent: "", + GDPRSignal: gdpr.SignalNo, + }, + err: nil, + }, + }, + { + desc: "No GPP string, SectionTCFEU2 found in SID list in query, expect blank request info and error", + inUri: "/setuid?gpp_sid=2", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{GDPRSignal: gdpr.SignalAmbiguous}, + err: errors.New("GDPR consent is required when gdpr signal equals 1"), + }, + }, + { + desc: "SectionTCFEU2 only found in SID list, expect blank request info and error", + inUri: "/setuid?gpp=DBABBgA~xlgWEYCZAA&gpp_sid=2", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{GDPRSignal: gdpr.SignalAmbiguous}, + err: errors.New("GDPR consent is required when gdpr signal equals 1"), + }, + }, + { + desc: "SectionTCFEU2 found in GPP string but SID list is nil, expect valid consent and SignalAmbiguous", + inUri: "/setuid?gpp=DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{ + Consent: "CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + GDPRSignal: gdpr.SignalAmbiguous, + }, + err: nil, + }, + }, + { + desc: "SectionTCFEU2 found in GPP string but not in the non-nil SID list, expect valid consent and signalNo", + inUri: "/setuid?gpp=DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA&gpp_sid=6", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{ + Consent: "CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + GDPRSignal: gdpr.SignalNo, + }, + err: nil, + }, + }, + { + desc: "SectionTCFEU2 found both in GPP string and SID list, expect valid consent and signalYes", + inUri: "/setuid?gpp=DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA&gpp_sid=2,4", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{ + Consent: "CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + GDPRSignal: gdpr.SignalYes, + }, + err: nil, + }, + }, + }, + }, + { + sDesc: "GPP values take priority over GDPR", + tests: []testCase{ + { + desc: "SignalNo in gdpr field but SignalYes in SID list, CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA consent in gpp but legacyConsent in gdpr_consent, expect GPP values to prevail", + inUri: "/setuid?gpp=DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA&gpp_sid=2,4&gdpr=0&gdpr_consent=legacyConsent", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{ + Consent: "CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + GDPRSignal: gdpr.SignalYes, + }, + err: &errortypes.Warning{ + Message: "'gpp' value will be used over the one found in the deprecated 'gdpr_consent' field.", + WarningCode: errortypes.UnknownWarningCode, + }, + }, + }, + { + desc: "SignalNo in gdpr field but SignalYes in SID list because SectionTCFEU2 is listed, expect GPP to prevail", + inUri: "/setuid?gpp=DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA&gpp_sid=2,4&gdpr=0", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{ + Consent: "CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + GDPRSignal: gdpr.SignalYes, + }, + err: &errortypes.Warning{ + Message: "'gpp_sid' signal value will be used over the one found in the deprecated 'gdpr' field.", + WarningCode: errortypes.UnknownWarningCode, + }, + }, + }, + { + desc: "No gpp string in URL query, use gdpr_consent and SignalYes found in SID list because SectionTCFEU2 is listed", + inUri: "/setuid?gpp_sid=2,4&gdpr_consent=legacyConsent", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{ + Consent: "", + GDPRSignal: gdpr.SignalAmbiguous, + }, + err: errors.New("GDPR consent is required when gdpr signal equals 1"), + }, + }, + { + desc: "SectionTCFEU2 not found in GPP string but found in SID list, choose the GDPR_CONSENT and GPP_SID signal", + inUri: "/setuid?gpp=DBABBgA~xlgWEYCZAA&gpp_sid=2&gdpr=0&gdpr_consent=legacyConsent", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{ + Consent: "", + GDPRSignal: gdpr.SignalAmbiguous, + }, + err: errors.New("GDPR consent is required when gdpr signal equals 1"), + }, + }, + { + desc: "SectionTCFEU2 found in GPP string but not in SID list, choose GDPR signal GPP consent value", + inUri: "/setuid?gpp=DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA&gpp_sid=6&gdpr=1&gdpr_consent=legacyConsent", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{ + Consent: "CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + GDPRSignal: gdpr.SignalNo, + }, + err: &errortypes.Warning{ + Message: "'gpp' value will be used over the one found in the deprecated 'gdpr_consent' field.", + WarningCode: errortypes.UnknownWarningCode, + }, + }, + }, + { + desc: "SectionTCFEU2 not found in GPP, use GDPR_CONSENT value. SignalYes found in gdpr field, but not in the valid SID list, expect SignalNo", + inUri: "/setuid?gpp=DBABBgA~xlgWEYCZAA&gpp_sid=6&gdpr=1&gdpr_consent=legacyConsent", + expected: testOutput{ + requestInfo: gdpr.RequestInfo{ + Consent: "", + GDPRSignal: gdpr.SignalNo, + }, + err: &errortypes.Warning{ + Message: "'gpp_sid' signal value will be used over the one found in the deprecated 'gdpr' field.", + WarningCode: errortypes.UnknownWarningCode, + }, + }, + }, + }, + }, + } + + for _, ts := range testSuite { + for _, tc := range ts.tests { + // set test + testURL, err := url.Parse(tc.inUri) + assert.NoError(t, err, tc.desc) + + query := testURL.Query() + + // run + outReqInfo, outErr := extractGDPRInfo(query) + + // assertions + assert.Equal(t, tc.expected.requestInfo, outReqInfo, tc.desc) + assert.Equal(t, tc.expected.err, outErr, tc.desc) + } + } +} + func TestSetUIDEndpointMetrics(t *testing.T) { cookieWithOptOut := usersync.NewCookie() cookieWithOptOut.SetOptOut(true) @@ -425,7 +1039,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { Status: 400, Bidder: "pubmatic", UID: "", - Errors: []error{errors.New("gdpr_consent is required when gdpr=1")}, + Errors: []error{errors.New("GDPR consent is required when gdpr signal equals 1")}, Success: false, } a.On("LogSetUIDObject", &expected).Once() diff --git a/errortypes/errortypes.go b/errortypes/errortypes.go index d93075b7c6c..aff0482280e 100644 --- a/errortypes/errortypes.go +++ b/errortypes/errortypes.go @@ -183,7 +183,8 @@ func (err *MalformedAcct) Severity() Severity { return SeverityFatal } -// Warning is a generic non-fatal error. +// Warning is a generic non-fatal error. Throughout the codebase, an error can +// only be a warning if it's of the type defined below type Warning struct { Message string WarningCode int diff --git a/errortypes/severity.go b/errortypes/severity.go index 0838b09592e..5f9cd80dd28 100644 --- a/errortypes/severity.go +++ b/errortypes/severity.go @@ -20,7 +20,10 @@ func isFatal(err error) bool { return !ok || s.Severity() == SeverityFatal } -func isWarning(err error) bool { +// IsWarning returns true if an error is labeled with a Severity of SeverityWarning +// Throughout the codebase, errors with SeverityWarning are of the type Warning +// defined in this package +func IsWarning(err error) bool { s, ok := err.(Coder) return ok && s.Severity() == SeverityWarning } @@ -54,7 +57,7 @@ func WarningOnly(errs []error) []error { errsWarning := make([]error, 0, len(errs)) for _, err := range errs { - if isWarning(err) { + if IsWarning(err) { errsWarning = append(errsWarning, err) } } diff --git a/privacy/gpp/gpp.go b/privacy/gpp/gpp.go index 2ebf4b9752a..350004062e8 100644 --- a/privacy/gpp/gpp.go +++ b/privacy/gpp/gpp.go @@ -23,9 +23,10 @@ func IsSIDInList(gppSIDs []int8, sid gppConstants.SectionID) bool { return false } -// IndexOfSID returns a zero or non-negative integer that represents the position of the 'sid' value in the -// 'gpp.SectionTypes' array. If the 'sid' value is not found, returns -1. This logic is used in -// more than one place in our codebase, therefore it was decided to make it its own function. +// IndexOfSID returns a zero or non-negative integer that represents the position of +// the 'sid' value in the 'gpp.SectionTypes' array. If the 'sid' value is not found, +// returns -1. This logic is used in more than one place in our codebase, therefore +// it was decided to make it its own function. func IndexOfSID(gpp gpplib.GppContainer, sid gppConstants.SectionID) int { for i, id := range gpp.SectionTypes { if id == sid { From 60cf8e73a6c6453c4948e752b27604313bbf4802 Mon Sep 17 00:00:00 2001 From: AlexBVolcy <74930484+AlexBVolcy@users.noreply.github.com> Date: Mon, 17 Jul 2023 10:38:49 -0700 Subject: [PATCH 025/268] Refactor Usersync (#2830) --- endpoints/cookie_sync.go | 4 +- endpoints/cookie_sync_test.go | 9 +- endpoints/getuids.go | 6 +- endpoints/openrtb2/amp_auction.go | 5 +- endpoints/openrtb2/auction.go | 6 +- endpoints/openrtb2/video_auction.go | 6 +- endpoints/setuid.go | 27 +- endpoints/setuid_test.go | 23 +- pbs/usersync.go | 14 +- usersync/chooser_test.go | 4 +- usersync/cookie.go | 255 +++++---- usersync/cookie_test.go | 853 +++++++++++++++++++--------- usersync/decoder.go | 27 + usersync/encoder.go | 23 + usersync/encoder_decoder_test.go | 149 +++++ 15 files changed, 996 insertions(+), 415 deletions(-) create mode 100644 usersync/decoder.go create mode 100644 usersync/encoder.go create mode 100644 usersync/encoder_decoder_test.go diff --git a/endpoints/cookie_sync.go b/endpoints/cookie_sync.go index fa154bbcbff..ef3c40e8815 100644 --- a/endpoints/cookie_sync.go +++ b/endpoints/cookie_sync.go @@ -90,8 +90,10 @@ func (c *cookieSyncEndpoint) Handle(w http.ResponseWriter, r *http.Request, _ ht c.handleError(w, err, http.StatusBadRequest) return } + decoder := usersync.Base64Decoder{} - cookie := usersync.ParseCookieFromRequest(r, &c.config.HostCookie) + cookie := usersync.ReadCookie(r, decoder, &c.config.HostCookie) + usersync.SyncHostCookie(r, cookie, &c.config.HostCookie) result := c.chooser.Choose(request, cookie) switch result.Status { diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go index 37acf0c2add..a69a2cdb819 100644 --- a/endpoints/cookie_sync_test.go +++ b/endpoints/cookie_sync_test.go @@ -11,7 +11,6 @@ import ( "strings" "testing" "testing/iotest" - "time" "github.com/prebid/prebid-server/analytics" "github.com/prebid/prebid-server/config" @@ -106,7 +105,7 @@ func TestCookieSyncHandle(t *testing.T) { syncer.On("GetSync", syncTypeExpected, privacy.Policies{}).Return(sync, nil).Maybe() cookieWithSyncs := usersync.NewCookie() - cookieWithSyncs.TrySync("foo", "anyID") + cookieWithSyncs.Sync("foo", "anyID") testCases := []struct { description string @@ -271,7 +270,9 @@ func TestCookieSyncHandle(t *testing.T) { request := httptest.NewRequest("POST", "/cookiesync", test.givenBody) if test.givenCookie != nil { - request.AddCookie(test.givenCookie.ToHTTPCookie(24 * time.Hour)) + httpCookie, err := ToHTTPCookie(test.givenCookie) + assert.NoError(t, err) + request.AddCookie(httpCookie) } writer := httptest.NewRecorder() @@ -1663,7 +1664,7 @@ func TestCookieSyncHandleResponse(t *testing.T) { cookie := usersync.NewCookie() if test.givenCookieHasSyncs { - if err := cookie.TrySync("foo", "anyID"); err != nil { + if err := cookie.Sync("foo", "anyID"); err != nil { assert.FailNow(t, test.description+":set_cookie") } } diff --git a/endpoints/getuids.go b/endpoints/getuids.go index ad984a8df00..f420c64fa6b 100644 --- a/endpoints/getuids.go +++ b/endpoints/getuids.go @@ -18,9 +18,11 @@ type userSyncs struct { // returns all the existing syncs for the user func NewGetUIDsEndpoint(cfg config.HostCookie) httprouter.Handle { return httprouter.Handle(func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { - pc := usersync.ParseCookieFromRequest(r, &cfg) + cookie := usersync.ReadCookie(r, usersync.Base64Decoder{}, &cfg) + usersync.SyncHostCookie(r, cookie, &cfg) + userSyncs := new(userSyncs) - userSyncs.BuyerUIDs = pc.GetUIDs() + userSyncs.BuyerUIDs = cookie.GetUIDs() json.NewEncoder(w).Encode(userSyncs) }) } diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index a37c6874d2e..9324b15d9ef 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -182,12 +182,15 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h } defer cancel() - usersyncs := usersync.ParseCookieFromRequest(r, &(deps.cfg.HostCookie)) + // Read UserSyncs/Cookie from Request + usersyncs := usersync.ReadCookie(r, usersync.Base64Decoder{}, &deps.cfg.HostCookie) + usersync.SyncHostCookie(r, usersyncs, &deps.cfg.HostCookie) if usersyncs.HasAnyLiveSyncs() { labels.CookieFlag = metrics.CookieFlagYes } else { labels.CookieFlag = metrics.CookieFlagNo } + labels.PubID = getAccountID(reqWrapper.Site.Publisher) // Look up account now that we have resolved the pubID value account, acctIDErrs := accountService.GetAccount(ctx, deps.cfg, deps.accounts, labels.PubID, deps.metricsEngine) diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index c5aa88dd722..9a0d0d07640 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -209,7 +209,11 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http defer cancel() } - usersyncs := usersync.ParseCookieFromRequest(r, &(deps.cfg.HostCookie)) + // Read Usersyncs/Cookie + decoder := usersync.Base64Decoder{} + usersyncs := usersync.ReadCookie(r, decoder, &deps.cfg.HostCookie) + usersync.SyncHostCookie(r, usersyncs, &deps.cfg.HostCookie) + if req.Site != nil { if usersyncs.HasAnyLiveSyncs() { labels.CookieFlag = metrics.CookieFlagYes diff --git a/endpoints/openrtb2/video_auction.go b/endpoints/openrtb2/video_auction.go index d3731062b55..872ea2bdb74 100644 --- a/endpoints/openrtb2/video_auction.go +++ b/endpoints/openrtb2/video_auction.go @@ -275,7 +275,11 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re defer cancel() } - usersyncs := usersync.ParseCookieFromRequest(r, &(deps.cfg.HostCookie)) + // Read Usersyncs/Cookie + decoder := usersync.Base64Decoder{} + usersyncs := usersync.ReadCookie(r, decoder, &deps.cfg.HostCookie) + usersync.SyncHostCookie(r, usersyncs, &deps.cfg.HostCookie) + if bidReqWrapper.App != nil { labels.Source = metrics.DemandApp labels.PubID = getAccountID(bidReqWrapper.App.Publisher) diff --git a/endpoints/setuid.go b/endpoints/setuid.go index 0b832f6f324..905fa26b2f2 100644 --- a/endpoints/setuid.go +++ b/endpoints/setuid.go @@ -8,7 +8,6 @@ import ( "net/url" "strconv" "strings" - "time" "github.com/julienschmidt/httprouter" gpplib "github.com/prebid/go-gpp" @@ -34,8 +33,11 @@ const ( chromeiOSStrLen = len(chromeiOSStr) ) +const uidCookieName = "uids" + func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]usersync.Syncer, gdprPermsBuilder gdpr.PermissionsBuilder, tcf2CfgBuilder gdpr.TCF2ConfigBuilder, pbsanalytics analytics.PBSAnalyticsModule, accountsFetcher stored_requests.AccountFetcher, metricsEngine metrics.MetricsEngine) httprouter.Handle { - cookieTTL := time.Duration(cfg.HostCookie.TTL) * 24 * time.Hour + encoder := usersync.Base64Encoder{} + decoder := usersync.Base64Decoder{} // convert map of syncers by bidder to map of syncers by key // - its safe to assume that if multiple bidders map to the same key, the syncers are interchangeable. @@ -52,13 +54,14 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use defer pbsanalytics.LogSetUIDObject(&so) - pc := usersync.ParseCookieFromRequest(r, &cfg.HostCookie) - if !pc.AllowSyncs() { + cookie := usersync.ReadCookie(r, decoder, &cfg.HostCookie) + if !cookie.AllowSyncs() { w.WriteHeader(http.StatusUnauthorized) metricsEngine.RecordSetUid(metrics.SetUidOptOut) so.Status = http.StatusUnauthorized return } + usersync.SyncHostCookie(r, cookie, &cfg.HostCookie) query := r.URL.Query() @@ -141,18 +144,28 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use so.UID = uid if uid == "" { - pc.Unsync(syncer.Key()) + cookie.Unsync(syncer.Key()) metricsEngine.RecordSetUid(metrics.SetUidOK) metricsEngine.RecordSyncerSet(syncer.Key(), metrics.SyncerSetUidCleared) so.Success = true - } else if err = pc.TrySync(syncer.Key(), uid); err == nil { + } else if err = cookie.Sync(syncer.Key(), uid); err == nil { metricsEngine.RecordSetUid(metrics.SetUidOK) metricsEngine.RecordSyncerSet(syncer.Key(), metrics.SyncerSetUidOK) so.Success = true } setSiteCookie := siteCookieCheck(r.UserAgent()) - pc.SetCookieOnResponse(w, setSiteCookie, &cfg.HostCookie, cookieTTL) + + // Write Cookie + encodedCookie, err := cookie.PrepareCookieForWrite(&cfg.HostCookie, encoder) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + metricsEngine.RecordSetUid(metrics.SetUidBadRequest) + so.Errors = []error{err} + so.Status = http.StatusBadRequest + return + } + usersync.WriteCookie(w, encodedCookie, &cfg.HostCookie, setSiteCookie) switch responseFormat { case "i": diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go index b927f339403..9176041ed8e 100644 --- a/endpoints/setuid_test.go +++ b/endpoints/setuid_test.go @@ -1311,7 +1311,7 @@ func makeRequest(uri string, existingSyncs map[string]string) *http.Request { if len(existingSyncs) > 0 { pbsCookie := usersync.NewCookie() for key, value := range existingSyncs { - pbsCookie.TrySync(key, value) + pbsCookie.Sync(key, value) } addCookie(request, pbsCookie) } @@ -1363,10 +1363,12 @@ func doRequest(req *http.Request, analytics analytics.PBSAnalyticsModule, metric } func addCookie(req *http.Request, cookie *usersync.Cookie) { - req.AddCookie(cookie.ToHTTPCookie(time.Duration(1) * time.Hour)) + httpCookie, _ := ToHTTPCookie(cookie) + req.AddCookie(httpCookie) } func parseCookieString(t *testing.T, response *httptest.ResponseRecorder) *usersync.Cookie { + decoder := usersync.Base64Decoder{} cookieString := response.Header().Get("Set-Cookie") parser := regexp.MustCompile("uids=(.*?);") res := parser.FindStringSubmatch(cookieString) @@ -1375,7 +1377,7 @@ func parseCookieString(t *testing.T, response *httptest.ResponseRecorder) *users Name: "uids", Value: res[1], } - return usersync.ParseCookie(&httpCookie) + return decoder.Decode(httpCookie.Value) } type fakePermissionsBuilder struct { @@ -1444,3 +1446,18 @@ func (s fakeSyncer) SupportsType(syncTypes []usersync.SyncType) bool { func (s fakeSyncer) GetSync(syncTypes []usersync.SyncType, privacyPolicies privacy.Policies) (usersync.Sync, error) { return usersync.Sync{}, nil } + +func ToHTTPCookie(cookie *usersync.Cookie) (*http.Cookie, error) { + encoder := usersync.Base64Encoder{} + encodedCookie, err := encoder.Encode(cookie) + if err != nil { + return nil, nil + } + + return &http.Cookie{ + Name: uidCookieName, + Value: encodedCookie, + Expires: time.Now().Add((90 * 24 * time.Hour)), + Path: "/", + }, nil +} diff --git a/pbs/usersync.go b/pbs/usersync.go index 748581af759..7b468cb039d 100644 --- a/pbs/usersync.go +++ b/pbs/usersync.go @@ -58,6 +58,8 @@ func (deps *UserSyncDeps) VerifyRecaptcha(response string) error { func (deps *UserSyncDeps) OptOut(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { optout := r.FormValue("optout") rr := r.FormValue("g-recaptcha-response") + encoder := usersync.Base64Encoder{} + decoder := usersync.Base64Decoder{} if rr == "" { http.Redirect(w, r, fmt.Sprintf("%s/static/optout.html", deps.ExternalUrl), http.StatusMovedPermanently) @@ -73,10 +75,18 @@ func (deps *UserSyncDeps) OptOut(w http.ResponseWriter, r *http.Request, _ httpr return } - pc := usersync.ParseCookieFromRequest(r, deps.HostCookieConfig) + // Read Cookie + pc := usersync.ReadCookie(r, decoder, deps.HostCookieConfig) + usersync.SyncHostCookie(r, pc, deps.HostCookieConfig) pc.SetOptOut(optout != "") - pc.SetCookieOnResponse(w, false, deps.HostCookieConfig, deps.HostCookieConfig.TTLDuration()) + // Write Cookie + encodedCookie, err := pc.PrepareCookieForWrite(deps.HostCookieConfig, encoder) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + return + } + usersync.WriteCookie(w, encodedCookie, deps.HostCookieConfig, false) if optout == "" { http.Redirect(w, r, deps.HostCookieConfig.OptInURL, http.StatusMovedPermanently) diff --git a/usersync/chooser_test.go b/usersync/chooser_test.go index 3b820b99f24..0071a2e36b0 100644 --- a/usersync/chooser_test.go +++ b/usersync/chooser_test.go @@ -238,8 +238,8 @@ func TestChooserEvaluate(t *testing.T) { Redirect: NewUniformBidderFilter(BidderFilterModeExclude)} cookieNeedsSync := Cookie{} - cookieAlreadyHasSyncForA := Cookie{uids: map[string]uidWithExpiry{"keyA": {Expires: time.Now().Add(time.Duration(24) * time.Hour)}}} - cookieAlreadyHasSyncForB := Cookie{uids: map[string]uidWithExpiry{"keyB": {Expires: time.Now().Add(time.Duration(24) * time.Hour)}}} + cookieAlreadyHasSyncForA := Cookie{uids: map[string]UIDEntry{"keyA": {Expires: time.Now().Add(time.Duration(24) * time.Hour)}}} + cookieAlreadyHasSyncForB := Cookie{uids: map[string]UIDEntry{"keyB": {Expires: time.Now().Add(time.Duration(24) * time.Hour)}}} testCases := []struct { description string diff --git a/usersync/cookie.go b/usersync/cookie.go index 4f80fa5d5f6..c0eb898c5ea 100644 --- a/usersync/cookie.go +++ b/usersync/cookie.go @@ -1,11 +1,10 @@ package usersync import ( - "encoding/base64" "encoding/json" "errors" - "math" "net/http" + "sort" "time" "github.com/prebid/prebid-server/config" @@ -20,70 +19,155 @@ const uidTTL = 14 * 24 * time.Hour // Cookie is the cookie used in Prebid Server. // -// To get an instance of this from a request, use ParseCookieFromRequest. -// To write an instance onto a response, use SetCookieOnResponse. +// To get an instance of this from a request, use ReadCookie. +// To write an instance onto a response, use WriteCookie. type Cookie struct { - uids map[string]uidWithExpiry + uids map[string]UIDEntry optOut bool } -// uidWithExpiry bundles the UID with an Expiration date. -// After the expiration, the UID is no longer valid. -type uidWithExpiry struct { +// UIDEntry bundles the UID with an Expiration date. +type UIDEntry struct { // UID is the ID given to a user by a particular bidder UID string `json:"uid"` // Expires is the time at which this UID should no longer apply. Expires time.Time `json:"expires"` } -// ParseCookieFromRequest parses the UserSyncMap from an HTTP Request. -func ParseCookieFromRequest(r *http.Request, cookie *config.HostCookie) *Cookie { - if cookie.OptOutCookie.Name != "" { - optOutCookie, err1 := r.Cookie(cookie.OptOutCookie.Name) - if err1 == nil && optOutCookie.Value == cookie.OptOutCookie.Value { - pc := NewCookie() - pc.SetOptOut(true) - return pc - } +// NewCookie returns a new empty cookie. +func NewCookie() *Cookie { + return &Cookie{ + uids: make(map[string]UIDEntry), } - var parsed *Cookie - uidCookie, err2 := r.Cookie(uidCookieName) - if err2 == nil { - parsed = ParseCookie(uidCookie) - } else { - parsed = NewCookie() +} + +// ReadCookie reads the cookie from the request +func ReadCookie(r *http.Request, decoder Decoder, host *config.HostCookie) *Cookie { + if hostOptOutCookie := checkHostCookieOptOut(r, host); hostOptOutCookie != nil { + return hostOptOutCookie + } + + // Read cookie from request + cookieFromRequest, err := r.Cookie(uidCookieName) + if err != nil { + return NewCookie() } - // Fixes #582 - if uid, _, _ := parsed.GetUID(cookie.Family); uid == "" && cookie.CookieName != "" { - if hostCookie, err := r.Cookie(cookie.CookieName); err == nil { - parsed.TrySync(cookie.Family, hostCookie.Value) + decodedCookie := decoder.Decode(cookieFromRequest.Value) + + return decodedCookie +} + +// PrepareCookieForWrite ejects UIDs as long as the cookie is too full +func (cookie *Cookie) PrepareCookieForWrite(cfg *config.HostCookie, encoder Encoder) (string, error) { + uuidKeys := sortUIDs(cookie.uids) + + i := 0 + for len(cookie.uids) > 0 { + encodedCookie, err := encoder.Encode(cookie) + if err != nil { + return encodedCookie, nil + } + + // Convert to HTTP Cookie to Get Size + httpCookie := &http.Cookie{ + Name: uidCookieName, + Value: encodedCookie, + Expires: time.Now().Add(cfg.TTLDuration()), + Path: "/", + } + cookieSize := len([]byte(httpCookie.String())) + + isCookieTooBig := cookieSize > cfg.MaxCookieSizeBytes && cfg.MaxCookieSizeBytes > 0 + if !isCookieTooBig { + return encodedCookie, nil } + + uidToDelete := uuidKeys[i] + delete(cookie.uids, uidToDelete) + + i++ } - return parsed + return "", nil } -// ParseCookie parses the UserSync cookie from a raw HTTP cookie. -func ParseCookie(httpCookie *http.Cookie) *Cookie { - jsonValue, err := base64.URLEncoding.DecodeString(httpCookie.Value) - if err != nil { - // corrupted cookie; we should reset - return NewCookie() +// WriteCookie sets the prepared cookie onto the header +func WriteCookie(w http.ResponseWriter, encodedCookie string, cfg *config.HostCookie, setSiteCookie bool) { + ttl := cfg.TTLDuration() + + httpCookie := &http.Cookie{ + Name: uidCookieName, + Value: encodedCookie, + Expires: time.Now().Add(ttl), + Path: "/", } - var cookie Cookie - if err = json.Unmarshal(jsonValue, &cookie); err != nil { - // corrupted cookie; we should reset - return NewCookie() + if cfg.Domain != "" { + httpCookie.Domain = cfg.Domain + } + + if setSiteCookie { + httpCookie.Secure = true + httpCookie.SameSite = http.SameSiteNoneMode } - return &cookie + w.Header().Add("Set-Cookie", httpCookie.String()) } -// NewCookie returns a new empty cookie. -func NewCookie() *Cookie { - return &Cookie{ - uids: make(map[string]uidWithExpiry), +// Sync tries to set the UID for some syncer key. It returns an error if the set didn't happen. +func (cookie *Cookie) Sync(key string, uid string) error { + if !cookie.AllowSyncs() { + return errors.New("the user has opted out of prebid server cookie syncs") + } + + if checkAudienceNetwork(key, uid) { + return errors.New("audienceNetwork uses a UID of 0 as \"not yet recognized\"") } + + // Sync + cookie.uids[key] = UIDEntry{ + UID: uid, + Expires: time.Now().Add(uidTTL), + } + + return nil +} + +// sortUIDs is used to get a list of uids sorted from oldest to newest +// This list is used to eject oldest uids from the cookie +// This will be incorporated with a more complex ejection framework in a future PR +func sortUIDs(uids map[string]UIDEntry) []string { + if len(uids) > 0 { + uuidKeys := make([]string, 0, len(uids)) + for key := range uids { + uuidKeys = append(uuidKeys, key) + } + sort.SliceStable(uuidKeys, func(i, j int) bool { + return uids[uuidKeys[i]].Expires.Before(uids[uuidKeys[j]].Expires) + }) + return uuidKeys + } + return nil +} + +// SyncHostCookie syncs the request cookie with the host cookie +func SyncHostCookie(r *http.Request, requestCookie *Cookie, host *config.HostCookie) { + if uid, _, _ := requestCookie.GetUID(host.Family); uid == "" && host.CookieName != "" { + if hostCookie, err := r.Cookie(host.CookieName); err == nil { + requestCookie.Sync(host.Family, hostCookie.Value) + } + } +} + +func checkHostCookieOptOut(r *http.Request, host *config.HostCookie) *Cookie { + if host.OptOutCookie.Name != "" { + optOutCookie, err := r.Cookie(host.OptOutCookie.Name) + if err == nil && optOutCookie.Value == host.OptOutCookie.Value { + hostOptOut := NewCookie() + hostOptOut.SetOptOut(true) + return hostOptOut + } + } + return nil } // AllowSyncs is true if the user lets bidders sync cookies, and false otherwise. @@ -96,30 +180,12 @@ func (cookie *Cookie) SetOptOut(optOut bool) { cookie.optOut = optOut if optOut { - cookie.uids = make(map[string]uidWithExpiry) - } -} - -// Gets an HTTP cookie containing all the data from this UserSyncMap. This is a snapshot--not a live view. -func (cookie *Cookie) ToHTTPCookie(ttl time.Duration) *http.Cookie { - j, _ := json.Marshal(cookie) - b64 := base64.URLEncoding.EncodeToString(j) - - return &http.Cookie{ - Name: uidCookieName, - Value: b64, - Expires: time.Now().Add(ttl), - Path: "/", + cookie.uids = make(map[string]UIDEntry) } } // GetUID Gets this user's ID for the given syncer key. -// The first returned value is the user's ID. -// The second returned value is true if we had a value stored, and false if we didn't. -// The third returned value is true if that value is "active", and false if it's expired. -// -// If no value was stored, then the "isActive" return value will be false. -func (cookie *Cookie) GetUID(key string) (string, bool, bool) { +func (cookie *Cookie) GetUID(key string) (uid string, isUIDFound bool, isUIDActive bool) { if cookie != nil { if uid, ok := cookie.uids[key]; ok { return uid.UID, true, time.Now().Before(uid.Expires) @@ -140,41 +206,6 @@ func (cookie *Cookie) GetUIDs() map[string]string { return uids } -// SetCookieOnResponse is a shortcut for "ToHTTPCookie(); cookie.setDomain(domain); setCookie(w, cookie)" -func (cookie *Cookie) SetCookieOnResponse(w http.ResponseWriter, setSiteCookie bool, cfg *config.HostCookie, ttl time.Duration) { - httpCookie := cookie.ToHTTPCookie(ttl) - var domain string = cfg.Domain - - if domain != "" { - httpCookie.Domain = domain - } - - var currSize int = len([]byte(httpCookie.String())) - for cfg.MaxCookieSizeBytes > 0 && currSize > cfg.MaxCookieSizeBytes && len(cookie.uids) > 0 { - var oldestElem string = "" - var oldestDate int64 = math.MaxInt64 - for key, value := range cookie.uids { - timeUntilExpiration := time.Until(value.Expires) - if timeUntilExpiration < time.Duration(oldestDate) { - oldestElem = key - oldestDate = int64(timeUntilExpiration) - } - } - delete(cookie.uids, oldestElem) - httpCookie = cookie.ToHTTPCookie(ttl) - if domain != "" { - httpCookie.Domain = domain - } - currSize = len([]byte(httpCookie.String())) - } - - if setSiteCookie { - httpCookie.Secure = true - httpCookie.SameSite = http.SameSiteNoneMode - } - w.Header().Add("Set-Cookie", httpCookie.String()) -} - // Unsync removes the user's ID for the given syncer key from this cookie. func (cookie *Cookie) Unsync(key string) { delete(cookie.uids, key) @@ -199,24 +230,8 @@ func (cookie *Cookie) HasAnyLiveSyncs() bool { return false } -// TrySync tries to set the UID for some syncer key. It returns an error if the set didn't happen. -func (cookie *Cookie) TrySync(key string, uid string) error { - if !cookie.AllowSyncs() { - return errors.New("The user has opted out of prebid server cookie syncs.") - } - - // At the moment, Facebook calls /setuid with a UID of 0 if the user isn't logged into Facebook. - // They shouldn't be sending us a sentinel value... but since they are, we're refusing to save that ID. - if key == string(openrtb_ext.BidderAudienceNetwork) && uid == "0" { - return errors.New("audienceNetwork uses a UID of 0 as \"not yet recognized\".") - } - - cookie.uids[key] = uidWithExpiry{ - UID: uid, - Expires: time.Now().Add(uidTTL), - } - - return nil +func checkAudienceNetwork(key string, uid string) bool { + return key == string(openrtb_ext.BidderAudienceNetwork) && uid == "0" } // cookieJson defines the JSON contract for the cookie data's storage format. @@ -224,8 +239,8 @@ func (cookie *Cookie) TrySync(key string, uid string) error { // This exists so that Cookie (which is public) can have private fields, and the rest of // the code doesn't have to worry about the cookie data storage format. type cookieJson struct { - UIDs map[string]uidWithExpiry `json:"tempUIDs,omitempty"` - OptOut bool `json:"optout,omitempty"` + UIDs map[string]UIDEntry `json:"tempUIDs,omitempty"` + OptOut bool `json:"optout,omitempty"` } func (cookie *Cookie) MarshalJSON() ([]byte, error) { @@ -250,10 +265,10 @@ func (cookie *Cookie) UnmarshalJSON(b []byte) error { } if cookie.uids == nil { - cookie.uids = make(map[string]uidWithExpiry) + cookie.uids = make(map[string]UIDEntry) } - // Audience Network / Facebook Handling + // Audience Network Handling if id, ok := cookie.uids[string(openrtb_ext.BidderAudienceNetwork)]; ok && id.UID == "0" { delete(cookie.uids, string(openrtb_ext.BidderAudienceNetwork)) } diff --git a/usersync/cookie_test.go b/usersync/cookie_test.go index ee5062ea152..5b86df54441 100644 --- a/usersync/cookie_test.go +++ b/usersync/cookie_test.go @@ -1,177 +1,597 @@ package usersync import ( - "encoding/base64" + "errors" "net/http" "net/http/httptest" - "strings" "testing" "time" "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" "github.com/stretchr/testify/assert" ) -func TestOptOutCookie(t *testing.T) { - cookie := &Cookie{ - uids: map[string]uidWithExpiry{"appnexus": {UID: "test"}}, - optOut: true, +func TestReadCookie(t *testing.T) { + testCases := []struct { + name string + givenRequest *http.Request + givenHttpCookie *http.Cookie + givenCookie *Cookie + givenDecoder Decoder + expectedCookie *Cookie + }{ + { + name: "simple-cookie", + givenRequest: httptest.NewRequest("POST", "http://www.prebid.com", nil), + givenCookie: &Cookie{ + uids: map[string]UIDEntry{ + "adnxs": { + UID: "UID", + Expires: time.Time{}, + }, + }, + optOut: false, + }, + expectedCookie: &Cookie{ + uids: map[string]UIDEntry{ + "adnxs": { + UID: "UID", + }, + }, + optOut: false, + }, + }, + { + name: "empty-cookie", + givenRequest: httptest.NewRequest("POST", "http://www.prebid.com", nil), + givenCookie: &Cookie{}, + expectedCookie: &Cookie{ + uids: map[string]UIDEntry{}, + optOut: false, + }, + }, + { + name: "nil-cookie", + givenRequest: httptest.NewRequest("POST", "http://www.prebid.com", nil), + givenCookie: nil, + expectedCookie: &Cookie{ + uids: map[string]UIDEntry{}, + optOut: false, + }, + }, + { + name: "corruptted-http-cookie", + givenRequest: httptest.NewRequest("POST", "http://www.prebid.com", nil), + givenHttpCookie: &http.Cookie{ + Name: "uids", + Value: "bad base64 encoding", + }, + givenCookie: nil, + expectedCookie: &Cookie{ + uids: map[string]UIDEntry{}, + optOut: false, + }, + }, } - ensureConsistency(t, cookie) -} -func TestEmptyOptOutCookie(t *testing.T) { - cookie := &Cookie{ - uids: make(map[string]uidWithExpiry), - optOut: true, + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + if test.givenCookie != nil { + httpCookie, err := ToHTTPCookie(test.givenCookie) + assert.NoError(t, err) + test.givenRequest.AddCookie(httpCookie) + } else if test.givenCookie == nil && test.givenHttpCookie != nil { + test.givenRequest.AddCookie(test.givenHttpCookie) + } + actualCookie := ReadCookie(test.givenRequest, Base64Decoder{}, &config.HostCookie{}) + assert.Equal(t, test.expectedCookie.uids, actualCookie.uids) + assert.Equal(t, test.expectedCookie.optOut, actualCookie.optOut) + }) } - ensureConsistency(t, cookie) } -func TestEmptyCookie(t *testing.T) { - cookie := &Cookie{ - uids: make(map[string]uidWithExpiry), - optOut: false, +func TestWriteCookie(t *testing.T) { + encoder := Base64Encoder{} + decoder := Base64Decoder{} + + testCases := []struct { + name string + givenCookie *Cookie + givenSetSiteCookie bool + expectedCookie *Cookie + }{ + { + name: "simple-cookie", + givenCookie: &Cookie{ + uids: map[string]UIDEntry{ + "adnxs": { + UID: "UID", + Expires: time.Time{}, + }, + }, + optOut: false, + }, + givenSetSiteCookie: false, + expectedCookie: &Cookie{ + uids: map[string]UIDEntry{ + "adnxs": { + UID: "UID", + Expires: time.Time{}, + }, + }, + optOut: false, + }, + }, + { + name: "simple-cookie-opt-out", + givenCookie: &Cookie{ + uids: map[string]UIDEntry{ + "adnxs": { + UID: "UID", + Expires: time.Time{}, + }, + }, + optOut: true, + }, + givenSetSiteCookie: true, + expectedCookie: &Cookie{ + uids: map[string]UIDEntry{}, + optOut: true, + }, + }, + { + name: "cookie-multiple-uids", + givenCookie: &Cookie{ + uids: map[string]UIDEntry{ + "adnxs": { + UID: "UID", + Expires: time.Time{}, + }, + "rubicon": { + UID: "UID2", + Expires: time.Time{}, + }, + }, + optOut: false, + }, + givenSetSiteCookie: true, + expectedCookie: &Cookie{ + uids: map[string]UIDEntry{ + "adnxs": { + UID: "UID", + Expires: time.Time{}, + }, + "rubicon": { + UID: "UID2", + Expires: time.Time{}, + }, + }, + optOut: false, + }, + }, } - ensureConsistency(t, cookie) -} -func TestCookieWithData(t *testing.T) { - cookie := newSampleCookie() - ensureConsistency(t, cookie) + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + // Write Cookie + w := httptest.NewRecorder() + encodedCookie, err := encoder.Encode(test.givenCookie) + assert.NoError(t, err) + WriteCookie(w, encodedCookie, &config.HostCookie{}, test.givenSetSiteCookie) + writtenCookie := w.Header().Get("Set-Cookie") + + // Read Cookie + header := http.Header{} + header.Add("Cookie", writtenCookie) + r := &http.Request{Header: header} + actualCookie := ReadCookie(r, decoder, &config.HostCookie{}) + + assert.Equal(t, test.expectedCookie, actualCookie) + }) + } } -func TestBidderNameGets(t *testing.T) { - cookie := newSampleCookie() - id, exists, _ := cookie.GetUID("adnxs") - if !exists { - t.Errorf("Cookie missing expected Appnexus ID") - } - if id != "123" { - t.Errorf("Bad appnexus id. Expected %s, got %s", "123", id) +func TestSync(t *testing.T) { + testCases := []struct { + name string + givenCookie *Cookie + givenSyncerKey string + givenUID string + expectedCookie *Cookie + expectedError error + }{ + { + name: "simple-sync", + givenCookie: &Cookie{ + uids: map[string]UIDEntry{}, + }, + givenSyncerKey: "adnxs", + givenUID: "123", + expectedCookie: &Cookie{ + uids: map[string]UIDEntry{ + "adnxs": { + UID: "123", + }, + }, + }, + }, + { + name: "dont-allow-syncs", + givenCookie: &Cookie{ + uids: map[string]UIDEntry{}, + optOut: true, + }, + givenSyncerKey: "adnxs", + givenUID: "123", + expectedCookie: &Cookie{ + uids: map[string]UIDEntry{}, + }, + expectedError: errors.New("the user has opted out of prebid server cookie syncs"), + }, + { + name: "audienceNetwork", + givenCookie: &Cookie{ + uids: map[string]UIDEntry{}, + }, + givenSyncerKey: string(openrtb_ext.BidderAudienceNetwork), + givenUID: "0", + expectedError: errors.New("audienceNetwork uses a UID of 0 as \"not yet recognized\""), + }, } - id, exists, _ = cookie.GetUID("rubicon") - if !exists { - t.Errorf("Cookie missing expected Rubicon ID") - } - if id != "456" { - t.Errorf("Bad rubicon id. Expected %s, got %s", "456", id) + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + err := test.givenCookie.Sync(test.givenSyncerKey, test.givenUID) + if test.expectedError != nil { + assert.Equal(t, test.expectedError, err) + } else { + assert.NoError(t, err) + assert.Equal(t, test.expectedCookie.uids[test.givenSyncerKey].UID, test.givenCookie.uids[test.givenSyncerKey].UID) + } + }) } } -func TestRejectAudienceNetworkCookie(t *testing.T) { - raw := &Cookie{ - uids: map[string]uidWithExpiry{ - "audienceNetwork": newTempId("0", 10), +func TestGetUIDs(t *testing.T) { + testCases := []struct { + name string + givenCookie *Cookie + expectedCookie *Cookie + expectedLen int + }{ + { + name: "two-uids", + givenCookie: &Cookie{ + uids: map[string]UIDEntry{ + "adnxs": { + UID: "123", + }, + "rubicon": { + UID: "456", + }, + }, + }, + expectedLen: 2, + }, + { + name: "one-uid", + givenCookie: &Cookie{ + uids: map[string]UIDEntry{ + "adnxs": { + UID: "123", + }, + }, + }, + expectedLen: 1, + }, + { + name: "empty", + givenCookie: &Cookie{}, + expectedLen: 0, + }, + { + name: "nil", + givenCookie: nil, + expectedLen: 0, }, - optOut: false, - } - parsed := ParseCookie(raw.ToHTTPCookie(90 * 24 * time.Hour)) - if parsed.HasLiveSync("audienceNetwork") { - t.Errorf("Cookie serializing and deserializing should delete audienceNetwork values of 0") } - err := parsed.TrySync("audienceNetwork", "0") - if err == nil { - t.Errorf("Cookie should reject audienceNetwork values of 0.") - } - if parsed.HasLiveSync("audienceNetwork") { - t.Errorf("Cookie The cookie should have rejected the audienceNetwork sync.") + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + uids := test.givenCookie.GetUIDs() + assert.Len(t, uids, test.expectedLen) + for key, value := range uids { + assert.Equal(t, test.givenCookie.uids[key].UID, value) + } + + }) } } -func TestOptOutReset(t *testing.T) { - cookie := newSampleCookie() +func TestWriteCookieUserAgent(t *testing.T) { + encoder := Base64Encoder{} - cookie.SetOptOut(true) - if cookie.AllowSyncs() { - t.Error("After SetOptOut(true), a cookie should not allow more user syncs.") + testCases := []struct { + name string + givenUserAgent string + givenCookie *Cookie + givenHostCookie config.HostCookie + givenSetSiteCookie bool + expectedContains string + expectedNotContains string + }{ + { + name: "same-site-none", + givenUserAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36", + givenCookie: &Cookie{ + uids: map[string]UIDEntry{ + "adnxs": { + UID: "UID", + Expires: time.Time{}, + }, + }, + optOut: false, + }, + givenHostCookie: config.HostCookie{}, + givenSetSiteCookie: true, + expectedContains: "; Secure;", + }, + { + name: "older-chrome-version", + givenUserAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3770.142 Safari/537.36", + givenCookie: &Cookie{ + uids: map[string]UIDEntry{ + "adnxs": { + UID: "UID", + Expires: time.Time{}, + }, + }, + optOut: false, + }, + givenHostCookie: config.HostCookie{}, + givenSetSiteCookie: true, + expectedNotContains: "SameSite=none", + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + // Set Up + req := httptest.NewRequest("GET", "http://www.prebid.com", nil) + req.Header.Set("User-Agent", test.givenUserAgent) + + // Write Cookie + w := httptest.NewRecorder() + encodedCookie, err := encoder.Encode(test.givenCookie) + assert.NoError(t, err) + WriteCookie(w, encodedCookie, &test.givenHostCookie, test.givenSetSiteCookie) + writtenCookie := w.Header().Get("Set-Cookie") + + if test.expectedContains == "" { + assert.NotContains(t, writtenCookie, test.expectedNotContains) + } else { + assert.Contains(t, writtenCookie, test.expectedContains) + } + }) } - ensureConsistency(t, cookie) } -func TestOptIn(t *testing.T) { - cookie := &Cookie{ - uids: make(map[string]uidWithExpiry), - optOut: true, +func TestPrepareCookieForWrite(t *testing.T) { + encoder := Base64Encoder{} + decoder := Base64Decoder{} + cookieToSend := &Cookie{ + uids: map[string]UIDEntry{ + "1": newTempId("1234567890123456789012345678901234567890123456", 7), + "7": newTempId("abcdefghijklmnopqrstuvwxy", 1), + "2": newTempId("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 6), + "3": newTempId("123456789012345678901234567896123456789012345678", 5), + "4": newTempId("aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ", 4), + "5": newTempId("12345678901234567890123456789012345678901234567890", 3), + "6": newTempId("abcdefghij", 2), + }, + optOut: false, } - cookie.SetOptOut(false) - if !cookie.AllowSyncs() { - t.Error("After SetOptOut(false), a cookie should allow more user syncs.") + testCases := []struct { + name string + givenMaxCookieSize int + expectedRemainingUidKeys []string + }{ + { + name: "no-uids-ejected", + givenMaxCookieSize: 2000, + expectedRemainingUidKeys: []string{ + "1", "2", "3", "4", "5", "6", "7", + }, + }, + { + name: "no-uids-ejected-2", + givenMaxCookieSize: 0, + expectedRemainingUidKeys: []string{ + "1", "2", "3", "4", "5", "6", "7", + }, + }, + { + name: "one-uid-ejected", + givenMaxCookieSize: 900, + expectedRemainingUidKeys: []string{ + "1", "2", "3", "4", "5", "6", + }, + }, + { + name: "four-uids-ejected", + givenMaxCookieSize: 500, + expectedRemainingUidKeys: []string{ + "1", "2", "3", + }, + }, + { + name: "all-but-one-uids-ejected", + givenMaxCookieSize: 300, + expectedRemainingUidKeys: []string{ + "1", + }, + }, + { + name: "all-uids-ejected", + givenMaxCookieSize: 100, + expectedRemainingUidKeys: []string{}, + }, + { + name: "invalid-max-size", + givenMaxCookieSize: -100, + expectedRemainingUidKeys: []string{}, + }, } - ensureConsistency(t, cookie) -} -func TestParseCorruptedCookie(t *testing.T) { - raw := http.Cookie{ - Name: "uids", - Value: "bad base64 encoding", + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + encodedCookie, err := cookieToSend.PrepareCookieForWrite(&config.HostCookie{MaxCookieSizeBytes: test.givenMaxCookieSize}, encoder) + assert.NoError(t, err) + decodedCookie := decoder.Decode(encodedCookie) + + for _, key := range test.expectedRemainingUidKeys { + _, ok := decodedCookie.uids[key] + assert.Equal(t, true, ok) + } + assert.Equal(t, len(decodedCookie.uids), len(test.expectedRemainingUidKeys)) + }) } - parsed := ParseCookie(&raw) - ensureEmptyMap(t, parsed) } -func TestParseCorruptedCookieJSON(t *testing.T) { - cookieData := base64.URLEncoding.EncodeToString([]byte("bad json")) - raw := http.Cookie{ - Name: "uids", - Value: cookieData, +func TestSyncHostCookie(t *testing.T) { + testCases := []struct { + name string + givenCookie *Cookie + givenUID string + givenHostCookie *config.HostCookie + expectedCookie *Cookie + expectedError error + }{ + { + name: "simple-sync", + givenCookie: &Cookie{ + uids: map[string]UIDEntry{}, + }, + givenHostCookie: &config.HostCookie{ + Family: "syncer", + CookieName: "adnxs", + }, + expectedCookie: &Cookie{ + uids: map[string]UIDEntry{ + "syncer": { + UID: "some-user-id", + }, + }, + }, + }, + { + name: "uids-already-present", + givenCookie: &Cookie{ + uids: map[string]UIDEntry{ + "some-syncer": { + UID: "some-other-user-id", + }, + }, + }, + givenHostCookie: &config.HostCookie{ + Family: "syncer", + CookieName: "adnxs", + }, + expectedCookie: &Cookie{ + uids: map[string]UIDEntry{ + "syncer": { + UID: "some-user-id", + }, + "some-syncer": { + UID: "some-other-user-id", + }, + }, + }, + }, + { + name: "host-already-synced", + givenCookie: &Cookie{ + uids: map[string]UIDEntry{ + "syncer": { + UID: "some-user-id", + }, + }, + }, + givenHostCookie: &config.HostCookie{ + Family: "syncer", + CookieName: "adnxs", + }, + expectedCookie: &Cookie{ + uids: map[string]UIDEntry{ + "syncer": { + UID: "some-user-id", + }, + }, + }, + }, } - parsed := ParseCookie(&raw) - ensureEmptyMap(t, parsed) -} -func TestParseNilSyncMap(t *testing.T) { - raw := http.Cookie{ - Name: uidCookieName, - Value: "", + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + r := httptest.NewRequest("POST", "http://www.prebid.com", nil) + r.AddCookie(&http.Cookie{ + Name: test.givenHostCookie.CookieName, + Value: "some-user-id", + }) + + SyncHostCookie(r, test.givenCookie, test.givenHostCookie) + for key, value := range test.expectedCookie.uids { + assert.Equal(t, value.UID, test.givenCookie.uids[key].UID) + } + }) } - parsed := ParseCookie(&raw) - ensureEmptyMap(t, parsed) - ensureConsistency(t, parsed) } -func TestParseOtherCookie(t *testing.T) { - req := httptest.NewRequest("POST", "http://www.prebid.com", nil) - otherCookieName := "other" - id := "some-user-id" - req.AddCookie(&http.Cookie{ - Name: otherCookieName, - Value: id, - }) - parsed := ParseCookieFromRequest(req, &config.HostCookie{ - Family: "adnxs", - CookieName: otherCookieName, - }) - val, _, _ := parsed.GetUID("adnxs") - if val != id { - t.Errorf("Bad cookie value. Expected %s, got %s", id, val) +func TestBidderNameGets(t *testing.T) { + cookie := newSampleCookie() + id, exists, _ := cookie.GetUID("adnxs") + if !exists { + t.Errorf("Cookie missing expected Appnexus ID") + } + if id != "123" { + t.Errorf("Bad appnexus id. Expected %s, got %s", "123", id) + } + + id, exists, _ = cookie.GetUID("rubicon") + if !exists { + t.Errorf("Cookie missing expected Rubicon ID") + } + if id != "456" { + t.Errorf("Bad rubicon id. Expected %s, got %s", "456", id) } } -func TestParseCookieFromRequestOptOut(t *testing.T) { +func TestReadCookieOptOut(t *testing.T) { optOutCookieName := "optOutCookieName" optOutCookieValue := "optOutCookieValue" + decoder := Base64Decoder{} - existingCookie := *(&Cookie{ - uids: map[string]uidWithExpiry{ + cookie := *(&Cookie{ + uids: map[string]UIDEntry{ "foo": newTempId("fooID", 1), "bar": newTempId("barID", 2), }, optOut: false, - }).ToHTTPCookie(24 * time.Hour) + }) + + existingCookie, _ := ToHTTPCookie(&cookie) testCases := []struct { description string - givenExistingCookies []http.Cookie + givenExistingCookies []*http.Cookie expectedEmpty bool expectedSetOptOut bool }{ { description: "Opt Out Cookie", - givenExistingCookies: []http.Cookie{ + givenExistingCookies: []*http.Cookie{ existingCookie, {Name: optOutCookieName, Value: optOutCookieValue}}, expectedEmpty: true, @@ -179,14 +599,14 @@ func TestParseCookieFromRequestOptOut(t *testing.T) { }, { description: "No Opt Out Cookie", - givenExistingCookies: []http.Cookie{ + givenExistingCookies: []*http.Cookie{ existingCookie}, expectedEmpty: false, expectedSetOptOut: false, }, { description: "Opt Out Cookie - Wrong Value", - givenExistingCookies: []http.Cookie{ + givenExistingCookies: []*http.Cookie{ existingCookie, {Name: optOutCookieName, Value: "wrong"}}, expectedEmpty: false, @@ -194,7 +614,7 @@ func TestParseCookieFromRequestOptOut(t *testing.T) { }, { description: "Opt Out Cookie - Wrong Name", - givenExistingCookies: []http.Cookie{ + givenExistingCookies: []*http.Cookie{ existingCookie, {Name: "wrong", Value: optOutCookieValue}}, expectedEmpty: false, @@ -202,7 +622,7 @@ func TestParseCookieFromRequestOptOut(t *testing.T) { }, { description: "Opt Out Cookie - No Host Cookies", - givenExistingCookies: []http.Cookie{ + givenExistingCookies: []*http.Cookie{ {Name: optOutCookieName, Value: optOutCookieValue}}, expectedEmpty: true, expectedSetOptOut: true, @@ -213,10 +633,10 @@ func TestParseCookieFromRequestOptOut(t *testing.T) { req := httptest.NewRequest("POST", "http://www.prebid.com", nil) for _, c := range test.givenExistingCookies { - req.AddCookie(&c) + req.AddCookie(c) } - parsed := ParseCookieFromRequest(req, &config.HostCookie{ + parsed := ReadCookie(req, decoder, &config.HostCookie{ Family: "foo", OptOutCookie: config.Cookie{ Name: optOutCookieName, @@ -233,125 +653,59 @@ func TestParseCookieFromRequestOptOut(t *testing.T) { } } -func TestCookieReadWrite(t *testing.T) { - cookie := newSampleCookie() - - received := writeThenRead(cookie, 0) - uid, exists, isLive := received.GetUID("adnxs") - if !exists || !isLive || uid != "123" { - t.Errorf("Received cookie should have the adnxs ID=123. Got %s", uid) - } - - uid, exists, isLive = received.GetUID("rubicon") - if !exists || !isLive || uid != "456" { - t.Errorf("Received cookie should have the rubicon ID=456. Got %s", uid) - } - - assert.True(t, received.HasAnyLiveSyncs(), "Has Live Syncs") - assert.Len(t, received.uids, 2, "Sync Count") -} - -func TestNilCookie(t *testing.T) { - var nilCookie *Cookie - - if nilCookie.HasLiveSync("anything") { - t.Error("nil cookies should respond with false when asked if they have a sync") - } - - if nilCookie.HasAnyLiveSyncs() { - t.Error("nil cookies shouldn't have any syncs.") - } - - if nilCookie.AllowSyncs() { - t.Error("nil cookies shouldn't allow syncs to take place.") +func TestOptIn(t *testing.T) { + cookie := &Cookie{ + uids: make(map[string]UIDEntry), + optOut: true, } - uid, hadUID, isLive := nilCookie.GetUID("anything") - - if uid != "" { - t.Error("nil cookies should return empty strings for the UID.") - } - if hadUID { - t.Error("nil cookies shouldn't claim to have a UID mapping.") - } - if isLive { - t.Error("nil cookies shouldn't report live UID mappings.") + cookie.SetOptOut(false) + if !cookie.AllowSyncs() { + t.Error("After SetOptOut(false), a cookie should allow more user syncs.") } + ensureConsistency(t, cookie) } -func TestGetUIDs(t *testing.T) { +func TestOptOutReset(t *testing.T) { cookie := newSampleCookie() - uids := cookie.GetUIDs() - assert.Len(t, uids, 2, "GetUIDs should return user IDs for all bidders") - assert.Equal(t, "123", uids["adnxs"], "GetUIDs should return the correct user ID for each bidder") - assert.Equal(t, "456", uids["rubicon"], "GetUIDs should return the correct user ID for each bidder") + cookie.SetOptOut(true) + if cookie.AllowSyncs() { + t.Error("After SetOptOut(true), a cookie should not allow more user syncs.") + } + ensureConsistency(t, cookie) } -func TestGetUIDsWithEmptyCookie(t *testing.T) { - cookie := &Cookie{} - uids := cookie.GetUIDs() - - assert.Len(t, uids, 0, "GetUIDs shouldn't return any user syncs for an empty cookie") +func TestOptOutCookie(t *testing.T) { + cookie := &Cookie{ + uids: make(map[string]UIDEntry), + optOut: true, + } + ensureConsistency(t, cookie) } -func TestGetUIDsWithNilCookie(t *testing.T) { - var cookie *Cookie - uids := cookie.GetUIDs() - - assert.Len(t, uids, 0, "GetUIDs shouldn't return any user syncs for a nil cookie") +func newTempId(uid string, offset int) UIDEntry { + return UIDEntry{ + UID: uid, + Expires: time.Now().Add(time.Duration(offset) * time.Minute).UTC(), + } } -func TestTrimCookiesClosestExpirationDates(t *testing.T) { - cookieToSend := &Cookie{ - uids: map[string]uidWithExpiry{ - "k1": newTempId("12345678901234567890123456789012345678901234567890", 7), - "k2": newTempId("abcdefghijklmnopqrstuvwxyz", 1), - "k3": newTempId("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 6), - "k4": newTempId("12345678901234567890123456789612345678901234567890", 5), - "k5": newTempId("aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ", 4), - "k6": newTempId("12345678901234567890123456789012345678901234567890", 3), - "k7": newTempId("abcdefghijklmnopqrstuvwxyz", 2), +func newSampleCookie() *Cookie { + return &Cookie{ + uids: map[string]UIDEntry{ + "adnxs": newTempId("123", 10), + "rubicon": newTempId("456", 10), }, optOut: false, } - - type aTest struct { - maxCookieSize int - expKeys []string - } - testCases := []aTest{ - {maxCookieSize: 2000, expKeys: []string{"k1", "k2", "k3", "k4", "k5", "k6", "k7"}}, //1 don't trim, set - {maxCookieSize: 0, expKeys: []string{"k1", "k2", "k3", "k4", "k5", "k6", "k7"}}, //2 unlimited size: don't trim, set - {maxCookieSize: 800, expKeys: []string{"k1", "k5", "k4", "k3", "k6"}}, //3 trim to size and set - {maxCookieSize: 500, expKeys: []string{"k1", "k4", "k3"}}, //4 trim to size and set - {maxCookieSize: 200, expKeys: []string{}}, //5 insufficient size, trim to zero length and set - {maxCookieSize: -100, expKeys: []string{}}, //6 invalid size, trim to zero length and set - } - for i := range testCases { - processedCookie := writeThenRead(cookieToSend, testCases[i].maxCookieSize) - - actualKeys := make([]string, 0, 7) - for key := range processedCookie.uids { - actualKeys = append(actualKeys, key) - } - - assert.ElementsMatch(t, testCases[i].expKeys, actualKeys, "[Test %d]", i+1) - } -} - -func ensureEmptyMap(t *testing.T, cookie *Cookie) { - if !cookie.AllowSyncs() { - t.Error("Empty cookies should allow user syncs.") - } - if cookie.HasAnyLiveSyncs() { - t.Error("Empty cookies shouldn't have any user syncs. Found at least 1.") - } } func ensureConsistency(t *testing.T, cookie *Cookie) { + decoder := Base64Decoder{} + if cookie.AllowSyncs() { - err := cookie.TrySync("pulsepoint", "1") + err := cookie.Sync("pulsepoint", "1") if err != nil { t.Errorf("Cookie sync should succeed if the user has opted in.") } @@ -380,13 +734,14 @@ func ensureConsistency(t *testing.T, cookie *Cookie) { t.Error("If the user opted out, the PBSCookie should have no user syncs.") } - err := cookie.TrySync("adnxs", "123") + err := cookie.Sync("adnxs", "123") if err == nil { t.Error("TrySync should fail if the user has opted out of PBSCookie syncs, but it succeeded.") } } - - copiedCookie := ParseCookie(cookie.ToHTTPCookie(90 * 24 * time.Hour)) + httpCookie, err := ToHTTPCookie(cookie) + assert.NoError(t, err) + copiedCookie := decoder.Decode(httpCookie.Value) if copiedCookie.AllowSyncs() != cookie.AllowSyncs() { t.Error("The PBSCookie interface shouldn't let modifications happen if the user has opted out") } @@ -414,61 +769,17 @@ func ensureConsistency(t *testing.T, cookie *Cookie) { } } -func newTempId(uid string, offset int) uidWithExpiry { - return uidWithExpiry{ - UID: uid, - Expires: time.Now().Add(time.Duration(offset) * time.Minute).UTC(), +func ToHTTPCookie(cookie *Cookie) (*http.Cookie, error) { + encoder := Base64Encoder{} + encodedCookie, err := encoder.Encode(cookie) + if err != nil { + return nil, nil } -} -func newSampleCookie() *Cookie { - return &Cookie{ - uids: map[string]uidWithExpiry{ - "adnxs": newTempId("123", 10), - "rubicon": newTempId("456", 10), - }, - optOut: false, - } -} - -func writeThenRead(cookie *Cookie, maxCookieSize int) *Cookie { - w := httptest.NewRecorder() - hostCookie := &config.HostCookie{Domain: "mock-domain", MaxCookieSizeBytes: maxCookieSize} - cookie.SetCookieOnResponse(w, false, hostCookie, 90*24*time.Hour) - writtenCookie := w.HeaderMap.Get("Set-Cookie") - - header := http.Header{} - header.Add("Cookie", writtenCookie) - request := http.Request{Header: header} - return ParseCookieFromRequest(&request, hostCookie) -} - -func TestSetCookieOnResponseForSameSiteNone(t *testing.T) { - cookie := newSampleCookie() - w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "http://www.prebid.com", nil) - ua := "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36" - req.Header.Set("User-Agent", ua) - hostCookie := &config.HostCookie{Domain: "mock-domain", MaxCookieSizeBytes: 0} - cookie.SetCookieOnResponse(w, true, hostCookie, 90*24*time.Hour) - writtenCookie := w.HeaderMap.Get("Set-Cookie") - t.Log("Set-Cookie is: ", writtenCookie) - if !strings.Contains(writtenCookie, "; Secure;") { - t.Error("Set-Cookie should contain Secure") - } -} - -func TestSetCookieOnResponseForOlderChromeVersion(t *testing.T) { - cookie := newSampleCookie() - w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "http://www.prebid.com", nil) - ua := "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3770.142 Safari/537.36" - req.Header.Set("User-Agent", ua) - hostCookie := &config.HostCookie{Domain: "mock-domain", MaxCookieSizeBytes: 0} - cookie.SetCookieOnResponse(w, false, hostCookie, 90*24*time.Hour) - writtenCookie := w.HeaderMap.Get("Set-Cookie") - t.Log("Set-Cookie is: ", writtenCookie) - if strings.Contains(writtenCookie, "SameSite=none") { - t.Error("Set-Cookie should not contain SameSite=none") - } + return &http.Cookie{ + Name: uidCookieName, + Value: encodedCookie, + Expires: time.Now().Add((90 * 24 * time.Hour)), + Path: "/", + }, nil } diff --git a/usersync/decoder.go b/usersync/decoder.go new file mode 100644 index 00000000000..3ff13aa3242 --- /dev/null +++ b/usersync/decoder.go @@ -0,0 +1,27 @@ +package usersync + +import ( + "encoding/base64" + "encoding/json" +) + +type Decoder interface { + // Decode takes an encoded string and decodes it into a cookie + Decode(v string) *Cookie +} + +type Base64Decoder struct{} + +func (d Base64Decoder) Decode(encodedValue string) *Cookie { + jsonValue, err := base64.URLEncoding.DecodeString(encodedValue) + if err != nil { + return NewCookie() + } + + var cookie Cookie + if err = json.Unmarshal(jsonValue, &cookie); err != nil { + return NewCookie() + } + + return &cookie +} diff --git a/usersync/encoder.go b/usersync/encoder.go new file mode 100644 index 00000000000..eef7e2ef34f --- /dev/null +++ b/usersync/encoder.go @@ -0,0 +1,23 @@ +package usersync + +import ( + "encoding/base64" + "encoding/json" +) + +type Encoder interface { + // Encode a cookie into a base 64 string + Encode(c *Cookie) (string, error) +} + +type Base64Encoder struct{} + +func (e Base64Encoder) Encode(c *Cookie) (string, error) { + j, err := json.Marshal(c) + if err != nil { + return "", err + } + b64 := base64.URLEncoding.EncodeToString(j) + + return b64, nil +} diff --git a/usersync/encoder_decoder_test.go b/usersync/encoder_decoder_test.go new file mode 100644 index 00000000000..5a87d4e7c82 --- /dev/null +++ b/usersync/encoder_decoder_test.go @@ -0,0 +1,149 @@ +package usersync + +import ( + "net/http" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestEncoderDecoder(t *testing.T) { + encoder := Base64Encoder{} + decoder := Base64Decoder{} + + testCases := []struct { + name string + givenRequest *http.Request + givenHttpCookie *http.Cookie + givenCookie *Cookie + givenDecoder Decoder + expectedCookie *Cookie + }{ + { + name: "simple-cookie", + givenCookie: &Cookie{ + uids: map[string]UIDEntry{ + "adnxs": { + UID: "UID", + Expires: time.Time{}, + }, + }, + optOut: false, + }, + expectedCookie: &Cookie{ + uids: map[string]UIDEntry{ + "adnxs": { + UID: "UID", + }, + }, + optOut: false, + }, + }, + { + name: "empty-cookie", + givenCookie: &Cookie{}, + expectedCookie: &Cookie{ + uids: map[string]UIDEntry{}, + optOut: false, + }, + }, + { + name: "nil-cookie", + givenCookie: nil, + expectedCookie: &Cookie{ + uids: map[string]UIDEntry{}, + optOut: false, + }, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + encodedCookie, err := encoder.Encode(test.givenCookie) + assert.NoError(t, err) + decodedCookie := decoder.Decode(encodedCookie) + + assert.Equal(t, test.expectedCookie.uids, decodedCookie.uids) + assert.Equal(t, test.expectedCookie.optOut, decodedCookie.optOut) + }) + } +} + +func TestEncoder(t *testing.T) { + encoder := Base64Encoder{} + + testCases := []struct { + name string + givenCookie *Cookie + expectedEncodedCookie string + }{ + { + name: "simple-cookie", + givenCookie: &Cookie{ + uids: map[string]UIDEntry{ + "adnxs": { + UID: "UID", + Expires: time.Time{}, + }, + }, + optOut: false, + }, + expectedEncodedCookie: "eyJ0ZW1wVUlEcyI6eyJhZG54cyI6eyJ1aWQiOiJVSUQiLCJleHBpcmVzIjoiMDAwMS0wMS0wMVQwMDowMDowMFoifX19", + }, + { + name: "empty-cookie", + givenCookie: &Cookie{}, + expectedEncodedCookie: "e30=", + }, + { + name: "nil-cookie", + givenCookie: nil, + expectedEncodedCookie: "bnVsbA==", + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + encodedCookie, err := encoder.Encode(test.givenCookie) + assert.NoError(t, err) + + assert.Equal(t, test.expectedEncodedCookie, encodedCookie) + }) + } +} + +func TestDecoder(t *testing.T) { + decoder := Base64Decoder{} + + testCases := []struct { + name string + givenEncodedCookie string + expectedCookie *Cookie + }{ + { + name: "simple-encoded-cookie", + givenEncodedCookie: "eyJ0ZW1wVUlEcyI6eyJhZG54cyI6eyJ1aWQiOiJVSUQiLCJleHBpcmVzIjoiMDAwMS0wMS0wMVQwMDowMDowMFoifX19", + expectedCookie: &Cookie{ + uids: map[string]UIDEntry{ + "adnxs": { + UID: "UID", + }, + }, + optOut: false, + }, + }, + { + name: "nil-encoded-cookie", + givenEncodedCookie: "", + expectedCookie: NewCookie(), + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + decodedCookie := decoder.Decode(test.givenEncodedCookie) + assert.Equal(t, test.expectedCookie, decodedCookie) + }) + } +} From 097512f951eacb4e2c2b6f0506f6f80e96ee8d02 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Tue, 18 Jul 2023 11:53:13 +0530 Subject: [PATCH 026/268] specify branch to check out (#2940) Co-authored-by: @onkarvhanumante --- .github/workflows/semgrep.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml index a541dd9d861..a3ac7c54f9f 100644 --- a/.github/workflows/semgrep.yml +++ b/.github/workflows/semgrep.yml @@ -12,6 +12,7 @@ jobs: uses: actions/checkout@v3 with: fetch-depth: 0 + ref: ${{github.event.pull_request.head.ref}} - name: Calculate diff id: calculate_diff From 6c89af28a0fd709c1ae41969610cd38171c4ec73 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Tue, 18 Jul 2023 14:25:42 +0530 Subject: [PATCH 027/268] specify `repository` during checkout step (#2943) Co-authored-by: oh0387 --- .github/workflows/semgrep.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml index a3ac7c54f9f..565bb9b871a 100644 --- a/.github/workflows/semgrep.yml +++ b/.github/workflows/semgrep.yml @@ -13,6 +13,7 @@ jobs: with: fetch-depth: 0 ref: ${{github.event.pull_request.head.ref}} + repository: ${{github.event.pull_request.head.repo.full_name}} - name: Calculate diff id: calculate_diff From 413e5eb67a764fa42e8b14df0852773984749711 Mon Sep 17 00:00:00 2001 From: erictmf <120136093+erictmf@users.noreply.github.com> Date: Tue, 18 Jul 2023 08:23:28 -0400 Subject: [PATCH 028/268] Mobilefuse: Added support for skadn. Forwarding imp.ext.skadn (#2918) co-authored by @erictmf --- adapters/mobilefuse/mobilefuse.go | 42 +++++++--- .../mobilefusetest/exemplary/skadn.json | 78 +++++++++++++++++++ 2 files changed, 110 insertions(+), 10 deletions(-) create mode 100644 adapters/mobilefuse/mobilefusetest/exemplary/skadn.json diff --git a/adapters/mobilefuse/mobilefuse.go b/adapters/mobilefuse/mobilefuse.go index f46fc5913a3..07ecd61b26a 100644 --- a/adapters/mobilefuse/mobilefuse.go +++ b/adapters/mobilefuse/mobilefuse.go @@ -27,6 +27,10 @@ type BidExt struct { Mf ExtMf `json:"mf"` } +type ExtSkadn struct { + Skadn json.RawMessage `json:"skadn"` +} + // Builder builds a new instance of the MobileFuse adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { template, err := template.New("endpointTemplate").Parse(config.Endpoint) @@ -79,7 +83,7 @@ func (adapter *MobileFuseAdapter) MakeBids(incomingRequest *openrtb2.BidRequest, for _, seatbid := range incomingBidResponse.SeatBid { for i := range seatbid.Bid { - bidType := adapter.getBidType(seatbid.Bid[i]) + bidType := getBidType(seatbid.Bid[i]) seatbid.Bid[i].Ext = nil outgoingBidResponse.Bids = append(outgoingBidResponse.Bids, &adapters.TypedBid{ @@ -95,7 +99,7 @@ func (adapter *MobileFuseAdapter) MakeBids(incomingRequest *openrtb2.BidRequest, func (adapter *MobileFuseAdapter) makeRequest(bidRequest *openrtb2.BidRequest) (*adapters.RequestData, []error) { var errs []error - mobileFuseExtension, errs := adapter.getFirstMobileFuseExtension(bidRequest) + mobileFuseExtension, errs := getFirstMobileFuseExtension(bidRequest) if errs != nil { return nil, errs @@ -107,10 +111,9 @@ func (adapter *MobileFuseAdapter) makeRequest(bidRequest *openrtb2.BidRequest) ( return nil, append(errs, err) } - validImps := adapter.getValidImps(bidRequest, mobileFuseExtension) + validImps, err := getValidImps(bidRequest, mobileFuseExtension) - if len(validImps) == 0 { - err := fmt.Errorf("No valid imps") + if err != nil { errs = append(errs, err) return nil, errs } @@ -135,7 +138,7 @@ func (adapter *MobileFuseAdapter) makeRequest(bidRequest *openrtb2.BidRequest) ( }, errs } -func (adapter *MobileFuseAdapter) getFirstMobileFuseExtension(request *openrtb2.BidRequest) (*openrtb_ext.ExtImpMobileFuse, []error) { +func getFirstMobileFuseExtension(request *openrtb2.BidRequest) (*openrtb_ext.ExtImpMobileFuse, []error) { var mobileFuseImpExtension openrtb_ext.ExtImpMobileFuse var errs []error @@ -178,23 +181,42 @@ func (adapter *MobileFuseAdapter) getEndpoint(ext *openrtb_ext.ExtImpMobileFuse) return url, nil } -func (adapter *MobileFuseAdapter) getValidImps(bidRequest *openrtb2.BidRequest, ext *openrtb_ext.ExtImpMobileFuse) []openrtb2.Imp { +func getValidImps(bidRequest *openrtb2.BidRequest, ext *openrtb_ext.ExtImpMobileFuse) ([]openrtb2.Imp, error) { var validImps []openrtb2.Imp for _, imp := range bidRequest.Imp { if imp.Banner != nil || imp.Video != nil || imp.Native != nil { imp.TagID = strconv.Itoa(ext.PlacementId) - imp.Ext = nil + + var extSkadn ExtSkadn + err := json.Unmarshal(imp.Ext, &extSkadn) + if err != nil { + return nil, err + } + + if extSkadn.Skadn != nil { + imp.Ext, err = json.Marshal(map[string]json.RawMessage{"skadn": extSkadn.Skadn}) + if err != nil { + return nil, err + } + } else { + imp.Ext = nil + } + validImps = append(validImps, imp) break } } - return validImps + if len(validImps) == 0 { + return nil, fmt.Errorf("No valid imps") + } + + return validImps, nil } -func (adapter *MobileFuseAdapter) getBidType(bid openrtb2.Bid) openrtb_ext.BidType { +func getBidType(bid openrtb2.Bid) openrtb_ext.BidType { if bid.Ext != nil { var bidExt BidExt err := json.Unmarshal(bid.Ext, &bidExt) diff --git a/adapters/mobilefuse/mobilefusetest/exemplary/skadn.json b/adapters/mobilefuse/mobilefusetest/exemplary/skadn.json new file mode 100644 index 00000000000..e8fd66b1111 --- /dev/null +++ b/adapters/mobilefuse/mobilefusetest/exemplary/skadn.json @@ -0,0 +1,78 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "skadn": { + "versions": [ + "2.0", + "2.1" + ], + "sourceapp": "11111", + "skadnetids": [ + "424m5254lk.skadnetwork", + "4fzdc2evr5.skadnetwork" + ] + }, + "bidder": { + "placement_id": 999999, + "pub_id": 1111, + "tagid_src": "ext" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://mfx.mobilefuse.com/openrtb?pub_id=1111&tagid_src=ext", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "tagid": "999999", + "ext": { + "skadn": { + "versions": [ + "2.0", + "2.1" + ], + "sourceapp": "11111", + "skadnetids": [ + "424m5254lk.skadnetwork", + "4fzdc2evr5.skadnetwork" + ] + } + } + } + ] + } + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + "expectedBidResponses": [] +} \ No newline at end of file From cb08c4dc2ada0933a5a5b5e646a95b1e55a9de07 Mon Sep 17 00:00:00 2001 From: Brian Sardo <1168933+bsardo@users.noreply.github.com> Date: Tue, 18 Jul 2023 15:36:07 -0400 Subject: [PATCH 029/268] GDPR: support bidders without a GVL ID (#2882) --- gdpr/consent_parser.go | 67 +++++++++++++ gdpr/consent_parser_test.go | 160 +++++++++++++++++++++++++++++++ gdpr/full_enforcement.go | 6 ++ gdpr/full_enforcement_test.go | 60 ++++++++++++ gdpr/impl.go | 137 ++++---------------------- gdpr/impl_test.go | 174 ++++++++++++++++++++-------------- 6 files changed, 416 insertions(+), 188 deletions(-) create mode 100644 gdpr/consent_parser.go create mode 100644 gdpr/consent_parser_test.go diff --git a/gdpr/consent_parser.go b/gdpr/consent_parser.go new file mode 100644 index 00000000000..3a354886036 --- /dev/null +++ b/gdpr/consent_parser.go @@ -0,0 +1,67 @@ +package gdpr + +import ( + "errors" + "fmt" + + "github.com/prebid/go-gdpr/api" + "github.com/prebid/go-gdpr/vendorconsent" + tcf2 "github.com/prebid/go-gdpr/vendorconsent/tcf2" +) + +// parsedConsent represents a parsed consent string containing notable version information and a convenient +// metadata object that allows easy examination of encoded purpose and vendor information +type parsedConsent struct { + encodingVersion uint8 + listVersion uint16 + specVersion uint16 + consentMeta tcf2.ConsentMetadata +} + +// parseConsent parses and validates the specified consent string returning an instance of parsedConsent +func parseConsent(consent string) (*parsedConsent, error) { + pc, err := vendorconsent.ParseString(consent) + if err != nil { + return nil, &ErrorMalformedConsent{ + Consent: consent, + Cause: err, + } + } + if err = validateVersions(pc); err != nil { + return nil, &ErrorMalformedConsent{ + Consent: consent, + Cause: err, + } + } + cm, ok := pc.(tcf2.ConsentMetadata) + if !ok { + err = errors.New("Unable to access TCF2 parsed consent") + return nil, err + } + return &parsedConsent{ + encodingVersion: pc.Version(), + listVersion: pc.VendorListVersion(), + specVersion: getSpecVersion(pc.TCFPolicyVersion()), + consentMeta: cm, + }, nil +} + +// validateVersions ensures that certain version fields in the consent string contain valid values. +// An error is returned if at least one of them is invalid +func validateVersions(pc api.VendorConsents) (err error) { + version := pc.Version() + if version != 2 { + return fmt.Errorf("invalid encoding format version: %d", version) + } + return +} + +// getSpecVersion looks at the TCF policy version and determines the corresponding GVL specification +// version that should be used to calculate legal basis. A zero value is returned if the policy version +// is invalid +func getSpecVersion(policyVersion uint8) uint16 { + if policyVersion >= 4 { + return 3 + } + return 2 +} diff --git a/gdpr/consent_parser_test.go b/gdpr/consent_parser_test.go new file mode 100644 index 00000000000..4708f689f05 --- /dev/null +++ b/gdpr/consent_parser_test.go @@ -0,0 +1,160 @@ +package gdpr + +import ( + "errors" + "testing" + "time" + + "github.com/prebid/go-gdpr/consentconstants" + + "github.com/stretchr/testify/assert" +) + +func TestParseConsent(t *testing.T) { + validTCF1Consent := "BONV8oqONXwgmADACHENAO7pqzAAppY" + validTCF2Consent := "CPuKGCPPuKGCPNEAAAENCZCAAAAAAAAAAAAAAAAAAAAA" + + tests := []struct { + name string + consent string + expectedEncodingVersion uint8 + expectedListVersion uint16 + expectedSpecVersion uint16 + expectedError error + }{ + + { + name: "valid_consent_with_encoding_version_2", + consent: validTCF2Consent, + expectedEncodingVersion: 2, + expectedListVersion: 153, + expectedSpecVersion: 2, + }, + { + name: "invalid_consent_parsing_error", + consent: "", + expectedError: &ErrorMalformedConsent{ + Consent: "", + Cause: consentconstants.ErrEmptyDecodedConsent, + }, + }, + { + name: "invalid_consent_version_validation_error", + consent: validTCF1Consent, + expectedError: &ErrorMalformedConsent{ + Consent: validTCF1Consent, + Cause: errors.New("invalid encoding format version: 1"), + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + parsedConsent, err := parseConsent(tt.consent) + + if tt.expectedError != nil { + assert.Equal(t, tt.expectedError, err) + assert.Nil(t, parsedConsent) + } else { + assert.NoError(t, err) + assert.NotNil(t, parsedConsent) + assert.Equal(t, uint8(2), parsedConsent.encodingVersion) + assert.Equal(t, uint16(153), parsedConsent.listVersion) + assert.Equal(t, uint16(2), parsedConsent.specVersion) + assert.Equal(t, tt.expectedEncodingVersion, parsedConsent.consentMeta.Version()) + assert.Equal(t, tt.expectedListVersion, parsedConsent.consentMeta.VendorListVersion()) + } + }) + } +} + +func TestValidateVersions(t *testing.T) { + tests := []struct { + name string + version uint8 + expectedError error + }{ + { + name: "valid_consent_version=2", + version: 2, + }, + { + name: "invalid_consent_version<2", + version: 1, + expectedError: errors.New("invalid encoding format version: 1"), + }, + { + name: "invalid_consent_version>2", + version: 3, + expectedError: errors.New("invalid encoding format version: 3"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mcs := mockConsentString{ + version: tt.version, + } + err := validateVersions(&mcs) + if tt.expectedError != nil { + assert.Equal(t, tt.expectedError, err) + } else { + assert.Nil(t, err) + } + }) + } +} + +func TestGetSpecVersion(t *testing.T) { + tests := []struct { + name string + policyVersion uint8 + expectedSpecVersion uint16 + }{ + { + name: "policy_version_0_gives_spec_version_2", + policyVersion: 0, + expectedSpecVersion: 2, + }, + { + name: "policy_version_3_gives_spec_version_2", + policyVersion: 3, + expectedSpecVersion: 2, + }, + { + name: "policy_version_4_gives_spec_version_3", + policyVersion: 4, + expectedSpecVersion: 3, + }, + { + name: "policy_version_5_gives_spec_version_3", + policyVersion: 5, + expectedSpecVersion: 3, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + specVersion := getSpecVersion(tt.policyVersion) + assert.Equal(t, tt.expectedSpecVersion, specVersion) + }) + } +} + +type mockConsentString struct { + version uint8 + policyVersion uint8 +} + +func (mcs *mockConsentString) Version() uint8 { return mcs.version } +func (mcs *mockConsentString) Created() time.Time { return time.Time{} } +func (mcs *mockConsentString) LastUpdated() time.Time { return time.Time{} } +func (mcs *mockConsentString) CmpID() uint16 { return 0 } +func (mcs *mockConsentString) CmpVersion() uint16 { return 0 } +func (mcs *mockConsentString) ConsentScreen() uint8 { return 0 } +func (mcs *mockConsentString) ConsentLanguage() string { return "" } +func (mcs *mockConsentString) VendorListVersion() uint16 { return 0 } +func (mcs *mockConsentString) TCFPolicyVersion() uint8 { return mcs.policyVersion } +func (mcs *mockConsentString) MaxVendorID() uint16 { return 0 } +func (mcs *mockConsentString) PurposeAllowed(id consentconstants.Purpose) bool { return false } +func (mcs *mockConsentString) VendorConsent(id uint16) bool { return false } diff --git a/gdpr/full_enforcement.go b/gdpr/full_enforcement.go index b86f7a3ff88..eefa28d5499 100644 --- a/gdpr/full_enforcement.go +++ b/gdpr/full_enforcement.go @@ -67,6 +67,9 @@ func (fe *FullEnforcement) applyEnforceOverrides(overrides Overrides) (enforcePu // must declare the purpose as either consent or flex and the user must consent in accordance with // the purpose configs. func (fe *FullEnforcement) consentEstablished(consent tcf2.ConsentMetadata, vi VendorInfo, enforcePurpose bool, enforceVendors bool) bool { + if vi.vendor == nil { + return false + } if !vi.vendor.Purpose(fe.cfg.PurposeID) { return false } @@ -84,6 +87,9 @@ func (fe *FullEnforcement) consentEstablished(consent tcf2.ConsentMetadata, vi V // established, the vendor must declare the purpose as either legit interest or flex and the user // must have been provided notice for the legit interest basis in accordance with the purpose configs. func (fe *FullEnforcement) legitInterestEstablished(consent tcf2.ConsentMetadata, vi VendorInfo, enforcePurpose bool, enforceVendors bool) bool { + if vi.vendor == nil { + return false + } if !vi.vendor.LegitimateInterest(fe.cfg.PurposeID) { return false } diff --git a/gdpr/full_enforcement_test.go b/gdpr/full_enforcement_test.go index e8ccd1e4c0c..61f6e8b8520 100644 --- a/gdpr/full_enforcement_test.go +++ b/gdpr/full_enforcement_test.go @@ -898,6 +898,66 @@ func TestLegalBasisWithPubRestrictionRequireLI(t *testing.T) { } } +func TestLegalBasisWithoutVendor(t *testing.T) { + P1P2P3PurposeConsent := "CPfCRQAPfCRQAAAAAAENCgCAAOAAAAAAAAAAAAAAAAAA" + tests := []struct { + name string + config purposeConfig + wantResult bool + }{ + { + name: "enforce_purpose_&_vendors_off", + config: purposeConfig{ + EnforcePurpose: false, + EnforceVendors: false, + }, + wantResult: true, + }, + { + name: "enforce_purpose_on,_bidder_is_a_vendor_exception", + config: purposeConfig{ + EnforcePurpose: true, + EnforceVendors: false, + VendorExceptionMap: map[openrtb_ext.BidderName]struct{}{openrtb_ext.BidderAppnexus: {}}, + }, + wantResult: true, + }, + { + name: "enforce_purpose_on", + config: purposeConfig{ + EnforcePurpose: true, + EnforceVendors: false, + }, + wantResult: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // convert consent string to TCF2 object + parsedConsent, err := vendorconsent.ParseString(P1P2P3PurposeConsent) + if err != nil { + t.Fatalf("Failed to parse consent %s\n", P1P2P3PurposeConsent) + } + consentMeta, ok := parsedConsent.(tcf2.ConsentMetadata) + if !ok { + t.Fatalf("Failed to convert consent %s\n", P1P2P3PurposeConsent) + } + + vendorInfo := VendorInfo{ + vendorID: 32, + vendor: nil, + } + + enforcer := FullEnforcement{cfg: tt.config} + enforcer.cfg.PurposeID = consentconstants.Purpose(3) + + result := enforcer.LegalBasis(vendorInfo, openrtb_ext.BidderAppnexus, consentMeta, Overrides{}) + assert.Equal(t, tt.wantResult, result) + }) + } +} + func getVendorList(t *testing.T) vendorlist.VendorList { GVL := makeVendorList() diff --git a/gdpr/impl.go b/gdpr/impl.go index 4869a84d977..cc88a1fd3c6 100644 --- a/gdpr/impl.go +++ b/gdpr/impl.go @@ -2,12 +2,9 @@ package gdpr import ( "context" - "errors" - "fmt" "github.com/prebid/go-gdpr/api" "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/go-gdpr/vendorconsent" tcf2 "github.com/prebid/go-gdpr/vendorconsent/tcf2" "github.com/prebid/prebid-server/openrtb_ext" ) @@ -63,53 +60,27 @@ func (p *permissionsImpl) AuctionActivitiesAllowed(ctx context.Context, bidderCo if _, ok := p.nonStandardPublishers[p.publisherID]; ok { return AllowAll, nil } - if p.gdprSignal != SignalYes { return AllowAll, nil } - if p.consent == "" { return p.defaultPermissions(), nil } - - // note the bidder here is guaranteed to be enabled - vendorID, vendorFound := p.resolveVendorID(bidderCoreName, bidder) - basicEnforcementVendors := p.cfg.BasicEnforcementVendors() - _, weakVendorEnforcement := basicEnforcementVendors[string(bidder)] - - if !vendorFound && !weakVendorEnforcement { - return DenyAll, nil - } - - parsedConsent, vendor, err := p.parseVendor(ctx, vendorID, p.consent) + pc, err := parseConsent(p.consent) if err != nil { return p.defaultPermissions(), err } - - // vendor will be nil if not a valid TCF2 consent string - if vendor == nil { - if weakVendorEnforcement && parsedConsent.Version() == 2 { - vendor = vendorTrue{} - } else { - return p.defaultPermissions(), nil - } - } - - if !p.cfg.IsEnabled() { - return AllowBidRequestOnly, nil - } - - consentMeta, ok := parsedConsent.(tcf2.ConsentMetadata) - if !ok { - err = fmt.Errorf("Unable to access TCF2 parsed consent") + vendorID, _ := p.resolveVendorID(bidderCoreName, bidder) + vendor, err := p.getVendor(ctx, vendorID, *pc) + if err != nil { return p.defaultPermissions(), err } - vendorInfo := VendorInfo{vendorID: vendorID, vendor: vendor} + permissions = AuctionPermissions{} - permissions.AllowBidRequest = p.allowBidRequest(bidderCoreName, consentMeta, vendorInfo) - permissions.PassGeo = p.allowGeo(bidderCoreName, consentMeta, vendor) - permissions.PassID = p.allowID(bidderCoreName, consentMeta, vendorInfo) + permissions.AllowBidRequest = p.allowBidRequest(bidderCoreName, pc.consentMeta, vendorInfo) + permissions.PassGeo = p.allowGeo(bidderCoreName, pc.consentMeta, vendor) + permissions.PassID = p.allowID(bidderCoreName, pc.consentMeta, vendorInfo) return permissions, nil } @@ -148,34 +119,28 @@ func (p *permissionsImpl) allowSync(ctx context.Context, vendorID uint16, bidder if p.consent == "" { return false, nil } - - parsedConsent, vendor, err := p.parseVendor(ctx, vendorID, p.consent) + pc, err := parseConsent(p.consent) if err != nil { return false, err } - - if vendor == nil { + vendor, err := p.getVendor(ctx, vendorID, *pc) + if err != nil { return false, nil } + vendorInfo := VendorInfo{vendorID: vendorID, vendor: vendor} if !p.cfg.PurposeEnforced(consentconstants.Purpose(1)) { return true, nil } - consentMeta, ok := parsedConsent.(tcf2.ConsentMetadata) - if !ok { - err := errors.New("Unable to access TCF2 parsed consent") - return false, err - } - if p.cfg.PurposeOneTreatmentEnabled() && consentMeta.PurposeOneTreatment() { + if p.cfg.PurposeOneTreatmentEnabled() && pc.consentMeta.PurposeOneTreatment() { return p.cfg.PurposeOneTreatmentAccessAllowed(), nil } purpose := consentconstants.Purpose(1) enforcer := p.purposeEnforcerBuilder(purpose, bidder) - vendorInfo := VendorInfo{vendorID: vendorID, vendor: vendor} - if enforcer.LegalBasis(vendorInfo, bidder, consentMeta, Overrides{blockVendorExceptions: !vendorException}) { + if enforcer.LegalBasis(vendorInfo, bidder, pc.consentMeta, Overrides{blockVendorExceptions: !vendorException}) { return true, nil } return false, nil @@ -205,7 +170,7 @@ func (p *permissionsImpl) allowGeo(bidder openrtb_ext.BidderName, consentMeta tc basicEnforcementVendors := p.cfg.BasicEnforcementVendors() _, weakVendorEnforcement := basicEnforcementVendors[string(bidder)] - return consentMeta.SpecialFeatureOptIn(1) && (vendor.SpecialFeature(1) || weakVendorEnforcement) + return consentMeta.SpecialFeatureOptIn(1) && ((vendor != nil && vendor.SpecialFeature(1)) || weakVendorEnforcement) } // allowID computes the pass user ID activity legal basis for a given bidder using the enforcement algorithms @@ -229,53 +194,13 @@ func (p *permissionsImpl) allowID(bidder openrtb_ext.BidderName, consentMeta tcf return false } -// parseVendor parses the consent string and fetches the specified vendor's information from the GVL -func (p *permissionsImpl) parseVendor(ctx context.Context, vendorID uint16, consent string) (parsedConsent api.VendorConsents, vendor api.Vendor, err error) { - parsedConsent, err = vendorconsent.ParseString(consent) +// getVendor retrieves the GVL vendor information for a particular bidder +func (p *permissionsImpl) getVendor(ctx context.Context, vendorID uint16, pc parsedConsent) (api.Vendor, error) { + vendorList, err := p.fetchVendorList(ctx, pc.specVersion, pc.listVersion) if err != nil { - err = &ErrorMalformedConsent{ - Consent: consent, - Cause: err, - } - return - } - - version := parsedConsent.Version() - if version != 2 { - return - } - - policyVersion := parsedConsent.TCFPolicyVersion() - specVersion, err := getSpecVersion(policyVersion) - if err != nil { - err = &ErrorMalformedConsent{ - Consent: consent, - Cause: err, - } - return - } - - vendorList, err := p.fetchVendorList(ctx, uint16(specVersion), parsedConsent.VendorListVersion()) - if err != nil { - return - } - - vendor = vendorList.Vendor(vendorID) - return -} - -// getSpecVersion looks at the TCF policy version and determines the corresponding GVL specification -// version that should be used to calculate legal basis -func getSpecVersion(policyVersion uint8) (uint16, error) { - var specVersion uint16 = 3 - - if policyVersion > 4 { - return 0, fmt.Errorf("invalid TCF policy version %d", policyVersion) + return nil, err } - if policyVersion < 4 { - specVersion = 2 - } - return specVersion, nil + return vendorList.Vendor(vendorID), nil } // AllowHostCookies represents a GDPR permissions policy with host cookie syncing always allowed @@ -300,25 +225,3 @@ func (a AlwaysAllow) BidderSyncAllowed(ctx context.Context, bidder openrtb_ext.B func (a AlwaysAllow) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions AuctionPermissions, err error) { return AllowAll, nil } - -// vendorTrue claims everything. -type vendorTrue struct{} - -func (v vendorTrue) Purpose(purposeID consentconstants.Purpose) bool { - return true -} -func (v vendorTrue) PurposeStrict(purposeID consentconstants.Purpose) bool { - return true -} -func (v vendorTrue) LegitimateInterest(purposeID consentconstants.Purpose) bool { - return true -} -func (v vendorTrue) LegitimateInterestStrict(purposeID consentconstants.Purpose) bool { - return true -} -func (v vendorTrue) SpecialFeature(featureID consentconstants.SpecialFeature) (hasSpecialFeature bool) { - return true -} -func (v vendorTrue) SpecialPurpose(purposeID consentconstants.Purpose) (hasSpecialPurpose bool) { - return true -} diff --git a/gdpr/impl_test.go b/gdpr/impl_test.go index 4a65dbafec7..835a580f6e2 100644 --- a/gdpr/impl_test.go +++ b/gdpr/impl_test.go @@ -342,6 +342,109 @@ func TestAllowActivities(t *testing.T) { } } +func TestAllowActivitiesBidderWithoutGVLID(t *testing.T) { + bidderWithoutGVLID := openrtb_ext.BidderPangle + purpose2Consent := "CPuDXznPuDXznMOAAAENCZCAAEAAAAAAAAAAAAAAAAAA" + noPurposeConsent := "CPuDXznPuDXznMOAAAENCZCAAAAAAAAAAAAAAAAAAAAA" + + tests := []struct { + name string + enforceAlgoID config.TCF2EnforcementAlgo + vendorExceptions map[openrtb_ext.BidderName]struct{} + basicEnforcementVendors map[string]struct{} + consent string + allowBidRequest bool + passID bool + }{ + { + name: "full_enforcement_no_exceptions_user_consents_to_purpose_2", + enforceAlgoID: config.TCF2FullEnforcement, + consent: purpose2Consent, + }, + { + name: "full_enforcement_vendor_exception_user_consents_to_purpose_2", + enforceAlgoID: config.TCF2FullEnforcement, + vendorExceptions: map[openrtb_ext.BidderName]struct{}{bidderWithoutGVLID: {}}, + consent: purpose2Consent, + allowBidRequest: true, + passID: true, + }, + { + name: "basic_enforcement_no_exceptions_user_consents_to_purpose_2", + consent: purpose2Consent, + }, + { + name: "basic_enforcement_vendor_exception_user_consents_to_purpose_2", + vendorExceptions: map[openrtb_ext.BidderName]struct{}{bidderWithoutGVLID: {}}, + consent: purpose2Consent, + allowBidRequest: true, + passID: true, + }, + { + name: "full_enforcement_soft_vendor_exception_user_consents_to_purpose_2", // allow bid request and pass ID + enforceAlgoID: config.TCF2FullEnforcement, + basicEnforcementVendors: map[string]struct{}{string(bidderWithoutGVLID): {}}, + consent: purpose2Consent, + allowBidRequest: true, + passID: true, + }, + { + name: "basic_enforcement_soft_vendor_exception_user_consents_to_purpose_2", // allow bid request and pass ID + enforceAlgoID: config.TCF2BasicEnforcement, + basicEnforcementVendors: map[string]struct{}{string(bidderWithoutGVLID): {}}, + consent: purpose2Consent, + allowBidRequest: true, + passID: true, + }, + { + name: "full_enforcement_soft_vendor_exception_user_consents_to_purpose_4", + enforceAlgoID: config.TCF2FullEnforcement, + basicEnforcementVendors: map[string]struct{}{string(bidderWithoutGVLID): {}}, + consent: noPurposeConsent, + allowBidRequest: false, + passID: false, + }, + { + name: "basic_enforcement_soft_vendor_exception_user_consents_to_purpose_4", + enforceAlgoID: config.TCF2BasicEnforcement, + basicEnforcementVendors: map[string]struct{}{string(bidderWithoutGVLID): {}}, + consent: noPurposeConsent, + allowBidRequest: false, + passID: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tcf2AggConfig := allPurposesEnabledTCF2Config() + tcf2AggConfig.AccountConfig.BasicEnforcementVendorsMap = tt.basicEnforcementVendors + tcf2AggConfig.HostConfig.Purpose2.VendorExceptionMap = tt.vendorExceptions + tcf2AggConfig.HostConfig.Purpose2.EnforceAlgoID = tt.enforceAlgoID + tcf2AggConfig.HostConfig.PurposeConfigs[consentconstants.Purpose(2)] = &tcf2AggConfig.HostConfig.Purpose2 + + perms := permissionsImpl{ + cfg: &tcf2AggConfig, + consent: tt.consent, + gdprSignal: SignalYes, + hostVendorID: 2, + nonStandardPublishers: map[string]struct{}{}, + vendorIDs: map[openrtb_ext.BidderName]uint16{}, + fetchVendorList: listFetcher(map[uint16]map[uint16]vendorlist.VendorList{ + 2: { + 153: parseVendorListDataV2(t, MarshalVendorList(vendorList{GVLSpecificationVersion: 2, VendorListVersion: 153, Vendors: map[string]*vendor{}})), + }, + }), + purposeEnforcerBuilder: NewPurposeEnforcerBuilder(&tcf2AggConfig), + } + + permissions, err := perms.AuctionActivitiesAllowed(context.Background(), bidderWithoutGVLID, bidderWithoutGVLID) + assert.NoError(t, err) + assert.Equal(t, tt.allowBidRequest, permissions.AllowBidRequest) + assert.Equal(t, tt.passID, permissions.PassID) + }) + } +} + func buildVendorList34() vendorList { return vendorList{ VendorListVersion: 2, @@ -1006,28 +1109,6 @@ func TestAllowActivitiesBidRequests(t *testing.T) { } } -func TestTCF1Consent(t *testing.T) { - bidderAllowedByConsent := openrtb_ext.BidderAppnexus - tcf1Consent := "BOS2bx5OS2bx5ABABBAAABoAAAABBwAA" - - perms := permissionsImpl{ - cfg: &tcf2Config{}, - vendorIDs: map[openrtb_ext.BidderName]uint16{ - openrtb_ext.BidderAppnexus: 2, - }, - aliasGVLIDs: map[string]uint16{}, - consent: tcf1Consent, - gdprSignal: SignalYes, - } - - permissions, err := perms.AuctionActivitiesAllowed(context.Background(), bidderAllowedByConsent, bidderAllowedByConsent) - - assert.Nil(t, err, "TCF1 consent - no error returned") - assert.Equal(t, true, permissions.AllowBidRequest, "TCF1 consent - bid request not allowed") - assert.Equal(t, true, permissions.PassGeo, "TCF1 consent - passing geo not allowed") - assert.Equal(t, false, permissions.PassID, "TCF1 consent - passing id not allowed") -} - func TestAllowActivitiesVendorException(t *testing.T) { noPurposeOrVendorConsentAndPubRestrictsP2 := "CPF_61ePF_61eFxAAAENAiCAAAAAAAAAAAAAACEAAAACEAAgAgAA" noPurposeOrVendorConsentAndPubRestrictsNone := "CPF_61ePF_61eFxAAAENAiCAAAAAAAAAAAAAACEAAAAA" @@ -1244,53 +1325,9 @@ func TestDefaultPermissions(t *testing.T) { } } -func TestGetSpecVersion(t *testing.T) { - tests := []struct { - name string - policyVersion uint8 - expectedSpecVersion uint16 - expectedError bool - }{ - { - name: "policy_version_0_gives_spec_version_2", - policyVersion: 0, - expectedSpecVersion: 2, - }, - { - name: "policy_version_3_gives_spec_version_2", - policyVersion: 3, - expectedSpecVersion: 2, - }, - { - name: "policy_version_4_spec_version_3", - policyVersion: 4, - expectedSpecVersion: 3, - }, - { - name: "policy_version_5_error", - policyVersion: 5, - expectedSpecVersion: 0, - expectedError: true, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - specVersion, err := getSpecVersion(tt.policyVersion) - assert.Equal(t, tt.expectedSpecVersion, specVersion) - if tt.expectedError { - assert.Error(t, err) - } else { - assert.Nil(t, err) - } - }) - } -} - func TestVendorListSelection(t *testing.T) { policyVersion3WithVendor2AndPurpose1Consent := "CPGWbY_PGWbY_GYAAAENABDAAIAAAAAAAAAAACEAAAAA" policyVersion4WithVendor2AndPurpose1Consent := "CPGWbY_PGWbY_GYAAAENABEAAIAAAAAAAAAAACEAAAAA" - policyVersion5WithVendor2AndPurpose1Consent := "CPGWbY_PGWbY_GYAAAENABFAAIAAAAAAAAAAACEAAAAA" specVersion2vendorListData := MarshalVendorList(vendorList{ GVLSpecificationVersion: 2, @@ -1359,11 +1396,6 @@ func TestVendorListSelection(t *testing.T) { consent: policyVersion4WithVendor2AndPurpose1Consent, expectedAllowSync: true, }, - { - name: "consent_tcf_policy_version_5_causes_error", - consent: policyVersion5WithVendor2AndPurpose1Consent, - expectedErr: true, - }, } for _, tt := range tests { From 56de4d17c5031e0ad68932bbbb35b0f6a43bbdfa Mon Sep 17 00:00:00 2001 From: Ashish Garg Date: Thu, 20 Jul 2023 17:32:11 +0530 Subject: [PATCH 030/268] introduce aliasOf in bidderInfo struct (#2942) --- config/bidderinfo.go | 28 ++++++++++++++---- config/bidderinfo_test.go | 53 +++++++++++++++++++++++++++++++++++ exchange/adapter_util.go | 4 +++ exchange/adapter_util_test.go | 7 +++++ 4 files changed, 86 insertions(+), 6 deletions(-) diff --git a/config/bidderinfo.go b/config/bidderinfo.go index 6f62488c878..b4d7900196e 100644 --- a/config/bidderinfo.go +++ b/config/bidderinfo.go @@ -23,6 +23,7 @@ type BidderInfos map[string]BidderInfo // BidderInfo specifies all configuration for a bidder except for enabled status, endpoint, and extra information. type BidderInfo struct { + AliasOf string `yaml:"aliasOf" mapstructure:"aliasOf"` Disabled bool `yaml:"disabled" mapstructure:"disabled"` Endpoint string `yaml:"endpoint" mapstructure:"endpoint"` ExtraAdapterInfo string `yaml:"extra_info" mapstructure:"extra_info"` @@ -266,20 +267,35 @@ func (infos BidderInfos) validate(errs []error) []error { if bidder.IsEnabled() { errs = validateAdapterEndpoint(bidder.Endpoint, bidderName, errs) - validateInfoErr := validateInfo(bidder, bidderName) - if validateInfoErr != nil { - errs = append(errs, validateInfoErr) + if err := validateInfo(bidder, bidderName); err != nil { + errs = append(errs, err) } - validateSyncerErr := validateSyncer(bidder) - if validateSyncerErr != nil { - errs = append(errs, validateSyncerErr) + if err := validateSyncer(bidder); err != nil { + errs = append(errs, err) + } + + if err := validateAliases(bidder, infos, bidderName); err != nil { + errs = append(errs, err) } } } return errs } +func validateAliases(bidder BidderInfo, infos BidderInfos, bidderName string) error { + if len(bidder.AliasOf) > 0 { + if parentBidder, ok := infos[bidder.AliasOf]; ok { + if len(parentBidder.AliasOf) > 0 { + return fmt.Errorf("bidder: %s cannot be an alias of an alias: %s", bidder.AliasOf, bidderName) + } + } else { + return fmt.Errorf("bidder: %s not found for an alias: %s", bidder.AliasOf, bidderName) + } + } + return nil +} + var testEndpointTemplateParams = macros.EndpointTemplateParams{ Host: "anyHost", PublisherID: "anyPublisherID", diff --git a/config/bidderinfo_test.go b/config/bidderinfo_test.go index 6005178c605..f83d942c1a1 100644 --- a/config/bidderinfo_test.go +++ b/config/bidderinfo_test.go @@ -244,6 +244,22 @@ func TestBidderInfoValidationPositive(t *testing.T) { }, }, }, + "bidderC": BidderInfo{ + Endpoint: "http://bidderB.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + Site: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + openrtb_ext.BidTypeNative, + openrtb_ext.BidTypeBanner, + }, + }, + }, + AliasOf: "bidderB", + }, } errs := bidderInfos.validate(make([]error, 0)) assert.Len(t, errs, 0, "All bidder infos should be correct") @@ -467,6 +483,43 @@ func TestBidderInfoValidationNegative(t *testing.T) { errors.New("syncer could not be created, invalid supported endpoint: incorrect"), }, }, + { + "Invalid aliases", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + Site: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, + }, + AliasOf: "bidderB", + }, + "bidderB": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + Site: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, + }, + AliasOf: "bidderC", + }, + }, + []error{ + errors.New("bidder: bidderB cannot be an alias of an alias: bidderA"), + errors.New("bidder: bidderC not found for an alias: bidderB"), + }, + }, { "Two bidders, one with incorrect url", BidderInfos{ diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index ad1866a63c8..9551ab3ea69 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -33,6 +33,10 @@ func buildBidders(infos config.BidderInfos, builders map[openrtb_ext.BidderName] var errs []error for bidder, info := range infos { + if len(info.AliasOf) > 0 { + errs = append(errs, fmt.Errorf("This feature is currently under development")) + continue + } bidderName, bidderNameFound := openrtb_ext.NormalizeBidderName(bidder) if !bidderNameFound { errs = append(errs, fmt.Errorf("%v: unknown bidder", bidder)) diff --git a/exchange/adapter_util_test.go b/exchange/adapter_util_test.go index 2dd0fd04ab7..3b818bdd429 100644 --- a/exchange/adapter_util_test.go +++ b/exchange/adapter_util_test.go @@ -67,6 +67,13 @@ func TestBuildAdapters(t *testing.T) { errors.New("unknown: unknown bidder"), }, }, + { + description: "Alias feature disabled", + bidderInfos: map[string]config.BidderInfo{"appNexus": {AliasOf: "rubicon"}}, + expectedErrors: []error{ + errors.New("This feature is currently under development"), + }, + }, } cfg := &config.Configuration{} From b0a9b2fb87a8d05e1272194195151e3931cc87cc Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Thu, 20 Jul 2023 19:03:01 +0530 Subject: [PATCH 031/268] fix errors reported by go vet (#2954) --- adapters/bidder_test.go | 4 ++-- bidadjustment/apply_test.go | 4 ++-- endpoints/openrtb2/amp_auction_test.go | 6 +++--- endpoints/openrtb2/test_utils.go | 6 +++--- server/server.go | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/adapters/bidder_test.go b/adapters/bidder_test.go index f0b833cec2e..d6373bdeab1 100644 --- a/adapters/bidder_test.go +++ b/adapters/bidder_test.go @@ -52,12 +52,12 @@ type mockConversions struct { mock.Mock } -func (m mockConversions) GetRate(from string, to string) (float64, error) { +func (m *mockConversions) GetRate(from string, to string) (float64, error) { args := m.Called(from, to) return args.Get(0).(float64), args.Error(1) } -func (m mockConversions) GetRates() *map[string]map[string]float64 { +func (m *mockConversions) GetRates() *map[string]map[string]float64 { args := m.Called() return args.Get(0).(*map[string]map[string]float64) } diff --git a/bidadjustment/apply_test.go b/bidadjustment/apply_test.go index 27daa9c73d6..c0eb74ab419 100644 --- a/bidadjustment/apply_test.go +++ b/bidadjustment/apply_test.go @@ -223,12 +223,12 @@ type mockConversions struct { mock.Mock } -func (m mockConversions) GetRate(from string, to string) (float64, error) { +func (m *mockConversions) GetRate(from string, to string) (float64, error) { args := m.Called(from, to) return args.Get(0).(float64), args.Error(1) } -func (m mockConversions) GetRates() *map[string]map[string]float64 { +func (m *mockConversions) GetRates() *map[string]map[string]float64 { args := m.Called() return args.Get(0).(*map[string]map[string]float64) } diff --git a/endpoints/openrtb2/amp_auction_test.go b/endpoints/openrtb2/amp_auction_test.go index 27f84aee42c..d709a7020c7 100644 --- a/endpoints/openrtb2/amp_auction_test.go +++ b/endpoints/openrtb2/amp_auction_test.go @@ -88,7 +88,7 @@ func TestGoodAmpRequests(t *testing.T) { continue } - test.storedRequest = map[string]json.RawMessage{tagID: test.BidRequest} + test.StoredRequest = map[string]json.RawMessage{tagID: test.BidRequest} test.endpointType = AMP_ENDPOINT cfg := &config.Configuration{ @@ -165,7 +165,7 @@ func TestAccountErrors(t *testing.T) { if !assert.NoError(t, json.Unmarshal(fileJsonData, &test), "Failed to unmarshal data from file: %s. Error: %v", tt.filename, err) { continue } - test.storedRequest = map[string]json.RawMessage{tt.storedReqID: test.BidRequest} + test.StoredRequest = map[string]json.RawMessage{tt.storedReqID: test.BidRequest} test.endpointType = AMP_ENDPOINT cfg := &config.Configuration{ @@ -2190,7 +2190,7 @@ func TestValidAmpResponseWhenRequestRejected(t *testing.T) { query := request.URL.Query() tagID := query.Get("tag_id") - test.storedRequest = map[string]json.RawMessage{tagID: test.BidRequest} + test.StoredRequest = map[string]json.RawMessage{tagID: test.BidRequest} test.planBuilder = tc.planBuilder test.endpointType = AMP_ENDPOINT diff --git a/endpoints/openrtb2/test_utils.go b/endpoints/openrtb2/test_utils.go index afe883979ff..a93325eaf29 100644 --- a/endpoints/openrtb2/test_utils.go +++ b/endpoints/openrtb2/test_utils.go @@ -76,7 +76,7 @@ type testCase struct { ExpectedBidResponse json.RawMessage `json:"expectedBidResponse"` // "/openrtb2/amp" endpoint JSON test info - storedRequest map[string]json.RawMessage `json:"mockAmpStoredRequest"` + StoredRequest map[string]json.RawMessage `json:"mockAmpStoredRequest"` StoredResponse map[string]json.RawMessage `json:"mockAmpStoredResponse"` ExpectedAmpResponse json.RawMessage `json:"expectedAmpResponse"` } @@ -1265,8 +1265,8 @@ func buildTestEndpoint(test testCase, cfg *config.Configuration) (httprouter.Han testExchange, mockBidServersArray := buildTestExchange(test.Config, adapterMap, mockBidServersArray, mockCurrencyRatesServer, bidderInfos, cfg, met, mockFetcher) var storedRequestFetcher stored_requests.Fetcher - if len(test.storedRequest) > 0 { - storedRequestFetcher = &mockAmpStoredReqFetcher{test.storedRequest} + if len(test.StoredRequest) > 0 { + storedRequestFetcher = &mockAmpStoredReqFetcher{test.StoredRequest} } else { storedRequestFetcher = &mockStoredReqFetcher{} } diff --git a/server/server.go b/server/server.go index 31764cc40e9..9282f0fcf15 100644 --- a/server/server.go +++ b/server/server.go @@ -20,7 +20,7 @@ import ( // Listen blocks forever, serving PBS requests on the given port. This will block forever, until the process is shut down. func Listen(cfg *config.Configuration, handler http.Handler, adminHandler http.Handler, metrics *metricsconfig.DetailedMetricsEngine) (err error) { - stopSignals := make(chan os.Signal) + stopSignals := make(chan os.Signal, 1) signal.Notify(stopSignals, syscall.SIGTERM, syscall.SIGINT) // Run the servers. Fan any process-stopper signals out to each server for graceful shutdowns. From 9973c158f6aa783fad299f48f7d4c77caabf8a18 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Fri, 21 Jul 2023 11:08:29 +0530 Subject: [PATCH 032/268] record `PBS-auction-response` preparation time (#2841) co-authored by @onkarvhanumante --- endpoints/openrtb2/amp_auction.go | 5 +++++ endpoints/openrtb2/auction.go | 5 +++++ endpoints/openrtb2/video_auction.go | 5 +++++ exchange/exchange.go | 12 +++++++----- exchange/exchange_test.go | 7 ++++++- metrics/prometheus/prometheus.go | 2 +- 6 files changed, 29 insertions(+), 7 deletions(-) diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index 9324b15d9ef..9e06272b483 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -254,6 +254,11 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h } auctionResponse, err := deps.ex.HoldAuction(ctx, auctionRequest, nil) + defer func() { + if !auctionRequest.BidderResponseStartTime.IsZero() { + deps.metricsEngine.RecordOverheadTime(metrics.MakeAuctionResponse, time.Since(auctionRequest.BidderResponseStartTime)) + } + }() var response *openrtb2.BidResponse if auctionResponse != nil { response = auctionResponse.BidResponse diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 9a0d0d07640..087d0a5d49e 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -252,6 +252,11 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http Activities: activities, } auctionResponse, err := deps.ex.HoldAuction(ctx, auctionRequest, nil) + defer func() { + if !auctionRequest.BidderResponseStartTime.IsZero() { + deps.metricsEngine.RecordOverheadTime(metrics.MakeAuctionResponse, time.Since(auctionRequest.BidderResponseStartTime)) + } + }() ao.RequestWrapper = req ao.Account = account var response *openrtb2.BidResponse diff --git a/endpoints/openrtb2/video_auction.go b/endpoints/openrtb2/video_auction.go index 872ea2bdb74..565baf0261b 100644 --- a/endpoints/openrtb2/video_auction.go +++ b/endpoints/openrtb2/video_auction.go @@ -314,6 +314,11 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re } auctionResponse, err := deps.ex.HoldAuction(ctx, auctionRequest, &debugLog) + defer func() { + if !auctionRequest.BidderResponseStartTime.IsZero() { + deps.metricsEngine.RecordOverheadTime(metrics.MakeAuctionResponse, time.Since(auctionRequest.BidderResponseStartTime)) + } + }() vo.RequestWrapper = bidReqWrapper var response *openrtb2.BidResponse if auctionResponse != nil { diff --git a/exchange/exchange.go b/exchange/exchange.go index e1a9868db7a..390db973578 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -205,11 +205,12 @@ type AuctionRequest struct { // map of imp id to stored response StoredAuctionResponses stored_responses.ImpsWithBidResponses // map of imp id to bidder to stored response - StoredBidResponses stored_responses.ImpBidderStoredResp - BidderImpReplaceImpID stored_responses.BidderImpReplaceImpID - PubID string - HookExecutor hookexecution.StageExecutor - QueryParams url.Values + StoredBidResponses stored_responses.ImpBidderStoredResp + BidderImpReplaceImpID stored_responses.BidderImpReplaceImpID + PubID string + HookExecutor hookexecution.StageExecutor + QueryParams url.Values + BidderResponseStartTime time.Time } // BidderRequest holds the bidder specific request and all other @@ -370,6 +371,7 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog adapterBids, adapterExtra, extraRespInfo = e.getAllBids(auctionCtx, bidderRequests, bidAdjustmentFactors, conversions, accountDebugAllow, r.GlobalPrivacyControlHeader, debugLog.DebugOverride, alternateBidderCodes, requestExtLegacy.Prebid.Experiment, r.HookExecutor, r.StartTime, bidAdjustmentRules) fledge = extraRespInfo.fledge anyBidsReturned = extraRespInfo.bidsFound + r.BidderResponseStartTime = extraRespInfo.bidderResponseStartTime } var ( diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go index 2a35ef57777..8e7ba80b953 100644 --- a/exchange/exchange_test.go +++ b/exchange/exchange_test.go @@ -379,7 +379,7 @@ func TestDebugBehaviour(t *testing.T) { // Assert no HoldAuction error assert.NoErrorf(t, err, "%s. ex.HoldAuction returned an error: %v \n", test.desc, err) assert.NotNilf(t, outBidResponse.Ext, "%s. outBidResponse.Ext should not be nil \n", test.desc) - + assert.False(t, auctionRequest.BidderResponseStartTime.IsZero()) actualExt := &openrtb_ext.ExtBidResponse{} err = json.Unmarshal(outBidResponse.Ext, actualExt) assert.NoErrorf(t, err, "%s. \"ext\" JSON field could not be unmarshaled. err: \"%v\" \n outBidResponse.Ext: \"%s\" \n", test.desc, err, outBidResponse.Ext) @@ -540,6 +540,7 @@ func TestTwoBiddersDebugDisabledAndEnabled(t *testing.T) { // Assert no HoldAuction err assert.NoErrorf(t, err, "ex.HoldAuction returned an err") assert.NotNilf(t, outBidResponse.Ext, "outBidResponse.Ext should not be nil") + assert.False(t, auctionRequest.BidderResponseStartTime.IsZero()) actualExt := &openrtb_ext.ExtBidResponse{} err = json.Unmarshal(outBidResponse.Ext, actualExt) @@ -715,6 +716,7 @@ func TestOverrideWithCustomCurrency(t *testing.T) { // Assertions assert.NoErrorf(t, err, "%s. HoldAuction error: %v \n", test.desc, err) + assert.False(t, auctionRequest.BidderResponseStartTime.IsZero()) if test.expected.numBids > 0 { // Assert out currency @@ -1362,6 +1364,7 @@ func TestReturnCreativeEndToEnd(t *testing.T) { continue } else { assert.NoErrorf(t, err, "%s: %s. HoldAuction error: %v \n", testGroup.groupDesc, test.desc, err) + assert.False(t, auctionRequest.BidderResponseStartTime.IsZero()) } // Assert returned bid @@ -5143,6 +5146,7 @@ func TestOverrideConfigAlternateBidderCodesWithRequestValues(t *testing.T) { // Assertions assert.NoErrorf(t, err, "%s. HoldAuction error: %v \n", test.desc, err) assert.NotNil(t, outBidResponse) + assert.False(t, auctionRequest.BidderResponseStartTime.IsZero()) // So 2 seatBids are expected as, // the default "" and "pubmatic" bids will be in one seat and the extra-bids "groupm"/"appnexus"/"ix" in another seat. @@ -5569,6 +5573,7 @@ func TestModulesCanBeExecutedForMultipleBiddersSimultaneously(t *testing.T) { _, err := e.HoldAuction(context.Background(), auctionRequest, &DebugLog{}) // Assert no HoldAuction err assert.NoErrorf(t, err, "ex.HoldAuction returned an err") + assert.False(t, auctionRequest.BidderResponseStartTime.IsZero()) // check stage outcomes assert.Equal(t, len(exec.GetOutcomes()), len(e.adapterMap), "stage outcomes append operation failed") diff --git a/metrics/prometheus/prometheus.go b/metrics/prometheus/prometheus.go index eb387789e1d..f9d0c4d9f86 100644 --- a/metrics/prometheus/prometheus.go +++ b/metrics/prometheus/prometheus.go @@ -178,7 +178,7 @@ func NewMetrics(cfg config.PrometheusMetrics, disabledMetrics config.DisabledMet cacheWriteTimeBuckets := []float64{0.001, 0.002, 0.005, 0.01, 0.025, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 1} priceBuckets := []float64{250, 500, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000} queuedRequestTimeBuckets := []float64{0, 1, 5, 30, 60, 120, 180, 240, 300} - overheadTimeBuckets := []float64{0.00005, 0.0001, 0.0005, 0.001, 0.002, 0.005, 0.01, 0.05} + overheadTimeBuckets := []float64{0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1} metrics := Metrics{} reg := prometheus.NewRegistry() From 57236741c7464cb500aaa9b05508460982c53382 Mon Sep 17 00:00:00 2001 From: bretg Date: Fri, 21 Jul 2023 15:29:05 -0400 Subject: [PATCH 033/268] fixing inmobi contact email (#2958) --- static/bidder-info/inmobi.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/bidder-info/inmobi.yaml b/static/bidder-info/inmobi.yaml index ad3562de64b..72bdd21d974 100644 --- a/static/bidder-info/inmobi.yaml +++ b/static/bidder-info/inmobi.yaml @@ -1,6 +1,6 @@ endpoint: "https://api.w.inmobi.com/showad/openrtb/bidder/prebid" maintainer: - email: "technology-irv@inmobi.com" + email: "prebid-support@inmobi.com" gvlVendorID: 333 capabilities: app: From 238a4ec6b3e670e437c110d5b90f98f79ec5ded4 Mon Sep 17 00:00:00 2001 From: Arne Schulz Date: Mon, 24 Jul 2023 10:38:10 +0200 Subject: [PATCH 034/268] ORBIDDER: enable capability site with media type banner and native (#2924) --- adapters/orbidder/orbidder.go | 38 +++- .../multibid-multi-format-with-mtype.json | 185 ++++++++++++++++++ .../exemplary/simple-app-banner.json | 6 +- .../exemplary/simple-web-banner.json | 114 +++++++++++ .../exemplary/simple-web-native.json | 102 ++++++++++ .../supplemental/valid-and-invalid-imps.json | 6 +- static/bidder-info/orbidder.yaml | 4 + 7 files changed, 448 insertions(+), 7 deletions(-) create mode 100644 adapters/orbidder/orbiddertest/exemplary/multibid-multi-format-with-mtype.json create mode 100644 adapters/orbidder/orbiddertest/exemplary/simple-web-banner.json create mode 100644 adapters/orbidder/orbiddertest/exemplary/simple-web-native.json diff --git a/adapters/orbidder/orbidder.go b/adapters/orbidder/orbidder.go index 43c3574b4a7..b4f1a16c114 100644 --- a/adapters/orbidder/orbidder.go +++ b/adapters/orbidder/orbidder.go @@ -125,19 +125,51 @@ func (rcv OrbidderAdapter) MakeBids(_ *openrtb2.BidRequest, _ *adapters.RequestD return nil, []error{err} } + var bidErrs []error bidResponse := adapters.NewBidderResponseWithBidsCapacity(5) for _, seatBid := range bidResp.SeatBid { - for _, bid := range seatBid.Bid { + for i := range seatBid.Bid { + // later we have to add the bid as a pointer, + // because of this we need a variable that only exists at this loop iteration. + // otherwise there will be issues with multibid and pointer behavior. + bid := seatBid.Bid[i] + bidType, err := getBidType(bid) + if err != nil { + // could not determinate media type, append an error and continue with the next bid. + bidErrs = append(bidErrs, err) + continue + } + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ Bid: &bid, - BidType: openrtb_ext.BidTypeBanner, + BidType: bidType, }) } } if bidResp.Cur != "" { bidResponse.Currency = bidResp.Cur } - return bidResponse, nil + + return bidResponse, bidErrs +} + +func getBidType(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + + // determinate media type by bid response field mtype + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupAudio: + return openrtb_ext.BidTypeAudio, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + } + + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("Could not define media type for impression: %s", bid.ImpID), + } } // Builder builds a new instance of the Orbidder adapter for the given bidder with the given config. diff --git a/adapters/orbidder/orbiddertest/exemplary/multibid-multi-format-with-mtype.json b/adapters/orbidder/orbiddertest/exemplary/multibid-multi-format-with-mtype.json new file mode 100644 index 00000000000..011acb2c7e2 --- /dev/null +++ b/adapters/orbidder/orbiddertest/exemplary/multibid-multi-format-with-mtype.json @@ -0,0 +1,185 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://test.orbidder.de" + }, + "user": { + "buyeruid": "XX672XXX-5XXd-4XX2-8XX6-6XXXXc9cXXXX.v1" + }, + "imp": [ + { + "id": "multi-format-test-imp-id-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "native": { + "ver":"1.2", + "request":"\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140},{\"id\":1,\"img\":{\"h\":250,\"hmin\":0,\"type\":3,\"w\":300,\"wmin\":0}}]" + }, + "ext": { + "bidder": { + "accountId": "orbidder-test", + "placementId": "web-test-placement-1", + "bidfloor": 0.1 + } + } + },{ + "id": "multi-format-test-imp-id-2", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "native": { + "ver":"1.2", + "request":"\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140},{\"id\":1,\"img\":{\"h\":250,\"hmin\":0,\"type\":3,\"w\":300,\"wmin\":0}}]" + }, + "ext": { + "bidder": { + "accountId": "orbidder-test", + "placementId": "web-test-placement-2", + "bidfloor": 0.1 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://orbidder-test", + "body": { + "id": "test-request-id", + "site": { + "page": "https://test.orbidder.de" + }, + "user": { + "buyeruid": "XX672XXX-5XXd-4XX2-8XX6-6XXXXc9cXXXX.v1" + }, + "imp": [ + { + "id": "multi-format-test-imp-id-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "native": { + "ver":"1.2", + "request":"\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140},{\"id\":1,\"img\":{\"h\":250,\"hmin\":0,\"type\":3,\"w\":300,\"wmin\":0}}]" + }, + "bidfloorcur": "EUR", + "ext": { + "bidder": { + "accountId": "orbidder-test", + "placementId": "web-test-placement-1", + "bidfloor": 0.1 + } + } + },{ + "id": "multi-format-test-imp-id-2", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "native": { + "ver":"1.2", + "request":"\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140},{\"id\":1,\"img\":{\"h\":250,\"hmin\":0,\"type\":3,\"w\":300,\"wmin\":0}}]" + }, + "bidfloorcur": "EUR", + "ext": { + "bidder": { + "accountId": "orbidder-test", + "placementId": "web-test-placement-2", + "bidfloor": 0.1 + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "seat-id", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e900", + "impid": "multi-format-test-imp-id-1", + "adid": "11110126", + "price": 0.600000, + "adm": "banner-some-test-ad", + "crid": "banner-test-crid", + "h": 250, + "w": 300, + "mtype": 1 + },{ + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "multi-format-test-imp-id-2", + "adid": "11110136", + "price": 0.500000, + "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"text\":\"Orbidder rocks\"}},{\"id\":1,\"required\":1,\"img\":{\"url\":\"https://prd.orbidder.de/common/logo.png\"}}],\"link\":{\"url\":\"https://www.otto.de/\",\"clicktrackers\":[\"https://prd.orbidder.de/click\"]},\"imptrackers\":[\"https://prd.orbidder.de/imp\"]}", + "crid": "native-test-crid", + "mtype": 4 + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "EUR" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e900", + "impid": "multi-format-test-imp-id-1", + "adid": "11110126", + "price": 0.6, + "adm": "banner-some-test-ad", + "crid": "banner-test-crid", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + },{ + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "multi-format-test-imp-id-2", + "adid": "11110136", + "price": 0.5, + "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"text\":\"Orbidder rocks\"}},{\"id\":1,\"required\":1,\"img\":{\"url\":\"https://prd.orbidder.de/common/logo.png\"}}],\"link\":{\"url\":\"https://www.otto.de/\",\"clicktrackers\":[\"https://prd.orbidder.de/click\"]},\"imptrackers\":[\"https://prd.orbidder.de/imp\"]}", + "crid": "native-test-crid", + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/orbidder/orbiddertest/exemplary/simple-app-banner.json b/adapters/orbidder/orbiddertest/exemplary/simple-app-banner.json index 2315a52c130..80b3c794c5a 100644 --- a/adapters/orbidder/orbiddertest/exemplary/simple-app-banner.json +++ b/adapters/orbidder/orbiddertest/exemplary/simple-app-banner.json @@ -79,7 +79,8 @@ "adm": "some-test-ad", "crid": "test-crid", "h": 250, - "w": 300 + "w": 300, + "mtype": 1 } ] } @@ -102,7 +103,8 @@ "adm": "some-test-ad", "crid": "test-crid", "w": 300, - "h": 250 + "h": 250, + "mtype": 1 }, "type": "banner" } diff --git a/adapters/orbidder/orbiddertest/exemplary/simple-web-banner.json b/adapters/orbidder/orbiddertest/exemplary/simple-web-banner.json new file mode 100644 index 00000000000..9e1181a590b --- /dev/null +++ b/adapters/orbidder/orbiddertest/exemplary/simple-web-banner.json @@ -0,0 +1,114 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://test.orbidder.de" + }, + "user": { + "buyeruid": "XX672XXX-5XXd-4XX2-8XX6-6XXXXc9cXXXX.v1" + }, + "imp": [ + { + "id": "web-test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "accountId": "orbidder-test", + "placementId": "web-test-placement", + "bidfloor": 0.1 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://orbidder-test", + "body": { + "id": "test-request-id", + "site": { + "page": "https://test.orbidder.de" + }, + "user": { + "buyeruid": "XX672XXX-5XXd-4XX2-8XX6-6XXXXc9cXXXX.v1" + }, + "imp": [ + { + "id": "web-test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "bidfloorcur": "EUR", + "ext": { + "bidder": { + "accountId": "orbidder-test", + "placementId": "web-test-placement", + "bidfloor": 0.1 + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "web-test-request-id", + "seatbid": [ + { + "seat": "web-seat-id", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "web-test-imp-id", + "adid": "11110126", + "price": 0.600000, + "adm": "web-some-test-ad", + "crid": "web-test-crid", + "h": 250, + "w": 300, + "mtype": 1 + } + ] + } + ], + "cur": "EUR" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "web-test-imp-id", + "adid": "11110126", + "price": 0.6, + "adm": "web-some-test-ad", + "crid": "web-test-crid", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/orbidder/orbiddertest/exemplary/simple-web-native.json b/adapters/orbidder/orbiddertest/exemplary/simple-web-native.json new file mode 100644 index 00000000000..f4b8ec2c7db --- /dev/null +++ b/adapters/orbidder/orbiddertest/exemplary/simple-web-native.json @@ -0,0 +1,102 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "test.orbidder.de" + }, + "user": { + "buyeruid": "test-user" + }, + "imp": [ + { + "id": "test-imp-id", + "native": { + "ver":"1.2", + "request":"\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140},{\"id\":1,\"img\":{\"h\":250,\"hmin\":0,\"type\":3,\"w\":300,\"wmin\":0}}]" + }, + "ext": { + "bidder": { + "accountId": "orbidder-test", + "placementId": "test-placement", + "bidfloor": 0.1 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://orbidder-test", + "body": { + "id": "test-request-id", + "site": { + "page": "test.orbidder.de" + }, + "user": { + "buyeruid": "test-user" + }, + "imp": [ + { + "id": "test-imp-id", + "native": { + "ver":"1.2", + "request":"\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140},{\"id\":1,\"img\":{\"h\":250,\"hmin\":0,\"type\":3,\"w\":300,\"wmin\":0}}]" + }, + "bidfloorcur": "EUR", + "ext": { + "bidder": { + "accountId": "orbidder-test", + "placementId": "test-placement", + "bidfloor": 0.1 + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "seat-id", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "adid": "11110126", + "price": 0.500000, + "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"text\":\"Orbidder rocks\"}},{\"id\":1,\"required\":1,\"img\":{\"url\":\"https://prd.orbidder.de/common/logo.png\"}}],\"link\":{\"url\":\"https://www.otto.de/\",\"clicktrackers\":[\"https://prd.orbidder.de/click\"]},\"imptrackers\":[\"https://prd.orbidder.de/imp\"]}", + "crid": "test-crid", + "mtype": 4 + } + ] + } + ], + "cur": "EUR" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "adid": "11110126", + "price": 0.5, + "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"text\":\"Orbidder rocks\"}},{\"id\":1,\"required\":1,\"img\":{\"url\":\"https://prd.orbidder.de/common/logo.png\"}}],\"link\":{\"url\":\"https://www.otto.de/\",\"clicktrackers\":[\"https://prd.orbidder.de/click\"]},\"imptrackers\":[\"https://prd.orbidder.de/imp\"]}", + "crid": "test-crid", + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/orbidder/orbiddertest/supplemental/valid-and-invalid-imps.json b/adapters/orbidder/orbiddertest/supplemental/valid-and-invalid-imps.json index 1ea133ab1d3..5b4a523f261 100644 --- a/adapters/orbidder/orbiddertest/supplemental/valid-and-invalid-imps.json +++ b/adapters/orbidder/orbiddertest/supplemental/valid-and-invalid-imps.json @@ -85,7 +85,8 @@ "adm": "some-test-ad", "crid": "test-crid", "h": 250, - "w": 300 + "w": 300, + "mtype": 1 } ] } @@ -108,7 +109,8 @@ "adm": "some-test-ad", "crid": "test-crid", "w": 300, - "h": 250 + "h": 250, + "mtype": 1 }, "type": "banner" } diff --git a/static/bidder-info/orbidder.yaml b/static/bidder-info/orbidder.yaml index b7891af3195..705d35a5a20 100644 --- a/static/bidder-info/orbidder.yaml +++ b/static/bidder-info/orbidder.yaml @@ -6,3 +6,7 @@ capabilities: app: mediaTypes: - banner + site: + mediaTypes: + - banner + - native From d27b1398c40b42d98b5199e4cee0583b08e12c55 Mon Sep 17 00:00:00 2001 From: Mikael Lundin Date: Mon, 24 Jul 2023 14:17:33 +0200 Subject: [PATCH 035/268] Adnuntius: Max deals (#2901) --- adapters/adnuntius/adnuntius.go | 138 ++++++++------ .../supplemental/height-error.json | 2 +- .../supplemental/max-deals-test.json | 168 ++++++++++++++++++ .../supplemental/width-error.json | 2 +- openrtb_ext/imp_adnuntius.go | 3 +- 5 files changed, 258 insertions(+), 55 deletions(-) create mode 100644 adapters/adnuntius/adnuntiustest/supplemental/max-deals-test.json diff --git a/adapters/adnuntius/adnuntius.go b/adapters/adnuntius/adnuntius.go index 21830deb9c3..3f91d7403f0 100644 --- a/adapters/adnuntius/adnuntius.go +++ b/adapters/adnuntius/adnuntius.go @@ -27,31 +27,35 @@ type adnAdunit struct { AuId string `json:"auId"` TargetId string `json:"targetId"` Dimensions [][]int64 `json:"dimensions,omitempty"` + MaxDeals int `json:"maxDeals,omitempty"` } type extDeviceAdnuntius struct { NoCookies bool `json:"noCookies,omitempty"` } +type Ad struct { + Bid struct { + Amount float64 + Currency string + } + DealID string `json:"dealId,omitempty"` + AdId string + CreativeWidth string + CreativeHeight string + CreativeId string + LineItemId string + Html string + DestinationUrls map[string]string +} + type AdUnit struct { AuId string TargetId string Html string ResponseId string - Ads []struct { - Bid struct { - Amount float64 - Currency string - } - DealID string `json:"dealId,omitempty"` - AdId string - CreativeWidth string - CreativeHeight string - CreativeId string - LineItemId string - Html string - DestinationUrls map[string]string - } + Ads []Ad + Deals []Ad `json:"deals,omitempty"` } type AdnResponse struct { @@ -213,13 +217,17 @@ func (a *adapter) generateRequests(ortbRequest openrtb2.BidRequest) ([]*adapters network = adnuntiusExt.Network } + adUnit := adnAdunit{ + AuId: adnuntiusExt.Auid, + TargetId: fmt.Sprintf("%s-%s", adnuntiusExt.Auid, imp.ID), + Dimensions: getImpSizes(imp), + } + if adnuntiusExt.MaxDeals > 0 { + adUnit.MaxDeals = adnuntiusExt.MaxDeals + } networkAdunitMap[network] = append( networkAdunitMap[network], - adnAdunit{ - AuId: adnuntiusExt.Auid, - TargetId: fmt.Sprintf("%s-%s", adnuntiusExt.Auid, imp.ID), - Dimensions: getImpSizes(imp), - }) + adUnit) } endpoint, err := makeEndpointUrl(ortbRequest, a, noCookies) @@ -320,6 +328,46 @@ func getGDPR(request *openrtb2.BidRequest) (string, string, error) { return gdpr, consent, nil } +func generateAdResponse(ad Ad, impId string, html string, request *openrtb2.BidRequest) (*openrtb2.Bid, []error) { + + creativeWidth, widthErr := strconv.ParseInt(ad.CreativeWidth, 10, 64) + if widthErr != nil { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Value of width: %s is not a string", ad.CreativeWidth), + }} + } + + creativeHeight, heightErr := strconv.ParseInt(ad.CreativeHeight, 10, 64) + if heightErr != nil { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Value of height: %s is not a string", ad.CreativeHeight), + }} + } + + adDomain := []string{} + for _, url := range ad.DestinationUrls { + domainArray := strings.Split(url, "/") + domain := strings.Replace(domainArray[2], "www.", "", -1) + adDomain = append(adDomain, domain) + } + + bid := openrtb2.Bid{ + ID: ad.AdId, + ImpID: impId, + W: creativeWidth, + H: creativeHeight, + AdID: ad.AdId, + DealID: ad.DealID, + CID: ad.LineItemId, + CrID: ad.CreativeId, + Price: ad.Bid.Amount * 1000, + AdM: html, + ADomain: adDomain, + } + return &bid, nil + +} + func generateBidResponse(adnResponse *AdnResponse, request *openrtb2.BidRequest) (*adapters.BidderResponse, []error) { bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(adnResponse.AdUnits)) var currency string @@ -344,48 +392,34 @@ func generateBidResponse(adnResponse *AdnResponse, request *openrtb2.BidRequest) if len(adunit.Ads) > 0 { ad := adunit.Ads[0] - currency = ad.Bid.Currency - creativeWidth, widthErr := strconv.ParseInt(ad.CreativeWidth, 10, 64) - if widthErr != nil { + adBid, err := generateAdResponse(ad, request.Imp[i].ID, adunit.Html, request) + if err != nil { return nil, []error{&errortypes.BadInput{ - Message: fmt.Sprintf("Value of width: %s is not a string", ad.CreativeWidth), + Message: fmt.Sprintf("Error at ad generation"), }} } - creativeHeight, heightErr := strconv.ParseInt(ad.CreativeHeight, 10, 64) - if heightErr != nil { - return nil, []error{&errortypes.BadInput{ - Message: fmt.Sprintf("Value of height: %s is not a string", ad.CreativeHeight), - }} - } - - adDomain := []string{} - for _, url := range ad.DestinationUrls { - domainArray := strings.Split(url, "/") - domain := strings.Replace(domainArray[2], "www.", "", -1) - adDomain = append(adDomain, domain) - } - - bid := openrtb2.Bid{ - ID: ad.AdId, - ImpID: request.Imp[i].ID, - W: creativeWidth, - H: creativeHeight, - AdID: ad.AdId, - DealID: ad.DealID, - CID: ad.LineItemId, - CrID: ad.CreativeId, - Price: ad.Bid.Amount * 1000, - AdM: adunit.Html, - ADomain: adDomain, - } - bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ - Bid: &bid, + Bid: adBid, BidType: "banner", }) + + for _, deal := range adunit.Deals { + dealBid, err := generateAdResponse(deal, request.Imp[i].ID, deal.Html, request) + if err != nil { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Error at ad generation"), + }} + } + + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: dealBid, + BidType: "banner", + }) + } + } } diff --git a/adapters/adnuntius/adnuntiustest/supplemental/height-error.json b/adapters/adnuntius/adnuntiustest/supplemental/height-error.json index 1f213a43b6a..1987fb9d08e 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/height-error.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/height-error.json @@ -81,7 +81,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal number into Go struct field .AdUnits.Ads.CreativeHeight of type string", + "value": "json: cannot unmarshal number into Go struct field Ad.AdUnits.Ads.CreativeHeight of type string", "comparison": "literal" } ] diff --git a/adapters/adnuntius/adnuntiustest/supplemental/max-deals-test.json b/adapters/adnuntius/adnuntiustest/supplemental/max-deals-test.json new file mode 100644 index 00000000000..1d4c5bf0747 --- /dev/null +++ b/adapters/adnuntius/adnuntiustest/supplemental/max-deals-test.json @@ -0,0 +1,168 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "auId": "123", + "maxDeals": 2 + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://whatever.url?format=json&tzo=0", + "body": { + "adUnits": [ + { + "auId": "123", + "targetId": "123-test-imp-id", + "dimensions": [[300,250],[300,600]], + "maxDeals": 2 + } + ], + "context": "prebid.org", + "metaData": {} + } + }, + "mockResponse": { + "status": 200, + "body": { + "adUnits": [ + { + "auId": "0000000000000123", + "targetId": "123-test-imp-id", + "html": "", + "matchedAdCount": 1, + "responseId": "adn-rsp-815135818", + "deals": [ + { + "destinationUrlEsc": "", + "clickUrl": "https://click.url", + "urls": { + "url": "https://delivery.adnuntius.com/c/eKOchNsBJzE.net" + }, + "destinationUrls": { + "url": "http://www.google.com" + }, + "cpm": { + "amount": 1.0, + "currency": "NOK" + }, + "bid": { + "amount": 0.001, + "currency": "NOK" + }, + "grossBid": { + "amount": 0.001, + "currency": "NOK" + }, + "netBid": { + "amount": 0.001, + "currency": "NOK" + }, + "cost": { + "amount": 0.001, + "currency": "NOK" + }, + "dealId": "deal_123", + "adId": "adn-id-116330612", + "creativeWidth": "300", + "creativeHeight": "250", + "creativeId": "dl0knc1lnks9jgvx", + "lineItemId": "6l5w2d29kz3vkprq", + "layoutId": "adnuntius_image_layout_1", + "layoutName": "Image", + "layoutExternalReference": "", + "html": "" + } + ], + "ads": [ + { + "destinationUrls": { + "url": "http://www.google.com" + }, + "bid": { + "amount": 0.001, + "currency": "NOK" + }, + "adId": "adn-id-1559784095", + "creativeWidth": "300", + "creativeHeight": "250", + "creativeId": "jn9hpzvlsf8cpdmm", + "lineItemId": "q7y9qm5b0xt9htrv" + } + ] + } + ], + "metaData": { + "usi": "5dlpmw0d00btldjdvk1lp8rl", + "sessionId": "e4ada7251c93291a871f8e4319cc8fe5" + }, + "duplicateFilter": "AAAAAwAAAAAAJ33PAAAAAAAhrK4AAAAAACYNPAAAAAA=", + "segments": [], + "keywords": [] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "adn-id-1559784095", + "impid": "test-imp-id", + "price": 1, + "adm": "", + "adid": "adn-id-1559784095", + "adomain": ["google.com"], + "cid": "q7y9qm5b0xt9htrv", + "crid": "jn9hpzvlsf8cpdmm", + "w": 300, + "h": 250 + }, + "type": "banner" + }, + { + "bid": { + "id": "adn-id-116330612", + "impid": "test-imp-id", + "price": 1, + "adm": "", + "adid": "adn-id-116330612", + "adomain": ["google.com"], + "cid": "6l5w2d29kz3vkprq", + "crid": "dl0knc1lnks9jgvx", + "dealid": "deal_123", + "w": 300, + "h": 250 + }, + "type": "banner" + } + ], + "currency": "NOK" + } + ] +} diff --git a/adapters/adnuntius/adnuntiustest/supplemental/width-error.json b/adapters/adnuntius/adnuntiustest/supplemental/width-error.json index 1fd8a83f9dd..4f109942b91 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/width-error.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/width-error.json @@ -81,7 +81,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal number into Go struct field .AdUnits.Ads.CreativeWidth of type string", + "value": "json: cannot unmarshal number into Go struct field Ad.AdUnits.Ads.CreativeWidth of type string", "comparison": "literal" } ] diff --git a/openrtb_ext/imp_adnuntius.go b/openrtb_ext/imp_adnuntius.go index b1e41e806b6..3759ad50678 100644 --- a/openrtb_ext/imp_adnuntius.go +++ b/openrtb_ext/imp_adnuntius.go @@ -3,5 +3,6 @@ package openrtb_ext type ImpExtAdnunitus struct { Auid string `json:"auId"` Network string `json:"network"` - NoCookies bool `json:noCookies` + NoCookies bool `json:"noCookies'"` + MaxDeals int `json:"maxDeals"` } From 61a9fcb8b6b2024bbafe6aed3c65fe5bfc9f0909 Mon Sep 17 00:00:00 2001 From: erictmf <120136093+erictmf@users.noreply.github.com> Date: Mon, 24 Jul 2023 08:19:35 -0400 Subject: [PATCH 036/268] Added support for multi imps and multi formats. (#2950) --- adapters/mobilefuse/mobilefuse.go | 31 ++-- .../exemplary/multi-imps-multi-format.json | 154 ++++++++++++++++++ .../mobilefusetest/exemplary/multi-imps.json | 12 ++ 3 files changed, 186 insertions(+), 11 deletions(-) create mode 100644 adapters/mobilefuse/mobilefusetest/exemplary/multi-imps-multi-format.json diff --git a/adapters/mobilefuse/mobilefuse.go b/adapters/mobilefuse/mobilefuse.go index 07ecd61b26a..c13dbe8a6ae 100644 --- a/adapters/mobilefuse/mobilefuse.go +++ b/adapters/mobilefuse/mobilefuse.go @@ -100,19 +100,16 @@ func (adapter *MobileFuseAdapter) makeRequest(bidRequest *openrtb2.BidRequest) ( var errs []error mobileFuseExtension, errs := getFirstMobileFuseExtension(bidRequest) - if errs != nil { return nil, errs } endpoint, err := adapter.getEndpoint(mobileFuseExtension) - if err != nil { return nil, append(errs, err) } validImps, err := getValidImps(bidRequest, mobileFuseExtension) - if err != nil { errs = append(errs, err) return nil, errs @@ -121,7 +118,6 @@ func (adapter *MobileFuseAdapter) makeRequest(bidRequest *openrtb2.BidRequest) ( mobileFuseBidRequest := *bidRequest mobileFuseBidRequest.Imp = validImps body, err := json.Marshal(mobileFuseBidRequest) - if err != nil { return nil, append(errs, err) } @@ -165,13 +161,23 @@ func getFirstMobileFuseExtension(request *openrtb2.BidRequest) (*openrtb_ext.Ext return &mobileFuseImpExtension, errs } +func getMobileFuseExtensionForImp(imp *openrtb2.Imp, mobileFuseImpExtension *openrtb_ext.ExtImpMobileFuse) error { + var bidder_imp_extension adapters.ExtImpBidder + + err := json.Unmarshal(imp.Ext, &bidder_imp_extension) + if err != nil { + return err + } + + return json.Unmarshal(bidder_imp_extension.Bidder, &mobileFuseImpExtension) +} + func (adapter *MobileFuseAdapter) getEndpoint(ext *openrtb_ext.ExtImpMobileFuse) (string, error) { publisher_id := strconv.Itoa(ext.PublisherId) - url, errs := macros.ResolveMacros(adapter.EndpointTemplate, macros.EndpointTemplateParams{PublisherID: publisher_id}) - - if errs != nil { - return "", errs + url, err := macros.ResolveMacros(adapter.EndpointTemplate, macros.EndpointTemplateParams{PublisherID: publisher_id}) + if err != nil { + return "", err } if ext.TagidSrc == "ext" { @@ -186,10 +192,15 @@ func getValidImps(bidRequest *openrtb2.BidRequest, ext *openrtb_ext.ExtImpMobile for _, imp := range bidRequest.Imp { if imp.Banner != nil || imp.Video != nil || imp.Native != nil { + err := getMobileFuseExtensionForImp(&imp, ext) + if err != nil { + return nil, err + } + imp.TagID = strconv.Itoa(ext.PlacementId) var extSkadn ExtSkadn - err := json.Unmarshal(imp.Ext, &extSkadn) + err = json.Unmarshal(imp.Ext, &extSkadn) if err != nil { return nil, err } @@ -204,8 +215,6 @@ func getValidImps(bidRequest *openrtb2.BidRequest, ext *openrtb_ext.ExtImpMobile } validImps = append(validImps, imp) - - break } } diff --git a/adapters/mobilefuse/mobilefusetest/exemplary/multi-imps-multi-format.json b/adapters/mobilefuse/mobilefusetest/exemplary/multi-imps-multi-format.json new file mode 100644 index 00000000000..c31cb1ced55 --- /dev/null +++ b/adapters/mobilefuse/mobilefusetest/exemplary/multi-imps-multi-format.json @@ -0,0 +1,154 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 320, + "h": 50 + } + ] + }, + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 320, + "h": 480 + }, + "ext": { + "bidder": { + "placement_id": 123456, + "pub_id": 1234 + } + } + }, + { + "id": "2", + "banner": { + "format": [ + { + "w": 300, + "h": 50 + } + ] + }, + "native": { + "ver": "1.2", + "request": "{\"native\":{\"assets\":[{\"id\":0,\"required\":1,\"img\":{\"url\":\"...\"}},{\"id\":1,\"required\":1,\"title\":{\"text\":\"custom title\"}}]}}" + }, + "ext": { + "bidder": { + "placement_id": 234567, + "pub_id": 1234 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://mfx.mobilefuse.com/openrtb?pub_id=1234", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "1", + "banner": { + "format": [ + { + "w": 320, + "h": 50 + } + ] + }, + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 320, + "h": 480 + }, + "tagid": "123456" + }, + { + "id": "2", + "banner": { + "format": [ + { + "w": 300, + "h": 50 + } + ] + }, + "native": { + "ver": "1.2", + "request": "{\"native\":{\"assets\":[{\"id\":0,\"required\":1,\"img\":{\"url\":\"...\"}},{\"id\":1,\"required\":1,\"title\":{\"text\":\"custom title\"}}]}}" + }, + "tagid": "234567" + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "mobilefuse", + "bid": [ + { + "id": "test-bid-id", + "impid": "1", + "price": 1.50, + "adm": "some-test-ad", + "crid": "test-crid", + "h": 50, + "w": 320, + "ext": { + "mf": { + "media_type": "banner" + } + } + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "1", + "price": 1.50, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 320, + "h": 50 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/mobilefuse/mobilefusetest/exemplary/multi-imps.json b/adapters/mobilefuse/mobilefusetest/exemplary/multi-imps.json index 568e51af61b..15ba4f96d6b 100644 --- a/adapters/mobilefuse/mobilefusetest/exemplary/multi-imps.json +++ b/adapters/mobilefuse/mobilefusetest/exemplary/multi-imps.json @@ -57,6 +57,18 @@ ] }, "tagid": "123456" + }, + { + "id": "2", + "banner": { + "format": [ + { + "w": 300, + "h": 50 + } + ] + }, + "tagid": "234567" } ] } From 35db00f170625a2436019a0a175864ed6f2d437e Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Tue, 25 Jul 2023 11:33:28 +0530 Subject: [PATCH 037/268] Set updated tmax value to bidder's MakeRequest implementation (#2930) co-authored by: @onkarvhanumante --- endpoints/openrtb2/amp_auction.go | 9 +- endpoints/openrtb2/amp_auction_test.go | 13 +++ endpoints/openrtb2/auction.go | 9 +- endpoints/openrtb2/auction_benchmark_test.go | 1 + endpoints/openrtb2/auction_test.go | 59 ++++++++-- endpoints/openrtb2/test_utils.go | 3 +- endpoints/openrtb2/video_auction.go | 9 +- endpoints/openrtb2/video_auction_test.go | 4 + exchange/bidder.go | 6 ++ exchange/bidder_test.go | 76 +++++++++++++ exchange/exchange.go | 10 +- exchange/tmax_adjustments.go | 57 ++++++++++ exchange/tmax_adjustments_test.go | 108 +++++++++++++++++++ router/router.go | 7 +- 14 files changed, 352 insertions(+), 19 deletions(-) create mode 100644 exchange/tmax_adjustments.go create mode 100644 exchange/tmax_adjustments_test.go diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index 9e06272b483..0d5c35f9416 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -69,6 +69,7 @@ func NewAmpEndpoint( bidderMap map[string]openrtb_ext.BidderName, storedRespFetcher stored_requests.Fetcher, hookExecutionPlanBuilder hooks.ExecutionPlanBuilder, + tmaxAdjustments *exchange.TmaxAdjustmentsPreprocessed, ) (httprouter.Handle, error) { if ex == nil || validator == nil || requestsById == nil || accounts == nil || cfg == nil || metricsEngine == nil { @@ -100,7 +101,9 @@ func NewAmpEndpoint( nil, ipValidator, storedRespFetcher, - hookExecutionPlanBuilder}).AmpAuction), nil + hookExecutionPlanBuilder, + tmaxAdjustments, + }).AmpAuction), nil } @@ -251,6 +254,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h QueryParams: r.URL.Query(), TCF2Config: tcf2Config, Activities: activities, + TmaxAdjustments: deps.tmaxAdjustments, } auctionResponse, err := deps.ex.HoldAuction(ctx, auctionRequest, nil) @@ -292,6 +296,9 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h } labels, ao = sendAmpResponse(w, hookExecutor, auctionResponse, reqWrapper, account, labels, ao, errL) + if len(ao.Errors) == 0 && !auctionRequest.BidderResponseStartTime.IsZero() { + deps.metricsEngine.RecordOverheadTime(metrics.MakeAuctionResponse, time.Since(auctionRequest.BidderResponseStartTime)) + } } func rejectAmpRequest( diff --git a/endpoints/openrtb2/amp_auction_test.go b/endpoints/openrtb2/amp_auction_test.go index d709a7020c7..87033f71b64 100644 --- a/endpoints/openrtb2/amp_auction_test.go +++ b/endpoints/openrtb2/amp_auction_test.go @@ -216,6 +216,7 @@ func TestAMPPageInfo(t *testing.T) { openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, ) request := httptest.NewRequest("GET", fmt.Sprintf("/openrtb2/auction/amp?tag_id=1&curl=%s", url.QueryEscape(page)), nil) recorder := httptest.NewRecorder() @@ -319,6 +320,7 @@ func TestGDPRConsent(t *testing.T) { openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, ) // Invoke Endpoint @@ -742,6 +744,7 @@ func TestCCPAConsent(t *testing.T) { openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, ) // Invoke Endpoint @@ -855,6 +858,7 @@ func TestConsentWarnings(t *testing.T) { openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, ) // Invoke Endpoint @@ -953,6 +957,7 @@ func TestNewAndLegacyConsentBothProvided(t *testing.T) { openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, ) // Invoke Endpoint @@ -1007,6 +1012,7 @@ func TestAMPSiteExt(t *testing.T) { openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, ) request, err := http.NewRequest("GET", "/openrtb2/auction/amp?tag_id=1", nil) if !assert.NoError(t, err) { @@ -1049,6 +1055,7 @@ func TestAmpBadRequests(t *testing.T) { openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, ) for requestID := range badRequests { request := httptest.NewRequest("GET", fmt.Sprintf("/openrtb2/auction/amp?tag_id=%s", requestID), nil) @@ -1082,6 +1089,7 @@ func TestAmpDebug(t *testing.T) { openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, ) for requestID := range requests { @@ -1217,6 +1225,7 @@ func TestQueryParamOverrides(t *testing.T) { openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, ) requestID := "1" @@ -1374,6 +1383,7 @@ func (s formatOverrideSpec) execute(t *testing.T) { openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, ) url := fmt.Sprintf("/openrtb2/auction/amp?tag_id=1&debug=1&w=%d&h=%d&ow=%d&oh=%d&ms=%s&account=%s", s.width, s.height, s.overrideWidth, s.overrideHeight, s.multisize, s.account) @@ -1914,6 +1924,7 @@ func ampObjectTestSetup(t *testing.T, inTagId string, inStoredRequest json.RawMe openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, ) return &actualAmpObject, endpoint } @@ -1966,6 +1977,7 @@ func TestAmpAuctionResponseHeaders(t *testing.T) { openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, ) for _, test := range testCases { @@ -2001,6 +2013,7 @@ func TestRequestWithTargeting(t *testing.T) { openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, ) url, err := url.Parse("/openrtb2/auction/amp") assert.NoError(t, err, "unexpected error received while parsing url") diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 087d0a5d49e..8e01552c07a 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -92,6 +92,7 @@ func NewEndpoint( bidderMap map[string]openrtb_ext.BidderName, storedRespFetcher stored_requests.Fetcher, hookExecutionPlanBuilder hooks.ExecutionPlanBuilder, + tmaxAdjustments *exchange.TmaxAdjustmentsPreprocessed, ) (httprouter.Handle, error) { if ex == nil || validator == nil || requestsById == nil || accounts == nil || cfg == nil || metricsEngine == nil { return nil, errors.New("NewEndpoint requires non-nil arguments.") @@ -122,7 +123,8 @@ func NewEndpoint( nil, ipValidator, storedRespFetcher, - hookExecutionPlanBuilder}).Auction), nil + hookExecutionPlanBuilder, + tmaxAdjustments}).Auction), nil } type endpointDeps struct { @@ -144,6 +146,7 @@ type endpointDeps struct { privateNetworkIPValidator iputil.IPValidator storedRespFetcher stored_requests.Fetcher hookExecutionPlanBuilder hooks.ExecutionPlanBuilder + tmaxAdjustments *exchange.TmaxAdjustmentsPreprocessed } func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { @@ -250,6 +253,7 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http HookExecutor: hookExecutor, TCF2Config: tcf2Config, Activities: activities, + TmaxAdjustments: deps.tmaxAdjustments, } auctionResponse, err := deps.ex.HoldAuction(ctx, auctionRequest, nil) defer func() { @@ -288,6 +292,9 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http glog.Errorf("Error setting seat non-bid: %v", err) } labels, ao = sendAuctionResponse(w, hookExecutor, response, req.BidRequest, account, labels, ao) + if len(ao.Errors) == 0 && !auctionRequest.BidderResponseStartTime.IsZero() { + deps.metricsEngine.RecordOverheadTime(metrics.MakeAuctionResponse, time.Since(auctionRequest.BidderResponseStartTime)) + } } // setSeatNonBidRaw is transitional function for setting SeatNonBid inside bidResponse.Ext diff --git a/endpoints/openrtb2/auction_benchmark_test.go b/endpoints/openrtb2/auction_benchmark_test.go index 9ad3c768a83..a3c19ee0b10 100644 --- a/endpoints/openrtb2/auction_benchmark_test.go +++ b/endpoints/openrtb2/auction_benchmark_test.go @@ -111,6 +111,7 @@ func BenchmarkOpenrtbEndpoint(b *testing.B) { nil, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, ) b.ResetTimer() diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index c6604fcf9c9..4be48811d00 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -454,7 +454,9 @@ func TestExplicitUserId(t *testing.T) { []byte{}, openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, - hooks.EmptyPlanBuilder{}) + hooks.EmptyPlanBuilder{}, + nil, + ) endpoint(httptest.NewRecorder(), request, nil) @@ -510,7 +512,9 @@ func doBadAliasRequest(t *testing.T, filename string, expectMsg string) { aliasJSON, bidderMap, empty_fetcher.EmptyFetcher{}, - hooks.EmptyPlanBuilder{}) + hooks.EmptyPlanBuilder{}, + nil, + ) request := httptest.NewRequest("POST", "/openrtb2/auction", bytes.NewReader(testBidRequest)) recorder := httptest.NewRecorder() @@ -562,7 +566,9 @@ func TestNilExchange(t *testing.T) { []byte{}, openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, - hooks.EmptyPlanBuilder{}) + hooks.EmptyPlanBuilder{}, + nil, + ) if err == nil { t.Errorf("NewEndpoint should return an error when given a nil Exchange.") @@ -586,7 +592,9 @@ func TestNilValidator(t *testing.T) { []byte{}, openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, - hooks.EmptyPlanBuilder{}) + hooks.EmptyPlanBuilder{}, + nil, + ) if err == nil { t.Errorf("NewEndpoint should return an error when given a nil BidderParamValidator.") @@ -610,7 +618,9 @@ func TestExchangeError(t *testing.T) { []byte{}, openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, - hooks.EmptyPlanBuilder{}) + hooks.EmptyPlanBuilder{}, + nil, + ) request := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(validRequest(t, "site.json"))) recorder := httptest.NewRecorder() @@ -735,7 +745,9 @@ func TestImplicitIPsEndToEnd(t *testing.T) { []byte{}, openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, - hooks.EmptyPlanBuilder{}) + hooks.EmptyPlanBuilder{}, + nil, + ) httpReq := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(validRequest(t, test.reqJSONFile))) httpReq.Header.Set("X-Forwarded-For", test.xForwardedForHeader) @@ -933,7 +945,9 @@ func TestImplicitDNTEndToEnd(t *testing.T) { []byte{}, openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, - hooks.EmptyPlanBuilder{}) + hooks.EmptyPlanBuilder{}, + nil, + ) httpReq := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(validRequest(t, test.reqJSONFile))) httpReq.Header.Set("DNT", test.dntHeader) @@ -1144,6 +1158,7 @@ func TestStoredRequests(t *testing.T) { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } testStoreVideoAttr := []bool{true, true, false, false, false} @@ -1517,6 +1532,7 @@ func TestValidateRequest(t *testing.T) { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } testCases := []struct { @@ -2235,6 +2251,7 @@ func TestSetIntegrationType(t *testing.T) { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } testCases := []struct { @@ -2300,6 +2317,7 @@ func TestStoredRequestGenerateUuid(t *testing.T) { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } req := &openrtb2.BidRequest{} @@ -2403,6 +2421,7 @@ func TestOversizedRequest(t *testing.T) { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } req := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(reqBody)) @@ -2441,6 +2460,7 @@ func TestRequestSizeEdgeCase(t *testing.T) { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } req := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(reqBody)) @@ -2473,6 +2493,7 @@ func TestNoEncoding(t *testing.T) { openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, ) request := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(validRequest(t, "site.json"))) recorder := httptest.NewRecorder() @@ -2557,6 +2578,7 @@ func TestContentType(t *testing.T) { openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, ) request := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(validRequest(t, "site.json"))) recorder := httptest.NewRecorder() @@ -2777,6 +2799,7 @@ func TestValidateImpExt(t *testing.T) { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } for _, group := range testGroups { @@ -2829,6 +2852,7 @@ func TestCurrencyTrunc(t *testing.T) { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } ui := int64(1) @@ -2876,6 +2900,7 @@ func TestCCPAInvalid(t *testing.T) { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } ui := int64(1) @@ -2927,6 +2952,7 @@ func TestNoSaleInvalid(t *testing.T) { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } ui := int64(1) @@ -2981,6 +3007,7 @@ func TestValidateSourceTID(t *testing.T) { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } ui := int64(1) @@ -3025,6 +3052,7 @@ func TestSChainInvalid(t *testing.T) { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } ui := int64(1) @@ -3520,6 +3548,7 @@ func TestEidPermissionsInvalid(t *testing.T) { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } ui := int64(1) @@ -3768,7 +3797,9 @@ func TestIOS14EndToEnd(t *testing.T) { []byte{}, openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, - hooks.EmptyPlanBuilder{}) + hooks.EmptyPlanBuilder{}, + nil, + ) httpReq := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(validRequest(t, "app-ios140-no-ifa.json"))) @@ -3834,6 +3865,7 @@ func TestAuctionWarnings(t *testing.T) { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } for _, test := range testCases { t.Run(test.name, func(t *testing.T) { @@ -3879,6 +3911,7 @@ func TestParseRequestParseImpInfoError(t *testing.T) { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } hookExecutor := hookexecution.NewHookExecutor(deps.hookExecutionPlanBuilder, hookexecution.EndpointAuction, deps.metricsEngine) @@ -3958,6 +3991,7 @@ func TestParseGzipedRequest(t *testing.T) { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } hookExecutor := hookexecution.NewHookExecutor(deps.hookExecutionPlanBuilder, hookexecution.EndpointAuction, deps.metricsEngine) @@ -4451,7 +4485,9 @@ func TestAuctionResponseHeaders(t *testing.T) { []byte{}, openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, - hooks.EmptyPlanBuilder{}) + hooks.EmptyPlanBuilder{}, + nil, + ) for _, test := range testCases { httpReq := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(test.requestBody)) @@ -4555,6 +4591,7 @@ func TestParseRequestMergeBidderParams(t *testing.T) { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } hookExecutor := hookexecution.NewHookExecutor(deps.hookExecutionPlanBuilder, hookexecution.EndpointAuction, deps.metricsEngine) @@ -4657,6 +4694,7 @@ func TestParseRequestStoredResponses(t *testing.T) { hardcodedResponseIPValidator{response: true}, &mockStoredResponseFetcher{mockStoredResponses}, hooks.EmptyPlanBuilder{}, + nil, } hookExecutor := hookexecution.NewHookExecutor(deps.hookExecutionPlanBuilder, hookexecution.EndpointAuction, deps.metricsEngine) @@ -4744,6 +4782,7 @@ func TestParseRequestStoredBidResponses(t *testing.T) { hardcodedResponseIPValidator{response: true}, &mockStoredResponseFetcher{mockStoredBidResponses}, hooks.EmptyPlanBuilder{}, + nil, } hookExecutor := hookexecution.NewHookExecutor(deps.hookExecutionPlanBuilder, hookexecution.EndpointAuction, deps.metricsEngine) @@ -4780,6 +4819,7 @@ func TestValidateStoredResp(t *testing.T) { hardcodedResponseIPValidator{response: true}, &mockStoredResponseFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } testCases := []struct { @@ -5592,6 +5632,7 @@ func TestParseRequestMultiBid(t *testing.T) { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } hookExecutor := hookexecution.NewHookExecutor(deps.hookExecutionPlanBuilder, hookexecution.EndpointAuction, deps.metricsEngine) diff --git a/endpoints/openrtb2/test_utils.go b/endpoints/openrtb2/test_utils.go index a93325eaf29..401fbf623c0 100644 --- a/endpoints/openrtb2/test_utils.go +++ b/endpoints/openrtb2/test_utils.go @@ -1290,7 +1290,7 @@ func buildTestEndpoint(test testCase, cfg *config.Configuration) (httprouter.Han planBuilder = hooks.EmptyPlanBuilder{} } - var endpointBuilder func(uuidutil.UUIDGenerator, exchange.Exchange, openrtb_ext.BidderParamValidator, stored_requests.Fetcher, stored_requests.AccountFetcher, *config.Configuration, metrics.MetricsEngine, analytics.PBSAnalyticsModule, map[string]string, []byte, map[string]openrtb_ext.BidderName, stored_requests.Fetcher, hooks.ExecutionPlanBuilder) (httprouter.Handle, error) + var endpointBuilder func(uuidutil.UUIDGenerator, exchange.Exchange, openrtb_ext.BidderParamValidator, stored_requests.Fetcher, stored_requests.AccountFetcher, *config.Configuration, metrics.MetricsEngine, analytics.PBSAnalyticsModule, map[string]string, []byte, map[string]openrtb_ext.BidderName, stored_requests.Fetcher, hooks.ExecutionPlanBuilder, *exchange.TmaxAdjustmentsPreprocessed) (httprouter.Handle, error) switch test.endpointType { case AMP_ENDPOINT: @@ -1313,6 +1313,7 @@ func buildTestEndpoint(test testCase, cfg *config.Configuration) (httprouter.Han bidderMap, storedResponseFetcher, planBuilder, + nil, ) return endpoint, testExchange.(*exchangeTestWrapper), mockBidServersArray, mockCurrencyRatesServer, err diff --git a/endpoints/openrtb2/video_auction.go b/endpoints/openrtb2/video_auction.go index 565baf0261b..a2a1e03e684 100644 --- a/endpoints/openrtb2/video_auction.go +++ b/endpoints/openrtb2/video_auction.go @@ -56,6 +56,7 @@ func NewVideoEndpoint( defReqJSON []byte, bidderMap map[string]openrtb_ext.BidderName, cache prebid_cache_client.Client, + tmaxAdjustments *exchange.TmaxAdjustmentsPreprocessed, ) (httprouter.Handle, error) { if ex == nil || validator == nil || requestsById == nil || accounts == nil || cfg == nil || met == nil { @@ -89,7 +90,8 @@ func NewVideoEndpoint( videoEndpointRegexp, ipValidator, empty_fetcher.EmptyFetcher{}, - hooks.EmptyPlanBuilder{}}).VideoAuctionEndpoint), nil + hooks.EmptyPlanBuilder{}, + tmaxAdjustments}).VideoAuctionEndpoint), nil } /* @@ -311,6 +313,7 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re GlobalPrivacyControlHeader: secGPC, PubID: labels.PubID, HookExecutor: hookexecution.EmptyHookExecutor{}, + TmaxAdjustments: deps.tmaxAdjustments, } auctionResponse, err := deps.ex.HoldAuction(ctx, auctionRequest, &debugLog) @@ -372,6 +375,10 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re return } + if len(vo.Errors) == 0 && !auctionRequest.BidderResponseStartTime.IsZero() { + deps.metricsEngine.RecordOverheadTime(metrics.MakeAuctionResponse, time.Since(auctionRequest.BidderResponseStartTime)) + } + w.Header().Set("Content-Type", "application/json") w.Write(resp) diff --git a/endpoints/openrtb2/video_auction_test.go b/endpoints/openrtb2/video_auction_test.go index 496a2ac8cff..1f28efb8a6f 100644 --- a/endpoints/openrtb2/video_auction_test.go +++ b/endpoints/openrtb2/video_auction_test.go @@ -1225,6 +1225,7 @@ func mockDepsWithMetrics(t *testing.T, ex *mockExchangeVideo) (*endpointDeps, *m hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } return deps, metrics, mockModule } @@ -1270,6 +1271,7 @@ func mockDeps(t *testing.T, ex *mockExchangeVideo) *endpointDeps { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } } @@ -1293,6 +1295,7 @@ func mockDepsAppendBidderNames(t *testing.T, ex *mockExchangeAppendBidderNames) hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } return deps @@ -1318,6 +1321,7 @@ func mockDepsNoBids(t *testing.T, ex *mockExchangeVideoNoBids) *endpointDeps { hardcodedResponseIPValidator{response: true}, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, + nil, } return edep diff --git a/exchange/bidder.go b/exchange/bidder.go index 27012ff4aa2..5d9d5cba68b 100644 --- a/exchange/bidder.go +++ b/exchange/bidder.go @@ -67,6 +67,7 @@ type bidRequestOptions struct { headerDebugAllowed bool addCallSignHeader bool bidAdjustments map[string]float64 + tmaxAdjustments *TmaxAdjustmentsPreprocessed } type extraBidderRespInfo struct { @@ -143,6 +144,11 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest Bidde //check if real request exists for this bidder or it only has stored responses dataLen := 0 if len(bidderRequest.BidRequest.Imp) > 0 { + // Reducing the amount of time bidders have to compensate for the processing time used by PBS to fetch a stored request (if needed), validate the OpenRTB request and split it into multiple requests sanitized for each bidder + // As well as for the time needed by PBS to prepare the auction response + if bidRequestOptions.tmaxAdjustments != nil && bidRequestOptions.tmaxAdjustments.IsEnforced { + bidderRequest.BidRequest.TMax = getBidderTmax(&bidderTmaxCtx{ctx}, bidderRequest.BidRequest.TMax, *bidRequestOptions.tmaxAdjustments) + } reqData, errs = bidder.Bidder.MakeRequests(bidderRequest.BidRequest, reqInfo) if len(reqData) == 0 { diff --git a/exchange/bidder_test.go b/exchange/bidder_test.go index 9d36808ce31..3eeb3e909af 100644 --- a/exchange/bidder_test.go +++ b/exchange/bidder_test.go @@ -3063,3 +3063,79 @@ func TestGetBidType(t *testing.T) { }) } } + +type mockBidderTmaxCtx struct { + startTime, deadline time.Time + ok bool +} + +func (m *mockBidderTmaxCtx) Deadline() (deadline time.Time, _ bool) { + return m.deadline, m.ok +} +func (m *mockBidderTmaxCtx) RemainingDurationMS(deadline time.Time) int64 { + return deadline.Sub(m.startTime).Milliseconds() +} + +func TestUpdateBidderTmax(t *testing.T) { + respStatus := 200 + respBody := "{\"bid\":false}" + server := httptest.NewServer(mockHandler(respStatus, "getBody", respBody)) + defer server.Close() + + requestHeaders := http.Header{} + requestHeaders.Add("Content-Type", "application/json") + + currencyConverter := currency.NewRateConverter(&http.Client{}, "", time.Duration(0)) + var requestTmax int64 = 700 + + bidderReq := BidderRequest{ + BidRequest: &openrtb2.BidRequest{Imp: []openrtb2.Imp{{ID: "impId"}}, TMax: requestTmax}, + BidderName: "test", + } + extraInfo := &adapters.ExtraRequestInfo{} + + tests := []struct { + description string + requestTmax int64 + tmaxAdjustments *TmaxAdjustmentsPreprocessed + assertFn func(actualTmax int64) bool + }{ + { + description: "tmax-is-not-enabled", + requestTmax: requestTmax, + tmaxAdjustments: &TmaxAdjustmentsPreprocessed{IsEnforced: false}, + assertFn: func(actualTmax int64) bool { + return requestTmax == actualTmax + }, + }, + { + description: "updates-bidder-tmax", + requestTmax: requestTmax, + tmaxAdjustments: &TmaxAdjustmentsPreprocessed{IsEnforced: true, BidderResponseDurationMin: 100, BidderNetworkLatencyBuffer: 50, PBSResponsePreparationDuration: 50}, + assertFn: func(actualTmax int64) bool { + return requestTmax > actualTmax + }, + }, + } + for _, test := range tests { + t.Run(test.description, func(t *testing.T) { + bidderImpl := &goodSingleBidder{ + httpRequest: &adapters.RequestData{ + Method: "POST", + Uri: server.URL, + Body: []byte("{\"key\":\"val\"}"), + Headers: http.Header{}, + }, + bidResponse: &adapters.BidderResponse{}, + } + + ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(50*time.Millisecond)) + defer cancel() + bidReqOptions := bidRequestOptions{tmaxAdjustments: test.tmaxAdjustments} + bidder := AdaptBidder(bidderImpl, server.Client(), &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, openrtb_ext.BidderAppnexus, &config.DebugInfo{Allow: false}, "") + _, _, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), extraInfo, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) + assert.Empty(t, errs) + assert.True(t, test.assertFn(bidderImpl.bidRequest.TMax)) + }) + } +} diff --git a/exchange/exchange.go b/exchange/exchange.go index 390db973578..1436f3ea2df 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -6,7 +6,6 @@ import ( "encoding/json" "errors" "fmt" - "github.com/prebid/prebid-server/privacy" "math/rand" "net/url" "runtime/debug" @@ -15,6 +14,8 @@ import ( "strings" "time" + "github.com/prebid/prebid-server/privacy" + "github.com/prebid/prebid-server/adapters" "github.com/prebid/prebid-server/adservertargeting" "github.com/prebid/prebid-server/bidadjustment" @@ -211,6 +212,7 @@ type AuctionRequest struct { HookExecutor hookexecution.StageExecutor QueryParams url.Values BidderResponseStartTime time.Time + TmaxAdjustments *TmaxAdjustmentsPreprocessed } // BidderRequest holds the bidder specific request and all other @@ -368,7 +370,7 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog alternateBidderCodes = *r.Account.AlternateBidderCodes } var extraRespInfo extraAuctionResponseInfo - adapterBids, adapterExtra, extraRespInfo = e.getAllBids(auctionCtx, bidderRequests, bidAdjustmentFactors, conversions, accountDebugAllow, r.GlobalPrivacyControlHeader, debugLog.DebugOverride, alternateBidderCodes, requestExtLegacy.Prebid.Experiment, r.HookExecutor, r.StartTime, bidAdjustmentRules) + adapterBids, adapterExtra, extraRespInfo = e.getAllBids(auctionCtx, bidderRequests, bidAdjustmentFactors, conversions, accountDebugAllow, r.GlobalPrivacyControlHeader, debugLog.DebugOverride, alternateBidderCodes, requestExtLegacy.Prebid.Experiment, r.HookExecutor, r.StartTime, bidAdjustmentRules, r.TmaxAdjustments) fledge = extraRespInfo.fledge anyBidsReturned = extraRespInfo.bidsFound r.BidderResponseStartTime = extraRespInfo.bidderResponseStartTime @@ -660,7 +662,8 @@ func (e *exchange) getAllBids( experiment *openrtb_ext.Experiment, hookExecutor hookexecution.StageExecutor, pbsRequestStartTime time.Time, - bidAdjustmentRules map[string][]openrtb_ext.Adjustment) ( + bidAdjustmentRules map[string][]openrtb_ext.Adjustment, + tmaxAdjustments *TmaxAdjustmentsPreprocessed) ( map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid, map[openrtb_ext.BidderName]*seatResponseExtra, extraAuctionResponseInfo) { @@ -699,6 +702,7 @@ func (e *exchange) getAllBids( headerDebugAllowed: headerDebugAllowed, addCallSignHeader: isAdsCertEnabled(experiment, e.bidderInfo[string(bidderRequest.BidderName)]), bidAdjustments: bidAdjustments, + tmaxAdjustments: tmaxAdjustments, } seatBids, extraBidderRespInfo, err := e.adapterMap[bidderRequest.BidderCoreName].requestBid(ctx, bidderRequest, conversions, &reqInfo, e.adsCertSigner, bidReqOptions, alternateBidderCodes, hookExecutor, bidAdjustmentRules) brw.bidderResponseStartTime = extraBidderRespInfo.respProcessingStartTime diff --git a/exchange/tmax_adjustments.go b/exchange/tmax_adjustments.go new file mode 100644 index 00000000000..86934ecc331 --- /dev/null +++ b/exchange/tmax_adjustments.go @@ -0,0 +1,57 @@ +package exchange + +import ( + "context" + "time" + + "github.com/prebid/prebid-server/config" +) + +type TmaxAdjustmentsPreprocessed struct { + BidderNetworkLatencyBuffer uint + PBSResponsePreparationDuration uint + BidderResponseDurationMin uint + + IsEnforced bool +} + +func ProcessTMaxAdjustments(adjustmentsConfig config.TmaxAdjustments) *TmaxAdjustmentsPreprocessed { + if !adjustmentsConfig.Enabled { + return nil + } + + isEnforced := adjustmentsConfig.BidderResponseDurationMin != 0 && + (adjustmentsConfig.BidderNetworkLatencyBuffer != 0 || adjustmentsConfig.PBSResponsePreparationDuration != 0) + + tmax := &TmaxAdjustmentsPreprocessed{ + BidderNetworkLatencyBuffer: adjustmentsConfig.BidderNetworkLatencyBuffer, + PBSResponsePreparationDuration: adjustmentsConfig.PBSResponsePreparationDuration, + BidderResponseDurationMin: adjustmentsConfig.BidderResponseDurationMin, + IsEnforced: isEnforced, + } + + return tmax +} + +type bidderTmaxContext interface { + Deadline() (deadline time.Time, ok bool) + RemainingDurationMS(deadline time.Time) int64 +} +type bidderTmaxCtx struct{ ctx context.Context } + +func (b *bidderTmaxCtx) RemainingDurationMS(deadline time.Time) int64 { + return time.Until(deadline).Milliseconds() +} +func (b *bidderTmaxCtx) Deadline() (deadline time.Time, ok bool) { + deadline, ok = b.ctx.Deadline() + return +} + +func getBidderTmax(ctx bidderTmaxContext, requestTmaxMS int64, tmaxAdjustments TmaxAdjustmentsPreprocessed) int64 { + if tmaxAdjustments.IsEnforced { + if deadline, ok := ctx.Deadline(); ok { + return ctx.RemainingDurationMS(deadline) - int64(tmaxAdjustments.BidderNetworkLatencyBuffer) - int64(tmaxAdjustments.PBSResponsePreparationDuration) + } + } + return requestTmaxMS +} diff --git a/exchange/tmax_adjustments_test.go b/exchange/tmax_adjustments_test.go new file mode 100644 index 00000000000..7e6a02ab81e --- /dev/null +++ b/exchange/tmax_adjustments_test.go @@ -0,0 +1,108 @@ +package exchange + +import ( + "testing" + "time" + + "github.com/prebid/prebid-server/config" + "github.com/stretchr/testify/assert" +) + +func TestGetBidderTmax(t *testing.T) { + var ( + requestTmaxMS int64 = 700 + bidderNetworkLatencyBuffer uint = 50 + responsePreparationDuration uint = 60 + ) + requestTmaxNS := requestTmaxMS * int64(time.Millisecond) + startTime := time.Date(2023, 5, 30, 1, 0, 0, 0, time.UTC) + deadline := time.Date(2023, 5, 30, 1, 0, 0, int(requestTmaxNS), time.UTC) + ctx := &mockBidderTmaxCtx{startTime: startTime, deadline: deadline, ok: true} + tests := []struct { + description string + ctx bidderTmaxContext + requestTmax int64 + expectedTmax int64 + tmaxAdjustments TmaxAdjustmentsPreprocessed + }{ + { + description: "returns-requestTmax-when-IsEnforced-is-false", + ctx: ctx, + requestTmax: requestTmaxMS, + tmaxAdjustments: TmaxAdjustmentsPreprocessed{IsEnforced: false}, + expectedTmax: requestTmaxMS, + }, + { + description: "returns-requestTmax-when-BidderResponseDurationMin-is-not-set", + ctx: ctx, + requestTmax: requestTmaxMS, + tmaxAdjustments: TmaxAdjustmentsPreprocessed{IsEnforced: true, BidderResponseDurationMin: 0}, + expectedTmax: requestTmaxMS, + }, + { + description: "returns-requestTmax-when-BidderNetworkLatencyBuffer-and-PBSResponsePreparationDuration-is-not-set", + ctx: ctx, + requestTmax: requestTmaxMS, + tmaxAdjustments: TmaxAdjustmentsPreprocessed{IsEnforced: true, BidderResponseDurationMin: 100, BidderNetworkLatencyBuffer: 0, PBSResponsePreparationDuration: 0}, + expectedTmax: requestTmaxMS, + }, + { + description: "returns-requestTmax-when-context-deadline-is-not-set", + ctx: &mockBidderTmaxCtx{ok: false}, + requestTmax: requestTmaxMS, + tmaxAdjustments: TmaxAdjustmentsPreprocessed{IsEnforced: true, BidderResponseDurationMin: 100, BidderNetworkLatencyBuffer: 50, PBSResponsePreparationDuration: 60}, + expectedTmax: requestTmaxMS, + }, + { + description: "returns-remaing-duration-by-subtracting-BidderNetworkLatencyBuffer-and-PBSResponsePreparationDuration", + ctx: ctx, + requestTmax: requestTmaxMS, + tmaxAdjustments: TmaxAdjustmentsPreprocessed{IsEnforced: true, BidderResponseDurationMin: 100, BidderNetworkLatencyBuffer: bidderNetworkLatencyBuffer, PBSResponsePreparationDuration: responsePreparationDuration}, + expectedTmax: ctx.RemainingDurationMS(deadline) - int64(bidderNetworkLatencyBuffer) - int64(responsePreparationDuration), + }, + } + for _, test := range tests { + t.Run(test.description, func(t *testing.T) { + assert.Equal(t, test.expectedTmax, getBidderTmax(test.ctx, test.requestTmax, test.tmaxAdjustments)) + }) + } +} + +func TestProcessTMaxAdjustments(t *testing.T) { + tests := []struct { + description string + expected *TmaxAdjustmentsPreprocessed + tmaxAdjustments config.TmaxAdjustments + }{ + { + description: "returns-nil-when-tmax-is-not-enabled", + tmaxAdjustments: config.TmaxAdjustments{Enabled: false}, + expected: nil, + }, + { + description: "BidderResponseDurationMin-is-not-set", + tmaxAdjustments: config.TmaxAdjustments{Enabled: true, BidderResponseDurationMin: 0, BidderNetworkLatencyBuffer: 10, PBSResponsePreparationDuration: 20}, + expected: &TmaxAdjustmentsPreprocessed{IsEnforced: false, BidderResponseDurationMin: 0, BidderNetworkLatencyBuffer: 10, PBSResponsePreparationDuration: 20}, + }, + { + description: "BidderNetworkLatencyBuffer-and-PBSResponsePreparationDuration-are-not-set", + tmaxAdjustments: config.TmaxAdjustments{Enabled: true, BidderResponseDurationMin: 100, BidderNetworkLatencyBuffer: 0, PBSResponsePreparationDuration: 0}, + expected: &TmaxAdjustmentsPreprocessed{IsEnforced: false, BidderResponseDurationMin: 100, BidderNetworkLatencyBuffer: 0, PBSResponsePreparationDuration: 0}, + }, + { + description: "BidderNetworkLatencyBuffer-is-not-set", + tmaxAdjustments: config.TmaxAdjustments{Enabled: true, BidderResponseDurationMin: 100, BidderNetworkLatencyBuffer: 0, PBSResponsePreparationDuration: 10}, + expected: &TmaxAdjustmentsPreprocessed{IsEnforced: true, BidderResponseDurationMin: 100, BidderNetworkLatencyBuffer: 0, PBSResponsePreparationDuration: 10}, + }, + { + description: "PBSResponsePreparationDuration-is-not-set", + tmaxAdjustments: config.TmaxAdjustments{Enabled: true, BidderResponseDurationMin: 100, BidderNetworkLatencyBuffer: 10, PBSResponsePreparationDuration: 0}, + expected: &TmaxAdjustmentsPreprocessed{IsEnforced: true, BidderResponseDurationMin: 100, BidderNetworkLatencyBuffer: 10, PBSResponsePreparationDuration: 0}, + }, + } + for _, test := range tests { + t.Run(test.description, func(t *testing.T) { + assert.Equal(t, test.expected, ProcessTMaxAdjustments(test.tmaxAdjustments)) + }) + } +} diff --git a/router/router.go b/router/router.go index 8fc99589c22..12bfbf593f5 100644 --- a/router/router.go +++ b/router/router.go @@ -214,21 +214,22 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R glog.Fatalf("Failed to create ads cert signer: %v", err) } + tmaxAdjustments := exchange.ProcessTMaxAdjustments(cfg.TmaxAdjustments) planBuilder := hooks.NewExecutionPlanBuilder(cfg.Hooks, repo) macroReplacer := macros.NewStringIndexBasedReplacer() theExchange := exchange.NewExchange(adapters, cacheClient, cfg, syncersByBidder, r.MetricsEngine, cfg.BidderInfos, gdprPermsBuilder, rateConvertor, categoriesFetcher, adsCertSigner, macroReplacer) var uuidGenerator uuidutil.UUIDRandomGenerator - openrtbEndpoint, err := openrtb2.NewEndpoint(uuidGenerator, theExchange, paramsValidator, fetcher, accounts, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBidders, storedRespFetcher, planBuilder) + openrtbEndpoint, err := openrtb2.NewEndpoint(uuidGenerator, theExchange, paramsValidator, fetcher, accounts, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBidders, storedRespFetcher, planBuilder, tmaxAdjustments) if err != nil { glog.Fatalf("Failed to create the openrtb2 endpoint handler. %v", err) } - ampEndpoint, err := openrtb2.NewAmpEndpoint(uuidGenerator, theExchange, paramsValidator, ampFetcher, accounts, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBidders, storedRespFetcher, planBuilder) + ampEndpoint, err := openrtb2.NewAmpEndpoint(uuidGenerator, theExchange, paramsValidator, ampFetcher, accounts, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBidders, storedRespFetcher, planBuilder, tmaxAdjustments) if err != nil { glog.Fatalf("Failed to create the amp endpoint handler. %v", err) } - videoEndpoint, err := openrtb2.NewVideoEndpoint(uuidGenerator, theExchange, paramsValidator, fetcher, videoFetcher, accounts, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBidders, cacheClient) + videoEndpoint, err := openrtb2.NewVideoEndpoint(uuidGenerator, theExchange, paramsValidator, fetcher, videoFetcher, accounts, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBidders, cacheClient, tmaxAdjustments) if err != nil { glog.Fatalf("Failed to create the video endpoint handler. %v", err) } From abcb76de0a8d5484e567ec83c67c8f2fd724138b Mon Sep 17 00:00:00 2001 From: Piotr Jaworski <109736938+piotrj-rtbh@users.noreply.github.com> Date: Wed, 26 Jul 2023 07:39:10 +0200 Subject: [PATCH 038/268] RTB House: currency and floors support & config update (#2860) --- adapters/rtbhouse/rtbhouse.go | 78 ++++++++++- .../exemplary/currency-conversion.json | 123 ++++++++++++++++++ .../rtbhousetest/exemplary/simple-banner.json | 1 + .../supplemental/bad_response.json | 1 + .../currency-missing-conversion.json | 43 ++++++ .../rtbhousetest/supplemental/status_204.json | 1 + .../rtbhousetest/supplemental/status_400.json | 1 + .../rtbhousetest/supplemental/status_418.json | 1 + openrtb_ext/imp_rtbhouse.go | 10 ++ static/bidder-info/rtbhouse.yaml | 1 + static/bidder-params/rtbhouse.json | 12 ++ 11 files changed, 266 insertions(+), 6 deletions(-) create mode 100644 adapters/rtbhouse/rtbhousetest/exemplary/currency-conversion.json create mode 100644 adapters/rtbhouse/rtbhousetest/supplemental/currency-missing-conversion.json create mode 100644 openrtb_ext/imp_rtbhouse.go diff --git a/adapters/rtbhouse/rtbhouse.go b/adapters/rtbhouse/rtbhouse.go index c8afb0c4259..dc67df9aa2b 100644 --- a/adapters/rtbhouse/rtbhouse.go +++ b/adapters/rtbhouse/rtbhouse.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "net/http" + "strings" "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/adapters" @@ -12,6 +13,15 @@ import ( "github.com/prebid/prebid-server/openrtb_ext" ) +const ( + BidderCurrency string = "USD" +) + +// RTBHouseAdapter implements the Bidder interface. +type RTBHouseAdapter struct { + endpoint string +} + // Builder builds a new instance of the RTBHouse adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { bidder := &RTBHouseAdapter{ @@ -20,11 +30,6 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co return bidder, nil } -// RTBHouseAdapter implements the Bidder interface. -type RTBHouseAdapter struct { - endpoint string -} - // MakeRequests prepares the HTTP requests which should be made to fetch bids. func (adapter *RTBHouseAdapter) MakeRequests( openRTBRequest *openrtb2.BidRequest, @@ -33,7 +38,48 @@ func (adapter *RTBHouseAdapter) MakeRequests( requestsToBidder []*adapters.RequestData, errs []error, ) { - openRTBRequestJSON, err := json.Marshal(openRTBRequest) + + reqCopy := *openRTBRequest + reqCopy.Imp = []openrtb2.Imp{} + for _, imp := range openRTBRequest.Imp { + var bidFloorCur = imp.BidFloorCur + var bidFloor = imp.BidFloor + if bidFloorCur == "" && bidFloor == 0 { + rtbhouseExt, err := getImpressionExt(imp) + if err != nil { + return nil, []error{err} + } + if rtbhouseExt.BidFloor > 0 && len(reqCopy.Cur) > 0 { + bidFloorCur = reqCopy.Cur[0] + bidFloor = rtbhouseExt.BidFloor + } + } + + // Check if imp comes with bid floor amount defined in a foreign currency + if bidFloor > 0 && bidFloorCur != "" && strings.ToUpper(bidFloorCur) != BidderCurrency { + // Convert to US dollars + convertedValue, err := reqInfo.ConvertCurrency(bidFloor, bidFloorCur, BidderCurrency) + if err != nil { + return nil, []error{err} + } + + bidFloorCur = BidderCurrency + bidFloor = convertedValue + } + + if bidFloor > 0 && bidFloorCur == BidderCurrency { + // Update after conversion. All imp elements inside request.Imp are shallow copies + // therefore, their non-pointer values are not shared memory and are safe to modify. + imp.BidFloorCur = bidFloorCur + imp.BidFloor = bidFloor + } + + // Set the CUR of bid to BIDDER_CURRENCY after converting all floors + reqCopy.Cur = []string{BidderCurrency} + reqCopy.Imp = append(reqCopy.Imp, imp) + } + + openRTBRequestJSON, err := json.Marshal(reqCopy) if err != nil { errs = append(errs, err) return nil, errs @@ -52,6 +98,24 @@ func (adapter *RTBHouseAdapter) MakeRequests( return requestsToBidder, errs } +func getImpressionExt(imp openrtb2.Imp) (*openrtb_ext.ExtImpRTBHouse, error) { + var bidderExt adapters.ExtImpBidder + if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + return nil, &errortypes.BadInput{ + Message: "Bidder extension not provided or can't be unmarshalled", + } + } + + var rtbhouseExt openrtb_ext.ExtImpRTBHouse + if err := json.Unmarshal(bidderExt.Bidder, &rtbhouseExt); err != nil { + return nil, &errortypes.BadInput{ + Message: "Error while unmarshaling bidder extension", + } + } + + return &rtbhouseExt, nil +} + const unexpectedStatusCodeFormat = "" + "Unexpected status code: %d. Run with request.debug = 1 for more info" @@ -97,6 +161,8 @@ func (adapter *RTBHouseAdapter) MakeBids( } } + bidderResponse.Currency = BidderCurrency + return bidderResponse, nil } diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/currency-conversion.json b/adapters/rtbhouse/rtbhousetest/exemplary/currency-conversion.json new file mode 100644 index 00000000000..95bfb1e4420 --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/exemplary/currency-conversion.json @@ -0,0 +1,123 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "bidfloor": 1.00, + "bidfloorcur": "EUR", + "ext": { + "bidder": { + "placementId": "12345" + } + } + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server", + "body": { + "id": "test-request-id", + "cur": ["USD"], + "imp": [ + { + "banner": { + "format": [ + { + "h": 250, + "w": 300 + } + ] + }, + "bidfloor": 0.05, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "placementId": "12345" + } + }, + "id": "test-imp-id" + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "cur": "USD", + "seatbid": [{ + "seat": "rtbhouse", + "bid": [{ + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300 + } + ] + }] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300 + }, + "type": "banner" + } + ] + } + ] + } diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json b/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json index 3a636450f3c..2a8c4681ffa 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json @@ -23,6 +23,7 @@ "uri": "http://localhost/prebid_server", "body": { "id": "test-request-id", + "cur": ["USD"], "site": { "page": "https://good.site/url" }, diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/bad_response.json b/adapters/rtbhouse/rtbhousetest/supplemental/bad_response.json index f84f5555259..e0861fb027d 100644 --- a/adapters/rtbhouse/rtbhousetest/supplemental/bad_response.json +++ b/adapters/rtbhouse/rtbhousetest/supplemental/bad_response.json @@ -26,6 +26,7 @@ "uri": "http://localhost/prebid_server", "body": { "id": "test-request-id", + "cur": ["USD"], "imp": [ { "id": "test-imp-id", diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/currency-missing-conversion.json b/adapters/rtbhouse/rtbhousetest/supplemental/currency-missing-conversion.json new file mode 100644 index 00000000000..d7d65e43e76 --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/supplemental/currency-missing-conversion.json @@ -0,0 +1,43 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "banner-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "bidfloor": 1.00, + "bidfloorcur": "JPY", + "ext": { + "bidder": { + "placement": "12345" + } + } + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "MXN": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "Currency conversion rate not found: 'JPY' => 'USD'", + "comparison": "literal" + } + ] + } diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/status_204.json b/adapters/rtbhouse/rtbhousetest/supplemental/status_204.json index 0702c103332..bb7754ec1fc 100644 --- a/adapters/rtbhouse/rtbhousetest/supplemental/status_204.json +++ b/adapters/rtbhouse/rtbhousetest/supplemental/status_204.json @@ -26,6 +26,7 @@ "uri": "http://localhost/prebid_server", "body": { "id": "test-request-id", + "cur": ["USD"], "imp": [ { "id": "test-imp-id", diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/status_400.json b/adapters/rtbhouse/rtbhousetest/supplemental/status_400.json index 65d21406bf0..0b5279326d2 100644 --- a/adapters/rtbhouse/rtbhousetest/supplemental/status_400.json +++ b/adapters/rtbhouse/rtbhousetest/supplemental/status_400.json @@ -26,6 +26,7 @@ "uri": "http://localhost/prebid_server", "body": { "id": "test-request-id", + "cur": ["USD"], "imp": [ { "id": "test-imp-id", diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/status_418.json b/adapters/rtbhouse/rtbhousetest/supplemental/status_418.json index 4c5dd576aa6..6ff3860ee65 100644 --- a/adapters/rtbhouse/rtbhousetest/supplemental/status_418.json +++ b/adapters/rtbhouse/rtbhousetest/supplemental/status_418.json @@ -26,6 +26,7 @@ "uri": "http://localhost/prebid_server", "body": { "id": "test-request-id", + "cur": ["USD"], "imp": [ { "id": "test-imp-id", diff --git a/openrtb_ext/imp_rtbhouse.go b/openrtb_ext/imp_rtbhouse.go new file mode 100644 index 00000000000..747ea158f9d --- /dev/null +++ b/openrtb_ext/imp_rtbhouse.go @@ -0,0 +1,10 @@ +package openrtb_ext + +// ExtImpRTBHouse defines the contract for bidrequest.imp[i].ext.prebid.bidder.rtbhouse +type ExtImpRTBHouse struct { + PublisherId string `json:"publisherId"` + Region string `json:"region"` + + BidFloor float64 `json:"bidfloor,omitempty"` + Channel string `json:"channel,omitempty"` +} diff --git a/static/bidder-info/rtbhouse.yaml b/static/bidder-info/rtbhouse.yaml index 6a116448f22..ad2fbfcbc95 100644 --- a/static/bidder-info/rtbhouse.yaml +++ b/static/bidder-info/rtbhouse.yaml @@ -1,6 +1,7 @@ endpoint: "http://prebidserver-s2s-ams.creativecdn.com/bidder/prebidserver/bids" maintainer: email: "prebid@rtbhouse.com" +endpointCompression: gzip gvlVendorID: 16 capabilities: site: diff --git a/static/bidder-params/rtbhouse.json b/static/bidder-params/rtbhouse.json index 00732bedd2f..727f51bcc30 100644 --- a/static/bidder-params/rtbhouse.json +++ b/static/bidder-params/rtbhouse.json @@ -7,6 +7,18 @@ "publisherId": { "type": "string", "description": "The publisher’s ID provided by RTB House" + }, + "region": { + "type": "string", + "description": "The publisher’s assigned datacenter region" + }, + "bidfloor": { + "type": "number", + "description": "(optional) Minimum bid price in CPM that will be considered" + }, + "channel": { + "type": "string", + "description": "Inventory channel identifier, limited to 50 characters" } }, "required": ["publisherId"] From 74cce61af15f133038565d691ad5327d9f165c0c Mon Sep 17 00:00:00 2001 From: Maksim Kislyakov Date: Wed, 26 Jul 2023 10:27:41 +0300 Subject: [PATCH 039/268] New adapter: Vox (#2928) --- adapters/vox/params_test.go | 56 ++++++++++++ adapters/vox/vox.go | 86 ++++++++++++++++++ adapters/vox/vox_test.go | 21 +++++ adapters/vox/voxtest/exemplary/banner.json | 82 +++++++++++++++++ adapters/vox/voxtest/exemplary/video.json | 87 +++++++++++++++++++ .../response_204_to_nocontent.json | 45 ++++++++++ .../supplemental/response_500_to_error.json | 56 ++++++++++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_vox.go | 7 ++ static/bidder-info/vox.yaml | 19 ++++ static/bidder-params/vox.json | 27 ++++++ 12 files changed, 490 insertions(+) create mode 100644 adapters/vox/params_test.go create mode 100644 adapters/vox/vox.go create mode 100644 adapters/vox/vox_test.go create mode 100644 adapters/vox/voxtest/exemplary/banner.json create mode 100644 adapters/vox/voxtest/exemplary/video.json create mode 100644 adapters/vox/voxtest/supplemental/response_204_to_nocontent.json create mode 100644 adapters/vox/voxtest/supplemental/response_500_to_error.json create mode 100644 openrtb_ext/imp_vox.go create mode 100644 static/bidder-info/vox.yaml create mode 100644 static/bidder-params/vox.json diff --git a/adapters/vox/params_test.go b/adapters/vox/params_test.go new file mode 100644 index 00000000000..be148d3b32d --- /dev/null +++ b/adapters/vox/params_test.go @@ -0,0 +1,56 @@ +package vox + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range validParams { + if err := validator.Validate(openrtb_ext.BidderVox, json.RawMessage(p)); err != nil { + t.Errorf("Schema rejected valid params: %s", p) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderVox, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} + +var validParams = []string{ + `{"placementId": "64be6fe6685a271d37e900d2"}`, + `{"placementId": "Any String Basically"}`, + `{"placementId":""}`, + `{"placementId":"id", "imageUrl":"http://site.com/img1.png"}`, + `{"placementId":"id", "imageUrl":"http://site.com/img1.png", "displaySizes":["123x90", "1x1", "987x1111"]}`, +} + +var invalidParams = []string{ + `{"placementId": 42}`, + `{"placementId": null}`, + `{"placementId": 3.1415}`, + `{"placementId": true}`, + `{"placementId": false}`, + `{"placementId":"id", "imageUrl": null}`, + `{"placementId":"id", "imageUrl": true}`, + `{"placementId":"id", "imageUrl": []}`, + `{"placementId":"id", "imageUrl": "http://some.url", "displaySizes": null}`, + `{"placementId":"id", "imageUrl": "http://some.url", "displaySizes": {}}`, + `{"placementId":"id", "imageUrl": "http://some.url", "displaySizes": "String"}`, +} diff --git a/adapters/vox/vox.go b/adapters/vox/vox.go new file mode 100644 index 00000000000..0b56fcbf9d7 --- /dev/null +++ b/adapters/vox/vox.go @@ -0,0 +1,86 @@ +package vox + +import ( + "encoding/json" + "fmt" + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +type adapter struct { + endpoint string +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + requestJSON, err := json.Marshal(request) + if err != nil { + return nil, []error{err} + } + + requestData := &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: requestJSON, + } + + return []*adapters.RequestData{requestData}, nil +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} + } + + var response openrtb2.BidResponse + if err := json.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + bidResponse.Currency = response.Cur + + for _, seatBid := range response.SeatBid { + for i, bid := range seatBid.Bid { + bidType, err := getMediaTypeForBid(bid) + if err != nil { + return nil, []error{err} + } + + b := &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + } + + return bidResponse, nil +} + +func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupAudio: + return openrtb_ext.BidTypeAudio, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + return "", fmt.Errorf("Unable to fetch mediaType in multi-format: %s", bid.ImpID) + } +} diff --git a/adapters/vox/vox_test.go b/adapters/vox/vox_test.go new file mode 100644 index 00000000000..95d11a8ad79 --- /dev/null +++ b/adapters/vox/vox_test.go @@ -0,0 +1,21 @@ +package vox + +import ( + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderVox, config.Adapter{ + Endpoint: "http://somecoolurlfor.vox"}, + config.Server{ExternalUrl: "http://somecoolurlfor.vox", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error: %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "voxtest", bidder) +} diff --git a/adapters/vox/voxtest/exemplary/banner.json b/adapters/vox/voxtest/exemplary/banner.json new file mode 100644 index 00000000000..898fcea4826 --- /dev/null +++ b/adapters/vox/voxtest/exemplary/banner.json @@ -0,0 +1,82 @@ +{ + "mockBidRequest": { + "id": "cf4b0abb-7ccc-4057-9914-c85f467260c6", + "site": { + "page": "http://some.site/url/page?id=338" + }, + "cur": [ "USD" ], + "imp": [{ + "id": "8a7510f9-0ca1-44c4-a8c6-1ce639b5eef9", + "banner": { "w": 100, "h": 100 }, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "placementId":"64b939146d66df22ccae95c5" + } + } + }] + }, + + "httpCalls": [{ + "expectedRequest": { + "uri": "http://somecoolurlfor.vox", + "headers": {}, + "body": { + "id": "cf4b0abb-7ccc-4057-9914-c85f467260c6", + "site": { + "page": "http://some.site/url/page?id=338" + }, + "imp": [ + { + "id": "8a7510f9-0ca1-44c4-a8c6-1ce639b5eef9", + "banner": { + "w": 100, + "h": 100 + }, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "placementId": "64b939146d66df22ccae95c5" + } + } + } + ], + "cur": [ "USD" ] + } + }, + "mockResponse": { + "status": 200, + "headers": {}, + "body": { + "id": "cf4b0abb-7ccc-4057-9914-c85f467260c6", + "cur": "USD", + "seatbid": [{ + "bid": [{ + "id": "e6a143f3-5176-4607-b09e-0e67e358b0b6", + "impid": "8a7510f9-0ca1-44c4-a8c6-1ce639b5eef9", + "price": 3.1415, + "adm": "

Hi, there

", + "w": 50, + "h": 50, + "mtype": 1 + }] + }] + }} + }], + + "expectedBidResponses": [{ + "bids": [{ + "currency": "USD", + "bid": { + "id": "e6a143f3-5176-4607-b09e-0e67e358b0b6", + "impid": "8a7510f9-0ca1-44c4-a8c6-1ce639b5eef9", + "price": 3.1415, + "adm": "

Hi, there

", + "w": 50, + "h": 50, + "mtype": 1 + }, + "type": "banner" + }] + }] +} \ No newline at end of file diff --git a/adapters/vox/voxtest/exemplary/video.json b/adapters/vox/voxtest/exemplary/video.json new file mode 100644 index 00000000000..37464da1aec --- /dev/null +++ b/adapters/vox/voxtest/exemplary/video.json @@ -0,0 +1,87 @@ +{ + "mockBidRequest": { + "id": "9a4bdb67-43ef-488f-937d-cd01e9dce43d", + "site": { + "page": "http://blog.com/article/1" + }, + "cur": ["PLN"], + "imp": [{ + "id": "d190d6f3-5264-4df5-91b2-8a9c72cbeb6a", + "bidfloorcur": "PLN", + "video": { + "mimes": ["video/mp4"], + "minduration": 5, + "maxduration": 15, + "w": 1280, + "h": 720 + }, + "ext": { + "bidder": { + "placementId":"64b9486efecad2330718e233" + } + } + }] + }, + + "httpCalls": [{ + "expectedRequest": { + "uri": "http://somecoolurlfor.vox", + "header": {}, + "body": { + "id": "9a4bdb67-43ef-488f-937d-cd01e9dce43d", + "site": { + "page": "http://blog.com/article/1" + }, + "cur": [ "PLN" ], + "imp": [{ + "id": "d190d6f3-5264-4df5-91b2-8a9c72cbeb6a", + "bidfloorcur": "PLN", + "video": { + "mimes": ["video/mp4"], + "minduration": 5, + "maxduration": 15, + "w": 1280, + "h": 720 + }, + "ext": { + "bidder": { + "placementId":"64b9486efecad2330718e233" + } + } + }] + } + }, + + "mockResponse": { + "status": 200, + "headers": {}, + "body": { + "id":"d64fdeae-cb1c-4322-8fb6-18f5ec49bb76", + "cur": "PLN", + "seatbid": [{ + "bid": [{ + "id": "05349123-29e2-4be0-b662-48914f75ebe1", + "impid": "d190d6f3-5264-4df5-91b2-8a9c72cbeb6a", + "price": 2.149, + "adm": "...", + "mtype": 2 + }] + }] + } + } + }], + + "expectedBidResponses": [{ + "bids": [{ + "currency": "PLN", + "bid": { + "id": "05349123-29e2-4be0-b662-48914f75ebe1", + "impid": "d190d6f3-5264-4df5-91b2-8a9c72cbeb6a", + "price": 2.149, + "adm": "...", + "mtype": 2 + }, + "type": "video" + }] + }] +} \ No newline at end of file diff --git a/adapters/vox/voxtest/supplemental/response_204_to_nocontent.json b/adapters/vox/voxtest/supplemental/response_204_to_nocontent.json new file mode 100644 index 00000000000..0a49b85d612 --- /dev/null +++ b/adapters/vox/voxtest/supplemental/response_204_to_nocontent.json @@ -0,0 +1,45 @@ +{ + "mockBidRequest": { + "id": "Some Id (445455)", + "cur": ["AUD"], + "imp": [{ + "id": "Impression id #1", + "banner": {}, + "bidfloorcur": "AUD", + "ext": { + "bidder": { + "placementId": "64b94ad4ed136806629dd51c" + } + } + }] + }, + + "httpCalls": [{ + "expectedRequest": { + "uri": "http://somecoolurlfor.vox", + "headers": {}, + "body": { + "id": "Some Id (445455)", + "cur": ["AUD"], + "imp": [{ + "id": "Impression id #1", + "banner": {}, + "bidfloorcur": "AUD", + "ext": { + "bidder": { + "placementId": "64b94ad4ed136806629dd51c" + } + } + }] + } + }, + + "mockResponse": { + "status": 204, + "headers": {}, + "body": {} + } + }], + + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/vox/voxtest/supplemental/response_500_to_error.json b/adapters/vox/voxtest/supplemental/response_500_to_error.json new file mode 100644 index 00000000000..f245ef45c99 --- /dev/null +++ b/adapters/vox/voxtest/supplemental/response_500_to_error.json @@ -0,0 +1,56 @@ +{ + "mockBidRequest": { + "id": "It is hard to make up ids.", + "site": { + "page": "http://catsanddogs.com/article/887" + }, + "cur": ["USD"], + "imp": [{ + "id": "Impression id #4", + "bidfloorcur": "USD", + "video": { "w": 1280, "h": 720, "mimes": ["video/mp4"] }, + "ext": { + "bidder": { + "placementId": "64b94ca2b5eb3605e0a0e3be" + } + } + }] + }, + + "httpCalls": [{ + "expectedRequest": { + "uri": "http://somecoolurlfor.vox", + "heades": {}, + "body": { + "id": "It is hard to make up ids.", + "site": { + "page": "http://catsanddogs.com/article/887" + }, + "cur": ["USD"], + "imp": [{ + "id": "Impression id #4", + "bidfloorcur": "USD", + "video": { "w": 1280, "h": 720, "mimes": ["video/mp4"] }, + "ext": { + "bidder": { + "placementId": "64b94ca2b5eb3605e0a0e3be" + } + } + }] + } + }, + + "mockResponse": { + "status": 500, + "headers": {}, + "body": {} + } + }], + + "expectedBidResponses": [], + + "expectedMakeBidsErrors": [{ + "value": "Unexpected status code: 500", + "comparison": "regex" + }] +} \ No newline at end of file diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index f83445256d6..6d0a4d8019a 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -169,6 +169,7 @@ import ( "github.com/prebid/prebid-server/adapters/vidoomy" "github.com/prebid/prebid-server/adapters/visiblemeasures" "github.com/prebid/prebid-server/adapters/visx" + "github.com/prebid/prebid-server/adapters/vox" "github.com/prebid/prebid-server/adapters/vrtcal" "github.com/prebid/prebid-server/adapters/xeworks" "github.com/prebid/prebid-server/adapters/yahooAds" @@ -369,6 +370,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderViewdeos: adtelligent.Builder, openrtb_ext.BidderVisibleMeasures: visiblemeasures.Builder, openrtb_ext.BidderVisx: visx.Builder, + openrtb_ext.BidderVox: vox.Builder, openrtb_ext.BidderVrtcal: vrtcal.Builder, openrtb_ext.BidderXeworks: xeworks.Builder, openrtb_ext.BidderYahooAds: yahooAds.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 978af5e0118..a43861ddc49 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -269,6 +269,7 @@ const ( BidderViewdeos BidderName = "viewdeos" BidderVisibleMeasures BidderName = "visiblemeasures" BidderVisx BidderName = "visx" + BidderVox BidderName = "vox" BidderVrtcal BidderName = "vrtcal" BidderXeworks BidderName = "xeworks" BidderYahooAds BidderName = "yahooAds" @@ -468,6 +469,7 @@ func CoreBidderNames() []BidderName { BidderViewdeos, BidderVisibleMeasures, BidderVisx, + BidderVox, BidderVrtcal, BidderXeworks, BidderYahooAds, diff --git a/openrtb_ext/imp_vox.go b/openrtb_ext/imp_vox.go new file mode 100644 index 00000000000..a61525077b3 --- /dev/null +++ b/openrtb_ext/imp_vox.go @@ -0,0 +1,7 @@ +package openrtb_ext + +type ImpExtVox struct { + PlacementID string `json:"placementId"` + ImageUrl string `json:"imageUrl"` + DisplaySizes []string `json:"displaySizes"` +} diff --git a/static/bidder-info/vox.yaml b/static/bidder-info/vox.yaml new file mode 100644 index 00000000000..e2b5c902be6 --- /dev/null +++ b/static/bidder-info/vox.yaml @@ -0,0 +1,19 @@ +endpoint: "https://ssp.hybrid.ai/prebid/server/v1/auction" +maintainer: + email: prebid@hybrid.ai +endpointCompression: gzip +gvlVendorID: 206 +modifyingVastXmlAllowed: true +capabilities: + site: + mediaTypes: + - banner + - video + app: + mediaTypes: + - banner + - video +userSync: + redirect: + url: "https://ssp.hybrid.ai/prebid/server/v1/userSync?consent={{.GDPRConsent}}&redirect={{.RedirectURL}}" + userMacro: $UID \ No newline at end of file diff --git a/static/bidder-params/vox.json b/static/bidder-params/vox.json new file mode 100644 index 00000000000..2ae65e99fc7 --- /dev/null +++ b/static/bidder-params/vox.json @@ -0,0 +1,27 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Vox Adapter Params", + "description": "A schema which validates params accepted by the Vox adapter", + "type": "object", + + "properties": { + "placementId": { + "type": "string", + "description": "Placement ID" + }, + "imageUrl": { + "type": "string", + "description": "An URL of image on which banner should be put(InImage Ad format)." + }, + "displaySizes": { + "type": "array", + "items": { + "type": "string", + "description": "x(Example: 123x90, 720x100)" + }, + "description": "Display banner sizes which could be shown on top of image." + } + }, + + "required": ["placementId"] +} \ No newline at end of file From 23bed063b947b15dfbdc7810f300d0ce660f4aa1 Mon Sep 17 00:00:00 2001 From: radubarbos Date: Wed, 26 Jul 2023 13:24:15 +0300 Subject: [PATCH 040/268] Brightroll: Remove Bidder (#2894) Co-authored-by: oath-jac --- adapters/brightroll/brightroll.go | 263 ------------------ adapters/brightroll/brightroll_test.go | 73 ----- .../exemplary/banner-native-audio.json | 169 ----------- .../exemplary/banner-video-native.json | 176 ------------ .../exemplary/banner-video.json | 152 ---------- .../exemplary/simple-banner.json | 119 -------- .../exemplary/simple-video.json | 98 ------- .../exemplary/valid-extension.json | 96 ------- .../exemplary/video-and-audio.json | 121 -------- .../supplemental/invalid-extension.json | 31 --- .../supplemental/invalid-imp.json | 16 -- .../supplemental/invalid-publisher.json | 34 --- .../supplemental/missing-extension.json | 22 -- .../supplemental/missing-param.json | 34 --- adapters/brightroll/params_test.go | 62 ----- adapters/gamma/params_test.go | 2 - config/config_test.go | 1 - endpoints/openrtb2/auction_test.go | 8 +- exchange/adapter_builders.go | 2 - exchange/adapter_util.go | 1 + exchange/adapter_util_test.go | 4 + exchange/utils_test.go | 25 +- openrtb_ext/bidders.go | 2 - openrtb_ext/imp_brightroll.go | 6 - static/bidder-info/brightroll.yaml | 17 -- static/bidder-params/brightroll.json | 13 - 26 files changed, 17 insertions(+), 1530 deletions(-) delete mode 100644 adapters/brightroll/brightroll.go delete mode 100644 adapters/brightroll/brightroll_test.go delete mode 100644 adapters/brightroll/brightrolltest/exemplary/banner-native-audio.json delete mode 100644 adapters/brightroll/brightrolltest/exemplary/banner-video-native.json delete mode 100644 adapters/brightroll/brightrolltest/exemplary/banner-video.json delete mode 100644 adapters/brightroll/brightrolltest/exemplary/simple-banner.json delete mode 100644 adapters/brightroll/brightrolltest/exemplary/simple-video.json delete mode 100644 adapters/brightroll/brightrolltest/exemplary/valid-extension.json delete mode 100644 adapters/brightroll/brightrolltest/exemplary/video-and-audio.json delete mode 100644 adapters/brightroll/brightrolltest/supplemental/invalid-extension.json delete mode 100644 adapters/brightroll/brightrolltest/supplemental/invalid-imp.json delete mode 100644 adapters/brightroll/brightrolltest/supplemental/invalid-publisher.json delete mode 100644 adapters/brightroll/brightrolltest/supplemental/missing-extension.json delete mode 100644 adapters/brightroll/brightrolltest/supplemental/missing-param.json delete mode 100644 adapters/brightroll/params_test.go delete mode 100644 openrtb_ext/imp_brightroll.go delete mode 100644 static/bidder-info/brightroll.yaml delete mode 100644 static/bidder-params/brightroll.json diff --git a/adapters/brightroll/brightroll.go b/adapters/brightroll/brightroll.go deleted file mode 100644 index a917fe87277..00000000000 --- a/adapters/brightroll/brightroll.go +++ /dev/null @@ -1,263 +0,0 @@ -package brightroll - -import ( - "encoding/json" - "fmt" - "net/http" - "strconv" - - "github.com/prebid/openrtb/v19/adcom1" - "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" -) - -type BrightrollAdapter struct { - URI string - extraInfo ExtraInfo -} - -type ExtraInfo struct { - Accounts []Account `json:"accounts"` -} - -type Account struct { - ID string `json:"id"` - Badv []string `json:"badv"` - Bcat []string `json:"bcat"` - Battr []int8 `json:"battr"` - BidFloor float64 `json:"bidfloor"` -} - -func (a *BrightrollAdapter) MakeRequests(requestIn *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - - request := *requestIn - errs := make([]error, 0, len(request.Imp)) - if len(request.Imp) == 0 { - err := &errortypes.BadInput{ - Message: "No impression in the bid request", - } - errs = append(errs, err) - return nil, errs - } - - errors := make([]error, 0, 1) - - var bidderExt adapters.ExtImpBidder - err := json.Unmarshal(request.Imp[0].Ext, &bidderExt) - if err != nil { - err = &errortypes.BadInput{ - Message: "ext.bidder not provided", - } - errors = append(errors, err) - return nil, errors - } - var brightrollExt openrtb_ext.ExtImpBrightroll - err = json.Unmarshal(bidderExt.Bidder, &brightrollExt) - if err != nil { - err = &errortypes.BadInput{ - Message: "ext.bidder.publisher not provided", - } - errors = append(errors, err) - return nil, errors - } - if brightrollExt.Publisher == "" { - err = &errortypes.BadInput{ - Message: "publisher is empty", - } - errors = append(errors, err) - return nil, errors - } - - var account *Account - for _, a := range a.extraInfo.Accounts { - if a.ID == brightrollExt.Publisher { - account = &a - break - } - } - - if account == nil { - err = &errortypes.BadInput{ - Message: "Invalid publisher", - } - errors = append(errors, err) - return nil, errors - } - - validImpExists := false - for i := 0; i < len(request.Imp); i++ { - //Brightroll supports only banner and video impressions as of now - if request.Imp[i].Banner != nil { - bannerCopy := *request.Imp[i].Banner - if bannerCopy.W == nil && bannerCopy.H == nil && len(bannerCopy.Format) > 0 { - firstFormat := bannerCopy.Format[0] - bannerCopy.W = &(firstFormat.W) - bannerCopy.H = &(firstFormat.H) - } - - if len(account.Battr) > 0 { - bannerCopy.BAttr = getBlockedCreativetypes(account.Battr) - } - request.Imp[i].Banner = &bannerCopy - validImpExists = true - } else if request.Imp[i].Video != nil { - validImpExists = true - if brightrollExt.Publisher == "adthrive" { - videoCopy := *request.Imp[i].Video - if len(account.Battr) > 0 { - videoCopy.BAttr = getBlockedCreativetypes(account.Battr) - } - request.Imp[i].Video = &videoCopy - } - } - if validImpExists && request.Imp[i].BidFloor == 0 && account.BidFloor > 0 { - request.Imp[i].BidFloor = account.BidFloor - } - } - if !validImpExists { - err := &errortypes.BadInput{ - Message: fmt.Sprintf("No valid impression in the bid request"), - } - errs = append(errs, err) - return nil, errs - } - - request.AT = 1 //Defaulting to first price auction for all prebid requests - - if len(account.Bcat) > 0 { - request.BCat = account.Bcat - } - - if len(account.Badv) > 0 { - request.BAdv = account.Badv - } - reqJSON, err := json.Marshal(request) - if err != nil { - errs = append(errs, err) - return nil, errs - } - thisURI := a.URI - thisURI = thisURI + "?publisher=" + brightrollExt.Publisher - headers := http.Header{} - headers.Add("Content-Type", "application/json;charset=utf-8") - headers.Add("Accept", "application/json") - headers.Add("x-openrtb-version", "2.5") - - if request.Device != nil { - addHeaderIfNonEmpty(headers, "User-Agent", request.Device.UA) - addHeaderIfNonEmpty(headers, "X-Forwarded-For", request.Device.IP) - addHeaderIfNonEmpty(headers, "Accept-Language", request.Device.Language) - if request.Device.DNT != nil { - addHeaderIfNonEmpty(headers, "DNT", strconv.Itoa(int(*request.Device.DNT))) - } - } - - return []*adapters.RequestData{{ - Method: "POST", - Uri: thisURI, - Body: reqJSON, - Headers: headers, - }}, errors -} - -func (a *BrightrollAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { - - if response.StatusCode == http.StatusNoContent { - return nil, nil - } - - if response.StatusCode == http.StatusBadRequest { - return nil, []error{&errortypes.BadInput{ - Message: fmt.Sprintf("Unexpected status code: %d. ", response.StatusCode), - }} - } - - if response.StatusCode != http.StatusOK { - return nil, []error{&errortypes.BadServerResponse{ - Message: fmt.Sprintf("unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), - }} - } - - var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { - return nil, []error{&errortypes.BadServerResponse{ - Message: fmt.Sprintf("bad server response: %d. ", err), - }} - } - - bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(bidResp.SeatBid[0].Bid)) - sb := bidResp.SeatBid[0] - for i := 0; i < len(sb.Bid); i++ { - bid := sb.Bid[i] - bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ - Bid: &bid, - BidType: getMediaTypeForImp(bid.ImpID, internalRequest.Imp), - }) - } - return bidResponse, nil -} - -func getBlockedCreativetypes(attr []int8) []adcom1.CreativeAttribute { - var creativeAttr []adcom1.CreativeAttribute - for i := 0; i < len(attr); i++ { - creativeAttr = append(creativeAttr, adcom1.CreativeAttribute(attr[i])) - } - return creativeAttr -} - -// Adding header fields to request header -func addHeaderIfNonEmpty(headers http.Header, headerName string, headerValue string) { - if len(headerValue) > 0 { - headers.Add(headerName, headerValue) - } -} - -// getMediaTypeForImp figures out which media type this bid is for. -func getMediaTypeForImp(impId string, imps []openrtb2.Imp) openrtb_ext.BidType { - mediaType := openrtb_ext.BidTypeBanner //default type - for _, imp := range imps { - if imp.ID == impId { - if imp.Video != nil { - mediaType = openrtb_ext.BidTypeVideo - } - return mediaType - } - } - return mediaType -} - -// Builder builds a new instance of the Brightroll adapter for the given bidder with the given config. -func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { - extraInfo, err := getExtraInfo(config.ExtraAdapterInfo) - if err != nil { - return nil, err - } - - bidder := &BrightrollAdapter{ - URI: config.Endpoint, - extraInfo: extraInfo, - } - return bidder, nil -} - -func getExtraInfo(v string) (ExtraInfo, error) { - if len(v) == 0 { - return getDefaultExtraInfo(), nil - } - - var extraInfo ExtraInfo - if err := json.Unmarshal([]byte(v), &extraInfo); err != nil { - return extraInfo, fmt.Errorf("invalid extra info: %v", err) - } - - return extraInfo, nil -} - -func getDefaultExtraInfo() ExtraInfo { - return ExtraInfo{ - Accounts: []Account{}, - } -} diff --git a/adapters/brightroll/brightroll_test.go b/adapters/brightroll/brightroll_test.go deleted file mode 100644 index 4cf0f46fda7..00000000000 --- a/adapters/brightroll/brightroll_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package brightroll - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" -) - -func TestEmptyConfig(t *testing.T) { - bidder, buildErr := Builder(openrtb_ext.BidderBrightroll, config.Adapter{ - Endpoint: `http://test-bid.ybp.yahoo.com/bid/appnexuspbs`, - ExtraAdapterInfo: ``, - }, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - if buildErr != nil { - t.Fatalf("Builder returned unexpected error %v", buildErr) - } - - ex := ExtraInfo{ - Accounts: []Account{}, - } - expected := &BrightrollAdapter{ - URI: "http://test-bid.ybp.yahoo.com/bid/appnexuspbs", - extraInfo: ex, - } - assert.Equal(t, expected, bidder) -} - -func TestNonEmptyConfig(t *testing.T) { - bidder, buildErr := Builder(openrtb_ext.BidderBrightroll, config.Adapter{ - Endpoint: `http://test-bid.ybp.yahoo.com/bid/appnexuspbs`, - ExtraAdapterInfo: `{"accounts": [{"id": "test","bidfloor":0.1}]}`, - }, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - if buildErr != nil { - t.Fatalf("Builder returned unexpected error %v", buildErr) - } - - ex := ExtraInfo{ - Accounts: []Account{{ID: "test", BidFloor: 0.1}}, - } - expected := &BrightrollAdapter{ - URI: "http://test-bid.ybp.yahoo.com/bid/appnexuspbs", - extraInfo: ex, - } - assert.Equal(t, expected, bidder) -} - -func TestMalformedEmpty(t *testing.T) { - _, buildErr := Builder(openrtb_ext.BidderBrightroll, config.Adapter{ - Endpoint: `http://test-bid.ybp.yahoo.com/bid/appnexuspbs`, - ExtraAdapterInfo: `malformed`, - }, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - assert.Error(t, buildErr) -} - -func TestJsonSamples(t *testing.T) { - bidder, buildErr := Builder(openrtb_ext.BidderBrightroll, config.Adapter{ - Endpoint: `http://test-bid.ybp.yahoo.com/bid/appnexuspbs`, - ExtraAdapterInfo: `{"accounts": [{"id": "adthrive","badv": [], "bcat": ["IAB8-5","IAB8-18"],"battr": [1,2,3], "bidfloor":0.0}]}`, - }, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - if buildErr != nil { - t.Fatalf("Builder returned unexpected error %v", buildErr) - } - - adapterstest.RunJSONBidderTest(t, "brightrolltest", bidder) -} diff --git a/adapters/brightroll/brightrolltest/exemplary/banner-native-audio.json b/adapters/brightroll/brightrolltest/exemplary/banner-native-audio.json deleted file mode 100644 index f67fa259c6d..00000000000 --- a/adapters/brightroll/brightrolltest/exemplary/banner-native-audio.json +++ /dev/null @@ -1,169 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - }, - { - "id": "unsupported-native-imp", - "native": { - "ver": "1.1", - "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}" - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - }, - { - "id": "unsupported-audio-imp", - "audio": { - "mimes": [ - "video/mp4" - ] - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://test-bid.ybp.yahoo.com/bid/appnexuspbs?publisher=adthrive", - "body": { - "id": "test-request-id", - "at":1, - "bcat": [ - "IAB8-5", - "IAB8-18" - ], - "imp": [ - { - "id": "test-imp-id", - "banner": { - "battr": [ - 1, - 2, - 3 - ], - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ], - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - }, - { - "id": "unsupported-native-imp", - "native": { - "ver": "1.1", - "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}" - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - }, - { - "id": "unsupported-audio-imp", - "audio": { - "mimes": [ - "video/mp4" - ] - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "958", - "bid": [{ - "id": "7706636740145184841", - "impid": "test-imp-id", - "price": 0.500000, - "adid": "29681110", - "adm": "some-test-ad", - "adomain": ["yahoo.com"], - "cid": "958", - "crid": "29681110", - "h": 250, - "w": 300 - }] - } - ], - "bidid": "5778926625248726496", - "cur": "USD" - } - } - } - ], - - "expectedBidResponses": [ - { - "bids": [ - { - "bid": { - "id": "7706636740145184841", - "impid": "test-imp-id", - "price": 0.5, - "adm": "some-test-ad", - "adid": "29681110", - "adomain": ["yahoo.com"], - "cid": "958", - "crid": "29681110", - "w": 300, - "h": 250 - }, - "type": "banner" - } - ] - } - ] - -} diff --git a/adapters/brightroll/brightrolltest/exemplary/banner-video-native.json b/adapters/brightroll/brightrolltest/exemplary/banner-video-native.json deleted file mode 100644 index 97081b708d3..00000000000 --- a/adapters/brightroll/brightrolltest/exemplary/banner-video-native.json +++ /dev/null @@ -1,176 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - }, - { - "id": "unsupported-native-imp", - "native": { - "ver": "1.1", - "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}" - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - }, - { - "id": "test-imp-video-id", - "video": { - "mimes": ["video/mp4"], - "protocols": [2, 5], - "w": 1024, - "h": 576 - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://test-bid.ybp.yahoo.com/bid/appnexuspbs?publisher=adthrive", - "body": { - "id": "test-request-id", - "at":1, - "bcat": [ - "IAB8-5", - "IAB8-18" - ], - "imp": [ - { - "id": "test-imp-id", - "banner": { - "battr": [ - 1, - 2, - 3 - ], - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ], - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - }, - { - "id": "unsupported-native-imp", - "native": { - "ver": "1.1", - "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}" - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - }, - { - "id": "test-imp-video-id", - "video": { - "battr": [ - 1, - 2, - 3 - ], - "mimes": ["video/mp4"], - "protocols": [2, 5], - "w": 1024, - "h": 576 - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "958", - "bid": [{ - "id": "7706636740145184841", - "impid": "test-imp-video-id", - "price": 0.500000, - "adid": "29681110", - "adm": "some-test-ad", - "adomain": ["yahoo.com"], - "cid": "958", - "crid": "29681110", - "h": 576, - "w": 1024 - }] - } - ], - "bidid": "5778926625248726496", - "cur": "USD" - } - } - } - ], - - "expectedBidResponses": [ - { - "bids": [ - { - "bid": { - "id": "7706636740145184841", - "impid": "test-imp-video-id", - "price": 0.5, - "adm": "some-test-ad", - "adid": "29681110", - "adomain": ["yahoo.com"], - "cid": "958", - "crid": "29681110", - "w": 1024, - "h": 576 - }, - "type": "video" - } - ] - } - ] - -} diff --git a/adapters/brightroll/brightrolltest/exemplary/banner-video.json b/adapters/brightroll/brightrolltest/exemplary/banner-video.json deleted file mode 100644 index 17441152edc..00000000000 --- a/adapters/brightroll/brightrolltest/exemplary/banner-video.json +++ /dev/null @@ -1,152 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - }, - { - "id": "test-imp-video-id", - "video": { - "mimes": ["video/mp4"], - "protocols": [2, 5], - "w": 1024, - "h": 576 - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://test-bid.ybp.yahoo.com/bid/appnexuspbs?publisher=adthrive", - "body": { - "id": "test-request-id", - "at":1, - "bcat": [ - "IAB8-5", - "IAB8-18" - ], - "imp": [ - { - "id": "test-imp-id", - "banner": { - "battr": [ - 1, - 2, - 3 - ], - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ], - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - }, - { - "id": "test-imp-video-id", - "video": { - "battr": [ - 1, - 2, - 3 - ], - "mimes": ["video/mp4"], - "protocols": [2, 5], - "w": 1024, - "h": 576 - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "958", - "bid": [{ - "id": "7706636740145184841", - "impid": "test-imp-video-id", - "price": 0.500000, - "adid": "29681110", - "adm": "some-test-ad", - "adomain": ["yahoo.com"], - "cid": "958", - "crid": "29681110", - "h": 576, - "w": 1024 - }] - } - ], - "bidid": "5778926625248726496", - "cur": "USD" - } - } - } - ], - - "expectedBidResponses": [ - { - "bids": [ - { - "bid": { - "id": "7706636740145184841", - "impid": "test-imp-video-id", - "price": 0.5, - "adm": "some-test-ad", - "adid": "29681110", - "adomain": ["yahoo.com"], - "cid": "958", - "crid": "29681110", - "w": 1024, - "h": 576 - }, - "type": "video" - } - ] - } - ] - -} diff --git a/adapters/brightroll/brightrolltest/exemplary/simple-banner.json b/adapters/brightroll/brightrolltest/exemplary/simple-banner.json deleted file mode 100644 index f59038503cf..00000000000 --- a/adapters/brightroll/brightrolltest/exemplary/simple-banner.json +++ /dev/null @@ -1,119 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://test-bid.ybp.yahoo.com/bid/appnexuspbs?publisher=adthrive", - "body": { - "id": "test-request-id", - "at":1, - "bcat": [ - "IAB8-5", - "IAB8-18" - ], - "imp": [ - { - "id": "test-imp-id", - "banner": { - "battr": [ - 1, - 2, - 3 - ], - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ], - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "958", - "bid": [{ - "id": "7706636740145184841", - "impid": "test-imp-id", - "price": 0.500000, - "adid": "29681110", - "adm": "some-test-ad", - "adomain": ["yahoo.com"], - "cid": "958", - "crid": "29681110", - "h": 250, - "w": 300 - }] - } - ], - "bidid": "5778926625248726496", - "cur": "USD" - } - } - } - ], - - "expectedBidResponses": [ - { - "bids": [ - { - "bid": { - "id": "7706636740145184841", - "impid": "test-imp-id", - "price": 0.5, - "adm": "some-test-ad", - "adid": "29681110", - "adomain": ["yahoo.com"], - "cid": "958", - "crid": "29681110", - "w": 300, - "h": 250 - }, - "type": "banner" - } - ] - } - ] -} diff --git a/adapters/brightroll/brightrolltest/exemplary/simple-video.json b/adapters/brightroll/brightrolltest/exemplary/simple-video.json deleted file mode 100644 index 88539276043..00000000000 --- a/adapters/brightroll/brightrolltest/exemplary/simple-video.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "video": { - "mimes": ["video/mp4"], - "protocols": [2, 5], - "w": 1024, - "h": 576 - }, - "ext":{ - "bidder":{ - "publisher": "adthrive" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://test-bid.ybp.yahoo.com/bid/appnexuspbs?publisher=adthrive", - "body": { - "id": "test-request-id", - "at":1, - "bcat": [ - "IAB8-5", - "IAB8-18" - ], - "imp": [ - { - "id": "test-imp-id", - "video": { - "battr": [ - 1, - 2, - 3 - ], - "mimes": ["video/mp4"], - "protocols": [2, 5], - "w": 1024, - "h": 576 - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "cur": "USD", - "seatbid": [ - { - "seat": "Brightroll", - "bid": [{ - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id", - "price": 0.500000, - "adm": "some-test-ad", - "crid": "crid_10", - "w": 1024, - "h": 576 - }] - } - ] - } - } - } - ], - - "expectedBidResponses": [ - { - "bids": [ - { - "bid": { - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id", - "price": 0.5, - "adm": "some-test-ad", - "crid": "crid_10", - "w": 1024, - "h": 576 - }, - "type": "video" - } - ] - } - ] -} diff --git a/adapters/brightroll/brightrolltest/exemplary/valid-extension.json b/adapters/brightroll/brightrolltest/exemplary/valid-extension.json deleted file mode 100644 index 9a5e571ce1b..00000000000 --- a/adapters/brightroll/brightrolltest/exemplary/valid-extension.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "video": { - "mimes": ["video/mp4"], - "protocols": [2, 5], - "w": 1024, - "h": 576 - }, - "ext":{ - "bidder":{ - "publisher": "adthrive" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://test-bid.ybp.yahoo.com/bid/appnexuspbs?publisher=adthrive", - "body": { - "id": "test-request-id", - "at":1, - "bcat": [ - "IAB8-5", - "IAB8-18" - ], - "imp": [ - { - "id": "test-imp-id", - "video": { - "battr": [ - 1, - 2, - 3 - ], - "mimes": ["video/mp4"], - "protocols": [2, 5], - "w": 1024, - "h": 576 - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "cur": "USD", - "seatbid": [ - { - "seat": "brightroll", - "bid": [{ - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id", - "price": 0.500000, - "adm": "some-test-ad", - "crid": "crid_10", - "w": 1024, - "h": 576 - }] - } - ] - } - } - } - ], - - "expectedBidResponses": [ - { - "bids": [{ - "bid": { - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id", - "price": 0.5, - "adm": "some-test-ad", - "crid": "crid_10", - "w": 1024, - "h": 576 - }, - "type": "video" - }] - } - ] -} diff --git a/adapters/brightroll/brightrolltest/exemplary/video-and-audio.json b/adapters/brightroll/brightrolltest/exemplary/video-and-audio.json deleted file mode 100644 index 4184842b60e..00000000000 --- a/adapters/brightroll/brightrolltest/exemplary/video-and-audio.json +++ /dev/null @@ -1,121 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-video-id", - "video": { - "mimes": ["video/mp4"], - "protocols": [2, 5], - "w": 1024, - "h": 576 - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - }, - { - "id": "unsupported-audio-imp", - "audio": { - "mimes": [ - "video/mp4" - ] - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://test-bid.ybp.yahoo.com/bid/appnexuspbs?publisher=adthrive", - "body": { - "id": "test-request-id", - "at":1, - "bcat": [ - "IAB8-5", - "IAB8-18" - ], - "imp": [ - { - "id": "test-imp-video-id", - "video": { - "battr": [ - 1, - 2, - 3 - ], - "mimes": ["video/mp4"], - "protocols": [2, 5], - "w": 1024, - "h": 576 - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - }, - { - "id": "unsupported-audio-imp", - "audio": { - "mimes": [ - "video/mp4" - ] - }, - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "cur": "USD", - "seatbid": [ - { - "seat": "brightroll", - "bid": [{ - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-video-id", - "price": 0.500000, - "adm": "some-test-ad", - "crid": "crid_10", - "w": 1024, - "h": 576 - }] - } - ] - } - } - } - ], - - "expectedBidResponses": [ - { - "bids": [{ - "bid": { - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-video-id", - "price": 0.5, - "adm": "some-test-ad", - "crid": "crid_10", - "w": 1024, - "h": 576 - }, - "type": "video" - }] - } - ] -} diff --git a/adapters/brightroll/brightrolltest/supplemental/invalid-extension.json b/adapters/brightroll/brightrolltest/supplemental/invalid-extension.json deleted file mode 100644 index 35b1563822f..00000000000 --- a/adapters/brightroll/brightrolltest/supplemental/invalid-extension.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-invalid-ext-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "ext": { - } - - } - ] - }, - "expectedMakeRequestsErrors": [ - { - "value": "ext.bidder.publisher not provided", - "comparison": "literal" - } - ] -} diff --git a/adapters/brightroll/brightrolltest/supplemental/invalid-imp.json b/adapters/brightroll/brightrolltest/supplemental/invalid-imp.json deleted file mode 100644 index 01beec712c7..00000000000 --- a/adapters/brightroll/brightrolltest/supplemental/invalid-imp.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "ext": { - "bidder": { - "publisher": "adthrive" - } - } - }, - "expectedMakeRequestsErrors": [ - { - "value": "No impression in the bid request", - "comparison": "literal" - } - ] -} diff --git a/adapters/brightroll/brightrolltest/supplemental/invalid-publisher.json b/adapters/brightroll/brightrolltest/supplemental/invalid-publisher.json deleted file mode 100644 index da48108af0b..00000000000 --- a/adapters/brightroll/brightrolltest/supplemental/invalid-publisher.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-missing-req-param-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "ext": { - "bidder": { - "publisher":"test" - } - } - - } - ] - }, - "expectedMakeRequestsErrors": [ - { - "value": "Invalid publisher", - "comparison": "literal" - } - ] -} \ No newline at end of file diff --git a/adapters/brightroll/brightrolltest/supplemental/missing-extension.json b/adapters/brightroll/brightrolltest/supplemental/missing-extension.json deleted file mode 100644 index 82ec775da30..00000000000 --- a/adapters/brightroll/brightrolltest/supplemental/missing-extension.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-missing-ext-id", - "video": { - "mimes": ["video/mp4"], - "protocols": [2, 5], - "w": 1024, - "h": 576 - } - } - ] - }, - "expectedMakeRequestsErrors": [ - { - "value": "ext.bidder not provided", - "comparison": "literal" - } - ] -} \ No newline at end of file diff --git a/adapters/brightroll/brightrolltest/supplemental/missing-param.json b/adapters/brightroll/brightrolltest/supplemental/missing-param.json deleted file mode 100644 index 08e82c0e31c..00000000000 --- a/adapters/brightroll/brightrolltest/supplemental/missing-param.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-missing-req-param-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "ext": { - "bidder": { - "publisher":"" - } - } - - } - ] - }, - "expectedMakeRequestsErrors": [ - { - "value": "publisher is empty", - "comparison": "literal" - } - ] -} diff --git a/adapters/brightroll/params_test.go b/adapters/brightroll/params_test.go deleted file mode 100644 index c14ee6d73ff..00000000000 --- a/adapters/brightroll/params_test.go +++ /dev/null @@ -1,62 +0,0 @@ -package brightroll - -import ( - "encoding/json" - "testing" - - "github.com/prebid/prebid-server/openrtb_ext" -) - -// This file actually intends to test static/bidder-params/brightroll.json -// -// These also validate the format of the external API: request.imp[i].ext.prebid.bidder.brightroll - -// TestValidParams makes sure that the Brightroll schema accepts all imp.ext fields which we intend to support. -func TestValidParams(t *testing.T) { - validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") - if err != nil { - t.Fatalf("Failed to fetch the json-schemas. %v", err) - } - - for _, validParam := range validParams { - if err := validator.Validate(openrtb_ext.BidderBrightroll, json.RawMessage(validParam)); err != nil { - t.Errorf("Schema rejected Brightroll params: %s", validParam) - } - } -} - -// TestInvalidParams makes sure that the Brightroll schema rejects all the imp.ext fields we don't support. -func TestInvalidParams(t *testing.T) { - validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") - if err != nil { - t.Fatalf("Failed to fetch the json-schemas. %v", err) - } - - for _, invalidParam := range invalidParams { - if err := validator.Validate(openrtb_ext.BidderBrightroll, json.RawMessage(invalidParam)); err == nil { - t.Errorf("Schema allowed unexpected params: %s", invalidParam) - } - } -} - -var validParams = []string{ - `{"publisher": "testpublisher"}`, - `{"publisher": "123"}`, - `{"publisher": "cafemedia"}`, - `{"publisher": "test", "headerbidding": false}`, -} - -var invalidParams = []string{ - `{"publisher": 100}`, - `{"headerbidding": false}`, - `{"publisher": true}`, - `{"publisherId": 123, "headerbidding": true}`, - `{"publisherID": "1"}`, - ``, - `null`, - `true`, - `9`, - `1.2`, - `[]`, - `{}`, -} diff --git a/adapters/gamma/params_test.go b/adapters/gamma/params_test.go index 56f1b591190..c6a149c23bc 100644 --- a/adapters/gamma/params_test.go +++ b/adapters/gamma/params_test.go @@ -8,8 +8,6 @@ import ( ) // This file actually intends to test static/bidder-params/gamma.json -// -// These also validate the format of the external API: request.imp[i].ext.prebid.bidder.brightroll // TestValidParams makes sure that the Gamma schema accepts all imp.ext fields which we intend to support. func TestValidParams(t *testing.T) { diff --git a/config/config_test.go b/config/config_test.go index 402f9ada8db..30733372135 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -885,7 +885,6 @@ func TestUserSyncFromEnv(t *testing.T) { assert.Nil(t, cfg.BidderInfos["bidder2"].Syncer.Redirect) assert.Nil(t, cfg.BidderInfos["bidder2"].Syncer.SupportCORS) - assert.Nil(t, cfg.BidderInfos["brightroll"].Syncer) } func TestBidderInfoFromEnv(t *testing.T) { diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index 4be48811d00..b39f6e03c00 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -1627,7 +1627,7 @@ func TestValidateRequest(t *testing.T) { Ext: []byte(`{"appnexus":{"placementId": 12345678}}`), }, }, - Ext: []byte(`{"prebid":{"aliases":{"brightroll":"appnexus"}, "aliasgvlids":{"pubmatic1":1}}}`), + Ext: []byte(`{"prebid":{"aliases":{"yahoossp":"appnexus"}, "aliasgvlids":{"pubmatic1":1}}}`), }, }, givenIsAmp: false, @@ -1658,11 +1658,11 @@ func TestValidateRequest(t *testing.T) { Ext: []byte(`{"appnexus":{"placementId": 12345678}}`), }, }, - Ext: []byte(`{"prebid":{"aliases":{"brightroll":"appnexus"}, "aliasgvlids":{"brightroll":0}}}`), + Ext: []byte(`{"prebid":{"aliases":{"yahoossp":"appnexus"}, "aliasgvlids":{"yahoossp":0}}}`), }, }, givenIsAmp: false, - expectedErrorList: []error{errors.New("request.ext.prebid.aliasgvlids. Invalid vendorId 0 for alias: brightroll. Choose a different vendorId, or remove this entry.")}, + expectedErrorList: []error{errors.New("request.ext.prebid.aliasgvlids. Invalid vendorId 0 for alias: yahoossp. Choose a different vendorId, or remove this entry.")}, expectedChannelObject: &openrtb_ext.ExtRequestPrebidChannel{Name: appChannel, Version: ""}, }, { @@ -1689,7 +1689,7 @@ func TestValidateRequest(t *testing.T) { Ext: []byte(`{"appnexus":{"placementId": 12345678}}`), }, }, - Ext: []byte(`{"prebid":{"aliases":{"brightroll":"appnexus"}, "aliasgvlids":{"brightroll":1}}}`), + Ext: []byte(`{"prebid":{"aliases":{"yahoossp":"appnexus"}, "aliasgvlids":{"yahoossp":1}}}`), }, }, givenIsAmp: false, diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 6d0a4d8019a..96d6aa64b0f 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -56,7 +56,6 @@ import ( "github.com/prebid/prebid-server/adapters/bmtm" "github.com/prebid/prebid-server/adapters/boldwin" "github.com/prebid/prebid-server/adapters/brave" - "github.com/prebid/prebid-server/adapters/brightroll" "github.com/prebid/prebid-server/adapters/ccx" "github.com/prebid/prebid-server/adapters/coinzilla" "github.com/prebid/prebid-server/adapters/colossus" @@ -243,7 +242,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderBmtm: bmtm.Builder, openrtb_ext.BidderBoldwin: boldwin.Builder, openrtb_ext.BidderBrave: brave.Builder, - openrtb_ext.BidderBrightroll: brightroll.Builder, openrtb_ext.BidderCcx: ccx.Builder, openrtb_ext.BidderCoinzilla: coinzilla.Builder, openrtb_ext.BidderColossus: colossus.Builder, diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index 9551ab3ea69..624a22ce363 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -97,6 +97,7 @@ func GetDisabledBiddersErrorMessages(infos config.BidderInfos) map[string]string "oftmedia": `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`, "groupm": `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`, "verizonmedia": `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`, + "brightroll": `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`, } for name, info := range infos { diff --git a/exchange/adapter_util_test.go b/exchange/adapter_util_test.go index 3b818bdd429..2f3c8e9abab 100644 --- a/exchange/adapter_util_test.go +++ b/exchange/adapter_util_test.go @@ -222,6 +222,7 @@ func TestGetDisabledBiddersErrorMessages(t *testing.T) { "oftmedia": `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`, "groupm": `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`, "verizonmedia": `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`, + "brightroll": `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`, }, }, { @@ -236,6 +237,7 @@ func TestGetDisabledBiddersErrorMessages(t *testing.T) { "oftmedia": `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`, "groupm": `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`, "verizonmedia": `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`, + "brightroll": `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`, }, }, { @@ -251,6 +253,7 @@ func TestGetDisabledBiddersErrorMessages(t *testing.T) { "oftmedia": `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`, "groupm": `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`, "verizonmedia": `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`, + "brightroll": `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`, }, }, { @@ -266,6 +269,7 @@ func TestGetDisabledBiddersErrorMessages(t *testing.T) { "oftmedia": `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`, "groupm": `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`, "verizonmedia": `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`, + "brightroll": `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`, }, }, } diff --git a/exchange/utils_test.go b/exchange/utils_test.go index 973edc53355..b62e9597e0b 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -74,8 +74,6 @@ func assertReq(t *testing.T, bidderRequests []BidderRequest, assert.NotEqual(t, bidderRequests, 0, "cleanOpenRTBRequest should split request into individual bidder requests") // assert for PI data - // Both appnexus and brightroll should be allowed since brightroll - // is used as an alias for appnexus in the test request for _, req := range bidderRequests { if !applyCOPPA && consentedVendors[req.BidderName.String()] { assert.NotEqual(t, req.BidRequest.User.BuyerUID, "", "cleanOpenRTBRequest shouldn't clean PI data as per COPPA or for a consented vendor as per GDPR or per CCPA") @@ -459,7 +457,7 @@ func TestCleanOpenRTBRequests(t *testing.T) { bidReqAssertions: assertReq, hasError: false, applyCOPPA: false, - consentedVendors: map[string]bool{"appnexus": true, "brightroll": true}, + consentedVendors: map[string]bool{"appnexus": true}, }, } @@ -508,13 +506,6 @@ func TestCleanOpenRTBRequestsWithFPD(t *testing.T) { } fpd[openrtb_ext.BidderName("rubicon")] = &apnFpd - brightrollFpd := firstpartydata.ResolvedFirstPartyData{ - Site: &openrtb2.Site{Name: "fpdBrightrollSite"}, - App: &openrtb2.App{Name: "fpdBrightrollApp"}, - User: &openrtb2.User{Keywords: "fpdBrightrollUser"}, - } - fpd[openrtb_ext.BidderName("brightroll")] = &brightrollFpd - emptyTCF2Config := gdpr.NewTCF2Config(config.TCF2{}, config.AccountGDPR{}) testCases := []struct { @@ -2580,9 +2571,9 @@ func newAdapterAliasBidRequest(t *testing.T) *openrtb2.BidRequest { H: 600, }}, }, - Ext: json.RawMessage(`{"appnexus": {"placementId": 1},"brightroll": {"placementId": 105}}`), + Ext: json.RawMessage(`{"appnexus": {"placementId": 1},"somealias": {"placementId": 105}}`), }}, - Ext: json.RawMessage(`{"prebid":{"aliases":{"brightroll":"appnexus"}}}`), + Ext: json.RawMessage(`{"prebid":{"aliases":{"somealias":"appnexus"}}}`), } } @@ -3196,17 +3187,17 @@ func Test_parseAliasesGVLIDs(t *testing.T) { "AliasGVLID Parsed Correctly", args{ orig: &openrtb2.BidRequest{ - Ext: json.RawMessage(`{"prebid":{"aliases":{"brightroll":"appnexus"}, "aliasgvlids":{"brightroll":1}}}`), + Ext: json.RawMessage(`{"prebid":{"aliases":{"somealiascode":"appnexus"}, "aliasgvlids":{"somealiascode":1}}}`), }, }, - map[string]uint16{"brightroll": 1}, + map[string]uint16{"somealiascode": 1}, false, }, { "AliasGVLID parsing error", args{ orig: &openrtb2.BidRequest{ - Ext: json.RawMessage(`{"prebid":{"aliases":{"brightroll":"appnexus"}, "aliasgvlids": {"brightroll":"abc"}`), + Ext: json.RawMessage(`{"prebid":{"aliases":{"somealiascode":"appnexus"}, "aliasgvlids": {"somealiascode":"abc"}`), }, }, nil, @@ -3216,7 +3207,7 @@ func Test_parseAliasesGVLIDs(t *testing.T) { "Invalid AliasGVLID", args{ orig: &openrtb2.BidRequest{ - Ext: json.RawMessage(`{"prebid":{"aliases":{"brightroll":"appnexus"}, "aliasgvlids":"abc"}`), + Ext: json.RawMessage(`{"prebid":{"aliases":{"somealiascode":"appnexus"}, "aliasgvlids":"abc"}`), }, }, nil, @@ -3226,7 +3217,7 @@ func Test_parseAliasesGVLIDs(t *testing.T) { "Missing AliasGVLID", args{ orig: &openrtb2.BidRequest{ - Ext: json.RawMessage(`{"prebid":{"aliases":{"brightroll":"appnexus"}}`), + Ext: json.RawMessage(`{"prebid":{"aliases":{"somealiascode":"appnexus"}}`), }, }, nil, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index a43861ddc49..2398af8e62a 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -142,7 +142,6 @@ const ( BidderBmtm BidderName = "bmtm" BidderBoldwin BidderName = "boldwin" BidderBrave BidderName = "brave" - BidderBrightroll BidderName = "brightroll" BidderCcx BidderName = "ccx" BidderCoinzilla BidderName = "coinzilla" BidderColossus BidderName = "colossus" @@ -342,7 +341,6 @@ func CoreBidderNames() []BidderName { BidderBmtm, BidderBoldwin, BidderBrave, - BidderBrightroll, BidderCcx, BidderCoinzilla, BidderColossus, diff --git a/openrtb_ext/imp_brightroll.go b/openrtb_ext/imp_brightroll.go deleted file mode 100644 index bd42d4aae5d..00000000000 --- a/openrtb_ext/imp_brightroll.go +++ /dev/null @@ -1,6 +0,0 @@ -package openrtb_ext - -// ExtImpBrightroll defines the contract for bidrequest.imp[i].ext.prebid.bidder.brightroll -type ExtImpBrightroll struct { - Publisher string `json:"publisher"` -} diff --git a/static/bidder-info/brightroll.yaml b/static/bidder-info/brightroll.yaml deleted file mode 100644 index 196344e9f25..00000000000 --- a/static/bidder-info/brightroll.yaml +++ /dev/null @@ -1,17 +0,0 @@ -endpoint: "http://east-bid.ybp.yahoo.com/bid/appnexuspbs" -maintainer: - email: "dsp-supply-prebid@verizonmedia.com" -gvlVendorID: 25 -capabilities: - app: - mediaTypes: - - banner - - video - site: - mediaTypes: - - banner - - video -userSync: - redirect: - url: "https://pr-bh.ybp.yahoo.com/sync/appnexusprebidserver/?gdpr={{.GDPR}}&euconsent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&url={{.RedirectURL}}" - userMacro: "$UID" diff --git a/static/bidder-params/brightroll.json b/static/bidder-params/brightroll.json deleted file mode 100644 index 48e48d8a36d..00000000000 --- a/static/bidder-params/brightroll.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Brightroll Adapter Params", - "description": "A schema which validates params accepted by the Brightroll adapter", - "type": "object", - "properties": { - "publisher": { - "type": "string", - "description": "Publisher Name to use." - } - }, - "required": ["publisher"] -} From 33714f275908f709738689681d9b12cdcdd06e6b Mon Sep 17 00:00:00 2001 From: ownAdx <135326256+ownAdx-prebid@users.noreply.github.com> Date: Wed, 26 Jul 2023 20:49:57 +0530 Subject: [PATCH 041/268] New Adapter: OwnAdX (#2850) Co-authored by @ownAdx-prebid --- adapters/ownadx/ownadx.go | 213 ++++++++++++++++++ adapters/ownadx/ownadx_test.go | 17 ++ .../ownadx/ownadxtest/exemplary/banner.json | 166 ++++++++++++++ .../ownadx/ownadxtest/exemplary/video.json | 196 ++++++++++++++++ .../supplemental/bad-server-response.json | 108 +++++++++ .../ownadxtest/supplemental/bid-empty-.json | 118 ++++++++++ .../ownadxtest/supplemental/bidext-type.json | 141 ++++++++++++ .../supplemental/http-status-204.json | 51 +++++ .../supplemental/http-status-400.json | 57 +++++ .../supplemental/invalid-req-empty-imp.json | 34 +++ .../supplemental/invalid-req-imp-ext.json | 47 ++++ .../invalid-req-imp.ext.bidder.json | 49 ++++ .../supplemental/seatbid-empty-.json | 113 ++++++++++ .../supplemental/unexpected-status.json | 107 +++++++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_ownadx.go | 7 + static/bidder-info/ownadx.yaml | 12 + static/bidder-params/ownadx.json | 27 +++ 19 files changed, 1467 insertions(+) create mode 100644 adapters/ownadx/ownadx.go create mode 100644 adapters/ownadx/ownadx_test.go create mode 100644 adapters/ownadx/ownadxtest/exemplary/banner.json create mode 100644 adapters/ownadx/ownadxtest/exemplary/video.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/bad-server-response.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/bid-empty-.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/bidext-type.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/http-status-204.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/http-status-400.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/invalid-req-empty-imp.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/invalid-req-imp-ext.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/invalid-req-imp.ext.bidder.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/seatbid-empty-.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/unexpected-status.json create mode 100644 openrtb_ext/imp_ownadx.go create mode 100644 static/bidder-info/ownadx.yaml create mode 100644 static/bidder-params/ownadx.json diff --git a/adapters/ownadx/ownadx.go b/adapters/ownadx/ownadx.go new file mode 100644 index 00000000000..c19343ba47f --- /dev/null +++ b/adapters/ownadx/ownadx.go @@ -0,0 +1,213 @@ +package ownadx + +import ( + "encoding/json" + "fmt" + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/macros" + "github.com/prebid/prebid-server/openrtb_ext" + "net/http" + "text/template" +) + +type adapter struct { + endpoint *template.Template +} +type bidExt struct { + MediaType string `json:"mediaType"` +} + +func (adapter *adapter) getRequestData(bidRequest *openrtb2.BidRequest, impExt *openrtb_ext.ExtImpOwnAdx, imps []openrtb2.Imp) (*adapters.RequestData, error) { + pbidRequest := createBidRequest(bidRequest, imps) + reqJSON, err := json.Marshal(pbidRequest) + if err != nil { + return nil, &errortypes.BadInput{ + Message: "Prebid bidder request not valid or can't be marshalled. Err: " + err.Error(), + } + } + url, err := adapter.buildEndpointURL(impExt) + if err != nil { + return nil, &errortypes.BadInput{ + Message: "Error while creating endpoint. Err: " + err.Error(), + } + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + headers.Add("x-openrtb-version", "2.5") + + return &adapters.RequestData{ + Method: "POST", + Uri: url, + Body: reqJSON, + Headers: headers}, nil + +} +func createBidRequest(rtbBidRequest *openrtb2.BidRequest, imps []openrtb2.Imp) *openrtb2.BidRequest { + bidRequest := *rtbBidRequest + bidRequest.Imp = imps + return &bidRequest +} +func (adapter *adapter) buildEndpointURL(params *openrtb_ext.ExtImpOwnAdx) (string, error) { + endpointParams := macros.EndpointTemplateParams{ + ZoneID: params.SspId, + AccountID: params.SeatId, + SourceId: params.TokenId, + } + return macros.ResolveMacros(adapter.endpoint, endpointParams) +} + +func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpOwnAdx, error) { + var bidderExt adapters.ExtImpBidder + if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + return nil, &errortypes.BadInput{ + Message: "Bidder extension not valid or can't be unmarshalled", + } + } + + var ownAdxExt openrtb_ext.ExtImpOwnAdx + if err := json.Unmarshal(bidderExt.Bidder, &ownAdxExt); err != nil { + return nil, &errortypes.BadInput{ + Message: "Error while unmarshaling bidder extension", + } + } + + return &ownAdxExt, nil +} + +func (adapter *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + + errs := make([]error, 0, len(request.Imp)) + if len(request.Imp) == 0 { + errs = append(errs, &errortypes.BadInput{ + Message: "No impression in the bid request"}, + ) + return nil, errs + } + extImps, errors := groupImpsByExt(request.Imp) + if len(errors) != 0 { + errs = append(errs, errors...) + } + if len(extImps) == 0 { + return nil, errs + } + reqDetail := make([]*adapters.RequestData, 0, len(extImps)) + for k, imps := range extImps { + bidRequest, err := adapter.getRequestData(request, &k, imps) + if err != nil { + errs = append(errs, err) + } else { + reqDetail = append(reqDetail, bidRequest) + } + } + return reqDetail, errs +} +func groupImpsByExt(imps []openrtb2.Imp) (map[openrtb_ext.ExtImpOwnAdx][]openrtb2.Imp, []error) { + respExt := make(map[openrtb_ext.ExtImpOwnAdx][]openrtb2.Imp) + errors := make([]error, 0, len(imps)) + for _, imp := range imps { + ownAdxExt, err := getImpressionExt(&(imp)) + if err != nil { + errors = append(errors, err) + continue + } + + respExt[*ownAdxExt] = append(respExt[*ownAdxExt], imp) + } + return respExt, errors +} + +func (adapter *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if response.StatusCode == http.StatusNoContent { + return nil, nil + } + if response.StatusCode == http.StatusBadRequest { + return nil, []error{ + &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Bad request: %d", response.StatusCode), + }, + } + } + if response.StatusCode != http.StatusOK { + return nil, []error{ + &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unexpected status code: %d. Run with request.test = 1 for more info.", response.StatusCode), + }, + } + } + var bidResp openrtb2.BidResponse + if err := json.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{ + &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Bad server response "), + }, + } + } + if len(bidResp.SeatBid) == 0 { + return nil, []error{ + &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Array SeatBid cannot be empty "), + }, + } + } + + seatBid := bidResp.SeatBid[0] + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(bidResp.SeatBid[0].Bid)) + if len(seatBid.Bid) == 0 { + return nil, []error{ + &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Bid cannot be empty "), + }, + } + } + for i := 0; i < len(seatBid.Bid); i++ { + var bidType openrtb_ext.BidType + bid := seatBid.Bid[i] + + bidType, err := getMediaType(bid) + if err != nil { + return nil, []error{&errortypes.BadServerResponse{ + Message: "Bid type is invalid", + }} + } + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &bid, + BidType: bidType, + }) + } + + return bidResponse, nil +} + +// Builder builds a new instance of the OwnAdx adapter for the given bidder with the given config +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + template, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) + } + + bidder := &adapter{ + endpoint: template, + } + + return bidder, nil +} + +func getMediaType(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupAudio: + return openrtb_ext.BidTypeAudio, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + return "", fmt.Errorf("invalid BidType: %d", bid.MType) + } +} diff --git a/adapters/ownadx/ownadx_test.go b/adapters/ownadx/ownadx_test.go new file mode 100644 index 00000000000..9bd7ba70353 --- /dev/null +++ b/adapters/ownadx/ownadx_test.go @@ -0,0 +1,17 @@ +package ownadx + +import ( + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderOwnAdx, config.Adapter{ + Endpoint: "https://pbs.prebid-ownadx.com/bidder/bid/{{.AccountID}}/{{.ZoneID}}?token={{.SourceId}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + assert.NoError(t, buildErr) + adapterstest.RunJSONBidderTest(t, "ownadxtest", bidder) +} diff --git a/adapters/ownadx/ownadxtest/exemplary/banner.json b/adapters/ownadx/ownadxtest/exemplary/banner.json new file mode 100644 index 00000000000..f77321c53b1 --- /dev/null +++ b/adapters/ownadx/ownadxtest/exemplary/banner.json @@ -0,0 +1,166 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [ + { + "mtype": 1, + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "mediaType": "banner" + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "mtype": 1, + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "mediaType": "banner" + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/ownadx/ownadxtest/exemplary/video.json b/adapters/ownadx/ownadxtest/exemplary/video.json new file mode 100644 index 00000000000..7cac425c7e3 --- /dev/null +++ b/adapters/ownadx/ownadxtest/exemplary/video.json @@ -0,0 +1,196 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "video": { + "mimes": [ + "video/mp4", + "video/ogg", + "video/webm" + ], + "minduration": 3, + "maxduration": 3000, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 480, + "h": 320, + "linearity": 1, + "playbackmethod": [ + 2 + ], + "pos": 0 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "video": { + "mimes": [ + "video/mp4", + "video/ogg", + "video/webm" + ], + "minduration": 3, + "maxduration": 3000, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 480, + "h": 320, + "linearity": 1, + "playbackmethod": [ + 2 + ], + "pos": 0 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "mtype": 2 + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/ownadx/ownadxtest/supplemental/bad-server-response.json b/adapters/ownadx/ownadxtest/supplemental/bad-server-response.json new file mode 100644 index 00000000000..61b6da04fa8 --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/bad-server-response.json @@ -0,0 +1,108 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200 + + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bad server response ", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/ownadx/ownadxtest/supplemental/bid-empty-.json b/adapters/ownadx/ownadxtest/supplemental/bid-empty-.json new file mode 100644 index 00000000000..8d40e878925 --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/bid-empty-.json @@ -0,0 +1,118 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "seat": "seat" + } + ], + "cur": "USD" + } + + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bid cannot be empty ", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/ownadx/ownadxtest/supplemental/bidext-type.json b/adapters/ownadx/ownadxtest/supplemental/bidext-type.json new file mode 100644 index 00000000000..b1d634287d7 --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/bidext-type.json @@ -0,0 +1,141 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bid type is invalid", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/ownadx/ownadxtest/supplemental/http-status-204.json b/adapters/ownadx/ownadxtest/supplemental/http-status-204.json new file mode 100644 index 00000000000..4b7f8663f02 --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/http-status-204.json @@ -0,0 +1,51 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ] + } + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/ownadx/ownadxtest/supplemental/http-status-400.json b/adapters/ownadx/ownadxtest/supplemental/http-status-400.json new file mode 100644 index 00000000000..035bc323e38 --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/http-status-400.json @@ -0,0 +1,57 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ] + } + }, + "mockResponse": { + "status": 400 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bad request: 400", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/ownadx/ownadxtest/supplemental/invalid-req-empty-imp.json b/adapters/ownadx/ownadxtest/supplemental/invalid-req-empty-imp.json new file mode 100644 index 00000000000..0407ed6cfbf --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/invalid-req-empty-imp.json @@ -0,0 +1,34 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "No impression in the bid request", + "comparison": "literal" + } + ], + "mockBidRequest": { + "id": "id", + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [] +} diff --git a/adapters/ownadx/ownadxtest/supplemental/invalid-req-imp-ext.json b/adapters/ownadx/ownadxtest/supplemental/invalid-req-imp-ext.json new file mode 100644 index 00000000000..9b8ba0d1820 --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/invalid-req-imp-ext.json @@ -0,0 +1,47 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "Bidder extension not valid or can't be unmarshalled", + "comparison": "literal" + } + ], + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + } + + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [] +} diff --git a/adapters/ownadx/ownadxtest/supplemental/invalid-req-imp.ext.bidder.json b/adapters/ownadx/ownadxtest/supplemental/invalid-req-imp.ext.bidder.json new file mode 100644 index 00000000000..b04e037d0a2 --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/invalid-req-imp.ext.bidder.json @@ -0,0 +1,49 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "Error while unmarshaling bidder extension", + "comparison": "literal" + } + ], + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": [] + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [] +} diff --git a/adapters/ownadx/ownadxtest/supplemental/seatbid-empty-.json b/adapters/ownadx/ownadxtest/supplemental/seatbid-empty-.json new file mode 100644 index 00000000000..f49ece3ea2f --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/seatbid-empty-.json @@ -0,0 +1,113 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "cur": "USD" + } + + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Array SeatBid cannot be empty ", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/ownadx/ownadxtest/supplemental/unexpected-status.json b/adapters/ownadx/ownadxtest/supplemental/unexpected-status.json new file mode 100644 index 00000000000..f501a11064e --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/unexpected-status.json @@ -0,0 +1,107 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 403 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 403. Run with request.test = 1 for more info.", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 96d6aa64b0f..a1038d7152d 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -127,6 +127,7 @@ import ( "github.com/prebid/prebid-server/adapters/operaads" "github.com/prebid/prebid-server/adapters/orbidder" "github.com/prebid/prebid-server/adapters/outbrain" + "github.com/prebid/prebid-server/adapters/ownadx" "github.com/prebid/prebid-server/adapters/pangle" "github.com/prebid/prebid-server/adapters/pubmatic" "github.com/prebid/prebid-server/adapters/pubnative" @@ -320,6 +321,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderOperaads: operaads.Builder, openrtb_ext.BidderOrbidder: orbidder.Builder, openrtb_ext.BidderOutbrain: outbrain.Builder, + openrtb_ext.BidderOwnAdx: ownadx.Builder, openrtb_ext.BidderPangle: pangle.Builder, openrtb_ext.BidderPGAM: adtelligent.Builder, openrtb_ext.BidderPubmatic: pubmatic.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 2398af8e62a..e9cc81f8c38 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -220,6 +220,7 @@ const ( BidderOperaads BidderName = "operaads" BidderOrbidder BidderName = "orbidder" BidderOutbrain BidderName = "outbrain" + BidderOwnAdx BidderName = "ownadx" BidderPangle BidderName = "pangle" BidderPGAM BidderName = "pgam" BidderPubmatic BidderName = "pubmatic" @@ -419,6 +420,7 @@ func CoreBidderNames() []BidderName { BidderOperaads, BidderOrbidder, BidderOutbrain, + BidderOwnAdx, BidderPangle, BidderPGAM, BidderPubmatic, diff --git a/openrtb_ext/imp_ownadx.go b/openrtb_ext/imp_ownadx.go new file mode 100644 index 00000000000..caac600b50e --- /dev/null +++ b/openrtb_ext/imp_ownadx.go @@ -0,0 +1,7 @@ +package openrtb_ext + +type ExtImpOwnAdx struct { + SspId string `json:"sspId"` + SeatId string `json:"seatId"` + TokenId string `json:"tokenId"` +} diff --git a/static/bidder-info/ownadx.yaml b/static/bidder-info/ownadx.yaml new file mode 100644 index 00000000000..37567db1144 --- /dev/null +++ b/static/bidder-info/ownadx.yaml @@ -0,0 +1,12 @@ +endpoint: "https://pbs.prebid-ownadx.com/bidder/bid/{{.AccountID}}/{{.ZoneID}}?token={{.SourceId}}" +maintainer: + email: prebid-team@techbravo.com +capabilities: + app: + mediaTypes: + - banner + - video + site: + mediaTypes: + - banner + - video diff --git a/static/bidder-params/ownadx.json b/static/bidder-params/ownadx.json new file mode 100644 index 00000000000..f529e74cb01 --- /dev/null +++ b/static/bidder-params/ownadx.json @@ -0,0 +1,27 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "OwnAdx Adapter Params", + "description": "A schema which validates params accepted by the OwnAdx adapter", + "type": "object", + + "properties": { + "sspId": { + "type": "string", + "description": "Ssp ID" + }, + "seatId": { + "type": "string", + "description": "Seat ID" + }, + "tokenId": { + "type": "string", + "description": "Token ID" + } + }, + + "oneOf": [ + { "required": ["sspId"] }, + { "required": ["feedId"] }, + { "required": ["token"] } + ] +} From 831dd711a23f1c32b7829f0843abee45126fc312 Mon Sep 17 00:00:00 2001 From: Veronika Solovei Date: Wed, 26 Jul 2023 11:38:46 -0700 Subject: [PATCH 042/268] Use bidder name instead of syncer key (#2948) --- config/bidderinfo.go | 2 +- endpoints/setuid.go | 17 +++++------------ endpoints/setuid_test.go | 2 +- usersync/syncer.go | 14 ++++++++------ usersync/syncer_test.go | 27 +++++++++++++++++++++++---- usersync/syncersbuilder.go | 19 +++++++++---------- usersync/syncersbuilder_test.go | 25 +++++++++++++------------ 7 files changed, 60 insertions(+), 46 deletions(-) diff --git a/config/bidderinfo.go b/config/bidderinfo.go index b4d7900196e..630952a6884 100644 --- a/config/bidderinfo.go +++ b/config/bidderinfo.go @@ -162,7 +162,7 @@ type SyncerEndpoint struct { // startup: // // {{.ExternalURL}} - This will be replaced with the host server's externally reachable http path. - // {{.SyncerKey}} - This will be replaced with the syncer key. + // {{.BidderName}} - This will be replaced with the bidder name. // {{.SyncType}} - This will be replaced with the sync type, either 'b' for iframe syncs or 'i' // for redirect/image syncs. // {{.UserMacro}} - This will be replaced with the bidder server's user id macro. diff --git a/endpoints/setuid.go b/endpoints/setuid.go index 905fa26b2f2..25fb246593a 100644 --- a/endpoints/setuid.go +++ b/endpoints/setuid.go @@ -39,13 +39,6 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use encoder := usersync.Base64Encoder{} decoder := usersync.Base64Decoder{} - // convert map of syncers by bidder to map of syncers by key - // - its safe to assume that if multiple bidders map to the same key, the syncers are interchangeable. - syncersByKey := make(map[string]usersync.Syncer, len(syncersByBidder)) - for _, v := range syncersByBidder { - syncersByKey[v.Key()] = v - } - return httprouter.Handle(func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { so := analytics.SetUIDObject{ Status: http.StatusOK, @@ -65,7 +58,7 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use query := r.URL.Query() - syncer, err := getSyncer(query, syncersByKey) + syncer, err := getSyncer(query, syncersByBidder) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) @@ -313,14 +306,14 @@ func parseConsentFromGppStr(gppQueryValue string) (string, error) { return gdprConsent, nil } -func getSyncer(query url.Values, syncersByKey map[string]usersync.Syncer) (usersync.Syncer, error) { - key := query.Get("bidder") +func getSyncer(query url.Values, syncersByBidder map[string]usersync.Syncer) (usersync.Syncer, error) { + bidder := query.Get("bidder") - if key == "" { + if bidder == "" { return nil, errors.New(`"bidder" query param is required`) } - syncer, syncerExists := syncersByKey[key] + syncer, syncerExists := syncersByBidder[bidder] if !syncerExists { return nil, errors.New("The bidder name provided is not supported by Prebid Server") } diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go index 9176041ed8e..65bc26559da 100644 --- a/endpoints/setuid_test.go +++ b/endpoints/setuid_test.go @@ -50,7 +50,7 @@ func TestSetUIDEndpoint(t *testing.T) { description: "Set uid for valid bidder", }, { - uri: "/setuid?bidder=adnxs&uid=123", + uri: "/setuid?bidder=appnexus&uid=123", syncersBidderNameToKey: map[string]string{"appnexus": "adnxs"}, existingSyncs: nil, gdprAllowsHostCookies: true, diff --git a/usersync/syncer.go b/usersync/syncer.go index 2e0e41027b5..fb14201f2dc 100644 --- a/usersync/syncer.go +++ b/usersync/syncer.go @@ -63,7 +63,7 @@ var ErrSyncerKeyRequired = errors.New("key is required") // NewSyncer creates a new Syncer from the provided configuration, or return an error if macro substition // fails or an endpoint url is invalid. -func NewSyncer(hostConfig config.UserSync, syncerConfig config.Syncer) (Syncer, error) { +func NewSyncer(hostConfig config.UserSync, syncerConfig config.Syncer, bidder string) (Syncer, error) { if syncerConfig.Key == "" { return nil, ErrSyncerKeyRequired } @@ -80,7 +80,7 @@ func NewSyncer(hostConfig config.UserSync, syncerConfig config.Syncer) (Syncer, if syncerConfig.IFrame != nil { var err error - syncer.iframe, err = buildTemplate(syncerConfig.Key, setuidSyncTypeIFrame, hostConfig, syncerConfig.ExternalURL, *syncerConfig.IFrame) + syncer.iframe, err = buildTemplate(bidder, setuidSyncTypeIFrame, hostConfig, syncerConfig.ExternalURL, *syncerConfig.IFrame) if err != nil { return nil, fmt.Errorf("iframe %v", err) } @@ -91,7 +91,7 @@ func NewSyncer(hostConfig config.UserSync, syncerConfig config.Syncer) (Syncer, if syncerConfig.Redirect != nil { var err error - syncer.redirect, err = buildTemplate(syncerConfig.Key, setuidSyncTypeRedirect, hostConfig, syncerConfig.ExternalURL, *syncerConfig.Redirect) + syncer.redirect, err = buildTemplate(bidder, setuidSyncTypeRedirect, hostConfig, syncerConfig.ExternalURL, *syncerConfig.Redirect) if err != nil { return nil, fmt.Errorf("redirect %v", err) } @@ -114,13 +114,14 @@ func resolveDefaultSyncType(syncerConfig config.Syncer) SyncType { var ( macroRegexExternalHost = regexp.MustCompile(`{{\s*\.ExternalURL\s*}}`) macroRegexSyncerKey = regexp.MustCompile(`{{\s*\.SyncerKey\s*}}`) + macroRegexBidderName = regexp.MustCompile(`{{\s*\.BidderName\s*}}`) macroRegexSyncType = regexp.MustCompile(`{{\s*\.SyncType\s*}}`) macroRegexUserMacro = regexp.MustCompile(`{{\s*\.UserMacro\s*}}`) macroRegexRedirect = regexp.MustCompile(`{{\s*\.RedirectURL\s*}}`) macroRegex = regexp.MustCompile(`{{\s*\..*?\s*}}`) ) -func buildTemplate(key, syncTypeValue string, hostConfig config.UserSync, syncerExternalURL string, syncerEndpoint config.SyncerEndpoint) (*template.Template, error) { +func buildTemplate(bidderName, syncTypeValue string, hostConfig config.UserSync, syncerExternalURL string, syncerEndpoint config.SyncerEndpoint) (*template.Template, error) { redirectTemplate := syncerEndpoint.RedirectURL if redirectTemplate == "" { redirectTemplate = hostConfig.RedirectURL @@ -128,7 +129,8 @@ func buildTemplate(key, syncTypeValue string, hostConfig config.UserSync, syncer externalURL := chooseExternalURL(syncerEndpoint.ExternalURL, syncerExternalURL, hostConfig.ExternalURL) - redirectURL := macroRegexSyncerKey.ReplaceAllLiteralString(redirectTemplate, key) + redirectURL := macroRegexSyncerKey.ReplaceAllLiteralString(redirectTemplate, bidderName) + redirectURL = macroRegexBidderName.ReplaceAllLiteralString(redirectURL, bidderName) redirectURL = macroRegexSyncType.ReplaceAllLiteralString(redirectURL, syncTypeValue) redirectURL = macroRegexUserMacro.ReplaceAllLiteralString(redirectURL, syncerEndpoint.UserMacro) redirectURL = macroRegexExternalHost.ReplaceAllLiteralString(redirectURL, externalURL) @@ -136,7 +138,7 @@ func buildTemplate(key, syncTypeValue string, hostConfig config.UserSync, syncer url := macroRegexRedirect.ReplaceAllString(syncerEndpoint.URL, redirectURL) - templateName := strings.ToLower(key) + "_usersync_url" + templateName := strings.ToLower(bidderName) + "_usersync_url" return template.New(templateName).Parse(url) } diff --git a/usersync/syncer_test.go b/usersync/syncer_test.go index 6e727c3a49c..c309b899358 100644 --- a/usersync/syncer_test.go +++ b/usersync/syncer_test.go @@ -26,6 +26,7 @@ func TestNewSyncer(t *testing.T) { testCases := []struct { description string givenKey string + givenBidderName string givenIFrameConfig *config.SyncerEndpoint givenRedirectConfig *config.SyncerEndpoint givenExternalURL string @@ -37,6 +38,7 @@ func TestNewSyncer(t *testing.T) { { description: "Missing Key", givenKey: "", + givenBidderName: "", givenIFrameConfig: iframeConfig, givenRedirectConfig: nil, expectedError: "key is required", @@ -44,6 +46,7 @@ func TestNewSyncer(t *testing.T) { { description: "Missing Endpoints", givenKey: "a", + givenBidderName: "bidderA", givenIFrameConfig: nil, givenRedirectConfig: nil, expectedError: "at least one endpoint (iframe and/or redirect) is required", @@ -51,6 +54,7 @@ func TestNewSyncer(t *testing.T) { { description: "IFrame & Redirect Endpoints", givenKey: "a", + givenBidderName: "bidderA", givenIFrameConfig: iframeConfig, givenRedirectConfig: redirectConfig, expectedDefault: SyncTypeIFrame, @@ -60,13 +64,15 @@ func TestNewSyncer(t *testing.T) { { description: "IFrame - Parse Error", givenKey: "a", + givenBidderName: "bidderA", givenIFrameConfig: errParseConfig, givenRedirectConfig: nil, - expectedError: "iframe template: a_usersync_url:1: function \"malformed\" not defined", + expectedError: "iframe template: biddera_usersync_url:1: function \"malformed\" not defined", }, { description: "IFrame - Validation Error", givenKey: "a", + givenBidderName: "bidderA", givenIFrameConfig: errInvalidConfig, givenRedirectConfig: nil, expectedError: "iframe composed url: \"notAURL:http%3A%2F%2Fhost.com%2Fhost\" is invalid", @@ -74,13 +80,15 @@ func TestNewSyncer(t *testing.T) { { description: "Redirect - Parse Error", givenKey: "a", + givenBidderName: "bidderA", givenIFrameConfig: nil, givenRedirectConfig: errParseConfig, - expectedError: "redirect template: a_usersync_url:1: function \"malformed\" not defined", + expectedError: "redirect template: biddera_usersync_url:1: function \"malformed\" not defined", }, { description: "Redirect - Validation Error", givenKey: "a", + givenBidderName: "bidderA", givenIFrameConfig: nil, givenRedirectConfig: errInvalidConfig, expectedError: "redirect composed url: \"notAURL:http%3A%2F%2Fhost.com%2Fhost\" is invalid", @@ -88,6 +96,7 @@ func TestNewSyncer(t *testing.T) { { description: "Syncer Level External URL", givenKey: "a", + givenBidderName: "bidderA", givenExternalURL: "http://syncer.com", givenIFrameConfig: iframeConfig, givenRedirectConfig: redirectConfig, @@ -106,7 +115,7 @@ func TestNewSyncer(t *testing.T) { ExternalURL: test.givenExternalURL, } - result, err := NewSyncer(hostConfig, syncerConfig) + result, err := NewSyncer(hostConfig, syncerConfig, test.givenBidderName) if test.expectedError == "" { assert.NoError(t, err, test.description+":err") @@ -196,7 +205,7 @@ func TestBuildTemplate(t *testing.T) { expectedRendered: "hasNoComposedMacros,gdpr=A", }, { - description: "All Composed Macros", + description: "All Composed Macros - SyncerKey", givenSyncerEndpoint: config.SyncerEndpoint{ URL: "https://bidder.com/sync?redirect={{.RedirectURL}}", RedirectURL: "{{.ExternalURL}}/setuid?bidder={{.SyncerKey}}&f={{.SyncType}}&gdpr={{.GDPR}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&uid={{.UserMacro}}", @@ -205,6 +214,16 @@ func TestBuildTemplate(t *testing.T) { }, expectedRendered: "https://bidder.com/sync?redirect=http%3A%2F%2Fsyncer.com%2Fsetuid%3Fbidder%3DanyKey%26f%3Dx%26gdpr%3DA%26gpp%3DD%26gpp_sid%3D1%26uid%3D%24UID%24", }, + { + description: "All Composed Macros - BidderName", + givenSyncerEndpoint: config.SyncerEndpoint{ + URL: "https://bidder.com/sync?redirect={{.RedirectURL}}", + RedirectURL: "{{.ExternalURL}}/setuid?bidder={{.BidderName}}&f={{.SyncType}}&gdpr={{.GDPR}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&uid={{.UserMacro}}", + ExternalURL: "http://syncer.com", + UserMacro: "$UID$", + }, + expectedRendered: "https://bidder.com/sync?redirect=http%3A%2F%2Fsyncer.com%2Fsetuid%3Fbidder%3DanyKey%26f%3Dx%26gdpr%3DA%26gpp%3DD%26gpp_sid%3D1%26uid%3D%24UID%24", + }, { description: "Redirect URL + External URL From Host", givenSyncerEndpoint: config.SyncerEndpoint{ diff --git a/usersync/syncersbuilder.go b/usersync/syncersbuilder.go index c521d36dde2..9a52a740f31 100644 --- a/usersync/syncersbuilder.go +++ b/usersync/syncersbuilder.go @@ -59,17 +59,16 @@ func BuildSyncers(hostConfig *config.Configuration, bidderInfos config.BidderInf continue } - syncer, err := NewSyncer(hostUserSyncConfig, primaryCfg.cfg) - if err != nil { - errs = append(errs, SyncerBuildError{ - Bidder: primaryCfg.name, - SyncerKey: key, - Err: err, - }) - continue - } - for _, bidder := range cfgGroup { + syncer, err := NewSyncer(hostUserSyncConfig, primaryCfg.cfg, bidder.name) + if err != nil { + errs = append(errs, SyncerBuildError{ + Bidder: primaryCfg.name, + SyncerKey: key, + Err: err, + }) + continue + } syncers[bidder.name] = syncer } } diff --git a/usersync/syncersbuilder_test.go b/usersync/syncersbuilder_test.go index b3672a501bb..fbc1863959b 100644 --- a/usersync/syncersbuilder_test.go +++ b/usersync/syncersbuilder_test.go @@ -48,7 +48,7 @@ func TestBuildSyncers(t *testing.T) { givenConfig: hostConfig, givenBidderInfos: map[string]config.BidderInfo{"bidder1": infoKeyAPopulated}, expectedIFramesURLs: map[string]string{ - "bidder1": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fa%2Fhost", + "bidder1": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fbidder1%2Fhost", }, }, { @@ -64,7 +64,7 @@ func TestBuildSyncers(t *testing.T) { givenConfig: hostConfig, givenBidderInfos: map[string]config.BidderInfo{"bidder1": infoKeyAError}, expectedErrors: []string{ - "cannot create syncer for bidder bidder1 with key a: iframe template: a_usersync_url:1: function \"xRedirectURL\" not defined", + "cannot create syncer for bidder bidder1 with key a: iframe template: bidder1_usersync_url:1: function \"xRedirectURL\" not defined", }, }, { @@ -72,8 +72,8 @@ func TestBuildSyncers(t *testing.T) { givenConfig: hostConfig, givenBidderInfos: map[string]config.BidderInfo{"bidder1": infoKeyAPopulated, "bidder2": infoKeyBPopulated}, expectedIFramesURLs: map[string]string{ - "bidder1": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fa%2Fhost", - "bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fb%2Fhost", + "bidder1": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fbidder1%2Fhost", + "bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fbidder2%2Fhost", }, }, { @@ -81,8 +81,8 @@ func TestBuildSyncers(t *testing.T) { givenConfig: hostConfig, givenBidderInfos: map[string]config.BidderInfo{"bidder1": infoKeyAPopulated, "bidder2": infoKeyAEmpty}, expectedIFramesURLs: map[string]string{ - "bidder1": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fa%2Fhost", - "bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fa%2Fhost", + "bidder1": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fbidder1%2Fhost", + "bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fbidder2%2Fhost", }, }, { @@ -106,7 +106,8 @@ func TestBuildSyncers(t *testing.T) { givenConfig: hostConfig, givenBidderInfos: map[string]config.BidderInfo{"bidder1": infoKeyAEmpty, "bidder2": infoKeyAError}, expectedErrors: []string{ - "cannot create syncer for bidder bidder2 with key a: iframe template: a_usersync_url:1: function \"xRedirectURL\" not defined", + "cannot create syncer for bidder bidder2 with key a: iframe template: bidder1_usersync_url:1: function \"xRedirectURL\" not defined", + "cannot create syncer for bidder bidder2 with key a: iframe template: bidder2_usersync_url:1: function \"xRedirectURL\" not defined", }, }, { @@ -114,7 +115,7 @@ func TestBuildSyncers(t *testing.T) { givenConfig: hostConfig, givenBidderInfos: map[string]config.BidderInfo{"bidder1": {}, "bidder2": infoKeyBPopulated}, expectedIFramesURLs: map[string]string{ - "bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fb%2Fhost", + "bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fbidder2%2Fhost", }, }, { @@ -122,7 +123,7 @@ func TestBuildSyncers(t *testing.T) { givenConfig: hostConfig, givenBidderInfos: map[string]config.BidderInfo{"bidder1": infoKeyADisabled, "bidder2": infoKeyBPopulated}, expectedIFramesURLs: map[string]string{ - "bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fb%2Fhost", + "bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fbidder2%2Fhost", }, }, { @@ -130,7 +131,7 @@ func TestBuildSyncers(t *testing.T) { givenConfig: hostConfig, givenBidderInfos: map[string]config.BidderInfo{"bidder1": infoKeyASupportsOnly, "bidder2": infoKeyBPopulated}, expectedIFramesURLs: map[string]string{ - "bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fb%2Fhost", + "bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fbidder2%2Fhost", }, }, { @@ -138,7 +139,7 @@ func TestBuildSyncers(t *testing.T) { givenConfig: hostConfig, givenBidderInfos: map[string]config.BidderInfo{"bidder1": infoKeyAError, "bidder2": infoKeyBEmpty}, expectedErrors: []string{ - "cannot create syncer for bidder bidder1 with key a: iframe template: a_usersync_url:1: function \"xRedirectURL\" not defined", + "cannot create syncer for bidder bidder1 with key a: iframe template: bidder1_usersync_url:1: function \"xRedirectURL\" not defined", "cannot create syncer for bidder bidder2 with key b: at least one endpoint (iframe and/or redirect) is required", }, }, @@ -147,7 +148,7 @@ func TestBuildSyncers(t *testing.T) { givenConfig: config.Configuration{ExternalURL: "http://host.com", UserSync: config.UserSync{ExternalURL: "http://hostoverride.com", RedirectURL: "{{.ExternalURL}}/{{.SyncerKey}}/host"}}, givenBidderInfos: map[string]config.BidderInfo{"bidder1": infoKeyAPopulated}, expectedIFramesURLs: map[string]string{ - "bidder1": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhostoverride.com%2Fa%2Fhost", + "bidder1": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhostoverride.com%2Fbidder1%2Fhost", }, }, } From 8a96e3dc85beb3a31763f12334ef5ce8567ccecb Mon Sep 17 00:00:00 2001 From: Veronika Solovei Date: Wed, 26 Jul 2023 11:39:50 -0700 Subject: [PATCH 043/268] Added format script to simplify avoiding .semgrep directory (#2946) --- Makefile | 6 +++++- README.md | 9 +++++++++ scripts/format.sh | 34 ++++++++++++++++++++++++++++++++++ validate.sh | 24 +----------------------- 4 files changed, 49 insertions(+), 24 deletions(-) create mode 100755 scripts/format.sh diff --git a/Makefile b/Makefile index baf69cafbf8..b5b7281e5ed 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ all: deps test build-modules build -.PHONY: deps test build-modules build image +.PHONY: deps test build-modules build image format # deps will clean out the vendor directory and use go mod for a fresh install deps: @@ -29,3 +29,7 @@ build: test # image will build a docker image image: docker build -t prebid-server . + +# format runs format +format: + ./scripts/format.sh -f true \ No newline at end of file diff --git a/README.md b/README.md index 9b657f35db6..cb64ed9a3b1 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,15 @@ go build . ./prebid-server ``` +Run format: +``` +make format +``` +or +```bash +./scripts/format.sh -f true +``` + Load the landing page in your browser at `http://localhost:8000/`. For the full API reference, see [the endpoint documentation](https://docs.prebid.org/prebid-server/endpoints/pbs-endpoint-overview.html) diff --git a/scripts/format.sh b/scripts/format.sh new file mode 100755 index 00000000000..d5f33e517e4 --- /dev/null +++ b/scripts/format.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +die() { echo -e "$@" 1>&2 ; exit 1; } + +AUTOFMT=true +while getopts 'f:' OPTION; do + case "$OPTION" in + f) + AUTOFMT="$OPTARG" + ;; + esac +done + +# Build a list of all the top-level directories in the project. +for DIRECTORY in */ ; do + GOGLOB="$GOGLOB ${DIRECTORY%/}" +done +GOGLOB="${GOGLOB/ docs/}" +GOGLOB="${GOGLOB/ vendor/}" + +# Check that there are no formatting issues +GOFMT_LINES=`gofmt -s -l $GOGLOB | tr '\\\\' '/' | wc -l | xargs` +if $AUTOFMT; then + # if there are files with formatting issues, they will be automatically corrected using the gofmt -w command + if [[ $GOFMT_LINES -ne 0 ]]; then + FMT_FILES=`gofmt -s -l $GOGLOB | tr '\\\\' '/' | xargs` + for FILE in $FMT_FILES; do + echo "Running: gofmt -s -w $FILE" + `gofmt -s -w $FILE` + done + fi +else + test $GOFMT_LINES -eq 0 || die "gofmt needs to be run, ${GOFMT_LINES} files have issues. Below is a list of files to review:\n`gofmt -s -l $GOGLOB`" +fi \ No newline at end of file diff --git a/validate.sh b/validate.sh index b81ade344d2..becd42ceb50 100755 --- a/validate.sh +++ b/validate.sh @@ -17,29 +17,7 @@ while true; do esac done -die() { echo -e "$@" 1>&2 ; exit 1; } - -# Build a list of all the top-level directories in the project. -for DIRECTORY in */ ; do - GOGLOB="$GOGLOB ${DIRECTORY%/}" -done -GOGLOB="${GOGLOB/ docs/}" -GOGLOB="${GOGLOB/ vendor/}" - -# Check that there are no formatting issues -GOFMT_LINES=`gofmt -s -l $GOGLOB | tr '\\\\' '/' | wc -l | xargs` -if $AUTOFMT; then - # if there are files with formatting issues, they will be automatically corrected using the gofmt -w command - if [[ $GOFMT_LINES -ne 0 ]]; then - FMT_FILES=`gofmt -s -l $GOGLOB | tr '\\\\' '/' | xargs` - for FILE in $FMT_FILES; do - echo "Running: gofmt -s -w $FILE" - `gofmt -s -w $FILE` - done - fi -else - test $GOFMT_LINES -eq 0 || die "gofmt needs to be run, ${GOFMT_LINES} files have issues. Below is a list of files to review:\n`gofmt -s -l $GOGLOB`" -fi +./scripts/format.sh -f $AUTOFMT # Run the actual tests. Make sure there's enough coverage too, if the flags call for it. if $COVERAGE; then From b7221234778c3fe02d18712b63c19828d9c43e97 Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Thu, 27 Jul 2023 13:34:08 -0400 Subject: [PATCH 044/268] Prebid SDK Rendering API Extensions (#2972) --- .../request-ext-prebid-filtering.json | 16 ++++ exchange/utils.go | 7 +- exchange/utils_test.go | 12 +-- openrtb_ext/bid.go | 6 +- openrtb_ext/request.go | 77 +++++++++++-------- 5 files changed, 74 insertions(+), 44 deletions(-) diff --git a/exchange/exchangetest/request-ext-prebid-filtering.json b/exchange/exchangetest/request-ext-prebid-filtering.json index 499f779af26..4355f51762c 100644 --- a/exchange/exchangetest/request-ext-prebid-filtering.json +++ b/exchange/exchangetest/request-ext-prebid-filtering.json @@ -60,6 +60,14 @@ "rubicon": { "not": "permitted-for-appnexus" } + }, + "sdk": { + "renderers": [ + { + "name": "test-name", + "version": "test-version" + } + ] } } } @@ -108,6 +116,14 @@ "bidderparams": { "param1": 1, "paramA": "A" + }, + "sdk": { + "renderers": [ + { + "name": "test-name", + "version": "test-version" + } + ] } } } diff --git a/exchange/utils.go b/exchange/utils.go index 5b29fd6292f..8fd8f8c3ea4 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -363,12 +363,13 @@ func buildRequestExtForBidder(bidder string, requestExt json.RawMessage, request } if requestExtParsed != nil { - prebid.CurrencyConversions = requestExtParsed.Prebid.CurrencyConversions - prebid.Integration = requestExtParsed.Prebid.Integration prebid.Channel = requestExtParsed.Prebid.Channel + prebid.CurrencyConversions = requestExtParsed.Prebid.CurrencyConversions prebid.Debug = requestExtParsed.Prebid.Debug - prebid.Server = requestExtParsed.Prebid.Server + prebid.Integration = requestExtParsed.Prebid.Integration prebid.MultiBid = buildRequestExtMultiBid(bidder, requestExtParsed.Prebid.MultiBid, alternateBidderCodes) + prebid.Sdk = requestExtParsed.Prebid.Sdk + prebid.Server = requestExtParsed.Prebid.Server } // Marshal New Prebid Object diff --git a/exchange/utils_test.go b/exchange/utils_test.go index b62e9597e0b..a736dcfae08 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -2383,14 +2383,14 @@ func TestBuildRequestExtForBidder(t *testing.T) { { description: "Prebid - Allowed Fields Only", bidderParams: nil, - requestExt: json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}}}`), - expectedJson: json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}}}`), + requestExt: json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "sdk": {"renderers": [{"name": "r1"}]}}}`), + expectedJson: json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "sdk": {"renderers": [{"name": "r1"}]}}}`), }, { description: "Prebid - Allowed Fields + Bidder Params", bidderParams: map[string]json.RawMessage{bidder: bidderParams}, - requestExt: json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}}}`), - expectedJson: json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "bidderparams":"bar"}}`), + requestExt: json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "sdk": {"renderers": [{"name": "r1"}]}}}`), + expectedJson: json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "sdk": {"renderers": [{"name": "r1"}]}, "bidderparams":"bar"}}`), }, { description: "Other", @@ -2401,8 +2401,8 @@ func TestBuildRequestExtForBidder(t *testing.T) { { description: "Prebid + Other + Bider Params", bidderParams: map[string]json.RawMessage{bidder: bidderParams}, - requestExt: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}}}`), - expectedJson: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "bidderparams":"bar"}}`), + requestExt: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "sdk": {"renderers": [{"name": "r1"}]}}}`), + expectedJson: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "sdk": {"renderers": [{"name": "r1"}]}, "bidderparams":"bar"}}`), }, { description: "Prebid + AlternateBidderCodes in pbs config but current bidder not in AlternateBidderCodes config", diff --git a/openrtb_ext/bid.go b/openrtb_ext/bid.go index 20bbf0b3734..7dc620d46d7 100644 --- a/openrtb_ext/bid.go +++ b/openrtb_ext/bid.go @@ -50,6 +50,7 @@ type ExtBidPrebidCacheBids struct { // ExtBidPrebidMeta defines the contract for bidresponse.seatbid.bid[i].ext.prebid.meta type ExtBidPrebidMeta struct { + AdapterCode string `json:"adaptercode,omitempty"` AdvertiserDomains []string `json:"advertiserDomains,omitempty"` AdvertiserID int `json:"advertiserId,omitempty"` AdvertiserName string `json:"advertiserName,omitempty"` @@ -57,14 +58,15 @@ type ExtBidPrebidMeta struct { AgencyName string `json:"agencyName,omitempty"` BrandID int `json:"brandId,omitempty"` BrandName string `json:"brandName,omitempty"` - DemandSource string `json:"demandSource,omitempty"` DChain json.RawMessage `json:"dchain,omitempty"` + DemandSource string `json:"demandSource,omitempty"` MediaType string `json:"mediaType,omitempty"` NetworkID int `json:"networkId,omitempty"` NetworkName string `json:"networkName,omitempty"` PrimaryCategoryID string `json:"primaryCatId,omitempty"` + RendererName string `json:"rendererName,omitempty"` + RendererVersion string `json:"rendererVersion,omitempty"` SecondaryCategoryIDs []string `json:"secondaryCatIds,omitempty"` - AdapterCode string `json:"adaptercode,omitempty"` } // ExtBidPrebidVideo defines the contract for bidresponse.seatbid.bid[i].ext.prebid.video diff --git a/openrtb_ext/request.go b/openrtb_ext/request.go index adf00fcd169..6f39f0be288 100644 --- a/openrtb_ext/request.go +++ b/openrtb_ext/request.go @@ -41,52 +41,54 @@ type ExtRequest struct { // ExtRequestPrebid defines the contract for bidrequest.ext.prebid type ExtRequestPrebid struct { - Aliases map[string]string `json:"aliases,omitempty"` - AliasGVLIDs map[string]uint16 `json:"aliasgvlids,omitempty"` - BidAdjustmentFactors map[string]float64 `json:"bidadjustmentfactors,omitempty"` - BidderConfigs []BidderConfig `json:"bidderconfig,omitempty"` - BidderParams json.RawMessage `json:"bidderparams,omitempty"` - Cache *ExtRequestPrebidCache `json:"cache,omitempty"` - Channel *ExtRequestPrebidChannel `json:"channel,omitempty"` - CurrencyConversions *ExtRequestCurrency `json:"currency,omitempty"` - Data *ExtRequestPrebidData `json:"data,omitempty"` - Debug bool `json:"debug,omitempty"` - Events json.RawMessage `json:"events,omitempty"` - Experiment *Experiment `json:"experiment,omitempty"` - Integration string `json:"integration,omitempty"` - MultiBid []*ExtMultiBid `json:"multibid,omitempty"` - Passthrough json.RawMessage `json:"passthrough,omitempty"` - SChains []*ExtRequestPrebidSChain `json:"schains,omitempty"` - Server *ExtRequestPrebidServer `json:"server,omitempty"` - StoredRequest *ExtStoredRequest `json:"storedrequest,omitempty"` - SupportDeals bool `json:"supportdeals,omitempty"` - Targeting *ExtRequestTargeting `json:"targeting,omitempty"` + AdServerTargeting []AdServerTarget `json:"adservertargeting,omitempty"` + Aliases map[string]string `json:"aliases,omitempty"` + AliasGVLIDs map[string]uint16 `json:"aliasgvlids,omitempty"` + BidAdjustmentFactors map[string]float64 `json:"bidadjustmentfactors,omitempty"` + BidAdjustments *ExtRequestPrebidBidAdjustments `json:"bidadjustments,omitempty"` + BidderConfigs []BidderConfig `json:"bidderconfig,omitempty"` + BidderParams json.RawMessage `json:"bidderparams,omitempty"` + Cache *ExtRequestPrebidCache `json:"cache,omitempty"` + Channel *ExtRequestPrebidChannel `json:"channel,omitempty"` + CurrencyConversions *ExtRequestCurrency `json:"currency,omitempty"` + Data *ExtRequestPrebidData `json:"data,omitempty"` + Debug bool `json:"debug,omitempty"` + Events json.RawMessage `json:"events,omitempty"` + Experiment *Experiment `json:"experiment,omitempty"` + Floors *PriceFloorRules `json:"floors,omitempty"` + Integration string `json:"integration,omitempty"` + MultiBid []*ExtMultiBid `json:"multibid,omitempty"` + MultiBidMap map[string]ExtMultiBid `json:"-"` + Passthrough json.RawMessage `json:"passthrough,omitempty"` + SChains []*ExtRequestPrebidSChain `json:"schains,omitempty"` + Sdk *ExtRequestSdk `json:"sdk,omitempty"` + Server *ExtRequestPrebidServer `json:"server,omitempty"` + StoredRequest *ExtStoredRequest `json:"storedrequest,omitempty"` + SupportDeals bool `json:"supportdeals,omitempty"` + Targeting *ExtRequestTargeting `json:"targeting,omitempty"` + + //AlternateBidderCodes is populated with host's AlternateBidderCodes config if not defined in request + AlternateBidderCodes *ExtAlternateBidderCodes `json:"alternatebiddercodes,omitempty"` + + // Macros specifies list of custom macros along with the values. This is used while forming + // the tracker URLs, where PBS will replace the Custom Macro with its value with url-encoding + Macros map[string]string `json:"macros,omitempty"` // NoSale specifies bidders with whom the publisher has a legal relationship where the // passing of personally identifiable information doesn't constitute a sale per CCPA law. // The array may contain a single sstar ('*') entry to represent all bidders. NoSale []string `json:"nosale,omitempty"` - //AlternateBidderCodes is populated with host's AlternateBidderCodes config if not defined in request - AlternateBidderCodes *ExtAlternateBidderCodes `json:"alternatebiddercodes,omitempty"` + // ReturnAllBidStatus if true populates bidresponse.ext.prebid.seatnonbid with all bids which was + // either rejected, nobid, input error + ReturnAllBidStatus bool `json:"returnallbidstatus,omitempty"` - Floors *PriceFloorRules `json:"floors,omitempty"` - MultiBidMap map[string]ExtMultiBid `json:"-"` // Trace controls the level of detail in the output information returned from executing hooks. // There are two options: // - verbose: sets maximum level of output information // - basic: excludes debugmessages and analytic_tags from output // any other value or an empty string disables trace output at all. Trace string `json:"trace,omitempty"` - - // Macros specifies list of custom macros along with the values. This is used while forming - // the tracker URLs, where PBS will replace the Custom Macro with its value with url-encoding - Macros map[string]string `json:"macros,omitempty"` - AdServerTargeting []AdServerTarget `json:"adservertargeting,omitempty"` - BidAdjustments *ExtRequestPrebidBidAdjustments `json:"bidadjustments,omitempty"` - // ReturnAllBidStatus if true populates bidresponse.ext.prebid.seatnonbid with all bids which was - // either rejected, nobid, input error - ReturnAllBidStatus bool `json:"returnallbidstatus,omitempty"` } type AdServerTarget struct { @@ -345,6 +347,15 @@ type ExtRequestPrebidDataEidPermission struct { Bidders []string `json:"bidders"` } +type ExtRequestSdk struct { + Renderers []ExtRequestSdkRenderer `json:"renderers,omitempty"` +} + +type ExtRequestSdkRenderer struct { + Name string `json:"name,omitempty"` + Version string `json:"version,omitempty"` +} + type ExtMultiBid struct { Bidder string `json:"bidder,omitempty"` Bidders []string `json:"bidders,omitempty"` From 9d72dbe2a505a8a2b635ac103b77c7be2c2bcd06 Mon Sep 17 00:00:00 2001 From: Veronika Solovei Date: Thu, 27 Jul 2023 12:57:46 -0700 Subject: [PATCH 045/268] TransmitUserFPD and TransmitPreciseGeo activity integration (#2906) --- exchange/utils.go | 81 ++++++++---- exchange/utils_test.go | 137 +++++++++++++++----- privacy/enforcement.go | 25 +++- privacy/enforcement_test.go | 140 ++++++++++++++++++++- privacy/enforcer.go | 4 - privacy/enforcer_test.go | 2 +- privacy/scrubber.go | 115 +++++++++++++++-- privacy/scrubber_test.go | 240 +++++++++++++++++++++++++++++++----- 8 files changed, 629 insertions(+), 115 deletions(-) diff --git a/exchange/utils.go b/exchange/utils.go index 8fd8f8c3ea4..e70f52490fc 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -112,15 +112,13 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, lmtEnforcer := extractLMT(req.BidRequest, rs.privacyConfig) // request level privacy policies - privacyEnforcement := privacy.Enforcement{ - COPPA: req.BidRequest.Regs != nil && req.BidRequest.Regs.COPPA == 1, - LMT: lmtEnforcer.ShouldEnforce(unknownBidder), - } + coppa := req.BidRequest.Regs != nil && req.BidRequest.Regs.COPPA == 1 + lmt := lmtEnforcer.ShouldEnforce(unknownBidder) privacyLabels.CCPAProvided = ccpaEnforcer.CanEnforce() privacyLabels.CCPAEnforced = ccpaEnforcer.ShouldEnforce(unknownBidder) - privacyLabels.COPPAEnforced = privacyEnforcement.COPPA - privacyLabels.LMTEnforced = lmtEnforcer.ShouldEnforce(unknownBidder) + privacyLabels.COPPAEnforced = coppa + privacyLabels.LMTEnforced = lmt var gdprEnforced bool var gdprPerms gdpr.Permissions = &gdpr.AlwaysAllow{} @@ -148,46 +146,75 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, // bidder level privacy policies for _, bidderRequest := range allBidderRequests { - bidRequestAllowed := true + privacyEnforcement := privacy.Enforcement{ + COPPA: coppa, + LMT: lmt, + } // fetchBids activity - fetchBidsActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityFetchBids, - privacy.ScopedName{Scope: privacy.ScopeTypeBidder, Name: bidderRequest.BidderName.String()}) + scopedName := privacy.ScopedName{Scope: privacy.ScopeTypeBidder, Name: bidderRequest.BidderName.String()} + fetchBidsActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityFetchBids, scopedName) if fetchBidsActivityAllowed == privacy.ActivityDeny { // skip the call to a bidder if fetchBids activity is not allowed // do not add this bidder to allowedBidderRequests continue } - // CCPA - privacyEnforcement.CCPA = ccpaEnforcer.ShouldEnforce(bidderRequest.BidderName.String()) + var auctionPermissions gdpr.AuctionPermissions + var gdprErr error - // GDPR if gdprEnforced { - auctionPermissions, err := gdprPerms.AuctionActivitiesAllowed(ctx, bidderRequest.BidderCoreName, bidderRequest.BidderName) - bidRequestAllowed = auctionPermissions.AllowBidRequest - - if err == nil { - privacyEnforcement.GDPRGeo = !auctionPermissions.PassGeo - privacyEnforcement.GDPRID = !auctionPermissions.PassID - } else { - privacyEnforcement.GDPRGeo = true - privacyEnforcement.GDPRID = true + auctionPermissions, gdprErr = gdprPerms.AuctionActivitiesAllowed(ctx, bidderRequest.BidderCoreName, bidderRequest.BidderName) + if !auctionPermissions.AllowBidRequest { + // auction request is not permitted by GDPR + // do not add this bidder to allowedBidderRequests + rs.me.RecordAdapterGDPRRequestBlocked(bidderRequest.BidderCoreName) + continue } + } - if !bidRequestAllowed { - rs.me.RecordAdapterGDPRRequestBlocked(bidderRequest.BidderCoreName) + passIDActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitUserFPD, scopedName) + if passIDActivityAllowed == privacy.ActivityDeny { + privacyEnforcement.UFPD = true + } else { + // run existing policies (GDPR, CCPA, COPPA, LMT) + // potentially block passing IDs based on GDPR + if gdprEnforced { + if gdprErr == nil { + privacyEnforcement.GDPRID = !auctionPermissions.PassID + } else { + privacyEnforcement.GDPRID = true + } } + // potentially block passing IDs based on CCPA + privacyEnforcement.CCPA = ccpaEnforcer.ShouldEnforce(bidderRequest.BidderName.String()) + } + + passGeoActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitPreciseGeo, scopedName) + if passGeoActivityAllowed == privacy.ActivityDeny { + privacyEnforcement.PreciseGeo = true + } else { + // run existing policies (GDPR, CCPA, COPPA, LMT) + // potentially block passing geo based on GDPR + if gdprEnforced { + if gdprErr == nil { + privacyEnforcement.GDPRGeo = !auctionPermissions.PassGeo + } else { + privacyEnforcement.GDPRGeo = true + } + } + // potentially block passing geo based on CCPA + privacyEnforcement.CCPA = ccpaEnforcer.ShouldEnforce(bidderRequest.BidderName.String()) + } if auctionReq.FirstPartyData != nil && auctionReq.FirstPartyData[bidderRequest.BidderName] != nil { applyFPD(auctionReq.FirstPartyData[bidderRequest.BidderName], bidderRequest.BidRequest) } - if bidRequestAllowed { - privacyEnforcement.Apply(bidderRequest.BidRequest) - allowedBidderRequests = append(allowedBidderRequests, bidderRequest) - } + privacyEnforcement.Apply(bidderRequest.BidRequest) + allowedBidderRequests = append(allowedBidderRequests, bidderRequest) + // GPP downgrade: always downgrade unless we can confirm GPP is supported if shouldSetLegacyPrivacy(rs.bidderInfo, string(bidderRequest.BidderCoreName)) { setLegacyGDPRFromGPP(bidderRequest.BidRequest, gpp) diff --git a/exchange/utils_test.go b/exchange/utils_test.go index a736dcfae08..aff1b3c09a1 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -2287,6 +2287,7 @@ func TestCleanOpenRTBRequestsWithOpenRTBDowngrade(t *testing.T) { bidReq.User.ID = "" bidReq.User.BuyerUID = "" bidReq.User.Yob = 0 + bidReq.User.Geo = &openrtb2.Geo{Lat: 123.46} downgradedRegs := *bidReq.Regs downgradedUser := *bidReq.User @@ -2601,6 +2602,7 @@ func newBidRequest(t *testing.T) *openrtb2.BidRequest { BuyerUID: "their-id", Yob: 1982, Ext: json.RawMessage(`{}`), + Geo: &openrtb2.Geo{Lat: 123.456}, }, Imp: []openrtb2.Imp{{ ID: "some-imp-id", @@ -4266,33 +4268,76 @@ func TestGetMediaTypeForBid(t *testing.T) { } } -func TemporarilyDisabledTestCleanOpenRTBRequestsActivitiesFetchBids(t *testing.T) { +func TestCleanOpenRTBRequestsActivitiesFetchBids(t *testing.T) { testCases := []struct { - name string - req *openrtb2.BidRequest - componentName string - allow bool - expectedReqNumber int + name string + req *openrtb2.BidRequest + privacyConfig *config.AccountPrivacy + componentName string + allow bool + expectedReqNumber int + expectedUserYOB int64 + expectedUserLat float64 + expectedDeviceDIDMD5 string }{ { - name: "request_with_one_bidder_allowed", - req: newBidRequest(t), - componentName: "appnexus", - allow: true, - expectedReqNumber: 1, - }, - { - name: "request_with_one_bidder_not_allowed", - req: newBidRequest(t), - componentName: "appnexus", - allow: false, - expectedReqNumber: 0, + name: "fetch_bids_request_with_one_bidder_allowed", + req: newBidRequest(t), + privacyConfig: getFetchBidsActivityConfig("appnexus", true), + expectedReqNumber: 1, + expectedUserYOB: 1982, + expectedUserLat: 123.456, + expectedDeviceDIDMD5: "some device ID hash", + }, + { + name: "fetch_bids_request_with_one_bidder_not_allowed", + req: newBidRequest(t), + privacyConfig: getFetchBidsActivityConfig("appnexus", false), + expectedReqNumber: 0, + expectedUserYOB: 1982, + expectedUserLat: 123.456, + expectedDeviceDIDMD5: "some device ID hash", + }, + { + name: "transmit_ufpd_allowed", + req: newBidRequest(t), + privacyConfig: getTransmitUFPDActivityConfig("appnexus", true), + expectedReqNumber: 1, + expectedUserYOB: 1982, + expectedUserLat: 123.456, + expectedDeviceDIDMD5: "some device ID hash", + }, + { + name: "transmit_ufpd_deny", + req: newBidRequest(t), + privacyConfig: getTransmitUFPDActivityConfig("appnexus", false), + expectedReqNumber: 1, + expectedUserYOB: 0, + expectedUserLat: 123.456, + expectedDeviceDIDMD5: "", + }, + { + name: "transmit_precise_geo_allowed", + req: newBidRequest(t), + privacyConfig: getTransmitPreciseGeoActivityConfig("appnexus", true), + expectedReqNumber: 1, + expectedUserYOB: 1982, + expectedUserLat: 123.456, + expectedDeviceDIDMD5: "some device ID hash", + }, + { + name: "transmit_precise_geo_deny", + req: newBidRequest(t), + privacyConfig: getTransmitPreciseGeoActivityConfig("appnexus", false), + expectedReqNumber: 1, + expectedUserYOB: 1982, + expectedUserLat: 123.46, + expectedDeviceDIDMD5: "some device ID hash", }, } for _, test := range testCases { - privacyConfig := getDefaultActivityConfig(test.componentName, test.allow) - activities, err := privacy.NewActivityControl(privacyConfig) + activities, err := privacy.NewActivityControl(test.privacyConfig) assert.NoError(t, err, "") auctionReq := AuctionRequest{ BidRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: test.req}, @@ -4312,25 +4357,51 @@ func TemporarilyDisabledTestCleanOpenRTBRequestsActivitiesFetchBids(t *testing.T bidderRequests, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, nil, gdpr.SignalNo) assert.Empty(t, errs) assert.Len(t, bidderRequests, test.expectedReqNumber) + + if test.expectedReqNumber == 1 { + assert.Equal(t, test.expectedUserYOB, bidderRequests[0].BidRequest.User.Yob) + assert.Equal(t, test.expectedUserLat, bidderRequests[0].BidRequest.User.Geo.Lat) + assert.Equal(t, test.expectedDeviceDIDMD5, bidderRequests[0].BidRequest.Device.DIDMD5) + } }) } } -func getDefaultActivityConfig(componentName string, allow bool) *config.AccountPrivacy { - return &config.AccountPrivacy{ - AllowActivities: config.AllowActivities{ - FetchBids: config.Activity{ - Default: ptrutil.ToPtr(true), - Rules: []config.ActivityRule{ - { - Allow: allow, - Condition: config.ActivityCondition{ - ComponentName: []string{componentName}, - ComponentType: []string{"bidder"}, - }, - }, +func buildDefaultActivityConfig(componentName string, allow bool) config.Activity { + return config.Activity{ + Default: ptrutil.ToPtr(true), + Rules: []config.ActivityRule{ + { + Allow: allow, + Condition: config.ActivityCondition{ + ComponentName: []string{componentName}, + ComponentType: []string{"bidder"}, }, }, }, } } + +func getFetchBidsActivityConfig(componentName string, allow bool) *config.AccountPrivacy { + return &config.AccountPrivacy{ + AllowActivities: config.AllowActivities{ + FetchBids: buildDefaultActivityConfig(componentName, allow), + }, + } +} + +func getTransmitUFPDActivityConfig(componentName string, allow bool) *config.AccountPrivacy { + return &config.AccountPrivacy{ + AllowActivities: config.AllowActivities{ + TransmitUserFPD: buildDefaultActivityConfig(componentName, allow), + }, + } +} + +func getTransmitPreciseGeoActivityConfig(componentName string, allow bool) *config.AccountPrivacy { + return &config.AccountPrivacy{ + AllowActivities: config.AllowActivities{ + TransmitPreciseGeo: buildDefaultActivityConfig(componentName, allow), + }, + } +} diff --git a/privacy/enforcement.go b/privacy/enforcement.go index 50d42e89435..1a66cfab929 100644 --- a/privacy/enforcement.go +++ b/privacy/enforcement.go @@ -9,22 +9,39 @@ type Enforcement struct { GDPRGeo bool GDPRID bool LMT bool + + // activities + UFPD bool + Eids bool + PreciseGeo bool + TID bool } // Any returns true if at least one privacy policy requires enforcement. -func (e Enforcement) Any() bool { +func (e Enforcement) AnyLegacy() bool { return e.CCPA || e.COPPA || e.GDPRGeo || e.GDPRID || e.LMT } +func (e Enforcement) AnyActivities() bool { + return e.UFPD || e.PreciseGeo || e.Eids || e.TID +} + // Apply cleans personally identifiable information from an OpenRTB bid request. func (e Enforcement) Apply(bidRequest *openrtb2.BidRequest) { e.apply(bidRequest, NewScrubber()) } func (e Enforcement) apply(bidRequest *openrtb2.BidRequest, scrubber Scrubber) { - if bidRequest != nil && e.Any() { - bidRequest.Device = scrubber.ScrubDevice(bidRequest.Device, e.getDeviceIDScrubStrategy(), e.getIPv4ScrubStrategy(), e.getIPv6ScrubStrategy(), e.getGeoScrubStrategy()) - bidRequest.User = scrubber.ScrubUser(bidRequest.User, e.getUserScrubStrategy(), e.getGeoScrubStrategy()) + if bidRequest != nil { + if e.AnyActivities() { + bidRequest = scrubber.ScrubRequest(bidRequest, e) + } + if e.AnyLegacy() && !(e.UFPD && e.PreciseGeo && e.Eids) { + bidRequest.User = scrubber.ScrubUser(bidRequest.User, e.getUserScrubStrategy(), e.getGeoScrubStrategy()) + } + if e.AnyLegacy() && !(e.UFPD && e.PreciseGeo) { + bidRequest.Device = scrubber.ScrubDevice(bidRequest.Device, e.getDeviceIDScrubStrategy(), e.getIPv4ScrubStrategy(), e.getIPv6ScrubStrategy(), e.getGeoScrubStrategy()) + } } } diff --git a/privacy/enforcement_test.go b/privacy/enforcement_test.go index a9d7ca9275a..be1ab0dca9f 100644 --- a/privacy/enforcement_test.go +++ b/privacy/enforcement_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/mock" ) -func TestAny(t *testing.T) { +func TestAnyLegacy(t *testing.T) { testCases := []struct { enforcement Enforcement expected bool @@ -50,12 +50,12 @@ func TestAny(t *testing.T) { } for _, test := range testCases { - result := test.enforcement.Any() + result := test.enforcement.AnyLegacy() assert.Equal(t, test.expected, result, test.description) } } -func TestApply(t *testing.T) { +func TestApplyGDPR(t *testing.T) { testCases := []struct { description string enforcement Enforcement @@ -216,6 +216,130 @@ func TestApply(t *testing.T) { } } +func TestApplyToggle(t *testing.T) { + testCases := []struct { + description string + enforcement Enforcement + expectedScrubRequestExecuted bool + expectedScrubUserExecuted bool + expectedScrubDeviceExecuted bool + }{ + { + description: "All enforced - only ScrubRequest execution expected", + enforcement: Enforcement{ + CCPA: true, + COPPA: true, + GDPRGeo: true, + GDPRID: true, + LMT: true, + UFPD: true, + Eids: true, + PreciseGeo: true, + TID: true, + }, + expectedScrubRequestExecuted: true, + expectedScrubUserExecuted: false, + expectedScrubDeviceExecuted: false, + }, + { + description: "All Legacy and no activities - ScrubUser and ScrubDevice execution expected", + enforcement: Enforcement{ + CCPA: true, + COPPA: true, + GDPRGeo: true, + GDPRID: true, + LMT: true, + UFPD: false, + Eids: false, + PreciseGeo: false, + TID: false, + }, + expectedScrubRequestExecuted: false, + expectedScrubUserExecuted: true, + expectedScrubDeviceExecuted: true, + }, + { + description: "Some Legacy and some activities - ScrubRequest, ScrubUser and ScrubDevice execution expected", + enforcement: Enforcement{ + CCPA: true, + COPPA: true, + GDPRGeo: true, + GDPRID: true, + LMT: true, + UFPD: true, + Eids: false, + PreciseGeo: false, + TID: false, + }, + expectedScrubRequestExecuted: true, + expectedScrubUserExecuted: true, + expectedScrubDeviceExecuted: true, + }, + { + description: "Some Legacy and some activities - ScrubRequest execution expected", + enforcement: Enforcement{ + CCPA: true, + COPPA: true, + GDPRGeo: true, + GDPRID: true, + LMT: true, + UFPD: true, + Eids: true, + PreciseGeo: true, + TID: false, + }, + expectedScrubRequestExecuted: true, + expectedScrubUserExecuted: false, + expectedScrubDeviceExecuted: false, + }, + { + description: "Some Legacy and some activities overlap - ScrubRequest and ScrubUser execution expected", + enforcement: Enforcement{ + CCPA: true, + COPPA: true, + GDPRGeo: true, + GDPRID: true, + LMT: true, + UFPD: true, + Eids: false, + PreciseGeo: true, + TID: false, + }, + expectedScrubRequestExecuted: true, + expectedScrubUserExecuted: true, + expectedScrubDeviceExecuted: false, + }, + } + + for _, test := range testCases { + t.Run(test.description, func(t *testing.T) { + req := &openrtb2.BidRequest{ + Device: &openrtb2.Device{}, + User: &openrtb2.User{}, + } + replacedDevice := &openrtb2.Device{} + replacedUser := &openrtb2.User{} + + m := &mockScrubber{} + + if test.expectedScrubRequestExecuted { + m.On("ScrubRequest", req, test.enforcement).Return(req).Once() + } + if test.expectedScrubUserExecuted { + m.On("ScrubUser", req.User, ScrubStrategyUserIDAndDemographic, ScrubStrategyGeoFull).Return(replacedUser).Once() + } + if test.expectedScrubDeviceExecuted { + m.On("ScrubDevice", req.Device, ScrubStrategyDeviceIDAll, ScrubStrategyIPV4Lowest8, ScrubStrategyIPV6Lowest32, ScrubStrategyGeoFull).Return(replacedDevice).Once() + } + + test.enforcement.apply(req, m) + + m.AssertExpectations(t) + + }) + } +} + func TestApplyNoneApplicable(t *testing.T) { req := &openrtb2.BidRequest{} @@ -227,6 +351,11 @@ func TestApplyNoneApplicable(t *testing.T) { GDPRGeo: false, GDPRID: false, LMT: false, + + UFPD: false, + PreciseGeo: false, + TID: false, + Eids: false, } enforcement.apply(req, m) @@ -248,6 +377,11 @@ type mockScrubber struct { mock.Mock } +func (m *mockScrubber) ScrubRequest(bidRequest *openrtb2.BidRequest, enforcement Enforcement) *openrtb2.BidRequest { + args := m.Called(bidRequest, enforcement) + return args.Get(0).(*openrtb2.BidRequest) +} + func (m *mockScrubber) ScrubDevice(device *openrtb2.Device, id ScrubStrategyDeviceID, ipv4 ScrubStrategyIPV4, ipv6 ScrubStrategyIPV6, geo ScrubStrategyGeo) *openrtb2.Device { args := m.Called(device, id, ipv4, ipv6, geo) return args.Get(0).(*openrtb2.Device) diff --git a/privacy/enforcer.go b/privacy/enforcer.go index d63cd8de31f..a8685e29276 100644 --- a/privacy/enforcer.go +++ b/privacy/enforcer.go @@ -3,7 +3,6 @@ package privacy import ( "fmt" "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" "strings" ) @@ -33,9 +32,6 @@ func NewActivityControl(privacyConf *config.AccountPrivacy) (ActivityControl, er if privacyConf == nil { return ac, err - } else { - //temporarily disable Activities if they are specified at the account level - return ac, &errortypes.Warning{Message: "account.Privacy has no effect as the feature is under development."} } plans := make(map[Activity]ActivityPlan) diff --git a/privacy/enforcer_test.go b/privacy/enforcer_test.go index e87a9eb2bff..2b9715f87f8 100644 --- a/privacy/enforcer_test.go +++ b/privacy/enforcer_test.go @@ -8,7 +8,7 @@ import ( "testing" ) -func TemporarilyDisabledTestNewActivityControl(t *testing.T) { +func TestNewActivityControl(t *testing.T) { testCases := []struct { name string diff --git a/privacy/scrubber.go b/privacy/scrubber.go index 428193bcda1..97419128952 100644 --- a/privacy/scrubber.go +++ b/privacy/scrubber.go @@ -2,6 +2,7 @@ package privacy import ( "encoding/json" + "github.com/prebid/prebid-server/util/ptrutil" "strings" "github.com/prebid/openrtb/v19/openrtb2" @@ -70,6 +71,7 @@ const ( // Scrubber removes PII from parts of an OpenRTB request. type Scrubber interface { + ScrubRequest(bidRequest *openrtb2.BidRequest, enforcement Enforcement) *openrtb2.BidRequest ScrubDevice(device *openrtb2.Device, id ScrubStrategyDeviceID, ipv4 ScrubStrategyIPV4, ipv6 ScrubStrategyIPV6, geo ScrubStrategyGeo) *openrtb2.Device ScrubUser(user *openrtb2.User, strategy ScrubStrategyUser, geo ScrubStrategyGeo) *openrtb2.User } @@ -81,6 +83,99 @@ func NewScrubber() Scrubber { return scrubber{} } +func (scrubber) ScrubRequest(bidRequest *openrtb2.BidRequest, enforcement Enforcement) *openrtb2.BidRequest { + var userExtParsed map[string]json.RawMessage + userExtModified := false + + var userCopy *openrtb2.User + userCopy = ptrutil.Clone(bidRequest.User) + + var deviceCopy *openrtb2.Device + deviceCopy = ptrutil.Clone(bidRequest.Device) + + if userCopy != nil && (enforcement.UFPD || enforcement.Eids) { + if len(userCopy.Ext) != 0 { + json.Unmarshal(userCopy.Ext, &userExtParsed) + } + } + + if enforcement.UFPD { + // transmitUfpd covers user.ext.data, user.data, user.id, user.buyeruid, user.yob, user.gender, user.keywords, user.kwarray + // and device.{ifa, macsha1, macmd5, dpidsha1, dpidmd5, didsha1, didmd5} + if deviceCopy != nil { + deviceCopy.DIDMD5 = "" + deviceCopy.DIDSHA1 = "" + deviceCopy.DPIDMD5 = "" + deviceCopy.DPIDSHA1 = "" + deviceCopy.IFA = "" + deviceCopy.MACMD5 = "" + deviceCopy.MACSHA1 = "" + } + if userCopy != nil { + userCopy.Data = nil + userCopy.ID = "" + userCopy.BuyerUID = "" + userCopy.Yob = 0 + userCopy.Gender = "" + userCopy.Keywords = "" + userCopy.KwArray = nil + + _, hasField := userExtParsed["data"] + if hasField { + delete(userExtParsed, "data") + userExtModified = true + } + } + } + if enforcement.Eids { + //transmitEids covers user.eids and user.ext.eids + if userCopy != nil { + userCopy.EIDs = nil + _, hasField := userExtParsed["eids"] + if hasField { + delete(userExtParsed, "eids") + userExtModified = true + } + } + } + + if userExtModified { + userExt, _ := json.Marshal(userExtParsed) + userCopy.Ext = userExt + } + + if enforcement.TID { + //remove source.tid and imp.ext.tid + if bidRequest.Source != nil { + bidRequest.Source.TID = "" + } + for ind, imp := range bidRequest.Imp { + impExt := scrubExtIDs(imp.Ext, "tid") + bidRequest.Imp[ind].Ext = impExt + } + } + + if enforcement.PreciseGeo { + //round user's geographic location by rounding off IP address and lat/lng data. + //this applies to both device.geo and user.geo + if userCopy != nil && userCopy.Geo != nil { + userCopy.Geo = scrubGeoPrecision(userCopy.Geo) + } + + if deviceCopy != nil { + if deviceCopy.Geo != nil { + deviceCopy.Geo = scrubGeoPrecision(deviceCopy.Geo) + } + deviceCopy.IP = scrubIPV4Lowest8(deviceCopy.IP) + deviceCopy.IPv6 = scrubIPV6Lowest32Bits(deviceCopy.IPv6) + } + } + + bidRequest.Device = deviceCopy + bidRequest.User = userCopy + return bidRequest +} + func (scrubber) ScrubDevice(device *openrtb2.Device, id ScrubStrategyDeviceID, ipv4 ScrubStrategyIPV4, ipv6 ScrubStrategyIPV6, geo ScrubStrategyGeo) *openrtb2.Device { if device == nil { return nil @@ -131,7 +226,7 @@ func (scrubber) ScrubUser(user *openrtb2.User, strategy ScrubStrategyUser, geo S if strategy == ScrubStrategyUserIDAndDemographic { userCopy.BuyerUID = "" userCopy.ID = "" - userCopy.Ext = scrubUserExtIDs(userCopy.Ext) + userCopy.Ext = scrubExtIDs(userCopy.Ext, "eids") userCopy.Yob = 0 userCopy.Gender = "" } @@ -205,25 +300,25 @@ func scrubGeoPrecision(geo *openrtb2.Geo) *openrtb2.Geo { return &geoCopy } -func scrubUserExtIDs(userExt json.RawMessage) json.RawMessage { - if len(userExt) == 0 { - return userExt +func scrubExtIDs(ext json.RawMessage, fieldName string) json.RawMessage { + if len(ext) == 0 { + return ext } var userExtParsed map[string]json.RawMessage - err := json.Unmarshal(userExt, &userExtParsed) + err := json.Unmarshal(ext, &userExtParsed) if err != nil { - return userExt + return ext } - _, hasEids := userExtParsed["eids"] - if hasEids { - delete(userExtParsed, "eids") + _, hasField := userExtParsed[fieldName] + if hasField { + delete(userExtParsed, fieldName) result, err := json.Marshal(userExtParsed) if err == nil { return result } } - return userExt + return ext } diff --git a/privacy/scrubber_test.go b/privacy/scrubber_test.go index 7b4afac247e..0691b2c7a2c 100644 --- a/privacy/scrubber_test.go +++ b/privacy/scrubber_test.go @@ -9,24 +9,7 @@ import ( ) func TestScrubDevice(t *testing.T) { - device := &openrtb2.Device{ - DIDMD5: "anyDIDMD5", - DIDSHA1: "anyDIDSHA1", - DPIDMD5: "anyDPIDMD5", - DPIDSHA1: "anyDPIDSHA1", - MACSHA1: "anyMACSHA1", - MACMD5: "anyMACMD5", - IFA: "anyIFA", - IP: "1.2.3.4", - IPv6: "2001:0db8:0000:0000:0000:ff00:0042:8329", - Geo: &openrtb2.Geo{ - Lat: 123.456, - Lon: 678.89, - Metro: "some metro", - City: "some city", - ZIP: "some zip", - }, - } + device := getTestDevice() testCases := []struct { description string @@ -197,20 +180,7 @@ func TestScrubDeviceNil(t *testing.T) { } func TestScrubUser(t *testing.T) { - user := &openrtb2.User{ - ID: "anyID", - BuyerUID: "anyBuyerUID", - Yob: 42, - Gender: "anyGender", - Ext: json.RawMessage(`{}`), - Geo: &openrtb2.Geo{ - Lat: 123.456, - Lon: 678.89, - Metro: "some metro", - City: "some city", - ZIP: "some zip", - }, - } + user := getTestUser() testCases := []struct { description string @@ -333,6 +303,171 @@ func TestScrubUserNil(t *testing.T) { assert.Nil(t, result) } +func TestScrubRequest(t *testing.T) { + + imps := []openrtb2.Imp{ + {ID: "testId", Ext: json.RawMessage(`{"test": 1, "tid": 2}`)}, + } + source := &openrtb2.Source{ + TID: "testTid", + } + device := getTestDevice() + user := getTestUser() + user.Ext = json.RawMessage(`{"data": 1, "eids": 2}`) + user.EIDs = []openrtb2.EID{{Source: "test"}} + + testCases := []struct { + description string + enforcement Enforcement + userExtPresent bool + expected *openrtb2.BidRequest + }{ + { + description: "enforce transmitUFPD with user.ext", + enforcement: Enforcement{UFPD: true}, + userExtPresent: true, + expected: &openrtb2.BidRequest{ + Imp: imps, + Source: source, + User: &openrtb2.User{ + EIDs: []openrtb2.EID{{Source: "test"}}, + Geo: user.Geo, + Ext: json.RawMessage(`{"eids":2}`), + }, + Device: &openrtb2.Device{ + IP: "1.2.3.4", + IPv6: "2001:0db8:0000:0000:0000:ff00:0042:8329", + Geo: device.Geo, + }, + }, + }, + { + description: "enforce transmitUFPD without user.ext", + enforcement: Enforcement{UFPD: true}, + userExtPresent: false, + expected: &openrtb2.BidRequest{ + Imp: imps, + Source: source, + User: &openrtb2.User{ + EIDs: []openrtb2.EID{{Source: "test"}}, + Geo: user.Geo, + }, + Device: &openrtb2.Device{ + IP: "1.2.3.4", + IPv6: "2001:0db8:0000:0000:0000:ff00:0042:8329", + Geo: device.Geo, + }, + }, + }, + { + description: "enforce transmitEids", + enforcement: Enforcement{Eids: true}, + userExtPresent: true, + expected: &openrtb2.BidRequest{ + Imp: imps, + Source: source, + Device: device, + User: &openrtb2.User{ + ID: "anyID", + BuyerUID: "anyBuyerUID", + Yob: 42, + Gender: "anyGender", + Geo: user.Geo, + EIDs: nil, + Ext: json.RawMessage(`{"data":1}`), + }, + }, + }, + { + description: "enforce transmitTid", + enforcement: Enforcement{TID: true}, + userExtPresent: true, + expected: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "testId", Ext: json.RawMessage(`{"test":1}`)}, + }, + Source: &openrtb2.Source{ + TID: "", + }, + Device: device, + User: &openrtb2.User{ + ID: "anyID", + BuyerUID: "anyBuyerUID", + Yob: 42, + Gender: "anyGender", + Geo: user.Geo, + EIDs: []openrtb2.EID{{Source: "test"}}, + Ext: json.RawMessage(`{"data": 1, "eids": 2}`), + }, + }, + }, + { + description: "enforce precise Geo", + enforcement: Enforcement{PreciseGeo: true}, + userExtPresent: true, + expected: &openrtb2.BidRequest{ + Imp: imps, + Source: source, + User: &openrtb2.User{ + ID: "anyID", + BuyerUID: "anyBuyerUID", + Yob: 42, + Gender: "anyGender", + Geo: &openrtb2.Geo{ + Lat: 123.46, Lon: 678.89, + Metro: "some metro", + City: "some city", + ZIP: "some zip", + }, + EIDs: []openrtb2.EID{{Source: "test"}}, + Ext: json.RawMessage(`{"data": 1, "eids": 2}`), + }, + Device: &openrtb2.Device{ + IFA: "anyIFA", + DIDSHA1: "anyDIDSHA1", + DIDMD5: "anyDIDMD5", + DPIDSHA1: "anyDPIDSHA1", + DPIDMD5: "anyDPIDMD5", + MACSHA1: "anyMACSHA1", + MACMD5: "anyMACMD5", + IP: "1.2.3.0", + IPv6: "2001:0db8:0000:0000:0000:ff00:0:0", + Geo: &openrtb2.Geo{ + Lat: 123.46, Lon: 678.89, + Metro: "some metro", + City: "some city", + ZIP: "some zip", + }, + }, + }, + }, + } + + for _, test := range testCases { + t.Run(test.description, func(t *testing.T) { + bidRequest := &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "testId", Ext: json.RawMessage(`{"test": 1, "tid": 2}`)}, + }, + Source: &openrtb2.Source{ + TID: "testTid", + }, + User: getTestUser(), + Device: getTestDevice(), + } + if test.userExtPresent { + bidRequest.User.Ext = json.RawMessage(`{"data": 1, "eids": 2}`) + } else { + bidRequest.User.Ext = nil + } + bidRequest.User.EIDs = []openrtb2.EID{{Source: "test"}} + + result := NewScrubber().ScrubRequest(bidRequest, test.enforcement) + assert.Equal(t, test.expected, result, test.description) + }) + } +} + func TestScrubIPV4(t *testing.T) { testCases := []struct { IP string @@ -572,7 +707,46 @@ func TestScrubUserExtIDs(t *testing.T) { } for _, test := range testCases { - result := scrubUserExtIDs(test.userExt) + result := scrubExtIDs(test.userExt, "eids") assert.Equal(t, test.expected, result, test.description) } } + +func getTestUser() *openrtb2.User { + return &openrtb2.User{ + ID: "anyID", + BuyerUID: "anyBuyerUID", + Yob: 42, + Gender: "anyGender", + Ext: json.RawMessage(`{}`), + Geo: &openrtb2.Geo{ + Lat: 123.456, + Lon: 678.89, + Metro: "some metro", + City: "some city", + ZIP: "some zip", + }, + } +} + +func getTestDevice() *openrtb2.Device { + return &openrtb2.Device{ + DIDMD5: "anyDIDMD5", + DIDSHA1: "anyDIDSHA1", + DPIDMD5: "anyDPIDMD5", + DPIDSHA1: "anyDPIDSHA1", + MACSHA1: "anyMACSHA1", + MACMD5: "anyMACMD5", + IFA: "anyIFA", + IP: "1.2.3.4", + IPv6: "2001:0db8:0000:0000:0000:ff00:0042:8329", + Geo: &openrtb2.Geo{ + Lat: 123.456, + Lon: 678.89, + Metro: "some metro", + City: "some city", + ZIP: "some zip", + }, + } + +} From 555c0a1f39b7252833fe513693eae2e45aefe33f Mon Sep 17 00:00:00 2001 From: Veronika Solovei Date: Thu, 27 Jul 2023 16:54:27 -0700 Subject: [PATCH 046/268] UserSync activity (#2897) --- endpoints/cookie_sync.go | 15 ++++++ endpoints/cookie_sync_test.go | 92 ++++++++++++++++++++++++++++++++++- endpoints/setuid.go | 26 +++++++--- endpoints/setuid_test.go | 33 +++++++++++++ privacy/enforcer.go | 2 +- usersync/chooser.go | 9 ++++ usersync/chooser_test.go | 61 ++++++++++++++--------- 7 files changed, 205 insertions(+), 33 deletions(-) diff --git a/endpoints/cookie_sync.go b/endpoints/cookie_sync.go index ef3c40e8815..49ef70744ff 100644 --- a/endpoints/cookie_sync.go +++ b/endpoints/cookie_sync.go @@ -149,6 +149,13 @@ func (c *cookieSyncEndpoint) parseRequest(r *http.Request) (usersync.Request, pr } } + activityControl, activitiesErr := privacy.NewActivityControl(account.Privacy) + if activitiesErr != nil { + if errortypes.ContainsFatalError([]error{activitiesErr}) { + activityControl = privacy.ActivityControl{} + } + } + syncTypeFilter, err := parseTypeFilter(request.FilterSettings) if err != nil { return usersync.Request{}, privacy.Policies{}, err @@ -172,6 +179,7 @@ func (c *cookieSyncEndpoint) parseRequest(r *http.Request) (usersync.Request, pr Privacy: usersyncPrivacy{ gdprPermissions: gdprPerms, ccpaParsedPolicy: ccpaParsedPolicy, + activityControl: activityControl, }, SyncTypeFilter: syncTypeFilter, } @@ -501,6 +509,7 @@ type usersyncPrivacyConfig struct { type usersyncPrivacy struct { gdprPermissions gdpr.Permissions ccpaParsedPolicy ccpa.ParsedPolicy + activityControl privacy.ActivityControl } func (p usersyncPrivacy) GDPRAllowsHostCookie() bool { @@ -517,3 +526,9 @@ func (p usersyncPrivacy) CCPAAllowsBidderSync(bidder string) bool { enforce := p.ccpaParsedPolicy.CanEnforce() && p.ccpaParsedPolicy.ShouldEnforce(bidder) return !enforce } + +func (p usersyncPrivacy) ActivityAllowsUserSync(bidder string) bool { + activityResult := p.activityControl.Allow(privacy.ActivitySyncUser, + privacy.ScopedName{Scope: privacy.ScopeTypeBidder, Name: bidder}) + return activityResult == privacy.ActivityAllow +} diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go index a69a2cdb819..e9d812b8baf 100644 --- a/endpoints/cookie_sync_test.go +++ b/endpoints/cookie_sync_test.go @@ -499,6 +499,7 @@ func TestCookieSyncParseRequest(t *testing.T) { expectedPrivacy privacy.Policies expectedRequest usersync.Request }{ + { description: "Complete Request - includes GPP string with EU TCF V2", givenBody: strings.NewReader(`{` + @@ -973,6 +974,38 @@ func TestCookieSyncParseRequest(t *testing.T) { expectedError: errCookieSyncAccountBlocked.Error(), givenAccountRequired: true, }, + + { + description: "Account Defaults - Invalid Activities", + givenBody: strings.NewReader(`{` + + `"bidders":["a", "b"],` + + `"account":"ValidAccountInvalidActivities"` + + `}`), + givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, + givenCCPAEnabled: true, + givenConfig: config.UserSync{ + Cooperative: config.UserSyncCooperative{ + EnabledByDefault: false, + PriorityGroups: [][]string{{"a", "b", "c"}}, + }, + }, + expectedPrivacy: privacy.Policies{}, + expectedRequest: usersync.Request{ + Bidders: []string{"a", "b"}, + Cooperative: usersync.Cooperative{ + Enabled: false, + PriorityGroups: [][]string{{"a", "b", "c"}}, + }, + Limit: 0, + Privacy: usersyncPrivacy{ + gdprPermissions: &fakePermissions{}, + }, + SyncTypeFilter: usersync.SyncTypeFilter{ + IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), + Redirect: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), + }, + }, + }, } for _, test := range testCases { @@ -997,8 +1030,9 @@ func TestCookieSyncParseRequest(t *testing.T) { ccpaEnforce: test.givenCCPAEnabled, }, accountsFetcher: FakeAccountsFetcher{AccountData: map[string]json.RawMessage{ - "TestAccount": json.RawMessage(`{"cookie_sync": {"default_limit": 20, "max_limit": 30, "default_coop_sync": true}}`), - "DisabledAccount": json.RawMessage(`{"disabled":true}`), + "TestAccount": json.RawMessage(`{"cookie_sync": {"default_limit": 20, "max_limit": 30, "default_coop_sync": true}}`), + "DisabledAccount": json.RawMessage(`{"disabled":true}`), + "ValidAccountInvalidActivities": json.RawMessage(`{"privacy":{"allowactivities":{"syncUser":{"rules":[{"condition":{"componentName": ["bidderA.bidderB.bidderC"]}}]}}}}`), }}, } assert.NoError(t, endpoint.config.MarshalAccountDefaults()) @@ -1871,6 +1905,41 @@ func TestUsersyncPrivacyCCPAAllowsBidderSync(t *testing.T) { } } +func TestCookieSyncActivityControlIntegration(t *testing.T) { + testCases := []struct { + name string + bidderName string + allow bool + expectedResult bool + }{ + { + name: "activity_is_allowed", + bidderName: "bidderA", + allow: true, + expectedResult: true, + }, + { + name: "activity_is_denied", + bidderName: "bidderA", + allow: false, + expectedResult: false, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + privacyConfig := getDefaultActivityConfig(test.bidderName, test.allow) + activities, err := privacy.NewActivityControl(privacyConfig) + assert.NoError(t, err) + up := usersyncPrivacy{ + activityControl: activities, + } + actualResult := up.ActivityAllowsUserSync(test.bidderName) + assert.Equal(t, test.expectedResult, actualResult) + }) + } +} + func TestCombineErrors(t *testing.T) { testCases := []struct { description string @@ -2031,3 +2100,22 @@ func (p *fakePermissions) AuctionActivitiesAllowed(ctx context.Context, bidderCo AllowBidRequest: true, }, nil } + +func getDefaultActivityConfig(componentName string, allow bool) *config.AccountPrivacy { + return &config.AccountPrivacy{ + AllowActivities: config.AllowActivities{ + SyncUser: config.Activity{ + Default: ptrutil.ToPtr(true), + Rules: []config.ActivityRule{ + { + Allow: allow, + Condition: config.ActivityCondition{ + ComponentName: []string{componentName}, + ComponentType: []string{"bidder"}, + }, + }, + }, + }, + }, + } +} diff --git a/endpoints/setuid.go b/endpoints/setuid.go index 25fb246593a..8f691389758 100644 --- a/endpoints/setuid.go +++ b/endpoints/setuid.go @@ -18,6 +18,7 @@ import ( "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/gdpr" "github.com/prebid/prebid-server/metrics" + "github.com/prebid/prebid-server/privacy" gppPrivacy "github.com/prebid/prebid-server/privacy/gpp" "github.com/prebid/prebid-server/stored_requests" "github.com/prebid/prebid-server/usersync" @@ -58,7 +59,7 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use query := r.URL.Query() - syncer, err := getSyncer(query, syncersByBidder) + syncer, bidderName, err := getSyncer(query, syncersByBidder) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) @@ -103,6 +104,20 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use return } + activities, activitiesErr := privacy.NewActivityControl(account.Privacy) + if activitiesErr != nil { + if errortypes.ContainsFatalError([]error{activitiesErr}) { + activities = privacy.ActivityControl{} + } + } + + userSyncActivityAllowed := activities.Allow(privacy.ActivitySyncUser, + privacy.ScopedName{Scope: privacy.ScopeTypeBidder, Name: bidderName}) + if userSyncActivityAllowed == privacy.ActivityDeny { + w.WriteHeader(http.StatusUnavailableForLegalReasons) + return + } + gdprRequestInfo, err := extractGDPRInfo(query) if err != nil { // Only exit if non-warning @@ -178,7 +193,6 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use // first and the 'gdpr' and 'gdpr_consent' query params second. If found in both, throws a // warning. Can also throw a parsing or validation error func extractGDPRInfo(query url.Values) (reqInfo gdpr.RequestInfo, err error) { - reqInfo, err = parseGDPRFromGPP(query) if err != nil { return gdpr.RequestInfo{GDPRSignal: gdpr.SignalAmbiguous}, err @@ -306,19 +320,19 @@ func parseConsentFromGppStr(gppQueryValue string) (string, error) { return gdprConsent, nil } -func getSyncer(query url.Values, syncersByBidder map[string]usersync.Syncer) (usersync.Syncer, error) { +func getSyncer(query url.Values, syncersByBidder map[string]usersync.Syncer) (usersync.Syncer, string, error) { bidder := query.Get("bidder") if bidder == "" { - return nil, errors.New(`"bidder" query param is required`) + return nil, "", errors.New(`"bidder" query param is required`) } syncer, syncerExists := syncersByBidder[bidder] if !syncerExists { - return nil, errors.New("The bidder name provided is not supported by Prebid Server") + return nil, "", errors.New("The bidder name provided is not supported by Prebid Server") } - return syncer, nil + return syncer, bidder, nil } // getResponseFormat reads the format query parameter or falls back to the syncer's default. diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go index 65bc26559da..05030cc7cf7 100644 --- a/endpoints/setuid_test.go +++ b/endpoints/setuid_test.go @@ -277,6 +277,35 @@ func TestSetUIDEndpoint(t *testing.T) { expectedBody: "account is disabled, please reach out to the prebid server host", description: "Set uid for valid bidder with valid disabled account provided", }, + { + uri: "/setuid?bidder=pubmatic&uid=123&account=valid_acct_with_valid_activities_usersync_enabled", + syncersBidderNameToKey: map[string]string{"pubmatic": "pubmatic"}, + existingSyncs: nil, + gdprAllowsHostCookies: true, + expectedSyncs: map[string]string{"pubmatic": "123"}, + expectedStatusCode: http.StatusOK, + expectedHeaders: map[string]string{"Content-Type": "text/html", "Content-Length": "0"}, + description: "Set uid for valid bidder with valid account provided with user sync allowed activity", + }, + { + uri: "/setuid?bidder=pubmatic&uid=123&account=valid_acct_with_valid_activities_usersync_disabled", + syncersBidderNameToKey: map[string]string{"pubmatic": "pubmatic"}, + existingSyncs: nil, + gdprAllowsHostCookies: true, + expectedSyncs: nil, + expectedStatusCode: http.StatusUnavailableForLegalReasons, + description: "Set uid for valid bidder with valid account provided with user sync disallowed activity", + }, + { + uri: "/setuid?bidder=pubmatic&uid=123&account=valid_acct_with_invalid_activities", + syncersBidderNameToKey: map[string]string{"pubmatic": "pubmatic"}, + existingSyncs: nil, + gdprAllowsHostCookies: true, + expectedSyncs: map[string]string{"pubmatic": "123"}, + expectedStatusCode: http.StatusOK, + expectedHeaders: map[string]string{"Content-Type": "text/html", "Content-Length": "0"}, + description: "Set uid for valid bidder with valid account provided with invalid user sync activity", + }, } analytics := analyticsConf.NewPBSAnalytics(&config.Analytics{}) @@ -1354,6 +1383,10 @@ func doRequest(req *http.Request, analytics analytics.PBSAnalyticsModule, metric "disabled_acct": json.RawMessage(`{"disabled":true}`), "malformed_acct": json.RawMessage(`{"disabled":"malformed"}`), "invalid_json_acct": json.RawMessage(`{"}`), + + "valid_acct_with_valid_activities_usersync_enabled": json.RawMessage(`{"privacy":{"allowactivities":{"syncUser":{"default": true}}}}`), + "valid_acct_with_valid_activities_usersync_disabled": json.RawMessage(`{"privacy":{"allowactivities":{"syncUser":{"default": false}}}}`), + "valid_acct_with_invalid_activities": json.RawMessage(`{"privacy":{"allowactivities":{"syncUser":{"rules":[{"condition":{"componentName": ["bidderA.bidderB.bidderC"]}}]}}}}`), }} endpoint := NewSetUIDEndpoint(&cfg, syncersByBidder, gdprPermsBuilder, tcf2ConfigBuilder, analytics, fakeAccountsFetcher, metrics) diff --git a/privacy/enforcer.go b/privacy/enforcer.go index a8685e29276..bcd9e948377 100644 --- a/privacy/enforcer.go +++ b/privacy/enforcer.go @@ -31,7 +31,7 @@ func NewActivityControl(privacyConf *config.AccountPrivacy) (ActivityControl, er var err error if privacyConf == nil { - return ac, err + return ac, nil } plans := make(map[Activity]ActivityPlan) diff --git a/usersync/chooser.go b/usersync/chooser.go index 97fa1471b7e..3f478049066 100644 --- a/usersync/chooser.go +++ b/usersync/chooser.go @@ -85,6 +85,9 @@ const ( // StatusDuplicate specifies the bidder is a duplicate or shared a syncer key with another bidder choice. StatusDuplicate + + // StatusBlockedByPrivacy specifies a bidder sync url is not allowed by privacy activities + StatusBlockedByPrivacy ) // Privacy determines which privacy policies will be enforced for a user sync request. @@ -92,6 +95,7 @@ type Privacy interface { GDPRAllowsHostCookie() bool GDPRAllowsBidderSync(bidder string) bool CCPAAllowsBidderSync(bidder string) bool + ActivityAllowsUserSync(bidder string) bool } // standardChooser implements the user syncer algorithm per official Prebid specification. @@ -151,6 +155,11 @@ func (c standardChooser) evaluate(bidder string, syncersSeen map[string]struct{} return nil, BidderEvaluation{Status: StatusAlreadySynced, Bidder: bidder, SyncerKey: syncer.Key()} } + userSyncActivityAllowed := privacy.ActivityAllowsUserSync(bidder) + if !userSyncActivityAllowed { + return nil, BidderEvaluation{Status: StatusBlockedByPrivacy, Bidder: bidder, SyncerKey: syncer.Key()} + } + if !privacy.GDPRAllowsBidderSync(bidder) { return nil, BidderEvaluation{Status: StatusBlockedByGDPR, Bidder: bidder, SyncerKey: syncer.Key()} } diff --git a/usersync/chooser_test.go b/usersync/chooser_test.go index 0071a2e36b0..adc217ae8f5 100644 --- a/usersync/chooser_test.go +++ b/usersync/chooser_test.go @@ -1,12 +1,11 @@ package usersync import ( - "testing" - "time" - "github.com/prebid/prebid-server/privacy" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + "testing" + "time" ) func TestNewChooser(t *testing.T) { @@ -66,7 +65,7 @@ func TestChooserChoose(t *testing.T) { { description: "Cookie Opt Out", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true}, + Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: 0, }, givenChosenBidders: []string{"a"}, @@ -80,7 +79,7 @@ func TestChooserChoose(t *testing.T) { { description: "GDPR Host Cookie Not Allowed", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: false, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true}, + Privacy: fakePrivacy{gdprAllowsHostCookie: false, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: 0, }, givenChosenBidders: []string{"a"}, @@ -94,7 +93,7 @@ func TestChooserChoose(t *testing.T) { { description: "No Bidders", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true}, + Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: 0, }, givenChosenBidders: []string{}, @@ -108,7 +107,7 @@ func TestChooserChoose(t *testing.T) { { description: "One Bidder - Sync", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true}, + Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: 0, }, givenChosenBidders: []string{"a"}, @@ -122,7 +121,7 @@ func TestChooserChoose(t *testing.T) { { description: "One Bidder - No Sync", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true}, + Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: 0, }, givenChosenBidders: []string{"c"}, @@ -136,7 +135,7 @@ func TestChooserChoose(t *testing.T) { { description: "Many Bidders - All Sync - Limit Disabled With 0", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true}, + Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: 0, }, givenChosenBidders: []string{"a", "b"}, @@ -150,7 +149,7 @@ func TestChooserChoose(t *testing.T) { { description: "Many Bidders - All Sync - Limit Disabled With Negative Value", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true}, + Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: -1, }, givenChosenBidders: []string{"a", "b"}, @@ -164,7 +163,7 @@ func TestChooserChoose(t *testing.T) { { description: "Many Bidders - Limited Sync", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true}, + Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: 1, }, givenChosenBidders: []string{"a", "b"}, @@ -178,7 +177,7 @@ func TestChooserChoose(t *testing.T) { { description: "Many Bidders - Limited Sync - Disqualified Syncers Don't Count Towards Limit", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true}, + Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: 1, }, givenChosenBidders: []string{"c", "a", "b"}, @@ -192,7 +191,7 @@ func TestChooserChoose(t *testing.T) { { description: "Many Bidders - Some Sync, Some Don't", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true}, + Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: 0, }, givenChosenBidders: []string{"a", "c"}, @@ -254,7 +253,7 @@ func TestChooserEvaluate(t *testing.T) { description: "Valid", givenBidder: "a", givenSyncersSeen: map[string]struct{}{}, - givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, givenCookie: cookieNeedsSync, expectedSyncer: fakeSyncerA, expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusOK}, @@ -263,7 +262,7 @@ func TestChooserEvaluate(t *testing.T) { description: "Unknown Bidder", givenBidder: "unknown", givenSyncersSeen: map[string]struct{}{}, - givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, givenCookie: cookieNeedsSync, expectedSyncer: nil, expectedEvaluation: BidderEvaluation{Bidder: "unknown", Status: StatusUnknownBidder}, @@ -272,7 +271,7 @@ func TestChooserEvaluate(t *testing.T) { description: "Duplicate Syncer", givenBidder: "a", givenSyncersSeen: map[string]struct{}{"keyA": {}}, - givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, givenCookie: cookieNeedsSync, expectedSyncer: nil, expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusDuplicate}, @@ -281,7 +280,7 @@ func TestChooserEvaluate(t *testing.T) { description: "Incompatible Kind", givenBidder: "b", givenSyncersSeen: map[string]struct{}{}, - givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, givenCookie: cookieNeedsSync, expectedSyncer: nil, expectedEvaluation: BidderEvaluation{Bidder: "b", SyncerKey: "keyB", Status: StatusTypeNotSupported}, @@ -290,7 +289,7 @@ func TestChooserEvaluate(t *testing.T) { description: "Already Synced", givenBidder: "a", givenSyncersSeen: map[string]struct{}{}, - givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, givenCookie: cookieAlreadyHasSyncForA, expectedSyncer: nil, expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusAlreadySynced}, @@ -299,7 +298,7 @@ func TestChooserEvaluate(t *testing.T) { description: "Different Bidder Already Synced", givenBidder: "a", givenSyncersSeen: map[string]struct{}{}, - givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, givenCookie: cookieAlreadyHasSyncForB, expectedSyncer: fakeSyncerA, expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusOK}, @@ -308,7 +307,7 @@ func TestChooserEvaluate(t *testing.T) { description: "Blocked By GDPR", givenBidder: "a", givenSyncersSeen: map[string]struct{}{}, - givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: false, ccpaAllowsBidderSync: true}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: false, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, givenCookie: cookieNeedsSync, expectedSyncer: nil, expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusBlockedByGDPR}, @@ -317,11 +316,20 @@ func TestChooserEvaluate(t *testing.T) { description: "Blocked By CCPA", givenBidder: "a", givenSyncersSeen: map[string]struct{}{}, - givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: false}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: false, activityAllowUserSync: true}, givenCookie: cookieNeedsSync, expectedSyncer: nil, expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusBlockedByCCPA}, }, + { + description: "Blocked By activity control", + givenBidder: "a", + givenSyncersSeen: map[string]struct{}{}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: false}, + givenCookie: cookieNeedsSync, + expectedSyncer: nil, + expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusBlockedByPrivacy}, + }, } for _, test := range testCases { @@ -373,9 +381,10 @@ func (fakeSyncer) GetSync(syncTypes []SyncType, privacyPolicies privacy.Policies } type fakePrivacy struct { - gdprAllowsHostCookie bool - gdprAllowsBidderSync bool - ccpaAllowsBidderSync bool + gdprAllowsHostCookie bool + gdprAllowsBidderSync bool + ccpaAllowsBidderSync bool + activityAllowUserSync bool } func (p fakePrivacy) GDPRAllowsHostCookie() bool { @@ -389,3 +398,7 @@ func (p fakePrivacy) GDPRAllowsBidderSync(bidder string) bool { func (p fakePrivacy) CCPAAllowsBidderSync(bidder string) bool { return p.ccpaAllowsBidderSync } + +func (p fakePrivacy) ActivityAllowsUserSync(bidder string) bool { + return p.activityAllowUserSync +} From 462bb1d83ac6218a4a1f8887456ca54c712dc931 Mon Sep 17 00:00:00 2001 From: TPMN Admin Date: Fri, 28 Jul 2023 14:53:11 +0900 Subject: [PATCH 047/268] New Adapter: TPMN (#2947) Co-authored-by: changjun --- adapters/tpmn/params_test.go | 44 ++++++ adapters/tpmn/tpmn.go | 126 ++++++++++++++++ adapters/tpmn/tpmn_test.go | 20 +++ .../tpmntest/exemplary/simple-banner.json | 135 ++++++++++++++++++ .../tpmntest/exemplary/simple-native.json | 119 +++++++++++++++ .../exemplary/simple-site-banner.json | 132 +++++++++++++++++ .../exemplary/simple-site-native.json | 104 ++++++++++++++ .../tpmntest/exemplary/simple-site-video.json | 128 +++++++++++++++++ .../tpmn/tpmntest/exemplary/simple-video.json | 130 +++++++++++++++++ .../tpmntest/supplemental/bad-imp-ext.json | 79 ++++++++++ .../tpmntest/supplemental/bad_response.json | 87 +++++++++++ .../tpmntest/supplemental/no-imp-ext.json | 81 +++++++++++ .../tpmntest/supplemental/status-204.json | 81 +++++++++++ .../tpmntest/supplemental/status-404.json | 86 +++++++++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_tpmn.go | 6 + static/bidder-info/tpmn.yaml | 20 +++ static/bidder-params/tpmn.json | 16 +++ 19 files changed, 1398 insertions(+) create mode 100644 adapters/tpmn/params_test.go create mode 100644 adapters/tpmn/tpmn.go create mode 100644 adapters/tpmn/tpmn_test.go create mode 100644 adapters/tpmn/tpmntest/exemplary/simple-banner.json create mode 100644 adapters/tpmn/tpmntest/exemplary/simple-native.json create mode 100644 adapters/tpmn/tpmntest/exemplary/simple-site-banner.json create mode 100644 adapters/tpmn/tpmntest/exemplary/simple-site-native.json create mode 100644 adapters/tpmn/tpmntest/exemplary/simple-site-video.json create mode 100644 adapters/tpmn/tpmntest/exemplary/simple-video.json create mode 100644 adapters/tpmn/tpmntest/supplemental/bad-imp-ext.json create mode 100644 adapters/tpmn/tpmntest/supplemental/bad_response.json create mode 100644 adapters/tpmn/tpmntest/supplemental/no-imp-ext.json create mode 100644 adapters/tpmn/tpmntest/supplemental/status-204.json create mode 100644 adapters/tpmn/tpmntest/supplemental/status-404.json create mode 100644 openrtb_ext/imp_tpmn.go create mode 100644 static/bidder-info/tpmn.yaml create mode 100644 static/bidder-params/tpmn.json diff --git a/adapters/tpmn/params_test.go b/adapters/tpmn/params_test.go new file mode 100644 index 00000000000..7bd7c478638 --- /dev/null +++ b/adapters/tpmn/params_test.go @@ -0,0 +1,44 @@ +package tpmn + +import ( + "encoding/json" + "github.com/prebid/prebid-server/openrtb_ext" + "testing" +) + +var validParams = []string{ + `{"inventoryId": 10000001}`, +} + +var invalidParams = []string{ + `{"inventoryId": "00000001"}`, + `{"inventoryid": 100000000}`, +} + +// TestValidParams makes sure that the tpmn schema accepts all imp.ext fields which we intend to support. +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderTpmn, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected TPMN params: %s", validParam) + } + } +} + +// TestInvalidParams makes sure that the tpmn schema rejects all the imp.ext fields we don't support. +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderTpmn, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} diff --git a/adapters/tpmn/tpmn.go b/adapters/tpmn/tpmn.go new file mode 100644 index 00000000000..7afe94e5f79 --- /dev/null +++ b/adapters/tpmn/tpmn.go @@ -0,0 +1,126 @@ +package tpmn + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +// TpmnAdapter struct +type adapter struct { + uri string +} + +// MakeRequests makes the HTTP requests which should be made to fetch bids from TpmnBidder. +func (rcv *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + validImps, errs := getValidImpressions(request, reqInfo) + if len(validImps) == 0 { + return nil, errs + } + + request.Imp = validImps + + requestBodyJSON, err := json.Marshal(request) + if err != nil { + errs = append(errs, err) + return nil, errs + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + + return []*adapters.RequestData{{ + Method: http.MethodPost, + Uri: rcv.uri, + Body: requestBodyJSON, + Headers: headers, + }}, errs +} + +// getValidImpressions validate imps and check for bid floor currency. Convert to EUR if necessary +func getValidImpressions(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]openrtb2.Imp, []error) { + var errs []error + var validImps []openrtb2.Imp + + for _, imp := range request.Imp { + if err := preprocessBidFloorCurrency(&imp, reqInfo); err != nil { + errs = append(errs, err) + continue + } + validImps = append(validImps, imp) + } + return validImps, errs +} + +func preprocessBidFloorCurrency(imp *openrtb2.Imp, reqInfo *adapters.ExtraRequestInfo) error { + // we expect every currency related data to be EUR + if imp.BidFloor > 0 && strings.ToUpper(imp.BidFloorCur) != "USD" && imp.BidFloorCur != "" { + if convertedValue, err := reqInfo.ConvertCurrency(imp.BidFloor, imp.BidFloorCur, "USD"); err != nil { + return err + } else { + imp.BidFloor = convertedValue + } + } + imp.BidFloorCur = "USD" + return nil +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} + } + + var response openrtb2.BidResponse + if err := json.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{fmt.Errorf("bid response unmarshal: %v", err)} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + bidResponse.Currency = response.Cur + for _, seatBid := range response.SeatBid { + for i, bid := range seatBid.Bid { + bidType, err := getMediaTypeForImp(bid) + if err != nil { + return nil, []error{err} + } + b := &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + } + return bidResponse, nil +} + +func getMediaTypeForImp(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + return "", fmt.Errorf("unsupported MType %d", bid.MType) + } +} + +// Builder builds a new instance of the TpmnBidder adapter for the given bidder with the given config. +func Builder(_ openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + uri: config.Endpoint, + } + return bidder, nil +} diff --git a/adapters/tpmn/tpmn_test.go b/adapters/tpmn/tpmn_test.go new file mode 100644 index 00000000000..6fbd85936f1 --- /dev/null +++ b/adapters/tpmn/tpmn_test.go @@ -0,0 +1,20 @@ +package tpmn + +import ( + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderTpmn, config.Adapter{ + Endpoint: "https://gat.tpmn.io/ortb/pbs_bidder"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "tpmntest", bidder) +} diff --git a/adapters/tpmn/tpmntest/exemplary/simple-banner.json b/adapters/tpmn/tpmntest/exemplary/simple-banner.json new file mode 100644 index 00000000000..197d03b174e --- /dev/null +++ b/adapters/tpmn/tpmntest/exemplary/simple-banner.json @@ -0,0 +1,135 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "tagid": "00000001", + "ext": { + "bidder": { + "inventoryId": 10000001 + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://gat.tpmn.io/ortb/pbs_bidder", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "tagid": "00000001", + "bidfloorcur": "USD", + "ext": { + "bidder": { + "inventoryId": 10000001 + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "tpmn" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/tpmn/tpmntest/exemplary/simple-native.json b/adapters/tpmn/tpmntest/exemplary/simple-native.json new file mode 100644 index 00000000000..1880c74ac7e --- /dev/null +++ b/adapters/tpmn/tpmntest/exemplary/simple-native.json @@ -0,0 +1,119 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "inventoryId": 10000001 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://gat.tpmn.io/ortb/pbs_bidder", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "inventoryId": 10000001 + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "mtype": 4, + "ext": { + "prebid": { + "type": "native" + } + } + } + ], + "seat": "tpmn" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "mtype": 4, + "ext": { + "prebid": { + "type": "native" + } + } + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/tpmn/tpmntest/exemplary/simple-site-banner.json b/adapters/tpmn/tpmntest/exemplary/simple-site-banner.json new file mode 100644 index 00000000000..8f7c5d59301 --- /dev/null +++ b/adapters/tpmn/tpmntest/exemplary/simple-site-banner.json @@ -0,0 +1,132 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "inventoryId": 10000001 + } + } + } + ], + "site": { + "id": "1", + "domain": "test.com" + }, + "device": { + "ip": "123.123.123.123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://gat.tpmn.io/ortb/pbs_bidder", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "inventoryId": 10000001 + } + } + } + ], + "site": { + "id": "1", + "domain": "test.com" + }, + "device": { + "ip": "123.123.123.123" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 468, + "h": 60, + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "tpmn" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 468, + "h": 60, + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} + \ No newline at end of file diff --git a/adapters/tpmn/tpmntest/exemplary/simple-site-native.json b/adapters/tpmn/tpmntest/exemplary/simple-site-native.json new file mode 100644 index 00000000000..20e6c23e966 --- /dev/null +++ b/adapters/tpmn/tpmntest/exemplary/simple-site-native.json @@ -0,0 +1,104 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "device": { + "ip":"123.123.123.123" + }, + "imp": [ + { + "id": "test-imp-id", + "native": { + "ver": "1.1", + "request": "{\"ver\":\"1.0\",\"layout\":1,\"adunit\":1,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":60,\"hmin\":60,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":75}},{\"id\":4,\"required\":0,\"data\":{\"type\":6,\"len\":1000}},{\"id\":5,\"required\":0,\"data\":{\"type\":7,\"len\":1000}},{\"id\":6,\"required\":0,\"data\":{\"type\":11,\"len\":1000}}]}" + }, + "ext": { + "bidder": { + "inventoryId": 10000001 + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://gat.tpmn.io/ortb/pbs_bidder", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "device": { + "ip":"123.123.123.123" + }, + "imp": [ + { + "id": "test-imp-id", + "native": { + "ver": "1.1", + "request": "{\"ver\":\"1.0\",\"layout\":1,\"adunit\":1,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":60,\"hmin\":60,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":75}},{\"id\":4,\"required\":0,\"data\":{\"type\":6,\"len\":1000}},{\"id\":5,\"required\":0,\"data\":{\"type\":7,\"len\":1000}},{\"id\":6,\"required\":0,\"data\":{\"type\":11,\"len\":1000}}]}" + }, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "inventoryId": 10000001 + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "tpmn", + "bid": [{ + "id": "1", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-adm", + "crid": "test-crid", + "mtype": 4 + }] + } + ], + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-adm", + "crid": "test-crid", + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/tpmn/tpmntest/exemplary/simple-site-video.json b/adapters/tpmn/tpmntest/exemplary/simple-site-video.json new file mode 100644 index 00000000000..7b2375cd07a --- /dev/null +++ b/adapters/tpmn/tpmntest/exemplary/simple-site-video.json @@ -0,0 +1,128 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "device": { + "ip":"123.123.123.123" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "inventoryId": 10000001 + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://gat.tpmn.io/ortb/pbs_bidder", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "device": { + "ip":"123.123.123.123" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "inventoryId": 10000001 + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "tpmn", + "bid": [ + { + "id": "1", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-adm", + "crid": "test-crid", + "w": 1024, + "h": 576, + "mtype": 2 + } + ] + } + ] + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-adm", + "crid": "test-crid", + "w": 1024, + "h": 576, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/tpmn/tpmntest/exemplary/simple-video.json b/adapters/tpmn/tpmntest/exemplary/simple-video.json new file mode 100644 index 00000000000..505b6167069 --- /dev/null +++ b/adapters/tpmn/tpmntest/exemplary/simple-video.json @@ -0,0 +1,130 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "inventoryId": 10000001 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://gat.tpmn.io/ortb/pbs_bidder", + "body": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + + "bidfloorcur": "USD", + "ext": { + "bidder": { + "inventoryId": 10000001 + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "00:01:00", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 2, + "ext": { + "prebid": { + "type": "video" + } + } + } + ], + "seat": "tpmn" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "00:01:00", + "cid": "test_cid", + "crid": "test_crid", + "mtype": 2, + "dealid": "test_dealid", + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/tpmn/tpmntest/supplemental/bad-imp-ext.json b/adapters/tpmn/tpmntest/supplemental/bad-imp-ext.json new file mode 100644 index 00000000000..3bbb23f95a4 --- /dev/null +++ b/adapters/tpmn/tpmntest/supplemental/bad-imp-ext.json @@ -0,0 +1,79 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "tagid": "00000001", + "ext": { + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://gat.tpmn.io/ortb/pbs_bidder", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "tagid": "00000001", + "bidfloorcur": "USD", + "ext": { + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" + } + } + }, + "mockResponse": { + "status": 204, + "body": { + } + } + } + ], + "expectedBidResponses": [ + ] +} diff --git a/adapters/tpmn/tpmntest/supplemental/bad_response.json b/adapters/tpmn/tpmntest/supplemental/bad_response.json new file mode 100644 index 00000000000..12c3a72d49f --- /dev/null +++ b/adapters/tpmn/tpmntest/supplemental/bad_response.json @@ -0,0 +1,87 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "inventoryId": 10000001 + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://gat.tpmn.io/ortb/pbs_bidder", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "inventoryId": 10000001 + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + } + }, + "mockResponse": { + "status": 200, + "body": "" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "bid response unmarshal: json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "comparison": "literal" + } + ] +} diff --git a/adapters/tpmn/tpmntest/supplemental/no-imp-ext.json b/adapters/tpmn/tpmntest/supplemental/no-imp-ext.json new file mode 100644 index 00000000000..8bcbb93d004 --- /dev/null +++ b/adapters/tpmn/tpmntest/supplemental/no-imp-ext.json @@ -0,0 +1,81 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "tagid": "16", + "ext": "" + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://gat.tpmn.io/ortb/pbs_bidder", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "tagid": "16", + "ext": "", + "bidfloorcur": "USD" + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" + } + } + }, + "mockResponse": { + "status": 200, + "body": "" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "bid response unmarshal: json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "comparison": "literal" + } + ] +} + \ No newline at end of file diff --git a/adapters/tpmn/tpmntest/supplemental/status-204.json b/adapters/tpmn/tpmntest/supplemental/status-204.json new file mode 100644 index 00000000000..fdcd3f7fd55 --- /dev/null +++ b/adapters/tpmn/tpmntest/supplemental/status-204.json @@ -0,0 +1,81 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "inventoryId": 10000001 + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://gat.tpmn.io/ortb/pbs_bidder", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "inventoryId": 10000001 + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + } + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/tpmn/tpmntest/supplemental/status-404.json b/adapters/tpmn/tpmntest/supplemental/status-404.json new file mode 100644 index 00000000000..74ced15217c --- /dev/null +++ b/adapters/tpmn/tpmntest/supplemental/status-404.json @@ -0,0 +1,86 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "inventoryId": 10000001 + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://gat.tpmn.io/ortb/pbs_bidder", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "inventoryId": 10000001 + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + } + }, + "mockResponse": { + "status": 404, + "body": {} + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 404. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index a1038d7152d..11529c5e9c3 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -157,6 +157,7 @@ import ( "github.com/prebid/prebid-server/adapters/taboola" "github.com/prebid/prebid-server/adapters/tappx" "github.com/prebid/prebid-server/adapters/telaria" + "github.com/prebid/prebid-server/adapters/tpmn" "github.com/prebid/prebid-server/adapters/trafficgate" "github.com/prebid/prebid-server/adapters/triplelift" "github.com/prebid/prebid-server/adapters/triplelift_native" @@ -355,6 +356,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderTaboola: taboola.Builder, openrtb_ext.BidderTappx: tappx.Builder, openrtb_ext.BidderTelaria: telaria.Builder, + openrtb_ext.BidderTpmn: tpmn.Builder, openrtb_ext.BidderTrafficGate: trafficgate.Builder, openrtb_ext.BidderTriplelift: triplelift.Builder, openrtb_ext.BidderTripleliftNative: triplelift_native.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index e9cc81f8c38..c873e9ab567 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -254,6 +254,7 @@ const ( BidderTaboola BidderName = "taboola" BidderTappx BidderName = "tappx" BidderTelaria BidderName = "telaria" + BidderTpmn BidderName = "tpmn" BidderTrafficGate BidderName = "trafficgate" BidderTriplelift BidderName = "triplelift" BidderTripleliftNative BidderName = "triplelift_native" @@ -454,6 +455,7 @@ func CoreBidderNames() []BidderName { BidderTaboola, BidderTappx, BidderTelaria, + BidderTpmn, BidderTrafficGate, BidderTriplelift, BidderTripleliftNative, diff --git a/openrtb_ext/imp_tpmn.go b/openrtb_ext/imp_tpmn.go new file mode 100644 index 00000000000..373b3089cc8 --- /dev/null +++ b/openrtb_ext/imp_tpmn.go @@ -0,0 +1,6 @@ +package openrtb_ext + +// ExtImpTpmn defines TPMN specifiec param +type ExtImpTpmn struct { + InventoryId int `json:"inventoryId"` +} diff --git a/static/bidder-info/tpmn.yaml b/static/bidder-info/tpmn.yaml new file mode 100644 index 00000000000..8d88c451da6 --- /dev/null +++ b/static/bidder-info/tpmn.yaml @@ -0,0 +1,20 @@ +endpoint: "https://gat.tpmn.io/ortb/pbs_bidder" +maintainer: + email: "prebid@tpmn.io" +modifyingVastXmlAllowed: true +endpointCompression: GZIP +capabilities: + app: + mediaTypes: + - banner + - video + - native + site: + mediaTypes: + - banner + - video + - native +userSync: + redirect: + url: "https://gat.tpmn.io/sync/redirect?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir={{.RedirectURL}}" + userMacro: "$UID" \ No newline at end of file diff --git a/static/bidder-params/tpmn.json b/static/bidder-params/tpmn.json new file mode 100644 index 00000000000..68b54373179 --- /dev/null +++ b/static/bidder-params/tpmn.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "TPMN Adapter Params", + "description": "A schema which validates params accepted by the TPMN adapter", + "type": "object", + "properties": { + "inventoryId": { + "description": "Inventory ID", + "type": "integer", + "minLength": 1 + } + }, + "required": [ + "inventoryId" + ] +} \ No newline at end of file From 24584d395c0c9b091985d8c7a02f82f2f618db26 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Fri, 28 Jul 2023 13:07:51 +0530 Subject: [PATCH 048/268] adapters package fixes reported by go vet (#2955) co-authored by @onkarvhanumante --- adapters/huaweiads/huaweiads.go | 1 - adapters/rubicon/rubicon_test.go | 4 ++-- adapters/taboola/taboola.go | 3 +-- openrtb_ext/imp_adnuntius.go | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/adapters/huaweiads/huaweiads.go b/adapters/huaweiads/huaweiads.go index 2008eecd9f1..071f0761bb3 100644 --- a/adapters/huaweiads/huaweiads.go +++ b/adapters/huaweiads/huaweiads.go @@ -902,7 +902,6 @@ func getReqConsentInfo(request *huaweiAdsRequest, openRTBRequest *openrtb2.BidRe if openRTBRequest.User != nil && openRTBRequest.User.Ext != nil { var extUser openrtb_ext.ExtUser if err := json.Unmarshal(openRTBRequest.User.Ext, &extUser); err != nil { - fmt.Errorf("failed to parse ExtUser in HuaweiAds GDPR check: %v", err) return } request.Consent = extUser.Consent diff --git a/adapters/rubicon/rubicon_test.go b/adapters/rubicon/rubicon_test.go index b665746e1a8..5f75ea5f06f 100644 --- a/adapters/rubicon/rubicon_test.go +++ b/adapters/rubicon/rubicon_test.go @@ -290,12 +290,12 @@ type mockCurrencyConversion struct { mock.Mock } -func (m mockCurrencyConversion) GetRate(from string, to string) (float64, error) { +func (m *mockCurrencyConversion) GetRate(from string, to string) (float64, error) { args := m.Called(from, to) return args.Get(0).(float64), args.Error(1) } -func (m mockCurrencyConversion) GetRates() *map[string]map[string]float64 { +func (m *mockCurrencyConversion) GetRates() *map[string]map[string]float64 { args := m.Called() return args.Get(0).(*map[string]map[string]float64) } diff --git a/adapters/taboola/taboola.go b/adapters/taboola/taboola.go index cb47fc9b250..087f661104f 100644 --- a/adapters/taboola/taboola.go +++ b/adapters/taboola/taboola.go @@ -253,8 +253,7 @@ func makeRequestExt(pageType string) (json.RawMessage, error) { requestExtJson, err := json.Marshal(requestExt) if err != nil { - fmt.Errorf("could not marshal %s", requestExt) - return nil, err + return nil, fmt.Errorf("could not marshal %s, err: %s", requestExt, err) } return requestExtJson, nil diff --git a/openrtb_ext/imp_adnuntius.go b/openrtb_ext/imp_adnuntius.go index 3759ad50678..86023c48231 100644 --- a/openrtb_ext/imp_adnuntius.go +++ b/openrtb_ext/imp_adnuntius.go @@ -3,6 +3,6 @@ package openrtb_ext type ImpExtAdnunitus struct { Auid string `json:"auId"` Network string `json:"network"` - NoCookies bool `json:"noCookies'"` + NoCookies bool `json:"noCookies"` MaxDeals int `json:"maxDeals"` } From a3c1a742a03717cd3129dbea60dffe4eba25075d Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Fri, 28 Jul 2023 16:17:59 +0530 Subject: [PATCH 049/268] invoke `go vet` command correctly (#2984) Co-authored-by: @onkarvhanumante --- validate.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/validate.sh b/validate.sh index becd42ceb50..d263df0ab51 100755 --- a/validate.sh +++ b/validate.sh @@ -35,7 +35,6 @@ if [ "$RACE" -ne "0" ]; then fi if $VET; then - COMMAND="go vet" - echo "Running: $COMMAND" - `$COMMAND` + echo "Running go vet check" + go vet -composites=false ./... fi From 3bf447b3f577e906a9124f5c52872aceaa9ccb09 Mon Sep 17 00:00:00 2001 From: screencore-io <140408408+screencore-io@users.noreply.github.com> Date: Mon, 31 Jul 2023 09:17:30 +0300 Subject: [PATCH 050/268] New adapter: Screencore (#2969) Co-authored-by: afront-io --- adapters/screencore/params_test.go | 50 +++++ adapters/screencore/screencore.go | 176 ++++++++++++++++ adapters/screencore/screencore_test.go | 20 ++ .../screencoretest/exemplary/banner-app.json | 152 ++++++++++++++ .../screencoretest/exemplary/banner-web.json | 197 ++++++++++++++++++ .../screencoretest/exemplary/native-app.json | 148 +++++++++++++ .../screencoretest/exemplary/native-web.json | 135 ++++++++++++ .../screencoretest/exemplary/video-app.json | 161 ++++++++++++++ .../screencoretest/exemplary/video-web.json | 159 ++++++++++++++ .../supplemental/bad_media_type.json | 135 ++++++++++++ .../supplemental/empty-imp-array.json | 16 ++ .../supplemental/empty-seatbid-array.json | 130 ++++++++++++ .../invalid-bidder-ext-object.json | 33 +++ .../supplemental/invalid-response.json | 112 ++++++++++ .../invalid-screencore-ext-object.json | 31 +++ .../supplemental/status-code-bad-request.json | 93 +++++++++ .../supplemental/status-code-no-content.json | 76 +++++++ .../supplemental/status-code-other-error.json | 81 +++++++ .../status-code-service-unavailable.json | 81 +++++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_screencore.go | 6 + static/bidder-info/screencore.yaml | 14 ++ static/bidder-params/screencore.json | 22 ++ 24 files changed, 2032 insertions(+) create mode 100644 adapters/screencore/params_test.go create mode 100644 adapters/screencore/screencore.go create mode 100644 adapters/screencore/screencore_test.go create mode 100644 adapters/screencore/screencoretest/exemplary/banner-app.json create mode 100644 adapters/screencore/screencoretest/exemplary/banner-web.json create mode 100644 adapters/screencore/screencoretest/exemplary/native-app.json create mode 100644 adapters/screencore/screencoretest/exemplary/native-web.json create mode 100644 adapters/screencore/screencoretest/exemplary/video-app.json create mode 100644 adapters/screencore/screencoretest/exemplary/video-web.json create mode 100644 adapters/screencore/screencoretest/supplemental/bad_media_type.json create mode 100644 adapters/screencore/screencoretest/supplemental/empty-imp-array.json create mode 100644 adapters/screencore/screencoretest/supplemental/empty-seatbid-array.json create mode 100644 adapters/screencore/screencoretest/supplemental/invalid-bidder-ext-object.json create mode 100644 adapters/screencore/screencoretest/supplemental/invalid-response.json create mode 100644 adapters/screencore/screencoretest/supplemental/invalid-screencore-ext-object.json create mode 100644 adapters/screencore/screencoretest/supplemental/status-code-bad-request.json create mode 100644 adapters/screencore/screencoretest/supplemental/status-code-no-content.json create mode 100644 adapters/screencore/screencoretest/supplemental/status-code-other-error.json create mode 100644 adapters/screencore/screencoretest/supplemental/status-code-service-unavailable.json create mode 100644 openrtb_ext/imp_screencore.go create mode 100644 static/bidder-info/screencore.yaml create mode 100644 static/bidder-params/screencore.json diff --git a/adapters/screencore/params_test.go b/adapters/screencore/params_test.go new file mode 100644 index 00000000000..faa2f854928 --- /dev/null +++ b/adapters/screencore/params_test.go @@ -0,0 +1,50 @@ +package screencore + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/openrtb_ext" +) + +var validParams = []string{ + `{ "accountId": "hash", "placementId": "hash"}`, +} + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderScreencore, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected Screencore params: %s", validParam) + } + } +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `5.2`, + `[]`, + `{}`, + `{"adCode": "string", "seatCode": 5, "originalPublisherid": "string"}`, + `{ "placementId": "", "accountId": "" }`, +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderScreencore, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} diff --git a/adapters/screencore/screencore.go b/adapters/screencore/screencore.go new file mode 100644 index 00000000000..668e8b5e131 --- /dev/null +++ b/adapters/screencore/screencore.go @@ -0,0 +1,176 @@ +package screencore + +import ( + "encoding/json" + "fmt" + "net/http" + "text/template" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/macros" + "github.com/prebid/prebid-server/openrtb_ext" +) + +type adapter struct { + endpoint *template.Template +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + template, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) + } + + bidder := &adapter{ + endpoint: template, + } + return bidder, nil +} + +func getHeaders(request *openrtb2.BidRequest) http.Header { + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + headers.Add("X-Openrtb-Version", "2.5") + + if request.Device != nil { + if len(request.Device.UA) > 0 { + headers.Add("User-Agent", request.Device.UA) + } + + if len(request.Device.IPv6) > 0 { + headers.Add("X-Forwarded-For", request.Device.IPv6) + } + + if len(request.Device.IP) > 0 { + headers.Add("X-Forwarded-For", request.Device.IP) + } + } + + return headers +} + +func (a *adapter) MakeRequests(openRTBRequest *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) (requestsToBidder []*adapters.RequestData, errs []error) { + if len(openRTBRequest.Imp) == 0 { + return nil, []error{&errortypes.BadInput{ + Message: "Empty Imp array in BidRequest", + }} + } + + screencoreExt, err := getImpressionExt(&openRTBRequest.Imp[0]) + if err != nil { + return nil, []error{err} + } + + openRTBRequest.Imp[0].Ext = nil + + url, err := a.buildEndpointURL(screencoreExt) + if err != nil { + return nil, []error{err} + } + + reqJSON, err := json.Marshal(openRTBRequest) + if err != nil { + return nil, []error{err} + } + + return []*adapters.RequestData{{ + Method: http.MethodPost, + Body: reqJSON, + Uri: url, + Headers: getHeaders(openRTBRequest), + }}, nil +} + +func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtScreencore, error) { + var bidderExt adapters.ExtImpBidder + if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + return nil, &errortypes.BadInput{ + Message: "Error parsing screencoreExt - " + err.Error(), + } + } + var screencoreExt openrtb_ext.ExtScreencore + if err := json.Unmarshal(bidderExt.Bidder, &screencoreExt); err != nil { + return nil, &errortypes.BadInput{ + Message: "Error parsing bidderExt - " + err.Error(), + } + } + + return &screencoreExt, nil +} + +func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtScreencore) (string, error) { + endpointParams := macros.EndpointTemplateParams{AccountID: params.AccountID, SourceId: params.PlacementID} + return macros.ResolveMacros(a.endpoint, endpointParams) +} + +func checkResponseStatusCodes(response *adapters.ResponseData) error { + if response.StatusCode == http.StatusServiceUnavailable { + return &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Something went wrong Status Code: [ %d ] ", response.StatusCode), + } + } + + return adapters.CheckResponseStatusCodeForErrors(response) +} + +func (a *adapter) MakeBids(openRTBRequest *openrtb2.BidRequest, requestToBidder *adapters.RequestData, bidderRawResponse *adapters.ResponseData) (bidderResponse *adapters.BidderResponse, errs []error) { + if adapters.IsResponseStatusCodeNoContent(bidderRawResponse) { + return nil, nil + } + + httpStatusError := checkResponseStatusCodes(bidderRawResponse) + if httpStatusError != nil { + return nil, []error{httpStatusError} + } + + responseBody := bidderRawResponse.Body + var bidResp openrtb2.BidResponse + if err := json.Unmarshal(responseBody, &bidResp); err != nil { + return nil, []error{&errortypes.BadServerResponse{ + Message: "Bad Server Response", + }} + } + + if len(bidResp.SeatBid) == 0 { + return nil, []error{&errortypes.BadServerResponse{ + Message: "Empty SeatBid array", + }} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(5) + var bidsArray []*adapters.TypedBid + + for _, sb := range bidResp.SeatBid { + for idx, bid := range sb.Bid { + bidType, err := getMediaTypeForImp(bid) + if err != nil { + return nil, []error{err} + } + + bidsArray = append(bidsArray, &adapters.TypedBid{ + Bid: &sb.Bid[idx], + BidType: bidType, + }) + } + } + + bidResponse.Bids = bidsArray + return bidResponse, nil +} + +func getMediaTypeForImp(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + return "", fmt.Errorf("unsupported MType %d", bid.MType) + } +} diff --git a/adapters/screencore/screencore_test.go b/adapters/screencore/screencore_test.go new file mode 100644 index 00000000000..6ee7f3ad554 --- /dev/null +++ b/adapters/screencore/screencore_test.go @@ -0,0 +1,20 @@ +package screencore + +import ( + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderScreencore, config.Adapter{ + Endpoint: "http://h1.screencore.io/?kp={{.AccountID}}&kn={{.SourceId}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "screencoretest", bidder) +} diff --git a/adapters/screencore/screencoretest/exemplary/banner-app.json b/adapters/screencore/screencoretest/exemplary/banner-app.json new file mode 100644 index 00000000000..0b75398d767 --- /dev/null +++ b/adapters/screencore/screencoretest/exemplary/banner-app.json @@ -0,0 +1,152 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "1", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "placementId": "placementId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "1", + "banner": { + "w": 320, + "h": 50 + }, + "tagid": "ogTAGID" + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "1", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 320, + "h": 50, + "mtype": 1 + } + ], + "type": "banner", + "seat": "screencore" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "1", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 320, + "h": 50, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/screencore/screencoretest/exemplary/banner-web.json b/adapters/screencore/screencoretest/exemplary/banner-web.json new file mode 100644 index 00000000000..a9eed6bfb53 --- /dev/null +++ b/adapters/screencore/screencoretest/exemplary/banner-web.json @@ -0,0 +1,197 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "some-impression-id1", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "placementId": "placementId" + } + } + }, + { + "id": "some-impression-id2", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "placementId": "placementId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id1", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + } + }, + { + "id": "some-impression-id2", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "placementId": "placementId" + } + } + } + ], + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id1", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 320, + "h": 50, + "mtype": 1 + }, + { + "id": "a3ae1b4e2fc24a4fb45540082e98e162", + "impid": "some-impression-id2", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 320, + "h": 50, + "mtype": 1 + } + ], + "type": "banner", + "seat": "screencore" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id1", + "price": 3.5, + "adm": "awesome-markup", + "crid": "20", + "adomain": [ + "awesome.com" + ], + "w": 320, + "h": 50, + "mtype": 1 + }, + "type": "banner" + }, + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e162", + "impid": "some-impression-id2", + "price": 3.5, + "adm": "awesome-markup", + "crid": "20", + "adomain": [ + "awesome.com" + ], + "w": 320, + "h": 50, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/screencore/screencoretest/exemplary/native-app.json b/adapters/screencore/screencoretest/exemplary/native-app.json new file mode 100644 index 00000000000..eece64eea2d --- /dev/null +++ b/adapters/screencore/screencoretest/exemplary/native-app.json @@ -0,0 +1,148 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "native": { + "ver": "1.1", + "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}" + }, + "ext": { + "bidder": { + "accountId": "accountId", + "placementId": "placementId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "native": { + "ver": "1.1", + "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}" + }, + "tagid": "ogTAGID" + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "mtype": 4 + } + ], + "type": "native", + "seat": "screencore" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "crid": "20", + "adomain": [ + "awesome.com" + ], + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/screencore/screencoretest/exemplary/native-web.json b/adapters/screencore/screencoretest/exemplary/native-web.json new file mode 100644 index 00000000000..5878519f33f --- /dev/null +++ b/adapters/screencore/screencoretest/exemplary/native-web.json @@ -0,0 +1,135 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ipv6": "2607:fb90:f27:4512:d800:cb23:a603:e245", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "native": { + "ver": "1.1", + "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}" + }, + "ext": { + "bidder": { + "accountId": "accountId", + "placementId": "placementId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "2607:fb90:f27:4512:d800:cb23:a603:e245" + ] + }, + "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ipv6": "2607:fb90:f27:4512:d800:cb23:a603:e245", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "native": { + "ver": "1.1", + "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}" + } + } + ], + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "mtype": 4 + } + ], + "seat": "screencore" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "crid": "20", + "adomain": [ + "awesome.com" + ], + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/screencore/screencoretest/exemplary/video-app.json b/adapters/screencore/screencoretest/exemplary/video-app.json new file mode 100644 index 00000000000..7368af33a98 --- /dev/null +++ b/adapters/screencore/screencoretest/exemplary/video-app.json @@ -0,0 +1,161 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "placementId": "placementId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + }, + "tagid": "ogTAGID" + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 1280, + "h": 720, + "mtype": 2 + } + ], + "seat": "screencore" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "crid": "20", + "adomain": [ + "awesome.com" + ], + "w": 1280, + "h": 720, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/screencore/screencoretest/exemplary/video-web.json b/adapters/screencore/screencoretest/exemplary/video-web.json new file mode 100644 index 00000000000..a56ddb78bea --- /dev/null +++ b/adapters/screencore/screencoretest/exemplary/video-web.json @@ -0,0 +1,159 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "placementId": "placementId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + } + } + ], + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 1280, + "h": 720, + "ext": { + "prebid": { + "type": "video" + } + }, + "mtype": 2 + } + ], + "seat": "screencore" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 1280, + "h": 720, + "ext": { + "prebid": { + "type": "video" + } + }, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/screencore/screencoretest/supplemental/bad_media_type.json b/adapters/screencore/screencoretest/supplemental/bad_media_type.json new file mode 100644 index 00000000000..ed7200c54a6 --- /dev/null +++ b/adapters/screencore/screencoretest/supplemental/bad_media_type.json @@ -0,0 +1,135 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "1", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "placementId": "placementId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "1", + "banner": { + "w": 320, + "h": 50 + }, + "tagid": "ogTAGID" + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "test-imp-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 320, + "h": 50 + } + ], + "mtype": 0, + "seat": "screencore" + } + ], + "cur": "USD" + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "unsupported MType 0", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/screencore/screencoretest/supplemental/empty-imp-array.json b/adapters/screencore/screencoretest/supplemental/empty-imp-array.json new file mode 100644 index 00000000000..e19996fbe2a --- /dev/null +++ b/adapters/screencore/screencoretest/supplemental/empty-imp-array.json @@ -0,0 +1,16 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "Empty Imp array in BidRequest", + "comparison": "literal" + } + ], + "mockBidRequest": { + "id": "test-request-id", + "imp": [], + "site": { + "page": "test.com" + } + }, + "httpCalls": [] + } \ No newline at end of file diff --git a/adapters/screencore/screencoretest/supplemental/empty-seatbid-array.json b/adapters/screencore/screencoretest/supplemental/empty-seatbid-array.json new file mode 100644 index 00000000000..0ed6159a54a --- /dev/null +++ b/adapters/screencore/screencoretest/supplemental/empty-seatbid-array.json @@ -0,0 +1,130 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "placementId": "placementId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + }, + "tagid": "ogTAGID" + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [], + "cur": "USD" + } + } + } + ], + "mockResponse": { + "status": 200, + "body": "invalid response" + }, + "expectedMakeBidsErrors": [ + { + "value": "Empty SeatBid array", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/screencore/screencoretest/supplemental/invalid-bidder-ext-object.json b/adapters/screencore/screencoretest/supplemental/invalid-bidder-ext-object.json new file mode 100644 index 00000000000..4dc5c5a62bc --- /dev/null +++ b/adapters/screencore/screencoretest/supplemental/invalid-bidder-ext-object.json @@ -0,0 +1,33 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "Error parsing bidderExt - json: cannot unmarshal string into Go value of type openrtb_ext.ExtScreencore", + "comparison": "literal" + } + ], + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "some-impression-id", + "tagid": "my-adcode", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": "wrongBidderExt" + } + } + ], + "site": { + "page": "test.com" + } + }, + "httpCalls": [] +} \ No newline at end of file diff --git a/adapters/screencore/screencoretest/supplemental/invalid-response.json b/adapters/screencore/screencoretest/supplemental/invalid-response.json new file mode 100644 index 00000000000..b2417d9d8d6 --- /dev/null +++ b/adapters/screencore/screencoretest/supplemental/invalid-response.json @@ -0,0 +1,112 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "placementId": "placementId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 320, + "h": 50 + }, + "tagid": "ogTAGID" + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": "invalid response" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bad Server Response", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/screencore/screencoretest/supplemental/invalid-screencore-ext-object.json b/adapters/screencore/screencoretest/supplemental/invalid-screencore-ext-object.json new file mode 100644 index 00000000000..b52e18fab50 --- /dev/null +++ b/adapters/screencore/screencoretest/supplemental/invalid-screencore-ext-object.json @@ -0,0 +1,31 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "Error parsing screencoreExt - json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "comparison": "literal" + } + ], + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "some-impression-id", + "tagid": "my-adcode", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": "wrongscreencoreExt" + } + ], + "site": { + "page": "test.com" + } + }, + "httpCalls": [] +} \ No newline at end of file diff --git a/adapters/screencore/screencoretest/supplemental/status-code-bad-request.json b/adapters/screencore/screencoretest/supplemental/status-code-bad-request.json new file mode 100644 index 00000000000..68deeef92de --- /dev/null +++ b/adapters/screencore/screencoretest/supplemental/status-code-bad-request.json @@ -0,0 +1,93 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "placementId": "placementId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", + "body": { + "id": "some-request-id", + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + }, + "tagid": "ogTAGID" + } + ], + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 400 + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/screencore/screencoretest/supplemental/status-code-no-content.json b/adapters/screencore/screencoretest/supplemental/status-code-no-content.json new file mode 100644 index 00000000000..1b6fa699a1b --- /dev/null +++ b/adapters/screencore/screencoretest/supplemental/status-code-no-content.json @@ -0,0 +1,76 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "placementId": "placementId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", + "body": { + "id": "some-request-id", + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + } + } + ], + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [] +} \ No newline at end of file diff --git a/adapters/screencore/screencoretest/supplemental/status-code-other-error.json b/adapters/screencore/screencoretest/supplemental/status-code-other-error.json new file mode 100644 index 00000000000..994b33f2b80 --- /dev/null +++ b/adapters/screencore/screencoretest/supplemental/status-code-other-error.json @@ -0,0 +1,81 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "placementId": "placementId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", + "body": { + "id": "some-request-id", + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + } + } + ], + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 306 + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 306. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/screencore/screencoretest/supplemental/status-code-service-unavailable.json b/adapters/screencore/screencoretest/supplemental/status-code-service-unavailable.json new file mode 100644 index 00000000000..b885df20c58 --- /dev/null +++ b/adapters/screencore/screencoretest/supplemental/status-code-service-unavailable.json @@ -0,0 +1,81 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "placementId": "placementId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://h1.screencore.io/?kp=accountId&kn=placementId", + "body": { + "id": "some-request-id", + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + } + } + ], + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 503 + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Something went wrong Status Code: [ 503 ] ", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 11529c5e9c3..c360ad915af 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -140,6 +140,7 @@ import ( "github.com/prebid/prebid-server/adapters/rtbhouse" "github.com/prebid/prebid-server/adapters/rubicon" salunamedia "github.com/prebid/prebid-server/adapters/sa_lunamedia" + "github.com/prebid/prebid-server/adapters/screencore" "github.com/prebid/prebid-server/adapters/seedingAlliance" "github.com/prebid/prebid-server/adapters/sharethrough" "github.com/prebid/prebid-server/adapters/silvermob" @@ -338,6 +339,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderRubicon: rubicon.Builder, openrtb_ext.BidderSeedingAlliance: seedingAlliance.Builder, openrtb_ext.BidderSaLunaMedia: salunamedia.Builder, + openrtb_ext.BidderScreencore: screencore.Builder, openrtb_ext.BidderSharethrough: sharethrough.Builder, openrtb_ext.BidderSilverMob: silvermob.Builder, openrtb_ext.BidderSmaato: smaato.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index c873e9ab567..b42966eede1 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -236,6 +236,7 @@ const ( BidderRubicon BidderName = "rubicon" BidderSeedingAlliance BidderName = "seedingAlliance" BidderSaLunaMedia BidderName = "sa_lunamedia" + BidderScreencore BidderName = "screencore" BidderSharethrough BidderName = "sharethrough" BidderSilverMob BidderName = "silvermob" BidderSmaato BidderName = "smaato" @@ -437,6 +438,7 @@ func CoreBidderNames() []BidderName { BidderRubicon, BidderSeedingAlliance, BidderSaLunaMedia, + BidderScreencore, BidderSharethrough, BidderSilverMob, BidderSmaato, diff --git a/openrtb_ext/imp_screencore.go b/openrtb_ext/imp_screencore.go new file mode 100644 index 00000000000..5a3fa1c39ff --- /dev/null +++ b/openrtb_ext/imp_screencore.go @@ -0,0 +1,6 @@ +package openrtb_ext + +type ExtScreencore struct { + AccountID string `json:"accountId"` + PlacementID string `json:"placementId"` +} diff --git a/static/bidder-info/screencore.yaml b/static/bidder-info/screencore.yaml new file mode 100644 index 00000000000..67777a13782 --- /dev/null +++ b/static/bidder-info/screencore.yaml @@ -0,0 +1,14 @@ +endpoint: 'http://h1.screencore.io/?kp={{.AccountID}}&kn={{.SourceId}}' +maintainer: + email: 'connect@screencore.io' +capabilities: + app: + mediaTypes: + - banner + - video + - native + site: + mediaTypes: + - banner + - video + - native diff --git a/static/bidder-params/screencore.json b/static/bidder-params/screencore.json new file mode 100644 index 00000000000..0a181b20f1c --- /dev/null +++ b/static/bidder-params/screencore.json @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Screencore Adapter Params", + "description": "A schema which validates params accepted by the Screencore adapter", + "type": "object", + "properties": { + "accountId": { + "type": "string", + "description": "Account id", + "minLength": 1 + }, + "placementId": { + "type": "string", + "description": "Placement id", + "minLength": 1 + } + }, + "required": [ + "accountId", + "placementId" + ] +} \ No newline at end of file From 16b701369fcea9e66cefe756d81139cee8d8a790 Mon Sep 17 00:00:00 2001 From: johnwier <49074029+johnwier@users.noreply.github.com> Date: Sun, 30 Jul 2023 23:18:38 -0700 Subject: [PATCH 051/268] Add consent strings to the user sync pixel for the Conversant adapter (#2949) Co-authored-by: johwier --- static/bidder-info/conversant.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/bidder-info/conversant.yaml b/static/bidder-info/conversant.yaml index 2135544d509..7ffd2761fde 100644 --- a/static/bidder-info/conversant.yaml +++ b/static/bidder-info/conversant.yaml @@ -13,6 +13,6 @@ capabilities: - video userSync: redirect: - url: "https://prebid-match.dotomi.com/match/bounce/current?version=1&networkId=72582&rurl={{.RedirectURL}}" + url: "https://prebid-match.dotomi.com/match/bounce/current?version=1&networkId=72582&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&rurl={{.RedirectURL}}" userMacro: "" # epsilon appends the user id to end of the redirect url and does not utilize a macro From 8ffa1c66082f1d289aa17206e9b54668afb14741 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Mon, 31 Jul 2023 11:49:32 +0530 Subject: [PATCH 052/268] Add `BidderResponseDurationMin` check (#2848) co-authored by @onkarvhanumante --- adapters/bidder.go | 2 - endpoints/openrtb2/amp_auction.go | 3 - endpoints/openrtb2/auction.go | 3 - endpoints/openrtb2/video_auction.go | 4 - exchange/bidder.go | 48 +++++++-- exchange/bidder_test.go | 151 +++++++++++++++++++++++++--- exchange/exchange.go | 12 +-- exchange/tmax_adjustments.go | 6 ++ 8 files changed, 186 insertions(+), 43 deletions(-) diff --git a/adapters/bidder.go b/adapters/bidder.go index 6e1630579f5..bb7424f3e00 100644 --- a/adapters/bidder.go +++ b/adapters/bidder.go @@ -4,7 +4,6 @@ import ( "encoding/base64" "encoding/json" "net/http" - "time" "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/config" @@ -146,7 +145,6 @@ func (r *RequestData) SetBasicAuth(username string, password string) { type ExtraRequestInfo struct { PbsEntryPoint metrics.RequestType - BidderRequestStartTime time.Time GlobalPrivacyControlHeader string CurrencyConversions currency.Conversions } diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index 0d5c35f9416..fb4b192824a 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -296,9 +296,6 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h } labels, ao = sendAmpResponse(w, hookExecutor, auctionResponse, reqWrapper, account, labels, ao, errL) - if len(ao.Errors) == 0 && !auctionRequest.BidderResponseStartTime.IsZero() { - deps.metricsEngine.RecordOverheadTime(metrics.MakeAuctionResponse, time.Since(auctionRequest.BidderResponseStartTime)) - } } func rejectAmpRequest( diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 8e01552c07a..edb478d2b73 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -292,9 +292,6 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http glog.Errorf("Error setting seat non-bid: %v", err) } labels, ao = sendAuctionResponse(w, hookExecutor, response, req.BidRequest, account, labels, ao) - if len(ao.Errors) == 0 && !auctionRequest.BidderResponseStartTime.IsZero() { - deps.metricsEngine.RecordOverheadTime(metrics.MakeAuctionResponse, time.Since(auctionRequest.BidderResponseStartTime)) - } } // setSeatNonBidRaw is transitional function for setting SeatNonBid inside bidResponse.Ext diff --git a/endpoints/openrtb2/video_auction.go b/endpoints/openrtb2/video_auction.go index a2a1e03e684..49e4585d173 100644 --- a/endpoints/openrtb2/video_auction.go +++ b/endpoints/openrtb2/video_auction.go @@ -375,10 +375,6 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re return } - if len(vo.Errors) == 0 && !auctionRequest.BidderResponseStartTime.IsZero() { - deps.metricsEngine.RecordOverheadTime(metrics.MakeAuctionResponse, time.Since(auctionRequest.BidderResponseStartTime)) - } - w.Header().Set("Content-Type", "application/json") w.Write(resp) diff --git a/exchange/bidder.go b/exchange/bidder.go index 5d9d5cba68b..03cd81f5f86 100644 --- a/exchange/bidder.go +++ b/exchange/bidder.go @@ -63,11 +63,12 @@ type AdaptedBidder interface { // bidRequestOptions holds additional options for bid request execution to maintain clean code and reasonable number of parameters type bidRequestOptions struct { - accountDebugAllowed bool - headerDebugAllowed bool - addCallSignHeader bool - bidAdjustments map[string]float64 - tmaxAdjustments *TmaxAdjustmentsPreprocessed + accountDebugAllowed bool + headerDebugAllowed bool + addCallSignHeader bool + bidAdjustments map[string]float64 + tmaxAdjustments *TmaxAdjustmentsPreprocessed + bidderRequestStartTime time.Time } type extraBidderRespInfo struct { @@ -87,6 +88,8 @@ const ( Gzip string = "GZIP" ) +var errTmaxTimeout = errors.New("exceeded tmax duration") + // AdaptBidder converts an adapters.Bidder into an exchange.AdaptedBidder. // // The name refers to the "Adapter" architecture pattern, and should not be confused with a Prebid "Adapter" @@ -190,11 +193,11 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest Bidde dataLen = len(reqData) + len(bidderRequest.BidderStoredResponses) responseChannel = make(chan *httpCallInfo, dataLen) if len(reqData) == 1 { - responseChannel <- bidder.doRequest(ctx, reqData[0], reqInfo.BidderRequestStartTime) + responseChannel <- bidder.doRequest(ctx, reqData[0], bidRequestOptions.bidderRequestStartTime, bidRequestOptions.tmaxAdjustments) } else { for _, oneReqData := range reqData { go func(data *adapters.RequestData) { - responseChannel <- bidder.doRequest(ctx, data, reqInfo.BidderRequestStartTime) + responseChannel <- bidder.doRequest(ctx, data, bidRequestOptions.bidderRequestStartTime, bidRequestOptions.tmaxAdjustments) }(oneReqData) // Method arg avoids a race condition on oneReqData } } @@ -513,11 +516,11 @@ func makeExt(httpInfo *httpCallInfo) *openrtb_ext.ExtHttpCall { // doRequest makes a request, handles the response, and returns the data needed by the // Bidder interface. -func (bidder *bidderAdapter) doRequest(ctx context.Context, req *adapters.RequestData, pbsRequestStartTime time.Time) *httpCallInfo { - return bidder.doRequestImpl(ctx, req, glog.Warningf, pbsRequestStartTime) +func (bidder *bidderAdapter) doRequest(ctx context.Context, req *adapters.RequestData, bidderRequestStartTime time.Time, tmaxAdjustments *TmaxAdjustmentsPreprocessed) *httpCallInfo { + return bidder.doRequestImpl(ctx, req, glog.Warningf, bidderRequestStartTime, tmaxAdjustments) } -func (bidder *bidderAdapter) doRequestImpl(ctx context.Context, req *adapters.RequestData, logger util.LogMsg, pbsRequestStartTime time.Time) *httpCallInfo { +func (bidder *bidderAdapter) doRequestImpl(ctx context.Context, req *adapters.RequestData, logger util.LogMsg, bidderRequestStartTime time.Time, tmaxAdjustments *TmaxAdjustmentsPreprocessed) *httpCallInfo { var requestBody []byte switch strings.ToUpper(bidder.config.EndpointCompression) { @@ -541,7 +544,17 @@ func (bidder *bidderAdapter) doRequestImpl(ctx context.Context, req *adapters.Re if !bidder.config.DisableConnMetrics { ctx = bidder.addClientTrace(ctx) } - bidder.me.RecordOverheadTime(metrics.PreBidder, time.Since(pbsRequestStartTime)) + bidder.me.RecordOverheadTime(metrics.PreBidder, time.Since(bidderRequestStartTime)) + + if tmaxAdjustments != nil && tmaxAdjustments.IsEnforced { + if hasShorterDurationThanTmax(&bidderTmaxCtx{ctx}, *tmaxAdjustments) { + return &httpCallInfo{ + request: req, + err: errTmaxTimeout, + } + } + } + httpCallStart := time.Now() httpResp, err := ctxhttp.Do(ctx, bidder.Client, httpReq) if err != nil { @@ -724,3 +737,16 @@ func getBidTypeForAdjustments(bidType openrtb_ext.BidType, impID string, imp []o } return string(bidType) } + +func hasShorterDurationThanTmax(ctx bidderTmaxContext, tmaxAdjustments TmaxAdjustmentsPreprocessed) bool { + if tmaxAdjustments.IsEnforced { + if deadline, ok := ctx.Deadline(); ok { + overheadNS := time.Duration(tmaxAdjustments.BidderNetworkLatencyBuffer+tmaxAdjustments.PBSResponsePreparationDuration) * time.Millisecond + bidderTmax := deadline.Add(-overheadNS) + + remainingDuration := ctx.Until(bidderTmax).Milliseconds() + return remainingDuration < int64(tmaxAdjustments.BidderResponseDurationMin) + } + } + return false +} diff --git a/exchange/bidder_test.go b/exchange/bidder_test.go index 3eeb3e909af..9d58e947a14 100644 --- a/exchange/bidder_test.go +++ b/exchange/bidder_test.go @@ -555,11 +555,11 @@ func TestBidderTimeout(t *testing.T) { Client: server.Client(), me: &metricsConfig.NilMetricsEngine{}, } - + tmaxAdjustments := &TmaxAdjustmentsPreprocessed{} callInfo := bidder.doRequest(ctx, &adapters.RequestData{ Method: "POST", Uri: server.URL, - }, time.Now()) + }, time.Now(), tmaxAdjustments) if callInfo.err == nil { t.Errorf("The bidder should report an error if the context has expired already.") } @@ -575,10 +575,10 @@ func TestInvalidRequest(t *testing.T) { Bidder: &mixedMultiBidder{}, Client: server.Client(), } - + tmaxAdjustments := &TmaxAdjustmentsPreprocessed{} callInfo := bidder.doRequest(context.Background(), &adapters.RequestData{ Method: "\"", // force http.NewRequest() to fail - }, time.Now()) + }, time.Now(), tmaxAdjustments) if callInfo.err == nil { t.Errorf("bidderAdapter.doRequest should return an error if the request data is malformed.") } @@ -598,11 +598,11 @@ func TestConnectionClose(t *testing.T) { BidderName: openrtb_ext.BidderAppnexus, me: &metricsConfig.NilMetricsEngine{}, } - + tmaxAdjustments := &TmaxAdjustmentsPreprocessed{} callInfo := bidder.doRequest(context.Background(), &adapters.RequestData{ Method: "POST", Uri: server.URL, - }, time.Now()) + }, time.Now(), tmaxAdjustments) if callInfo.err == nil { t.Errorf("bidderAdapter.doRequest should return an error if the connection closes unexpectedly.") } @@ -2107,9 +2107,10 @@ func TestCallRecordDNSTime(t *testing.T) { Client: &http.Client{Transport: DNSDoneTripper{}}, me: metricsMock, } + tmaxAdjustments := &TmaxAdjustmentsPreprocessed{} // Run test - bidder.doRequest(context.Background(), &adapters.RequestData{Method: "POST", Uri: "http://www.example.com/"}, time.Now()) + bidder.doRequest(context.Background(), &adapters.RequestData{Method: "POST", Uri: "http://www.example.com/"}, time.Now(), tmaxAdjustments) // Tried one or another, none seem to work without panicking metricsMock.AssertExpectations(t) @@ -2130,9 +2131,10 @@ func TestCallRecordTLSHandshakeTime(t *testing.T) { Client: &http.Client{Transport: TLSHandshakeTripper{}}, me: metricsMock, } + tmaxAdjustments := &TmaxAdjustmentsPreprocessed{} // Run test - bidder.doRequest(context.Background(), &adapters.RequestData{Method: "POST", Uri: "http://www.example.com/"}, time.Now()) + bidder.doRequest(context.Background(), &adapters.RequestData{Method: "POST", Uri: "http://www.example.com/"}, time.Now(), tmaxAdjustments) // Tried one or another, none seem to work without panicking metricsMock.AssertExpectations(t) @@ -2219,8 +2221,8 @@ func TestTimeoutNotificationOn(t *testing.T) { logger := func(msg string, args ...interface{}) { loggerBuffer.WriteString(fmt.Sprintf(fmt.Sprintln(msg), args...)) } - - bidderAdapter.doRequestImpl(ctx, &bidRequest, logger, time.Now()) + tmaxAdjustments := &TmaxAdjustmentsPreprocessed{} + bidderAdapter.doRequestImpl(ctx, &bidRequest, logger, time.Now(), tmaxAdjustments) // Wait a little longer than the 205ms mock server sleep. time.Sleep(210 * time.Millisecond) @@ -3065,8 +3067,8 @@ func TestGetBidType(t *testing.T) { } type mockBidderTmaxCtx struct { - startTime, deadline time.Time - ok bool + startTime, deadline, now time.Time + ok bool } func (m *mockBidderTmaxCtx) Deadline() (deadline time.Time, _ bool) { @@ -3076,6 +3078,10 @@ func (m *mockBidderTmaxCtx) RemainingDurationMS(deadline time.Time) int64 { return deadline.Sub(m.startTime).Milliseconds() } +func (m *mockBidderTmaxCtx) Until(t time.Time) time.Duration { + return t.Sub(m.now) +} + func TestUpdateBidderTmax(t *testing.T) { respStatus := 200 respBody := "{\"bid\":false}" @@ -3129,9 +3135,10 @@ func TestUpdateBidderTmax(t *testing.T) { bidResponse: &adapters.BidderResponse{}, } - ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(50*time.Millisecond)) + now := time.Now() + ctx, cancel := context.WithDeadline(context.Background(), now.Add(500*time.Millisecond)) defer cancel() - bidReqOptions := bidRequestOptions{tmaxAdjustments: test.tmaxAdjustments} + bidReqOptions := bidRequestOptions{bidderRequestStartTime: now, tmaxAdjustments: test.tmaxAdjustments} bidder := AdaptBidder(bidderImpl, server.Client(), &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, openrtb_ext.BidderAppnexus, &config.DebugInfo{Allow: false}, "") _, _, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), extraInfo, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{}, &hookexecution.EmptyHookExecutor{}, nil) assert.Empty(t, errs) @@ -3139,3 +3146,119 @@ func TestUpdateBidderTmax(t *testing.T) { }) } } + +func TestHasShorterDurationThanTmax(t *testing.T) { + var requestTmaxMS int64 = 700 + requestTmaxNS := requestTmaxMS * int64(time.Millisecond) + startTime := time.Date(2023, 5, 30, 1, 0, 0, 0, time.UTC) + now := time.Date(2023, 5, 30, 1, 0, 0, int(200*time.Millisecond), time.UTC) + deadline := time.Date(2023, 5, 30, 1, 0, 0, int(requestTmaxNS), time.UTC) + ctx := &mockBidderTmaxCtx{startTime: startTime, deadline: deadline, now: now, ok: true} + + tests := []struct { + description string + ctx bidderTmaxContext + requestTmax int64 + tmaxAdjustments TmaxAdjustmentsPreprocessed + expected bool + }{ + { + description: "tmax-disabled", + ctx: ctx, + requestTmax: requestTmaxMS, + tmaxAdjustments: TmaxAdjustmentsPreprocessed{IsEnforced: false}, + expected: false, + }, + { + description: "remaing-duration-greater-than-bidder-response-min", + ctx: ctx, + requestTmax: requestTmaxMS, + tmaxAdjustments: TmaxAdjustmentsPreprocessed{IsEnforced: true, PBSResponsePreparationDuration: 50, BidderNetworkLatencyBuffer: 10, BidderResponseDurationMin: 40}, + expected: false, + }, + { + description: "remaing-duration-less-than-bidder-response-min", + ctx: ctx, + requestTmax: requestTmaxMS, + tmaxAdjustments: TmaxAdjustmentsPreprocessed{IsEnforced: true, PBSResponsePreparationDuration: 100, BidderNetworkLatencyBuffer: 10, BidderResponseDurationMin: 500}, + expected: true, + }, + } + + for _, test := range tests { + t.Run(test.description, func(t *testing.T) { + assert.Equal(t, test.expected, hasShorterDurationThanTmax(test.ctx, test.tmaxAdjustments)) + }) + } +} + +func TestDoRequestImplWithTmax(t *testing.T) { + respStatus := 200 + respBody := "{\"bid\":false}" + server := httptest.NewServer(mockHandler(respStatus, "getBody", respBody)) + defer server.Close() + requestStartTime := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC) + + bidRequest := adapters.RequestData{ + Method: "POST", + Uri: server.URL, + Body: []byte(`{"id":"this-id","app":{"publisher":{"id":"pub-id"}}}`), + } + + bidderAdapter := bidderAdapter{ + me: &metricsConfig.NilMetricsEngine{}, + Client: server.Client(), + } + logger := func(msg string, args ...interface{}) {} + + tests := []struct { + ctxDeadline time.Time + description string + tmaxAdjustments *TmaxAdjustmentsPreprocessed + assertFn func(err error) + }{ + { + ctxDeadline: time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC), + description: "returns-tmax-timeout-error", + tmaxAdjustments: &TmaxAdjustmentsPreprocessed{IsEnforced: true, PBSResponsePreparationDuration: 100, BidderNetworkLatencyBuffer: 10, BidderResponseDurationMin: 5000}, + assertFn: func(err error) { assert.Equal(t, errTmaxTimeout, err) }, + }, + { + ctxDeadline: time.Now().Add(5 * time.Second), + description: "remaining-duration-greater-than-tmax-min", + tmaxAdjustments: &TmaxAdjustmentsPreprocessed{IsEnforced: true, PBSResponsePreparationDuration: 100, BidderNetworkLatencyBuffer: 10, BidderResponseDurationMin: 100}, + assertFn: func(err error) { assert.Nil(t, err) }, + }, + { + description: "tmax-disabled", + tmaxAdjustments: &TmaxAdjustmentsPreprocessed{IsEnforced: false}, + assertFn: func(err error) { assert.Nil(t, err) }, + }, + { + description: "tmax-BidderResponseDurationMin-not-set", + tmaxAdjustments: &TmaxAdjustmentsPreprocessed{IsEnforced: true, BidderResponseDurationMin: 0}, + assertFn: func(err error) { assert.Nil(t, err) }, + }, + { + description: "tmax-is-nil", + tmaxAdjustments: nil, + assertFn: func(err error) { assert.Nil(t, err) }, + }, + } + for _, test := range tests { + var ( + ctx context.Context + cancelFn context.CancelFunc + ) + + if test.ctxDeadline.IsZero() { + ctx = context.Background() + } else { + ctx, cancelFn = context.WithDeadline(context.Background(), test.ctxDeadline) + defer cancelFn() + } + + httpCallInfo := bidderAdapter.doRequestImpl(ctx, &bidRequest, logger, requestStartTime, test.tmaxAdjustments) + test.assertFn(httpCallInfo.err) + } +} diff --git a/exchange/exchange.go b/exchange/exchange.go index 1436f3ea2df..7ad15200682 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -695,14 +695,14 @@ func (e *exchange) getAllBids( reqInfo := adapters.NewExtraRequestInfo(conversions) reqInfo.PbsEntryPoint = bidderRequest.BidderLabels.RType reqInfo.GlobalPrivacyControlHeader = globalPrivacyControlHeader - reqInfo.BidderRequestStartTime = start bidReqOptions := bidRequestOptions{ - accountDebugAllowed: accountDebugAllowed, - headerDebugAllowed: headerDebugAllowed, - addCallSignHeader: isAdsCertEnabled(experiment, e.bidderInfo[string(bidderRequest.BidderName)]), - bidAdjustments: bidAdjustments, - tmaxAdjustments: tmaxAdjustments, + accountDebugAllowed: accountDebugAllowed, + headerDebugAllowed: headerDebugAllowed, + addCallSignHeader: isAdsCertEnabled(experiment, e.bidderInfo[string(bidderRequest.BidderName)]), + bidAdjustments: bidAdjustments, + tmaxAdjustments: tmaxAdjustments, + bidderRequestStartTime: start, } seatBids, extraBidderRespInfo, err := e.adapterMap[bidderRequest.BidderCoreName].requestBid(ctx, bidderRequest, conversions, &reqInfo, e.adsCertSigner, bidReqOptions, alternateBidderCodes, hookExecutor, bidAdjustmentRules) brw.bidderResponseStartTime = extraBidderRespInfo.respProcessingStartTime diff --git a/exchange/tmax_adjustments.go b/exchange/tmax_adjustments.go index 86934ecc331..29e732995af 100644 --- a/exchange/tmax_adjustments.go +++ b/exchange/tmax_adjustments.go @@ -36,6 +36,7 @@ func ProcessTMaxAdjustments(adjustmentsConfig config.TmaxAdjustments) *TmaxAdjus type bidderTmaxContext interface { Deadline() (deadline time.Time, ok bool) RemainingDurationMS(deadline time.Time) int64 + Until(t time.Time) time.Duration } type bidderTmaxCtx struct{ ctx context.Context } @@ -47,6 +48,11 @@ func (b *bidderTmaxCtx) Deadline() (deadline time.Time, ok bool) { return } +// Until returns the remaining duration until the specified time +func (b *bidderTmaxCtx) Until(t time.Time) time.Duration { + return time.Until(t) +} + func getBidderTmax(ctx bidderTmaxContext, requestTmaxMS int64, tmaxAdjustments TmaxAdjustmentsPreprocessed) int64 { if tmaxAdjustments.IsEnforced { if deadline, ok := ctx.Deadline(); ok { From 2c3ec84c2aa68b9bd4fd08bec90f43ce60e8e155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zdravko=20Kosanovi=C4=87?= <41286499+zkosanovic@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:25:57 +0400 Subject: [PATCH 053/268] Rise: Change the name of the mandatory field (#2929) Authored by: @zkosanovic --- adapters/rise/rise.go | 14 ++- .../exemplary/banner-and-video-app.json | 8 +- .../exemplary/banner-and-video-gdpr.json | 8 +- .../risetest/exemplary/banner-and-video.json | 4 +- .../exemplary/simple-banner-both-ids.json | 117 ++++++++++++++++++ .../rise/risetest/exemplary/simple-video.json | 4 +- .../risetest/supplemental/bad-request.json | 4 +- .../risetest/supplemental/missing-bidder.json | 2 +- .../supplemental/missing-extension.json | 2 +- .../risetest/supplemental/missing-mtype.json | 4 +- ...ing-publisher-id.json => missing-org.json} | 3 +- openrtb_ext/imp_rise.go | 1 + static/bidder-params/rise.json | 11 +- 13 files changed, 156 insertions(+), 26 deletions(-) create mode 100644 adapters/rise/risetest/exemplary/simple-banner-both-ids.json rename adapters/rise/risetest/supplemental/{missing-publisher-id.json => missing-org.json} (89%) diff --git a/adapters/rise/rise.go b/adapters/rise/rise.go index 5570e27d6ef..e18b7c93852 100644 --- a/adapters/rise/rise.go +++ b/adapters/rise/rise.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/openrtb_ext" @@ -26,9 +27,9 @@ func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) ( // MakeRequests prepares the HTTP requests which should be made to fetch bids. func (a *adapter) MakeRequests(openRTBRequest *openrtb2.BidRequest, _ *adapters.ExtraRequestInfo) (requestsToBidder []*adapters.RequestData, errs []error) { - publisherID, err := extractPublisherID(openRTBRequest) + org, err := extractOrg(openRTBRequest) if err != nil { - errs = append(errs, fmt.Errorf("extractPublisherID: %w", err)) + errs = append(errs, fmt.Errorf("extractOrg: %w", err)) return nil, errs } @@ -43,7 +44,7 @@ func (a *adapter) MakeRequests(openRTBRequest *openrtb2.BidRequest, _ *adapters. return append(requestsToBidder, &adapters.RequestData{ Method: http.MethodPost, - Uri: a.endpointURL + "?publisher_id=" + publisherID, + Uri: a.endpointURL + "?publisher_id=" + org, Body: openRTBRequestJSON, Headers: headers, }), nil @@ -87,7 +88,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData return bidResponse, errs } -func extractPublisherID(openRTBRequest *openrtb2.BidRequest) (string, error) { +func extractOrg(openRTBRequest *openrtb2.BidRequest) (string, error) { var err error for _, imp := range openRTBRequest.Imp { var bidderExt adapters.ExtImpBidder @@ -100,12 +101,15 @@ func extractPublisherID(openRTBRequest *openrtb2.BidRequest) (string, error) { return "", fmt.Errorf("unmarshal ImpExtRise: %w", err) } + if impExt.Org != "" { + return strings.TrimSpace(impExt.Org), nil + } if impExt.PublisherID != "" { return strings.TrimSpace(impExt.PublisherID), nil } } - return "", errors.New("no publisherID supplied") + return "", errors.New("no org or publisher_id supplied") } func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { diff --git a/adapters/rise/risetest/exemplary/banner-and-video-app.json b/adapters/rise/risetest/exemplary/banner-and-video-app.json index 9eb79156403..fa267977f72 100644 --- a/adapters/rise/risetest/exemplary/banner-and-video-app.json +++ b/adapters/rise/risetest/exemplary/banner-and-video-app.json @@ -18,7 +18,7 @@ }, "ext": { "bidder": { - "publisher_id": "72721", + "org": "72721", "path": "mvo", "zone": "1r" } @@ -41,7 +41,7 @@ }, "ext": { "bidder": { - "publisher_id": "72721", + "org": "72721", "path": "mvo", "zone": "1r" } @@ -98,7 +98,7 @@ }, "ext": { "bidder": { - "publisher_id": "72721", + "org": "72721", "zone": "1r", "path": "mvo" } @@ -121,7 +121,7 @@ }, "ext": { "bidder": { - "publisher_id": "72721", + "org": "72721", "zone": "1r", "path": "mvo" } diff --git a/adapters/rise/risetest/exemplary/banner-and-video-gdpr.json b/adapters/rise/risetest/exemplary/banner-and-video-gdpr.json index dfdf54a8c67..980b62446b5 100644 --- a/adapters/rise/risetest/exemplary/banner-and-video-gdpr.json +++ b/adapters/rise/risetest/exemplary/banner-and-video-gdpr.json @@ -18,7 +18,7 @@ }, "ext": { "bidder": { - "publisher_id": "72721", + "org": "72721", "path": "mvo", "zone": "1r" } @@ -41,7 +41,7 @@ }, "ext": { "bidder": { - "publisher_id": "72721", + "org": "72721", "path": "mvo", "zone": "1r" } @@ -83,7 +83,7 @@ }, "ext": { "bidder": { - "publisher_id": "72721", + "org": "72721", "zone": "1r", "path": "mvo" } @@ -106,7 +106,7 @@ }, "ext": { "bidder": { - "publisher_id": "72721", + "org": "72721", "zone": "1r", "path": "mvo" } diff --git a/adapters/rise/risetest/exemplary/banner-and-video.json b/adapters/rise/risetest/exemplary/banner-and-video.json index 2a2e3f681a1..d0d6a9bcc44 100644 --- a/adapters/rise/risetest/exemplary/banner-and-video.json +++ b/adapters/rise/risetest/exemplary/banner-and-video.json @@ -55,7 +55,7 @@ }, "ext": { "bidder": { - "publisher_id": "72721", + "org": "72721", "path": "mvo", "zone": "1r" } @@ -123,7 +123,7 @@ }, "ext": { "bidder": { - "publisher_id": "72721", + "org": "72721", "zone": "1r", "path": "mvo" } diff --git a/adapters/rise/risetest/exemplary/simple-banner-both-ids.json b/adapters/rise/risetest/exemplary/simple-banner-both-ids.json new file mode 100644 index 00000000000..cb6bbfa779f --- /dev/null +++ b/adapters/rise/risetest/exemplary/simple-banner-both-ids.json @@ -0,0 +1,117 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 300 + } + ] + }, + "ext": { + "bidder": { + "org": "72720", + "publisher_id": "72721", + "path": "mvo", + "zone": "1r" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server?publisher_id=72720", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 300 + } + ] + }, + "ext": { + "bidder": { + "org": "72720", + "publisher_id": "72721", + "zone": "1r", + "path": "mvo" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "Rhythmone", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "yahoo.com" + ], + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "mtype": 1 + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [{ + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": [ + "yahoo.com" + ], + "cid": "958", + "crid": "29681110", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + }] + } + ] +} diff --git a/adapters/rise/risetest/exemplary/simple-video.json b/adapters/rise/risetest/exemplary/simple-video.json index 16ca8ac72dc..921736a6295 100644 --- a/adapters/rise/risetest/exemplary/simple-video.json +++ b/adapters/rise/risetest/exemplary/simple-video.json @@ -21,7 +21,7 @@ }, "ext": { "bidder": { - "publisher_id": "72721", + "org": "72721", "path": "mvo", "zone": "1r" } @@ -55,7 +55,7 @@ }, "ext": { "bidder": { - "publisher_id": "72721", + "org": "72721", "zone": "1r", "path": "mvo" } diff --git a/adapters/rise/risetest/supplemental/bad-request.json b/adapters/rise/risetest/supplemental/bad-request.json index f2ba84b1c78..b5bedc090d9 100644 --- a/adapters/rise/risetest/supplemental/bad-request.json +++ b/adapters/rise/risetest/supplemental/bad-request.json @@ -21,7 +21,7 @@ }, "ext": { "bidder": { - "publisher_id": "72721", + "org": "72721", "path": "mvo", "zone": "1r" } @@ -55,7 +55,7 @@ }, "ext": { "bidder": { - "publisher_id": "72721", + "org": "72721", "zone": "1r", "path": "mvo" } diff --git a/adapters/rise/risetest/supplemental/missing-bidder.json b/adapters/rise/risetest/supplemental/missing-bidder.json index 2bda5161c67..0a7cc67ca08 100644 --- a/adapters/rise/risetest/supplemental/missing-bidder.json +++ b/adapters/rise/risetest/supplemental/missing-bidder.json @@ -28,7 +28,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "extractPublisherID: unmarshal ImpExtRise: unexpected end of JSON input", + "value": "extractOrg: unmarshal ImpExtRise: unexpected end of JSON input", "comparison": "literal" } ] diff --git a/adapters/rise/risetest/supplemental/missing-extension.json b/adapters/rise/risetest/supplemental/missing-extension.json index db8dbdf74d9..74e94f45c79 100644 --- a/adapters/rise/risetest/supplemental/missing-extension.json +++ b/adapters/rise/risetest/supplemental/missing-extension.json @@ -27,7 +27,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "extractPublisherID: unmarshal bidderExt: unexpected end of JSON input", + "value": "extractOrg: unmarshal bidderExt: unexpected end of JSON input", "comparison": "literal" } ] diff --git a/adapters/rise/risetest/supplemental/missing-mtype.json b/adapters/rise/risetest/supplemental/missing-mtype.json index be45db584ea..5693f25ad83 100644 --- a/adapters/rise/risetest/supplemental/missing-mtype.json +++ b/adapters/rise/risetest/supplemental/missing-mtype.json @@ -21,7 +21,7 @@ }, "ext": { "bidder": { - "publisher_id": "72721", + "org": "72721", "path": "mvo", "zone": "1r" } @@ -55,7 +55,7 @@ }, "ext": { "bidder": { - "publisher_id": "72721", + "org": "72721", "zone": "1r", "path": "mvo" } diff --git a/adapters/rise/risetest/supplemental/missing-publisher-id.json b/adapters/rise/risetest/supplemental/missing-org.json similarity index 89% rename from adapters/rise/risetest/supplemental/missing-publisher-id.json rename to adapters/rise/risetest/supplemental/missing-org.json index 3a14b213160..4107d40e1c3 100644 --- a/adapters/rise/risetest/supplemental/missing-publisher-id.json +++ b/adapters/rise/risetest/supplemental/missing-org.json @@ -24,6 +24,7 @@ }, "ext": { "bidder": { + "org": "", "publisher_id": "" }} } @@ -31,7 +32,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "extractPublisherID: no publisherID supplied", + "value": "extractOrg: no org or publisher_id supplied", "comparison": "literal" } ] diff --git a/openrtb_ext/imp_rise.go b/openrtb_ext/imp_rise.go index 4bdd302ee99..7311f05d52d 100644 --- a/openrtb_ext/imp_rise.go +++ b/openrtb_ext/imp_rise.go @@ -3,4 +3,5 @@ package openrtb_ext // ImpExtRise defines the contract for bidrequest.imp[i].ext.prebid.bidder.rise type ImpExtRise struct { PublisherID string `json:"publisher_id"` + Org string `json:"org"` } diff --git a/static/bidder-params/rise.json b/static/bidder-params/rise.json index 8e745d89fd0..c5344b7ab0f 100644 --- a/static/bidder-params/rise.json +++ b/static/bidder-params/rise.json @@ -4,10 +4,17 @@ "description": "A schema which validates params accepted by the Rise adapter", "type": "object", "properties": { + "org": { + "type": "string", + "description": "The organization ID." + }, "publisher_id": { "type": "string", - "description": "The publisher ID" + "description": "Deprecated, use org instead." } }, - "required": ["publisher_id"] + "oneOf": [ + { "required": ["org"] }, + { "required": ["publisher_id"] } + ] } From 02ff1922123dc589621e44aaeb3173c7550b5ae2 Mon Sep 17 00:00:00 2001 From: Sonali-More-Xandr <87759626+Sonali-More-Xandr@users.noreply.github.com> Date: Mon, 31 Jul 2023 12:53:16 +0530 Subject: [PATCH 054/268] Semgrep rule to add warning to use MType (#2965) --- .semgrep/README.md | 17 +++++++ .semgrep/adapter/bid-type-if-check.go | 55 ++++++++++++++++++++++ .semgrep/adapter/bid-type-if-check.yml | 19 ++++++++ .semgrep/adapter/bid-type-switch-check.go | 36 ++++++++++++++ .semgrep/adapter/bid-type-switch-check.yml | 23 +++++++++ .semgrep/adapter/parse-bid-type-check.go | 29 ++++++++++++ .semgrep/adapter/parse-bid-type-check.yml | 8 ++++ 7 files changed, 187 insertions(+) create mode 100644 .semgrep/README.md create mode 100644 .semgrep/adapter/bid-type-if-check.go create mode 100644 .semgrep/adapter/bid-type-if-check.yml create mode 100644 .semgrep/adapter/bid-type-switch-check.go create mode 100644 .semgrep/adapter/bid-type-switch-check.yml create mode 100644 .semgrep/adapter/parse-bid-type-check.go create mode 100644 .semgrep/adapter/parse-bid-type-check.yml diff --git a/.semgrep/README.md b/.semgrep/README.md new file mode 100644 index 00000000000..cd19e4bcc61 --- /dev/null +++ b/.semgrep/README.md @@ -0,0 +1,17 @@ +# Semgrep Test + +Running semgrep unit tests: +```bash +semgrep --test +``` + + +Running single semgrep rules against adapter code: +```bash +semgrep --config=./adapter/{rule}.yml ../adapters/ +``` + +Running all semgrep rules simultaneously: +```bash +semgrep --config=./adapter ../adapters/ +``` diff --git a/.semgrep/adapter/bid-type-if-check.go b/.semgrep/adapter/bid-type-if-check.go new file mode 100644 index 00000000000..52b5d551377 --- /dev/null +++ b/.semgrep/adapter/bid-type-if-check.go @@ -0,0 +1,55 @@ +/* + bid-type-if-check tests + https://semgrep.dev/docs/writing-rules/testing-rules + "ruleid" prefix in comment indicates patterns that should be flagged by semgrep + "ok" prefix in comment indidcates patterns that should not be flagged by the semgrep +*/ + +func getMediaTypeForImp(impID string, imps []openrtb2.Imp) openrtb_ext.BidType { + for _, imp := range imps { + if imp.ID == impID { + // ruleid: bid-type-if-check + if imp.Banner != nil { + return openrtb_ext.BidTypeBanner, nil + // ruleid: bid-type-if-check + } else if imp.Video != nil { + return openrtb_ext.BidTypeVideo, nil + // ruleid: bid-type-if-check + } else if imp.Native != nil { + return openrtb_ext.BidTypeNative, nil + // ruleid: bid-type-if-check + } else if imp.Audio != nil { + return openrtb_ext.BidTypeAudio, nil + } + } + } + return openrtb_ext.BidTypeBanner +} + +func getMediaTypeForImp(impID string, imps []openrtb2.Imp) (openrtb_ext.BidType, error) { + for _, imp := range imps { + if imp.ID == impID { + // ruleid: bid-type-if-check + if imp.Banner != nil { + return openrtb_ext.BidTypeBanner, nil + } + } + } + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("Failed to find native/banner/video impression \"%s\" ", impID), + } +} + +func getMediaTypeForImp(impID string, imps []openrtb2.Imp) (openrtb_ext.BidType, error) { + for _, imp := range imps { + if imp.ID == impID { + // ruleid: bid-type-if-check + if imp.Banner != nil { + return openrtb_ext.BidTypeBanner + } + } + } + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("Failed to find native/banner/video impression \"%s\" ", impID), + } +} diff --git a/.semgrep/adapter/bid-type-if-check.yml b/.semgrep/adapter/bid-type-if-check.yml new file mode 100644 index 00000000000..a2aa238e5f7 --- /dev/null +++ b/.semgrep/adapter/bid-type-if-check.yml @@ -0,0 +1,19 @@ +rules: + - id: bid-type-if-check + message: The current implementation follows an anti-pattern, assumes that if there is a multi-format request, the media type defaults to $ORTBTYPE. Prebid server expects the media type to be explicitly set in the adapter response. Therefore, we strongly recommend implementing a pattern where the adapter server sets the [MType](https://github.com/prebid/openrtb/blob/main/openrtb2/bid.go#L334) field in the response to accurately determine the media type for the impression. + languages: + - go + severity: WARNING + patterns: + - pattern-inside: | + if $CONDITION != nil { + return $ORTBTYPE + } + - metavariable-pattern: + metavariable: $ORTBTYPE + patterns: + - pattern-either: + - pattern: openrtb_ext.$BIDTYPE + - metavariable-regex: + metavariable: $BIDTYPE + regex: BidType* \ No newline at end of file diff --git a/.semgrep/adapter/bid-type-switch-check.go b/.semgrep/adapter/bid-type-switch-check.go new file mode 100644 index 00000000000..c8adf4f9834 --- /dev/null +++ b/.semgrep/adapter/bid-type-switch-check.go @@ -0,0 +1,36 @@ +/* + bid-type-switch-check tests + https://semgrep.dev/docs/writing-rules/testing-rules + "ruleid" prefix in comment indicates patterns that should be flagged by semgrep + "ok" prefix in comment indidcates patterns that should not be flagged by the semgrep +*/ + +// ruleid: bid-type-switch-check +switch bidExt.AdCodeType { +case "banner": + return openrtb_ext.BidTypeBanner, nil +case "native": + return openrtb_ext.BidTypeNative, nil +case "video": + return openrtb_ext.BidTypeVideo, nil +} + +// ruleid: bid-type-switch-check +switch impExt.Adot.MediaType { +case string(openrtb_ext.BidTypeBanner): + return openrtb_ext.BidTypeBanner, nil +case string(openrtb_ext.BidTypeVideo): + return openrtb_ext.BidTypeVideo, nil +case string(openrtb_ext.BidTypeNative): + return openrtb_ext.BidTypeNative, nil +} + +// ok: bid-type-switch-check +switch bid.MType { +case "banner": + return openrtb_ext.BidTypeBanner, nil +case "native": + return openrtb_ext.BidTypeNative, nil +case "video": + return openrtb_ext.BidTypeVideo, nil +} diff --git a/.semgrep/adapter/bid-type-switch-check.yml b/.semgrep/adapter/bid-type-switch-check.yml new file mode 100644 index 00000000000..b39cf870aa7 --- /dev/null +++ b/.semgrep/adapter/bid-type-switch-check.yml @@ -0,0 +1,23 @@ +rules: + - id: bid-type-switch-check + message: The current implementation follows an anti-pattern, assumes that if there is a multi-format request, the media type defaults to $ORTBTYPE. Prebid server expects the media type to be explicitly set in the adapter response. Therefore, we strongly recommend implementing a pattern where the adapter server sets the [MType](https://github.com/prebid/openrtb/blob/main/openrtb2/bid.go#L334) field in the response to accurately determine the media type for the impression. + languages: + - go + severity: WARNING + patterns: + - pattern-inside: | + switch $BIDTYPE { + case ...: + return $ORTBTYPE, nil + } + - metavariable-regex: + metavariable: $BIDTYPE + regex: ^(?!bid\.MType$).*$ + - metavariable-pattern: + metavariable: $ORTBTYPE + patterns: + - pattern-either: + - pattern: openrtb_ext.$W + - metavariable-regex: + metavariable: $W + regex: BidType* \ No newline at end of file diff --git a/.semgrep/adapter/parse-bid-type-check.go b/.semgrep/adapter/parse-bid-type-check.go new file mode 100644 index 00000000000..77badd14b16 --- /dev/null +++ b/.semgrep/adapter/parse-bid-type-check.go @@ -0,0 +1,29 @@ +/* + parse-bid-type-check tests + https://semgrep.dev/docs/writing-rules/testing-rules + "ruleid" prefix in comment indicates patterns that should be flagged by semgrep + "ok" prefix in comment indidcates patterns that should not be flagged by the semgrep +*/ + +func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + if bid.Ext != nil { + var bidExt openrtb_ext.ExtBid + err := json.Unmarshal(bid.Ext, &bidExt) + if err == nil && bidExt.Prebid != nil { + // ruleid: parse-bid-type-check + return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type)) + } + } + + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Failed to parse impression \"%s\" mediatype", bid.ImpID), + } +} + +func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + var bidExt bidExt + // ruleid: parse-bid-type-check + bidType, err := openrtb_ext.ParseBidType(bidExt.Prebid.Type) + + return bidType, err +} diff --git a/.semgrep/adapter/parse-bid-type-check.yml b/.semgrep/adapter/parse-bid-type-check.yml new file mode 100644 index 00000000000..e2d3624115b --- /dev/null +++ b/.semgrep/adapter/parse-bid-type-check.yml @@ -0,0 +1,8 @@ +rules: + - id: parse-bid-type-check + message: The current implementation follows an anti-pattern, assumes that if there is a multi-format request, the media type defaults to $ORTBTYPE. Prebid server expects the media type to be explicitly set in the adapter response. Therefore, we strongly recommend implementing a pattern where the adapter server sets the [MType](https://github.com/prebid/openrtb/blob/main/openrtb2/bid.go#L334) field in the response to accurately determine the media type for the impression. + languages: + - go + severity: WARNING + patterns: + - pattern: openrtb_ext.ParseBidType(...) \ No newline at end of file From 21cf1f1af4db9467c69b1c3ccf22f3d6e93e6180 Mon Sep 17 00:00:00 2001 From: mwang-sticky Date: Mon, 31 Jul 2023 21:41:20 +0800 Subject: [PATCH 055/268] freewheel: support int and string for zoneId (#2935) --- .../freewheelssptest/exemplary/multi-imp.json | 2 +- .../exemplary/string-single-imp.json | 97 +++++++++++++++++++ .../supplemental/zoneid_error.json | 29 ++++++ openrtb_ext/imp_freewheelssp.go | 6 +- static/bidder-params/freewheel-ssp.json | 2 +- static/bidder-params/freewheelssp.json | 2 +- 6 files changed, 134 insertions(+), 4 deletions(-) create mode 100644 adapters/freewheelssp/freewheelssptest/exemplary/string-single-imp.json create mode 100644 adapters/freewheelssp/freewheelssptest/supplemental/zoneid_error.json diff --git a/adapters/freewheelssp/freewheelssptest/exemplary/multi-imp.json b/adapters/freewheelssp/freewheelssptest/exemplary/multi-imp.json index 5ec36993375..e6838240ca4 100644 --- a/adapters/freewheelssp/freewheelssptest/exemplary/multi-imp.json +++ b/adapters/freewheelssp/freewheelssptest/exemplary/multi-imp.json @@ -14,7 +14,7 @@ }, "ext": { "bidder": { - "zoneId": 12345 + "zoneId": "12345" } } }, diff --git a/adapters/freewheelssp/freewheelssptest/exemplary/string-single-imp.json b/adapters/freewheelssp/freewheelssptest/exemplary/string-single-imp.json new file mode 100644 index 00000000000..c17c7167d6e --- /dev/null +++ b/adapters/freewheelssp/freewheelssptest/exemplary/string-single-imp.json @@ -0,0 +1,97 @@ +{ + "mockBidRequest": { + "id": "freewheelssp-test", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "imp-1", + "video": { + "mimes": ["video/mp4"], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "zoneId": "12345" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://testjsonsample.com", + "body":{ + "id": "freewheelssp-test", + "site": { + "page": "prebid.org" + }, + "imp": [{ + "id": "imp-1", + "video": { + "mimes": ["video/mp4"], + "w": 300, + "h": 250 + }, + "ext": { + "zoneId": 12345 + } + }] + }, + "headers": { + "Componentid": [ + "prebid-go" + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "freewheelssp-test", + "seatbid": [ + { + "bid": [ + { + "id": "12345_freewheelssp-test_1", + "impid": "imp-1", + "price": 1.0, + "adid": "7857", + "adm": "", + "cid": "4001", + "crid": "7857" + } + ], + "seat": "freewheelsspTv" + } + ], + "bidid": "freewheelssp-test", + "cur": "EUR" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "CUR", + "bids": [ + { + "bid": { + "id": "12345_freewheelssp-test_1", + "impid": "imp-1", + "price": 1.0, + "adid": "7857", + "adm": "", + "cid": "4001", + "crid": "7857" + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/freewheelssp/freewheelssptest/supplemental/zoneid_error.json b/adapters/freewheelssp/freewheelssptest/supplemental/zoneid_error.json new file mode 100644 index 00000000000..b45296ab32c --- /dev/null +++ b/adapters/freewheelssp/freewheelssptest/supplemental/zoneid_error.json @@ -0,0 +1,29 @@ +{ + "mockBidRequest": { + "id": "freewheelssp-test", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "imp-1", + "video": { + "mimes": ["video/mp4"], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "zoneId": "abc123" + } + } + } + ] + }, + "expectedMakeRequestsErrors": [ + { + "value": ".*Invalid imp.ext for impression index 0.*", + "comparison": "regex" + } + ] +} \ No newline at end of file diff --git a/openrtb_ext/imp_freewheelssp.go b/openrtb_ext/imp_freewheelssp.go index 11c22ff8154..110f018f512 100644 --- a/openrtb_ext/imp_freewheelssp.go +++ b/openrtb_ext/imp_freewheelssp.go @@ -1,5 +1,9 @@ package openrtb_ext +import ( + "github.com/prebid/prebid-server/util/jsonutil" +) + type ImpExtFreewheelSSP struct { - ZoneId int `json:"zoneId"` + ZoneId jsonutil.StringInt `json:"zoneId"` } diff --git a/static/bidder-params/freewheel-ssp.json b/static/bidder-params/freewheel-ssp.json index 103aed03198..23375f7603c 100644 --- a/static/bidder-params/freewheel-ssp.json +++ b/static/bidder-params/freewheel-ssp.json @@ -6,7 +6,7 @@ "properties": { "zoneId": { - "type": "integer", + "type": ["integer", "string"], "description": "Zone ID" } }, diff --git a/static/bidder-params/freewheelssp.json b/static/bidder-params/freewheelssp.json index 6f93501a3e1..ced3c28daf3 100644 --- a/static/bidder-params/freewheelssp.json +++ b/static/bidder-params/freewheelssp.json @@ -6,7 +6,7 @@ "properties": { "zoneId": { - "type": "integer", + "type": ["integer", "string"], "description": "Zone ID" } }, From 61a209ae876cd4119474029914fd8d1684f98a8c Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Tue, 1 Aug 2023 13:13:04 -0400 Subject: [PATCH 056/268] AppNexus: Downgrade SChain In Adapter (#2988) --- adapters/appnexus/appnexus.go | 128 ++++++++--- adapters/appnexus/appnexus_test.go | 7 +- .../appnexustest/amp/simple-banner.json | 2 - .../appnexustest/amp/simple-video.json | 2 - .../exemplary/dynamic-keywords-params.json | 3 +- .../appnexustest/exemplary/native-1.1.json | 3 +- .../exemplary/optional-params.json | 3 +- .../exemplary/schain-24-other-ext.json | 193 +++++++++++++++++ .../appnexustest/exemplary/schain-24.json | 191 ++++++++++++++++ .../exemplary/schain-25-other-ext.json | 203 ++++++++++++++++++ .../appnexustest/exemplary/schain-25.json | 194 +++++++++++++++++ .../simple-banner-foreign-currency.json | 3 +- .../appnexustest/exemplary/simple-banner.json | 3 +- .../appnexustest/exemplary/simple-video.json | 3 +- .../exemplary/string-keywords-params.json | 3 +- .../exemplary/video-invalid-category.json | 3 +- .../supplemental/displaymanager-test.json | 3 +- .../supplemental/explicit-dimensions.json | 3 +- .../supplemental/invalid-bid-type.json | 3 +- .../supplemental/legacy-params.json | 3 +- .../appnexustest/supplemental/multi-bid.json | 3 +- .../placement-id-as-string-test.json | 3 +- .../request-ext-appnexus-existing.json | 171 +++++++++++++++ .../supplemental/reserve-ignored.json | 3 +- .../supplemental/reserve-test.json | 3 +- .../appnexustest/supplemental/status-400.json | 3 +- .../supplemental/usePmtRule-test.json | 3 +- .../video/video-brand-category.json | 179 +++++++++++++++ ...deo-no-adpodid-two-imps-different-pod.json | 3 +- .../video-same-adpodid-two-imps-same-pod.json | 3 +- adapters/appnexus/models.go | 12 +- 31 files changed, 1257 insertions(+), 85 deletions(-) create mode 100644 adapters/appnexus/appnexustest/exemplary/schain-24-other-ext.json create mode 100644 adapters/appnexus/appnexustest/exemplary/schain-24.json create mode 100644 adapters/appnexus/appnexustest/exemplary/schain-25-other-ext.json create mode 100644 adapters/appnexus/appnexustest/exemplary/schain-25.json create mode 100644 adapters/appnexus/appnexustest/supplemental/request-ext-appnexus-existing.json create mode 100644 adapters/appnexus/appnexustest/video/video-brand-category.json diff --git a/adapters/appnexus/appnexus.go b/adapters/appnexus/appnexus.go index 93a0bf95593..ddba6a58de7 100644 --- a/adapters/appnexus/appnexus.go +++ b/adapters/appnexus/appnexus.go @@ -13,6 +13,8 @@ import ( "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/util/maputil" + "github.com/prebid/prebid-server/util/ptrutil" "github.com/prebid/prebid-server/util/randomutil" "github.com/prebid/prebid-server/adapters" @@ -22,8 +24,8 @@ import ( ) const ( - defaultPlatformID int = 5 - maxImpsPerReq = 10 + defaultPlatformID = 5 + maxImpsPerReq = 10 ) type adapter struct { @@ -65,7 +67,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E var ( shouldGenerateAdPodId *bool uniqueMemberID string - errs = make([]error, 0, len(request.Imp)) + errs []error ) validImps := []openrtb2.Imp{} @@ -112,7 +114,6 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E } requestURI := a.uri - if uniqueMemberID != "" { requestURI = appendMemberId(requestURI, uniqueMemberID) } @@ -125,10 +126,20 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E isVIDEO = 1 } - reqExt, err := a.getRequestExt(request.Ext, isAMP, isVIDEO) + reqExt, err := getRequestExt(request.Ext) + if err != nil { + return nil, append(errs, err) + } + + reqExtAppnexus, err := a.getAppnexusExt(reqExt, isAMP, isVIDEO) if err != nil { return nil, append(errs, err) } + + if err := moveSupplyChain(request, reqExt); err != nil { + return nil, append(errs, err) + } + // 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 @@ -136,11 +147,11 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E // If impressions number per pod is more than maxImpsPerReq - divide those imps to several requests but keep pod id the same // 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 && *shouldGenerateAdPodId { - requests, errors := a.buildAdPodRequests(request.Imp, request, reqExt, requestURI.String()) + requests, errors := a.buildAdPodRequests(request.Imp, request, reqExt, reqExtAppnexus, requestURI.String()) return requests, append(errs, errors...) } - requests, errors := splitRequests(request.Imp, request, reqExt, requestURI.String()) + requests, errors := splitRequests(request.Imp, request, reqExt, reqExtAppnexus, requestURI.String()) return requests, append(errs, errors...) } @@ -200,25 +211,43 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest return bidderResponse, errs } -func (a *adapter) getRequestExt(ext json.RawMessage, isAMP int, isVIDEO int) (bidReqExt, error) { - var reqExt bidReqExt +func getRequestExt(ext json.RawMessage) (map[string]json.RawMessage, error) { + extMap := make(map[string]json.RawMessage) + if len(ext) > 0 { - if err := json.Unmarshal(ext, &reqExt); err != nil { - return bidReqExt{}, err + if err := json.Unmarshal(ext, &extMap); err != nil { + return nil, err } } - if reqExt.Appnexus == nil { - reqExt.Appnexus = &bidReqExtAppnexus{} + + return extMap, nil +} + +func (a *adapter) getAppnexusExt(extMap map[string]json.RawMessage, isAMP int, isVIDEO int) (bidReqExtAppnexus, error) { + var appnexusExt bidReqExtAppnexus + + if appnexusExtJson, exists := extMap["appnexus"]; exists && len(appnexusExtJson) > 0 { + if err := json.Unmarshal(appnexusExtJson, &appnexusExt); err != nil { + return appnexusExt, err + } } - includeBrandCategory := reqExt.Prebid.Targeting != nil && reqExt.Prebid.Targeting.IncludeBrandCategory != nil - if includeBrandCategory { - reqExt.Appnexus.BrandCategoryUniqueness = &includeBrandCategory - reqExt.Appnexus.IncludeBrandCategory = &includeBrandCategory + + if prebidJson, exists := extMap["prebid"]; exists { + _, valueType, _, err := jsonparser.Get(prebidJson, "targeting", "includebrandcategory") + if err != nil && !errors.Is(err, jsonparser.KeyPathNotFoundError) { + return appnexusExt, err + } + + if valueType == jsonparser.Object { + appnexusExt.BrandCategoryUniqueness = ptrutil.ToPtr(true) + appnexusExt.IncludeBrandCategory = ptrutil.ToPtr(true) + } } - reqExt.Appnexus.IsAMP = isAMP - reqExt.Appnexus.HeaderBiddingSource = a.hbSource + isVIDEO - return reqExt, nil + appnexusExt.IsAMP = isAMP + appnexusExt.HeaderBiddingSource = a.hbSource + isVIDEO + + return appnexusExt, nil } func validateAndBuildAppNexusExt(imp *openrtb2.Imp) (openrtb_ext.ExtImpAppnexus, error) { @@ -266,7 +295,7 @@ func groupByPods(imps []openrtb2.Imp) map[string]([]openrtb2.Imp) { return podImps } -func splitRequests(imps []openrtb2.Imp, request *openrtb2.BidRequest, requestExtension bidReqExt, uri string) ([]*adapters.RequestData, []error) { +func splitRequests(imps []openrtb2.Imp, request *openrtb2.BidRequest, requestExt map[string]json.RawMessage, requestExtAppnexus bidReqExtAppnexus, uri string) ([]*adapters.RequestData, []error) { var errs []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. @@ -281,14 +310,20 @@ func splitRequests(imps []openrtb2.Imp, request *openrtb2.BidRequest, requestExt headers.Add("Content-Type", "application/json;charset=utf-8") headers.Add("Accept", "application/json") - var err error - request.Ext, err = json.Marshal(requestExtension) + appnexusExtJson, err := json.Marshal(requestExtAppnexus) if err != nil { errs = append(errs, err) } - for impsLeft { + requestExtClone := maputil.Clone(requestExt) + requestExtClone["appnexus"] = appnexusExtJson + request.Ext, err = json.Marshal(requestExtClone) + if err != nil { + errs = append(errs, err) + } + + for impsLeft { endInd := startInd + maxImpsPerReq if endInd >= len(imps) { endInd = len(imps) @@ -327,9 +362,11 @@ func buildRequestImp(imp *openrtb2.Imp, appnexusExt *openrtb_ext.ExtImpAppnexus, if appnexusExt.InvCode != "" { imp.TagID = appnexusExt.InvCode } + if imp.BidFloor <= 0 && appnexusExt.Reserve > 0 { imp.BidFloor = appnexusExt.Reserve // This will be broken for non-USD currency. } + if imp.Banner != nil { bannerCopy := *imp.Banner if appnexusExt.Position == "above" { @@ -358,7 +395,7 @@ func buildRequestImp(imp *openrtb2.Imp, appnexusExt *openrtb_ext.ExtImpAppnexus, UsePmtRule: appnexusExt.UsePaymentRule, PrivateSizes: appnexusExt.PrivateSizes, ExtInvCode: appnexusExt.ExtInvCode, - ExternalImpId: appnexusExt.ExternalImpId, + ExternalImpID: appnexusExt.ExternalImpId, }} var err error @@ -413,14 +450,49 @@ func buildDisplayManageVer(req *openrtb2.BidRequest) string { return fmt.Sprintf("%s-%s", source, version) } -func (a *adapter) buildAdPodRequests(imps []openrtb2.Imp, request *openrtb2.BidRequest, requestExtension bidReqExt, uri string) ([]*adapters.RequestData, []error) { +// moveSupplyChain moves the supply chain object from source.ext.schain to ext.schain. +func moveSupplyChain(request *openrtb2.BidRequest, extMap map[string]json.RawMessage) error { + if request == nil || request.Source == nil || len(request.Source.Ext) == 0 { + return nil + } + + sourceExtMap := make(map[string]json.RawMessage) + if err := json.Unmarshal(request.Source.Ext, &sourceExtMap); err != nil { + return err + } + + schainJson, exists := sourceExtMap["schain"] + if !exists { + return nil + } + + delete(sourceExtMap, "schain") + + request.Source = ptrutil.Clone(request.Source) + + if len(sourceExtMap) > 0 { + ext, err := json.Marshal(sourceExtMap) + if err != nil { + return err + } + request.Source.Ext = ext + } else { + request.Source.Ext = nil + } + + extMap["schain"] = schainJson + + return nil +} + +func (a *adapter) buildAdPodRequests(imps []openrtb2.Imp, request *openrtb2.BidRequest, requestExt map[string]json.RawMessage, requestExtAppnexus bidReqExtAppnexus, uri string) ([]*adapters.RequestData, []error) { var errs []error podImps := groupByPods(imps) requests := make([]*adapters.RequestData, 0, len(podImps)) for _, podImps := range podImps { - requestExtension.Appnexus.AdPodId = fmt.Sprint(a.randomGenerator.GenerateInt63()) + requestExtAppnexus.AdPodID = fmt.Sprint(a.randomGenerator.GenerateInt63()) - reqs, errors := splitRequests(podImps, request, requestExtension, uri) + reqs, errors := splitRequests(podImps, request, requestExt, requestExtAppnexus, uri) requests = append(requests, reqs...) errs = append(errs, errors...) } diff --git a/adapters/appnexus/appnexus_test.go b/adapters/appnexus/appnexus_test.go index e6ba0109185..bb04b61bb97 100644 --- a/adapters/appnexus/appnexus_test.go +++ b/adapters/appnexus/appnexus_test.go @@ -8,6 +8,7 @@ import ( "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/openrtb_ext" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestJsonSamples(t *testing.T) { @@ -26,7 +27,8 @@ func TestJsonSamples(t *testing.T) { func TestAppendMemberID(t *testing.T) { uri, err := url.Parse("http://ib.adnxs.com/openrtb2?query_param=true") - assert.NoError(t, err, "Failed to parse URI with query string") + require.NoError(t, err, "Failed to parse URI with query string") + uriWithMember := appendMemberId(*uri, "102") expected := "http://ib.adnxs.com/openrtb2?member_id=102&query_param=true" assert.Equal(t, expected, uriWithMember.String(), "Failed to append member id to URI with query string") @@ -37,11 +39,10 @@ func TestBuilderWithPlatformID(t *testing.T) { Endpoint: "http://ib.adnxs.com/openrtb2", PlatformID: "3"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) assert.NoError(t, buildErr) - assert.NotNil(t, bidder) + require.NotNil(t, bidder) assert.Equal(t, 3, (*bidder.(*adapter)).hbSource) } -// fakerandomNumberGenerator type FakeRandomNumberGenerator struct { Number int64 } diff --git a/adapters/appnexus/appnexustest/amp/simple-banner.json b/adapters/appnexus/appnexustest/amp/simple-banner.json index 54e6a143e19..4ed3403db7a 100644 --- a/adapters/appnexus/appnexustest/amp/simple-banner.json +++ b/adapters/appnexus/appnexustest/amp/simple-banner.json @@ -34,8 +34,6 @@ "appnexus": { "is_amp": 1, "hb_source": 5 - }, - "prebid": { } }, "id": "test-request-id", diff --git a/adapters/appnexus/appnexustest/amp/simple-video.json b/adapters/appnexus/appnexustest/amp/simple-video.json index c9744831b8b..623085e72a0 100644 --- a/adapters/appnexus/appnexustest/amp/simple-video.json +++ b/adapters/appnexus/appnexustest/amp/simple-video.json @@ -30,8 +30,6 @@ "appnexus": { "is_amp": 1, "hb_source": 5 - }, - "prebid": { } }, "id": "test-request-id", diff --git a/adapters/appnexus/appnexustest/exemplary/dynamic-keywords-params.json b/adapters/appnexus/appnexustest/exemplary/dynamic-keywords-params.json index 869c32d8c9f..d0af71e648a 100644 --- a/adapters/appnexus/appnexustest/exemplary/dynamic-keywords-params.json +++ b/adapters/appnexus/appnexustest/exemplary/dynamic-keywords-params.json @@ -41,8 +41,7 @@ "ext": { "appnexus": { "hb_source": 5 - }, - "prebid": {} + } }, "imp": [ { diff --git a/adapters/appnexus/appnexustest/exemplary/native-1.1.json b/adapters/appnexus/appnexustest/exemplary/native-1.1.json index 189304fdb4c..b40543f12e9 100644 --- a/adapters/appnexus/appnexustest/exemplary/native-1.1.json +++ b/adapters/appnexus/appnexustest/exemplary/native-1.1.json @@ -51,8 +51,7 @@ "ext": { "appnexus": { "hb_source": 5 - }, - "prebid": {} + } }, "site": { "domain": "prebid.org", diff --git a/adapters/appnexus/appnexustest/exemplary/optional-params.json b/adapters/appnexus/appnexustest/exemplary/optional-params.json index e105d6e1e8e..01af8252ba9 100644 --- a/adapters/appnexus/appnexustest/exemplary/optional-params.json +++ b/adapters/appnexus/appnexustest/exemplary/optional-params.json @@ -46,8 +46,7 @@ "ext": { "appnexus": { "hb_source": 5 - }, - "prebid": {} + } }, "imp": [ { diff --git a/adapters/appnexus/appnexustest/exemplary/schain-24-other-ext.json b/adapters/appnexus/appnexustest/exemplary/schain-24-other-ext.json new file mode 100644 index 00000000000..e5a258e7f35 --- /dev/null +++ b/adapters/appnexus/appnexustest/exemplary/schain-24-other-ext.json @@ -0,0 +1,193 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "ext": { + "prebid": { + "source": "source", + "version": "version" + } + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placement_id": 1, + "position": "above" + } + } + } + ], + "ext": { + "schain": { + "complete": 0, + "nodes": [ + { + "asi": "pbshostcompany.com", + "sid": "00001", + "rid": "BidRequest", + "hp": 1 + } + ], + "ver": "1.0" + }, + "otherRequest": "value" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://ib.adnxs.com/openrtb2", + "body": { + "id": "test-request-id", + "app": { + "ext": { + "prebid": { + "source": "source", + "version": "version" + } + } + }, + "ext": { + "appnexus": { + "hb_source": 5 + }, + "schain": { + "complete": 0, + "nodes": [ + { + "asi": "pbshostcompany.com", + "sid": "00001", + "rid": "BidRequest", + "hp": 1 + } + ], + "ver": "1.0" + }, + "otherRequest": "value" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ], + "w": 300, + "pos": 1, + "h": 250 + }, + "displaymanagerver": "source-version", + "ext": { + "appnexus": { + "placement_id": 1 + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "appnexus.com" + ], + "iurl": "http://nym1-ib.adnxs.com/cr?id=29681110", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": { + "appnexus": { + "brand_id": 1, + "brand_category_id": 1, + "auction_id": 8189378542222915032, + "bid_ad_type": 0, + "bidder_id": 2, + "ranking_price": 0.000000, + "deal_priority": 5 + } + } + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": [ + "appnexus.com" + ], + "iurl": "http://nym1-ib.adnxs.com/cr?id=29681110", + "cid": "958", + "crid": "29681110", + "w": 300, + "h": 250, + "cat": [ + "IAB20-3" + ], + "ext": { + "appnexus": { + "brand_id": 1, + "brand_category_id": 1, + "auction_id": 8189378542222915032, + "bid_ad_type": 0, + "bidder_id": 2, + "ranking_price": 0.000000, + "deal_priority": 5 + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/appnexus/appnexustest/exemplary/schain-24.json b/adapters/appnexus/appnexustest/exemplary/schain-24.json new file mode 100644 index 00000000000..d8f26d10a07 --- /dev/null +++ b/adapters/appnexus/appnexustest/exemplary/schain-24.json @@ -0,0 +1,191 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "ext": { + "prebid": { + "source": "source", + "version": "version" + } + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placement_id": 1, + "position": "above" + } + } + } + ], + "ext": { + "schain": { + "complete": 0, + "nodes": [ + { + "asi": "pbshostcompany.com", + "sid": "00001", + "rid": "BidRequest", + "hp": 1 + } + ], + "ver": "1.0" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://ib.adnxs.com/openrtb2", + "body": { + "id": "test-request-id", + "app": { + "ext": { + "prebid": { + "source": "source", + "version": "version" + } + } + }, + "ext": { + "appnexus": { + "hb_source": 5 + }, + "schain": { + "complete": 0, + "nodes": [ + { + "asi": "pbshostcompany.com", + "sid": "00001", + "rid": "BidRequest", + "hp": 1 + } + ], + "ver": "1.0" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ], + "w": 300, + "pos": 1, + "h": 250 + }, + "displaymanagerver": "source-version", + "ext": { + "appnexus": { + "placement_id": 1 + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "appnexus.com" + ], + "iurl": "http://nym1-ib.adnxs.com/cr?id=29681110", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": { + "appnexus": { + "brand_id": 1, + "brand_category_id": 1, + "auction_id": 8189378542222915032, + "bid_ad_type": 0, + "bidder_id": 2, + "ranking_price": 0.000000, + "deal_priority": 5 + } + } + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": [ + "appnexus.com" + ], + "iurl": "http://nym1-ib.adnxs.com/cr?id=29681110", + "cid": "958", + "crid": "29681110", + "w": 300, + "h": 250, + "cat": [ + "IAB20-3" + ], + "ext": { + "appnexus": { + "brand_id": 1, + "brand_category_id": 1, + "auction_id": 8189378542222915032, + "bid_ad_type": 0, + "bidder_id": 2, + "ranking_price": 0.000000, + "deal_priority": 5 + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/appnexus/appnexustest/exemplary/schain-25-other-ext.json b/adapters/appnexus/appnexustest/exemplary/schain-25-other-ext.json new file mode 100644 index 00000000000..19b9f1db6c4 --- /dev/null +++ b/adapters/appnexus/appnexustest/exemplary/schain-25-other-ext.json @@ -0,0 +1,203 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "ext": { + "prebid": { + "source": "source", + "version": "version" + } + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placement_id": 1, + "position": "above" + } + } + } + ], + "source": { + "ext": { + "schain": { + "complete": 0, + "nodes": [ + { + "asi": "pbshostcompany.com", + "sid": "00001", + "rid": "BidRequest", + "hp": 1 + } + ], + "ver": "1.0" + }, + "otherSource": "value" + } + }, + "ext": { + "otherRequest": "value" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://ib.adnxs.com/openrtb2", + "body": { + "id": "test-request-id", + "app": { + "ext": { + "prebid": { + "source": "source", + "version": "version" + } + } + }, + "ext": { + "appnexus": { + "hb_source": 5 + }, + "schain": { + "complete": 0, + "nodes": [ + { + "asi": "pbshostcompany.com", + "sid": "00001", + "rid": "BidRequest", + "hp": 1 + } + ], + "ver": "1.0" + }, + "otherRequest": "value" + }, + "source": { + "ext": { + "otherSource": "value" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ], + "w": 300, + "pos": 1, + "h": 250 + }, + "displaymanagerver": "source-version", + "ext": { + "appnexus": { + "placement_id": 1 + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "appnexus.com" + ], + "iurl": "http://nym1-ib.adnxs.com/cr?id=29681110", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": { + "appnexus": { + "brand_id": 1, + "brand_category_id": 1, + "auction_id": 8189378542222915032, + "bid_ad_type": 0, + "bidder_id": 2, + "ranking_price": 0.000000, + "deal_priority": 5 + } + } + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": [ + "appnexus.com" + ], + "iurl": "http://nym1-ib.adnxs.com/cr?id=29681110", + "cid": "958", + "crid": "29681110", + "w": 300, + "h": 250, + "cat": [ + "IAB20-3" + ], + "ext": { + "appnexus": { + "brand_id": 1, + "brand_category_id": 1, + "auction_id": 8189378542222915032, + "bid_ad_type": 0, + "bidder_id": 2, + "ranking_price": 0.000000, + "deal_priority": 5 + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/appnexus/appnexustest/exemplary/schain-25.json b/adapters/appnexus/appnexustest/exemplary/schain-25.json new file mode 100644 index 00000000000..8ff11b0122c --- /dev/null +++ b/adapters/appnexus/appnexustest/exemplary/schain-25.json @@ -0,0 +1,194 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "ext": { + "prebid": { + "source": "source", + "version": "version" + } + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placement_id": 1, + "position": "above" + } + } + } + ], + "source": { + "ext": { + "schain": { + "complete": 0, + "nodes": [ + { + "asi": "pbshostcompany.com", + "sid": "00001", + "rid": "BidRequest", + "hp": 1 + } + ], + "ver": "1.0" + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://ib.adnxs.com/openrtb2", + "body": { + "id": "test-request-id", + "app": { + "ext": { + "prebid": { + "source": "source", + "version": "version" + } + } + }, + "ext": { + "appnexus": { + "hb_source": 5 + }, + "schain": { + "complete": 0, + "nodes": [ + { + "asi": "pbshostcompany.com", + "sid": "00001", + "rid": "BidRequest", + "hp": 1 + } + ], + "ver": "1.0" + } + }, + "source": {}, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ], + "w": 300, + "pos": 1, + "h": 250 + }, + "displaymanagerver": "source-version", + "ext": { + "appnexus": { + "placement_id": 1 + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "appnexus.com" + ], + "iurl": "http://nym1-ib.adnxs.com/cr?id=29681110", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": { + "appnexus": { + "brand_id": 1, + "brand_category_id": 1, + "auction_id": 8189378542222915032, + "bid_ad_type": 0, + "bidder_id": 2, + "ranking_price": 0.000000, + "deal_priority": 5 + } + } + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": [ + "appnexus.com" + ], + "iurl": "http://nym1-ib.adnxs.com/cr?id=29681110", + "cid": "958", + "crid": "29681110", + "w": 300, + "h": 250, + "cat": [ + "IAB20-3" + ], + "ext": { + "appnexus": { + "brand_id": 1, + "brand_category_id": 1, + "auction_id": 8189378542222915032, + "bid_ad_type": 0, + "bidder_id": 2, + "ranking_price": 0.000000, + "deal_priority": 5 + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/appnexus/appnexustest/exemplary/simple-banner-foreign-currency.json b/adapters/appnexus/appnexustest/exemplary/simple-banner-foreign-currency.json index b46c6f5f76f..52112419a8d 100644 --- a/adapters/appnexus/appnexustest/exemplary/simple-banner-foreign-currency.json +++ b/adapters/appnexus/appnexustest/exemplary/simple-banner-foreign-currency.json @@ -34,8 +34,7 @@ "ext": { "appnexus": { "hb_source": 5 - }, - "prebid": {} + } }, "imp": [ { diff --git a/adapters/appnexus/appnexustest/exemplary/simple-banner.json b/adapters/appnexus/appnexustest/exemplary/simple-banner.json index ec769abdbf5..24deea82428 100644 --- a/adapters/appnexus/appnexustest/exemplary/simple-banner.json +++ b/adapters/appnexus/appnexustest/exemplary/simple-banner.json @@ -51,8 +51,7 @@ "ext": { "appnexus": { "hb_source": 5 - }, - "prebid": {} + } }, "imp": [ { diff --git a/adapters/appnexus/appnexustest/exemplary/simple-video.json b/adapters/appnexus/appnexustest/exemplary/simple-video.json index a127e2a0fb1..beb630104ca 100644 --- a/adapters/appnexus/appnexustest/exemplary/simple-video.json +++ b/adapters/appnexus/appnexustest/exemplary/simple-video.json @@ -30,8 +30,7 @@ "ext": { "appnexus": { "hb_source": 5 - }, - "prebid": {} + } }, "imp": [ { diff --git a/adapters/appnexus/appnexustest/exemplary/string-keywords-params.json b/adapters/appnexus/appnexustest/exemplary/string-keywords-params.json index f43c47fe8b4..a6d8d95eb5c 100644 --- a/adapters/appnexus/appnexustest/exemplary/string-keywords-params.json +++ b/adapters/appnexus/appnexustest/exemplary/string-keywords-params.json @@ -41,8 +41,7 @@ "ext": { "appnexus": { "hb_source": 5 - }, - "prebid": {} + } }, "imp": [ { diff --git a/adapters/appnexus/appnexustest/exemplary/video-invalid-category.json b/adapters/appnexus/appnexustest/exemplary/video-invalid-category.json index 257905c873f..a65595e1bc0 100644 --- a/adapters/appnexus/appnexustest/exemplary/video-invalid-category.json +++ b/adapters/appnexus/appnexustest/exemplary/video-invalid-category.json @@ -30,8 +30,7 @@ "ext": { "appnexus": { "hb_source": 5 - }, - "prebid": {} + } }, "imp": [ { diff --git a/adapters/appnexus/appnexustest/supplemental/displaymanager-test.json b/adapters/appnexus/appnexustest/supplemental/displaymanager-test.json index c6ad330e3a8..ebfa1f239fe 100644 --- a/adapters/appnexus/appnexustest/supplemental/displaymanager-test.json +++ b/adapters/appnexus/appnexustest/supplemental/displaymanager-test.json @@ -50,8 +50,7 @@ "ext": { "appnexus": { "hb_source": 5 - }, - "prebid": {} + } }, "imp": [ { diff --git a/adapters/appnexus/appnexustest/supplemental/explicit-dimensions.json b/adapters/appnexus/appnexustest/supplemental/explicit-dimensions.json index 685a908b4f7..c66f897349f 100644 --- a/adapters/appnexus/appnexustest/supplemental/explicit-dimensions.json +++ b/adapters/appnexus/appnexustest/supplemental/explicit-dimensions.json @@ -31,8 +31,7 @@ "ext": { "appnexus": { "hb_source": 5 - }, - "prebid": {} + } }, "imp": [ { diff --git a/adapters/appnexus/appnexustest/supplemental/invalid-bid-type.json b/adapters/appnexus/appnexustest/supplemental/invalid-bid-type.json index 6c7f16338f8..a66f69e358e 100644 --- a/adapters/appnexus/appnexustest/supplemental/invalid-bid-type.json +++ b/adapters/appnexus/appnexustest/supplemental/invalid-bid-type.json @@ -51,8 +51,7 @@ "ext": { "appnexus": { "hb_source": 5 - }, - "prebid": {} + } }, "imp": [ { diff --git a/adapters/appnexus/appnexustest/supplemental/legacy-params.json b/adapters/appnexus/appnexustest/supplemental/legacy-params.json index 82031145b7a..15a4c54587a 100644 --- a/adapters/appnexus/appnexustest/supplemental/legacy-params.json +++ b/adapters/appnexus/appnexustest/supplemental/legacy-params.json @@ -37,8 +37,7 @@ "ext": { "appnexus": { "hb_source": 5 - }, - "prebid": {} + } }, "imp": [ { diff --git a/adapters/appnexus/appnexustest/supplemental/multi-bid.json b/adapters/appnexus/appnexustest/supplemental/multi-bid.json index 9e63bdced95..664244a9850 100644 --- a/adapters/appnexus/appnexustest/supplemental/multi-bid.json +++ b/adapters/appnexus/appnexustest/supplemental/multi-bid.json @@ -34,8 +34,7 @@ "ext": { "appnexus": { "hb_source": 5 - }, - "prebid": {} + } }, "imp": [ { diff --git a/adapters/appnexus/appnexustest/supplemental/placement-id-as-string-test.json b/adapters/appnexus/appnexustest/supplemental/placement-id-as-string-test.json index 1d28983ba7c..b1e0401ecfc 100644 --- a/adapters/appnexus/appnexustest/supplemental/placement-id-as-string-test.json +++ b/adapters/appnexus/appnexustest/supplemental/placement-id-as-string-test.json @@ -51,8 +51,7 @@ "ext": { "appnexus": { "hb_source": 5 - }, - "prebid": {} + } }, "site": { "domain": "prebid.org", diff --git a/adapters/appnexus/appnexustest/supplemental/request-ext-appnexus-existing.json b/adapters/appnexus/appnexustest/supplemental/request-ext-appnexus-existing.json new file mode 100644 index 00000000000..0f153117550 --- /dev/null +++ b/adapters/appnexus/appnexustest/supplemental/request-ext-appnexus-existing.json @@ -0,0 +1,171 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "ext": { + "prebid": { + "source": "source", + "version": "version" + } + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placement_id": 1, + "position": "above" + } + } + } + ], + "ext": { + "appnexus": { + "adpod_id": "42" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://ib.adnxs.com/openrtb2", + "body": { + "id": "test-request-id", + "app": { + "ext": { + "prebid": { + "source": "source", + "version": "version" + } + } + }, + "ext": { + "appnexus": { + "hb_source": 5, + "adpod_id": "42" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ], + "w": 300, + "pos": 1, + "h": 250 + }, + "displaymanagerver": "source-version", + "ext": { + "appnexus": { + "placement_id": 1 + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "appnexus.com" + ], + "iurl": "http://nym1-ib.adnxs.com/cr?id=29681110", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": { + "appnexus": { + "brand_id": 1, + "brand_category_id": 1, + "auction_id": 8189378542222915032, + "bid_ad_type": 0, + "bidder_id": 2, + "ranking_price": 0.000000, + "deal_priority": 5 + } + } + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": [ + "appnexus.com" + ], + "iurl": "http://nym1-ib.adnxs.com/cr?id=29681110", + "cid": "958", + "crid": "29681110", + "w": 300, + "h": 250, + "cat": [ + "IAB20-3" + ], + "ext": { + "appnexus": { + "brand_id": 1, + "brand_category_id": 1, + "auction_id": 8189378542222915032, + "bid_ad_type": 0, + "bidder_id": 2, + "ranking_price": 0.000000, + "deal_priority": 5 + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/appnexus/appnexustest/supplemental/reserve-ignored.json b/adapters/appnexus/appnexustest/supplemental/reserve-ignored.json index 84e2b48484e..e9df5038c1d 100644 --- a/adapters/appnexus/appnexustest/supplemental/reserve-ignored.json +++ b/adapters/appnexus/appnexustest/supplemental/reserve-ignored.json @@ -36,8 +36,7 @@ "ext": { "appnexus": { "hb_source": 5 - }, - "prebid": {} + } }, "imp": [ { diff --git a/adapters/appnexus/appnexustest/supplemental/reserve-test.json b/adapters/appnexus/appnexustest/supplemental/reserve-test.json index f5c6dfceb4f..df861897d74 100644 --- a/adapters/appnexus/appnexustest/supplemental/reserve-test.json +++ b/adapters/appnexus/appnexustest/supplemental/reserve-test.json @@ -35,8 +35,7 @@ "ext": { "appnexus": { "hb_source": 5 - }, - "prebid": {} + } }, "imp": [ { diff --git a/adapters/appnexus/appnexustest/supplemental/status-400.json b/adapters/appnexus/appnexustest/supplemental/status-400.json index dc88901231a..58c7a465219 100644 --- a/adapters/appnexus/appnexustest/supplemental/status-400.json +++ b/adapters/appnexus/appnexustest/supplemental/status-400.json @@ -35,8 +35,7 @@ "ext": { "appnexus": { "hb_source": 5 - }, - "prebid": {} + } }, "imp": [ { diff --git a/adapters/appnexus/appnexustest/supplemental/usePmtRule-test.json b/adapters/appnexus/appnexustest/supplemental/usePmtRule-test.json index 64e519273ab..2d3f307a5a8 100644 --- a/adapters/appnexus/appnexustest/supplemental/usePmtRule-test.json +++ b/adapters/appnexus/appnexustest/supplemental/usePmtRule-test.json @@ -63,8 +63,7 @@ "ext": { "appnexus": { "hb_source": 5 - }, - "prebid": {} + } }, "imp": [ { diff --git a/adapters/appnexus/appnexustest/video/video-brand-category.json b/adapters/appnexus/appnexustest/video/video-brand-category.json new file mode 100644 index 00000000000..1671b97171d --- /dev/null +++ b/adapters/appnexus/appnexustest/video/video-brand-category.json @@ -0,0 +1,179 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "placement_id": 1 + } + } + } + ], + "ext": { + "prebid": { + "targeting": { + "includebrandcategory": { + "primaryadserver": 1, + "publisher": "anyPublisher", + "withcategory": true + } + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://ib.adnxs.com/openrtb2", + "body": { + "id": "test-request-id", + "ext": { + "appnexus": { + "hb_source": 6, + "brand_category_uniqueness": true, + "include_brand_category": true + }, + "prebid": { + "targeting": { + "includebrandcategory": { + "primaryadserver": 1, + "publisher": "anyPublisher", + "withcategory": true + } + } + } + }, + "imp": [ + { + "id": "test-imp-id", + "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": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "appnexus.com" + ], + "iurl": "http://nym1-ib.adnxs.com/cr?id=29681110", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "cat": [ + "IAB9-1" + ], + "ext": { + "appnexus": { + "brand_id": 9, + "brand_category_id": 9, + "auction_id": 8189378542222915032, + "bid_ad_type": 1, + "bidder_id": 2, + "ranking_price": 0.000000, + "deal_priority": 5 + } + } + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": [ + "appnexus.com" + ], + "iurl": "http://nym1-ib.adnxs.com/cr?id=29681110", + "cid": "958", + "crid": "29681110", + "w": 300, + "h": 250, + "cat": [ + "IAB5-1" + ], + "ext": { + "appnexus": { + "brand_id": 9, + "brand_category_id": 9, + "auction_id": 8189378542222915032, + "bid_ad_type": 1, + "bidder_id": 2, + "ranking_price": 0.000000, + "deal_priority": 5 + } + } + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/appnexus/appnexustest/video/video-no-adpodid-two-imps-different-pod.json b/adapters/appnexus/appnexustest/video/video-no-adpodid-two-imps-different-pod.json index ef1368abeed..811cfcb2866 100644 --- a/adapters/appnexus/appnexustest/video/video-no-adpodid-two-imps-different-pod.json +++ b/adapters/appnexus/appnexustest/video/video-no-adpodid-two-imps-different-pod.json @@ -46,8 +46,7 @@ "ext": { "appnexus": { "hb_source": 6 - }, - "prebid": {} + } }, "imp": [ { diff --git a/adapters/appnexus/appnexustest/video/video-same-adpodid-two-imps-same-pod.json b/adapters/appnexus/appnexustest/video/video-same-adpodid-two-imps-same-pod.json index efaf95ed2b4..8f0f15262c4 100644 --- a/adapters/appnexus/appnexustest/video/video-same-adpodid-two-imps-same-pod.json +++ b/adapters/appnexus/appnexustest/video/video-same-adpodid-two-imps-same-pod.json @@ -49,8 +49,7 @@ "appnexus": { "adpod_id": "10", "hb_source": 6 - }, - "prebid": {} + } }, "imp": [ { diff --git a/adapters/appnexus/models.go b/adapters/appnexus/models.go index 826451b45e8..c70f89faa6c 100644 --- a/adapters/appnexus/models.go +++ b/adapters/appnexus/models.go @@ -2,8 +2,6 @@ package appnexus import ( "encoding/json" - - "github.com/prebid/prebid-server/openrtb_ext" ) type impExtAppnexus struct { @@ -13,7 +11,7 @@ type impExtAppnexus struct { UsePmtRule *bool `json:"use_pmt_rule,omitempty"` PrivateSizes json.RawMessage `json:"private_sizes,omitempty"` ExtInvCode string `json:"ext_inv_code,omitempty"` - ExternalImpId string `json:"external_imp_id,omitempty"` + ExternalImpID string `json:"external_imp_id,omitempty"` } type impExt struct { @@ -45,11 +43,5 @@ type bidReqExtAppnexus struct { BrandCategoryUniqueness *bool `json:"brand_category_uniqueness,omitempty"` IsAMP int `json:"is_amp,omitempty"` HeaderBiddingSource int `json:"hb_source,omitempty"` - AdPodId string `json:"adpod_id,omitempty"` -} - -// Full request extension including appnexus extension object -type bidReqExt struct { - openrtb_ext.ExtRequest - Appnexus *bidReqExtAppnexus `json:"appnexus,omitempty"` + AdPodID string `json:"adpod_id,omitempty"` } From ef678c1109f4c3c84e9f2eff41039a56ea7f1a89 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Wed, 2 Aug 2023 11:20:04 +0530 Subject: [PATCH 057/268] minor refactor in HoldAuction (#2995) authored by @onkarvhanumante --- exchange/exchange.go | 12 ++++-------- exchange/exchange_test.go | 16 ++++------------ 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/exchange/exchange.go b/exchange/exchange.go index 7ad15200682..70d92c08fba 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -490,17 +490,14 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog e.bidValidationEnforcement.SetBannerCreativeMaxSize(r.Account.Validations) // Build the response - bidResponse, err := e.buildBidResponse(ctx, liveAdapters, adapterBids, r.BidRequestWrapper.BidRequest, adapterExtra, auc, bidResponseExt, cacheInstructions.returnCreative, r.ImpExtInfoMap, r.PubID, errs) - + bidResponse := e.buildBidResponse(ctx, liveAdapters, adapterBids, r.BidRequestWrapper.BidRequest, adapterExtra, auc, bidResponseExt, cacheInstructions.returnCreative, r.ImpExtInfoMap, r.PubID, errs) bidResponse = adservertargeting.Apply(r.BidRequestWrapper, r.ResolvedBidRequest, bidResponse, r.QueryParams, bidResponseExt, r.Account.TruncateTargetAttribute) bidResponse.Ext, err = encodeBidResponseExt(bidResponseExt) - - bidResponseExt = setSeatNonBid(bidResponseExt, seatNonBids) - if err != nil { return nil, err } + bidResponseExt = setSeatNonBid(bidResponseExt, seatNonBids) return &AuctionResponse{ BidResponse: bidResponse, @@ -880,9 +877,8 @@ func errsToBidderWarnings(errs []error) []openrtb_ext.ExtBidderMessage { } // This piece takes all the bids supplied by the adapters and crafts an openRTB response to send back to the requester -func (e *exchange) buildBidResponse(ctx context.Context, liveAdapters []openrtb_ext.BidderName, adapterSeatBids map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid, bidRequest *openrtb2.BidRequest, adapterExtra map[openrtb_ext.BidderName]*seatResponseExtra, auc *auction, bidResponseExt *openrtb_ext.ExtBidResponse, returnCreative bool, impExtInfoMap map[string]ImpExtInfo, pubID string, errList []error) (*openrtb2.BidResponse, error) { +func (e *exchange) buildBidResponse(ctx context.Context, liveAdapters []openrtb_ext.BidderName, adapterSeatBids map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid, bidRequest *openrtb2.BidRequest, adapterExtra map[openrtb_ext.BidderName]*seatResponseExtra, auc *auction, bidResponseExt *openrtb_ext.ExtBidResponse, returnCreative bool, impExtInfoMap map[string]ImpExtInfo, pubID string, errList []error) *openrtb2.BidResponse { bidResponse := new(openrtb2.BidResponse) - var err error bidResponse.ID = bidRequest.ID if len(liveAdapters) == 0 { @@ -903,7 +899,7 @@ func (e *exchange) buildBidResponse(ctx context.Context, liveAdapters []openrtb_ } bidResponse.SeatBid = seatBids - return bidResponse, err + return bidResponse } func encodeBidResponseExt(bidResponseExt *openrtb_ext.ExtBidResponse) ([]byte, error) { diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go index 8e7ba80b953..52813897142 100644 --- a/exchange/exchange_test.go +++ b/exchange/exchange_test.go @@ -167,12 +167,9 @@ func TestCharacterEscape(t *testing.T) { var errList []error // 4) Build bid response - bidResp, err := e.buildBidResponse(context.Background(), liveAdapters, adapterBids, bidRequest, adapterExtra, nil, nil, true, nil, "", errList) + bidResp := e.buildBidResponse(context.Background(), liveAdapters, adapterBids, bidRequest, adapterExtra, nil, nil, true, nil, "", errList) // 5) Assert we have no errors and one '&' character as we are supposed to - if err != nil { - t.Errorf("exchange.buildBidResponse returned unexpected error: %v", err) - } if len(errList) > 0 { t.Errorf("exchange.buildBidResponse returned %d errors", len(errList)) } @@ -1533,10 +1530,7 @@ func TestGetBidCacheInfoEndToEnd(t *testing.T) { var errList []error // 4) Build bid response - bid_resp, err := e.buildBidResponse(context.Background(), liveAdapters, adapterBids, bidRequest, adapterExtra, auc, nil, true, nil, "", errList) - - // 5) Assert we have no errors and the bid response we expected - assert.NoError(t, err, "[TestGetBidCacheInfo] buildBidResponse() threw an error") + bid_resp := e.buildBidResponse(context.Background(), liveAdapters, adapterBids, bidRequest, adapterExtra, auc, nil, true, nil, "", errList) expectedBidResponse := &openrtb2.BidResponse{ SeatBid: []openrtb2.SeatBid{ @@ -1909,8 +1903,7 @@ func TestBidResponseCurrency(t *testing.T) { } // Run tests for i := range testCases { - actualBidResp, err := e.buildBidResponse(context.Background(), liveAdapters, testCases[i].adapterBids, bidRequest, adapterExtra, nil, bidResponseExt, true, nil, "", errList) - assert.NoError(t, err, fmt.Sprintf("[TEST_FAILED] e.buildBidResponse resturns error in test: %s Error message: %s \n", testCases[i].description, err)) + actualBidResp := e.buildBidResponse(context.Background(), liveAdapters, testCases[i].adapterBids, bidRequest, adapterExtra, nil, bidResponseExt, true, nil, "", errList) assert.Equalf(t, testCases[i].expectedBidResponse, actualBidResp, fmt.Sprintf("[TEST_FAILED] Objects must be equal for test: %s \n Expected: >>%s<< \n Actual: >>%s<< ", testCases[i].description, testCases[i].expectedBidResponse.Ext, actualBidResp.Ext)) } } @@ -1976,8 +1969,7 @@ func TestBidResponseImpExtInfo(t *testing.T) { expectedBidResponseExt := `{"origbidcpm":0,"prebid":{"type":"video","passthrough":{"imp_passthrough_val":1}},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]}}` - actualBidResp, err := e.buildBidResponse(context.Background(), liveAdapters, adapterBids, bidRequest, nil, nil, nil, true, impExtInfo, "", errList) - assert.NoError(t, err, fmt.Sprintf("imp ext info was not passed through correctly: %s", err)) + actualBidResp := e.buildBidResponse(context.Background(), liveAdapters, adapterBids, bidRequest, nil, nil, nil, true, impExtInfo, "", errList) resBidExt := string(actualBidResp.SeatBid[0].Bid[0].Ext) assert.Equalf(t, expectedBidResponseExt, resBidExt, "Expected bid response extension is incorrect") From 77ca553feae2dacce125e0b4692ba19c34da6a50 Mon Sep 17 00:00:00 2001 From: Marcin Muras <47107445+mmuras@users.noreply.github.com> Date: Wed, 2 Aug 2023 15:24:37 +0200 Subject: [PATCH 058/268] AdOcean: Use partially dynamic hostnames instead of fully dynamic. (#2910) --- adapters/adocean/adocean.go | 22 +++++--- adapters/adocean/adocean_test.go | 2 +- .../exemplary/multi-banner-impression.json | 6 +- .../exemplary/single-banner-impression.json | 4 +- .../adocean/adoceantest/supplemental/app.json | 4 +- .../supplemental/bad-response.json | 4 +- .../supplemental/emiter-param-error.json | 55 +++++++++++++++++++ .../supplemental/encode-error.json | 4 +- .../supplemental/network-error.json | 4 +- .../adoceantest/supplemental/no-bid.json | 10 ++-- .../adoceantest/supplemental/no-sizes.json | 10 ++-- .../supplemental/requests-merge.json | 10 ++-- adapters/adocean/params_test.go | 15 +++-- openrtb_ext/imp_adocean.go | 2 +- static/bidder-info/adocean.yaml | 2 +- static/bidder-params/adocean.json | 12 +++- 16 files changed, 119 insertions(+), 47 deletions(-) create mode 100644 adapters/adocean/adoceantest/supplemental/emiter-param-error.json diff --git a/adapters/adocean/adocean.go b/adapters/adocean/adocean.go index ce0f78e8f00..a4e6223be6d 100644 --- a/adapters/adocean/adocean.go +++ b/adapters/adocean/adocean.go @@ -21,7 +21,7 @@ import ( "github.com/prebid/prebid-server/openrtb_ext" ) -const adapterVersion = "1.2.0" +const adapterVersion = "1.3.0" const maxUriLength = 8000 const measurementCode = ` ", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + } + ], + "seat": "silverpush" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "bids": [ + {"bid": { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + }, + "type":"banner" + } + ], + "cur": "USD" + + } + ] + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/exemplary/banner-device-ctv-.json b/adapters/silverpush/silverpushtest/exemplary/banner-device-ctv-.json new file mode 100644 index 00000000000..037b844c519 --- /dev/null +++ b/adapters/silverpush/silverpushtest/exemplary/banner-device-ctv-.json @@ -0,0 +1,257 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.05, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + + }, + "device": { + "devicetype": 3, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (X11; smarttv Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "http://localhost:8080/bidder/?identifier=5krH8Q", + "body": { + + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.05, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 3, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Linux", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (X11; smarttv Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36", + "w": 1080 + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + } + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + + }, + "body": { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "seatbid": [ + { + "bid": [ + { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + } + ], + "seat": "silverpush" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "bids": [ + {"bid": { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + }, + "type":"banner" + } + ], + "cur": "USD" + + } + ] + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/exemplary/banner-device-site.json b/adapters/silverpush/silverpushtest/exemplary/banner-device-site.json new file mode 100644 index 00000000000..f12af4b3738 --- /dev/null +++ b/adapters/silverpush/silverpushtest/exemplary/banner-device-site.json @@ -0,0 +1,257 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + + }, + "device": { + "devicetype": 2, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "http://localhost:8080/bidder/?identifier=5krH8Q", + "body": { + + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.05, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 2, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Linux", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36", + "w": 1080 + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + } + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + + }, + "body": { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "seatbid": [ + { + "bid": [ + { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + } + ], + "seat": "silverpush" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "bids": [ + {"bid": { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + }, + "type":"banner" + } + ], + "cur": "USD" + + } + ] + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/exemplary/banner-eids.json b/adapters/silverpush/silverpushtest/exemplary/banner-eids.json new file mode 100644 index 00000000000..62273801292 --- /dev/null +++ b/adapters/silverpush/silverpushtest/exemplary/banner-eids.json @@ -0,0 +1,285 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + + }, + "device": { + "devicetype": 2, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "macOS", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC", + "ext": { + "data": { + "eids": [{ + "source":"pubcid.org", + "uids":[ + { + "id":"01EAJWWNEPN3CYMM5N8M5VXY22", + "atype":1 + } + ] + }] + } + + } + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "http://localhost:8080/bidder/?identifier=5krH8Q", + "body": { + + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.05, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 2, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "macOS", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", + "w": 1080 + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC", + "ext": { + + "eids": [{ + "source":"pubcid.org", + "uids":[ + { + "id":"01EAJWWNEPN3CYMM5N8M5VXY22", + "atype":1 + } + ] + }] + + + } + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + } + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + + }, + "body": { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "seatbid": [ + { + "bid": [ + { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + } + ], + "seat": "silverpush" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "bids": [ + {"bid": { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + }, + "type":"banner" + } + ], + "cur": "USD" + + } + ] + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/exemplary/banner-iOS-ua.json b/adapters/silverpush/silverpushtest/exemplary/banner-iOS-ua.json new file mode 100644 index 00000000000..4a8868ce7fa --- /dev/null +++ b/adapters/silverpush/silverpushtest/exemplary/banner-iOS-ua.json @@ -0,0 +1,257 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (iPhone12,1; U; CPU iPhone OS 13_0 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Mobile/15E148 Safari/602.1", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "http://localhost:8080/bidder/?identifier=5krH8Q", + "body": { + + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.05, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "iOS", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (iPhone12,1; U; CPU iPhone OS 13_0 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Mobile/15E148 Safari/602.1", + "w": 1080 + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + } + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + + }, + "body": { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "seatbid": [ + { + "bid": [ + { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + } + ], + "seat": "silverpush" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "bids": [ + {"bid": { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + }, + "type":"banner" + } + ], + "cur": "USD" + + } + ] + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/exemplary/banner-windows-ua.json b/adapters/silverpush/silverpushtest/exemplary/banner-windows-ua.json new file mode 100644 index 00000000000..7e6eb647c27 --- /dev/null +++ b/adapters/silverpush/silverpushtest/exemplary/banner-windows-ua.json @@ -0,0 +1,257 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1; Microsoft; RM-1152) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Mobile Safari/537.36 Edge/15.15254", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "http://localhost:8080/bidder/?identifier=5krH8Q", + "body": { + + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.05, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Windows", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1; Microsoft; RM-1152) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Mobile Safari/537.36 Edge/15.15254", + "w": 1080 + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + } + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + + }, + "body": { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "seatbid": [ + { + "bid": [ + { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + } + ], + "seat": "silverpush" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "bids": [ + {"bid": { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + }, + "type":"banner" + } + ], + "cur": "USD" + + } + ] + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/exemplary/banner-without-site-publisher.json b/adapters/silverpush/silverpushtest/exemplary/banner-without-site-publisher.json new file mode 100644 index 00000000000..042dd9c5021 --- /dev/null +++ b/adapters/silverpush/silverpushtest/exemplary/banner-without-site-publisher.json @@ -0,0 +1,244 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "site": { + "domain": "stg.betterbutter.in" + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "http://localhost:8080/bidder/?identifier=5krH8Q", + "body": { + + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.05, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + } + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + + }, + "body": { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "seatbid": [ + { + "bid": [ + { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + } + ], + "seat": "silverpush" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "bids": [ + {"bid": { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + }, + "type":"banner" + } + ], + "cur": "USD" + + } + ] + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/exemplary/banner-without-w-h.json b/adapters/silverpush/silverpushtest/exemplary/banner-without-w-h.json new file mode 100644 index 00000000000..a3764658c03 --- /dev/null +++ b/adapters/silverpush/silverpushtest/exemplary/banner-without-w-h.json @@ -0,0 +1,278 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC", + "ext": { + "eids": [ + { + "source": "amxid", + "uids": [ + { + "atype": 1, + "id": "88de601e-3d98-48e7-81d7-00000000" + } + ] + }] + } + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "http://localhost:8080/bidder/?identifier=5krH8Q", + "body": { + + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 290, + "h": 260, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.05, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC", + "ext": { + "eids": [ + { + "source": "amxid", + "uids": [ + { + "atype": 1, + "id": "88de601e-3d98-48e7-81d7-00000000" + } + ] + }] + } + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + } + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "body": { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "seatbid": [ + { + "bid": [ + { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + } + ], + "seat": "silverpush" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "bids": [ + {"bid": { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + }, + "type":"banner" + } + ], + "cur": "USD" + + } + ] + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/exemplary/banner.json b/adapters/silverpush/silverpushtest/exemplary/banner.json new file mode 100644 index 00000000000..8476f805716 --- /dev/null +++ b/adapters/silverpush/silverpushtest/exemplary/banner.json @@ -0,0 +1,257 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + + }, + "device": { + "devicetype": 2, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "macOS", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "http://localhost:8080/bidder/?identifier=5krH8Q", + "body": { + + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.05, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 2, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "macOS", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", + "w": 1080 + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + } + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + + }, + "body": { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "seatbid": [ + { + "bid": [ + { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + } + ], + "seat": "silverpush" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "bids": [ + {"bid": { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + }, + "type":"banner" + } + ], + "cur": "USD" + + } + ] + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/exemplary/banner_without_publisher.json b/adapters/silverpush/silverpushtest/exemplary/banner_without_publisher.json new file mode 100644 index 00000000000..2fd4188f4a5 --- /dev/null +++ b/adapters/silverpush/silverpushtest/exemplary/banner_without_publisher.json @@ -0,0 +1,242 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "http://localhost:8080/bidder/?identifier=5krH8Q", + "body": { + + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.05, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + } + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + + }, + "body": { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "seatbid": [ + { + "bid": [ + { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + } + ], + "seat": "silverpush" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "bids": [ + {"bid": { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + }, + "type":"banner" + } + ], + "cur": "USD" + + } + ] + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/exemplary/video-bidfloor-zero.json b/adapters/silverpush/silverpushtest/exemplary/video-bidfloor-zero.json new file mode 100644 index 00000000000..d9650cd0e8a --- /dev/null +++ b/adapters/silverpush/silverpushtest/exemplary/video-bidfloor-zero.json @@ -0,0 +1,247 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "video": { + "api": [ + 1, + 2, + 4, + 6 + ], + "mimes": [ + "video/mp4" + ], + "protocols": [ + 4, + 5, + 6, + 7 + ], + "linearity": 1, + "placement": 1, + "minduration": 1, + "maxduration": 0, + "startdelay": 0, + "w": 320, + "h": 250 + }, + "tagid": "2612792908", + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123" + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "http://localhost:8080/bidder/?identifier=5krH8Q", + "body": { + + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "video": { + "api": [ + 1, + 2, + 4, + 6 + ], + "mimes": [ + "video/mp4" + ], + "protocols": [ + 4, + 5, + 6, + 7 + ], + "linearity": 1, + "placement": 1, + "minduration": 1, + "maxduration": 120, + "startdelay": 0, + "w": 320, + "h": 250 + }, + "tagid": "2612792908", + "bidfloor": 0.1, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123" + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + } + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "body": { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "seatbid": [ + { + "bid": [ + { + "id": "iJQDNZRA", + "impid": "1", + "price": 0.04, + "burl": "https://localhost:8181/tracker/?p=iEUrKGOlRpwuy6LMCoEc8oew34TcCljlTEjAN1URYhXSxosy0IanKUQw36mX8Igm5v5887kijBb_kwdRT8OIJv1KQWLtEYJFkSJOdZJvSFNF_6Ir6_yaslz3Br4JuIUC9owtY46bQy0ltarrzOf8Xhq5XosFj88AVue5y5aBCxvdNF0nqtk1f_IN5h59yNBlUGTQ6_hAxOO_f27g3t1sjDpoojfZ5gcj2P3K3PN5uVB5IFU-xUV84jil_CYyXLuA1v9kG2DH0Y1ypDZ7LUSSX0rGlH-XUX22hWFue0ENIsvoAqk5FPYXmfmIAWH6JpJ6_mHQdC9IP_gXOiXqXL2HLrFHWeKkXqb7by6UzoptT8Ro60EHzWd5VfmhAUv42UExriCZRW8YRW_LAFCFlauvRcwCL-lv8DsrbUgj1oPbxI_G9Z9q-8o_qqAqU9dwXlRgIboANc69AOX3JGtCKxfxlAEAVjrONzgO9LNyDHbUUv5oT7fv3HEgf6UQcbzbyQ8ISo1rq48ypIA9RWCb9hFmkjxUsIZJc0ScL3QHIdoXxxJ3Q0Zu7MgctSYMoCn77gsNr57HQJLsgXJDi53AgMsxdmHpj64kJTVoemRHpvbPv3REHAGXcAfixF0XQOEj-uDP9SDQ_ZXI-LaFbpdYyX6GWqQtpOnLjK4FIg6nKZD_W7MnLw6TWqh7o3BV-uouOmExvHgU2bbMpAtcDEVYL0rVh1jBIpSLk3UEZuidovj3TlnYVXG07hmJb-jsRzMplAK3UqPTaCa-3RrA8gklQTiampKoryI5G5dijCOTp0kYSWcYh50cqzG9pXqkH-73y3aeYa-RauCIJdFnq-17kfImdVCNSBELe_uW-dTDUUFZ22i8f5C_Ifn9xnGlqMUrq9AEJ2OOmuKgMJ0IuFhTqD18V4HhojWstF-O3B4_UyXte-ZN598PCFXkg_Uc8gsP5yQ3sFLMOWv-HDfuGnLDxDvT8T-yjUjRAem0IlaCsECR3eaAhSrP8yVe7OzFdRDYo-ZnZq_KW97U9aMTy7xUvoRP_fLGpVH0KLxjzEr9dTrQContTAu8knYWE0vcWRJZbPm28mzBVMwtXp8HMEi1-afUhJyhgkvRYRCaKUqyP3n3OAXN-5zggxUtH4tnvpy6Ew1xkBIQ9aFjWwJZRaE7-t1HhVjtXtyyQmPE6U-qax8IWxUqNE5cLi2J2Avjh5S69yfOOXwzWe_HDT7jFeCA8YLsx9G5iUFQpcvbnGlb4RWfTgLzpALlpssAT-sd33_zXXQ0oWvbsgOPibMmt5g7ggbNCy9J9onz2DE_CMjm6SySPS1l0eIpl3vB8dYgNt-e2Wowj7FrATYKLuVa_2VQY9juIOLyGd_VB1rrayJdliWzidzitZXbiqWbl6-XLLh28x7b3OheTRG_SWC3opXSiA2r4aTc3VvqAeMo2XtflWIuLjt7jvgtH_TwqR3oli-9bD1UeTT9AaWJRfS6xmMNlqbHw3fKXwTKGJEMQkyIkiXY4vOcMUYJBfaRkQbKRJ5wRGw3FLhgE56oSAhEPnjPZDx69-toWOziSJGWKR4p4iAaLNh2Xoeyi8Y9yjId7u07OwKNsOUqYo8GaF4hgA6kkrfofB1064vi2-_AUqGch4WFZQ5CyOyT3_FfKXxqR5HrHWXevT8zlXX4dFmiMt3rI5riojhVjMW9XwxUJFkvKW-n0SWPgx7phnT0Rew0WcY-pp86g04AjqxJ-WBXCYpR6z1_No6znnkPm3zaPKLDUgffx7ImRGfNxoIQGUQ5CV9P2v8W2mBaENDjDMuQh09wG0q7y0ttvj9PtqyRtYwB_VhxX5iiFl6d2No5IIJIpUK5QqykI06pWDU_7M4qoIKLwGgc8ICdUqqy3UgZZZxWnyuwuJP0FNgzjKxnZE8PBrtY-m9CSU_UYSuMtUw7cE1XsCvenDrGgj32OLjVoKkp8IrULovZxnSHhV8Cg0Q6mgtDmSuVGc4cqA_nvzK6JwGhAN1Zn2dY3xcdjt5HUqK9SxGMiQUM3yEtX5BsyBqyGmP8m8PBEtscoZpQ-qvDHEUpk7VIuimUhnDlzaFdSzMwMmEBMabHu5tBau5aU4eUmCxCWVrndeKlszgDqbuOgz6sJ5xGoVcmBR2ri80B_d_2ZkOZhq0_X9Dyisyb-ggYNLbUuoFYemVSqJ67pEnVILZRqUrlgWN-xQ6FTshQfLoAWFetUK-89bAAi8Ly76plHomz4NYGqWhfOz9ot09ivybHVY66BtxLYYGwcVeXLB2y3cqQ94Pyo7B-ixe6IQQOvWP0CO6hgkwNqYqThQaU8VEQQR2ehprcE0uE2t4bqLlsuNEZfrqGJx8UNxfoflVZXx2hqdmQN_r0-vQwjAXKvbElOkJZP0Yvs3Vf-Ym0UocU2a51_iQklxvpDqMVW4dmRCbvUcIcKmXX2C8xwqYg5z9SzKzyYqUZjvQZJ0xrF_T-uiQjKQAUxTxWI9K39xV-OL_KlTlR8OqSUrjzQS1mSloLLMFuQvctujaf0cH1a6yqGHUaUkHwTO0UvzIzR_-4LEmiGJSPQP0qDyqjr2RxqbRZRAgnjOMjjo9dZc4mf_2ywdeC2KAS56gtr8hfDI0lp7R6fIVLfrDAL2PzqIERjqoEyP3WAuqjsBiVw-tui3O1Te4tliQ7IhvLjeaG1LvuvbfI1z7A&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "\n\n \n \n DBM\n In-Stream Video\n \n \n\n\n\n \n \n \n \n \n 00:00:15\n \n \n \n \n \n \n \n \n \n \n \n \n \n\n\n\n\n\n\n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n IN\n 4\n 6260\n 0.0400USD\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n 485459443-1\n Yes\n \n \n \n Silverpush-1687361105\n \n\n", + "adomain": [ + "disney.com" + ], + "cid": "sEJAtadBdhxs", + "crid": "485459443", + "w": 360, + "h": 727, + "mtype":2, + "ext": { + "origbidcpm": 0.04, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "video" + }, + "third_party_buyer_token": "AKAmf-CsVHgbcp3N0PM2mbsEk1oxApVbS1Hirp9rrNZ-_AFPCptW6_0kFrISwByjI8QMGTsTLgEB6Wq-fmTmi--xzsoyp4oME_pWeNmkLm0Na81xc7ZVv90IF3Pe1kZszpASOYUkxSXH" + } + } + ], + "seat": "silverpush" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "bids": [ + { + "bid": { + "id": "iJQDNZRA", + "impid": "1", + "price": 0.04, + "burl": "https://localhost:8181/tracker/?p=iEUrKGOlRpwuy6LMCoEc8oew34TcCljlTEjAN1URYhXSxosy0IanKUQw36mX8Igm5v5887kijBb_kwdRT8OIJv1KQWLtEYJFkSJOdZJvSFNF_6Ir6_yaslz3Br4JuIUC9owtY46bQy0ltarrzOf8Xhq5XosFj88AVue5y5aBCxvdNF0nqtk1f_IN5h59yNBlUGTQ6_hAxOO_f27g3t1sjDpoojfZ5gcj2P3K3PN5uVB5IFU-xUV84jil_CYyXLuA1v9kG2DH0Y1ypDZ7LUSSX0rGlH-XUX22hWFue0ENIsvoAqk5FPYXmfmIAWH6JpJ6_mHQdC9IP_gXOiXqXL2HLrFHWeKkXqb7by6UzoptT8Ro60EHzWd5VfmhAUv42UExriCZRW8YRW_LAFCFlauvRcwCL-lv8DsrbUgj1oPbxI_G9Z9q-8o_qqAqU9dwXlRgIboANc69AOX3JGtCKxfxlAEAVjrONzgO9LNyDHbUUv5oT7fv3HEgf6UQcbzbyQ8ISo1rq48ypIA9RWCb9hFmkjxUsIZJc0ScL3QHIdoXxxJ3Q0Zu7MgctSYMoCn77gsNr57HQJLsgXJDi53AgMsxdmHpj64kJTVoemRHpvbPv3REHAGXcAfixF0XQOEj-uDP9SDQ_ZXI-LaFbpdYyX6GWqQtpOnLjK4FIg6nKZD_W7MnLw6TWqh7o3BV-uouOmExvHgU2bbMpAtcDEVYL0rVh1jBIpSLk3UEZuidovj3TlnYVXG07hmJb-jsRzMplAK3UqPTaCa-3RrA8gklQTiampKoryI5G5dijCOTp0kYSWcYh50cqzG9pXqkH-73y3aeYa-RauCIJdFnq-17kfImdVCNSBELe_uW-dTDUUFZ22i8f5C_Ifn9xnGlqMUrq9AEJ2OOmuKgMJ0IuFhTqD18V4HhojWstF-O3B4_UyXte-ZN598PCFXkg_Uc8gsP5yQ3sFLMOWv-HDfuGnLDxDvT8T-yjUjRAem0IlaCsECR3eaAhSrP8yVe7OzFdRDYo-ZnZq_KW97U9aMTy7xUvoRP_fLGpVH0KLxjzEr9dTrQContTAu8knYWE0vcWRJZbPm28mzBVMwtXp8HMEi1-afUhJyhgkvRYRCaKUqyP3n3OAXN-5zggxUtH4tnvpy6Ew1xkBIQ9aFjWwJZRaE7-t1HhVjtXtyyQmPE6U-qax8IWxUqNE5cLi2J2Avjh5S69yfOOXwzWe_HDT7jFeCA8YLsx9G5iUFQpcvbnGlb4RWfTgLzpALlpssAT-sd33_zXXQ0oWvbsgOPibMmt5g7ggbNCy9J9onz2DE_CMjm6SySPS1l0eIpl3vB8dYgNt-e2Wowj7FrATYKLuVa_2VQY9juIOLyGd_VB1rrayJdliWzidzitZXbiqWbl6-XLLh28x7b3OheTRG_SWC3opXSiA2r4aTc3VvqAeMo2XtflWIuLjt7jvgtH_TwqR3oli-9bD1UeTT9AaWJRfS6xmMNlqbHw3fKXwTKGJEMQkyIkiXY4vOcMUYJBfaRkQbKRJ5wRGw3FLhgE56oSAhEPnjPZDx69-toWOziSJGWKR4p4iAaLNh2Xoeyi8Y9yjId7u07OwKNsOUqYo8GaF4hgA6kkrfofB1064vi2-_AUqGch4WFZQ5CyOyT3_FfKXxqR5HrHWXevT8zlXX4dFmiMt3rI5riojhVjMW9XwxUJFkvKW-n0SWPgx7phnT0Rew0WcY-pp86g04AjqxJ-WBXCYpR6z1_No6znnkPm3zaPKLDUgffx7ImRGfNxoIQGUQ5CV9P2v8W2mBaENDjDMuQh09wG0q7y0ttvj9PtqyRtYwB_VhxX5iiFl6d2No5IIJIpUK5QqykI06pWDU_7M4qoIKLwGgc8ICdUqqy3UgZZZxWnyuwuJP0FNgzjKxnZE8PBrtY-m9CSU_UYSuMtUw7cE1XsCvenDrGgj32OLjVoKkp8IrULovZxnSHhV8Cg0Q6mgtDmSuVGc4cqA_nvzK6JwGhAN1Zn2dY3xcdjt5HUqK9SxGMiQUM3yEtX5BsyBqyGmP8m8PBEtscoZpQ-qvDHEUpk7VIuimUhnDlzaFdSzMwMmEBMabHu5tBau5aU4eUmCxCWVrndeKlszgDqbuOgz6sJ5xGoVcmBR2ri80B_d_2ZkOZhq0_X9Dyisyb-ggYNLbUuoFYemVSqJ67pEnVILZRqUrlgWN-xQ6FTshQfLoAWFetUK-89bAAi8Ly76plHomz4NYGqWhfOz9ot09ivybHVY66BtxLYYGwcVeXLB2y3cqQ94Pyo7B-ixe6IQQOvWP0CO6hgkwNqYqThQaU8VEQQR2ehprcE0uE2t4bqLlsuNEZfrqGJx8UNxfoflVZXx2hqdmQN_r0-vQwjAXKvbElOkJZP0Yvs3Vf-Ym0UocU2a51_iQklxvpDqMVW4dmRCbvUcIcKmXX2C8xwqYg5z9SzKzyYqUZjvQZJ0xrF_T-uiQjKQAUxTxWI9K39xV-OL_KlTlR8OqSUrjzQS1mSloLLMFuQvctujaf0cH1a6yqGHUaUkHwTO0UvzIzR_-4LEmiGJSPQP0qDyqjr2RxqbRZRAgnjOMjjo9dZc4mf_2ywdeC2KAS56gtr8hfDI0lp7R6fIVLfrDAL2PzqIERjqoEyP3WAuqjsBiVw-tui3O1Te4tliQ7IhvLjeaG1LvuvbfI1z7A&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "\n\n \n \n DBM\n In-Stream Video\n \n \n\n\n\n \n \n \n \n \n 00:00:15\n \n \n \n \n \n \n \n \n \n \n \n \n \n\n\n\n\n\n\n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n IN\n 4\n 6260\n 0.0400USD\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n 485459443-1\n Yes\n \n \n \n Silverpush-1687361105\n \n\n", + "adomain": [ + "disney.com" + ], + "cid": "sEJAtadBdhxs", + "crid": "485459443", + "w": 360, + "h": 727, + "mtype":2, + "ext": { + "origbidcpm": 0.04, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "video" + }, + "third_party_buyer_token": "AKAmf-CsVHgbcp3N0PM2mbsEk1oxApVbS1Hirp9rrNZ-_AFPCptW6_0kFrISwByjI8QMGTsTLgEB6Wq-fmTmi--xzsoyp4oME_pWeNmkLm0Na81xc7ZVv90IF3Pe1kZszpASOYUkxSXH" + } + }, + "type":"video" + } + ], + "cur": "USD" + + } + ] + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/exemplary/video.json b/adapters/silverpush/silverpushtest/exemplary/video.json new file mode 100644 index 00000000000..2f0dccef05a --- /dev/null +++ b/adapters/silverpush/silverpushtest/exemplary/video.json @@ -0,0 +1,250 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "video": { + "api": [ + 1, + 2, + 4, + 6 + ], + "mimes": [ + "video/mp4" + ], + "protocols": [ + 4, + 5, + 6, + 7 + ], + "linearity": 1, + "placement": 1, + "minduration": 1, + "maxduration": 0, + "startdelay": 0, + "w": 320, + "h": 250 + }, + "tagid": "2612792908", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "http://localhost:8080/bidder/?identifier=5krH8Q", + "body": { + + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "video": { + "api": [ + 1, + 2, + 4, + 6 + ], + "mimes": [ + "video/mp4" + ], + "protocols": [ + 4, + 5, + 6, + 7 + ], + "linearity": 1, + "placement": 1, + "minduration": 1, + "maxduration": 120, + "startdelay": 0, + "w": 320, + "h": 250 + }, + "tagid": "2612792908", + "bidfloor": 0.05, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + } + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "body": { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "seatbid": [ + { + "bid": [ + { + "id": "iJQDNZRA", + "impid": "1", + "price": 0.04, + "burl": "https://localhost:8181/tracker/?p=iEUrKGOlRpwuy6LMCoEc8oew34TcCljlTEjAN1URYhXSxosy0IanKUQw36mX8Igm5v5887kijBb_kwdRT8OIJv1KQWLtEYJFkSJOdZJvSFNF_6Ir6_yaslz3Br4JuIUC9owtY46bQy0ltarrzOf8Xhq5XosFj88AVue5y5aBCxvdNF0nqtk1f_IN5h59yNBlUGTQ6_hAxOO_f27g3t1sjDpoojfZ5gcj2P3K3PN5uVB5IFU-xUV84jil_CYyXLuA1v9kG2DH0Y1ypDZ7LUSSX0rGlH-XUX22hWFue0ENIsvoAqk5FPYXmfmIAWH6JpJ6_mHQdC9IP_gXOiXqXL2HLrFHWeKkXqb7by6UzoptT8Ro60EHzWd5VfmhAUv42UExriCZRW8YRW_LAFCFlauvRcwCL-lv8DsrbUgj1oPbxI_G9Z9q-8o_qqAqU9dwXlRgIboANc69AOX3JGtCKxfxlAEAVjrONzgO9LNyDHbUUv5oT7fv3HEgf6UQcbzbyQ8ISo1rq48ypIA9RWCb9hFmkjxUsIZJc0ScL3QHIdoXxxJ3Q0Zu7MgctSYMoCn77gsNr57HQJLsgXJDi53AgMsxdmHpj64kJTVoemRHpvbPv3REHAGXcAfixF0XQOEj-uDP9SDQ_ZXI-LaFbpdYyX6GWqQtpOnLjK4FIg6nKZD_W7MnLw6TWqh7o3BV-uouOmExvHgU2bbMpAtcDEVYL0rVh1jBIpSLk3UEZuidovj3TlnYVXG07hmJb-jsRzMplAK3UqPTaCa-3RrA8gklQTiampKoryI5G5dijCOTp0kYSWcYh50cqzG9pXqkH-73y3aeYa-RauCIJdFnq-17kfImdVCNSBELe_uW-dTDUUFZ22i8f5C_Ifn9xnGlqMUrq9AEJ2OOmuKgMJ0IuFhTqD18V4HhojWstF-O3B4_UyXte-ZN598PCFXkg_Uc8gsP5yQ3sFLMOWv-HDfuGnLDxDvT8T-yjUjRAem0IlaCsECR3eaAhSrP8yVe7OzFdRDYo-ZnZq_KW97U9aMTy7xUvoRP_fLGpVH0KLxjzEr9dTrQContTAu8knYWE0vcWRJZbPm28mzBVMwtXp8HMEi1-afUhJyhgkvRYRCaKUqyP3n3OAXN-5zggxUtH4tnvpy6Ew1xkBIQ9aFjWwJZRaE7-t1HhVjtXtyyQmPE6U-qax8IWxUqNE5cLi2J2Avjh5S69yfOOXwzWe_HDT7jFeCA8YLsx9G5iUFQpcvbnGlb4RWfTgLzpALlpssAT-sd33_zXXQ0oWvbsgOPibMmt5g7ggbNCy9J9onz2DE_CMjm6SySPS1l0eIpl3vB8dYgNt-e2Wowj7FrATYKLuVa_2VQY9juIOLyGd_VB1rrayJdliWzidzitZXbiqWbl6-XLLh28x7b3OheTRG_SWC3opXSiA2r4aTc3VvqAeMo2XtflWIuLjt7jvgtH_TwqR3oli-9bD1UeTT9AaWJRfS6xmMNlqbHw3fKXwTKGJEMQkyIkiXY4vOcMUYJBfaRkQbKRJ5wRGw3FLhgE56oSAhEPnjPZDx69-toWOziSJGWKR4p4iAaLNh2Xoeyi8Y9yjId7u07OwKNsOUqYo8GaF4hgA6kkrfofB1064vi2-_AUqGch4WFZQ5CyOyT3_FfKXxqR5HrHWXevT8zlXX4dFmiMt3rI5riojhVjMW9XwxUJFkvKW-n0SWPgx7phnT0Rew0WcY-pp86g04AjqxJ-WBXCYpR6z1_No6znnkPm3zaPKLDUgffx7ImRGfNxoIQGUQ5CV9P2v8W2mBaENDjDMuQh09wG0q7y0ttvj9PtqyRtYwB_VhxX5iiFl6d2No5IIJIpUK5QqykI06pWDU_7M4qoIKLwGgc8ICdUqqy3UgZZZxWnyuwuJP0FNgzjKxnZE8PBrtY-m9CSU_UYSuMtUw7cE1XsCvenDrGgj32OLjVoKkp8IrULovZxnSHhV8Cg0Q6mgtDmSuVGc4cqA_nvzK6JwGhAN1Zn2dY3xcdjt5HUqK9SxGMiQUM3yEtX5BsyBqyGmP8m8PBEtscoZpQ-qvDHEUpk7VIuimUhnDlzaFdSzMwMmEBMabHu5tBau5aU4eUmCxCWVrndeKlszgDqbuOgz6sJ5xGoVcmBR2ri80B_d_2ZkOZhq0_X9Dyisyb-ggYNLbUuoFYemVSqJ67pEnVILZRqUrlgWN-xQ6FTshQfLoAWFetUK-89bAAi8Ly76plHomz4NYGqWhfOz9ot09ivybHVY66BtxLYYGwcVeXLB2y3cqQ94Pyo7B-ixe6IQQOvWP0CO6hgkwNqYqThQaU8VEQQR2ehprcE0uE2t4bqLlsuNEZfrqGJx8UNxfoflVZXx2hqdmQN_r0-vQwjAXKvbElOkJZP0Yvs3Vf-Ym0UocU2a51_iQklxvpDqMVW4dmRCbvUcIcKmXX2C8xwqYg5z9SzKzyYqUZjvQZJ0xrF_T-uiQjKQAUxTxWI9K39xV-OL_KlTlR8OqSUrjzQS1mSloLLMFuQvctujaf0cH1a6yqGHUaUkHwTO0UvzIzR_-4LEmiGJSPQP0qDyqjr2RxqbRZRAgnjOMjjo9dZc4mf_2ywdeC2KAS56gtr8hfDI0lp7R6fIVLfrDAL2PzqIERjqoEyP3WAuqjsBiVw-tui3O1Te4tliQ7IhvLjeaG1LvuvbfI1z7A&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "\n\n \n \n DBM\n In-Stream Video\n \n \n\n\n\n \n \n \n \n \n 00:00:15\n \n \n \n \n \n \n \n \n \n \n \n \n \n\n\n\n\n\n\n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n IN\n 4\n 6260\n 0.0400USD\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n 485459443-1\n Yes\n \n \n \n Silverpush-1687361105\n \n\n", + "adomain": [ + "disney.com" + ], + "cid": "sEJAtadBdhxs", + "crid": "485459443", + "w": 360, + "h": 727, + "mtype":2, + "ext": { + "origbidcpm": 0.04, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "video" + }, + "third_party_buyer_token": "AKAmf-CsVHgbcp3N0PM2mbsEk1oxApVbS1Hirp9rrNZ-_AFPCptW6_0kFrISwByjI8QMGTsTLgEB6Wq-fmTmi--xzsoyp4oME_pWeNmkLm0Na81xc7ZVv90IF3Pe1kZszpASOYUkxSXH" + } + } + ], + "seat": "silverpush" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "bids": [ + { + "bid": { + "id": "iJQDNZRA", + "impid": "1", + "price": 0.04, + "burl": "https://localhost:8181/tracker/?p=iEUrKGOlRpwuy6LMCoEc8oew34TcCljlTEjAN1URYhXSxosy0IanKUQw36mX8Igm5v5887kijBb_kwdRT8OIJv1KQWLtEYJFkSJOdZJvSFNF_6Ir6_yaslz3Br4JuIUC9owtY46bQy0ltarrzOf8Xhq5XosFj88AVue5y5aBCxvdNF0nqtk1f_IN5h59yNBlUGTQ6_hAxOO_f27g3t1sjDpoojfZ5gcj2P3K3PN5uVB5IFU-xUV84jil_CYyXLuA1v9kG2DH0Y1ypDZ7LUSSX0rGlH-XUX22hWFue0ENIsvoAqk5FPYXmfmIAWH6JpJ6_mHQdC9IP_gXOiXqXL2HLrFHWeKkXqb7by6UzoptT8Ro60EHzWd5VfmhAUv42UExriCZRW8YRW_LAFCFlauvRcwCL-lv8DsrbUgj1oPbxI_G9Z9q-8o_qqAqU9dwXlRgIboANc69AOX3JGtCKxfxlAEAVjrONzgO9LNyDHbUUv5oT7fv3HEgf6UQcbzbyQ8ISo1rq48ypIA9RWCb9hFmkjxUsIZJc0ScL3QHIdoXxxJ3Q0Zu7MgctSYMoCn77gsNr57HQJLsgXJDi53AgMsxdmHpj64kJTVoemRHpvbPv3REHAGXcAfixF0XQOEj-uDP9SDQ_ZXI-LaFbpdYyX6GWqQtpOnLjK4FIg6nKZD_W7MnLw6TWqh7o3BV-uouOmExvHgU2bbMpAtcDEVYL0rVh1jBIpSLk3UEZuidovj3TlnYVXG07hmJb-jsRzMplAK3UqPTaCa-3RrA8gklQTiampKoryI5G5dijCOTp0kYSWcYh50cqzG9pXqkH-73y3aeYa-RauCIJdFnq-17kfImdVCNSBELe_uW-dTDUUFZ22i8f5C_Ifn9xnGlqMUrq9AEJ2OOmuKgMJ0IuFhTqD18V4HhojWstF-O3B4_UyXte-ZN598PCFXkg_Uc8gsP5yQ3sFLMOWv-HDfuGnLDxDvT8T-yjUjRAem0IlaCsECR3eaAhSrP8yVe7OzFdRDYo-ZnZq_KW97U9aMTy7xUvoRP_fLGpVH0KLxjzEr9dTrQContTAu8knYWE0vcWRJZbPm28mzBVMwtXp8HMEi1-afUhJyhgkvRYRCaKUqyP3n3OAXN-5zggxUtH4tnvpy6Ew1xkBIQ9aFjWwJZRaE7-t1HhVjtXtyyQmPE6U-qax8IWxUqNE5cLi2J2Avjh5S69yfOOXwzWe_HDT7jFeCA8YLsx9G5iUFQpcvbnGlb4RWfTgLzpALlpssAT-sd33_zXXQ0oWvbsgOPibMmt5g7ggbNCy9J9onz2DE_CMjm6SySPS1l0eIpl3vB8dYgNt-e2Wowj7FrATYKLuVa_2VQY9juIOLyGd_VB1rrayJdliWzidzitZXbiqWbl6-XLLh28x7b3OheTRG_SWC3opXSiA2r4aTc3VvqAeMo2XtflWIuLjt7jvgtH_TwqR3oli-9bD1UeTT9AaWJRfS6xmMNlqbHw3fKXwTKGJEMQkyIkiXY4vOcMUYJBfaRkQbKRJ5wRGw3FLhgE56oSAhEPnjPZDx69-toWOziSJGWKR4p4iAaLNh2Xoeyi8Y9yjId7u07OwKNsOUqYo8GaF4hgA6kkrfofB1064vi2-_AUqGch4WFZQ5CyOyT3_FfKXxqR5HrHWXevT8zlXX4dFmiMt3rI5riojhVjMW9XwxUJFkvKW-n0SWPgx7phnT0Rew0WcY-pp86g04AjqxJ-WBXCYpR6z1_No6znnkPm3zaPKLDUgffx7ImRGfNxoIQGUQ5CV9P2v8W2mBaENDjDMuQh09wG0q7y0ttvj9PtqyRtYwB_VhxX5iiFl6d2No5IIJIpUK5QqykI06pWDU_7M4qoIKLwGgc8ICdUqqy3UgZZZxWnyuwuJP0FNgzjKxnZE8PBrtY-m9CSU_UYSuMtUw7cE1XsCvenDrGgj32OLjVoKkp8IrULovZxnSHhV8Cg0Q6mgtDmSuVGc4cqA_nvzK6JwGhAN1Zn2dY3xcdjt5HUqK9SxGMiQUM3yEtX5BsyBqyGmP8m8PBEtscoZpQ-qvDHEUpk7VIuimUhnDlzaFdSzMwMmEBMabHu5tBau5aU4eUmCxCWVrndeKlszgDqbuOgz6sJ5xGoVcmBR2ri80B_d_2ZkOZhq0_X9Dyisyb-ggYNLbUuoFYemVSqJ67pEnVILZRqUrlgWN-xQ6FTshQfLoAWFetUK-89bAAi8Ly76plHomz4NYGqWhfOz9ot09ivybHVY66BtxLYYGwcVeXLB2y3cqQ94Pyo7B-ixe6IQQOvWP0CO6hgkwNqYqThQaU8VEQQR2ehprcE0uE2t4bqLlsuNEZfrqGJx8UNxfoflVZXx2hqdmQN_r0-vQwjAXKvbElOkJZP0Yvs3Vf-Ym0UocU2a51_iQklxvpDqMVW4dmRCbvUcIcKmXX2C8xwqYg5z9SzKzyYqUZjvQZJ0xrF_T-uiQjKQAUxTxWI9K39xV-OL_KlTlR8OqSUrjzQS1mSloLLMFuQvctujaf0cH1a6yqGHUaUkHwTO0UvzIzR_-4LEmiGJSPQP0qDyqjr2RxqbRZRAgnjOMjjo9dZc4mf_2ywdeC2KAS56gtr8hfDI0lp7R6fIVLfrDAL2PzqIERjqoEyP3WAuqjsBiVw-tui3O1Te4tliQ7IhvLjeaG1LvuvbfI1z7A&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "\n\n \n \n DBM\n In-Stream Video\n \n \n\n\n\n \n \n \n \n \n 00:00:15\n \n \n \n \n \n \n \n \n \n \n \n \n \n\n\n\n\n\n\n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n IN\n 4\n 6260\n 0.0400USD\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n 485459443-1\n Yes\n \n \n \n Silverpush-1687361105\n \n\n", + "adomain": [ + "disney.com" + ], + "cid": "sEJAtadBdhxs", + "crid": "485459443", + "w": 360, + "h": 727, + "mtype":2, + "ext": { + "origbidcpm": 0.04, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "video" + }, + "third_party_buyer_token": "AKAmf-CsVHgbcp3N0PM2mbsEk1oxApVbS1Hirp9rrNZ-_AFPCptW6_0kFrISwByjI8QMGTsTLgEB6Wq-fmTmi--xzsoyp4oME_pWeNmkLm0Na81xc7ZVv90IF3Pe1kZszpASOYUkxSXH" + } + }, + "type":"video" + } + ], + "cur": "USD" + + } + ] + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/exemplary/video_min_max_duration.json b/adapters/silverpush/silverpushtest/exemplary/video_min_max_duration.json new file mode 100644 index 00000000000..d0ac6889362 --- /dev/null +++ b/adapters/silverpush/silverpushtest/exemplary/video_min_max_duration.json @@ -0,0 +1,250 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "video": { + "api": [ + 1, + 2, + 4, + 6 + ], + "mimes": [ + "video/mp4" + ], + "protocols": [ + 4, + 5, + 6, + 7 + ], + "linearity": 1, + "placement": 1, + "minduration": 10, + "maxduration": 5, + "startdelay": 0, + "w": 320, + "h": 250 + }, + "tagid": "2612792908", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "http://localhost:8080/bidder/?identifier=5krH8Q", + "body": { + + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "video": { + "api": [ + 1, + 2, + 4, + 6 + ], + "mimes": [ + "video/mp4" + ], + "protocols": [ + 4, + 5, + 6, + 7 + ], + "linearity": 1, + "placement": 1, + + "maxduration": 10, + "startdelay": 0, + "w": 320, + "h": 250 + }, + "tagid": "2612792908", + "bidfloor": 0.05, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + } + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "body": { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "seatbid": [ + { + "bid": [ + { + "id": "iJQDNZRA", + "impid": "1", + "price": 0.04, + "burl": "https://localhost:8181/tracker/?p=iEUrKGOlRpwuy6LMCoEc8oew34TcCljlTEjAN1URYhXSxosy0IanKUQw36mX8Igm5v5887kijBb_kwdRT8OIJv1KQWLtEYJFkSJOdZJvSFNF_6Ir6_yaslz3Br4JuIUC9owtY46bQy0ltarrzOf8Xhq5XosFj88AVue5y5aBCxvdNF0nqtk1f_IN5h59yNBlUGTQ6_hAxOO_f27g3t1sjDpoojfZ5gcj2P3K3PN5uVB5IFU-xUV84jil_CYyXLuA1v9kG2DH0Y1ypDZ7LUSSX0rGlH-XUX22hWFue0ENIsvoAqk5FPYXmfmIAWH6JpJ6_mHQdC9IP_gXOiXqXL2HLrFHWeKkXqb7by6UzoptT8Ro60EHzWd5VfmhAUv42UExriCZRW8YRW_LAFCFlauvRcwCL-lv8DsrbUgj1oPbxI_G9Z9q-8o_qqAqU9dwXlRgIboANc69AOX3JGtCKxfxlAEAVjrONzgO9LNyDHbUUv5oT7fv3HEgf6UQcbzbyQ8ISo1rq48ypIA9RWCb9hFmkjxUsIZJc0ScL3QHIdoXxxJ3Q0Zu7MgctSYMoCn77gsNr57HQJLsgXJDi53AgMsxdmHpj64kJTVoemRHpvbPv3REHAGXcAfixF0XQOEj-uDP9SDQ_ZXI-LaFbpdYyX6GWqQtpOnLjK4FIg6nKZD_W7MnLw6TWqh7o3BV-uouOmExvHgU2bbMpAtcDEVYL0rVh1jBIpSLk3UEZuidovj3TlnYVXG07hmJb-jsRzMplAK3UqPTaCa-3RrA8gklQTiampKoryI5G5dijCOTp0kYSWcYh50cqzG9pXqkH-73y3aeYa-RauCIJdFnq-17kfImdVCNSBELe_uW-dTDUUFZ22i8f5C_Ifn9xnGlqMUrq9AEJ2OOmuKgMJ0IuFhTqD18V4HhojWstF-O3B4_UyXte-ZN598PCFXkg_Uc8gsP5yQ3sFLMOWv-HDfuGnLDxDvT8T-yjUjRAem0IlaCsECR3eaAhSrP8yVe7OzFdRDYo-ZnZq_KW97U9aMTy7xUvoRP_fLGpVH0KLxjzEr9dTrQContTAu8knYWE0vcWRJZbPm28mzBVMwtXp8HMEi1-afUhJyhgkvRYRCaKUqyP3n3OAXN-5zggxUtH4tnvpy6Ew1xkBIQ9aFjWwJZRaE7-t1HhVjtXtyyQmPE6U-qax8IWxUqNE5cLi2J2Avjh5S69yfOOXwzWe_HDT7jFeCA8YLsx9G5iUFQpcvbnGlb4RWfTgLzpALlpssAT-sd33_zXXQ0oWvbsgOPibMmt5g7ggbNCy9J9onz2DE_CMjm6SySPS1l0eIpl3vB8dYgNt-e2Wowj7FrATYKLuVa_2VQY9juIOLyGd_VB1rrayJdliWzidzitZXbiqWbl6-XLLh28x7b3OheTRG_SWC3opXSiA2r4aTc3VvqAeMo2XtflWIuLjt7jvgtH_TwqR3oli-9bD1UeTT9AaWJRfS6xmMNlqbHw3fKXwTKGJEMQkyIkiXY4vOcMUYJBfaRkQbKRJ5wRGw3FLhgE56oSAhEPnjPZDx69-toWOziSJGWKR4p4iAaLNh2Xoeyi8Y9yjId7u07OwKNsOUqYo8GaF4hgA6kkrfofB1064vi2-_AUqGch4WFZQ5CyOyT3_FfKXxqR5HrHWXevT8zlXX4dFmiMt3rI5riojhVjMW9XwxUJFkvKW-n0SWPgx7phnT0Rew0WcY-pp86g04AjqxJ-WBXCYpR6z1_No6znnkPm3zaPKLDUgffx7ImRGfNxoIQGUQ5CV9P2v8W2mBaENDjDMuQh09wG0q7y0ttvj9PtqyRtYwB_VhxX5iiFl6d2No5IIJIpUK5QqykI06pWDU_7M4qoIKLwGgc8ICdUqqy3UgZZZxWnyuwuJP0FNgzjKxnZE8PBrtY-m9CSU_UYSuMtUw7cE1XsCvenDrGgj32OLjVoKkp8IrULovZxnSHhV8Cg0Q6mgtDmSuVGc4cqA_nvzK6JwGhAN1Zn2dY3xcdjt5HUqK9SxGMiQUM3yEtX5BsyBqyGmP8m8PBEtscoZpQ-qvDHEUpk7VIuimUhnDlzaFdSzMwMmEBMabHu5tBau5aU4eUmCxCWVrndeKlszgDqbuOgz6sJ5xGoVcmBR2ri80B_d_2ZkOZhq0_X9Dyisyb-ggYNLbUuoFYemVSqJ67pEnVILZRqUrlgWN-xQ6FTshQfLoAWFetUK-89bAAi8Ly76plHomz4NYGqWhfOz9ot09ivybHVY66BtxLYYGwcVeXLB2y3cqQ94Pyo7B-ixe6IQQOvWP0CO6hgkwNqYqThQaU8VEQQR2ehprcE0uE2t4bqLlsuNEZfrqGJx8UNxfoflVZXx2hqdmQN_r0-vQwjAXKvbElOkJZP0Yvs3Vf-Ym0UocU2a51_iQklxvpDqMVW4dmRCbvUcIcKmXX2C8xwqYg5z9SzKzyYqUZjvQZJ0xrF_T-uiQjKQAUxTxWI9K39xV-OL_KlTlR8OqSUrjzQS1mSloLLMFuQvctujaf0cH1a6yqGHUaUkHwTO0UvzIzR_-4LEmiGJSPQP0qDyqjr2RxqbRZRAgnjOMjjo9dZc4mf_2ywdeC2KAS56gtr8hfDI0lp7R6fIVLfrDAL2PzqIERjqoEyP3WAuqjsBiVw-tui3O1Te4tliQ7IhvLjeaG1LvuvbfI1z7A&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "\n\n \n \n DBM\n In-Stream Video\n \n \n\n\n\n \n \n \n \n \n 00:00:15\n \n \n \n \n \n \n \n \n \n \n \n \n \n\n\n\n\n\n\n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n IN\n 4\n 6260\n 0.0400USD\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n 485459443-1\n Yes\n \n \n \n Silverpush-1687361105\n \n\n", + "adomain": [ + "disney.com" + ], + "cid": "sEJAtadBdhxs", + "crid": "485459443", + "w": 360, + "h": 727, + "mtype":2, + "ext": { + "origbidcpm": 0.04, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "video" + }, + "third_party_buyer_token": "AKAmf-CsVHgbcp3N0PM2mbsEk1oxApVbS1Hirp9rrNZ-_AFPCptW6_0kFrISwByjI8QMGTsTLgEB6Wq-fmTmi--xzsoyp4oME_pWeNmkLm0Na81xc7ZVv90IF3Pe1kZszpASOYUkxSXH" + } + } + ], + "seat": "silverpush" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "bids": [ + { + "bid": { + "id": "iJQDNZRA", + "impid": "1", + "price": 0.04, + "burl": "https://localhost:8181/tracker/?p=iEUrKGOlRpwuy6LMCoEc8oew34TcCljlTEjAN1URYhXSxosy0IanKUQw36mX8Igm5v5887kijBb_kwdRT8OIJv1KQWLtEYJFkSJOdZJvSFNF_6Ir6_yaslz3Br4JuIUC9owtY46bQy0ltarrzOf8Xhq5XosFj88AVue5y5aBCxvdNF0nqtk1f_IN5h59yNBlUGTQ6_hAxOO_f27g3t1sjDpoojfZ5gcj2P3K3PN5uVB5IFU-xUV84jil_CYyXLuA1v9kG2DH0Y1ypDZ7LUSSX0rGlH-XUX22hWFue0ENIsvoAqk5FPYXmfmIAWH6JpJ6_mHQdC9IP_gXOiXqXL2HLrFHWeKkXqb7by6UzoptT8Ro60EHzWd5VfmhAUv42UExriCZRW8YRW_LAFCFlauvRcwCL-lv8DsrbUgj1oPbxI_G9Z9q-8o_qqAqU9dwXlRgIboANc69AOX3JGtCKxfxlAEAVjrONzgO9LNyDHbUUv5oT7fv3HEgf6UQcbzbyQ8ISo1rq48ypIA9RWCb9hFmkjxUsIZJc0ScL3QHIdoXxxJ3Q0Zu7MgctSYMoCn77gsNr57HQJLsgXJDi53AgMsxdmHpj64kJTVoemRHpvbPv3REHAGXcAfixF0XQOEj-uDP9SDQ_ZXI-LaFbpdYyX6GWqQtpOnLjK4FIg6nKZD_W7MnLw6TWqh7o3BV-uouOmExvHgU2bbMpAtcDEVYL0rVh1jBIpSLk3UEZuidovj3TlnYVXG07hmJb-jsRzMplAK3UqPTaCa-3RrA8gklQTiampKoryI5G5dijCOTp0kYSWcYh50cqzG9pXqkH-73y3aeYa-RauCIJdFnq-17kfImdVCNSBELe_uW-dTDUUFZ22i8f5C_Ifn9xnGlqMUrq9AEJ2OOmuKgMJ0IuFhTqD18V4HhojWstF-O3B4_UyXte-ZN598PCFXkg_Uc8gsP5yQ3sFLMOWv-HDfuGnLDxDvT8T-yjUjRAem0IlaCsECR3eaAhSrP8yVe7OzFdRDYo-ZnZq_KW97U9aMTy7xUvoRP_fLGpVH0KLxjzEr9dTrQContTAu8knYWE0vcWRJZbPm28mzBVMwtXp8HMEi1-afUhJyhgkvRYRCaKUqyP3n3OAXN-5zggxUtH4tnvpy6Ew1xkBIQ9aFjWwJZRaE7-t1HhVjtXtyyQmPE6U-qax8IWxUqNE5cLi2J2Avjh5S69yfOOXwzWe_HDT7jFeCA8YLsx9G5iUFQpcvbnGlb4RWfTgLzpALlpssAT-sd33_zXXQ0oWvbsgOPibMmt5g7ggbNCy9J9onz2DE_CMjm6SySPS1l0eIpl3vB8dYgNt-e2Wowj7FrATYKLuVa_2VQY9juIOLyGd_VB1rrayJdliWzidzitZXbiqWbl6-XLLh28x7b3OheTRG_SWC3opXSiA2r4aTc3VvqAeMo2XtflWIuLjt7jvgtH_TwqR3oli-9bD1UeTT9AaWJRfS6xmMNlqbHw3fKXwTKGJEMQkyIkiXY4vOcMUYJBfaRkQbKRJ5wRGw3FLhgE56oSAhEPnjPZDx69-toWOziSJGWKR4p4iAaLNh2Xoeyi8Y9yjId7u07OwKNsOUqYo8GaF4hgA6kkrfofB1064vi2-_AUqGch4WFZQ5CyOyT3_FfKXxqR5HrHWXevT8zlXX4dFmiMt3rI5riojhVjMW9XwxUJFkvKW-n0SWPgx7phnT0Rew0WcY-pp86g04AjqxJ-WBXCYpR6z1_No6znnkPm3zaPKLDUgffx7ImRGfNxoIQGUQ5CV9P2v8W2mBaENDjDMuQh09wG0q7y0ttvj9PtqyRtYwB_VhxX5iiFl6d2No5IIJIpUK5QqykI06pWDU_7M4qoIKLwGgc8ICdUqqy3UgZZZxWnyuwuJP0FNgzjKxnZE8PBrtY-m9CSU_UYSuMtUw7cE1XsCvenDrGgj32OLjVoKkp8IrULovZxnSHhV8Cg0Q6mgtDmSuVGc4cqA_nvzK6JwGhAN1Zn2dY3xcdjt5HUqK9SxGMiQUM3yEtX5BsyBqyGmP8m8PBEtscoZpQ-qvDHEUpk7VIuimUhnDlzaFdSzMwMmEBMabHu5tBau5aU4eUmCxCWVrndeKlszgDqbuOgz6sJ5xGoVcmBR2ri80B_d_2ZkOZhq0_X9Dyisyb-ggYNLbUuoFYemVSqJ67pEnVILZRqUrlgWN-xQ6FTshQfLoAWFetUK-89bAAi8Ly76plHomz4NYGqWhfOz9ot09ivybHVY66BtxLYYGwcVeXLB2y3cqQ94Pyo7B-ixe6IQQOvWP0CO6hgkwNqYqThQaU8VEQQR2ehprcE0uE2t4bqLlsuNEZfrqGJx8UNxfoflVZXx2hqdmQN_r0-vQwjAXKvbElOkJZP0Yvs3Vf-Ym0UocU2a51_iQklxvpDqMVW4dmRCbvUcIcKmXX2C8xwqYg5z9SzKzyYqUZjvQZJ0xrF_T-uiQjKQAUxTxWI9K39xV-OL_KlTlR8OqSUrjzQS1mSloLLMFuQvctujaf0cH1a6yqGHUaUkHwTO0UvzIzR_-4LEmiGJSPQP0qDyqjr2RxqbRZRAgnjOMjjo9dZc4mf_2ywdeC2KAS56gtr8hfDI0lp7R6fIVLfrDAL2PzqIERjqoEyP3WAuqjsBiVw-tui3O1Te4tliQ7IhvLjeaG1LvuvbfI1z7A&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "\n\n \n \n DBM\n In-Stream Video\n \n \n\n\n\n \n \n \n \n \n 00:00:15\n \n \n \n \n \n \n \n \n \n \n \n \n \n\n\n\n\n\n\n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n IN\n 4\n 6260\n 0.0400USD\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n 485459443-1\n Yes\n \n \n \n Silverpush-1687361105\n \n\n", + "adomain": [ + "disney.com" + ], + "cid": "sEJAtadBdhxs", + "crid": "485459443", + "w": 360, + "h": 727, + "mtype":2, + "ext": { + "origbidcpm": 0.04, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "video" + }, + "third_party_buyer_token": "AKAmf-CsVHgbcp3N0PM2mbsEk1oxApVbS1Hirp9rrNZ-_AFPCptW6_0kFrISwByjI8QMGTsTLgEB6Wq-fmTmi--xzsoyp4oME_pWeNmkLm0Na81xc7ZVv90IF3Pe1kZszpASOYUkxSXH" + } + }, + "type":"video" + } + ], + "cur": "USD" + + } + ] + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/supplemental/bad-banner-format.json b/adapters/silverpush/silverpushtest/supplemental/bad-banner-format.json new file mode 100644 index 00000000000..78a7d09dbc9 --- /dev/null +++ b/adapters/silverpush/silverpushtest/supplemental/bad-banner-format.json @@ -0,0 +1,94 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [] + }, + "tagid": "2612792908", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + + }, + "device": { + "devicetype": 3, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC", + "ext": { + "eids": [ + { + "source": "amxid", + "uids": [ + { + "atype": 1, + "id": "88de601e-3d98-48e7-81d7-00000000" + } + ] + }] + } + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "No sizes provided for Banner.", + "comparison": "literal" + } + ] + + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/supplemental/bad-eids-data.json b/adapters/silverpush/silverpushtest/supplemental/bad-eids-data.json new file mode 100644 index 00000000000..d813bdf0bb0 --- /dev/null +++ b/adapters/silverpush/silverpushtest/supplemental/bad-eids-data.json @@ -0,0 +1,87 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + + }, + "device": { + "devicetype": 3, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC", + "ext": {"data":9} + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + + "expectedMakeRequestsErrors": [ + { + "value": "Invalid user.ext.data.", + "comparison": "literal" + } + ] + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/supplemental/bad-eids-value.json b/adapters/silverpush/silverpushtest/supplemental/bad-eids-value.json new file mode 100644 index 00000000000..f91b0fc7cce --- /dev/null +++ b/adapters/silverpush/silverpushtest/supplemental/bad-eids-value.json @@ -0,0 +1,278 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC", + "ext": { + "eids": [ + { + "source": "amxid", + "uids": [ + { + "atype": 1, + "id": "" + } + ] + }] + } + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "http://localhost:8080/bidder/?identifier=5krH8Q", + "body": { + + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 290, + "h": 260, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.05, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC", + "ext": { + "eids": [ + { + "source": "amxid", + "uids": [ + { + "atype": 1, + "id": "" + } + ] + }] + } + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + } + }, + "mockResponse": { + "status": 200, + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "body": { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "seatbid": [ + { + "bid": [ + { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + } + ], + "seat": "silverpush" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "bids": [ + {"bid": { + "id": "TbthOMFy", + "impid": "1", + "price": 0.03, + "burl": "https://localhost:8181/tracker/?p=FAlHYmO6o9Zl4J-A9I0lpSo19KeQaWQU_nIsE-kC1tevBA0xn9BSCf1FxK6f-zkPdD88g5V1wAwJnsj3HFHsQMoWLEv7j-DOqwSR_qtcTs77QhThKsEptZTR1BfmIaiBzNK3PCqdbUzSAdcUv8ftAZkzKBpRcoZuFYUFiSCRq014TN8AOhmgartsPmNuex_hS9Zq4Px-SsZkbGzL9MoBNfygT8v-eIC7lgDdKIlhUfcTOwHqcVx2Ji3vHQieaBDBlw2GTAATu1KEwLfS2hqzh0XQEI-TFBjvrvEypqfjQMdTtUcS1N34Pc7WPPgVbJk4X2p8DeoTBpKpCQJHRvveYUvC46WySfNha1lv_MB0Mf1hadYrDDqt3hjZa0o-7wRZsjGutVf2bM-I4LUSSNMCTNJF48ooJ_cZMd6Z0GWWQGZpM5yG5qUBJKtvN4ZbHTNftqyspsy_XyMD9c2Bl4QZA3Hn-McV0mQ_eelyCg-2vtLCDEOq4BsqhPNHy5jUsIC-kJYSng1LM_sAi6SAVhLWj0cH7hTGqPNhvTevCfd6o-B1v4ynptVnDmmBT7Mz4pDNWSYiJapg9QnBwjmENG1hbTtrxQoSVCXhhWgjsoQOB6XA_RdHmGqqQ4MgSn0pjKi--jnKCloXykuh3CM8a8PGzbNRk8aCHucTA-g12bmM5xsZg08hTW44eB-CJ7DHltjSc8FuDG2866YSXWahG488QWYmS-_AEBMSV2mIk49BWOWSOfjDK0Wo0_k9FqaoPpB-rtdsUMo-0VWLlZInDNJ1-BZgGC0CKx3BgYTonAoKxU5w86OayNr_kOGHzFKMMt2a7d6lTZmPz-x8ndFIYzsrzLMLxvvwLs2FZnHhobmPHgwDCO94QhrHtHC31edqa2T3QnlBnEg2fovlzi44a2vItNIZYYdhxlGKvfW4BwgPVc0BQVxl9voP-p4cytPrstWODIZ_2D6HiU1vdlZyXBFoPaeovOHE5Nvf1n9IQOlDRmp-7tE3Nx6iS_jiqnGZYIFKSwOGL7gUyoeYKZHc7tN_XUg6cxzBTf1ERC7C5StsLs7VCXCqWZg0t-RSeCdQ4zLt2eZEB_60KpW9RtXo5aALR49OsBLrXe2gldLKMwm9Waa6LZC1R5hj8T4gnpvjEC9jLyFEt7TmVRDkXWeXYiKW2cZCpZjPxv8S5cb0FPliR4tT3lkkOoRhlP9yWiVoHp58CGcfNonBvvwG9rMUdAqqVJD7Agw-v6jpLl_v3nk5ujdD09YT8Da6peM5m5J3Qmm7eTyUsm8zNroHeDSkcUh6kkpvUbrpvaFNaefIw1e1kzR7ONG9SWmpULSIygX4Ibh6FXRbyXw3Ekx-UQLS2EZ2b-MCuL08lyjGioRnDk8zB5jZo-0DKql93CbtDnjJbV-Q6a3Zy0L3zpyCx4V6mnd5kpe7USU-am-dy0aSAgNWkERkcc-v2l4oNVn9gLG5C5L7CS_xA1gceds34LfKFKFn0PwCZglpDUoOk1PZUWY6dQbTnC3qpK4_quEZxU4gZxoMlzsD1DiyX-RtXfqc-vUeKCVUzfz4IaL4BWizOh5c_YNdUib6d70DXGm_eKIBMVrSFGKuXelo2g6QsfosDV-qxnqhkwaFiAVzGFfrRYj5DYVHJHsr4TJ-7_c-OMX5ncr_3FiFHUk3ZVHVOUxTW3jfgWnnHSoPDmy9M2FAcbFQnbgnp9TB_Zmw7xxZXrzXvZuAbFbDqN34hIhqdz-U8I4KfituMY1HCCpgz7wCh6etG6868-g5wu6BRR7qv4F5ID4TEZzQOKodx-Hy5hJcBPwgphMMt6Ch7q_v4Hur-e-JMoJhjzsatxSc5klv-ZrJF6GkfMchMPwHYtfIyBcEKCQHKZAMsaJN20EhRcmNjMPS1thFqN4TXQSPVD__j4yn_KF175Xz7VAnIzfoFW9NiE9_trtZGPiJ&wn_wp=${AUCTION_PRICE}&wn_aid=${AUCTION_ID}&wn_abi=${AUCTION_BID_ID}&wn_aii=${AUCTION_IMP_ID}&wn_aai=${AUCTION_AD_ID}&wn_asi=${AUCTION_SEAT_ID}", + "adm": "https://adrta.com/i?clid=slp&paid=choc&avid=2008&caid=&plid=cr39487593745jefoijdf&publisherId=17281&siteId=&lineItemId=QKWUYk&kv1=360x640&kv2=&kv3=Uyb8g9qJmfcma4ABC&kv7=159&kv10=Optus&kv4=110.33.122.75&kv11=7360132c-cc30-4334-b3fe-c3ec98e27a0e&kv12=3&kv15=AUS&kv26=Android&kv16=-35.342200&kv17=149.210100&kv18=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv19=9e13d2bf-e968-4065-b4db-852123b627a9&kv25=a.f.fnf.mod.returns.rapper.music.funkin.fire&kv27=Mozilla%2F5.0+%28Linux%3B+Android+11%3B+CPH2209+Build%2FRP1A.200720.011%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F100.0.4896.127+Mobile+Safari%2F537.36&kv24=OTT/CTV", + "adomain": [ + "linio.com.co" + ], + "cid": "FmQOmKiRUsLh", + "crid": "cr39487593745jefoijdf", + "w": 360, + "h": 640, + "mtype":1, + "ext": { + "origbidcpm": 0.03, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "silverpush" + }, + "type": "banner" + } + } + }, + "type":"banner" + } + ], + "cur": "USD" + + } + ] + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/supplemental/bad-imp-ext-bidder.json b/adapters/silverpush/silverpushtest/supplemental/bad-imp-ext-bidder.json new file mode 100644 index 00000000000..5bedcfe34c6 --- /dev/null +++ b/adapters/silverpush/silverpushtest/supplemental/bad-imp-ext-bidder.json @@ -0,0 +1,86 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder":98 + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + + }, + "device": { + "devicetype": 3, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "json: cannot unmarshal number into Go value of type openrtb_ext.ImpExtSilverpush", + "comparison": "literal" + } + ] + + + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/supplemental/bad-imp-ext.json b/adapters/silverpush/silverpushtest/supplemental/bad-imp-ext.json new file mode 100644 index 00000000000..7c5b7af90e2 --- /dev/null +++ b/adapters/silverpush/silverpushtest/supplemental/bad-imp-ext.json @@ -0,0 +1,84 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "secure": 1, + "ext": 98 + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + + }, + "device": { + "devicetype": 3, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "json: cannot unmarshal number into Go value of type adapters.ExtImpBidder", + "comparison": "literal" + } + ] + + + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/supplemental/bad-publisherId.json b/adapters/silverpush/silverpushtest/supplemental/bad-publisherId.json new file mode 100644 index 00000000000..97f292d670c --- /dev/null +++ b/adapters/silverpush/silverpushtest/supplemental/bad-publisherId.json @@ -0,0 +1,82 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 3, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "Missing publisherId parameter.", + "comparison": "literal" + } + ] + + + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/supplemental/bad-response-unmarshal.json b/adapters/silverpush/silverpushtest/supplemental/bad-response-unmarshal.json new file mode 100644 index 00000000000..c48c48f1bf0 --- /dev/null +++ b/adapters/silverpush/silverpushtest/supplemental/bad-response-unmarshal.json @@ -0,0 +1,184 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + + }, + "device": { + "devicetype": 2, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "macOS", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "http://localhost:8080/bidder/?identifier=5krH8Q", + "body": { + + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.05, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 2, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "macOS", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", + "w": 1080 + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + } + }, + "mockResponse": { + "status": 200, + "body": "for unmarshal error" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "comparison": "literal" + } + ] + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/supplemental/bad-user-ext-eids.json b/adapters/silverpush/silverpushtest/supplemental/bad-user-ext-eids.json new file mode 100644 index 00000000000..11922cd54b2 --- /dev/null +++ b/adapters/silverpush/silverpushtest/supplemental/bad-user-ext-eids.json @@ -0,0 +1,87 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + + }, + "device": { + "devicetype": 3, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC", + "ext": 99 + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + + "expectedMakeRequestsErrors": [ + { + "value": "Invalid user.ext.", + "comparison": "literal" + } + ] + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/supplemental/bad-video-format.json b/adapters/silverpush/silverpushtest/supplemental/bad-video-format.json new file mode 100644 index 00000000000..62d330679f2 --- /dev/null +++ b/adapters/silverpush/silverpushtest/supplemental/bad-video-format.json @@ -0,0 +1,81 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "video": { + "api": [ + 1, + 2, + 4, + 6 + ], + + "protocols": [ + 4, + 5, + 6, + 7 + ], + "linearity": 1, + "placement": 1, + "minduration": 0, + "maxduration": 60, + "startdelay": 0, + "w": 320, + "h": 250 + }, + "tagid": "2612792908", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 3, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "Invalid or missing video field(s)", + "comparison": "literal" + } + ] + + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/supplemental/status-204-resp.json b/adapters/silverpush/silverpushtest/supplemental/status-204-resp.json new file mode 100644 index 00000000000..fa95a6af1c7 --- /dev/null +++ b/adapters/silverpush/silverpushtest/supplemental/status-204-resp.json @@ -0,0 +1,188 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "http://localhost:8080/bidder/?identifier=5krH8Q", + "body": { + + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.05, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + } + }, + "mockResponse": { + "status": 204, + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "body": { + + } + } + } + ] + + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/supplemental/status-400-resp.json b/adapters/silverpush/silverpushtest/supplemental/status-400-resp.json new file mode 100644 index 00000000000..1a3c57f6eb4 --- /dev/null +++ b/adapters/silverpush/silverpushtest/supplemental/status-400-resp.json @@ -0,0 +1,194 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "http://localhost:8080/bidder/?identifier=5krH8Q", + "body": { + + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.05, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + } + }, + "mockResponse": { + "status": 400, + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "body": { + + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] + + } \ No newline at end of file diff --git a/adapters/silverpush/silverpushtest/supplemental/status-500-resp.json b/adapters/silverpush/silverpushtest/supplemental/status-500-resp.json new file mode 100644 index 00000000000..86dff666431 --- /dev/null +++ b/adapters/silverpush/silverpushtest/supplemental/status-500-resp.json @@ -0,0 +1,194 @@ +{ + "mockBidRequest":{ + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "http://localhost:8080/bidder/?identifier=5krH8Q", + "body": { + + "id": "X4lwEgAAyXAKlqvGCwa9kg", + "imp": [ + { + "id": "1", + "banner": { + "w": 300, + "h": 50, + "pos": 3, + "mimes": [ + "image/jpeg", + "image/gif" + ], + "expdir": [ + 1, + 2, + 3, + 4 + ], + + "format": [ + { + "w": 290, + "h": 260 + } + ] + }, + "tagid": "2612792908", + "bidfloor": 0.05, + "bidfloorcur": "USD", + "secure": 1, + "ext": { + "bidder": { + "publisherId": "publisher123", + "bidfloor": 0.05 + } + } + } + ], + "app": { + "publisher": { + "id": "publisher123" + } + }, + "device": { + "devicetype": 1, + "dnt": 0, + "h": 2340, + "ifa": "9e13d2bf-e968-4065-b4db-852123b627a9", + "ip": "110.33.122.75", + "js": 1, + "make": "OPPO", + "model": "CPH2209", + "os": "Android", + "osv": "11", + "pxratio": 3, + "ua": "Mozilla/5.0 (Linux; Android 11; CPH2209 Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36", + "w": 1080 + }, + "site": { + "domain": "stg.betterbutter.in", + "publisher": { + "id": "publisher123" + } + }, + "user": { + "id": "Uyb8g9qJmfcma4ABC" + }, + "at": 1, + "tmax": 1300, + "cur": [ + "USD" + ], + "ext": { + "bc": "sp_pb_ortb_1.0.0", + "publisherId": "publisher123" + } + } + }, + "mockResponse": { + "status": 500, + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "body": { + + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] + + } \ No newline at end of file diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 6683f4cd61e..712c23d0786 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -146,6 +146,7 @@ import ( "github.com/prebid/prebid-server/adapters/seedingAlliance" "github.com/prebid/prebid-server/adapters/sharethrough" "github.com/prebid/prebid-server/adapters/silvermob" + "github.com/prebid/prebid-server/adapters/silverpush" "github.com/prebid/prebid-server/adapters/smaato" "github.com/prebid/prebid-server/adapters/smartadserver" "github.com/prebid/prebid-server/adapters/smarthub" @@ -347,6 +348,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderScreencore: screencore.Builder, openrtb_ext.BidderSharethrough: sharethrough.Builder, openrtb_ext.BidderSilverMob: silvermob.Builder, + openrtb_ext.BidderSilverPush: silverpush.Builder, openrtb_ext.BidderSmaato: smaato.Builder, openrtb_ext.BidderSmartAdserver: smartadserver.Builder, openrtb_ext.BidderSmartHub: smarthub.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index ae6dc48e962..5e4b9308ea1 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -242,6 +242,7 @@ const ( BidderScreencore BidderName = "screencore" BidderSharethrough BidderName = "sharethrough" BidderSilverMob BidderName = "silvermob" + BidderSilverPush BidderName = "silverpush" BidderSmaato BidderName = "smaato" BidderSmartAdserver BidderName = "smartadserver" BidderSmartHub BidderName = "smarthub" @@ -448,6 +449,7 @@ func CoreBidderNames() []BidderName { BidderScreencore, BidderSharethrough, BidderSilverMob, + BidderSilverPush, BidderSmaato, BidderSmartAdserver, BidderSmartHub, diff --git a/openrtb_ext/bidders_validate_test.go b/openrtb_ext/bidders_validate_test.go index 87a8c96d6f8..33148d1ed41 100644 --- a/openrtb_ext/bidders_validate_test.go +++ b/openrtb_ext/bidders_validate_test.go @@ -50,7 +50,7 @@ func TestBidderUniquenessGatekeeping(t *testing.T) { // - Exclude duplicates of adapters for the same bidder, as it's unlikely a publisher will use both. var bidders []string for _, bidder := range CoreBidderNames() { - if bidder != BidderTripleliftNative && bidder != BidderAdkernelAdn && bidder != BidderFreewheelSSPOld && bidder != BidderYahooAdvertising { + if bidder != BidderSilverPush && bidder != BidderTripleliftNative && bidder != BidderAdkernelAdn && bidder != BidderFreewheelSSPOld && bidder != BidderYahooAdvertising { bidders = append(bidders, string(bidder)) } } diff --git a/openrtb_ext/imp_silverpush.go b/openrtb_ext/imp_silverpush.go new file mode 100644 index 00000000000..0a043356332 --- /dev/null +++ b/openrtb_ext/imp_silverpush.go @@ -0,0 +1,8 @@ +package openrtb_ext + +// ImpExtSilverpush defines the contract for bidrequest.imp[i].ext.prebid.bidder.silverpush +// PublisherId is mandatory parameters +type ImpExtSilverpush struct { + PublisherId string `json:"publisherId"` + BidFloor float64 `json:"bidfloor"` +} diff --git a/static/bidder-info/silverpush.yaml b/static/bidder-info/silverpush.yaml new file mode 100644 index 00000000000..19da68a2e8c --- /dev/null +++ b/static/bidder-info/silverpush.yaml @@ -0,0 +1,12 @@ +endpoint: "https://prebid.chocolateplatform.co/bidder/?identifier=prebidchoc" +maintainer: + email: "prebid@silverpush.co" +capabilities: + app: + mediaTypes: + - banner + - video + site: + mediaTypes: + - banner + - video \ No newline at end of file diff --git a/static/bidder-params/silverpush.json b/static/bidder-params/silverpush.json new file mode 100644 index 00000000000..36dec33bb92 --- /dev/null +++ b/static/bidder-params/silverpush.json @@ -0,0 +1,19 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Silverpush OpenRTB Bidder Adapter", + "description": "A schema which validates params accepted by the SilverPush adapter", + "type": "object", + + "properties": { + "publisherId": { + "type":"string", + "description": "Publisher id provided by silverpush" + }, + "bidfloor": { + "type":"number", + "description": "Minimum price in USD. bidFloor applies to a specific unit. For example, use the following value to set a $1.50 floor: 1.50." + } + }, + + "required": ["publisherId"] + } \ No newline at end of file From 56de256d2bf6b96ac60caf93ef48273739f672ce Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Tue, 15 Aug 2023 23:15:07 +0530 Subject: [PATCH 078/268] Optionally inherit parent bidder info for alias adapter (#3001) * add test cases for validateAliases function * inherit fields for alias from parent adapter * extract parent bidderInfo into common var * reuse `parentBidderInfo` in unit test * use assertFunc in TestProcessAliasBidderInfo * optionally inherit bidder info for alias adapter Check if bidder info param is defined for alias. If not, then inherit information from the parent bidder * fix nits - rename few vars * add check before validating alias * update aliasInfos initialization * ProcessAliasBidderInfo : update table tests --------- Co-authored-by: Ashish Garg --- config/bidderinfo.go | 66 ++++++--- config/bidderinfo_test.go | 292 +++++++++++++++++--------------------- 2 files changed, 183 insertions(+), 175 deletions(-) diff --git a/config/bidderinfo.go b/config/bidderinfo.go index 028307333fd..fac4b56dbf0 100644 --- a/config/bidderinfo.go +++ b/config/bidderinfo.go @@ -268,7 +268,7 @@ func processBidderInfos(reader InfoReader, normalizeBidderName func(string) (ope } func processBidderAliases(aliasNillableFieldsByBidder map[string]aliasNillableFields, bidderInfos BidderInfos) (BidderInfos, error) { - for bidderName := range aliasNillableFieldsByBidder { + for bidderName, alias := range aliasNillableFieldsByBidder { aliasBidderInfo, ok := bidderInfos[bidderName] if !ok { return nil, fmt.Errorf("bidder info not found for an alias: %s", bidderName) @@ -277,22 +277,54 @@ func processBidderAliases(aliasNillableFieldsByBidder map[string]aliasNillableFi return nil, err } parentBidderInfo := bidderInfos[aliasBidderInfo.AliasOf] - aliasBidderInfo.AppSecret = parentBidderInfo.AppSecret - aliasBidderInfo.Capabilities = parentBidderInfo.Capabilities - aliasBidderInfo.Debug = parentBidderInfo.Debug - aliasBidderInfo.Disabled = parentBidderInfo.Disabled - aliasBidderInfo.Endpoint = parentBidderInfo.Endpoint - aliasBidderInfo.EndpointCompression = parentBidderInfo.EndpointCompression - aliasBidderInfo.Experiment = parentBidderInfo.Experiment - aliasBidderInfo.ExtraAdapterInfo = parentBidderInfo.ExtraAdapterInfo - aliasBidderInfo.GVLVendorID = parentBidderInfo.GVLVendorID - aliasBidderInfo.Maintainer = parentBidderInfo.Maintainer - aliasBidderInfo.ModifyingVastXmlAllowed = parentBidderInfo.ModifyingVastXmlAllowed - aliasBidderInfo.OpenRTB = parentBidderInfo.OpenRTB - aliasBidderInfo.PlatformID = parentBidderInfo.PlatformID - aliasBidderInfo.Syncer = parentBidderInfo.Syncer - aliasBidderInfo.UserSyncURL = parentBidderInfo.UserSyncURL - aliasBidderInfo.XAPI = parentBidderInfo.XAPI + if aliasBidderInfo.AppSecret == "" { + aliasBidderInfo.AppSecret = parentBidderInfo.AppSecret + } + if aliasBidderInfo.Capabilities == nil { + aliasBidderInfo.Capabilities = parentBidderInfo.Capabilities + } + if aliasBidderInfo.Debug == nil { + aliasBidderInfo.Debug = parentBidderInfo.Debug + } + if aliasBidderInfo.Endpoint == "" { + aliasBidderInfo.Endpoint = parentBidderInfo.Endpoint + } + if aliasBidderInfo.EndpointCompression == "" { + aliasBidderInfo.EndpointCompression = parentBidderInfo.EndpointCompression + } + if aliasBidderInfo.ExtraAdapterInfo == "" { + aliasBidderInfo.ExtraAdapterInfo = parentBidderInfo.ExtraAdapterInfo + } + if aliasBidderInfo.GVLVendorID == 0 { + aliasBidderInfo.GVLVendorID = parentBidderInfo.GVLVendorID + } + if aliasBidderInfo.Maintainer == nil { + aliasBidderInfo.Maintainer = parentBidderInfo.Maintainer + } + if aliasBidderInfo.OpenRTB == nil { + aliasBidderInfo.OpenRTB = parentBidderInfo.OpenRTB + } + if aliasBidderInfo.PlatformID == "" { + aliasBidderInfo.PlatformID = parentBidderInfo.PlatformID + } + if aliasBidderInfo.Syncer == nil { + aliasBidderInfo.Syncer = parentBidderInfo.Syncer + } + if aliasBidderInfo.UserSyncURL == "" { + aliasBidderInfo.UserSyncURL = parentBidderInfo.UserSyncURL + } + if alias.Disabled == nil { + aliasBidderInfo.Disabled = parentBidderInfo.Disabled + } + if alias.Experiment == nil { + aliasBidderInfo.Experiment = parentBidderInfo.Experiment + } + if alias.ModifyingVastXmlAllowed == nil { + aliasBidderInfo.ModifyingVastXmlAllowed = parentBidderInfo.ModifyingVastXmlAllowed + } + if alias.XAPI == nil { + aliasBidderInfo.XAPI = parentBidderInfo.XAPI + } bidderInfos[bidderName] = aliasBidderInfo } return bidderInfos, nil diff --git a/config/bidderinfo_test.go b/config/bidderinfo_test.go index 4d7ae8f3450..4f7cc5a6c1d 100644 --- a/config/bidderinfo_test.go +++ b/config/bidderinfo_test.go @@ -273,174 +273,151 @@ func TestProcessBidderInfo(t *testing.T) { } func TestProcessAliasBidderInfo(t *testing.T) { + parentBidderInfo := BidderInfo{ + AppSecret: "app-secret", + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative}, + }, + Site: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative}, + }, + }, + Debug: &DebugInfo{ + Allow: true, + }, + Disabled: false, + Endpoint: "https://endpoint.com", + EndpointCompression: "GZIP", + Experiment: BidderInfoExperiment{ + AdsCert: BidderAdsCert{ + Enabled: true, + }, + }, + ExtraAdapterInfo: "extra-info", + GVLVendorID: 42, + Maintainer: &MaintainerInfo{ + Email: "some-email@domain.com", + }, + ModifyingVastXmlAllowed: true, + OpenRTB: &OpenRTBInfo{ + GPPSupported: true, + Version: "2.6", + }, + PlatformID: "123", + Syncer: &Syncer{ + Key: "foo", + IFrame: &SyncerEndpoint{ + URL: "https://foo.com/sync?mode=iframe&r={{.RedirectURL}}", + RedirectURL: "https://redirect/setuid/iframe", + ExternalURL: "https://iframe.host", + UserMacro: "UID", + }, + }, + UserSyncURL: "user-url", + XAPI: AdapterXAPI{ + Username: "uname", + Password: "pwd", + Tracker: "tracker", + }, + } + aliasBidderInfo := BidderInfo{ + AppSecret: "alias-app-secret", + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}, + }, + Site: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}, + }, + }, + Debug: &DebugInfo{ + Allow: false, + }, + Disabled: true, + Endpoint: "https://alias-endpoint.com", + EndpointCompression: "DEFAULT", + Experiment: BidderInfoExperiment{ + AdsCert: BidderAdsCert{ + Enabled: false, + }, + }, + ExtraAdapterInfo: "alias-extra-info", + GVLVendorID: 43, + Maintainer: &MaintainerInfo{ + Email: "alias-email@domain.com", + }, + ModifyingVastXmlAllowed: false, + OpenRTB: &OpenRTBInfo{ + GPPSupported: false, + Version: "2.5", + }, + PlatformID: "456", + Syncer: &Syncer{ + Key: "alias", + IFrame: &SyncerEndpoint{ + URL: "https://alias.com/sync?mode=iframe&r={{.RedirectURL}}", + RedirectURL: "https://alias-redirect/setuid/iframe", + ExternalURL: "https://alias-iframe.host", + UserMacro: "alias-UID", + }, + }, + UserSyncURL: "alias-user-url", + XAPI: AdapterXAPI{ + Username: "alias-uname", + Password: "alias-pwd", + Tracker: "alias-tracker", + }, + } + bidderB := parentBidderInfo + bidderB.AliasOf = "bidderA" testCases := []struct { description string - aliasFields map[string]aliasNillableFields + aliasInfos map[string]aliasNillableFields bidderInfos BidderInfos expectedBidderInfos BidderInfos - expectError string + expectedErr error }{ { - description: "valid alias - replace alias with parent info", - aliasFields: map[string]aliasNillableFields{ - "bidderB": {}, + description: "inherit all parent info in alias bidder", + aliasInfos: map[string]aliasNillableFields{ + "bidderB": { + Disabled: nil, + ModifyingVastXmlAllowed: nil, + Experiment: nil, + XAPI: nil, + }, }, bidderInfos: BidderInfos{ - "bidderA": BidderInfo{ - AppSecret: "app-secret", - Capabilities: &CapabilitiesInfo{ - App: &PlatformInfo{ - MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative}, - }, - Site: &PlatformInfo{ - MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative}, - }, - }, - Debug: &DebugInfo{ - Allow: true, - }, - Disabled: false, - Endpoint: "https://endpoint.com", - EndpointCompression: "GZIP", - Experiment: BidderInfoExperiment{ - AdsCert: BidderAdsCert{ - Enabled: true, - }, - }, - ExtraAdapterInfo: "extra-info", - GVLVendorID: 42, - Maintainer: &MaintainerInfo{ - Email: "some-email@domain.com", - }, - ModifyingVastXmlAllowed: true, - OpenRTB: &OpenRTBInfo{ - GPPSupported: true, - Version: "2.6", - }, - PlatformID: "123", - Syncer: &Syncer{ - Key: "foo", - IFrame: &SyncerEndpoint{ - URL: "https://foo.com/sync?mode=iframe&r={{.RedirectURL}}", - RedirectURL: "https://redirect/setuid/iframe", - ExternalURL: "https://iframe.host", - UserMacro: "UID", - }, - }, - UserSyncURL: "user-url", - XAPI: AdapterXAPI{ - Username: "uname", - Password: "pwd", - Tracker: "tracker", - }, - }, + "bidderA": parentBidderInfo, "bidderB": BidderInfo{ AliasOf: "bidderA", + // all other fields should be inherited from parent bidder }, }, - expectedBidderInfos: BidderInfos{ - "bidderA": BidderInfo{ - AppSecret: "app-secret", - Capabilities: &CapabilitiesInfo{ - App: &PlatformInfo{ - MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative}, - }, - Site: &PlatformInfo{ - MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative}, - }, - }, - Debug: &DebugInfo{ - Allow: true, - }, - Disabled: false, - Endpoint: "https://endpoint.com", - EndpointCompression: "GZIP", - Experiment: BidderInfoExperiment{ - AdsCert: BidderAdsCert{ - Enabled: true, - }, - }, - ExtraAdapterInfo: "extra-info", - GVLVendorID: 42, - Maintainer: &MaintainerInfo{ - Email: "some-email@domain.com", - }, - ModifyingVastXmlAllowed: true, - OpenRTB: &OpenRTBInfo{ - GPPSupported: true, - Version: "2.6", - }, - PlatformID: "123", - Syncer: &Syncer{ - Key: "foo", - IFrame: &SyncerEndpoint{ - URL: "https://foo.com/sync?mode=iframe&r={{.RedirectURL}}", - RedirectURL: "https://redirect/setuid/iframe", - ExternalURL: "https://iframe.host", - UserMacro: "UID", - }, - }, - UserSyncURL: "user-url", - XAPI: AdapterXAPI{ - Username: "uname", - Password: "pwd", - Tracker: "tracker", - }, - }, - "bidderB": BidderInfo{ - AliasOf: "bidderA", - AppSecret: "app-secret", - Capabilities: &CapabilitiesInfo{ - App: &PlatformInfo{ - MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative}, - }, - Site: &PlatformInfo{ - MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative}, - }, - }, - Debug: &DebugInfo{ - Allow: true, - }, - Disabled: false, - Endpoint: "https://endpoint.com", - EndpointCompression: "GZIP", - Experiment: BidderInfoExperiment{ - AdsCert: BidderAdsCert{ - Enabled: true, - }, - }, - ExtraAdapterInfo: "extra-info", - GVLVendorID: 42, - Maintainer: &MaintainerInfo{ - Email: "some-email@domain.com", - }, - ModifyingVastXmlAllowed: true, - OpenRTB: &OpenRTBInfo{ - GPPSupported: true, - Version: "2.6", - }, - PlatformID: "123", - Syncer: &Syncer{ - Key: "foo", - IFrame: &SyncerEndpoint{ - URL: "https://foo.com/sync?mode=iframe&r={{.RedirectURL}}", - RedirectURL: "https://redirect/setuid/iframe", - ExternalURL: "https://iframe.host", - UserMacro: "UID", - }, - }, - UserSyncURL: "user-url", - XAPI: AdapterXAPI{ - Username: "uname", - Password: "pwd", - Tracker: "tracker", - }, + expectedErr: nil, + expectedBidderInfos: BidderInfos{"bidderA": parentBidderInfo, "bidderB": bidderB}, + }, + { + description: "all bidder info specified for alias, do not inherit from parent bidder", + aliasInfos: map[string]aliasNillableFields{ + "bidderB": { + Disabled: &aliasBidderInfo.Disabled, + ModifyingVastXmlAllowed: &aliasBidderInfo.ModifyingVastXmlAllowed, + Experiment: &aliasBidderInfo.Experiment, + XAPI: &aliasBidderInfo.XAPI, }, }, + bidderInfos: BidderInfos{ + "bidderA": parentBidderInfo, + "bidderB": aliasBidderInfo, + }, + expectedErr: nil, + expectedBidderInfos: BidderInfos{"bidderA": parentBidderInfo, "bidderB": aliasBidderInfo}, }, { description: "invalid alias", - aliasFields: map[string]aliasNillableFields{ + aliasInfos: map[string]aliasNillableFields{ "bidderB": {}, }, bidderInfos: BidderInfos{ @@ -448,25 +425,24 @@ func TestProcessAliasBidderInfo(t *testing.T) { AliasOf: "bidderA", }, }, - expectError: "bidderA not found for an alias: bidderB", + expectedErr: errors.New("bidder: bidderA not found for an alias: bidderB"), }, { description: "bidder info not found for an alias", - aliasFields: map[string]aliasNillableFields{ + aliasInfos: map[string]aliasNillableFields{ "bidderB": {}, }, - expectError: "bidder info not found for an alias: bidderB", + expectedErr: errors.New("bidder info not found for an alias: bidderB"), }, } for _, test := range testCases { - bidderInfos, err := processBidderAliases(test.aliasFields, test.bidderInfos) - if test.expectError != "" { - assert.ErrorContains(t, err, test.expectError) + bidderInfos, err := processBidderAliases(test.aliasInfos, test.bidderInfos) + if test.expectedErr != nil { + assert.Equal(t, test.expectedErr, err) } else { assert.Equal(t, test.expectedBidderInfos, bidderInfos) } - } } From 4d9715d4489b5c3f94c6791bd3a4c3b7c192ae27 Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Wed, 16 Aug 2023 16:33:34 +0400 Subject: [PATCH 079/268] Evtech: Add user sync endpoint (#3033) --- static/bidder-info/evtech.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/static/bidder-info/evtech.yaml b/static/bidder-info/evtech.yaml index 4cc75cd3da6..4277a5c46c8 100644 --- a/static/bidder-info/evtech.yaml +++ b/static/bidder-info/evtech.yaml @@ -14,3 +14,10 @@ capabilities: - video - audio - native +userSync: + iframe: + url: https://tracker.direct.e-volution.ai/sync.html?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}} + userMacro: "{PLL_USER_ID}" + redirect: + url: https://tracker.direct.e-volution.ai/sync?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}} + userMacro: "{PLL_USER_ID}" From cb65b4bf93d468c931a00f5330378f69f8163a1e Mon Sep 17 00:00:00 2001 From: Ashish Garg Date: Mon, 21 Aug 2023 11:29:30 +0530 Subject: [PATCH 080/268] Adapter aliases - change coreBidderNames to return aliases (#3027) --- config/bidderinfo.go | 2 + config/bidderinfo_test.go | 1 + openrtb_ext/bidders.go | 425 ++++++++++++++------------- openrtb_ext/bidders_test.go | 6 + openrtb_ext/bidders_validate_test.go | 3 + 5 files changed, 233 insertions(+), 204 deletions(-) diff --git a/config/bidderinfo.go b/config/bidderinfo.go index fac4b56dbf0..c0d89841671 100644 --- a/config/bidderinfo.go +++ b/config/bidderinfo.go @@ -276,6 +276,8 @@ func processBidderAliases(aliasNillableFieldsByBidder map[string]aliasNillableFi if err := validateAliases(aliasBidderInfo, bidderInfos, bidderName); err != nil { return nil, err } + //required for CoreBidderNames function to also return aliasBiddernames + openrtb_ext.SetAliasBidderName(openrtb_ext.BidderName(string(bidderName))) parentBidderInfo := bidderInfos[aliasBidderInfo.AliasOf] if aliasBidderInfo.AppSecret == "" { aliasBidderInfo.AppSecret = parentBidderInfo.AppSecret diff --git a/config/bidderinfo_test.go b/config/bidderinfo_test.go index 4f7cc5a6c1d..60221da2f6f 100644 --- a/config/bidderinfo_test.go +++ b/config/bidderinfo_test.go @@ -442,6 +442,7 @@ func TestProcessAliasBidderInfo(t *testing.T) { assert.Equal(t, test.expectedErr, err) } else { assert.Equal(t, test.expectedBidderInfos, bidderInfos) + assert.Contains(t, openrtb_ext.CoreBidderNames(), openrtb_ext.BidderName("bidderB")) } } } diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 5e4b9308ea1..a9b1a8886c2 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -15,6 +15,226 @@ import ( // BidderName refers to a core bidder id or an alias id. type BidderName string +var aliasBidderNames []BidderName + +var coreBidderNames []BidderName = []BidderName{ + Bidder33Across, + BidderAax, + BidderAceex, + BidderAcuityAds, + BidderAdf, + BidderAdform, + BidderAdgeneration, + BidderAdhese, + BidderAdkernel, + BidderAdkernelAdn, + BidderAdman, + BidderAdmixer, + BidderAdnuntius, + BidderAdOcean, + BidderAdoppler, + BidderAdot, + BidderAdpone, + BidderAdprime, + BidderAdrino, + BidderAdsinteractive, + BidderAdsyield, + BidderAdtarget, + BidderAdtrgtme, + BidderAdtelligent, + BidderAdvangelists, + BidderAdView, + BidderAdxcg, + BidderAdyoulike, + BidderAidem, + BidderAJA, + BidderAlgorix, + BidderAMX, + BidderApacdex, + BidderApplogy, + BidderAppnexus, + BidderAppush, + BidderAudienceNetwork, + BidderAutomatad, + BidderAvocet, + BidderAxis, + BidderAxonix, + BidderBeachfront, + BidderBeintoo, + BidderBetween, + BidderBeyondMedia, + BidderBidmachine, + BidderBidmyadz, + BidderBidsCube, + BidderBidstack, + BidderBizzclick, + BidderBliink, + BidderBlue, + BidderBluesea, + BidderBmtm, + BidderBoldwin, + BidderBrave, + BidderCadentApertureMX, + BidderCcx, + BidderCoinzilla, + BidderColossus, + BidderCompass, + BidderConnectAd, + BidderConsumable, + BidderConversant, + BidderCopper6, + BidderCpmstar, + BidderCriteo, + BidderCWire, + BidderDatablocks, + BidderDecenterAds, + BidderDeepintent, + BidderDefinemedia, + BidderDianomi, + BidderDmx, + BidderEmtv, + BidderEmxDigital, + BidderEngageBDR, + BidderEPlanning, + BidderEpom, + BidderEpsilon, + BidderEVolution, + BidderEvtech, + BidderFlipp, + BidderFreewheelSSP, + BidderFreewheelSSPOld, + BidderFRVRAdNetwork, + BidderGamma, + BidderGamoshi, + BidderGlobalsun, + BidderGothamads, + BidderGrid, + BidderGumGum, + BidderHuaweiAds, + BidderIionads, + BidderImds, + BidderImpactify, + BidderImprovedigital, + BidderInfyTV, + BidderInMobi, + BidderInteractiveoffers, + BidderInvibes, + BidderIQZone, + BidderIx, + BidderJANet, + BidderJixie, + BidderKargo, + BidderKayzen, + BidderKidoz, + BidderKiviads, + BidderLmKiviads, + BidderKrushmedia, + BidderKubient, + BidderLiftoff, + BidderLimelightDigital, + BidderLockerDome, + BidderLogan, + BidderLogicad, + BidderLunaMedia, + BidderMadvertise, + BidderMarsmedia, + BidderMediafuse, + BidderMedianet, + BidderMgid, + BidderMgidX, + BidderMobfoxpb, + BidderMobileFuse, + BidderMotorik, + BidderNanoInteractive, + BidderNextMillennium, + BidderNinthDecimal, + BidderNoBid, + BidderOneTag, + BidderOpenWeb, + BidderOpenx, + BidderOperaads, + BidderOrbidder, + BidderOutbrain, + BidderOwnAdx, + BidderPangle, + BidderPGAM, + BidderPubmatic, + BidderPubnative, + BidderPulsepoint, + BidderPWBid, + BidderQuantumdex, + BidderRevcontent, + BidderRhythmone, + BidderRichaudience, + BidderRise, + BidderRTBHouse, + BidderRubicon, + BidderSeedingAlliance, + BidderSaLunaMedia, + BidderScreencore, + BidderSharethrough, + BidderSilverMob, + BidderSilverPush, + BidderSmaato, + BidderSmartAdserver, + BidderSmartHub, + BidderSmartRTB, + BidderSmartyAds, + BidderSmileWanted, + BidderSonobi, + BidderSovrn, + BidderSspBC, + BidderStreamkey, + BidderStroeerCore, + BidderSuntContent, + BidderSynacormedia, + BidderTaboola, + BidderTappx, + BidderTelaria, + BidderTpmn, + BidderTrafficGate, + BidderTriplelift, + BidderTripleliftNative, + BidderTrustX, + BidderUcfunnel, + BidderUndertone, + BidderUnicorn, + BidderUnruly, + BidderValueImpression, + BidderVideoByte, + BidderVideoHeroes, + BidderVidoomy, + BidderViewdeos, + BidderVisibleMeasures, + BidderVisx, + BidderVox, + BidderVrtcal, + BidderXeworks, + BidderXtrmqb, + BidderYahooAds, + BidderYahooAdvertising, + BidderYahooSSP, + BidderYeahmobi, + BidderYieldlab, + BidderYieldmo, + BidderYieldone, + BidderZeroClickFraud, + BidderZetaGlobalSsp, +} + +func SetAliasBidderName(name BidderName) { + aliasBidderNames = append(aliasBidderNames, name) + coreBidderNames = append(coreBidderNames, name) +} + +func GetAliasBidderNamesSet() map[BidderName]struct{} { + set := map[BidderName]struct{}{} + for _, name := range aliasBidderNames { + set[name] = struct{}{} + } + return set +} + func (name BidderName) MarshalJSON() ([]byte, error) { return []byte(name), nil } @@ -292,210 +512,7 @@ const ( // CoreBidderNames returns a slice of all core bidders. func CoreBidderNames() []BidderName { - return []BidderName{ - Bidder33Across, - BidderAax, - BidderAceex, - BidderAcuityAds, - BidderAdf, - BidderAdform, - BidderAdgeneration, - BidderAdhese, - BidderAdkernel, - BidderAdkernelAdn, - BidderAdman, - BidderAdmixer, - BidderAdnuntius, - BidderAdOcean, - BidderAdoppler, - BidderAdot, - BidderAdpone, - BidderAdprime, - BidderAdrino, - BidderAdsinteractive, - BidderAdsyield, - BidderAdtarget, - BidderAdtrgtme, - BidderAdtelligent, - BidderAdvangelists, - BidderAdView, - BidderAdxcg, - BidderAdyoulike, - BidderAidem, - BidderAJA, - BidderAlgorix, - BidderAMX, - BidderApacdex, - BidderApplogy, - BidderAppnexus, - BidderAppush, - BidderAudienceNetwork, - BidderAutomatad, - BidderAvocet, - BidderAxis, - BidderAxonix, - BidderBeachfront, - BidderBeintoo, - BidderBetween, - BidderBeyondMedia, - BidderBidmachine, - BidderBidmyadz, - BidderBidsCube, - BidderBidstack, - BidderBizzclick, - BidderBliink, - BidderBlue, - BidderBluesea, - BidderBmtm, - BidderBoldwin, - BidderBrave, - BidderCadentApertureMX, - BidderCcx, - BidderCoinzilla, - BidderColossus, - BidderCompass, - BidderConnectAd, - BidderConsumable, - BidderConversant, - BidderCopper6, - BidderCpmstar, - BidderCriteo, - BidderCWire, - BidderDatablocks, - BidderDecenterAds, - BidderDeepintent, - BidderDefinemedia, - BidderDianomi, - BidderDmx, - BidderEmtv, - BidderEmxDigital, - BidderEngageBDR, - BidderEPlanning, - BidderEpom, - BidderEpsilon, - BidderEVolution, - BidderEvtech, - BidderFlipp, - BidderFreewheelSSP, - BidderFreewheelSSPOld, - BidderFRVRAdNetwork, - BidderGamma, - BidderGamoshi, - BidderGlobalsun, - BidderGothamads, - BidderGrid, - BidderGumGum, - BidderHuaweiAds, - BidderIionads, - BidderImds, - BidderImpactify, - BidderImprovedigital, - BidderInfyTV, - BidderInMobi, - BidderInteractiveoffers, - BidderInvibes, - BidderIQZone, - BidderIx, - BidderJANet, - BidderJixie, - BidderKargo, - BidderKayzen, - BidderKidoz, - BidderKiviads, - BidderLmKiviads, - BidderKrushmedia, - BidderKubient, - BidderLiftoff, - BidderLimelightDigital, - BidderLockerDome, - BidderLogan, - BidderLogicad, - BidderLunaMedia, - BidderMadvertise, - BidderMarsmedia, - BidderMediafuse, - BidderMedianet, - BidderMgid, - BidderMgidX, - BidderMobfoxpb, - BidderMobileFuse, - BidderMotorik, - BidderNanoInteractive, - BidderNextMillennium, - BidderNinthDecimal, - BidderNoBid, - BidderOneTag, - BidderOpenWeb, - BidderOpenx, - BidderOperaads, - BidderOrbidder, - BidderOutbrain, - BidderOwnAdx, - BidderPangle, - BidderPGAM, - BidderPubmatic, - BidderPubnative, - BidderPulsepoint, - BidderPWBid, - BidderQuantumdex, - BidderRevcontent, - BidderRhythmone, - BidderRichaudience, - BidderRise, - BidderRTBHouse, - BidderRubicon, - BidderSeedingAlliance, - BidderSaLunaMedia, - BidderScreencore, - BidderSharethrough, - BidderSilverMob, - BidderSilverPush, - BidderSmaato, - BidderSmartAdserver, - BidderSmartHub, - BidderSmartRTB, - BidderSmartyAds, - BidderSmileWanted, - BidderSonobi, - BidderSovrn, - BidderSspBC, - BidderStreamkey, - BidderStroeerCore, - BidderSuntContent, - BidderSynacormedia, - BidderTaboola, - BidderTappx, - BidderTelaria, - BidderTpmn, - BidderTrafficGate, - BidderTriplelift, - BidderTripleliftNative, - BidderTrustX, - BidderUcfunnel, - BidderUndertone, - BidderUnicorn, - BidderUnruly, - BidderValueImpression, - BidderVideoByte, - BidderVideoHeroes, - BidderVidoomy, - BidderViewdeos, - BidderVisibleMeasures, - BidderVisx, - BidderVox, - BidderVrtcal, - BidderXeworks, - BidderXtrmqb, - BidderYahooAds, - BidderYahooAdvertising, - BidderYahooSSP, - BidderYeahmobi, - BidderYieldlab, - BidderYieldmo, - BidderYieldone, - BidderZeroClickFraud, - BidderZetaGlobalSsp, - } + return coreBidderNames } // BuildBidderMap builds a map of string to BidderName, to remain compatbile with the diff --git a/openrtb_ext/bidders_test.go b/openrtb_ext/bidders_test.go index f95d4a36540..eb60f452dc4 100644 --- a/openrtb_ext/bidders_test.go +++ b/openrtb_ext/bidders_test.go @@ -125,3 +125,9 @@ func TestIsBidderNameReserved(t *testing.T) { assert.Equal(t, test.expected, result, test.bidder) } } + +func TestCoreBidderNames(t *testing.T) { + bidderA := "BidderA" + SetAliasBidderName(BidderName(bidderA)) + assert.Contains(t, CoreBidderNames(), BidderName(bidderA)) +} diff --git a/openrtb_ext/bidders_validate_test.go b/openrtb_ext/bidders_validate_test.go index 33148d1ed41..c9528536780 100644 --- a/openrtb_ext/bidders_validate_test.go +++ b/openrtb_ext/bidders_validate_test.go @@ -24,6 +24,9 @@ var validator BidderParamValidator // returns valid JSON for all known CoreBidderNames. func TestBidderParamSchemas(t *testing.T) { for _, bidderName := range CoreBidderNames() { + if _, ok := GetAliasBidderNamesSet()[bidderName]; ok { + continue + } schema := validator.Schema(bidderName) if schema == "" { t.Errorf("No schema exists for bidder %s. Does static/bidder-params/%s.json exist?", bidderName, bidderName) From 60a60d212a0baf8779aaf41c0523d26e53d6450f Mon Sep 17 00:00:00 2001 From: Bernhard Pickenbrock Date: Mon, 21 Aug 2023 08:01:09 +0200 Subject: [PATCH 081/268] Smaato: Update userSync url (#3028) --- static/bidder-info/smaato.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/bidder-info/smaato.yaml b/static/bidder-info/smaato.yaml index 4eb5f17c17c..59a734c90fd 100644 --- a/static/bidder-info/smaato.yaml +++ b/static/bidder-info/smaato.yaml @@ -16,6 +16,6 @@ capabilities: - native userSync: redirect: - url: "https://s.ad.smaato.net/c/?adExInit=p&redir={{.RedirectURL}}" + url: "https://s.ad.smaato.net/c/?adExInit=p&redir={{.RedirectURL}}&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}" userMacro: "$UID" From 379466c1cbfbd1830eae6b9a4e0f9eb7d59b7cff Mon Sep 17 00:00:00 2001 From: Nick Jacob Date: Mon, 21 Aug 2023 02:19:42 -0400 Subject: [PATCH 082/268] AMX RTB: indicate support for GZIP, GPP, and add iframe sync (#3022) --- static/bidder-info/amx.yaml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/static/bidder-info/amx.yaml b/static/bidder-info/amx.yaml index 3ede0d0875f..7ab3cadf304 100644 --- a/static/bidder-info/amx.yaml +++ b/static/bidder-info/amx.yaml @@ -14,7 +14,12 @@ capabilities: - video - native userSync: + iframe: + url: "https://prebid.a-mo.net/isyn?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&s=pbs&cb={{.RedirectURL}}" + userMacro: "$UID" redirect: - url: "https://prebid.a-mo.net/cchain/0?gdpr={{.GDPR}}&us_privacy={{.USPrivacy}}&cb={{.RedirectURL}}" - userMacro: "" - + url: "https://prebid.a-mo.net/cchain/0?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&s=pbs&cb={{.RedirectURL}}" + userMacro: "$UID" +endpointCompression: GZIP +openrtb: + gpp-supported: true From 66c38fa44ef0d7f5ae3ade8cd8621718fe414874 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Mon, 21 Aug 2023 13:06:07 +0530 Subject: [PATCH 083/268] fix semgrep error message (#3038) co-authored by @onkarvhanumante --- .semgrep/adapter/parse-bid-type-check.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.semgrep/adapter/parse-bid-type-check.yml b/.semgrep/adapter/parse-bid-type-check.yml index e2d3624115b..daa70684023 100644 --- a/.semgrep/adapter/parse-bid-type-check.yml +++ b/.semgrep/adapter/parse-bid-type-check.yml @@ -1,6 +1,8 @@ rules: - id: parse-bid-type-check - message: The current implementation follows an anti-pattern, assumes that if there is a multi-format request, the media type defaults to $ORTBTYPE. Prebid server expects the media type to be explicitly set in the adapter response. Therefore, we strongly recommend implementing a pattern where the adapter server sets the [MType](https://github.com/prebid/openrtb/blob/main/openrtb2/bid.go#L334) field in the response to accurately determine the media type for the impression. + message: > + Prebid server expects the media type to be explicitly set in the adapter response. + Therefore, recommends implementing a pattern where the adapter server sets the [MType](https://github.com/prebid/openrtb/blob/main/openrtb2/bid.go#L334) field in the response to accurately determine the media type for the impression. languages: - go severity: WARNING From 2023f4c64a01a01c967eadd24974823e5e34fcc8 Mon Sep 17 00:00:00 2001 From: Veronika Solovei Date: Mon, 21 Aug 2023 10:40:13 -0700 Subject: [PATCH 084/268] TID activity (#3012) * Passed activity control to video endpoint * TID activity * Minor refactoring * Added exchange end-to-end tests --- endpoints/openrtb2/video_auction.go | 11 +++ endpoints/openrtb2/video_auction_test.go | 48 ++++++++++++ exchange/exchange_test.go | 8 ++ exchange/exchangetest/activity-tid-off.json | 85 +++++++++++++++++++++ exchange/exchangetest/activity-tid-on.json | 82 ++++++++++++++++++++ exchange/utils.go | 2 + exchange/utils_test.go | 48 ++++++++++-- privacy/scrubber.go | 5 +- 8 files changed, 282 insertions(+), 7 deletions(-) create mode 100644 exchange/exchangetest/activity-tid-off.json create mode 100644 exchange/exchangetest/activity-tid-on.json diff --git a/endpoints/openrtb2/video_auction.go b/endpoints/openrtb2/video_auction.go index 49e4585d173..8fc2f844c71 100644 --- a/endpoints/openrtb2/video_auction.go +++ b/endpoints/openrtb2/video_auction.go @@ -21,6 +21,7 @@ import ( "github.com/prebid/prebid-server/hooks" "github.com/prebid/prebid-server/hooks/hookexecution" "github.com/prebid/prebid-server/ortb" + "github.com/prebid/prebid-server/privacy" jsonpatch "gopkg.in/evanphx/json-patch.v4" accountService "github.com/prebid/prebid-server/account" @@ -302,6 +303,15 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re return } + activities, activitiesErr := privacy.NewActivityControl(account.Privacy) + if activitiesErr != nil { + errL = append(errL, activitiesErr) + if errortypes.ContainsFatalError(errL) { + handleError(&labels, w, errL, &vo, &debugLog) + return + } + } + secGPC := r.Header.Get("Sec-GPC") auctionRequest := &exchange.AuctionRequest{ BidRequestWrapper: bidReqWrapper, @@ -314,6 +324,7 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re PubID: labels.PubID, HookExecutor: hookexecution.EmptyHookExecutor{}, TmaxAdjustments: deps.tmaxAdjustments, + Activities: activities, } auctionResponse, err := deps.ex.HoldAuction(ctx, auctionRequest, &debugLog) diff --git a/endpoints/openrtb2/video_auction_test.go b/endpoints/openrtb2/video_auction_test.go index 1f28efb8a6f..2d74bbe5c12 100644 --- a/endpoints/openrtb2/video_auction_test.go +++ b/endpoints/openrtb2/video_auction_test.go @@ -65,6 +65,20 @@ func TestVideoEndpointImpressionsNumber(t *testing.T) { assert.Equal(t, resp.AdPods[0].Targeting[0].HbDeal, "ABC_123", "If DealID exists in bid response, hb_deal targeting needs to be added to resp") } +func TestVideoEndpointInvalidPrivacyConfig(t *testing.T) { + ex := &mockExchangeVideo{} + reqBody := readVideoTestFile(t, "sample-requests/video/video_valid_sample.json") + req := httptest.NewRequest("POST", "/openrtb2/video", strings.NewReader(reqBody)) + recorder := httptest.NewRecorder() + + deps := mockDepsInvalidPrivacy(t, ex) + deps.VideoAuctionEndpoint(recorder, req, nil) + + respBytes := recorder.Body.Bytes() + expectedErrorMessage := "Critical error while running the video endpoint: unable to parse condition: bidderA.BidderB.bidderC" + assert.Equal(t, expectedErrorMessage, string(respBytes), "error message is incorrect") +} + func TestVideoEndpointImpressionsDuration(t *testing.T) { ex := &mockExchangeVideo{} reqBody := readVideoTestFile(t, "sample-requests/video/video_valid_sample_different_durations.json") @@ -1275,6 +1289,40 @@ func mockDeps(t *testing.T, ex *mockExchangeVideo) *endpointDeps { } } +func mockDepsInvalidPrivacy(t *testing.T, ex *mockExchangeVideo) *endpointDeps { + return &endpointDeps{ + fakeUUIDGenerator{}, + ex, + mockBidderParamValidator{}, + &mockVideoStoredReqFetcher{}, + &mockVideoStoredReqFetcher{}, + &mockAccountFetcher{data: mockVideoAccountData}, + &config.Configuration{MaxRequestSize: maxSize, + AccountDefaults: config.Account{ + Privacy: &config.AccountPrivacy{ + AllowActivities: config.AllowActivities{ + TransmitPreciseGeo: config.Activity{Rules: []config.ActivityRule{ + {Condition: config.ActivityCondition{ComponentName: []string{"bidderA.BidderB.bidderC"}}}, + }}, + }, + }, + }, + }, + &metricsConfig.NilMetricsEngine{}, + analyticsConf.NewPBSAnalytics(&config.Analytics{}), + map[string]string{}, + false, + []byte{}, + openrtb_ext.BuildBidderMap(), + ex.cache, + regexp.MustCompile(`[<>]`), + hardcodedResponseIPValidator{response: true}, + empty_fetcher.EmptyFetcher{}, + hooks.EmptyPlanBuilder{}, + nil, + } +} + func mockDepsAppendBidderNames(t *testing.T, ex *mockExchangeAppendBidderNames) *endpointDeps { deps := &endpointDeps{ fakeUUIDGenerator{}, diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go index 52813897142..919f8dceb54 100644 --- a/exchange/exchange_test.go +++ b/exchange/exchange_test.go @@ -37,6 +37,7 @@ import ( metricsConfig "github.com/prebid/prebid-server/metrics/config" "github.com/prebid/prebid-server/openrtb_ext" pbc "github.com/prebid/prebid-server/prebid_cache_client" + "github.com/prebid/prebid-server/privacy" "github.com/prebid/prebid-server/stored_requests" "github.com/prebid/prebid-server/stored_requests/backends/file_fetcher" "github.com/prebid/prebid-server/usersync" @@ -2351,6 +2352,11 @@ func runSpec(t *testing.T, filename string, spec *exchangeSpec) { impExtInfoMap[impID] = ImpExtInfo{} } + activityControl, err := privacy.NewActivityControl(spec.AccountPrivacy) + if err != nil { + t.Errorf("%s: Exchange returned an unexpected error. Got %s", filename, err.Error()) + } + auctionRequest := &AuctionRequest{ BidRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: &spec.IncomingRequest.OrtbRequest}, Account: config.Account{ @@ -2366,6 +2372,7 @@ func runSpec(t *testing.T, filename string, spec *exchangeSpec) { ImpExtInfoMap: impExtInfoMap, HookExecutor: &hookexecution.EmptyHookExecutor{}, TCF2Config: gdpr.NewTCF2Config(privacyConfig.GDPR.TCF2, config.AccountGDPR{}), + Activities: activityControl, } if spec.MultiBid != nil { @@ -5187,6 +5194,7 @@ type exchangeSpec struct { FledgeEnabled bool `json:"fledge_enabled,omitempty"` MultiBid *multiBidSpec `json:"multiBid,omitempty"` Server exchangeServer `json:"server,omitempty"` + AccountPrivacy *config.AccountPrivacy `json:"accountPrivacy,omitempty"` } type multiBidSpec struct { diff --git a/exchange/exchangetest/activity-tid-off.json b/exchange/exchangetest/activity-tid-off.json new file mode 100644 index 00000000000..174f09659ec --- /dev/null +++ b/exchange/exchangetest/activity-tid-off.json @@ -0,0 +1,85 @@ +{ + "accountPrivacy": { + "allowactivities": { + "transmitTid": { + "default": true, + "rules": [ + { + "allow": true, + "condition": { + "componentName": ["appnexus"], + "componentType":["bidder"] + } + } + ] + } + } + }, + "incomingRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "my-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "tid": "extTestTID", + "prebid": { + "bidder": { + "appnexus": { + "placementId": 1 + } + } + } + } + } + ], + "source": { + "tid": "sourceTestTID" + } + } + }, + "outgoingRequests": { + "appnexus": { + "expectRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "my-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "tid": "extTestTID", + "bidder": { + "placementId": 1 + } + } + } + ], + "source": { + "tid": "sourceTestTID" + } + } + }, + "mockResponse": { + "errors": [ + "appnexus-error" + ] + } + } + } +} \ No newline at end of file diff --git a/exchange/exchangetest/activity-tid-on.json b/exchange/exchangetest/activity-tid-on.json new file mode 100644 index 00000000000..98da945bff2 --- /dev/null +++ b/exchange/exchangetest/activity-tid-on.json @@ -0,0 +1,82 @@ +{ + "accountPrivacy": { + "allowactivities": { + "transmitTid": { + "default": true, + "rules": [ + { + "allow": false, + "condition": { + "componentName": ["appnexus"], + "componentType":["bidder"] + } + } + ] + } + } + }, + "incomingRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "my-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "tid": "extTestTID", + "prebid": { + "bidder": { + "appnexus": { + "placementId": 1 + } + } + } + } + } + ], + "source": { + "tid": "sourceTestTID" + } + } + }, + "outgoingRequests": { + "appnexus": { + "expectRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "my-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "placementId": 1 + } + } + } + ], + "source": {} + } + }, + "mockResponse": { + "errors": [ + "appnexus-error" + ] + } + } + } +} \ No newline at end of file diff --git a/exchange/utils.go b/exchange/utils.go index 17bba334e89..907a039ae8a 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -212,6 +212,8 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, applyFPD(auctionReq.FirstPartyData[bidderRequest.BidderName], bidderRequest.BidRequest) } + privacyEnforcement.TID = !auctionReq.Activities.Allow(privacy.ActivityTransmitTids, scopedName) + privacyEnforcement.Apply(bidderRequest.BidRequest) allowedBidderRequests = append(allowedBidderRequests, bidderRequest) diff --git a/exchange/utils_test.go b/exchange/utils_test.go index aff1b3c09a1..63ca54c2a2e 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -2551,7 +2551,7 @@ func newAdapterAliasBidRequest(t *testing.T) *openrtb2.BidRequest { Language: "EN", }, Source: &openrtb2.Source{ - TID: "61018dc9-fa61-4c41-b7dc-f90b9ae80e87", + TID: "testTID", }, User: &openrtb2.User{ ID: "our-id", @@ -2595,7 +2595,7 @@ func newBidRequest(t *testing.T) *openrtb2.BidRequest { Language: "EN", }, Source: &openrtb2.Source{ - TID: "61018dc9-fa61-4c41-b7dc-f90b9ae80e87", + TID: "testTID", }, User: &openrtb2.User{ ID: "our-id", @@ -2615,7 +2615,7 @@ func newBidRequest(t *testing.T) *openrtb2.BidRequest { H: 600, }}, }, - Ext: json.RawMessage(`{"prebid":{"bidder":{"appnexus": {"placementId": 1}}}}`), + Ext: json.RawMessage(`{"prebid":{"tid":"1234567", "bidder":{"appnexus": {"placementId": 1}}}}`), }}, } } @@ -2637,7 +2637,7 @@ func newBidRequestWithBidderParams(t *testing.T) *openrtb2.BidRequest { Language: "EN", }, Source: &openrtb2.Source{ - TID: "61018dc9-fa61-4c41-b7dc-f90b9ae80e87", + TID: "testTID", }, User: &openrtb2.User{ ID: "our-id", @@ -3065,7 +3065,7 @@ func TestCleanOpenRTBRequestsSChainMultipleBidders(t *testing.T) { req := &openrtb2.BidRequest{ Site: &openrtb2.Site{}, Source: &openrtb2.Source{ - TID: "61018dc9-fa61-4c41-b7dc-f90b9ae80e87", + TID: "testTID", }, Imp: []openrtb2.Imp{{ Ext: json.RawMessage(`{"prebid":{"bidder":{"appnexus": {"placementId": 1}, "axonix": { "supplyId": "123"}}}}`), @@ -4268,7 +4268,7 @@ func TestGetMediaTypeForBid(t *testing.T) { } } -func TestCleanOpenRTBRequestsActivitiesFetchBids(t *testing.T) { +func TestCleanOpenRTBRequestsActivities(t *testing.T) { testCases := []struct { name string req *openrtb2.BidRequest @@ -4279,6 +4279,7 @@ func TestCleanOpenRTBRequestsActivitiesFetchBids(t *testing.T) { expectedUserYOB int64 expectedUserLat float64 expectedDeviceDIDMD5 string + expectedSourceTID string }{ { name: "fetch_bids_request_with_one_bidder_allowed", @@ -4288,6 +4289,7 @@ func TestCleanOpenRTBRequestsActivitiesFetchBids(t *testing.T) { expectedUserYOB: 1982, expectedUserLat: 123.456, expectedDeviceDIDMD5: "some device ID hash", + expectedSourceTID: "testTID", }, { name: "fetch_bids_request_with_one_bidder_not_allowed", @@ -4297,6 +4299,7 @@ func TestCleanOpenRTBRequestsActivitiesFetchBids(t *testing.T) { expectedUserYOB: 1982, expectedUserLat: 123.456, expectedDeviceDIDMD5: "some device ID hash", + expectedSourceTID: "testTID", }, { name: "transmit_ufpd_allowed", @@ -4306,6 +4309,7 @@ func TestCleanOpenRTBRequestsActivitiesFetchBids(t *testing.T) { expectedUserYOB: 1982, expectedUserLat: 123.456, expectedDeviceDIDMD5: "some device ID hash", + expectedSourceTID: "testTID", }, { name: "transmit_ufpd_deny", @@ -4315,6 +4319,7 @@ func TestCleanOpenRTBRequestsActivitiesFetchBids(t *testing.T) { expectedUserYOB: 0, expectedUserLat: 123.456, expectedDeviceDIDMD5: "", + expectedSourceTID: "testTID", }, { name: "transmit_precise_geo_allowed", @@ -4324,6 +4329,7 @@ func TestCleanOpenRTBRequestsActivitiesFetchBids(t *testing.T) { expectedUserYOB: 1982, expectedUserLat: 123.456, expectedDeviceDIDMD5: "some device ID hash", + expectedSourceTID: "testTID", }, { name: "transmit_precise_geo_deny", @@ -4333,6 +4339,27 @@ func TestCleanOpenRTBRequestsActivitiesFetchBids(t *testing.T) { expectedUserYOB: 1982, expectedUserLat: 123.46, expectedDeviceDIDMD5: "some device ID hash", + expectedSourceTID: "testTID", + }, + { + name: "transmit_tid_allowed", + req: newBidRequest(t), + privacyConfig: getTransmitTIDActivityConfig("appnexus", true), + expectedReqNumber: 1, + expectedUserYOB: 1982, + expectedUserLat: 123.456, + expectedDeviceDIDMD5: "some device ID hash", + expectedSourceTID: "testTID", + }, + { + name: "transmit_tid_deny", + req: newBidRequest(t), + privacyConfig: getTransmitTIDActivityConfig("appnexus", false), + expectedReqNumber: 1, + expectedUserYOB: 1982, + expectedUserLat: 123.456, + expectedDeviceDIDMD5: "some device ID hash", + expectedSourceTID: "", }, } @@ -4362,6 +4389,7 @@ func TestCleanOpenRTBRequestsActivitiesFetchBids(t *testing.T) { assert.Equal(t, test.expectedUserYOB, bidderRequests[0].BidRequest.User.Yob) assert.Equal(t, test.expectedUserLat, bidderRequests[0].BidRequest.User.Geo.Lat) assert.Equal(t, test.expectedDeviceDIDMD5, bidderRequests[0].BidRequest.Device.DIDMD5) + assert.Equal(t, test.expectedSourceTID, bidderRequests[0].BidRequest.Source.TID) } }) } @@ -4405,3 +4433,11 @@ func getTransmitPreciseGeoActivityConfig(componentName string, allow bool) *conf }, } } + +func getTransmitTIDActivityConfig(componentName string, allow bool) *config.AccountPrivacy { + return &config.AccountPrivacy{ + AllowActivities: config.AllowActivities{ + TransmitTids: buildDefaultActivityConfig(componentName, allow), + }, + } +} diff --git a/privacy/scrubber.go b/privacy/scrubber.go index 97419128952..f2fb790dc12 100644 --- a/privacy/scrubber.go +++ b/privacy/scrubber.go @@ -147,7 +147,10 @@ func (scrubber) ScrubRequest(bidRequest *openrtb2.BidRequest, enforcement Enforc if enforcement.TID { //remove source.tid and imp.ext.tid if bidRequest.Source != nil { - bidRequest.Source.TID = "" + var sourceCopy *openrtb2.Source + sourceCopy = ptrutil.Clone(bidRequest.Source) + sourceCopy.TID = "" + bidRequest.Source = sourceCopy } for ind, imp := range bidRequest.Imp { impExt := scrubExtIDs(imp.Ext, "tid") From 67f24a9543a59948615c5e64f172ce017cbc3dfb Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Mon, 21 Aug 2023 15:15:38 -0400 Subject: [PATCH 085/268] Activity Control: Separate Files (#3023) --- endpoints/cookie_sync.go | 2 +- endpoints/setuid.go | 2 +- exchange/utils.go | 2 +- privacy/{enforcer.go => activitycontrol.go} | 118 +---------- ...forcer_test.go => activitycontrol_test.go} | 193 ++---------------- privacy/component.go | 65 ++++++ privacy/component_test.go | 124 +++++++++++ privacy/rules.go | 59 ++++++ privacy/rules_test.go | 97 +++++++++ 9 files changed, 373 insertions(+), 289 deletions(-) rename privacy/{enforcer.go => activitycontrol.go} (53%) rename privacy/{enforcer_test.go => activitycontrol_test.go} (57%) create mode 100644 privacy/component.go create mode 100644 privacy/component_test.go create mode 100644 privacy/rules.go create mode 100644 privacy/rules_test.go diff --git a/endpoints/cookie_sync.go b/endpoints/cookie_sync.go index f0299d2e306..5caa543cbea 100644 --- a/endpoints/cookie_sync.go +++ b/endpoints/cookie_sync.go @@ -529,5 +529,5 @@ func (p usersyncPrivacy) CCPAAllowsBidderSync(bidder string) bool { func (p usersyncPrivacy) ActivityAllowsUserSync(bidder string) bool { return p.activityControl.Allow(privacy.ActivitySyncUser, - privacy.ScopedName{Scope: privacy.ScopeTypeBidder, Name: bidder}) + privacy.Component{Type: privacy.ComponentTypeBidder, Name: bidder}) } diff --git a/endpoints/setuid.go b/endpoints/setuid.go index 58b6f8db41d..561989e029d 100644 --- a/endpoints/setuid.go +++ b/endpoints/setuid.go @@ -112,7 +112,7 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use } userSyncActivityAllowed := activities.Allow(privacy.ActivitySyncUser, - privacy.ScopedName{Scope: privacy.ScopeTypeBidder, Name: bidderName}) + privacy.Component{Type: privacy.ComponentTypeBidder, Name: bidderName}) if !userSyncActivityAllowed { w.WriteHeader(http.StatusUnavailableForLegalReasons) return diff --git a/exchange/utils.go b/exchange/utils.go index 907a039ae8a..baedcf78475 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -152,7 +152,7 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, } // fetchBids activity - scopedName := privacy.ScopedName{Scope: privacy.ScopeTypeBidder, Name: bidderRequest.BidderName.String()} + scopedName := privacy.Component{Type: privacy.ComponentTypeBidder, Name: bidderRequest.BidderName.String()} fetchBidsActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityFetchBids, scopedName) if !fetchBidsActivityAllowed { // skip the call to a bidder if fetchBids activity is not allowed diff --git a/privacy/enforcer.go b/privacy/activitycontrol.go similarity index 53% rename from privacy/enforcer.go rename to privacy/activitycontrol.go index aeaaab8dd27..fee5c6508a6 100644 --- a/privacy/enforcer.go +++ b/privacy/activitycontrol.go @@ -1,9 +1,6 @@ package privacy import ( - "fmt" - "strings" - "github.com/prebid/prebid-server/config" ) @@ -15,14 +12,6 @@ const ( ActivityDeny ) -const ( - ScopeTypeBidder = "bidder" - ScopeTypeAnalytics = "analytics" - ScopeTypeRTD = "rtd" // real time data - ScopeTypeUserID = "userid" - ScopeTypeGeneral = "general" -) - const defaultActivityResult = true type ActivityControl struct { @@ -88,8 +77,8 @@ func buildEnforcementPlan(activity config.Activity) (ActivityPlan, error) { return ef, nil } -func activityRulesToEnforcementRules(rules []config.ActivityRule) ([]ActivityRule, error) { - var enfRules []ActivityRule +func activityRulesToEnforcementRules(rules []config.ActivityRule) ([]Rule, error) { + var enfRules []Rule for _, r := range rules { var result ActivityResult @@ -114,12 +103,12 @@ func activityRulesToEnforcementRules(rules []config.ActivityRule) ([]ActivityRul return enfRules, nil } -func conditionToRuleComponentNames(conditions []string) ([]ScopedName, error) { - sn := make([]ScopedName, 0) +func conditionToRuleComponentNames(conditions []string) ([]Component, error) { + sn := make([]Component, 0) for _, condition := range conditions { - scope, err := NewScopedName(condition) + scope, err := ParseComponent(condition) if err != nil { - return sn, err + return nil, err } sn = append(sn, scope) } @@ -128,13 +117,12 @@ func conditionToRuleComponentNames(conditions []string) ([]ScopedName, error) { func activityDefaultToDefaultResult(activityDefault *bool) bool { if activityDefault == nil { - // if default is unspecified, the hardcoded default-default is true. return defaultActivityResult } return *activityDefault } -func (e ActivityControl) Allow(activity Activity, target ScopedName) bool { +func (e ActivityControl) Allow(activity Activity, target Component) bool { plan, planDefined := e.plans[activity] if !planDefined { @@ -146,10 +134,10 @@ func (e ActivityControl) Allow(activity Activity, target ScopedName) bool { type ActivityPlan struct { defaultResult bool - rules []ActivityRule + rules []Rule } -func (p ActivityPlan) Evaluate(target ScopedName) bool { +func (p ActivityPlan) Evaluate(target Component) bool { for _, rule := range p.rules { result := rule.Evaluate(target) if result == ActivityDeny || result == ActivityAllow { @@ -158,91 +146,3 @@ func (p ActivityPlan) Evaluate(target ScopedName) bool { } return p.defaultResult } - -type ActivityRule interface { - Evaluate(target ScopedName) ActivityResult -} - -type ComponentEnforcementRule struct { - result ActivityResult - componentName []ScopedName - componentType []string -} - -func (r ComponentEnforcementRule) Evaluate(target ScopedName) ActivityResult { - if matched := evaluateComponentName(target, r.componentName); !matched { - return ActivityAbstain - } - - if matched := evaluateComponentType(target, r.componentType); !matched { - return ActivityAbstain - } - - return r.result -} - -func evaluateComponentName(target ScopedName, componentNames []ScopedName) bool { - // no clauses are considered a match - if len(componentNames) == 0 { - return true - } - - // if there are clauses, at least one needs to match - for _, n := range componentNames { - if strings.EqualFold(n.Scope, target.Scope) && (n.Name == "*" || strings.EqualFold(n.Name, target.Name)) { - return true - } - } - - return false -} - -func evaluateComponentType(target ScopedName, componentTypes []string) bool { - // no clauses are considered a match - if len(componentTypes) == 0 { - return true - } - - // if there are clauses, at least one needs to match - for _, s := range componentTypes { - if strings.EqualFold(s, target.Scope) { - return true - } - } - - return false -} - -type ScopedName struct { - Scope string - Name string -} - -func NewScopedName(condition string) (ScopedName, error) { - if condition == "" { - return ScopedName{}, fmt.Errorf("unable to parse empty condition") - } - var scope, name string - split := strings.Split(condition, ".") - if len(split) == 2 { - s := strings.ToLower(split[0]) - if s == ScopeTypeBidder || s == ScopeTypeAnalytics || s == ScopeTypeUserID { - scope = s - } else if strings.Contains(s, ScopeTypeRTD) { - scope = ScopeTypeRTD - } else { - scope = ScopeTypeGeneral - } - name = split[1] - } else if len(split) == 1 { - scope = ScopeTypeBidder - name = split[0] - } else { - return ScopedName{}, fmt.Errorf("unable to parse condition: %s", condition) - } - - return ScopedName{ - Scope: scope, - Name: name, - }, nil -} diff --git a/privacy/enforcer_test.go b/privacy/activitycontrol_test.go similarity index 57% rename from privacy/enforcer_test.go rename to privacy/activitycontrol_test.go index 864964c2a51..7927014a928 100644 --- a/privacy/enforcer_test.go +++ b/privacy/activitycontrol_test.go @@ -10,7 +10,6 @@ import ( ) func TestNewActivityControl(t *testing.T) { - testCases := []struct { name string privacyConf *config.AccountPrivacy @@ -57,7 +56,7 @@ func TestNewActivityControl(t *testing.T) { }, }, activityControl: ActivityControl{plans: nil}, - err: errors.New("unable to parse condition: bidder.bidderA.bidderB"), + err: errors.New("unable to parse component: bidder.bidderA.bidderB"), }, { name: "privacy_config_is_specified_and_FetchBids_is_incorrect", @@ -67,7 +66,7 @@ func TestNewActivityControl(t *testing.T) { }, }, activityControl: ActivityControl{plans: nil}, - err: errors.New("unable to parse condition: bidder.bidderA.bidderB"), + err: errors.New("unable to parse component: bidder.bidderA.bidderB"), }, { name: "privacy_config_is_specified_and_EnrichUserFPD_is_incorrect", @@ -77,7 +76,7 @@ func TestNewActivityControl(t *testing.T) { }, }, activityControl: ActivityControl{plans: nil}, - err: errors.New("unable to parse condition: bidder.bidderA.bidderB"), + err: errors.New("unable to parse component: bidder.bidderA.bidderB"), }, { name: "privacy_config_is_specified_and_ReportAnalytics_is_incorrect", @@ -87,7 +86,7 @@ func TestNewActivityControl(t *testing.T) { }, }, activityControl: ActivityControl{plans: nil}, - err: errors.New("unable to parse condition: bidder.bidderA.bidderB"), + err: errors.New("unable to parse component: bidder.bidderA.bidderB"), }, { name: "privacy_config_is_specified_and_TransmitUserFPD_is_incorrect", @@ -97,7 +96,7 @@ func TestNewActivityControl(t *testing.T) { }, }, activityControl: ActivityControl{plans: nil}, - err: errors.New("unable to parse condition: bidder.bidderA.bidderB"), + err: errors.New("unable to parse component: bidder.bidderA.bidderB"), }, { name: "privacy_config_is_specified_and_TransmitPreciseGeo_is_incorrect", @@ -107,7 +106,7 @@ func TestNewActivityControl(t *testing.T) { }, }, activityControl: ActivityControl{plans: nil}, - err: errors.New("unable to parse condition: bidder.bidderA.bidderB"), + err: errors.New("unable to parse component: bidder.bidderA.bidderB"), }, { name: "privacy_config_is_specified_and_TransmitUniqueRequestIds_is_incorrect", @@ -117,7 +116,7 @@ func TestNewActivityControl(t *testing.T) { }, }, activityControl: ActivityControl{plans: nil}, - err: errors.New("unable to parse condition: bidder.bidderA.bidderB"), + err: errors.New("unable to parse component: bidder.bidderA.bidderB"), }, { name: "privacy_config_is_specified_and_TransmitTids_is_incorrect", @@ -127,7 +126,7 @@ func TestNewActivityControl(t *testing.T) { }, }, activityControl: ActivityControl{plans: nil}, - err: errors.New("unable to parse condition: bidder.bidderA.bidderB"), + err: errors.New("unable to parse component: bidder.bidderA.bidderB"), }, } @@ -181,14 +180,14 @@ func TestAllowActivityControl(t *testing.T) { name string activityControl ActivityControl activity Activity - target ScopedName + target Component activityResult bool }{ { name: "plans_is_nil", activityControl: ActivityControl{plans: nil}, activity: ActivityFetchBids, - target: ScopedName{Scope: "bidder", Name: "bidderA"}, + target: Component{Type: "bidder", Name: "bidderA"}, activityResult: true, }, { @@ -196,7 +195,7 @@ func TestAllowActivityControl(t *testing.T) { activityControl: ActivityControl{plans: map[Activity]ActivityPlan{ ActivitySyncUser: getDefaultActivityPlan()}}, activity: ActivityFetchBids, - target: ScopedName{Scope: "bidder", Name: "bidderA"}, + target: Component{Type: "bidder", Name: "bidderA"}, activityResult: true, }, { @@ -204,7 +203,7 @@ func TestAllowActivityControl(t *testing.T) { activityControl: ActivityControl{plans: map[Activity]ActivityPlan{ ActivityFetchBids: getDefaultActivityPlan()}}, activity: ActivityFetchBids, - target: ScopedName{Scope: "bidder", Name: "bidderB"}, + target: Component{Type: "bidder", Name: "bidderB"}, activityResult: true, }, { @@ -212,7 +211,7 @@ func TestAllowActivityControl(t *testing.T) { activityControl: ActivityControl{plans: map[Activity]ActivityPlan{ ActivityFetchBids: getDefaultActivityPlan()}}, activity: ActivityFetchBids, - target: ScopedName{Scope: "bidder", Name: "bidderA"}, + target: Component{Type: "bidder", Name: "bidderA"}, activityResult: true, }, } @@ -226,166 +225,6 @@ func TestAllowActivityControl(t *testing.T) { } } -func TestComponentEnforcementRuleEvaluate(t *testing.T) { - testCases := []struct { - name string - componentRule ComponentEnforcementRule - target ScopedName - activityResult ActivityResult - }{ - { - name: "activity_is_allowed", - componentRule: ComponentEnforcementRule{ - result: ActivityAllow, - componentName: []ScopedName{ - {Scope: "bidder", Name: "bidderA"}, - }, - componentType: []string{"bidder"}, - }, - target: ScopedName{Scope: "bidder", Name: "bidderA"}, - activityResult: ActivityAllow, - }, - { - name: "activity_is_not_allowed", - componentRule: ComponentEnforcementRule{ - result: ActivityDeny, - componentName: []ScopedName{ - {Scope: "bidder", Name: "bidderA"}, - }, - componentType: []string{"bidder"}, - }, - target: ScopedName{Scope: "bidder", Name: "bidderA"}, - activityResult: ActivityDeny, - }, - { - name: "abstain_both_clauses_do_not_match", - componentRule: ComponentEnforcementRule{ - result: ActivityAllow, - componentName: []ScopedName{ - {Scope: "bidder", Name: "bidderA"}, - }, - componentType: []string{"bidder"}, - }, - target: ScopedName{Scope: "bidder", Name: "bidderB"}, - activityResult: ActivityAbstain, - }, - { - name: "activity_is_not_allowed_componentName_only", - componentRule: ComponentEnforcementRule{ - result: ActivityAllow, - componentName: []ScopedName{ - {Scope: "bidder", Name: "bidderA"}, - }, - }, - target: ScopedName{Scope: "bidder", Name: "bidderA"}, - activityResult: ActivityAllow, - }, - { - name: "activity_is_allowed_componentType_only", - componentRule: ComponentEnforcementRule{ - result: ActivityAllow, - componentType: []string{"bidder"}, - }, - target: ScopedName{Scope: "bidder", Name: "bidderB"}, - activityResult: ActivityAllow, - }, - { - name: "no-conditions-allow", - componentRule: ComponentEnforcementRule{ - result: ActivityAllow, - }, - target: ScopedName{Scope: "bidder", Name: "bidderA"}, - activityResult: ActivityAllow, - }, - { - name: "no-conditions-deny", - componentRule: ComponentEnforcementRule{ - result: ActivityDeny, - }, - target: ScopedName{Scope: "bidder", Name: "bidderA"}, - activityResult: ActivityDeny, - }, - } - - for _, test := range testCases { - t.Run(test.name, func(t *testing.T) { - actualResult := test.componentRule.Evaluate(test.target) - assert.Equal(t, test.activityResult, actualResult) - - }) - } -} - -func TestNewScopedName(t *testing.T) { - testCases := []struct { - name string - condition string - expectedScopeName ScopedName - err error - }{ - { - name: "empty", - condition: "", - expectedScopeName: ScopedName{}, - err: errors.New("unable to parse empty condition"), - }, - { - name: "incorrect", - condition: "bidder.bidderA.bidderB", - expectedScopeName: ScopedName{}, - err: errors.New("unable to parse condition: bidder.bidderA.bidderB"), - }, - { - name: "scope-bidder", - condition: "bidder.bidderA", - expectedScopeName: ScopedName{Scope: "bidder", Name: "bidderA"}, - err: nil, - }, - { - name: "scope-analytics", - condition: "analytics.bidderA", - expectedScopeName: ScopedName{Scope: "analytics", Name: "bidderA"}, - err: nil, - }, - { - name: "scope-userid", - condition: "userid.bidderA", - expectedScopeName: ScopedName{Scope: "userid", Name: "bidderA"}, - err: nil, - }, - { - name: "scope-default", - condition: "bidderA", - expectedScopeName: ScopedName{Scope: "bidder", Name: "bidderA"}, - err: nil, - }, - { - name: "scope-rtf", - condition: "rtd.test", - expectedScopeName: ScopedName{Scope: "rtd", Name: "test"}, - err: nil, - }, - { - name: "scope-general", - condition: "test.test", - expectedScopeName: ScopedName{Scope: "general", Name: "test"}, - err: nil, - }, - } - - for _, test := range testCases { - t.Run(test.name, func(t *testing.T) { - actualSN, actualErr := NewScopedName(test.condition) - if test.err == nil { - assert.Equal(t, test.expectedScopeName, actualSN) - assert.NoError(t, actualErr) - } else { - assert.EqualError(t, actualErr, test.err.Error()) - } - }) - } -} - // constants func getDefaultActivityConfig() config.Activity { return config.Activity{ @@ -405,11 +244,11 @@ func getDefaultActivityConfig() config.Activity { func getDefaultActivityPlan() ActivityPlan { return ActivityPlan{ defaultResult: true, - rules: []ActivityRule{ + rules: []Rule{ ComponentEnforcementRule{ result: ActivityAllow, - componentName: []ScopedName{ - {Scope: "bidder", Name: "bidderA"}, + componentName: []Component{ + {Type: "bidder", Name: "bidderA"}, }, componentType: []string{"bidder"}, }, diff --git a/privacy/component.go b/privacy/component.go new file mode 100644 index 00000000000..a203c6bdb3b --- /dev/null +++ b/privacy/component.go @@ -0,0 +1,65 @@ +package privacy + +import ( + "errors" + "fmt" + "strings" +) + +const ( + ComponentTypeBidder = "bidder" + ComponentTypeAnalytics = "analytics" + ComponentTypeRealTimeData = "rtd" + ComponentTypeGeneral = "general" +) + +type Component struct { + Type string + Name string +} + +func (c Component) Matches(target Component) bool { + return strings.EqualFold(c.Type, target.Type) && (c.Name == "*" || strings.EqualFold(c.Name, target.Name)) +} + +var ErrComponentEmpty = errors.New("unable to parse empty component") + +func ParseComponent(v string) (Component, error) { + if len(v) == 0 { + return Component{}, ErrComponentEmpty + } + + split := strings.Split(v, ".") + + if len(split) == 2 { + if !validComponentType(split[0]) { + return Component{}, fmt.Errorf("unable to parse component (invalid type): %s", v) + } + return Component{ + Type: split[0], + Name: split[1], + }, nil + } + + if len(split) == 1 { + return Component{ + Type: ComponentTypeBidder, + Name: split[0], + }, nil + } + + return Component{}, fmt.Errorf("unable to parse component: %s", v) +} + +func validComponentType(t string) bool { + t = strings.ToLower(t) + + if t == ComponentTypeBidder || + t == ComponentTypeAnalytics || + t == ComponentTypeRealTimeData || + t == ComponentTypeGeneral { + return true + } + + return false +} diff --git a/privacy/component_test.go b/privacy/component_test.go new file mode 100644 index 00000000000..38aa105d602 --- /dev/null +++ b/privacy/component_test.go @@ -0,0 +1,124 @@ +package privacy + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestComponentMatches(t *testing.T) { + testCases := []struct { + name string + given Component + target Component + result bool + }{ + { + name: "full", + given: Component{Type: "a", Name: "b"}, + target: Component{Type: "a", Name: "b"}, + result: true, + }, + { + name: "name-wildcard", + given: Component{Type: "a", Name: "*"}, + target: Component{Type: "a", Name: "b"}, + result: true, + }, + { + name: "different", + given: Component{Type: "a", Name: "b"}, + target: Component{Type: "foo", Name: "bar"}, + result: false, + }, + { + name: "different-type", + given: Component{Type: "a", Name: "b"}, + target: Component{Type: "foo", Name: "b"}, + result: false, + }, + { + name: "different-name", + given: Component{Type: "a", Name: "b"}, + target: Component{Type: "a", Name: "foo"}, + result: false, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + assert.Equal(t, test.result, test.given.Matches(test.target)) + }) + } +} + +func TestParseComponent(t *testing.T) { + testCases := []struct { + name string + component string + expected Component + expectedError error + }{ + { + name: "empty", + component: "", + expected: Component{}, + expectedError: errors.New("unable to parse empty component"), + }, + { + name: "too-many-parts", + component: "bidder.bidderA.bidderB", + expected: Component{}, + expectedError: errors.New("unable to parse component: bidder.bidderA.bidderB"), + }, + { + name: "type-bidder", + component: "bidder.bidderA", + expected: Component{Type: "bidder", Name: "bidderA"}, + expectedError: nil, + }, + { + name: "type-analytics", + component: "analytics.bidderA", + expected: Component{Type: "analytics", Name: "bidderA"}, + expectedError: nil, + }, + { + name: "type-default", + component: "bidderA", + expected: Component{Type: "bidder", Name: "bidderA"}, + expectedError: nil, + }, + { + name: "type-rtd", + component: "rtd.test", + expected: Component{Type: "rtd", Name: "test"}, + expectedError: nil, + }, + { + name: "type-general", + component: "general.test", + expected: Component{Type: "general", Name: "test"}, + expectedError: nil, + }, + { + name: "type-invalid", + component: "invalid.test", + expected: Component{}, + expectedError: errors.New("unable to parse component (invalid type): invalid.test"), + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + actualSN, actualErr := ParseComponent(test.component) + if test.expectedError == nil { + assert.Equal(t, test.expected, actualSN) + assert.NoError(t, actualErr) + } else { + assert.EqualError(t, actualErr, test.expectedError.Error()) + } + }) + } +} diff --git a/privacy/rules.go b/privacy/rules.go new file mode 100644 index 00000000000..502e10efbad --- /dev/null +++ b/privacy/rules.go @@ -0,0 +1,59 @@ +package privacy + +import ( + "strings" +) + +type Rule interface { + Evaluate(target Component) ActivityResult +} + +type ComponentEnforcementRule struct { + result ActivityResult + componentName []Component + componentType []string +} + +func (r ComponentEnforcementRule) Evaluate(target Component) ActivityResult { + if matched := evaluateComponentName(target, r.componentName); !matched { + return ActivityAbstain + } + + if matched := evaluateComponentType(target, r.componentType); !matched { + return ActivityAbstain + } + + return r.result +} + +func evaluateComponentName(target Component, componentNames []Component) bool { + // no clauses are considered a match + if len(componentNames) == 0 { + return true + } + + // if there are clauses, at least one needs to match + for _, n := range componentNames { + if n.Matches(target) { + return true + } + } + + return false +} + +func evaluateComponentType(target Component, componentTypes []string) bool { + // no clauses are considered a match + if len(componentTypes) == 0 { + return true + } + + // if there are clauses, at least one needs to match + for _, s := range componentTypes { + if strings.EqualFold(s, target.Type) { + return true + } + } + + return false +} diff --git a/privacy/rules_test.go b/privacy/rules_test.go new file mode 100644 index 00000000000..7e80c9cee95 --- /dev/null +++ b/privacy/rules_test.go @@ -0,0 +1,97 @@ +package privacy + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestComponentEnforcementRuleEvaluate(t *testing.T) { + testCases := []struct { + name string + componentRule ComponentEnforcementRule + target Component + activityResult ActivityResult + }{ + { + name: "activity_is_allowed", + componentRule: ComponentEnforcementRule{ + result: ActivityAllow, + componentName: []Component{ + {Type: "bidder", Name: "bidderA"}, + }, + componentType: []string{"bidder"}, + }, + target: Component{Type: "bidder", Name: "bidderA"}, + activityResult: ActivityAllow, + }, + { + name: "activity_is_not_allowed", + componentRule: ComponentEnforcementRule{ + result: ActivityDeny, + componentName: []Component{ + {Type: "bidder", Name: "bidderA"}, + }, + componentType: []string{"bidder"}, + }, + target: Component{Type: "bidder", Name: "bidderA"}, + activityResult: ActivityDeny, + }, + { + name: "abstain_both_clauses_do_not_match", + componentRule: ComponentEnforcementRule{ + result: ActivityAllow, + componentName: []Component{ + {Type: "bidder", Name: "bidderA"}, + }, + componentType: []string{"bidder"}, + }, + target: Component{Type: "bidder", Name: "bidderB"}, + activityResult: ActivityAbstain, + }, + { + name: "activity_is_not_allowed_componentName_only", + componentRule: ComponentEnforcementRule{ + result: ActivityAllow, + componentName: []Component{ + {Type: "bidder", Name: "bidderA"}, + }, + }, + target: Component{Type: "bidder", Name: "bidderA"}, + activityResult: ActivityAllow, + }, + { + name: "activity_is_allowed_componentType_only", + componentRule: ComponentEnforcementRule{ + result: ActivityAllow, + componentType: []string{"bidder"}, + }, + target: Component{Type: "bidder", Name: "bidderB"}, + activityResult: ActivityAllow, + }, + { + name: "no-conditions-allow", + componentRule: ComponentEnforcementRule{ + result: ActivityAllow, + }, + target: Component{Type: "bidder", Name: "bidderA"}, + activityResult: ActivityAllow, + }, + { + name: "no-conditions-deny", + componentRule: ComponentEnforcementRule{ + result: ActivityDeny, + }, + target: Component{Type: "bidder", Name: "bidderA"}, + activityResult: ActivityDeny, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + actualResult := test.componentRule.Evaluate(test.target) + assert.Equal(t, test.activityResult, actualResult) + + }) + } +} From eac1a6863baff8fb1070f29193290eab3c6ed38a Mon Sep 17 00:00:00 2001 From: Veronika Solovei Date: Mon, 21 Aug 2023 12:38:19 -0700 Subject: [PATCH 086/268] Error message fix (#3041) --- endpoints/openrtb2/video_auction_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/endpoints/openrtb2/video_auction_test.go b/endpoints/openrtb2/video_auction_test.go index 2d74bbe5c12..a32afd24907 100644 --- a/endpoints/openrtb2/video_auction_test.go +++ b/endpoints/openrtb2/video_auction_test.go @@ -75,7 +75,7 @@ func TestVideoEndpointInvalidPrivacyConfig(t *testing.T) { deps.VideoAuctionEndpoint(recorder, req, nil) respBytes := recorder.Body.Bytes() - expectedErrorMessage := "Critical error while running the video endpoint: unable to parse condition: bidderA.BidderB.bidderC" + expectedErrorMessage := "Critical error while running the video endpoint: unable to parse component: bidderA.BidderB.bidderC" assert.Equal(t, expectedErrorMessage, string(respBytes), "error message is incorrect") } From ae46cda864c238143a1c2bb9cbdeff64674efad8 Mon Sep 17 00:00:00 2001 From: SerhiiNahornyi Date: Tue, 22 Aug 2023 15:29:23 +0300 Subject: [PATCH 087/268] Rubicon: Drop stype requirement (#3034) co-authored by @SerhiiNahornyi --- adapters/rubicon/rubicon.go | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/adapters/rubicon/rubicon.go b/adapters/rubicon/rubicon.go index 4c625bd095f..a7ab9ad8f59 100644 --- a/adapters/rubicon/rubicon.go +++ b/adapters/rubicon/rubicon.go @@ -176,12 +176,6 @@ type rubiconUserExtEidExt struct { Segments []string `json:"segments,omitempty"` } -// defines the contract for bidrequest.user.ext.eids[i].uids[j].ext -type rubiconUserExtEidUidExt struct { - RtiPartner string `json:"rtiPartner,omitempty"` - Stype string `json:"stype"` -} - type mappedRubiconUidsParam struct { segments []string liverampIdl string @@ -940,15 +934,7 @@ func extractUserBuyerUID(eids []openrtb2.EID) string { } for _, uid := range eid.UIDs { - var uidExt rubiconUserExtEidUidExt - err := json.Unmarshal(uid.Ext, &uidExt) - if err != nil { - continue - } - - if uidExt.Stype == "ppuid" || uidExt.Stype == "other" { - return uid.ID - } + return uid.ID } } From af7a5b530deb92127516265c92a745a04ab1c697 Mon Sep 17 00:00:00 2001 From: Cadent Aperture MX <43830380+EMXDigital@users.noreply.github.com> Date: Tue, 22 Aug 2023 08:31:43 -0400 Subject: [PATCH 088/268] Cadent Aperture MX Bid Adapter: rename folders & files (#3021) Co-authored-by: Michael Denton --- .../exemplary/banner-and-video-app.json | 4 +- .../exemplary/banner-and-video-site.json | 4 +- .../exemplary/banner-app.json | 0 .../exemplary/minimal-banner.json | 0 .../exemplary/video-app.json | 0 .../exemplary/video-ctv.json | 0 .../exemplary/video-site.json | 0 .../supplemental/add-bidfloor.json | 0 .../app-domain-and-url-correctly-parsed.json | 0 .../app-storeUrl-correctly-parsed.json | 0 .../bad-imp-banner-missing-sizes.json | 0 .../supplemental/bad-imp-ext-tagid-value.json | 0 .../bad-imp-video-missing-mimes.json | 0 .../bad-imp-video-missing-sizes.json | 0 .../supplemental/build-banner-object.json | 0 .../supplemental/build-video-object.json | 0 .../invalid-request-no-banner.json | 0 .../invalid-response-no-bids.json | 0 .../invalid-response-unmarshall-error.json | 0 .../supplemental/no-imps-in-request.json | 0 .../supplemental/server-error-code.json | 0 .../supplemental/server-no-content.json | 0 .../site-domain-and-url-correctly-parsed.json | 0 .../cadentaperturemx.go} | 40 +++++++++---------- .../cadentaperturemx_test.go} | 10 ++--- .../params_test.go | 8 ++-- exchange/adapter_builders.go | 6 +-- ...x_digital.go => imp_cadent_aperture_mx.go} | 2 +- static/bidder-params/emx_digital.json | 2 +- 29 files changed, 38 insertions(+), 38 deletions(-) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/exemplary/banner-and-video-app.json (69%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/exemplary/banner-and-video-site.json (69%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/exemplary/banner-app.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/exemplary/minimal-banner.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/exemplary/video-app.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/exemplary/video-ctv.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/exemplary/video-site.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/supplemental/add-bidfloor.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/supplemental/app-domain-and-url-correctly-parsed.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/supplemental/app-storeUrl-correctly-parsed.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/supplemental/bad-imp-banner-missing-sizes.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/supplemental/bad-imp-ext-tagid-value.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/supplemental/bad-imp-video-missing-mimes.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/supplemental/bad-imp-video-missing-sizes.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/supplemental/build-banner-object.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/supplemental/build-video-object.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/supplemental/invalid-request-no-banner.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/supplemental/invalid-response-no-bids.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/supplemental/invalid-response-unmarshall-error.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/supplemental/no-imps-in-request.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/supplemental/server-error-code.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/supplemental/server-no-content.json (100%) rename adapters/{emx_digital/emx_digitaltest => cadent_aperture_mx/cadent_aperture_mxtest}/supplemental/site-domain-and-url-correctly-parsed.json (100%) rename adapters/{emx_digital/emx_digital.go => cadent_aperture_mx/cadentaperturemx.go} (84%) rename adapters/{emx_digital/emx_digital_test.go => cadent_aperture_mx/cadentaperturemx_test.go} (66%) rename adapters/{emx_digital => cadent_aperture_mx}/params_test.go (75%) rename openrtb_ext/{imp_emx_digital.go => imp_cadent_aperture_mx.go} (72%) diff --git a/adapters/emx_digital/emx_digitaltest/exemplary/banner-and-video-app.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/exemplary/banner-and-video-app.json similarity index 69% rename from adapters/emx_digital/emx_digitaltest/exemplary/banner-and-video-app.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/exemplary/banner-and-video-app.json index 46c469b9d28..255174e2ec1 100644 --- a/adapters/emx_digital/emx_digitaltest/exemplary/banner-and-video-app.json +++ b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/exemplary/banner-and-video-app.json @@ -133,7 +133,7 @@ { "seat": "12356", "bid": [{ - "adm": "
", + "adm": "
", "id": "some_test_ad_id_1", "impid": "some_test_ad_id_1", "ttl": 300, @@ -168,7 +168,7 @@ { "bids": [{ "bid": { - "adm": "
", + "adm": "
", "id": "some_test_ad_id_1", "impid": "some_test_ad_id_1", "crid": "94395500", diff --git a/adapters/emx_digital/emx_digitaltest/exemplary/banner-and-video-site.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/exemplary/banner-and-video-site.json similarity index 69% rename from adapters/emx_digital/emx_digitaltest/exemplary/banner-and-video-site.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/exemplary/banner-and-video-site.json index f47fd66784e..1ea0397fced 100644 --- a/adapters/emx_digital/emx_digitaltest/exemplary/banner-and-video-site.json +++ b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/exemplary/banner-and-video-site.json @@ -136,7 +136,7 @@ "seatbid": [{ "seat": "12356", "bid": [{ - "adm": "
", + "adm": "
", "id": "some_test_ad_id_1", "impid": "some_test_ad_id_1", "ttl": 300, @@ -170,7 +170,7 @@ "expectedBidResponses": [{ "bids": [{ "bid": { - "adm": "
", + "adm": "
", "id": "some_test_ad_id_1", "impid": "some_test_ad_id_1", "crid": "94395500", diff --git a/adapters/emx_digital/emx_digitaltest/exemplary/banner-app.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/exemplary/banner-app.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/exemplary/banner-app.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/exemplary/banner-app.json diff --git a/adapters/emx_digital/emx_digitaltest/exemplary/minimal-banner.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/exemplary/minimal-banner.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/exemplary/minimal-banner.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/exemplary/minimal-banner.json diff --git a/adapters/emx_digital/emx_digitaltest/exemplary/video-app.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/exemplary/video-app.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/exemplary/video-app.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/exemplary/video-app.json diff --git a/adapters/emx_digital/emx_digitaltest/exemplary/video-ctv.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/exemplary/video-ctv.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/exemplary/video-ctv.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/exemplary/video-ctv.json diff --git a/adapters/emx_digital/emx_digitaltest/exemplary/video-site.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/exemplary/video-site.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/exemplary/video-site.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/exemplary/video-site.json diff --git a/adapters/emx_digital/emx_digitaltest/supplemental/add-bidfloor.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/add-bidfloor.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/supplemental/add-bidfloor.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/add-bidfloor.json diff --git a/adapters/emx_digital/emx_digitaltest/supplemental/app-domain-and-url-correctly-parsed.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/app-domain-and-url-correctly-parsed.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/supplemental/app-domain-and-url-correctly-parsed.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/app-domain-and-url-correctly-parsed.json diff --git a/adapters/emx_digital/emx_digitaltest/supplemental/app-storeUrl-correctly-parsed.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/app-storeUrl-correctly-parsed.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/supplemental/app-storeUrl-correctly-parsed.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/app-storeUrl-correctly-parsed.json diff --git a/adapters/emx_digital/emx_digitaltest/supplemental/bad-imp-banner-missing-sizes.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/bad-imp-banner-missing-sizes.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/supplemental/bad-imp-banner-missing-sizes.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/bad-imp-banner-missing-sizes.json diff --git a/adapters/emx_digital/emx_digitaltest/supplemental/bad-imp-ext-tagid-value.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/bad-imp-ext-tagid-value.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/supplemental/bad-imp-ext-tagid-value.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/bad-imp-ext-tagid-value.json diff --git a/adapters/emx_digital/emx_digitaltest/supplemental/bad-imp-video-missing-mimes.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/bad-imp-video-missing-mimes.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/supplemental/bad-imp-video-missing-mimes.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/bad-imp-video-missing-mimes.json diff --git a/adapters/emx_digital/emx_digitaltest/supplemental/bad-imp-video-missing-sizes.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/bad-imp-video-missing-sizes.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/supplemental/bad-imp-video-missing-sizes.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/bad-imp-video-missing-sizes.json diff --git a/adapters/emx_digital/emx_digitaltest/supplemental/build-banner-object.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/build-banner-object.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/supplemental/build-banner-object.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/build-banner-object.json diff --git a/adapters/emx_digital/emx_digitaltest/supplemental/build-video-object.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/build-video-object.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/supplemental/build-video-object.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/build-video-object.json diff --git a/adapters/emx_digital/emx_digitaltest/supplemental/invalid-request-no-banner.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/invalid-request-no-banner.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/supplemental/invalid-request-no-banner.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/invalid-request-no-banner.json diff --git a/adapters/emx_digital/emx_digitaltest/supplemental/invalid-response-no-bids.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/invalid-response-no-bids.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/supplemental/invalid-response-no-bids.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/invalid-response-no-bids.json diff --git a/adapters/emx_digital/emx_digitaltest/supplemental/invalid-response-unmarshall-error.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/invalid-response-unmarshall-error.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/supplemental/invalid-response-unmarshall-error.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/invalid-response-unmarshall-error.json diff --git a/adapters/emx_digital/emx_digitaltest/supplemental/no-imps-in-request.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/no-imps-in-request.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/supplemental/no-imps-in-request.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/no-imps-in-request.json diff --git a/adapters/emx_digital/emx_digitaltest/supplemental/server-error-code.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/server-error-code.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/supplemental/server-error-code.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/server-error-code.json diff --git a/adapters/emx_digital/emx_digitaltest/supplemental/server-no-content.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/server-no-content.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/supplemental/server-no-content.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/server-no-content.json diff --git a/adapters/emx_digital/emx_digitaltest/supplemental/site-domain-and-url-correctly-parsed.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/site-domain-and-url-correctly-parsed.json similarity index 100% rename from adapters/emx_digital/emx_digitaltest/supplemental/site-domain-and-url-correctly-parsed.json rename to adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/site-domain-and-url-correctly-parsed.json diff --git a/adapters/emx_digital/emx_digital.go b/adapters/cadent_aperture_mx/cadentaperturemx.go similarity index 84% rename from adapters/emx_digital/emx_digital.go rename to adapters/cadent_aperture_mx/cadentaperturemx.go index 1b38263c6ff..5df000bf547 100644 --- a/adapters/emx_digital/emx_digital.go +++ b/adapters/cadent_aperture_mx/cadentaperturemx.go @@ -1,4 +1,4 @@ -package emx_digital +package cadentaperturemx import ( "encoding/json" @@ -17,7 +17,7 @@ import ( "github.com/prebid/prebid-server/openrtb_ext" ) -type EmxDigitalAdapter struct { +type adapter struct { endpoint string testing bool } @@ -33,7 +33,7 @@ func buildEndpoint(endpoint string, testing bool, timeout int64) string { return endpoint + "?t=" + strconv.FormatInt(timeout, 10) + "&ts=" + strconv.FormatInt(time.Now().Unix(), 10) + "&src=pbserver" } -func (a *EmxDigitalAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { var errs []error if len(request.Imp) == 0 { @@ -81,7 +81,7 @@ func (a *EmxDigitalAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo * }}, errs } -func unpackImpExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpEmxDigital, error) { +func unpackImpExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpCadentApertureMX, error) { var bidderExt adapters.ExtImpBidder if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ @@ -89,27 +89,27 @@ func unpackImpExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpEmxDigital, error) { } } - var emxExt openrtb_ext.ExtImpEmxDigital - if err := json.Unmarshal(bidderExt.Bidder, &emxExt); err != nil { + var cadentExt openrtb_ext.ExtImpCadentApertureMX + if err := json.Unmarshal(bidderExt.Bidder, &cadentExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("ignoring imp id=%s, invalid ImpExt", imp.ID), } } - tagIDValidation, err := strconv.ParseInt(emxExt.TagID, 10, 64) + tagIDValidation, err := strconv.ParseInt(cadentExt.TagID, 10, 64) if err != nil || tagIDValidation == 0 { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("ignoring imp id=%s, invalid tagid must be a String of numbers", imp.ID), } } - if emxExt.TagID == "" { + if cadentExt.TagID == "" { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("Ignoring imp id=%s, no tagid present", imp.ID), } } - return &emxExt, nil + return &cadentExt, nil } func buildImpBanner(imp *openrtb2.Imp) error { @@ -175,13 +175,13 @@ func cleanProtocol(protocols []adcom1.MediaCreativeSubtype) []adcom1.MediaCreati return newitems } -// Add EMX required properties to Imp object -func addImpProps(imp *openrtb2.Imp, secure *int8, emxExt *openrtb_ext.ExtImpEmxDigital) { - imp.TagID = emxExt.TagID +// Add Cadent required properties to Imp object +func addImpProps(imp *openrtb2.Imp, secure *int8, cadentExt *openrtb_ext.ExtImpCadentApertureMX) { + imp.TagID = cadentExt.TagID imp.Secure = secure - if emxExt.BidFloor != "" { - bidFloor, err := strconv.ParseFloat(emxExt.BidFloor, 64) + if cadentExt.BidFloor != "" { + bidFloor, err := strconv.ParseFloat(cadentExt.BidFloor, 64) if err != nil { bidFloor = 0 } @@ -202,7 +202,7 @@ func addHeaderIfNonEmpty(headers http.Header, headerName string, headerValue str } } -// Handle request errors and formatting to be sent to EMX +// Handle request errors and formatting to be sent to Cadent func preprocess(request *openrtb2.BidRequest) []error { impsCount := len(request.Imp) errors := make([]error, 0, impsCount) @@ -225,13 +225,13 @@ func preprocess(request *openrtb2.BidRequest) []error { } for _, imp := range request.Imp { - emxExt, err := unpackImpExt(&imp) + cadentExt, err := unpackImpExt(&imp) if err != nil { errors = append(errors, err) continue } - addImpProps(&imp, &secure, emxExt) + addImpProps(&imp, &secure, cadentExt) if imp.Video != nil { if err := buildImpVideo(&imp); err != nil { @@ -253,7 +253,7 @@ func preprocess(request *openrtb2.BidRequest) []error { } // MakeBids make the bids for the bid response. -func (a *EmxDigitalAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { +func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { if response.StatusCode == http.StatusNoContent { // no bid response @@ -309,9 +309,9 @@ func ContainsAny(raw string, keys []string) bool { } -// Builder builds a new instance of the EmxDigital adapter for the given bidder with the given config. +// Builder builds a new instance of the Cadent Aperture MX adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { - bidder := &EmxDigitalAdapter{ + bidder := &adapter{ endpoint: config.Endpoint, testing: false, } diff --git a/adapters/emx_digital/emx_digital_test.go b/adapters/cadent_aperture_mx/cadentaperturemx_test.go similarity index 66% rename from adapters/emx_digital/emx_digital_test.go rename to adapters/cadent_aperture_mx/cadentaperturemx_test.go index 6538ff70efa..60034322797 100644 --- a/adapters/emx_digital/emx_digital_test.go +++ b/adapters/cadent_aperture_mx/cadentaperturemx_test.go @@ -1,4 +1,4 @@ -package emx_digital +package cadentaperturemx import ( "testing" @@ -10,7 +10,7 @@ import ( ) func TestJsonSamples(t *testing.T) { - bidder, buildErr := Builder(openrtb_ext.BidderEmxDigital, config.Adapter{ + bidder, buildErr := Builder(openrtb_ext.BidderCadentApertureMX, config.Adapter{ Endpoint: "https://hb.emxdgt.com"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) if buildErr != nil { @@ -18,10 +18,10 @@ func TestJsonSamples(t *testing.T) { } setTesting(bidder) - adapterstest.RunJSONBidderTest(t, "emx_digitaltest", bidder) + adapterstest.RunJSONBidderTest(t, "cadent_aperture_mxtest", bidder) } func setTesting(bidder adapters.Bidder) { - bidderEmxDigital, _ := bidder.(*EmxDigitalAdapter) - bidderEmxDigital.testing = true + bidderCadentApertureMX, _ := bidder.(*adapter) + bidderCadentApertureMX.testing = true } diff --git a/adapters/emx_digital/params_test.go b/adapters/cadent_aperture_mx/params_test.go similarity index 75% rename from adapters/emx_digital/params_test.go rename to adapters/cadent_aperture_mx/params_test.go index 49ad9eb1a9c..b5b7355376f 100644 --- a/adapters/emx_digital/params_test.go +++ b/adapters/cadent_aperture_mx/params_test.go @@ -1,4 +1,4 @@ -package emx_digital +package cadentaperturemx import ( "encoding/json" @@ -14,8 +14,8 @@ func TestValidParams(t *testing.T) { } for _, validParam := range validParams { - if err := validator.Validate(openrtb_ext.BidderEmxDigital, json.RawMessage(validParam)); err != nil { - t.Errorf("Schema rejected emx_digital params: %s", validParam) + if err := validator.Validate(openrtb_ext.BidderCadentApertureMX, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected cadent_aperture_mx params: %s", validParam) } } } @@ -27,7 +27,7 @@ func TestInvalidParams(t *testing.T) { } for _, invalidParam := range invalidParams { - if err := validator.Validate(openrtb_ext.BidderEmxDigital, json.RawMessage(invalidParam)); err == nil { + if err := validator.Validate(openrtb_ext.BidderCadentApertureMX, json.RawMessage(invalidParam)); err == nil { t.Errorf("Schema allowed unexpected params: %s", invalidParam) } } diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 712c23d0786..5c3cb39ecda 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -56,6 +56,7 @@ import ( "github.com/prebid/prebid-server/adapters/bmtm" "github.com/prebid/prebid-server/adapters/boldwin" "github.com/prebid/prebid-server/adapters/brave" + cadentaperturemx "github.com/prebid/prebid-server/adapters/cadent_aperture_mx" "github.com/prebid/prebid-server/adapters/ccx" "github.com/prebid/prebid-server/adapters/coinzilla" "github.com/prebid/prebid-server/adapters/colossus" @@ -74,7 +75,6 @@ import ( "github.com/prebid/prebid-server/adapters/dmx" evolution "github.com/prebid/prebid-server/adapters/e_volution" "github.com/prebid/prebid-server/adapters/emtv" - "github.com/prebid/prebid-server/adapters/emx_digital" "github.com/prebid/prebid-server/adapters/engagebdr" "github.com/prebid/prebid-server/adapters/eplanning" "github.com/prebid/prebid-server/adapters/epom" @@ -248,7 +248,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderBmtm: bmtm.Builder, openrtb_ext.BidderBoldwin: boldwin.Builder, openrtb_ext.BidderBrave: brave.Builder, - openrtb_ext.BidderCadentApertureMX: emx_digital.Builder, + openrtb_ext.BidderCadentApertureMX: cadentaperturemx.Builder, openrtb_ext.BidderCcx: ccx.Builder, openrtb_ext.BidderCoinzilla: coinzilla.Builder, openrtb_ext.BidderColossus: colossus.Builder, @@ -267,7 +267,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderDianomi: dianomi.Builder, openrtb_ext.BidderDmx: dmx.Builder, openrtb_ext.BidderEmtv: emtv.Builder, - openrtb_ext.BidderEmxDigital: emx_digital.Builder, + openrtb_ext.BidderEmxDigital: cadentaperturemx.Builder, openrtb_ext.BidderEngageBDR: engagebdr.Builder, openrtb_ext.BidderEPlanning: eplanning.Builder, openrtb_ext.BidderEpom: epom.Builder, diff --git a/openrtb_ext/imp_emx_digital.go b/openrtb_ext/imp_cadent_aperture_mx.go similarity index 72% rename from openrtb_ext/imp_emx_digital.go rename to openrtb_ext/imp_cadent_aperture_mx.go index 5c5956b1fc1..fc4280ff491 100644 --- a/openrtb_ext/imp_emx_digital.go +++ b/openrtb_ext/imp_cadent_aperture_mx.go @@ -1,6 +1,6 @@ package openrtb_ext -type ExtImpEmxDigital struct { +type ExtImpCadentApertureMX struct { TagID string `json:"tagid"` BidFloor string `json:"bidfloor,omitempty"` } diff --git a/static/bidder-params/emx_digital.json b/static/bidder-params/emx_digital.json index f7516f57e63..42c243a9f4f 100644 --- a/static/bidder-params/emx_digital.json +++ b/static/bidder-params/emx_digital.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", "title": "EMX Digital Adapter Params", - "description": "A schema which validates params accepted by the EMX Digital adapter", + "description": "A schema which validates params accepted by the Cadent Aperture MX adapter", "type": "object", "properties": { "tagid" : { From e0999b8ef1db3c9e8dffde915de4ec0b355e6232 Mon Sep 17 00:00:00 2001 From: Kamil Mikolajczyk <125450079+kamilmclearcode@users.noreply.github.com> Date: Tue, 22 Aug 2023 14:35:15 +0200 Subject: [PATCH 089/268] New adapter: Adquery (#3020) co-authored by: @kamilmclearcode --- adapters/adquery/adquery.go | 207 ++++++++++++++++ adapters/adquery/adquery_test.go | 20 ++ .../adquery/adquerytest/exemplary/empty.json | 12 + .../adquerytest/exemplary/many-imps.json | 227 ++++++++++++++++++ .../adquerytest/exemplary/no-currency.json | 123 ++++++++++ .../adquery/adquerytest/exemplary/ok.json | 124 ++++++++++ .../exemplary/single-imp-banner-format.json | 115 +++++++++ .../adquerytest/supplemental/data-null.json | 72 ++++++ .../invalid-numerical-values.json | 114 +++++++++ .../supplemental/malformed-ext.json | 38 +++ .../supplemental/malformed-resp.json | 108 +++++++++ .../supplemental/mediatype-unknown.json | 108 +++++++++ .../supplemental/mediatype-video.json | 108 +++++++++ .../supplemental/no-imp-banner-measures.json | 61 +++++ .../supplemental/no-imp-banner.json | 60 +++++ .../supplemental/resp-bad-request.json | 68 ++++++ .../supplemental/resp-no-content.json | 66 +++++ .../supplemental/resp-server-error.json | 68 ++++++ adapters/adquery/params_test.go | 49 ++++ adapters/adquery/types.go | 42 ++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_adquery.go | 6 + static/bidder-info/adquery.yaml | 16 ++ static/bidder-params/adquery.json | 22 ++ 25 files changed, 1838 insertions(+) create mode 100644 adapters/adquery/adquery.go create mode 100644 adapters/adquery/adquery_test.go create mode 100644 adapters/adquery/adquerytest/exemplary/empty.json create mode 100644 adapters/adquery/adquerytest/exemplary/many-imps.json create mode 100644 adapters/adquery/adquerytest/exemplary/no-currency.json create mode 100644 adapters/adquery/adquerytest/exemplary/ok.json create mode 100644 adapters/adquery/adquerytest/exemplary/single-imp-banner-format.json create mode 100644 adapters/adquery/adquerytest/supplemental/data-null.json create mode 100644 adapters/adquery/adquerytest/supplemental/invalid-numerical-values.json create mode 100644 adapters/adquery/adquerytest/supplemental/malformed-ext.json create mode 100644 adapters/adquery/adquerytest/supplemental/malformed-resp.json create mode 100644 adapters/adquery/adquerytest/supplemental/mediatype-unknown.json create mode 100644 adapters/adquery/adquerytest/supplemental/mediatype-video.json create mode 100644 adapters/adquery/adquerytest/supplemental/no-imp-banner-measures.json create mode 100644 adapters/adquery/adquerytest/supplemental/no-imp-banner.json create mode 100644 adapters/adquery/adquerytest/supplemental/resp-bad-request.json create mode 100644 adapters/adquery/adquerytest/supplemental/resp-no-content.json create mode 100644 adapters/adquery/adquerytest/supplemental/resp-server-error.json create mode 100644 adapters/adquery/params_test.go create mode 100644 adapters/adquery/types.go create mode 100644 openrtb_ext/imp_adquery.go create mode 100644 static/bidder-info/adquery.yaml create mode 100644 static/bidder-params/adquery.json diff --git a/adapters/adquery/adquery.go b/adapters/adquery/adquery.go new file mode 100644 index 00000000000..6a7dafa0ccb --- /dev/null +++ b/adapters/adquery/adquery.go @@ -0,0 +1,207 @@ +package adquery + +import ( + "encoding/json" + "fmt" + "net/http" + "regexp" + "strconv" + "strings" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/openrtb_ext" +) + +const ( + defaultCurrency string = "PLN" + bidderName string = "adquery" + prebidVersion string = "server" +) + +type adapter struct { + endpoint string +} + +// Builder builds a new instance of the Adquery adapter for the given bidder with the given config. +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, _ *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + headers.Add("x-openrtb-version", "2.5") + + var result []*adapters.RequestData + var errs []error + for _, imp := range request.Imp { + ext, err := parseExt(imp.Ext) + if err != nil { + errs = append(errs, &errortypes.BadInput{err.Error()}) + continue + } + + requestJSON, err := json.Marshal(buildRequest(request, &imp, ext)) + if err != nil { + return nil, append(errs, err) + } + + data := &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: requestJSON, + Headers: headers, + } + result = append(result, data) + } + + return result, errs +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + err := adapters.CheckResponseStatusCodeForErrors(responseData) + if err != nil { + return nil, []error{err} + } + + respData, price, width, height, errs := parseResponseJson(responseData.Body) + if len(errs) > 0 { + return nil, errs + } + + if respData == nil { + return adapters.NewBidderResponse(), nil + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(1) + if respData.Currency != "" { + bidResponse.Currency = respData.Currency + } else { + bidResponse.Currency = defaultCurrency + } + + var bidReqIdRegex = regexp.MustCompile(`^` + request.ID) + impId := bidReqIdRegex.ReplaceAllLiteralString(respData.ReqID, "") + + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &openrtb2.Bid{ + // There's much more possible fields to be added here, see OpenRTB docs for reference (type: Bid) + ID: respData.ReqID, + ImpID: impId, + Price: price, + AdM: fmt.Sprintf("%s", respData.AdQLib, respData.Tag), + ADomain: respData.ADomains, + CrID: fmt.Sprintf("%d", respData.CrID), + W: width, + H: height, + }, + BidType: respData.MediaType.Name, + }) + + return bidResponse, nil +} + +func buildRequest(bidReq *openrtb2.BidRequest, imp *openrtb2.Imp, ext *openrtb_ext.ImpExtAdQuery) *BidderRequest { + userId := "" + if bidReq.User != nil { + userId = bidReq.User.ID + } + + return &BidderRequest{ + V: prebidVersion, + PlacementCode: ext.PlacementID, + AuctionId: "", + BidType: ext.Type, + AdUnitCode: imp.TagID, + BidQid: userId, + BidId: fmt.Sprintf("%s%s", bidReq.ID, imp.ID), + Bidder: bidderName, + BidderRequestId: bidReq.ID, + BidRequestsCount: 1, + BidderRequestsCount: 1, + Sizes: getImpSizes(imp), + } +} + +func parseExt(ext json.RawMessage) (*openrtb_ext.ImpExtAdQuery, error) { + var bext adapters.ExtImpBidder + err := json.Unmarshal(ext, &bext) + if err != nil { + return nil, err + } + + var adsExt openrtb_ext.ImpExtAdQuery + err = json.Unmarshal(bext.Bidder, &adsExt) + if err != nil { + return nil, err + } + + // not validating, because it should have been done earlier by the server + return &adsExt, nil +} + +func parseResponseJson(respBody []byte) (*ResponseData, float64, int64, int64, []error) { + var response ResponseAdQuery + if err := json.Unmarshal(respBody, &response); err != nil { + return nil, 0, 0, 0, []error{err} + } + + if response.Data == nil { + return nil, 0, 0, 0, nil + } + + var errs []error + price, err := strconv.ParseFloat(response.Data.CPM, 64) + if err != nil { + errs = append(errs, err) + } + width, err := strconv.ParseInt(response.Data.MediaType.Width, 10, 64) + if err != nil { + errs = append(errs, err) + } + height, err := strconv.ParseInt(response.Data.MediaType.Height, 10, 64) + if err != nil { + errs = append(errs, err) + } + + if response.Data.MediaType.Name != openrtb_ext.BidTypeBanner { + return nil, 0, 0, 0, []error{fmt.Errorf("unsupported MediaType: %s", response.Data.MediaType.Name)} + } + + if len(errs) > 0 { + return nil, 0, 0, 0, errs + } + return response.Data, price, width, height, nil +} + +func getImpSizes(imp *openrtb2.Imp) string { + if imp.Banner == nil { + return "" + } + + if len(imp.Banner.Format) > 0 { + sizes := make([]string, len(imp.Banner.Format)) + for i, format := range imp.Banner.Format { + sizes[i] = strconv.FormatInt(format.W, 10) + "x" + strconv.FormatInt(format.H, 10) + } + + return strings.Join(sizes, ",") + } + + if imp.Banner.W != nil && imp.Banner.H != nil { + return strconv.FormatInt(*imp.Banner.W, 10) + "x" + strconv.FormatInt(*imp.Banner.H, 10) + } + + return "" +} diff --git a/adapters/adquery/adquery_test.go b/adapters/adquery/adquery_test.go new file mode 100644 index 00000000000..228d835d6c4 --- /dev/null +++ b/adapters/adquery/adquery_test.go @@ -0,0 +1,20 @@ +package adquery + +import ( + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" + "testing" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderAdquery, config.Adapter{ + Endpoint: "https://bidder.adquery.io/prebid/bid"}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 902, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "adquerytest", bidder) +} diff --git a/adapters/adquery/adquerytest/exemplary/empty.json b/adapters/adquery/adquerytest/exemplary/empty.json new file mode 100644 index 00000000000..04f1d21bcab --- /dev/null +++ b/adapters/adquery/adquerytest/exemplary/empty.json @@ -0,0 +1,12 @@ +{ + "mockBidRequest": { + "id": "22e26bd9a702bc", + "user": { + "id": "xyz" + }, + "imp": [], + "bidder": "adquery" + }, + "httpCalls": [], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/adquery/adquerytest/exemplary/many-imps.json b/adapters/adquery/adquerytest/exemplary/many-imps.json new file mode 100644 index 00000000000..a3985c87dc1 --- /dev/null +++ b/adapters/adquery/adquerytest/exemplary/many-imps.json @@ -0,0 +1,227 @@ +{ + "mockBidRequest": { + "id": "22e26bd9a702bc", + "user": { + "id": "d93f2a0e5f0fe2cc3a6e" + }, + "imp": [ + { + "id": "1", + "tagid": "test-banner-imp-id", + "bidder": "adquery", + "banner": { + "format": [ + { + "w": 320, + "h": 100 + }, + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } + } + },{ + "id": "2", + "tagid": "test-banner-imp-id-2", + "bidder": "adquery", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f898", + "type": "banner" + } + } + } + ], + "bidder": "adquery" + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bidder.adquery.io/prebid/bid", + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"], + "X-Openrtb-Version": ["2.5"] + }, + "body": { + "adUnitCode": "test-banner-imp-id", + "bidId": "22e26bd9a702bc1", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidPageUrl": "", + "bidder": "adquery", + "bidderRequestId": "22e26bd9a702bc", + "bidRequestsCount": 1, + "bidderRequestsCount": 1, + "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "sizes": "320x100,300x250", + "type": "banner", + "v": "server" + } + }, + "mockResponse": { + "status": 200, + "headers": {}, + "body": { + "data": { + "requestId": "22e26bd9a702bc1", + "emission_id": "22e26bd9a702bc1", + "eventTracker": "https://bidder.adquery.io/prebid/ev/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "externalEmissionCodes": "", + "impressionTracker": "https://bidder.adquery.io/prebid/im/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "viewabilityTracker": "https://bidder.adquery.io/prebid/vi/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "clickTracker": "https://bidder.adquery.io/prebid/cl/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?url=https%3A%2F%2Fbrodacid.pl%2F%3Futm_source%3Dmobile_open%26utm_medium%3Dcpc%26utm_campaign%3Dhi2023", + "link": "https://brodacid.pl/?utm_source=mobile_open&utm_medium=cpc&utm_campaign=hi2023", + "logo": "https://api.adquery.io/img/adquery.png", + "medias": [ + { + "src": "banner/2023-06-05/17591", + "ext": "zip", + "type": 3 + } + ], + "domain": "https://bidder.adquery.io", + "urlAdq": "https://adquery.io", + "creationId": 7211, + "currency": "EUR", + "adDomains": [ + "https://s1.adquery.io" + ], + "tag": " ", + "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", + "mediaType": { + "width": "320", + "height": "50", + "name": "banner", + "type": "banner320x50" + }, + "cpm": "4.14", + "qid": "fc08aacb07eac44421ed", + "width": "320", + "height": "50", + "isExpand": false + } + } + } + },{ + "expectedRequest": { + "uri": "https://bidder.adquery.io/prebid/bid", + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"], + "X-Openrtb-Version": ["2.5"] + }, + "body": { + "adUnitCode": "test-banner-imp-id-2", + "bidId": "22e26bd9a702bc2", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidPageUrl": "", + "bidder": "adquery", + "bidderRequestId": "22e26bd9a702bc", + "bidRequestsCount": 1, + "bidderRequestsCount": 1, + "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f898", + "sizes": "300x250", + "type": "banner", + "v": "server" + } + }, + "mockResponse": { + "status": 200, + "headers": {}, + "body": { + "data": { + "requestId": "22e26bd9a702bc2", + "emission_id": "22e26bd9a702bc2", + "eventTracker": "https://bidder.adquery.io/prebid/ev/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "externalEmissionCodes": "", + "impressionTracker": "https://bidder.adquery.io/prebid/im/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "viewabilityTracker": "https://bidder.adquery.io/prebid/vi/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "clickTracker": "https://bidder.adquery.io/prebid/cl/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?url=https%3A%2F%2Fbrodacid.pl%2F%3Futm_source%3Dmobile_open%26utm_medium%3Dcpc%26utm_campaign%3Dhi2023", + "link": "https://brodacid.pl/?utm_source=mobile_open&utm_medium=cpc&utm_campaign=hi2023", + "logo": "https://api.adquery.io/img/adquery.png", + "medias": [ + { + "src": "banner/2023-06-05/17591", + "ext": "zip", + "type": 3 + } + ], + "domain": "https://bidder.adquery.io", + "urlAdq": "https://adquery.io", + "creationId": 7211, + "currency": "EUR", + "adDomains": [ + "https://s1.adquery.io" + ], + "tag": " ", + "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", + "mediaType": { + "width": "320", + "height": "50", + "name": "banner", + "type": "banner320x50" + }, + "cpm": "4.14", + "qid": "fc08aacb07eac44421ed", + "width": "320", + "height": "50", + "isExpand": false + } + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "22e26bd9a702bc1", + "impid": "1", + "price": 4.14, + "adm": " ", + "adomain": ["https://s1.adquery.io"], + "crid": "7211", + "w": 320, + "h": 50 + }, + "type": "banner" + } + ] + }, + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "22e26bd9a702bc2", + "impid": "2", + "price": 4.14, + "adm": " ", + "adomain": ["https://s1.adquery.io"], + "crid": "7211", + "w": 320, + "h": 50 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/adquery/adquerytest/exemplary/no-currency.json b/adapters/adquery/adquerytest/exemplary/no-currency.json new file mode 100644 index 00000000000..e97e4b9beaa --- /dev/null +++ b/adapters/adquery/adquerytest/exemplary/no-currency.json @@ -0,0 +1,123 @@ +{ + "mockBidRequest": { + "id": "22e26bd9a702bc", + "user": { + "id": "d93f2a0e5f0fe2cc3a6e" + }, + "imp": [ + { + "id": "1", + "tagid": "test-banner-imp-id", + "bidder": "adquery", + "banner": { + "format": [ + { + "w": 320, + "h": 100 + }, + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } + } + } + ], + "bidder": "adquery" + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bidder.adquery.io/prebid/bid", + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"], + "X-Openrtb-Version": ["2.5"] + }, + "body": { + "adUnitCode": "test-banner-imp-id", + "bidId": "22e26bd9a702bc1", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidPageUrl": "", + "bidder": "adquery", + "bidderRequestId": "22e26bd9a702bc", + "bidRequestsCount": 1, + "bidderRequestsCount": 1, + "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "sizes": "320x100,300x250", + "type": "banner", + "v": "server" + } + }, + "mockResponse": { + "status": 200, + "headers": {}, + "body": { + "data": { + "requestId": "22e26bd9a702bc1", + "emission_id": "22e26bd9a702bc1", + "eventTracker": "https://bidder.adquery.io/prebid/ev/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "externalEmissionCodes": "", + "impressionTracker": "https://bidder.adquery.io/prebid/im/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "viewabilityTracker": "https://bidder.adquery.io/prebid/vi/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "clickTracker": "https://bidder.adquery.io/prebid/cl/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?url=https%3A%2F%2Fbrodacid.pl%2F%3Futm_source%3Dmobile_open%26utm_medium%3Dcpc%26utm_campaign%3Dhi2023", + "link": "https://brodacid.pl/?utm_source=mobile_open&utm_medium=cpc&utm_campaign=hi2023", + "logo": "https://api.adquery.io/img/adquery.png", + "medias": [ + { + "src": "banner/2023-06-05/17591", + "ext": "zip", + "type": 3 + } + ], + "domain": "https://bidder.adquery.io", + "urlAdq": "https://adquery.io", + "creationId": 7211, + "adDomains": [ + "https://s1.adquery.io" + ], + "tag": " ", + "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", + "mediaType": { + "width": "320", + "height": "50", + "name": "banner", + "type": "banner320x50" + }, + "cpm": "4.14", + "qid": "fc08aacb07eac44421ed", + "width": "320", + "height": "50", + "isExpand": false + } + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "PLN", + "bids": [ + { + "bid": { + "id": "22e26bd9a702bc1", + "impid": "1", + "price": 4.14, + "adm": " ", + "adomain": ["https://s1.adquery.io"], + "crid": "7211", + "w": 320, + "h": 50 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/adquery/adquerytest/exemplary/ok.json b/adapters/adquery/adquerytest/exemplary/ok.json new file mode 100644 index 00000000000..e725e055293 --- /dev/null +++ b/adapters/adquery/adquerytest/exemplary/ok.json @@ -0,0 +1,124 @@ +{ + "mockBidRequest": { + "id": "22e26bd9a702bc", + "user": { + "id": "d93f2a0e5f0fe2cc3a6e" + }, + "imp": [ + { + "id": "1", + "tagid": "test-banner-imp-id", + "bidder": "adquery", + "banner": { + "format": [ + { + "w": 320, + "h": 100 + }, + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } + } + } + ], + "bidder": "adquery" + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bidder.adquery.io/prebid/bid", + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"], + "X-Openrtb-Version": ["2.5"] + }, + "body": { + "adUnitCode": "test-banner-imp-id", + "bidId": "22e26bd9a702bc1", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidPageUrl": "", + "bidder": "adquery", + "bidderRequestId": "22e26bd9a702bc", + "bidRequestsCount": 1, + "bidderRequestsCount": 1, + "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "sizes": "320x100,300x250", + "type": "banner", + "v": "server" + } + }, + "mockResponse": { + "status": 200, + "headers": {}, + "body": { + "data": { + "requestId": "22e26bd9a702bc1", + "emission_id": "22e26bd9a702bc1", + "eventTracker": "https://bidder.adquery.io/prebid/ev/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "externalEmissionCodes": "", + "impressionTracker": "https://bidder.adquery.io/prebid/im/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "viewabilityTracker": "https://bidder.adquery.io/prebid/vi/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "clickTracker": "https://bidder.adquery.io/prebid/cl/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?url=https%3A%2F%2Fbrodacid.pl%2F%3Futm_source%3Dmobile_open%26utm_medium%3Dcpc%26utm_campaign%3Dhi2023", + "link": "https://brodacid.pl/?utm_source=mobile_open&utm_medium=cpc&utm_campaign=hi2023", + "logo": "https://api.adquery.io/img/adquery.png", + "medias": [ + { + "src": "banner/2023-06-05/17591", + "ext": "zip", + "type": 3 + } + ], + "domain": "https://bidder.adquery.io", + "urlAdq": "https://adquery.io", + "creationId": 7211, + "currency": "EUR", + "adDomains": [ + "https://s1.adquery.io" + ], + "tag": " ", + "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", + "mediaType": { + "width": "320", + "height": "50", + "name": "banner", + "type": "banner320x50" + }, + "cpm": "4.14", + "qid": "fc08aacb07eac44421ed", + "width": "320", + "height": "50", + "isExpand": false + } + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "22e26bd9a702bc1", + "impid": "1", + "price": 4.14, + "adm": " ", + "adomain": ["https://s1.adquery.io"], + "crid": "7211", + "w": 320, + "h": 50 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/adquery/adquerytest/exemplary/single-imp-banner-format.json b/adapters/adquery/adquerytest/exemplary/single-imp-banner-format.json new file mode 100644 index 00000000000..7a0092d5f5a --- /dev/null +++ b/adapters/adquery/adquerytest/exemplary/single-imp-banner-format.json @@ -0,0 +1,115 @@ +{ + "mockBidRequest": { + "id": "22e26bd9a702bc", + "user": { + "id": "d93f2a0e5f0fe2cc3a6e" + }, + "imp": [ + { + "id": "1", + "tagid": "test-banner-imp-id", + "bidder": "adquery", + "banner": { + "w": 320, + "h": 100 + }, + "ext": { + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } + } + } + ], + "bidder": "adquery" + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bidder.adquery.io/prebid/bid", + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"], + "X-Openrtb-Version": ["2.5"] + }, + "body": { + "adUnitCode": "test-banner-imp-id", + "bidId": "22e26bd9a702bc1", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidPageUrl": "", + "bidder": "adquery", + "bidderRequestId": "22e26bd9a702bc", + "bidRequestsCount": 1, + "bidderRequestsCount": 1, + "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "sizes": "320x100", + "type": "banner", + "v": "server" + } + }, + "mockResponse": { + "status": 200, + "headers": {}, + "body": { + "data": { + "requestId": "22e26bd9a702bc1", + "emission_id": "22e26bd9a702bc1", + "eventTracker": "https://bidder.adquery.io/prebid/ev/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "externalEmissionCodes": "", + "impressionTracker": "https://bidder.adquery.io/prebid/im/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "viewabilityTracker": "https://bidder.adquery.io/prebid/vi/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "clickTracker": "https://bidder.adquery.io/prebid/cl/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?url=https%3A%2F%2Fbrodacid.pl%2F%3Futm_source%3Dmobile_open%26utm_medium%3Dcpc%26utm_campaign%3Dhi2023", + "link": "https://brodacid.pl/?utm_source=mobile_open&utm_medium=cpc&utm_campaign=hi2023", + "logo": "https://api.adquery.io/img/adquery.png", + "medias": [ + { + "src": "banner/2023-06-05/17591", + "ext": "zip", + "type": 3 + } + ], + "domain": "https://bidder.adquery.io", + "urlAdq": "https://adquery.io", + "creationId": 7211, + "currency": "PLN", + "adDomains": [ + "https://s1.adquery.io" + ], + "tag": " ", + "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", + "mediaType": { + "width": "320", + "height": "50", + "name": "banner", + "type": "banner320x50" + }, + "cpm": "4.14", + "qid": "fc08aacb07eac44421ed", + "width": "320", + "height": "50", + "isExpand": false + } + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "22e26bd9a702bc1", + "impid": "1", + "price": 4.14, + "adm": " ", + "adomain": ["https://s1.adquery.io"], + "crid": "7211", + "w": 320, + "h": 50 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/adquery/adquerytest/supplemental/data-null.json b/adapters/adquery/adquerytest/supplemental/data-null.json new file mode 100644 index 00000000000..0d21a2bd9f7 --- /dev/null +++ b/adapters/adquery/adquerytest/supplemental/data-null.json @@ -0,0 +1,72 @@ +{ + "mockBidRequest": { + "id": "22e26bd9a702bc", + "user": { + "id": "d93f2a0e5f0fe2cc3a6e" + }, + "imp": [ + { + "id": "1", + "tagid": "test-banner-imp-id", + "bidder": "adquery", + "banner": { + "format": [ + { + "w": 320, + "h": 100 + }, + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } + } + } + ], + "bidder": "adquery" + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bidder.adquery.io/prebid/bid", + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"], + "X-Openrtb-Version": ["2.5"] + }, + "body": { + "adUnitCode": "test-banner-imp-id", + "bidId": "22e26bd9a702bc1", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidPageUrl": "", + "bidder": "adquery", + "bidderRequestId": "22e26bd9a702bc", + "bidRequestsCount": 1, + "bidderRequestsCount": 1, + "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "sizes": "320x100,300x250", + "type": "banner", + "v": "server" + } + }, + "mockResponse": { + "status": 200, + "headers": {}, + "body": { + "data": null + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [] + } + ] +} \ No newline at end of file diff --git a/adapters/adquery/adquerytest/supplemental/invalid-numerical-values.json b/adapters/adquery/adquerytest/supplemental/invalid-numerical-values.json new file mode 100644 index 00000000000..daff3d0828c --- /dev/null +++ b/adapters/adquery/adquerytest/supplemental/invalid-numerical-values.json @@ -0,0 +1,114 @@ +{ + "mockBidRequest": { + "id": "22e26bd9a702bc", + "user": { + "id": "d93f2a0e5f0fe2cc3a6e" + }, + "imp": [ + { + "id": "1", + "tagid": "test-banner-imp-id", + "bidder": "adquery", + "banner": { + "format": [ + { + "w": 320, + "h": 100 + }, + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } + } + } + ], + "bidder": "adquery" + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bidder.adquery.io/prebid/bid", + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"], + "X-Openrtb-Version": ["2.5"] + }, + "body": { + "adUnitCode": "test-banner-imp-id", + "bidId": "22e26bd9a702bc1", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidPageUrl": "", + "bidder": "adquery", + "bidderRequestId": "22e26bd9a702bc", + "bidRequestsCount": 1, + "bidderRequestsCount": 1, + "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "sizes": "320x100,300x250", + "type": "banner", + "v": "server" + } + }, + "mockResponse": { + "status": 200, + "headers": {}, + "body": { + "data": { + "requestId": "22e26bd9a702bc", + "emission_id": "22e26bd9a702bc", + "eventTracker": "https://bidder.adquery.io/prebid/ev/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "externalEmissionCodes": "", + "impressionTracker": "https://bidder.adquery.io/prebid/im/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "viewabilityTracker": "https://bidder.adquery.io/prebid/vi/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "clickTracker": "https://bidder.adquery.io/prebid/cl/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?url=https%3A%2F%2Fbrodacid.pl%2F%3Futm_source%3Dmobile_open%26utm_medium%3Dcpc%26utm_campaign%3Dhi2023", + "link": "https://brodacid.pl/?utm_source=mobile_open&utm_medium=cpc&utm_campaign=hi2023", + "logo": "https://api.adquery.io/img/adquery.png", + "medias": [ + { + "src": "banner/2023-06-05/17591", + "ext": "zip", + "type": 3 + } + ], + "domain": "https://bidder.adquery.io", + "urlAdq": "https://adquery.io", + "creationId": 7211, + "currency": "PLN", + "adDomains": [ + "https://s1.adquery.io" + ], + "tag": " ", + "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", + "mediaType": { + "width": "320px", + "height": "50px", + "name": "banner", + "type": "banner320x50" + }, + "cpm": "$4.14", + "qid": "fc08aacb07eac44421ed", + "width": "320", + "height": "50", + "isExpand": false + } + } + } + } + ], + "expectedMakeBidsErrors": [{ + "value": "strconv.ParseFloat: parsing \"$4.14\": invalid syntax", + "comparison": "literal" + },{ + "value": "strconv.ParseInt: parsing \"320px\": invalid syntax", + "comparison": "literal" + },{ + "value": "strconv.ParseInt: parsing \"50px\": invalid syntax", + "comparison": "literal" + }] +} \ No newline at end of file diff --git a/adapters/adquery/adquerytest/supplemental/malformed-ext.json b/adapters/adquery/adquerytest/supplemental/malformed-ext.json new file mode 100644 index 00000000000..46aaaed431d --- /dev/null +++ b/adapters/adquery/adquerytest/supplemental/malformed-ext.json @@ -0,0 +1,38 @@ +{ + "mockBidRequest": { + "id": "22e26bd9a702bc", + "user": { + "id": "d93f2a0e5f0fe2cc3a6e" + }, + "imp": [ + { + "id": "1", + "tagid": "test-banner-imp-id", + "bidder": "adquery", + "banner": { + "format": [ + { + "w": 320, + "h": 100 + }, + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": [], + "type": "banner" + } + } + } + ], + "bidder": "adquery" + }, + "expectedMakeRequestsErrors": [{ + "value": "json: cannot unmarshal array into Go struct field ImpExtAdQuery.placementId of type string", + "comparison": "literal" + }] +} \ No newline at end of file diff --git a/adapters/adquery/adquerytest/supplemental/malformed-resp.json b/adapters/adquery/adquerytest/supplemental/malformed-resp.json new file mode 100644 index 00000000000..f7aa271e6fe --- /dev/null +++ b/adapters/adquery/adquerytest/supplemental/malformed-resp.json @@ -0,0 +1,108 @@ +{ + "mockBidRequest": { + "id": "22e26bd9a702bc", + "user": { + "id": "d93f2a0e5f0fe2cc3a6e" + }, + "imp": [ + { + "id": "1", + "tagid": "test-banner-imp-id", + "bidder": "adquery", + "banner": { + "format": [ + { + "w": 320, + "h": 100 + }, + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } + } + } + ], + "bidder": "adquery" + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bidder.adquery.io/prebid/bid", + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"], + "X-Openrtb-Version": ["2.5"] + }, + "body": { + "adUnitCode": "test-banner-imp-id", + "bidId": "22e26bd9a702bc1", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidPageUrl": "", + "bidder": "adquery", + "bidderRequestId": "22e26bd9a702bc", + "bidRequestsCount": 1, + "bidderRequestsCount": 1, + "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "sizes": "320x100,300x250", + "type": "banner", + "v": "server" + } + }, + "mockResponse": { + "status": 200, + "headers": {}, + "body": { + "data": { + "requestId": "22e26bd9a702bc", + "emission_id": "22e26bd9a702bc", + "eventTracker": "https://bidder.adquery.io/prebid/ev/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "externalEmissionCodes": "", + "impressionTracker": "https://bidder.adquery.io/prebid/im/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "viewabilityTracker": "https://bidder.adquery.io/prebid/vi/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "clickTracker": "https://bidder.adquery.io/prebid/cl/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?url=https%3A%2F%2Fbrodacid.pl%2F%3Futm_source%3Dmobile_open%26utm_medium%3Dcpc%26utm_campaign%3Dhi2023", + "link": "https://brodacid.pl/?utm_source=mobile_open&utm_medium=cpc&utm_campaign=hi2023", + "logo": "https://api.adquery.io/img/adquery.png", + "medias": [ + { + "src": "banner/2023-06-05/17591", + "ext": "zip", + "type": 3 + } + ], + "domain": "https://bidder.adquery.io", + "urlAdq": "https://adquery.io", + "creationId": "string-identifier", + "currency": "PLN", + "adDomains": [ + "https://s1.adquery.io" + ], + "tag": " ", + "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", + "mediaType": { + "width": "320", + "height": "50", + "name": "banner", + "type": "banner320x50" + }, + "cpm": "4.14", + "qid": "fc08aacb07eac44421ed", + "width": "320", + "height": "50", + "isExpand": false + } + } + } + } + ], + "expectedMakeBidsErrors": [{ + "value": "json: cannot unmarshal string into Go struct field ResponseData.data.creationId of type int64", + "comparison": "literal" + }] +} \ No newline at end of file diff --git a/adapters/adquery/adquerytest/supplemental/mediatype-unknown.json b/adapters/adquery/adquerytest/supplemental/mediatype-unknown.json new file mode 100644 index 00000000000..bf3cdc63f45 --- /dev/null +++ b/adapters/adquery/adquerytest/supplemental/mediatype-unknown.json @@ -0,0 +1,108 @@ +{ + "mockBidRequest": { + "id": "22e26bd9a702bc", + "user": { + "id": "d93f2a0e5f0fe2cc3a6e" + }, + "imp": [ + { + "id": "1", + "tagid": "test-banner-imp-id", + "bidder": "adquery", + "banner": { + "format": [ + { + "w": 320, + "h": 100 + }, + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } + } + } + ], + "bidder": "adquery" + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bidder.adquery.io/prebid/bid", + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"], + "X-Openrtb-Version": ["2.5"] + }, + "body": { + "adUnitCode": "test-banner-imp-id", + "bidId": "22e26bd9a702bc1", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidPageUrl": "", + "bidder": "adquery", + "bidderRequestId": "22e26bd9a702bc", + "bidRequestsCount": 1, + "bidderRequestsCount": 1, + "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "sizes": "320x100,300x250", + "type": "banner", + "v": "server" + } + }, + "mockResponse": { + "status": 200, + "headers": {}, + "body": { + "data": { + "requestId": "22e26bd9a702bc", + "emission_id": "22e26bd9a702bc", + "eventTracker": "https://bidder.adquery.io/prebid/ev/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "externalEmissionCodes": "", + "impressionTracker": "https://bidder.adquery.io/prebid/im/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "viewabilityTracker": "https://bidder.adquery.io/prebid/vi/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "clickTracker": "https://bidder.adquery.io/prebid/cl/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?url=https%3A%2F%2Fbrodacid.pl%2F%3Futm_source%3Dmobile_open%26utm_medium%3Dcpc%26utm_campaign%3Dhi2023", + "link": "https://brodacid.pl/?utm_source=mobile_open&utm_medium=cpc&utm_campaign=hi2023", + "logo": "https://api.adquery.io/img/adquery.png", + "medias": [ + { + "src": "banner/2023-06-05/17591", + "ext": "zip", + "type": 3 + } + ], + "domain": "https://bidder.adquery.io", + "urlAdq": "https://adquery.io", + "creationId": 7211, + "currency": "PLN", + "adDomains": [ + "https://s1.adquery.io" + ], + "tag": " ", + "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", + "mediaType": { + "width": "320", + "height": "50", + "name": "unknown", + "type": "unknown320x50" + }, + "cpm": "4.14", + "qid": "fc08aacb07eac44421ed", + "width": "320", + "height": "50", + "isExpand": false + } + } + } + } + ], + "expectedMakeBidsErrors": [{ + "value": "unsupported MediaType: unknown", + "comparison": "literal" + }] +} \ No newline at end of file diff --git a/adapters/adquery/adquerytest/supplemental/mediatype-video.json b/adapters/adquery/adquerytest/supplemental/mediatype-video.json new file mode 100644 index 00000000000..7becebab291 --- /dev/null +++ b/adapters/adquery/adquerytest/supplemental/mediatype-video.json @@ -0,0 +1,108 @@ +{ + "mockBidRequest": { + "id": "22e26bd9a702bc", + "user": { + "id": "d93f2a0e5f0fe2cc3a6e" + }, + "imp": [ + { + "id": "1", + "tagid": "test-banner-imp-id", + "bidder": "adquery", + "banner": { + "format": [ + { + "w": 320, + "h": 100 + }, + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } + } + } + ], + "bidder": "adquery" + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bidder.adquery.io/prebid/bid", + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"], + "X-Openrtb-Version": ["2.5"] + }, + "body": { + "adUnitCode": "test-banner-imp-id", + "bidId": "22e26bd9a702bc1", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidPageUrl": "", + "bidder": "adquery", + "bidderRequestId": "22e26bd9a702bc", + "bidRequestsCount": 1, + "bidderRequestsCount": 1, + "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "sizes": "320x100,300x250", + "type": "banner", + "v": "server" + } + }, + "mockResponse": { + "status": 200, + "headers": {}, + "body": { + "data": { + "requestId": "22e26bd9a702bc", + "emission_id": "22e26bd9a702bc", + "eventTracker": "https://bidder.adquery.io/prebid/ev/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "externalEmissionCodes": "", + "impressionTracker": "https://bidder.adquery.io/prebid/im/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "viewabilityTracker": "https://bidder.adquery.io/prebid/vi/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "clickTracker": "https://bidder.adquery.io/prebid/cl/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?url=https%3A%2F%2Fbrodacid.pl%2F%3Futm_source%3Dmobile_open%26utm_medium%3Dcpc%26utm_campaign%3Dhi2023", + "link": "https://brodacid.pl/?utm_source=mobile_open&utm_medium=cpc&utm_campaign=hi2023", + "logo": "https://api.adquery.io/img/adquery.png", + "medias": [ + { + "src": "banner/2023-06-05/17591", + "ext": "zip", + "type": 3 + } + ], + "domain": "https://bidder.adquery.io", + "urlAdq": "https://adquery.io", + "creationId": 7211, + "currency": "PLN", + "adDomains": [ + "https://s1.adquery.io" + ], + "tag": " ", + "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", + "mediaType": { + "width": "320", + "height": "50", + "name": "video", + "type": "video320x50" + }, + "cpm": "4.14", + "qid": "fc08aacb07eac44421ed", + "width": "320", + "height": "50", + "isExpand": false + } + } + } + } + ], + "expectedMakeBidsErrors": [{ + "value": "unsupported MediaType: video", + "comparison": "literal" + }] +} \ No newline at end of file diff --git a/adapters/adquery/adquerytest/supplemental/no-imp-banner-measures.json b/adapters/adquery/adquerytest/supplemental/no-imp-banner-measures.json new file mode 100644 index 00000000000..953d6de5d8d --- /dev/null +++ b/adapters/adquery/adquerytest/supplemental/no-imp-banner-measures.json @@ -0,0 +1,61 @@ +{ + "mockBidRequest": { + "id": "22e26bd9a702bc", + "user": { + "id": "d93f2a0e5f0fe2cc3a6e" + }, + "imp": [ + { + "id": "1", + "tagid": "test-banner-imp-id", + "bidder": "adquery", + "banner": {}, + "ext": { + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } + } + } + ], + "bidder": "adquery" + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bidder.adquery.io/prebid/bid", + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"], + "X-Openrtb-Version": ["2.5"] + }, + "body": { + "adUnitCode": "test-banner-imp-id", + "bidId": "22e26bd9a702bc1", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidPageUrl": "", + "bidder": "adquery", + "bidderRequestId": "22e26bd9a702bc", + "bidRequestsCount": 1, + "bidderRequestsCount": 1, + "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "sizes": "", + "type": "banner", + "v": "server" + } + }, + "mockResponse": { + "status": 200, + "headers": {}, + "body": { + "data": null + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [] + } + ] +} \ No newline at end of file diff --git a/adapters/adquery/adquerytest/supplemental/no-imp-banner.json b/adapters/adquery/adquerytest/supplemental/no-imp-banner.json new file mode 100644 index 00000000000..8589d97f606 --- /dev/null +++ b/adapters/adquery/adquerytest/supplemental/no-imp-banner.json @@ -0,0 +1,60 @@ +{ + "mockBidRequest": { + "id": "22e26bd9a702bc", + "user": { + "id": "d93f2a0e5f0fe2cc3a6e" + }, + "imp": [ + { + "id": "1", + "tagid": "test-banner-imp-id", + "bidder": "adquery", + "ext": { + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } + } + } + ], + "bidder": "adquery" + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bidder.adquery.io/prebid/bid", + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"], + "X-Openrtb-Version": ["2.5"] + }, + "body": { + "adUnitCode": "test-banner-imp-id", + "bidId": "22e26bd9a702bc1", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidPageUrl": "", + "bidder": "adquery", + "bidderRequestId": "22e26bd9a702bc", + "bidRequestsCount": 1, + "bidderRequestsCount": 1, + "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "sizes": "", + "type": "banner", + "v": "server" + } + }, + "mockResponse": { + "status": 200, + "headers": {}, + "body": { + "data": null + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [] + } + ] +} \ No newline at end of file diff --git a/adapters/adquery/adquerytest/supplemental/resp-bad-request.json b/adapters/adquery/adquerytest/supplemental/resp-bad-request.json new file mode 100644 index 00000000000..cb869625720 --- /dev/null +++ b/adapters/adquery/adquerytest/supplemental/resp-bad-request.json @@ -0,0 +1,68 @@ +{ + "mockBidRequest": { + "id": "22e26bd9a702bc", + "user": { + "id": "d93f2a0e5f0fe2cc3a6e" + }, + "imp": [ + { + "id": "1", + "tagid": "test-banner-imp-id", + "bidder": "adquery", + "banner": { + "format": [ + { + "w": 320, + "h": 100 + }, + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } + } + } + ], + "bidder": "adquery" + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bidder.adquery.io/prebid/bid", + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"], + "X-Openrtb-Version": ["2.5"] + }, + "body": { + "adUnitCode": "test-banner-imp-id", + "bidId": "22e26bd9a702bc1", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidPageUrl": "", + "bidder": "adquery", + "bidderRequestId": "22e26bd9a702bc", + "bidRequestsCount": 1, + "bidderRequestsCount": 1, + "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "sizes": "320x100,300x250", + "type": "banner", + "v": "server" + } + }, + "mockResponse": { + "status": 400, + "headers": {} + } + } + ], + "expectedMakeBidsErrors": [{ + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + }] +} \ No newline at end of file diff --git a/adapters/adquery/adquerytest/supplemental/resp-no-content.json b/adapters/adquery/adquerytest/supplemental/resp-no-content.json new file mode 100644 index 00000000000..5817e15a533 --- /dev/null +++ b/adapters/adquery/adquerytest/supplemental/resp-no-content.json @@ -0,0 +1,66 @@ +{ + "mockBidRequest": { + "id": "22e26bd9a702bc", + "user": { + "id": "d93f2a0e5f0fe2cc3a6e" + }, + "imp": [ + { + "id": "1", + "tagid": "test-banner-imp-id", + "bidder": "adquery", + "banner": { + "format": [ + { + "w": 320, + "h": 100 + }, + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } + } + } + ], + "bidder": "adquery" + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bidder.adquery.io/prebid/bid", + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"], + "X-Openrtb-Version": ["2.5"] + }, + "body": { + "adUnitCode": "test-banner-imp-id", + "bidId": "22e26bd9a702bc1", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidPageUrl": "", + "bidder": "adquery", + "bidderRequestId": "22e26bd9a702bc", + "bidRequestsCount": 1, + "bidderRequestsCount": 1, + "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "sizes": "320x100,300x250", + "type": "banner", + "v": "server" + } + }, + "mockResponse": { + "status": 204, + "headers": {} + } + } + ], + "expectedBidResponses": [ + ] +} \ No newline at end of file diff --git a/adapters/adquery/adquerytest/supplemental/resp-server-error.json b/adapters/adquery/adquerytest/supplemental/resp-server-error.json new file mode 100644 index 00000000000..05c1cae8488 --- /dev/null +++ b/adapters/adquery/adquerytest/supplemental/resp-server-error.json @@ -0,0 +1,68 @@ +{ + "mockBidRequest": { + "id": "22e26bd9a702bc", + "user": { + "id": "d93f2a0e5f0fe2cc3a6e" + }, + "imp": [ + { + "id": "1", + "tagid": "test-banner-imp-id", + "bidder": "adquery", + "banner": { + "format": [ + { + "w": 320, + "h": 100 + }, + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } + } + } + ], + "bidder": "adquery" + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bidder.adquery.io/prebid/bid", + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"], + "X-Openrtb-Version": ["2.5"] + }, + "body": { + "adUnitCode": "test-banner-imp-id", + "bidId": "22e26bd9a702bc1", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidPageUrl": "", + "bidder": "adquery", + "bidderRequestId": "22e26bd9a702bc", + "bidRequestsCount": 1, + "bidderRequestsCount": 1, + "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "sizes": "320x100,300x250", + "type": "banner", + "v": "server" + } + }, + "mockResponse": { + "status": 500, + "headers": {} + } + } + ], + "expectedMakeBidsErrors": [{ + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", + "comparison": "literal" + }] +} \ No newline at end of file diff --git a/adapters/adquery/params_test.go b/adapters/adquery/params_test.go new file mode 100644 index 00000000000..cba021007d3 --- /dev/null +++ b/adapters/adquery/params_test.go @@ -0,0 +1,49 @@ +package adquery + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range validParams { + if err := validator.Validate(openrtb_ext.BidderAdquery, json.RawMessage(p)); err != nil { + t.Errorf("Schema rejected valid params: %s", p) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderAdquery, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} + +var validParams = []string{ + `{"placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", "type": "banner300x250"}`, +} + +var invalidParams = []string{ + `{}`, + `{"placementId": 42}`, + `{"type": 3}`, + `{"placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897"}`, + `{"type": "banner"}`, + `{"placementId": 42, "type": "banner"}`, + `{"placementId": "too_short", "type": "banner"}`, + `{"placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", "type": ""}`, +} diff --git a/adapters/adquery/types.go b/adapters/adquery/types.go new file mode 100644 index 00000000000..e46afaea63e --- /dev/null +++ b/adapters/adquery/types.go @@ -0,0 +1,42 @@ +package adquery + +import "github.com/prebid/prebid-server/openrtb_ext" + +type BidderRequest struct { + V string `json:"v"` + PlacementCode string `json:"placementCode"` + AuctionId string `json:"auctionId,omitempty"` + BidType string `json:"type"` + AdUnitCode string `json:"adUnitCode"` + BidQid string `json:"bidQid"` + BidId string `json:"bidId"` + Bidder string `json:"bidder"` + BidPageUrl string `json:"bidPageUrl"` + BidderRequestId string `json:"bidderRequestId"` + BidRequestsCount int `json:"bidRequestsCount"` + BidderRequestsCount int `json:"bidderRequestsCount"` + Sizes string `json:"sizes"` +} + +type ResponseAdQuery struct { + Data *ResponseData `json:"data"` +} + +type ResponseData struct { + ReqID string `json:"requestId"` + CrID int64 `json:"creationId"` + Currency string `json:"currency"` + CPM string `json:"cpm"` + Code string `json:"code"` + AdQLib string `json:"adqLib"` + Tag string `json:"tag"` + ADomains []string `json:"adDomains"` + DealID string `json:"dealid"` + MediaType AdQueryMediaType `json:"mediaType"` +} + +type AdQueryMediaType struct { + Name openrtb_ext.BidType `json:"name"` + Width string `json:"width"` + Height string `json:"height"` +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 5c3cb39ecda..fb1dd69a018 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -19,6 +19,7 @@ import ( "github.com/prebid/prebid-server/adapters/adot" "github.com/prebid/prebid-server/adapters/adpone" "github.com/prebid/prebid-server/adapters/adprime" + "github.com/prebid/prebid-server/adapters/adquery" "github.com/prebid/prebid-server/adapters/adrino" "github.com/prebid/prebid-server/adapters/adsinteractive" "github.com/prebid/prebid-server/adapters/adtarget" @@ -210,6 +211,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderAdot: adot.Builder, openrtb_ext.BidderAdpone: adpone.Builder, openrtb_ext.BidderAdprime: adprime.Builder, + openrtb_ext.BidderAdquery: adquery.Builder, openrtb_ext.BidderAdrino: adrino.Builder, openrtb_ext.BidderAdsinteractive: adsinteractive.Builder, openrtb_ext.BidderAdsyield: limelightDigital.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index a9b1a8886c2..bed2f056d60 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -36,6 +36,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderAdot, BidderAdpone, BidderAdprime, + BidderAdquery, BidderAdrino, BidderAdsinteractive, BidderAdsyield, @@ -324,6 +325,7 @@ const ( BidderAdot BidderName = "adot" BidderAdpone BidderName = "adpone" BidderAdprime BidderName = "adprime" + BidderAdquery BidderName = "adquery" BidderAdrino BidderName = "adrino" BidderAdsinteractive BidderName = "adsinteractive" BidderAdsyield BidderName = "adsyield" diff --git a/openrtb_ext/imp_adquery.go b/openrtb_ext/imp_adquery.go new file mode 100644 index 00000000000..73477e784b1 --- /dev/null +++ b/openrtb_ext/imp_adquery.go @@ -0,0 +1,6 @@ +package openrtb_ext + +type ImpExtAdQuery struct { + PlacementID string `json:"placementId"` + Type string `json:"type"` +} diff --git a/static/bidder-info/adquery.yaml b/static/bidder-info/adquery.yaml new file mode 100644 index 00000000000..98b6b0ea432 --- /dev/null +++ b/static/bidder-info/adquery.yaml @@ -0,0 +1,16 @@ +endpoint: "https://bidder.adquery.io/prebid/bid" +maintainer: + email: prebid@adquery.io +#endpointCompression: gzip # disabled because otherwise bidder responds with {data:null} +gvlVendorID: 902 +capabilities: +# app: # disabled because currently it's only a site, not an app (?) +# mediaTypes: +# - banner + site: + mediaTypes: + - banner +userSync: + redirect: + url: https://bidder.adquery.io/prebid/userSync?1=1&gdpr={{.GDPR}}&consent={{.GDPRConsent}}&ccpa_consent={{.USPrivacy}}&redirect={{.RedirectURL}} + userMacro: $UID \ No newline at end of file diff --git a/static/bidder-params/adquery.json b/static/bidder-params/adquery.json new file mode 100644 index 00000000000..f2394b5e249 --- /dev/null +++ b/static/bidder-params/adquery.json @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Adquery Adapter Params", + "description": "A schema which validates params accepted by the Adquery adapter", + "type": "object", + + "properties": { + "placementId": { + "type": "string", + "minLength": 35, + "maxLength": 45, + "description": "Placement ID" + }, + "type": { + "type": "string", + "minLength": 1, + "description": "Bid type" + } + }, + + "required": ["placementId", "type"] +} From 892ea800a7c08fdbe51fe669514096897b50cefc Mon Sep 17 00:00:00 2001 From: Hasan Kanjee <55110940+hasan-kanjee@users.noreply.github.com> Date: Thu, 24 Aug 2023 02:26:53 -0400 Subject: [PATCH 090/268] OFF-657 remove ip as a bidder request parameter (#6) (#3047) --- adapters/flipp/flipp.go | 4 +--- adapters/flipp/flipptest/exemplary/simple-banner-native.json | 3 +-- openrtb_ext/imp_flipp.go | 1 - 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/adapters/flipp/flipp.go b/adapters/flipp/flipp.go index 9705fa574ba..14f31a91efb 100644 --- a/adapters/flipp/flipp.go +++ b/adapters/flipp/flipp.go @@ -114,9 +114,7 @@ func (a *adapter) processImp(request *openrtb2.BidRequest, imp openrtb2.Imp) (*a } var userIP string - if flippExtParams.IP != "" { - userIP = flippExtParams.IP - } else if request.Device != nil && request.Device.IP != "" { + if request.Device != nil && request.Device.IP != "" { userIP = request.Device.IP } else { return nil, fmt.Errorf("no IP set in flipp bidder params or request device") diff --git a/adapters/flipp/flipptest/exemplary/simple-banner-native.json b/adapters/flipp/flipptest/exemplary/simple-banner-native.json index c242c323003..d8a24131c77 100644 --- a/adapters/flipp/flipptest/exemplary/simple-banner-native.json +++ b/adapters/flipp/flipptest/exemplary/simple-banner-native.json @@ -30,7 +30,6 @@ "creativeType": "NativeX", "siteId": 1243066, "zoneIds": [285431], - "ip": "123.123.123.124", "options": { "startCompact": true, "contentCode": "publisher-test-2" @@ -46,7 +45,7 @@ "expectedRequest": { "uri": "http://example.com/pserver", "body": { - "ip":"123.123.123.124", + "ip":"123.123.123.123", "keywords":[ "" ], diff --git a/openrtb_ext/imp_flipp.go b/openrtb_ext/imp_flipp.go index 029e2882652..56874c024c6 100644 --- a/openrtb_ext/imp_flipp.go +++ b/openrtb_ext/imp_flipp.go @@ -6,7 +6,6 @@ type ImpExtFlipp struct { SiteID int64 `json:"siteId"` ZoneIds []int64 `json:"zoneIds,omitempty"` UserKey string `json:"userKey,omitempty"` - IP string `json:"ip,omitempty"` Options ImpExtFlippOptions `json:"options,omitempty"` } From 539c1b38ae4c5b2445c5f436ded461924ca4d992 Mon Sep 17 00:00:00 2001 From: Sonali-More-Xandr <87759626+Sonali-More-Xandr@users.noreply.github.com> Date: Thu, 24 Aug 2023 12:01:27 +0530 Subject: [PATCH 091/268] map alias bidder name to its parent builder (#3016) --- exchange/adapter_util.go | 21 +++++++++++++++ exchange/adapter_util_test.go | 49 +++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index c863f52ad48..ee9a066aa58 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -43,6 +43,13 @@ func buildBidders(infos config.BidderInfos, builders map[openrtb_ext.BidderName] continue } + if len(info.AliasOf) > 0 { + if err := setAliasBuilder(info, builders, bidderName); err != nil { + errs = append(errs, fmt.Errorf("%v: failed to set alias builder: %v", bidder, err)) + continue + } + } + builder, builderFound := builders[bidderName] if !builderFound { errs = append(errs, fmt.Errorf("%v: builder not registered", bidder)) @@ -63,6 +70,20 @@ func buildBidders(infos config.BidderInfos, builders map[openrtb_ext.BidderName] return bidders, errs } +func setAliasBuilder(info config.BidderInfo, builders map[openrtb_ext.BidderName]adapters.Builder, bidderName openrtb_ext.BidderName) error { + parentBidderName, parentBidderFound := openrtb_ext.NormalizeBidderName(info.AliasOf) + if !parentBidderFound { + return fmt.Errorf("unknown parent bidder: %v for alias: %v", info.AliasOf, bidderName) + } + + builder, builderFound := builders[parentBidderName] + if !builderFound { + return fmt.Errorf("%v: parent builder not registered", parentBidderName) + } + builders[bidderName] = builder + return nil +} + func buildAdapterInfo(bidderInfo config.BidderInfo) config.Adapter { adapter := config.Adapter{} adapter.Endpoint = bidderInfo.Endpoint diff --git a/exchange/adapter_util_test.go b/exchange/adapter_util_test.go index f860a1df291..611498fea0c 100644 --- a/exchange/adapter_util_test.go +++ b/exchange/adapter_util_test.go @@ -171,6 +171,55 @@ func TestBuildBidders(t *testing.T) { } } +func TestSetAliasBuilder(t *testing.T) { + rubiconBidder := fakeBidder{"b"} + ixBidder := fakeBidder{"ix"} + rubiconBuilder := fakeBuilder{rubiconBidder, nil}.Builder + ixBuilder := fakeBuilder{ixBidder, nil}.Builder + + testCases := []struct { + description string + bidderInfo config.BidderInfo + builders map[openrtb_ext.BidderName]adapters.Builder + bidderName openrtb_ext.BidderName + expectedBuilders map[openrtb_ext.BidderName]adapters.Builder + expectedError error + }{ + { + description: "Success - Alias builder", + bidderInfo: config.BidderInfo{Disabled: false, AliasOf: "rubicon"}, + bidderName: openrtb_ext.BidderName("appnexus"), + builders: map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderRubicon: rubiconBuilder}, + expectedBuilders: map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderRubicon: rubiconBuilder, openrtb_ext.BidderAppnexus: rubiconBuilder}, + }, + { + description: "Failure - Invalid parent bidder builder", + bidderInfo: config.BidderInfo{Disabled: false, AliasOf: "rubicon"}, + bidderName: openrtb_ext.BidderName("appnexus"), + builders: map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderIx: ixBuilder}, + expectedError: errors.New("rubicon: parent builder not registered"), + }, + { + description: "Failure - Invalid parent for alias", + bidderInfo: config.BidderInfo{Disabled: false, AliasOf: "unknown"}, + bidderName: openrtb_ext.BidderName("appnexus"), + builders: map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderIx: ixBuilder}, + expectedError: errors.New("unknown parent bidder: unknown for alias: appnexus"), + }, + } + + for _, test := range testCases { + err := setAliasBuilder(test.bidderInfo, test.builders, test.bidderName) + + if test.expectedBuilders != nil { + assert.ObjectsAreEqual(test.builders, test.expectedBuilders) + } + if test.expectedError != nil { + assert.EqualError(t, test.expectedError, err.Error(), test.description+":errors") + } + } +} + func TestGetActiveBidders(t *testing.T) { testCases := []struct { description string From bb06b11861dcf79f7904d60ea72f8cf4ec63f2cf Mon Sep 17 00:00:00 2001 From: Sonali-More-Xandr <87759626+Sonali-More-Xandr@users.noreply.github.com> Date: Thu, 24 Aug 2023 12:22:57 +0530 Subject: [PATCH 092/268] validate capabilities in alias config (#2996) --- config/bidderinfo.go | 60 ++++++- config/bidderinfo_test.go | 326 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 381 insertions(+), 5 deletions(-) diff --git a/config/bidderinfo.go b/config/bidderinfo.go index c0d89841671..df9e9d5a78a 100644 --- a/config/bidderinfo.go +++ b/config/bidderinfo.go @@ -350,7 +350,7 @@ func (infos BidderInfos) validate(errs []error) []error { if bidder.IsEnabled() { errs = validateAdapterEndpoint(bidder.Endpoint, bidderName, errs) - if err := validateInfo(bidder, bidderName); err != nil { + if err := validateInfo(bidder, infos, bidderName); err != nil { errs = append(errs, err) } @@ -417,14 +417,18 @@ func validateAdapterEndpoint(endpoint string, bidderName string, errs []error) [ return errs } -func validateInfo(info BidderInfo, bidderName string) error { - if err := validateMaintainer(info.Maintainer, bidderName); err != nil { +func validateInfo(bidder BidderInfo, infos BidderInfos, bidderName string) error { + if err := validateMaintainer(bidder.Maintainer, bidderName); err != nil { return err } - if err := validateCapabilities(info.Capabilities, bidderName); err != nil { + if err := validateCapabilities(bidder.Capabilities, bidderName); err != nil { return err } - + if len(bidder.AliasOf) > 0 { + if err := validateAliasCapabilities(bidder, infos, bidderName); err != nil { + return err + } + } return nil } @@ -435,6 +439,52 @@ func validateMaintainer(info *MaintainerInfo, bidderName string) error { return nil } +func validateAliasCapabilities(aliasBidderInfo BidderInfo, infos BidderInfos, bidderName string) error { + parentBidder, parentFound := infos[aliasBidderInfo.AliasOf] + if !parentFound { + return fmt.Errorf("parent bidder: %s not found for an alias: %s", aliasBidderInfo.AliasOf, bidderName) + } + + if aliasBidderInfo.Capabilities != nil { + if parentBidder.Capabilities == nil { + return fmt.Errorf("capabilities for alias: %s should be a subset of capabilities for parent bidder: %s", bidderName, aliasBidderInfo.AliasOf) + } + + if (aliasBidderInfo.Capabilities.App != nil && parentBidder.Capabilities.App == nil) || (aliasBidderInfo.Capabilities.Site != nil && parentBidder.Capabilities.Site == nil) { + return fmt.Errorf("capabilities for alias: %s should be a subset of capabilities for parent bidder: %s", bidderName, aliasBidderInfo.AliasOf) + } + + if aliasBidderInfo.Capabilities.Site != nil && parentBidder.Capabilities.Site != nil { + if err := isAliasPlatformInfoSubsetOfParent(*parentBidder.Capabilities.Site, *aliasBidderInfo.Capabilities.Site, bidderName, aliasBidderInfo.AliasOf); err != nil { + return err + } + } + + if aliasBidderInfo.Capabilities.App != nil && parentBidder.Capabilities.App != nil { + if err := isAliasPlatformInfoSubsetOfParent(*parentBidder.Capabilities.App, *aliasBidderInfo.Capabilities.App, bidderName, aliasBidderInfo.AliasOf); err != nil { + return err + } + } + } + + return nil +} + +func isAliasPlatformInfoSubsetOfParent(parentInfo PlatformInfo, aliasInfo PlatformInfo, bidderName string, parentBidderName string) error { + parentMediaTypes := make(map[openrtb_ext.BidType]struct{}) + for _, info := range parentInfo.MediaTypes { + parentMediaTypes[info] = struct{}{} + } + + for _, info := range aliasInfo.MediaTypes { + if _, found := parentMediaTypes[info]; !found { + return fmt.Errorf("mediaTypes for alias: %s should be a subset of MediaTypes for parent bidder: %s", bidderName, parentBidderName) + } + } + + return nil +} + func validateCapabilities(info *CapabilitiesInfo, bidderName string) error { if info == nil { return fmt.Errorf("missing required field: capabilities for adapter: %s", bidderName) diff --git a/config/bidderinfo_test.go b/config/bidderinfo_test.go index 60221da2f6f..e505d2f8b77 100644 --- a/config/bidderinfo_test.go +++ b/config/bidderinfo_test.go @@ -905,6 +905,332 @@ func TestBidderInfoValidationNegative(t *testing.T) { errors.New("The endpoint: incorrect for bidderB is not a valid URL"), }, }, + { + "Invalid alias Site capabilities", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + Site: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, + }, + }, + "bidderB": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, + }, + AliasOf: "bidderA", + }, + }, + []error{ + errors.New("capabilities for alias: bidderB should be a subset of capabilities for parent bidder: bidderA"), + }, + }, + { + "Invalid alias App capabilities", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, + }, + }, + "bidderB": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + Site: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, + }, + AliasOf: "bidderA", + }, + }, + []error{ + errors.New("capabilities for alias: bidderB should be a subset of capabilities for parent bidder: bidderA"), + }, + }, + { + "Invalid alias capabilities", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{}, + }, + "bidderB": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, + }, + AliasOf: "bidderA", + }, + }, + []error{ + errors.New("at least one of capabilities.site or capabilities.app must exist for adapter: bidderA"), + errors.New("capabilities for alias: bidderB should be a subset of capabilities for parent bidder: bidderA"), + }, + }, + { + "Invalid alias MediaTypes for site", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + Site: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, + }, + }, + "bidderB": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + Site: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeBanner, + openrtb_ext.BidTypeNative, + }, + }, + }, + AliasOf: "bidderA", + }, + }, + []error{ + errors.New("mediaTypes for alias: bidderB should be a subset of MediaTypes for parent bidder: bidderA"), + }, + }, + { + "Invalid alias MediaTypes for app", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, + }, + }, + "bidderB": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeBanner, + openrtb_ext.BidTypeNative, + }, + }, + }, + AliasOf: "bidderA", + }, + }, + []error{ + errors.New("mediaTypes for alias: bidderB should be a subset of MediaTypes for parent bidder: bidderA"), + }, + }, + { + "Invalid parent bidder capabilities", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + }, + "bidderB": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeBanner, + }, + }, + }, + AliasOf: "bidderA", + }, + }, + []error{ + errors.New("missing required field: capabilities for adapter: bidderA"), + errors.New("capabilities for alias: bidderB should be a subset of capabilities for parent bidder: bidderA"), + }, + }, + { + "Invalid site alias capabilities with both site and app", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeBanner, + openrtb_ext.BidTypeNative, + }, + }, + Site: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeNative, + }, + }, + }, + }, + "bidderB": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeBanner, + openrtb_ext.BidTypeNative, + }, + }, + Site: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeBanner, + openrtb_ext.BidTypeNative, + }, + }, + }, + AliasOf: "bidderA", + }, + }, + []error{ + errors.New("mediaTypes for alias: bidderB should be a subset of MediaTypes for parent bidder: bidderA"), + }, + }, + { + "Invalid app alias capabilities with both site and app", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeBanner, + openrtb_ext.BidTypeNative, + }, + }, + Site: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeNative, + }, + }, + }, + }, + "bidderB": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeBanner, + openrtb_ext.BidTypeNative, + }, + }, + Site: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeBanner, + openrtb_ext.BidTypeNative, + }, + }, + }, + AliasOf: "bidderA", + }, + }, + []error{ + errors.New("mediaTypes for alias: bidderB should be a subset of MediaTypes for parent bidder: bidderA"), + }, + }, + { + "Invalid parent bidder for alias", + BidderInfos{ + "bidderB": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeBanner, + openrtb_ext.BidTypeNative, + }, + }, + Site: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeBanner, + openrtb_ext.BidTypeNative, + }, + }, + }, + AliasOf: "bidderC", + }, + }, + []error{ + errors.New("parent bidder: bidderC not found for an alias: bidderB"), + }, + }, } for _, test := range testCases { From 961bb8357202142b9b5f4ab6ebe5c71bdd20a356 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Thu, 24 Aug 2023 12:24:35 +0530 Subject: [PATCH 093/268] remove feature development flag check (#3049) co-authored by: @onkarvhanumante --- config/config.go | 5 ----- config/config_test.go | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/config/config.go b/config/config.go index 353787aa4f9..2b539c578d5 100644 --- a/config/config.go +++ b/config/config.go @@ -149,11 +149,6 @@ func (cfg *Configuration) validate(v *viper.Viper) []error { errs = append(errs, errors.New("account_defaults.Events.VASTEvents has no effect as the feature is under development.")) } - if cfg.TmaxAdjustments.Enabled { - glog.Warning(`cfg.TmaxAdjustments.Enabled will currently not do anything as tmax adjustment feature is still under development.`) - cfg.TmaxAdjustments.Enabled = false - } - if cfg.AccountDefaults.Privacy != nil { glog.Warning("account_defaults.Privacy has no effect as the feature is under development.") } diff --git a/config/config_test.go b/config/config_test.go index 30733372135..a35891babd3 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -566,7 +566,7 @@ func TestFullConfig(t *testing.T) { cmpStrings(t, "validations.secure_markup", "skip", cfg.Validations.SecureMarkup) cmpInts(t, "validations.max_creative_width", 0, int(cfg.Validations.MaxCreativeWidth)) cmpInts(t, "validations.max_creative_height", 0, int(cfg.Validations.MaxCreativeHeight)) - cmpBools(t, "tmax_adjustments.enabled", false, cfg.TmaxAdjustments.Enabled) // Tmax adjustment feature is still under development. Therefore enabled flag is set to false + cmpBools(t, "tmax_adjustments.enabled", true, cfg.TmaxAdjustments.Enabled) cmpUnsignedInts(t, "tmax_adjustments.bidder_response_duration_min_ms", 700, cfg.TmaxAdjustments.BidderResponseDurationMin) cmpUnsignedInts(t, "tmax_adjustments.bidder_network_latency_buffer_ms", 100, cfg.TmaxAdjustments.BidderNetworkLatencyBuffer) cmpUnsignedInts(t, "tmax_adjustments.pbs_response_preparation_duration_ms", 100, cfg.TmaxAdjustments.PBSResponsePreparationDuration) From a4e205fa6f4e1e14e5a4d37b0d000c4c41e85dc0 Mon Sep 17 00:00:00 2001 From: BeMatterFull-Prebid <142401543+BeMatterFull-Prebid@users.noreply.github.com> Date: Mon, 28 Aug 2023 09:19:50 +0300 Subject: [PATCH 094/268] New Adapter: Bematterfull (#3036) Co-authored-by: Dmytro Shyrokov --- adapters/bematterfull/bematterfull.go | 161 ++++++++++ .../bematterfulltest/exemplary/banner.json | 279 ++++++++++++++++++ .../bematterfulltest/exemplary/native.json | 162 ++++++++++ .../bematterfulltest/exemplary/video.json | 202 +++++++++++++ .../supplemental/bad-response.json | 106 +++++++ .../supplemental/empty-mediatype.json | 188 ++++++++++++ .../supplemental/empty-seatbid-0-bid.json | 111 +++++++ .../supplemental/empty-seatbid.json | 111 +++++++ .../invalid-ext-bidder-object.json | 49 +++ .../supplemental/invalid-ext-object.json | 47 +++ .../supplemental/invalid-mediatype.json | 190 ++++++++++++ .../supplemental/status-204.json | 100 +++++++ .../supplemental/status-400.json | 106 +++++++ .../supplemental/status-503.json | 105 +++++++ .../supplemental/unexpected-status.json | 106 +++++++ .../bematterfull/bematterfulltest_test.go | 27 ++ adapters/bematterfull/params_test.go | 53 ++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_bematterfull.go | 6 + static/bidder-info/bematterfull.yaml | 19 ++ static/bidder-params/bematterfull.json | 22 ++ 22 files changed, 2154 insertions(+) create mode 100644 adapters/bematterfull/bematterfull.go create mode 100644 adapters/bematterfull/bematterfulltest/exemplary/banner.json create mode 100644 adapters/bematterfull/bematterfulltest/exemplary/native.json create mode 100644 adapters/bematterfull/bematterfulltest/exemplary/video.json create mode 100644 adapters/bematterfull/bematterfulltest/supplemental/bad-response.json create mode 100644 adapters/bematterfull/bematterfulltest/supplemental/empty-mediatype.json create mode 100644 adapters/bematterfull/bematterfulltest/supplemental/empty-seatbid-0-bid.json create mode 100644 adapters/bematterfull/bematterfulltest/supplemental/empty-seatbid.json create mode 100644 adapters/bematterfull/bematterfulltest/supplemental/invalid-ext-bidder-object.json create mode 100644 adapters/bematterfull/bematterfulltest/supplemental/invalid-ext-object.json create mode 100644 adapters/bematterfull/bematterfulltest/supplemental/invalid-mediatype.json create mode 100644 adapters/bematterfull/bematterfulltest/supplemental/status-204.json create mode 100644 adapters/bematterfull/bematterfulltest/supplemental/status-400.json create mode 100644 adapters/bematterfull/bematterfulltest/supplemental/status-503.json create mode 100644 adapters/bematterfull/bematterfulltest/supplemental/unexpected-status.json create mode 100644 adapters/bematterfull/bematterfulltest_test.go create mode 100644 adapters/bematterfull/params_test.go create mode 100644 openrtb_ext/imp_bematterfull.go create mode 100644 static/bidder-info/bematterfull.yaml create mode 100644 static/bidder-params/bematterfull.json diff --git a/adapters/bematterfull/bematterfull.go b/adapters/bematterfull/bematterfull.go new file mode 100644 index 00000000000..bf63e7c8c8b --- /dev/null +++ b/adapters/bematterfull/bematterfull.go @@ -0,0 +1,161 @@ +package bematterfull + +import ( + "encoding/json" + "fmt" + "net/http" + "text/template" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/macros" + "github.com/prebid/prebid-server/openrtb_ext" +) + +type bidType struct { + Type string `json:"type"` +} + +type bidExt struct { + Prebid bidType `json:"prebid"` +} + +type adapter struct { + endpoint *template.Template +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + tmpl, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint URL template: %v", err) + } + + bidder := &adapter{ + endpoint: tmpl, + } + + return bidder, nil +} + +func (a *adapter) buildEndpointFromRequest(imp *openrtb2.Imp) (string, error) { + var impExt adapters.ExtImpBidder + if err := json.Unmarshal(imp.Ext, &impExt); err != nil { + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("Failed to deserialize bidder impression extension: %v", err), + } + } + + var bematterfullExt openrtb_ext.ExtBematterfull + if err := json.Unmarshal(impExt.Bidder, &bematterfullExt); err != nil { + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("Failed to deserialize Bematterfull extension: %v", err), + } + } + + endpointParams := macros.EndpointTemplateParams{ + Host: bematterfullExt.Env, + SourceId: bematterfullExt.Pid, + } + + return macros.ResolveMacros(a.endpoint, endpointParams) +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var requests []*adapters.RequestData + var errs []error + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + + requestCopy := *request + for _, imp := range request.Imp { + requestCopy.Imp = []openrtb2.Imp{imp} + + endpoint, err := a.buildEndpointFromRequest(&imp) + if err != nil { + errs = append(errs, err) + continue + } + + requestJSON, err := json.Marshal(requestCopy) + if err != nil { + errs = append(errs, err) + continue + } + + request := &adapters.RequestData{ + Method: http.MethodPost, + Body: requestJSON, + Uri: endpoint, + Headers: headers, + } + + requests = append(requests, request) + } + + return requests, errs +} + +func (a *adapter) MakeBids(openRTBRequest *openrtb2.BidRequest, requestToBidder *adapters.RequestData, bidderRawResponse *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(bidderRawResponse) { + return nil, nil + } + + if bidderRawResponse.StatusCode == http.StatusServiceUnavailable { + return nil, []error{&errortypes.BadInput{ + Message: "Bidder Bematterfull is unavailable. Please contact the bidder support.", + }} + } + + if err := adapters.CheckResponseStatusCodeForErrors(bidderRawResponse); err != nil { + return nil, []error{err} + } + + var bidResp openrtb2.BidResponse + if err := json.Unmarshal(bidderRawResponse.Body, &bidResp); err != nil { + return nil, []error{err} + } + + if len(bidResp.SeatBid) == 0 { + return nil, []error{&errortypes.BadServerResponse{ + Message: "Array SeatBid cannot be empty", + }} + } + + return prepareBidResponse(bidResp.SeatBid) +} + +func prepareBidResponse(seats []openrtb2.SeatBid) (*adapters.BidderResponse, []error) { + errs := []error{} + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(seats)) + + for _, seatBid := range seats { + for bidId, bid := range seatBid.Bid { + var bidExt bidExt + if err := json.Unmarshal(bid.Ext, &bidExt); err != nil { + errs = append(errs, &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Failed to parse Bid[%d].Ext: %s", bidId, err.Error()), + }) + continue + } + + bidType, err := openrtb_ext.ParseBidType(bidExt.Prebid.Type) + if err != nil { + errs = append(errs, &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Bid[%d].Ext.Prebid.Type expects one of the following values: 'banner', 'native', 'video', 'audio', got '%s'", bidId, bidExt.Prebid.Type), + }) + continue + } + + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &seatBid.Bid[bidId], + BidType: bidType, + }) + } + } + + return bidResponse, errs +} diff --git a/adapters/bematterfull/bematterfulltest/exemplary/banner.json b/adapters/bematterfull/bematterfulltest/exemplary/banner.json new file mode 100644 index 00000000000..d90cc677c0f --- /dev/null +++ b/adapters/bematterfull/bematterfulltest/exemplary/banner.json @@ -0,0 +1,279 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "1", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250, + "pos": 0 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "533faf0754cd43ceab591077781b909b" + } + } + }, + { + "id": "2", + "secure": 1, + "bidfloor": 0.2, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250, + "pos": 4 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "533faf0754cd43ceab591077781b909b" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": ["IAB12"], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://prebid-srv.mtflll-system.live/?pid=533faf0754cd43ceab591077781b909b&host=mtflll-stage", + "body": { + "id": "id", + "imp": [ + { + "id": "1", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250, + "pos": 0 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "533faf0754cd43ceab591077781b909b" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": ["IAB12"], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "1", + "price": 1.2, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test2", + "adomain": ["test.com"], + "cat": ["IAB1"], + "cid": "cid", + "crid": "crid1", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + }, + { + "expectedRequest": { + "uri": "http://prebid-srv.mtflll-system.live/?pid=533faf0754cd43ceab591077781b909b&host=mtflll-stage", + "body": { + "id": "id", + "imp": [ + { + "id": "2", + "secure": 1, + "bidfloor": 0.2, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250, + "pos": 4 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "533faf0754cd43ceab591077781b909b" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": ["IAB12"], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "2", + "price": 2.4, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test3", + "adomain": ["test.com"], + "cat": ["IAB1"], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "id", + "impid": "1", + "price": 1.2, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test2", + "adomain": ["test.com"], + "cat": ["IAB1"], + "cid": "cid", + "crid": "crid1", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + }, + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "id", + "impid": "2", + "price": 2.4, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test3", + "adomain": ["test.com"], + "cat": ["IAB1"], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/bematterfull/bematterfulltest/exemplary/native.json b/adapters/bematterfull/bematterfulltest/exemplary/native.json new file mode 100644 index 00000000000..7f81dce6237 --- /dev/null +++ b/adapters/bematterfull/bematterfulltest/exemplary/native.json @@ -0,0 +1,162 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "533faf0754cd43ceab591077781b909b" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://prebid-srv.mtflll-system.live/?pid=533faf0754cd43ceab591077781b909b&host=mtflll-stage", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "533faf0754cd43ceab591077781b909b" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "{}", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "ext": { + "prebid": { + "type": "native" + } + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "{}", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "ext": { + "prebid": { + "type": "native" + } + } + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/bematterfull/bematterfulltest/exemplary/video.json b/adapters/bematterfull/bematterfulltest/exemplary/video.json new file mode 100644 index 00000000000..eb6a02a4249 --- /dev/null +++ b/adapters/bematterfull/bematterfulltest/exemplary/video.json @@ -0,0 +1,202 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "video": { + "mimes": [ + "video/mp4", + "video/ogg", + "video/webm" + ], + "minduration": 3, + "maxduration": 3000, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 480, + "h": 320, + "linearity": 1, + "playbackmethod": [ + 2 + ], + "pos": 0 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "533faf0754cd43ceab591077781b909b" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://prebid-srv.mtflll-system.live/?pid=533faf0754cd43ceab591077781b909b&host=mtflll-stage", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "video": { + "mimes": [ + "video/mp4", + "video/ogg", + "video/webm" + ], + "minduration": 3, + "maxduration": 3000, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 480, + "h": 320, + "linearity": 1, + "playbackmethod": [ + 2 + ], + "pos": 0 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "533faf0754cd43ceab591077781b909b" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "ext": { + "prebid": { + "type": "video" + } + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/bematterfull/bematterfulltest/supplemental/bad-response.json b/adapters/bematterfull/bematterfulltest/supplemental/bad-response.json new file mode 100644 index 00000000000..bf459fce210 --- /dev/null +++ b/adapters/bematterfull/bematterfulltest/supplemental/bad-response.json @@ -0,0 +1,106 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "533faf0754cd43ceab591077781b902" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://prebid-srv.mtflll-system.live/?pid=533faf0754cd43ceab591077781b902&host=mtflll-stage", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "533faf0754cd43ceab591077781b902" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": "" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/bematterfull/bematterfulltest/supplemental/empty-mediatype.json b/adapters/bematterfull/bematterfulltest/supplemental/empty-mediatype.json new file mode 100644 index 00000000000..b408c7510a7 --- /dev/null +++ b/adapters/bematterfull/bematterfulltest/supplemental/empty-mediatype.json @@ -0,0 +1,188 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "533faf0754cd43ceab591077781b902" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://prebid-srv.mtflll-system.live/?pid=533faf0754cd43ceab591077781b902&host=mtflll-stage", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "533faf0754cd43ceab591077781b902" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "1", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test1", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, { + "id": "id", + "impid": "2", + "price": 1.2, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test2", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "some": "value" + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bid[1].Ext.Prebid.Type expects one of the following values: 'banner', 'native', 'video', 'audio', got ''", + "comparison": "literal" + } + ], + "expectedBidResponses": [ + { + "currency":"USD", + "bids":[ + { + "bid": { + "id": "id", + "impid": "1", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test1", + "adomain": ["test.com"], + "cat": ["IAB1"], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/bematterfull/bematterfulltest/supplemental/empty-seatbid-0-bid.json b/adapters/bematterfull/bematterfulltest/supplemental/empty-seatbid-0-bid.json new file mode 100644 index 00000000000..94c7905832d --- /dev/null +++ b/adapters/bematterfull/bematterfulltest/supplemental/empty-seatbid-0-bid.json @@ -0,0 +1,111 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "dc230510f7eb516f0eb9a10e5913d3b5" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://prebid-srv.mtflll-system.live/?pid=dc230510f7eb516f0eb9a10e5913d3b5&host=mtflll-stage", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "dc230510f7eb516f0eb9a10e5913d3b5" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedMakeBidsErrors": [], + "expectedBidResponses": [{"currency":"USD","bids":[]}] +} diff --git a/adapters/bematterfull/bematterfulltest/supplemental/empty-seatbid.json b/adapters/bematterfull/bematterfulltest/supplemental/empty-seatbid.json new file mode 100644 index 00000000000..3a7fee5a102 --- /dev/null +++ b/adapters/bematterfull/bematterfulltest/supplemental/empty-seatbid.json @@ -0,0 +1,111 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "dc230510f7eb516f0eb9a10e5913d3b5" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://prebid-srv.mtflll-system.live/?pid=dc230510f7eb516f0eb9a10e5913d3b5&host=mtflll-stage", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "dc230510f7eb516f0eb9a10e5913d3b5" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "a1580f2f-be6d-11eb-a150-d094662c1c35", + "bidid": "359da97d0384d8a14767029c18fd840d", + "seatbid": [], + "cur": "USD" + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Array SeatBid cannot be empty", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/bematterfull/bematterfulltest/supplemental/invalid-ext-bidder-object.json b/adapters/bematterfull/bematterfulltest/supplemental/invalid-ext-bidder-object.json new file mode 100644 index 00000000000..67778fd4b8e --- /dev/null +++ b/adapters/bematterfull/bematterfulltest/supplemental/invalid-ext-bidder-object.json @@ -0,0 +1,49 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": [] + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [], + "expectedMakeRequestsErrors": [ + { + "value": "Failed to deserialize Bematterfull extension: json: cannot unmarshal array into Go value of type openrtb_ext.ExtBematterfull", + "comparison": "literal" + } + ] +} diff --git a/adapters/bematterfull/bematterfulltest/supplemental/invalid-ext-object.json b/adapters/bematterfull/bematterfulltest/supplemental/invalid-ext-object.json new file mode 100644 index 00000000000..aa215eb3e34 --- /dev/null +++ b/adapters/bematterfull/bematterfulltest/supplemental/invalid-ext-object.json @@ -0,0 +1,47 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": "" + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [], + "expectedMakeRequestsErrors": [ + { + "value": "Failed to deserialize bidder impression extension: json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "comparison": "literal" + } + ] +} diff --git a/adapters/bematterfull/bematterfulltest/supplemental/invalid-mediatype.json b/adapters/bematterfull/bematterfulltest/supplemental/invalid-mediatype.json new file mode 100644 index 00000000000..138dd7bbd5d --- /dev/null +++ b/adapters/bematterfull/bematterfulltest/supplemental/invalid-mediatype.json @@ -0,0 +1,190 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "dc230510f7eb516f0eb9a10e5913d3b5" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://prebid-srv.mtflll-system.live/?pid=dc230510f7eb516f0eb9a10e5913d3b5&host=mtflll-stage", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "dc230510f7eb516f0eb9a10e5913d3b5" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "1", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test1", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, { + "id": "id", + "impid": "2", + "price": 1.2, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test2", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "wrong" + } + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bid[1].Ext.Prebid.Type expects one of the following values: 'banner', 'native', 'video', 'audio', got 'wrong'", + "comparison": "literal" + } + ], + "expectedBidResponses": [ + { + "currency":"USD", + "bids":[ + { + "bid": { + "id": "id", + "impid": "1", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test1", + "adomain": ["test.com"], + "cat": ["IAB1"], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/bematterfull/bematterfulltest/supplemental/status-204.json b/adapters/bematterfull/bematterfulltest/supplemental/status-204.json new file mode 100644 index 00000000000..e5cf2f4096c --- /dev/null +++ b/adapters/bematterfull/bematterfulltest/supplemental/status-204.json @@ -0,0 +1,100 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "dc230510f7eb516f0eb9a10e5913d3b5" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://prebid-srv.mtflll-system.live/?pid=dc230510f7eb516f0eb9a10e5913d3b5&host=mtflll-stage", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "dc230510f7eb516f0eb9a10e5913d3b5" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/bematterfull/bematterfulltest/supplemental/status-400.json b/adapters/bematterfull/bematterfulltest/supplemental/status-400.json new file mode 100644 index 00000000000..0a74f74f751 --- /dev/null +++ b/adapters/bematterfull/bematterfulltest/supplemental/status-400.json @@ -0,0 +1,106 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "dc230510f7eb516f0eb9a10e5913d3b5" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://prebid-srv.mtflll-system.live/?pid=dc230510f7eb516f0eb9a10e5913d3b5&host=mtflll-stage", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "dc230510f7eb516f0eb9a10e5913d3b5" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 400, + "body": "The Key has a different ad format" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/bematterfull/bematterfulltest/supplemental/status-503.json b/adapters/bematterfull/bematterfulltest/supplemental/status-503.json new file mode 100644 index 00000000000..71c8936e94e --- /dev/null +++ b/adapters/bematterfull/bematterfulltest/supplemental/status-503.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "dc230510f7eb516f0eb9a10e5913d3b5" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://prebid-srv.mtflll-system.live/?pid=dc230510f7eb516f0eb9a10e5913d3b5&host=mtflll-stage", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "dc230510f7eb516f0eb9a10e5913d3b5" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 503 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bidder Bematterfull is unavailable. Please contact the bidder support.", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/bematterfull/bematterfulltest/supplemental/unexpected-status.json b/adapters/bematterfull/bematterfulltest/supplemental/unexpected-status.json new file mode 100644 index 00000000000..9f4c43ab0d2 --- /dev/null +++ b/adapters/bematterfull/bematterfulltest/supplemental/unexpected-status.json @@ -0,0 +1,106 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "dc230510f7eb516f0eb9a10e5913d3b5" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://prebid-srv.mtflll-system.live/?pid=dc230510f7eb516f0eb9a10e5913d3b5&host=mtflll-stage", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "mtflll-stage", + "pid": "dc230510f7eb516f0eb9a10e5913d3b5" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 403, + "body": "Access is denied" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 403. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/bematterfull/bematterfulltest_test.go b/adapters/bematterfull/bematterfulltest_test.go new file mode 100644 index 00000000000..f3d1f412761 --- /dev/null +++ b/adapters/bematterfull/bematterfulltest_test.go @@ -0,0 +1,27 @@ +package bematterfull + +import ( + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder( + openrtb_ext.BidderSmartHub, + config.Adapter{ + Endpoint: "http://prebid-srv.mtflll-system.live/?pid={{.SourceId}}&host={{.Host}}", + }, + config.Server{ + ExternalUrl: "http://hosturl.com", + GvlID: 1, + DataCenter: "2", + }, + ) + + assert.NoError(t, buildErr) + adapterstest.RunJSONBidderTest(t, "bematterfulltest", bidder) +} diff --git a/adapters/bematterfull/params_test.go b/adapters/bematterfull/params_test.go new file mode 100644 index 00000000000..5983dd3e375 --- /dev/null +++ b/adapters/bematterfull/params_test.go @@ -0,0 +1,53 @@ +package bematterfull + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/openrtb_ext" +) + +var validParams = []string{ + `{"env":"mtflll-stage", "pid":"123456"}`, +} + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderBematterfull, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected bematterfull params: %s", validParam) + } + } +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `[]`, + `{}`, + `{"some": "param"}`, + `{"env":"mtflll-stage"}`, + `{"pid":"1234"}`, + `{"othervalue":"Lorem ipsum"}`, + `{"env":"mtflll-stage", pid:""}`, + `{"env":"", pid:"1234"}`, +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderBematterfull, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index fb1dd69a018..84b1f1afa1a 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -44,6 +44,7 @@ import ( "github.com/prebid/prebid-server/adapters/axonix" "github.com/prebid/prebid-server/adapters/beachfront" "github.com/prebid/prebid-server/adapters/beintoo" + "github.com/prebid/prebid-server/adapters/bematterfull" "github.com/prebid/prebid-server/adapters/between" "github.com/prebid/prebid-server/adapters/beyondmedia" "github.com/prebid/prebid-server/adapters/bidmachine" @@ -237,6 +238,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderAxonix: axonix.Builder, openrtb_ext.BidderBeachfront: beachfront.Builder, openrtb_ext.BidderBeintoo: beintoo.Builder, + openrtb_ext.BidderBematterfull: bematterfull.Builder, openrtb_ext.BidderBetween: between.Builder, openrtb_ext.BidderBeyondMedia: beyondmedia.Builder, openrtb_ext.BidderBidmachine: bidmachine.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index bed2f056d60..c60b9dcabe2 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -62,6 +62,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderAxonix, BidderBeachfront, BidderBeintoo, + BidderBematterfull, BidderBetween, BidderBeyondMedia, BidderBidmachine, @@ -351,6 +352,7 @@ const ( BidderAxonix BidderName = "axonix" BidderBeachfront BidderName = "beachfront" BidderBeintoo BidderName = "beintoo" + BidderBematterfull BidderName = "bematterfull" BidderBetween BidderName = "between" BidderBeyondMedia BidderName = "beyondmedia" BidderBidmachine BidderName = "bidmachine" diff --git a/openrtb_ext/imp_bematterfull.go b/openrtb_ext/imp_bematterfull.go new file mode 100644 index 00000000000..bc3ca451a61 --- /dev/null +++ b/openrtb_ext/imp_bematterfull.go @@ -0,0 +1,6 @@ +package openrtb_ext + +type ExtBematterfull struct { + Env string `json:"env"` + Pid string `json:"pid"` +} diff --git a/static/bidder-info/bematterfull.yaml b/static/bidder-info/bematterfull.yaml new file mode 100644 index 00000000000..f4b48ee700e --- /dev/null +++ b/static/bidder-info/bematterfull.yaml @@ -0,0 +1,19 @@ +endpoint: "http://prebid-srv.mtflll-system.live/?pid={{.SourceId}}&host={{.Host}}" +maintainer: + email: "adops@bematterfull.com" +capabilities: + app: + mediaTypes: + - banner + - video + - native + site: + mediaTypes: + - banner + - video + - native +userSync: + # mtflll-system.live supports user syncing, but requires configuration by the host. contact this + # bidder directly at the email address in this file to ask about enabling user sync. + supports: + - redirect \ No newline at end of file diff --git a/static/bidder-params/bematterfull.json b/static/bidder-params/bematterfull.json new file mode 100644 index 00000000000..db3a505050c --- /dev/null +++ b/static/bidder-params/bematterfull.json @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Bematterfull Adapter Params", + "description": "A schema which validates params accepted by the bematterfull adapter", + "type": "object", + "properties": { + "env": { + "type": "string", + "description": "bematterfull environment", + "minLength": 1 + }, + "pid": { + "type": "string", + "description": "Uniq placement ID", + "minLength": 1 + } + }, + "required": [ + "env", + "pid" + ] +} From a729d40127d0f8ba33827baa3ef6b79d813b3ad3 Mon Sep 17 00:00:00 2001 From: Oscar Amat <486736+osuka@users.noreply.github.com> Date: Tue, 29 Aug 2023 07:01:09 +0100 Subject: [PATCH 095/268] added price macro expansion (#3051) co-authored by @osuka --- adapters/axonix/axonix.go | 12 ++++++++++++ .../axonix/axonixtest/exemplary/simple-banner.json | 6 ++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/adapters/axonix/axonix.go b/adapters/axonix/axonix.go index 7413cec37a3..2289050b462 100644 --- a/adapters/axonix/axonix.go +++ b/adapters/axonix/axonix.go @@ -5,6 +5,8 @@ import ( "fmt" "net/http" "net/url" + "strconv" + "strings" "text/template" "github.com/prebid/openrtb/v19/openrtb2" @@ -105,6 +107,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R for _, seatBid := range response.SeatBid { for _, bid := range seatBid.Bid { bid := bid + resolveMacros(&bid) b := &adapters.TypedBid{ Bid: &bid, BidType: getMediaType(bid.ImpID, request.Imp), @@ -129,3 +132,12 @@ func getMediaType(impId string, imps []openrtb2.Imp) openrtb_ext.BidType { } return openrtb_ext.BidTypeBanner } + +func resolveMacros(bid *openrtb2.Bid) { + if bid == nil { + return + } + price := strconv.FormatFloat(bid.Price, 'f', -1, 64) + bid.NURL = strings.Replace(bid.NURL, "${AUCTION_PRICE}", price, -1) + bid.AdM = strings.Replace(bid.AdM, "${AUCTION_PRICE}", price, -1) +} diff --git a/adapters/axonix/axonixtest/exemplary/simple-banner.json b/adapters/axonix/axonixtest/exemplary/simple-banner.json index 40441a46425..d1199b80929 100644 --- a/adapters/axonix/axonixtest/exemplary/simple-banner.json +++ b/adapters/axonix/axonixtest/exemplary/simple-banner.json @@ -67,7 +67,8 @@ "impid": "test-imp-id", "price": 0.500000, "adid": "29681110", - "adm": "some-test-ad", + "adm": "some-test-ad imp_${AUCTION_PRICE} creativeview_${AUCTION_PRICE}", + "nurl": "nurl.link/win?p=${AUCTION_PRICE}", "adomain": ["yahoo.com"], "cid": "958", "crid": "29681110", @@ -90,7 +91,8 @@ "id": "7706636740145184841", "impid": "test-imp-id", "price": 0.5, - "adm": "some-test-ad", + "adm": "some-test-ad imp_0.5 creativeview_0.5", + "nurl": "nurl.link/win?p=0.5", "adid": "29681110", "adomain": ["yahoo.com"], "cid": "958", From 72afff24a4528cf773c1240a73a7af6247fc6a77 Mon Sep 17 00:00:00 2001 From: Ashish Garg Date: Thu, 31 Aug 2023 16:15:33 +0530 Subject: [PATCH 096/268] inherit bidder params from parent for an alias (#3048) --- config/bidderinfo.go | 5 +- config/bidderinfo_test.go | 11 ++ openrtb_ext/bidders.go | 70 +++++++++--- openrtb_ext/bidders_test.go | 157 ++++++++++++++++++++++++++- openrtb_ext/bidders_validate_test.go | 3 - 5 files changed, 222 insertions(+), 24 deletions(-) diff --git a/config/bidderinfo.go b/config/bidderinfo.go index df9e9d5a78a..f2bf9ea1a6e 100644 --- a/config/bidderinfo.go +++ b/config/bidderinfo.go @@ -276,8 +276,11 @@ func processBidderAliases(aliasNillableFieldsByBidder map[string]aliasNillableFi if err := validateAliases(aliasBidderInfo, bidderInfos, bidderName); err != nil { return nil, err } + //required for CoreBidderNames function to also return aliasBiddernames - openrtb_ext.SetAliasBidderName(openrtb_ext.BidderName(string(bidderName))) + if err := openrtb_ext.SetAliasBidderName(bidderName, openrtb_ext.BidderName(aliasBidderInfo.AliasOf)); err != nil { + return nil, err + } parentBidderInfo := bidderInfos[aliasBidderInfo.AliasOf] if aliasBidderInfo.AppSecret == "" { aliasBidderInfo.AppSecret = parentBidderInfo.AppSecret diff --git a/config/bidderinfo_test.go b/config/bidderinfo_test.go index e505d2f8b77..f79e4ec5bea 100644 --- a/config/bidderinfo_test.go +++ b/config/bidderinfo_test.go @@ -434,6 +434,17 @@ func TestProcessAliasBidderInfo(t *testing.T) { }, expectedErr: errors.New("bidder info not found for an alias: bidderB"), }, + { + description: "unable to set an alias", + aliasInfos: map[string]aliasNillableFields{ + "all": {}, + }, + bidderInfos: BidderInfos{ + "bidderA": parentBidderInfo, + "all": aliasBidderInfo, + }, + expectedErr: errors.New("alias all is a reserved bidder name and cannot be used"), + }, } for _, test := range testCases { diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index c60b9dcabe2..4e4927ff3f5 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -15,7 +15,7 @@ import ( // BidderName refers to a core bidder id or an alias id. type BidderName string -var aliasBidderNames []BidderName +var aliasBidderToParent map[BidderName]BidderName = map[BidderName]BidderName{} var coreBidderNames []BidderName = []BidderName{ Bidder33Across, @@ -224,17 +224,14 @@ var coreBidderNames []BidderName = []BidderName{ BidderZetaGlobalSsp, } -func SetAliasBidderName(name BidderName) { - aliasBidderNames = append(aliasBidderNames, name) - coreBidderNames = append(coreBidderNames, name) -} - -func GetAliasBidderNamesSet() map[BidderName]struct{} { - set := map[BidderName]struct{}{} - for _, name := range aliasBidderNames { - set[name] = struct{}{} +func SetAliasBidderName(aliasBidderName string, parentBidderName BidderName) error { + if IsBidderNameReserved(aliasBidderName) { + return fmt.Errorf("alias %s is a reserved bidder name and cannot be used", aliasBidderName) } - return set + aliasBidder := BidderName(aliasBidderName) + coreBidderNames = append(coreBidderNames, aliasBidder) + aliasBidderToParent[aliasBidder] = parentBidderName + return nil } func (name BidderName) MarshalJSON() ([]byte, error) { @@ -572,10 +569,42 @@ type BidderParamValidator interface { Schema(name BidderName) string } +type bidderParamsFileSystem interface { + readDir(name string) ([]os.DirEntry, error) + readFile(name string) ([]byte, error) + newReferenceLoader(source string) gojsonschema.JSONLoader + newSchema(l gojsonschema.JSONLoader) (*gojsonschema.Schema, error) + abs(path string) (string, error) +} + +type standardBidderParamsFileSystem struct{} + +func (standardBidderParamsFileSystem) readDir(name string) ([]os.DirEntry, error) { + return os.ReadDir(name) +} + +func (standardBidderParamsFileSystem) readFile(name string) ([]byte, error) { + return os.ReadFile(name) +} + +func (standardBidderParamsFileSystem) newReferenceLoader(source string) gojsonschema.JSONLoader { + return gojsonschema.NewReferenceLoader(source) +} + +func (standardBidderParamsFileSystem) newSchema(l gojsonschema.JSONLoader) (*gojsonschema.Schema, error) { + return gojsonschema.NewSchema(l) +} + +func (standardBidderParamsFileSystem) abs(path string) (string, error) { + return filepath.Abs(path) +} + +var paramsValidator bidderParamsFileSystem = standardBidderParamsFileSystem{} + // NewBidderParamsValidator makes a BidderParamValidator, assuming all the necessary files exist in the filesystem. // This will error if, for example, a Bidder gets added but no JSON schema is written for them. func NewBidderParamsValidator(schemaDirectory string) (BidderParamValidator, error) { - fileInfos, err := os.ReadDir(schemaDirectory) + fileInfos, err := paramsValidator.readDir(schemaDirectory) if err != nil { return nil, fmt.Errorf("Failed to read JSON schemas from directory %s. %v", schemaDirectory, err) } @@ -589,17 +618,17 @@ func NewBidderParamsValidator(schemaDirectory string) (BidderParamValidator, err if _, ok := bidderMap[bidderName]; !ok { return nil, fmt.Errorf("File %s/%s does not match a valid BidderName.", schemaDirectory, fileInfo.Name()) } - toOpen, err := filepath.Abs(filepath.Join(schemaDirectory, fileInfo.Name())) + toOpen, err := paramsValidator.abs(filepath.Join(schemaDirectory, fileInfo.Name())) if err != nil { return nil, fmt.Errorf("Failed to get an absolute representation of the path: %s, %v", toOpen, err) } - schemaLoader := gojsonschema.NewReferenceLoader("file:///" + filepath.ToSlash(toOpen)) - loadedSchema, err := gojsonschema.NewSchema(schemaLoader) + schemaLoader := paramsValidator.newReferenceLoader("file:///" + filepath.ToSlash(toOpen)) + loadedSchema, err := paramsValidator.newSchema(schemaLoader) if err != nil { return nil, fmt.Errorf("Failed to load json schema at %s: %v", toOpen, err) } - fileBytes, err := os.ReadFile(fmt.Sprintf("%s/%s", schemaDirectory, fileInfo.Name())) + fileBytes, err := paramsValidator.readFile(fmt.Sprintf("%s/%s", schemaDirectory, fileInfo.Name())) if err != nil { return nil, fmt.Errorf("Failed to read file %s/%s: %v", schemaDirectory, fileInfo.Name(), err) } @@ -608,6 +637,15 @@ func NewBidderParamsValidator(schemaDirectory string) (BidderParamValidator, err schemaContents[BidderName(bidderName)] = string(fileBytes) } + //set alias bidder params schema to its parent + for alias, parent := range aliasBidderToParent { + parentSchema := schemas[parent] + schemas[alias] = parentSchema + + parentSchemaContents := schemaContents[parent] + schemaContents[alias] = parentSchemaContents + } + return &bidderParamValidator{ schemaContents: schemaContents, parsedSchemas: schemas, diff --git a/openrtb_ext/bidders_test.go b/openrtb_ext/bidders_test.go index eb60f452dc4..2176c28e184 100644 --- a/openrtb_ext/bidders_test.go +++ b/openrtb_ext/bidders_test.go @@ -2,7 +2,10 @@ package openrtb_ext import ( "encoding/json" + "errors" + "os" "testing" + "testing/fstest" "github.com/stretchr/testify/assert" "github.com/xeipuuv/gojsonschema" @@ -126,8 +129,154 @@ func TestIsBidderNameReserved(t *testing.T) { } } -func TestCoreBidderNames(t *testing.T) { - bidderA := "BidderA" - SetAliasBidderName(BidderName(bidderA)) - assert.Contains(t, CoreBidderNames(), BidderName(bidderA)) +func TestSetAliasBidderName(t *testing.T) { + parentBidder := BidderName("pBidder") + existingCoreBidderNames := coreBidderNames + + testCases := []struct { + aliasBidderName string + err error + }{ + {"aBidder", nil}, + {"all", errors.New("alias all is a reserved bidder name and cannot be used")}, + } + + for _, test := range testCases { + err := SetAliasBidderName(test.aliasBidderName, parentBidder) + if err != nil { + assert.Equal(t, test.err, err) + } else { + assert.Contains(t, CoreBidderNames(), BidderName(test.aliasBidderName)) + assert.Contains(t, aliasBidderToParent, BidderName(test.aliasBidderName)) + } + } + + //reset package variables to not interfere with other test cases. Example - TestBidderParamSchemas + coreBidderNames = existingCoreBidderNames + aliasBidderToParent = map[BidderName]BidderName{} +} + +type mockParamsHelper struct { + fs fstest.MapFS + absFilePath string + absPathErr error + schemaLoaderErr error + readFileErr error +} + +func (m *mockParamsHelper) readDir(name string) ([]os.DirEntry, error) { + return m.fs.ReadDir(name) +} + +func (m *mockParamsHelper) readFile(name string) ([]byte, error) { + if m.readFileErr != nil { + return nil, m.readFileErr + } + return m.fs.ReadFile(name) +} + +func (m *mockParamsHelper) newReferenceLoader(source string) gojsonschema.JSONLoader { + return nil +} + +func (m *mockParamsHelper) newSchema(l gojsonschema.JSONLoader) (*gojsonschema.Schema, error) { + return nil, m.schemaLoaderErr +} + +func (m *mockParamsHelper) abs(path string) (string, error) { + return m.absFilePath, m.absPathErr +} + +func TestNewBidderParamsValidator(t *testing.T) { + testCases := []struct { + description string + paramsValidator mockParamsHelper + dir string + expectedErr error + }{ + { + description: "Valid case", + paramsValidator: mockParamsHelper{ + fs: fstest.MapFS{ + "test/appnexus.json": { + Data: []byte("{}"), + }, + }, + }, + dir: "test", + }, + { + description: "failed to read directory", + paramsValidator: mockParamsHelper{}, + dir: "t", + expectedErr: errors.New("Failed to read JSON schemas from directory t. open t: file does not exist"), + }, + { + description: "file name does not match the bidder name", + paramsValidator: mockParamsHelper{ + fs: fstest.MapFS{ + "test/anyBidder.json": { + Data: []byte("{}"), + }, + }, + }, + dir: "test", + expectedErr: errors.New("File test/anyBidder.json does not match a valid BidderName."), + }, + { + description: "abs file path error", + paramsValidator: mockParamsHelper{ + fs: fstest.MapFS{ + "test/appnexus.json": { + Data: []byte("{}"), + }, + }, + absFilePath: "test/app.json", + absPathErr: errors.New("any abs error"), + }, + dir: "test", + expectedErr: errors.New("Failed to get an absolute representation of the path: test/app.json, any abs error"), + }, + { + description: "schema loader error", + paramsValidator: mockParamsHelper{ + fs: fstest.MapFS{ + "test/appnexus.json": { + Data: []byte("{}"), + }, + }, + schemaLoaderErr: errors.New("any schema loader error"), + }, + dir: "test", + expectedErr: errors.New("Failed to load json schema at : any schema loader error"), + }, + { + description: "read file error", + paramsValidator: mockParamsHelper{ + fs: fstest.MapFS{ + "test/appnexus.json": { + Data: []byte("{}"), + }, + }, + readFileErr: errors.New("any read file error"), + }, + dir: "test", + expectedErr: errors.New("Failed to read file test/appnexus.json: any read file error"), + }, + } + + for _, test := range testCases { + t.Run(test.description, func(t *testing.T) { + aliasBidderToParent = map[BidderName]BidderName{"rubicon": "appnexus"} + paramsValidator = &test.paramsValidator + bidderValidator, err := NewBidderParamsValidator(test.dir) + if test.expectedErr == nil { + assert.NoError(t, err) + assert.Contains(t, bidderValidator.Schema("appnexus"), "{}") + assert.Contains(t, bidderValidator.Schema("rubicon"), "{}") + } else { + assert.Equal(t, err, test.expectedErr) + } + }) + } } diff --git a/openrtb_ext/bidders_validate_test.go b/openrtb_ext/bidders_validate_test.go index c9528536780..33148d1ed41 100644 --- a/openrtb_ext/bidders_validate_test.go +++ b/openrtb_ext/bidders_validate_test.go @@ -24,9 +24,6 @@ var validator BidderParamValidator // returns valid JSON for all known CoreBidderNames. func TestBidderParamSchemas(t *testing.T) { for _, bidderName := range CoreBidderNames() { - if _, ok := GetAliasBidderNamesSet()[bidderName]; ok { - continue - } schema := validator.Schema(bidderName) if schema == "" { t.Errorf("No schema exists for bidder %s. Does static/bidder-params/%s.json exist?", bidderName, bidderName) From 47f840d66c3e9e7b24e3ce96dca476a503991136 Mon Sep 17 00:00:00 2001 From: jmayor Date: Mon, 4 Sep 2023 08:48:40 -0400 Subject: [PATCH 097/268] Update datablocks adapter (#2838) --- adapters/datablocks/datablocks.go | 12 ++----- adapters/datablocks/datablocks_test.go | 2 +- .../exemplary/multi-request.json | 10 +++--- .../datablockstest/exemplary/native.json | 6 ++-- .../exemplary/simple-banner.json | 6 ++-- .../exemplary/simple-video.json | 6 ++-- .../datablockstest/supplemental/bad-host.json | 33 ------------------- .../supplemental/bad-response-body.json | 6 ++-- .../supplemental/bad-server-response.json | 6 ++-- .../supplemental/bad-sourceId.json | 2 +- .../supplemental/missing-extparam.json | 30 ----------------- .../supplemental/no-content-response.json | 6 ++-- openrtb_ext/imp_datablocks.go | 3 +- static/bidder-info/datablocks.yaml | 2 +- static/bidder-params/datablocks.json | 6 +--- 15 files changed, 31 insertions(+), 105 deletions(-) delete mode 100644 adapters/datablocks/datablockstest/supplemental/bad-host.json delete mode 100644 adapters/datablocks/datablockstest/supplemental/missing-extparam.json diff --git a/adapters/datablocks/datablocks.go b/adapters/datablocks/datablocks.go index 8929c84853a..a39721a44a3 100644 --- a/adapters/datablocks/datablocks.go +++ b/adapters/datablocks/datablocks.go @@ -27,7 +27,7 @@ func (a *DatablocksAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo * "Accept": {"application/json"}, } - // Pull the host and source ID info from the bidder params. + // Pull the source ID info from the bidder params. reqImps, err := splitImpressions(request.Imp) if err != nil { @@ -45,7 +45,7 @@ func (a *DatablocksAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo * continue } - urlParams := macros.EndpointTemplateParams{Host: reqExt.Host, SourceId: strconv.Itoa(reqExt.SourceId)} + urlParams := macros.EndpointTemplateParams{SourceId: strconv.Itoa(reqExt.SourceId)} url, err := macros.ResolveMacros(a.EndpointTemplate, urlParams) if err != nil { @@ -137,7 +137,7 @@ func getBidderParams(imp *openrtb2.Imp) (*openrtb_ext.ExtImpDatablocks, error) { var datablocksExt openrtb_ext.ExtImpDatablocks if err := json.Unmarshal(bidderExt.Bidder, &datablocksExt); err != nil { return nil, &errortypes.BadInput{ - Message: fmt.Sprintf("Cannot Resolve host or sourceId: %s", err.Error()), + Message: fmt.Sprintf("Cannot Resolve sourceId: %s", err.Error()), } } @@ -147,12 +147,6 @@ func getBidderParams(imp *openrtb2.Imp) (*openrtb_ext.ExtImpDatablocks, error) { } } - if len(datablocksExt.Host) < 1 { - return nil, &errortypes.BadInput{ - Message: "Invalid/Missing Host", - } - } - return &datablocksExt, nil } diff --git a/adapters/datablocks/datablocks_test.go b/adapters/datablocks/datablocks_test.go index 9a5fb9a23f4..3d4d746d357 100644 --- a/adapters/datablocks/datablocks_test.go +++ b/adapters/datablocks/datablocks_test.go @@ -11,7 +11,7 @@ import ( func TestJsonSamples(t *testing.T) { bidder, buildErr := Builder(openrtb_ext.BidderDatablocks, config.Adapter{ - Endpoint: "http://{{.Host}}/openrtb2?sid={{.SourceId}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + Endpoint: "http://pbserver.dblks.net/openrtb2?sid={{.SourceId}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) if buildErr != nil { t.Fatalf("Builder returned unexpected error %v", buildErr) diff --git a/adapters/datablocks/datablockstest/exemplary/multi-request.json b/adapters/datablocks/datablockstest/exemplary/multi-request.json index 286e058a72e..eafd80927fa 100644 --- a/adapters/datablocks/datablockstest/exemplary/multi-request.json +++ b/adapters/datablocks/datablockstest/exemplary/multi-request.json @@ -17,7 +17,7 @@ { "bidder": { - "host": "search.nutella.datablocks.net", + "host": "pbserver.dblks.net", "sourceId": 906295 } } @@ -34,7 +34,7 @@ { "bidder": { - "host": "search.nutella.datablocks.net", + "host": "pbserver.dblks.net", "sourceId": 906295 } } @@ -54,7 +54,7 @@ { "expectedRequest": { - "uri": "http://search.nutella.datablocks.net/openrtb2?sid=906295", + "uri": "http://pbserver.dblks.net/openrtb2?sid=906295", "body": { "id": "some-request-id", @@ -73,7 +73,7 @@ { "bidder": { - "host": "search.nutella.datablocks.net", + "host": "pbserver.dblks.net", "sourceId": 906295 } } @@ -91,7 +91,7 @@ { "bidder": { - "host": "search.nutella.datablocks.net", + "host": "pbserver.dblks.net", "sourceId": 906295 } } diff --git a/adapters/datablocks/datablockstest/exemplary/native.json b/adapters/datablocks/datablockstest/exemplary/native.json index 9487079c734..c4cf189e1b4 100644 --- a/adapters/datablocks/datablockstest/exemplary/native.json +++ b/adapters/datablocks/datablockstest/exemplary/native.json @@ -14,7 +14,7 @@ { "bidder": { - "host": "search.nutella.datablocks.net", + "host": "pbserver.dblks.net", "sourceId": 906295 } } @@ -38,7 +38,7 @@ { "expectedRequest": { - "uri": "http://search.nutella.datablocks.net/openrtb2?sid=906295", + "uri": "http://pbserver.dblks.net/openrtb2?sid=906295", "body": { "id": "some-request-id", @@ -54,7 +54,7 @@ { "bidder": { - "host": "search.nutella.datablocks.net", + "host": "pbserver.dblks.net", "sourceId": 906295 } } diff --git a/adapters/datablocks/datablockstest/exemplary/simple-banner.json b/adapters/datablocks/datablockstest/exemplary/simple-banner.json index 289549ab588..5c01a29a519 100644 --- a/adapters/datablocks/datablockstest/exemplary/simple-banner.json +++ b/adapters/datablocks/datablockstest/exemplary/simple-banner.json @@ -21,7 +21,7 @@ { "bidder": { - "host": "search.nutella.datablocks.net", + "host": "pbserver.dblks.net", "sourceId": 906295 } } @@ -41,7 +41,7 @@ { "expectedRequest": { - "uri": "http://search.nutella.datablocks.net/openrtb2?sid=906295", + "uri": "http://pbserver.dblks.net/openrtb2?sid=906295", "body": { "id": "some-request-id", @@ -64,7 +64,7 @@ { "bidder": { - "host": "search.nutella.datablocks.net", + "host": "pbserver.dblks.net", "sourceId": 906295 } } diff --git a/adapters/datablocks/datablockstest/exemplary/simple-video.json b/adapters/datablocks/datablockstest/exemplary/simple-video.json index 6f8073107f3..fcb2defa649 100644 --- a/adapters/datablocks/datablockstest/exemplary/simple-video.json +++ b/adapters/datablocks/datablockstest/exemplary/simple-video.json @@ -18,7 +18,7 @@ { "bidder": { - "host": "search.nutella.datablocks.net", + "host": "pbserver.dblks.net", "sourceId": 906295 } } @@ -39,7 +39,7 @@ { "expectedRequest": { - "uri": "http://search.nutella.datablocks.net/openrtb2?sid=906295", + "uri": "http://pbserver.dblks.net/openrtb2?sid=906295", "body": { "id": "some-request-id", @@ -59,7 +59,7 @@ { "bidder": { - "host": "search.nutella.datablocks.net", + "host": "pbserver.dblks.net", "sourceId": 906295 } } diff --git a/adapters/datablocks/datablockstest/supplemental/bad-host.json b/adapters/datablocks/datablockstest/supplemental/bad-host.json deleted file mode 100644 index cee5efbe760..00000000000 --- a/adapters/datablocks/datablockstest/supplemental/bad-host.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "mockBidRequest": { - "id": "bad-host-test", - "imp": [ - { - "id": "bad-host-test-imp", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": - { - "bidder": - { - "host": "", - "sourceId": 123 - } - } - } - ] - }, - - "expectedMakeRequestsErrors": [ - { - "value": "Invalid/Missing Host", - "comparison": "literal" - } - ] -} diff --git a/adapters/datablocks/datablockstest/supplemental/bad-response-body.json b/adapters/datablocks/datablockstest/supplemental/bad-response-body.json index 7c4801e1685..e60c6aabb7d 100644 --- a/adapters/datablocks/datablockstest/supplemental/bad-response-body.json +++ b/adapters/datablocks/datablockstest/supplemental/bad-response-body.json @@ -17,7 +17,7 @@ { "bidder": { - "host": "search.nutella.datablocks.net", + "host": "pbserver.dblks.net", "sourceId": 123 } } @@ -37,7 +37,7 @@ { "expectedRequest": { - "uri": "http://search.nutella.datablocks.net/openrtb2?sid=123", + "uri": "http://pbserver.dblks.net/openrtb2?sid=123", "body": { "id": "some-request-id", @@ -56,7 +56,7 @@ { "bidder": { - "host": "search.nutella.datablocks.net", + "host": "pbserver.dblks.net", "sourceId": 123 } } diff --git a/adapters/datablocks/datablockstest/supplemental/bad-server-response.json b/adapters/datablocks/datablockstest/supplemental/bad-server-response.json index da2924f6f21..cdcc0c37d4c 100644 --- a/adapters/datablocks/datablockstest/supplemental/bad-server-response.json +++ b/adapters/datablocks/datablockstest/supplemental/bad-server-response.json @@ -17,7 +17,7 @@ { "bidder": { - "host": "search.nutella.datablocks.net", + "host": "pbserver.dblks.net", "sourceId": 123 } } @@ -37,7 +37,7 @@ { "expectedRequest": { - "uri": "http://search.nutella.datablocks.net/openrtb2?sid=123", + "uri": "http://pbserver.dblks.net/openrtb2?sid=123", "body": { "id": "some-request-id", @@ -56,7 +56,7 @@ { "bidder": { - "host": "search.nutella.datablocks.net", + "host": "pbserver.dblks.net", "sourceId": 123 } } diff --git a/adapters/datablocks/datablockstest/supplemental/bad-sourceId.json b/adapters/datablocks/datablockstest/supplemental/bad-sourceId.json index 08f2fddf568..3182e71dc84 100644 --- a/adapters/datablocks/datablockstest/supplemental/bad-sourceId.json +++ b/adapters/datablocks/datablockstest/supplemental/bad-sourceId.json @@ -16,7 +16,7 @@ { "bidder": { - "host": "search.nutella.datablocks.net", + "host": "pbserver.dblks.net", "sourceId": 0 } } diff --git a/adapters/datablocks/datablockstest/supplemental/missing-extparam.json b/adapters/datablocks/datablockstest/supplemental/missing-extparam.json deleted file mode 100644 index d272cd5347c..00000000000 --- a/adapters/datablocks/datablockstest/supplemental/missing-extparam.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "mockBidRequest": { - "id": "missing-extbid-test", - "imp": [ - { - "id": "missing-extbid-test", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "sourceId":54326 - } - } - ] - }, - - "expectedMakeRequestsErrors": [ - { - "value": "Cannot Resolve host or sourceId: unexpected end of JSON input", - "comparison": "literal" - } - ] - - -} diff --git a/adapters/datablocks/datablockstest/supplemental/no-content-response.json b/adapters/datablocks/datablockstest/supplemental/no-content-response.json index 7fc1b75c3ad..0e53f4720a9 100644 --- a/adapters/datablocks/datablockstest/supplemental/no-content-response.json +++ b/adapters/datablocks/datablockstest/supplemental/no-content-response.json @@ -17,7 +17,7 @@ { "bidder": { - "host": "search.nutella.datablocks.net", + "host": "pbserver.dblks.net", "sourceId": 123 } } @@ -37,7 +37,7 @@ { "expectedRequest": { - "uri": "http://search.nutella.datablocks.net/openrtb2?sid=123", + "uri": "http://pbserver.dblks.net/openrtb2?sid=123", "body": { "id": "some-request-id", @@ -56,7 +56,7 @@ { "bidder": { - "host": "search.nutella.datablocks.net", + "host": "pbserver.dblks.net", "sourceId": 123 } } diff --git a/openrtb_ext/imp_datablocks.go b/openrtb_ext/imp_datablocks.go index c8659d3ff11..dc3bae3f3fe 100644 --- a/openrtb_ext/imp_datablocks.go +++ b/openrtb_ext/imp_datablocks.go @@ -2,6 +2,5 @@ package openrtb_ext // ExtImpDatablocks defines the contract for bidrequest.imp[i].ext.prebid.bidder.datablocks type ExtImpDatablocks struct { - SourceId int `json:"sourceId"` - Host string `json:"host"` + SourceId int `json:"sourceId"` } diff --git a/static/bidder-info/datablocks.yaml b/static/bidder-info/datablocks.yaml index 418b0cabc1e..1f8d6e8d089 100644 --- a/static/bidder-info/datablocks.yaml +++ b/static/bidder-info/datablocks.yaml @@ -1,4 +1,4 @@ -endpoint: "http://{{.Host}}/openrtb2?sid={{.SourceId}}" +endpoint: "http://pbserver.dblks.net/openrtb2?sid={{.SourceId}}" maintainer: email: "prebid@datablocks.net" capabilities: diff --git a/static/bidder-params/datablocks.json b/static/bidder-params/datablocks.json index 2abb986786b..59b7f94706c 100644 --- a/static/bidder-params/datablocks.json +++ b/static/bidder-params/datablocks.json @@ -9,11 +9,7 @@ "type": "integer", "minimum": 1, "description": "Website Source Id" - }, - "host": { - "type": "string", - "description": "Network Host to request from" } }, - "required": ["host", "sourceId"] + "required": ["sourceId"] } From 55fcb1c0824d8d0d64565655455cb255bf1b3685 Mon Sep 17 00:00:00 2001 From: Ashish Garg Date: Tue, 5 Sep 2023 11:20:32 +0530 Subject: [PATCH 098/268] Fix few adapter aliases bug (#3055) --- config/bidderinfo.go | 28 ++++++++++++++++++---------- config/bidderinfo_test.go | 20 ++++++++------------ openrtb_ext/bidders.go | 8 ++++++-- router/router.go | 9 +++++++++ router/router_test.go | 6 ++++-- 5 files changed, 45 insertions(+), 26 deletions(-) diff --git a/config/bidderinfo.go b/config/bidderinfo.go index f2bf9ea1a6e..96d6fd15bfc 100644 --- a/config/bidderinfo.go +++ b/config/bidderinfo.go @@ -241,17 +241,11 @@ func processBidderInfos(reader InfoReader, normalizeBidderName func(string) (ope for fileName, data := range bidderConfigs { bidderName := strings.Split(fileName, ".") if len(bidderName) == 2 && bidderName[1] == "yaml" { - normalizedBidderName, bidderNameExists := normalizeBidderName(bidderName[0]) - if !bidderNameExists { - return nil, fmt.Errorf("error parsing config for bidder %s: unknown bidder", fileName) - } info := BidderInfo{} if err := yaml.Unmarshal(data, &info); err != nil { return nil, fmt.Errorf("error parsing config for bidder %s: %v", fileName, err) } - bidderInfos[string(normalizedBidderName)] = info - //need to maintain nullable fields from BidderInfo struct into bidderInfoNullableFields //to handle the default values in aliases yaml if len(info.AliasOf) > 0 { @@ -260,7 +254,25 @@ func processBidderInfos(reader InfoReader, normalizeBidderName func(string) (ope return nil, fmt.Errorf("error parsing config for aliased bidder %s: %v", fileName, err) } + //required for CoreBidderNames function to also return aliasBiddernames + if err := openrtb_ext.SetAliasBidderName(bidderName[0], openrtb_ext.BidderName(info.AliasOf)); err != nil { + return nil, err + } + + normalizedBidderName, bidderNameExists := normalizeBidderName(bidderName[0]) + if !bidderNameExists { + return nil, fmt.Errorf("error parsing config for an alias %s: unknown bidder", fileName) + } + aliasNillableFieldsByBidder[string(normalizedBidderName)] = aliasFields + bidderInfos[string(normalizedBidderName)] = info + } else { + normalizedBidderName, bidderNameExists := normalizeBidderName(bidderName[0]) + if !bidderNameExists { + return nil, fmt.Errorf("error parsing config for bidder %s: unknown bidder", fileName) + } + + bidderInfos[string(normalizedBidderName)] = info } } } @@ -277,10 +289,6 @@ func processBidderAliases(aliasNillableFieldsByBidder map[string]aliasNillableFi return nil, err } - //required for CoreBidderNames function to also return aliasBiddernames - if err := openrtb_ext.SetAliasBidderName(bidderName, openrtb_ext.BidderName(aliasBidderInfo.AliasOf)); err != nil { - return nil, err - } parentBidderInfo := bidderInfos[aliasBidderInfo.AliasOf] if aliasBidderInfo.AppSecret == "" { aliasBidderInfo.AppSecret = parentBidderInfo.AppSecret diff --git a/config/bidderinfo_test.go b/config/bidderinfo_test.go index f79e4ec5bea..77625c0cdd0 100644 --- a/config/bidderinfo_test.go +++ b/config/bidderinfo_test.go @@ -152,6 +152,14 @@ func TestProcessBidderInfo(t *testing.T) { expectedBidderInfos: nil, expectError: "error parsing config for bidder bidderA.yaml", }, + { + description: "Invalid alias name", + bidderInfos: map[string][]byte{ + "all.yaml": []byte(testSimpleAliasYAML), + }, + expectedBidderInfos: nil, + expectError: "alias all is a reserved bidder name and cannot be used", + }, { description: "Valid aliases", bidderInfos: map[string][]byte{ @@ -434,17 +442,6 @@ func TestProcessAliasBidderInfo(t *testing.T) { }, expectedErr: errors.New("bidder info not found for an alias: bidderB"), }, - { - description: "unable to set an alias", - aliasInfos: map[string]aliasNillableFields{ - "all": {}, - }, - bidderInfos: BidderInfos{ - "bidderA": parentBidderInfo, - "all": aliasBidderInfo, - }, - expectedErr: errors.New("alias all is a reserved bidder name and cannot be used"), - }, } for _, test := range testCases { @@ -453,7 +450,6 @@ func TestProcessAliasBidderInfo(t *testing.T) { assert.Equal(t, test.expectedErr, err) } else { assert.Equal(t, test.expectedBidderInfos, bidderInfos) - assert.Contains(t, openrtb_ext.CoreBidderNames(), openrtb_ext.BidderName("bidderB")) } } } diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 4e4927ff3f5..c60058ebb38 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -224,6 +224,10 @@ var coreBidderNames []BidderName = []BidderName{ BidderZetaGlobalSsp, } +func GetAliasBidderToParent() map[BidderName]BidderName { + return aliasBidderToParent +} + func SetAliasBidderName(aliasBidderName string, parentBidderName BidderName) error { if IsBidderNameReserved(aliasBidderName) { return fmt.Errorf("alias %s is a reserved bidder name and cannot be used", aliasBidderName) @@ -552,11 +556,11 @@ var bidderNameLookup = func() map[string]BidderName { lookup[bidderNameLower] = name } return lookup -}() +} func NormalizeBidderName(name string) (BidderName, bool) { nameLower := strings.ToLower(name) - bidderName, exists := bidderNameLookup[nameLower] + bidderName, exists := bidderNameLookup()[nameLower] return bidderName, exists } diff --git a/router/router.go b/router/router.go index fcf674b4143..f7270445ff4 100644 --- a/router/router.go +++ b/router/router.go @@ -55,6 +55,10 @@ import ( // This function stores the file contents in memory, and should not be used on large directories. // If the root directory, or any of the files in it, cannot be read, then the program will exit. func NewJsonDirectoryServer(schemaDirectory string, validator openrtb_ext.BidderParamValidator, aliases map[string]string) httprouter.Handle { + return newJsonDirectoryServer(schemaDirectory, validator, aliases, openrtb_ext.GetAliasBidderToParent()) +} + +func newJsonDirectoryServer(schemaDirectory string, validator openrtb_ext.BidderParamValidator, aliases map[string]string, yamlAliases map[openrtb_ext.BidderName]openrtb_ext.BidderName) httprouter.Handle { // Slurp the files into memory first, since they're small and it minimizes request latency. files, err := os.ReadDir(schemaDirectory) if err != nil { @@ -73,6 +77,11 @@ func NewJsonDirectoryServer(schemaDirectory string, validator openrtb_ext.Bidder data[bidder] = json.RawMessage(validator.Schema(bidderName)) } + // Add in any aliases + for aliasName, parentBidder := range yamlAliases { + data[string(aliasName)] = json.RawMessage(validator.Schema(parentBidder)) + } + // Add in any default aliases for aliasName, bidderName := range aliases { bidderData, ok := data[bidderName] diff --git a/router/router_test.go b/router/router_test.go index 2b4ff7fd3e7..41c2a724c91 100644 --- a/router/router_test.go +++ b/router/router_test.go @@ -37,8 +37,9 @@ func ensureHasKey(t *testing.T, data map[string]json.RawMessage, key string) { } func TestNewJsonDirectoryServer(t *testing.T) { - alias := map[string]string{"aliastest": "appnexus"} - handler := NewJsonDirectoryServer("../static/bidder-params", &testValidator{}, alias) + defaultAlias := map[string]string{"aliastest": "appnexus"} + yamlAlias := map[openrtb_ext.BidderName]openrtb_ext.BidderName{openrtb_ext.BidderName("alias"): openrtb_ext.BidderName("parentAlias")} + handler := newJsonDirectoryServer("../static/bidder-params", &testValidator{}, defaultAlias, yamlAlias) recorder := httptest.NewRecorder() request, _ := http.NewRequest("GET", "/whatever", nil) handler(recorder, request, nil) @@ -59,6 +60,7 @@ func TestNewJsonDirectoryServer(t *testing.T) { } ensureHasKey(t, data, "aliastest") + ensureHasKey(t, data, "alias") } func TestCheckSupportedUserSyncEndpoints(t *testing.T) { From 115e24f58efe0ba2ad496d9e5a5b98a6d8ab9243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20Faruk=20Karaku=C5=9F?= <65093478+ahmetfaruk59@users.noreply.github.com> Date: Tue, 5 Sep 2023 09:17:27 +0300 Subject: [PATCH 099/268] Update HuaweiAds email (#3071) --- static/bidder-info/huaweiads.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/bidder-info/huaweiads.yaml b/static/bidder-info/huaweiads.yaml index 8fe35b4e012..fc36ff953bd 100644 --- a/static/bidder-info/huaweiads.yaml +++ b/static/bidder-info/huaweiads.yaml @@ -1,7 +1,7 @@ endpoint: "https://acd.op.hicloud.com/ppsadx/getResult" disabled: true maintainer: - email: hwads@huawei.com + email: prebid@huawei.com gvlVendorID: 856 modifyingVastXmlAllowed: true capabilities: From 7373aa6c8b62a0565611fe28b497da66f887772c Mon Sep 17 00:00:00 2001 From: Irakli Gotsiridze Date: Tue, 5 Sep 2023 09:22:20 +0300 Subject: [PATCH 100/268] Sovrn: Adapter update user sync urls for gpp (#3061) Co-authored-by: Dmitry Borisenko Co-authored-by: Dmitry Borisenko --- static/bidder-info/sovrn.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/static/bidder-info/sovrn.yaml b/static/bidder-info/sovrn.yaml index 06dadcf9a05..62d74152b0b 100644 --- a/static/bidder-info/sovrn.yaml +++ b/static/bidder-info/sovrn.yaml @@ -17,6 +17,5 @@ userSync: url: "https://ap.lijit.com/pixel?redir={{.RedirectURL}}" userMacro: "$UID" iframe: - url: "https://ap.lijit.com/beacon/prebid-server/?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&url={{.RedirectURL}}" + url: "https://ap.lijit.com/beacon/prebid-server/?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&url={{.RedirectURL}}" userMacro: "$UID" - \ No newline at end of file From 89f79e3dc4c94a71b0ca85592a33a9197952c8ea Mon Sep 17 00:00:00 2001 From: Veronika Solovei Date: Tue, 5 Sep 2023 10:09:13 -0700 Subject: [PATCH 101/268] IP scrubber (#2990) * Added anonymizeIpv6 function to transmitPreciseGeo activitiy to match PBS-Java implementation * Rename and unit test refactoring * Replaced existing ip scrubbing function with new scrubIp function. Works both for ipv4 and ipv6 * Minor refactoring * Added ipv4 and ipv6 scrubbing config * Pointers refactoring * Naming refactoring * Unit tests * Naming refactoring * refactored IPv6 and IPv4 masking config to have just one value `left_mask_bits` * Unit tests * Test rename * Config refactoring, rename left-mask-bits to anon-keep-bits * Merge fixes * Refactoring * Refactoring * Constant rename and comments remove * Code refactoring and default IPv6 and IPv4 values set --- account/account.go | 10 +- account/account_test.go | 20 +- config/account.go | 31 +++- config/account_test.go | 46 +++++ config/config.go | 9 +- config/config_test.go | 11 ++ endpoints/cookie_sync.go | 2 +- endpoints/cookie_sync_test.go | 2 +- endpoints/openrtb2/amp_auction.go | 2 +- endpoints/openrtb2/auction.go | 2 +- endpoints/openrtb2/video_auction.go | 2 +- endpoints/openrtb2/video_auction_test.go | 4 +- endpoints/setuid.go | 2 +- exchange/utils.go | 2 +- exchange/utils_test.go | 28 +-- privacy/activitycontrol.go | 2 +- privacy/activitycontrol_test.go | 44 ++--- privacy/enforcement.go | 20 +- privacy/enforcement_test.go | 30 +-- privacy/scrubber.go | 86 +++------ privacy/scrubber_test.go | 225 ++++++++++------------- util/iputil/parse.go | 8 + 22 files changed, 324 insertions(+), 264 deletions(-) diff --git a/account/account.go b/account/account.go index 052d01994ce..156ad5e6d39 100644 --- a/account/account.go +++ b/account/account.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "github.com/buger/jsonparser" "github.com/prebid/go-gdpr/consentconstants" "github.com/prebid/prebid-server/config" @@ -12,6 +11,7 @@ import ( "github.com/prebid/prebid-server/metrics" "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/stored_requests" + "github.com/prebid/prebid-server/util/iputil" jsonpatch "gopkg.in/evanphx/json-patch.v4" ) @@ -103,6 +103,14 @@ func GetAccount(ctx context.Context, cfg *config.Configuration, fetcher stored_r return nil, errs } + if ipV6Err := account.Privacy.IPv6Config.Validate(nil); len(ipV6Err) > 0 { + account.Privacy.IPv6Config.AnonKeepBits = iputil.IPv6DefaultMaskingBitSize + } + + if ipV4Err := account.Privacy.IPv4Config.Validate(nil); len(ipV4Err) > 0 { + account.Privacy.IPv4Config.AnonKeepBits = iputil.IPv4DefaultMaskingBitSize + } + // set the value of events.enabled field based on deprecated events_enabled field and ensure backward compatibility deprecateEventsEnabledField(account) diff --git a/account/account_test.go b/account/account_test.go index 4bac0894577..d2694abc5a1 100644 --- a/account/account_test.go +++ b/account/account_test.go @@ -12,17 +12,19 @@ import ( "github.com/prebid/prebid-server/metrics" "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/stored_requests" + "github.com/prebid/prebid-server/util/iputil" "github.com/prebid/prebid-server/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) var mockAccountData = map[string]json.RawMessage{ - "valid_acct": json.RawMessage(`{"disabled":false}`), - "disabled_acct": json.RawMessage(`{"disabled":true}`), - "malformed_acct": json.RawMessage(`{"disabled":"invalid type"}`), - "gdpr_channel_enabled_acct": json.RawMessage(`{"disabled":false,"gdpr":{"channel_enabled":{"amp":true}}}`), - "ccpa_channel_enabled_acct": json.RawMessage(`{"disabled":false,"ccpa":{"channel_enabled":{"amp":true}}}`), + "valid_acct": json.RawMessage(`{"disabled":false}`), + "invalid_acct_ipv6_ipv4": json.RawMessage(`{"disabled":false, "privacy": {"ipv6": {"anon_keep_bits": -32}, "ipv4": {"anon_keep_bits": -16}}}`), + "disabled_acct": json.RawMessage(`{"disabled":true}`), + "malformed_acct": json.RawMessage(`{"disabled":"invalid type"}`), + "gdpr_channel_enabled_acct": json.RawMessage(`{"disabled":false,"gdpr":{"channel_enabled":{"amp":true}}}`), + "ccpa_channel_enabled_acct": json.RawMessage(`{"disabled":false,"ccpa":{"channel_enabled":{"amp":true}}}`), "gdpr_channel_enabled_deprecated_purpose_acct": json.RawMessage(`{"disabled":false,"gdpr":{"purpose1":{"enforce_purpose":"full"}, "channel_enabled":{"amp":true}}}`), "gdpr_deprecated_purpose1": json.RawMessage(`{"disabled":false,"gdpr":{"purpose1":{"enforce_purpose":"full"}}}`), "gdpr_deprecated_purpose2": json.RawMessage(`{"disabled":false,"gdpr":{"purpose2":{"enforce_purpose":"full"}}}`), @@ -54,6 +56,8 @@ func TestGetAccount(t *testing.T) { required bool // account_defaults.disabled disabled bool + // checkDefaultIP indicates IPv6 and IPv6 should be set to default values + checkDefaultIP bool // expected error, or nil if account should be found err error }{ @@ -78,6 +82,8 @@ func TestGetAccount(t *testing.T) { {accountID: "valid_acct", required: false, disabled: true, err: nil}, {accountID: "valid_acct", required: true, disabled: true, err: nil}, + {accountID: "invalid_acct_ipv6_ipv4", required: true, disabled: false, err: nil, checkDefaultIP: true}, + // pubID given and matches a host account explicitly disabled (Disabled: true on account json) {accountID: "disabled_acct", required: false, disabled: false, err: &errortypes.BlacklistedAcct{}}, {accountID: "disabled_acct", required: true, disabled: false, err: &errortypes.BlacklistedAcct{}}, @@ -129,6 +135,10 @@ func TestGetAccount(t *testing.T) { assert.Nil(t, account, "return account must be nil on error") assert.IsType(t, test.err, errors[0], "error is of unexpected type") } + if test.checkDefaultIP { + assert.Equal(t, account.Privacy.IPv6Config.AnonKeepBits, iputil.IPv6DefaultMaskingBitSize, "ipv6 should be set to default value") + assert.Equal(t, account.Privacy.IPv4Config.AnonKeepBits, iputil.IPv4DefaultMaskingBitSize, "ipv4 should be set to default value") + } }) } } diff --git a/config/account.go b/config/account.go index 020402114de..038a8daaf9e 100644 --- a/config/account.go +++ b/config/account.go @@ -8,6 +8,7 @@ import ( "github.com/prebid/go-gdpr/consentconstants" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/iputil" ) // ChannelType enumerates the values of integrations Prebid Server can configure for an account @@ -40,7 +41,7 @@ type Account struct { Validations Validations `mapstructure:"validations" json:"validations"` DefaultBidLimit int `mapstructure:"default_bid_limit" json:"default_bid_limit"` BidAdjustments *openrtb_ext.ExtRequestPrebidBidAdjustments `mapstructure:"bidadjustments" json:"bidadjustments"` - Privacy *AccountPrivacy `mapstructure:"privacy" json:"privacy"` + Privacy AccountPrivacy `mapstructure:"privacy" json:"privacy"` } // CookieSync represents the account-level defaults for the cookie sync endpoint. @@ -295,5 +296,31 @@ func (a *AccountChannel) IsSet() bool { } type AccountPrivacy struct { - AllowActivities AllowActivities `mapstructure:"allowactivities" json:"allowactivities"` + AllowActivities *AllowActivities `mapstructure:"allowactivities" json:"allowactivities"` + IPv6Config IPv6 `mapstructure:"ipv6" json:"ipv6"` + IPv4Config IPv4 `mapstructure:"ipv4" json:"ipv4"` +} + +type IPv6 struct { + AnonKeepBits int `mapstructure:"anon_keep_bits" json:"anon_keep_bits"` +} + +type IPv4 struct { + AnonKeepBits int `mapstructure:"anon_keep_bits" json:"anon_keep_bits"` +} + +func (ip *IPv6) Validate(errs []error) []error { + if ip.AnonKeepBits > iputil.IPv6BitSize || ip.AnonKeepBits < 0 { + err := fmt.Errorf("bits cannot exceed %d in ipv6 address, or be less than 0", iputil.IPv6BitSize) + errs = append(errs, err) + } + return errs +} + +func (ip *IPv4) Validate(errs []error) []error { + if ip.AnonKeepBits > iputil.IPv4BitSize || ip.AnonKeepBits < 0 { + err := fmt.Errorf("bits cannot exceed %d in ipv4 address, or be less than 0", iputil.IPv4BitSize) + errs = append(errs, err) + } + return errs } diff --git a/config/account_test.go b/config/account_test.go index 20c6053246e..31d9796a622 100644 --- a/config/account_test.go +++ b/config/account_test.go @@ -910,3 +910,49 @@ func TestAccountPriceFloorsValidate(t *testing.T) { }) } } + +func TestIPMaskingValidate(t *testing.T) { + tests := []struct { + name string + privacy AccountPrivacy + want []error + }{ + { + name: "valid", + privacy: AccountPrivacy{ + IPv4Config: IPv4{AnonKeepBits: 1}, + IPv6Config: IPv6{AnonKeepBits: 0}, + }, + }, + { + name: "invalid", + privacy: AccountPrivacy{ + IPv4Config: IPv4{AnonKeepBits: -100}, + IPv6Config: IPv6{AnonKeepBits: -200}, + }, + want: []error{ + errors.New("bits cannot exceed 32 in ipv4 address, or be less than 0"), + errors.New("bits cannot exceed 128 in ipv6 address, or be less than 0"), + }, + }, + { + name: "mixed", + privacy: AccountPrivacy{ + IPv4Config: IPv4{AnonKeepBits: 10}, + IPv6Config: IPv6{AnonKeepBits: -10}, + }, + want: []error{ + errors.New("bits cannot exceed 128 in ipv6 address, or be less than 0"), + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var errs []error + errs = tt.privacy.IPv4Config.Validate(errs) + errs = tt.privacy.IPv6Config.Validate(errs) + assert.ElementsMatch(t, errs, tt.want) + }) + } +} diff --git a/config/config.go b/config/config.go index 2b539c578d5..e564c34ae3a 100644 --- a/config/config.go +++ b/config/config.go @@ -149,12 +149,11 @@ func (cfg *Configuration) validate(v *viper.Viper) []error { errs = append(errs, errors.New("account_defaults.Events.VASTEvents has no effect as the feature is under development.")) } - if cfg.AccountDefaults.Privacy != nil { - glog.Warning("account_defaults.Privacy has no effect as the feature is under development.") - } - errs = cfg.Experiment.validate(errs) errs = cfg.BidderInfos.validate(errs) + errs = cfg.AccountDefaults.Privacy.IPv6Config.Validate(errs) + errs = cfg.AccountDefaults.Privacy.IPv4Config.Validate(errs) + return errs } @@ -1019,6 +1018,8 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { v.SetDefault("account_defaults.price_floors.max_rules", 100) v.SetDefault("account_defaults.price_floors.max_schema_dims", 3) v.SetDefault("account_defaults.events_enabled", false) + v.SetDefault("account_defaults.privacy.ipv6.anon_keep_bits", 56) + v.SetDefault("account_defaults.privacy.ipv4.anon_keep_bits", 24) v.SetDefault("compression.response.enable_gzip", false) v.SetDefault("compression.request.enable_gzip", false) diff --git a/config/config_test.go b/config/config_test.go index a35891babd3..057ed06ecc4 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -206,6 +206,9 @@ func TestDefaults(t *testing.T) { cmpUnsignedInts(t, "tmax_adjustments.bidder_network_latency_buffer_ms", 0, cfg.TmaxAdjustments.BidderNetworkLatencyBuffer) cmpUnsignedInts(t, "tmax_adjustments.pbs_response_preparation_duration_ms", 0, cfg.TmaxAdjustments.PBSResponsePreparationDuration) + cmpInts(t, "account_defaults.privacy.ipv6.anon_keep_bits", 56, cfg.AccountDefaults.Privacy.IPv6Config.AnonKeepBits) + cmpInts(t, "account_defaults.privacy.ipv4.anon_keep_bits", 24, cfg.AccountDefaults.Privacy.IPv4Config.AnonKeepBits) + //Assert purpose VendorExceptionMap hash tables were built correctly expectedTCF2 := TCF2{ Enabled: true, @@ -477,6 +480,11 @@ account_defaults: use_dynamic_data: true max_rules: 120 max_schema_dims: 5 + privacy: + ipv6: + anon_keep_bits: 50 + ipv4: + anon_keep_bits: 20 tmax_adjustments: enabled: true bidder_response_duration_min_ms: 700 @@ -583,6 +591,9 @@ func TestFullConfig(t *testing.T) { cmpBools(t, "account_defaults.events_enabled", *cfg.AccountDefaults.EventsEnabled, true) cmpNils(t, "account_defaults.events.enabled", cfg.AccountDefaults.Events.Enabled) + cmpInts(t, "account_defaults.privacy.ipv6.anon_keep_bits", 50, cfg.AccountDefaults.Privacy.IPv6Config.AnonKeepBits) + cmpInts(t, "account_defaults.privacy.ipv4.anon_keep_bits", 20, cfg.AccountDefaults.Privacy.IPv4Config.AnonKeepBits) + // Assert compression related defaults cmpBools(t, "enable_gzip", false, cfg.EnableGzip) cmpBools(t, "compression.request.enable_gzip", true, cfg.Compression.Request.GZIP) diff --git a/endpoints/cookie_sync.go b/endpoints/cookie_sync.go index 5caa543cbea..50cb449193a 100644 --- a/endpoints/cookie_sync.go +++ b/endpoints/cookie_sync.go @@ -149,7 +149,7 @@ func (c *cookieSyncEndpoint) parseRequest(r *http.Request) (usersync.Request, pr } } - activityControl, activitiesErr := privacy.NewActivityControl(account.Privacy) + activityControl, activitiesErr := privacy.NewActivityControl(&account.Privacy) if activitiesErr != nil { if errortypes.ContainsFatalError([]error{activitiesErr}) { activityControl = privacy.ActivityControl{} diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go index 22ecc1faf9e..45c27f0ea31 100644 --- a/endpoints/cookie_sync_test.go +++ b/endpoints/cookie_sync_test.go @@ -2108,7 +2108,7 @@ func (p *fakePermissions) AuctionActivitiesAllowed(ctx context.Context, bidderCo func getDefaultActivityConfig(componentName string, allow bool) *config.AccountPrivacy { return &config.AccountPrivacy{ - AllowActivities: config.AllowActivities{ + AllowActivities: &config.AllowActivities{ SyncUser: config.Activity{ Default: ptrutil.ToPtr(true), Rules: []config.ActivityRule{ diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index fb4b192824a..142f7320e27 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -229,7 +229,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h tcf2Config := gdpr.NewTCF2Config(deps.cfg.GDPR.TCF2, account.GDPR) - activities, activitiesErr := privacy.NewActivityControl(account.Privacy) + activities, activitiesErr := privacy.NewActivityControl(&account.Privacy) if activitiesErr != nil { errL = append(errL, activitiesErr) writeError(errL, w, &labels) diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 6ce2c323996..b56b7fc55a4 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -193,7 +193,7 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http tcf2Config := gdpr.NewTCF2Config(deps.cfg.GDPR.TCF2, account.GDPR) - activities, activitiesErr := privacy.NewActivityControl(account.Privacy) + activities, activitiesErr := privacy.NewActivityControl(&account.Privacy) if activitiesErr != nil { errL = append(errL, activitiesErr) if errortypes.ContainsFatalError(errL) { diff --git a/endpoints/openrtb2/video_auction.go b/endpoints/openrtb2/video_auction.go index 8fc2f844c71..5f848446333 100644 --- a/endpoints/openrtb2/video_auction.go +++ b/endpoints/openrtb2/video_auction.go @@ -303,7 +303,7 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re return } - activities, activitiesErr := privacy.NewActivityControl(account.Privacy) + activities, activitiesErr := privacy.NewActivityControl(&account.Privacy) if activitiesErr != nil { errL = append(errL, activitiesErr) if errortypes.ContainsFatalError(errL) { diff --git a/endpoints/openrtb2/video_auction_test.go b/endpoints/openrtb2/video_auction_test.go index a32afd24907..3c2528e2aeb 100644 --- a/endpoints/openrtb2/video_auction_test.go +++ b/endpoints/openrtb2/video_auction_test.go @@ -1299,8 +1299,8 @@ func mockDepsInvalidPrivacy(t *testing.T, ex *mockExchangeVideo) *endpointDeps { &mockAccountFetcher{data: mockVideoAccountData}, &config.Configuration{MaxRequestSize: maxSize, AccountDefaults: config.Account{ - Privacy: &config.AccountPrivacy{ - AllowActivities: config.AllowActivities{ + Privacy: config.AccountPrivacy{ + AllowActivities: &config.AllowActivities{ TransmitPreciseGeo: config.Activity{Rules: []config.ActivityRule{ {Condition: config.ActivityCondition{ComponentName: []string{"bidderA.BidderB.bidderC"}}}, }}, diff --git a/endpoints/setuid.go b/endpoints/setuid.go index 561989e029d..30a1cce2751 100644 --- a/endpoints/setuid.go +++ b/endpoints/setuid.go @@ -104,7 +104,7 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use return } - activities, activitiesErr := privacy.NewActivityControl(account.Privacy) + activities, activitiesErr := privacy.NewActivityControl(&account.Privacy) if activitiesErr != nil { if errortypes.ContainsFatalError([]error{activitiesErr}) { activities = privacy.ActivityControl{} diff --git a/exchange/utils.go b/exchange/utils.go index baedcf78475..267d928ca72 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -214,7 +214,7 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, privacyEnforcement.TID = !auctionReq.Activities.Allow(privacy.ActivityTransmitTids, scopedName) - privacyEnforcement.Apply(bidderRequest.BidRequest) + privacyEnforcement.Apply(bidderRequest.BidRequest, auctionReq.Account.Privacy) allowedBidderRequests = append(allowedBidderRequests, bidderRequest) // GPP downgrade: always downgrade unless we can confirm GPP is supported diff --git a/exchange/utils_test.go b/exchange/utils_test.go index 63ca54c2a2e..1ab86fcd9e7 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -4272,7 +4272,7 @@ func TestCleanOpenRTBRequestsActivities(t *testing.T) { testCases := []struct { name string req *openrtb2.BidRequest - privacyConfig *config.AccountPrivacy + privacyConfig config.AccountPrivacy componentName string allow bool expectedReqNumber int @@ -4364,7 +4364,7 @@ func TestCleanOpenRTBRequestsActivities(t *testing.T) { } for _, test := range testCases { - activities, err := privacy.NewActivityControl(test.privacyConfig) + activities, err := privacy.NewActivityControl(&test.privacyConfig) assert.NoError(t, err, "") auctionReq := AuctionRequest{ BidRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: test.req}, @@ -4410,33 +4410,33 @@ func buildDefaultActivityConfig(componentName string, allow bool) config.Activit } } -func getFetchBidsActivityConfig(componentName string, allow bool) *config.AccountPrivacy { - return &config.AccountPrivacy{ - AllowActivities: config.AllowActivities{ +func getFetchBidsActivityConfig(componentName string, allow bool) config.AccountPrivacy { + return config.AccountPrivacy{ + AllowActivities: &config.AllowActivities{ FetchBids: buildDefaultActivityConfig(componentName, allow), }, } } -func getTransmitUFPDActivityConfig(componentName string, allow bool) *config.AccountPrivacy { - return &config.AccountPrivacy{ - AllowActivities: config.AllowActivities{ +func getTransmitUFPDActivityConfig(componentName string, allow bool) config.AccountPrivacy { + return config.AccountPrivacy{ + AllowActivities: &config.AllowActivities{ TransmitUserFPD: buildDefaultActivityConfig(componentName, allow), }, } } -func getTransmitPreciseGeoActivityConfig(componentName string, allow bool) *config.AccountPrivacy { - return &config.AccountPrivacy{ - AllowActivities: config.AllowActivities{ +func getTransmitPreciseGeoActivityConfig(componentName string, allow bool) config.AccountPrivacy { + return config.AccountPrivacy{ + AllowActivities: &config.AllowActivities{ TransmitPreciseGeo: buildDefaultActivityConfig(componentName, allow), }, } } -func getTransmitTIDActivityConfig(componentName string, allow bool) *config.AccountPrivacy { - return &config.AccountPrivacy{ - AllowActivities: config.AllowActivities{ +func getTransmitTIDActivityConfig(componentName string, allow bool) config.AccountPrivacy { + return config.AccountPrivacy{ + AllowActivities: &config.AllowActivities{ TransmitTids: buildDefaultActivityConfig(componentName, allow), }, } diff --git a/privacy/activitycontrol.go b/privacy/activitycontrol.go index fee5c6508a6..5d68ce71770 100644 --- a/privacy/activitycontrol.go +++ b/privacy/activitycontrol.go @@ -22,7 +22,7 @@ func NewActivityControl(privacyConf *config.AccountPrivacy) (ActivityControl, er ac := ActivityControl{} var err error - if privacyConf == nil { + if privacyConf == nil || privacyConf.AllowActivities == nil { return ac, nil } diff --git a/privacy/activitycontrol_test.go b/privacy/activitycontrol_test.go index 7927014a928..db5d588de44 100644 --- a/privacy/activitycontrol_test.go +++ b/privacy/activitycontrol_test.go @@ -12,20 +12,20 @@ import ( func TestNewActivityControl(t *testing.T) { testCases := []struct { name string - privacyConf *config.AccountPrivacy + privacyConf config.AccountPrivacy activityControl ActivityControl err error }{ { - name: "privacy_config_is_nil", - privacyConf: nil, + name: "privacy_config_is_empty", + privacyConf: config.AccountPrivacy{}, activityControl: ActivityControl{plans: nil}, err: nil, }, { name: "privacy_config_is_specified_and_correct", - privacyConf: &config.AccountPrivacy{ - AllowActivities: config.AllowActivities{ + privacyConf: config.AccountPrivacy{ + AllowActivities: &config.AllowActivities{ SyncUser: getDefaultActivityConfig(), FetchBids: getDefaultActivityConfig(), EnrichUserFPD: getDefaultActivityConfig(), @@ -50,8 +50,8 @@ func TestNewActivityControl(t *testing.T) { }, { name: "privacy_config_is_specified_and_SyncUser_is_incorrect", - privacyConf: &config.AccountPrivacy{ - AllowActivities: config.AllowActivities{ + privacyConf: config.AccountPrivacy{ + AllowActivities: &config.AllowActivities{ SyncUser: getIncorrectActivityConfig(), }, }, @@ -60,8 +60,8 @@ func TestNewActivityControl(t *testing.T) { }, { name: "privacy_config_is_specified_and_FetchBids_is_incorrect", - privacyConf: &config.AccountPrivacy{ - AllowActivities: config.AllowActivities{ + privacyConf: config.AccountPrivacy{ + AllowActivities: &config.AllowActivities{ FetchBids: getIncorrectActivityConfig(), }, }, @@ -70,8 +70,8 @@ func TestNewActivityControl(t *testing.T) { }, { name: "privacy_config_is_specified_and_EnrichUserFPD_is_incorrect", - privacyConf: &config.AccountPrivacy{ - AllowActivities: config.AllowActivities{ + privacyConf: config.AccountPrivacy{ + AllowActivities: &config.AllowActivities{ EnrichUserFPD: getIncorrectActivityConfig(), }, }, @@ -80,8 +80,8 @@ func TestNewActivityControl(t *testing.T) { }, { name: "privacy_config_is_specified_and_ReportAnalytics_is_incorrect", - privacyConf: &config.AccountPrivacy{ - AllowActivities: config.AllowActivities{ + privacyConf: config.AccountPrivacy{ + AllowActivities: &config.AllowActivities{ ReportAnalytics: getIncorrectActivityConfig(), }, }, @@ -90,8 +90,8 @@ func TestNewActivityControl(t *testing.T) { }, { name: "privacy_config_is_specified_and_TransmitUserFPD_is_incorrect", - privacyConf: &config.AccountPrivacy{ - AllowActivities: config.AllowActivities{ + privacyConf: config.AccountPrivacy{ + AllowActivities: &config.AllowActivities{ TransmitUserFPD: getIncorrectActivityConfig(), }, }, @@ -100,8 +100,8 @@ func TestNewActivityControl(t *testing.T) { }, { name: "privacy_config_is_specified_and_TransmitPreciseGeo_is_incorrect", - privacyConf: &config.AccountPrivacy{ - AllowActivities: config.AllowActivities{ + privacyConf: config.AccountPrivacy{ + AllowActivities: &config.AllowActivities{ TransmitPreciseGeo: getIncorrectActivityConfig(), }, }, @@ -110,8 +110,8 @@ func TestNewActivityControl(t *testing.T) { }, { name: "privacy_config_is_specified_and_TransmitUniqueRequestIds_is_incorrect", - privacyConf: &config.AccountPrivacy{ - AllowActivities: config.AllowActivities{ + privacyConf: config.AccountPrivacy{ + AllowActivities: &config.AllowActivities{ TransmitUniqueRequestIds: getIncorrectActivityConfig(), }, }, @@ -120,8 +120,8 @@ func TestNewActivityControl(t *testing.T) { }, { name: "privacy_config_is_specified_and_TransmitTids_is_incorrect", - privacyConf: &config.AccountPrivacy{ - AllowActivities: config.AllowActivities{ + privacyConf: config.AccountPrivacy{ + AllowActivities: &config.AllowActivities{ TransmitTids: getIncorrectActivityConfig(), }, }, @@ -132,7 +132,7 @@ func TestNewActivityControl(t *testing.T) { for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - actualAC, actualErr := NewActivityControl(test.privacyConf) + actualAC, actualErr := NewActivityControl(&test.privacyConf) if test.err == nil { assert.Equal(t, test.activityControl, actualAC) assert.NoError(t, actualErr) diff --git a/privacy/enforcement.go b/privacy/enforcement.go index 1a66cfab929..8074d96acf3 100644 --- a/privacy/enforcement.go +++ b/privacy/enforcement.go @@ -1,6 +1,9 @@ package privacy -import "github.com/prebid/openrtb/v19/openrtb2" +import ( + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/config" +) // Enforcement represents the privacy policies to enforce for an OpenRTB bid request. type Enforcement struct { @@ -27,8 +30,8 @@ func (e Enforcement) AnyActivities() bool { } // Apply cleans personally identifiable information from an OpenRTB bid request. -func (e Enforcement) Apply(bidRequest *openrtb2.BidRequest) { - e.apply(bidRequest, NewScrubber()) +func (e Enforcement) Apply(bidRequest *openrtb2.BidRequest, privacy config.AccountPrivacy) { + e.apply(bidRequest, NewScrubber(privacy.IPv6Config, privacy.IPv4Config)) } func (e Enforcement) apply(bidRequest *openrtb2.BidRequest, scrubber Scrubber) { @@ -55,21 +58,16 @@ func (e Enforcement) getDeviceIDScrubStrategy() ScrubStrategyDeviceID { func (e Enforcement) getIPv4ScrubStrategy() ScrubStrategyIPV4 { if e.COPPA || e.GDPRGeo || e.CCPA || e.LMT { - return ScrubStrategyIPV4Lowest8 + return ScrubStrategyIPV4Subnet } return ScrubStrategyIPV4None } func (e Enforcement) getIPv6ScrubStrategy() ScrubStrategyIPV6 { - if e.COPPA { - return ScrubStrategyIPV6Lowest32 + if e.GDPRGeo || e.CCPA || e.LMT || e.COPPA { + return ScrubStrategyIPV6Subnet } - - if e.GDPRGeo || e.CCPA || e.LMT { - return ScrubStrategyIPV6Lowest16 - } - return ScrubStrategyIPV6None } diff --git a/privacy/enforcement_test.go b/privacy/enforcement_test.go index be1ab0dca9f..a97779eb903 100644 --- a/privacy/enforcement_test.go +++ b/privacy/enforcement_test.go @@ -76,8 +76,8 @@ func TestApplyGDPR(t *testing.T) { LMT: true, }, expectedDeviceID: ScrubStrategyDeviceIDAll, - expectedDeviceIPv4: ScrubStrategyIPV4Lowest8, - expectedDeviceIPv6: ScrubStrategyIPV6Lowest32, + expectedDeviceIPv4: ScrubStrategyIPV4Subnet, + expectedDeviceIPv6: ScrubStrategyIPV6Subnet, expectedDeviceGeo: ScrubStrategyGeoFull, expectedUser: ScrubStrategyUserIDAndDemographic, expectedUserGeo: ScrubStrategyGeoFull, @@ -92,8 +92,8 @@ func TestApplyGDPR(t *testing.T) { LMT: false, }, expectedDeviceID: ScrubStrategyDeviceIDAll, - expectedDeviceIPv4: ScrubStrategyIPV4Lowest8, - expectedDeviceIPv6: ScrubStrategyIPV6Lowest16, + expectedDeviceIPv4: ScrubStrategyIPV4Subnet, + expectedDeviceIPv6: ScrubStrategyIPV6Subnet, expectedDeviceGeo: ScrubStrategyGeoReducedPrecision, expectedUser: ScrubStrategyUserIDAndDemographic, expectedUserGeo: ScrubStrategyGeoReducedPrecision, @@ -108,8 +108,8 @@ func TestApplyGDPR(t *testing.T) { LMT: false, }, expectedDeviceID: ScrubStrategyDeviceIDAll, - expectedDeviceIPv4: ScrubStrategyIPV4Lowest8, - expectedDeviceIPv6: ScrubStrategyIPV6Lowest32, + expectedDeviceIPv4: ScrubStrategyIPV4Subnet, + expectedDeviceIPv6: ScrubStrategyIPV6Subnet, expectedDeviceGeo: ScrubStrategyGeoFull, expectedUser: ScrubStrategyUserIDAndDemographic, expectedUserGeo: ScrubStrategyGeoFull, @@ -124,8 +124,8 @@ func TestApplyGDPR(t *testing.T) { LMT: false, }, expectedDeviceID: ScrubStrategyDeviceIDAll, - expectedDeviceIPv4: ScrubStrategyIPV4Lowest8, - expectedDeviceIPv6: ScrubStrategyIPV6Lowest16, + expectedDeviceIPv4: ScrubStrategyIPV4Subnet, + expectedDeviceIPv6: ScrubStrategyIPV6Subnet, expectedDeviceGeo: ScrubStrategyGeoReducedPrecision, expectedUser: ScrubStrategyUserIDAndDemographic, expectedUserGeo: ScrubStrategyGeoReducedPrecision, @@ -156,8 +156,8 @@ func TestApplyGDPR(t *testing.T) { LMT: false, }, expectedDeviceID: ScrubStrategyDeviceIDNone, - expectedDeviceIPv4: ScrubStrategyIPV4Lowest8, - expectedDeviceIPv6: ScrubStrategyIPV6Lowest16, + expectedDeviceIPv4: ScrubStrategyIPV4Subnet, + expectedDeviceIPv6: ScrubStrategyIPV6Subnet, expectedDeviceGeo: ScrubStrategyGeoReducedPrecision, expectedUser: ScrubStrategyUserNone, expectedUserGeo: ScrubStrategyGeoReducedPrecision, @@ -172,8 +172,8 @@ func TestApplyGDPR(t *testing.T) { LMT: true, }, expectedDeviceID: ScrubStrategyDeviceIDAll, - expectedDeviceIPv4: ScrubStrategyIPV4Lowest8, - expectedDeviceIPv6: ScrubStrategyIPV6Lowest16, + expectedDeviceIPv4: ScrubStrategyIPV4Subnet, + expectedDeviceIPv6: ScrubStrategyIPV6Subnet, expectedDeviceGeo: ScrubStrategyGeoReducedPrecision, expectedUser: ScrubStrategyUserIDAndDemographic, expectedUserGeo: ScrubStrategyGeoReducedPrecision, @@ -188,8 +188,8 @@ func TestApplyGDPR(t *testing.T) { LMT: false, }, expectedDeviceID: ScrubStrategyDeviceIDAll, - expectedDeviceIPv4: ScrubStrategyIPV4Lowest8, - expectedDeviceIPv6: ScrubStrategyIPV6Lowest32, + expectedDeviceIPv4: ScrubStrategyIPV4Subnet, + expectedDeviceIPv6: ScrubStrategyIPV6Subnet, expectedDeviceGeo: ScrubStrategyGeoFull, expectedUser: ScrubStrategyUserIDAndDemographic, expectedUserGeo: ScrubStrategyGeoFull, @@ -329,7 +329,7 @@ func TestApplyToggle(t *testing.T) { m.On("ScrubUser", req.User, ScrubStrategyUserIDAndDemographic, ScrubStrategyGeoFull).Return(replacedUser).Once() } if test.expectedScrubDeviceExecuted { - m.On("ScrubDevice", req.Device, ScrubStrategyDeviceIDAll, ScrubStrategyIPV4Lowest8, ScrubStrategyIPV6Lowest32, ScrubStrategyGeoFull).Return(replacedDevice).Once() + m.On("ScrubDevice", req.Device, ScrubStrategyDeviceIDAll, ScrubStrategyIPV4Subnet, ScrubStrategyIPV6Subnet, ScrubStrategyGeoFull).Return(replacedDevice).Once() } test.enforcement.apply(req, m) diff --git a/privacy/scrubber.go b/privacy/scrubber.go index f2fb790dc12..4cc90c825df 100644 --- a/privacy/scrubber.go +++ b/privacy/scrubber.go @@ -2,8 +2,10 @@ package privacy import ( "encoding/json" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/util/iputil" "github.com/prebid/prebid-server/util/ptrutil" - "strings" + "net" "github.com/prebid/openrtb/v19/openrtb2" ) @@ -15,8 +17,8 @@ const ( // ScrubStrategyIPV4None does not remove any part of an IPV4 address. ScrubStrategyIPV4None ScrubStrategyIPV4 = iota - // ScrubStrategyIPV4Lowest8 zeroes out the last 8 bits of an IPV4 address. - ScrubStrategyIPV4Lowest8 + // ScrubStrategyIPV4Subnet zeroes out the last 8 bits of an IPV4 address. + ScrubStrategyIPV4Subnet ) // ScrubStrategyIPV6 defines the approach to scrub PII from an IPV6 address. @@ -26,11 +28,8 @@ const ( // ScrubStrategyIPV6None does not remove any part of an IPV6 address. ScrubStrategyIPV6None ScrubStrategyIPV6 = iota - // ScrubStrategyIPV6Lowest16 zeroes out the last 16 bits of an IPV6 address. - ScrubStrategyIPV6Lowest16 - - // ScrubStrategyIPV6Lowest32 zeroes out the last 32 bits of an IPV6 address. - ScrubStrategyIPV6Lowest32 + // ScrubStrategyIPV6Subnet zeroes out the last 16 bits of an IPV6 sub net address. + ScrubStrategyIPV6Subnet ) // ScrubStrategyGeo defines the approach to scrub PII from geographical data. @@ -76,14 +75,20 @@ type Scrubber interface { ScrubUser(user *openrtb2.User, strategy ScrubStrategyUser, geo ScrubStrategyGeo) *openrtb2.User } -type scrubber struct{} +type scrubber struct { + ipV6 config.IPv6 + ipV4 config.IPv4 +} // NewScrubber returns an OpenRTB scrubber. -func NewScrubber() Scrubber { - return scrubber{} +func NewScrubber(ipV6 config.IPv6, ipV4 config.IPv4) Scrubber { + return scrubber{ + ipV6: ipV6, + ipV4: ipV4, + } } -func (scrubber) ScrubRequest(bidRequest *openrtb2.BidRequest, enforcement Enforcement) *openrtb2.BidRequest { +func (s scrubber) ScrubRequest(bidRequest *openrtb2.BidRequest, enforcement Enforcement) *openrtb2.BidRequest { var userExtParsed map[string]json.RawMessage userExtModified := false @@ -169,8 +174,8 @@ func (scrubber) ScrubRequest(bidRequest *openrtb2.BidRequest, enforcement Enforc if deviceCopy.Geo != nil { deviceCopy.Geo = scrubGeoPrecision(deviceCopy.Geo) } - deviceCopy.IP = scrubIPV4Lowest8(deviceCopy.IP) - deviceCopy.IPv6 = scrubIPV6Lowest32Bits(deviceCopy.IPv6) + deviceCopy.IP = scrubIP(deviceCopy.IP, s.ipV4.AnonKeepBits, iputil.IPv4BitSize) + deviceCopy.IPv6 = scrubIP(deviceCopy.IPv6, s.ipV6.AnonKeepBits, iputil.IPv6BitSize) } } @@ -179,7 +184,7 @@ func (scrubber) ScrubRequest(bidRequest *openrtb2.BidRequest, enforcement Enforc return bidRequest } -func (scrubber) ScrubDevice(device *openrtb2.Device, id ScrubStrategyDeviceID, ipv4 ScrubStrategyIPV4, ipv6 ScrubStrategyIPV6, geo ScrubStrategyGeo) *openrtb2.Device { +func (s scrubber) ScrubDevice(device *openrtb2.Device, id ScrubStrategyDeviceID, ipv4 ScrubStrategyIPV4, ipv6 ScrubStrategyIPV6, geo ScrubStrategyGeo) *openrtb2.Device { if device == nil { return nil } @@ -198,15 +203,13 @@ func (scrubber) ScrubDevice(device *openrtb2.Device, id ScrubStrategyDeviceID, i } switch ipv4 { - case ScrubStrategyIPV4Lowest8: - deviceCopy.IP = scrubIPV4Lowest8(device.IP) + case ScrubStrategyIPV4Subnet: + deviceCopy.IP = scrubIP(device.IP, s.ipV4.AnonKeepBits, iputil.IPv4BitSize) } switch ipv6 { - case ScrubStrategyIPV6Lowest16: - deviceCopy.IPv6 = scrubIPV6Lowest16Bits(device.IPv6) - case ScrubStrategyIPV6Lowest32: - deviceCopy.IPv6 = scrubIPV6Lowest32Bits(device.IPv6) + case ScrubStrategyIPV6Subnet: + deviceCopy.IPv6 = scrubIP(device.IPv6, s.ipV6.AnonKeepBits, iputil.IPv6BitSize) } switch geo { @@ -244,44 +247,13 @@ func (scrubber) ScrubUser(user *openrtb2.User, strategy ScrubStrategyUser, geo S return &userCopy } -func scrubIPV4Lowest8(ip string) string { - i := strings.LastIndex(ip, ".") - if i == -1 { - return "" - } - - return ip[0:i] + ".0" -} - -func scrubIPV6Lowest16Bits(ip string) string { - ip = removeLowestIPV6Segment(ip) - - if ip != "" { - ip += ":0" - } - - return ip -} - -func scrubIPV6Lowest32Bits(ip string) string { - ip = removeLowestIPV6Segment(ip) - ip = removeLowestIPV6Segment(ip) - - if ip != "" { - ip += ":0:0" - } - - return ip -} - -func removeLowestIPV6Segment(ip string) string { - i := strings.LastIndex(ip, ":") - - if i == -1 { +func scrubIP(ip string, ones, bits int) string { + if ip == "" { return "" } - - return ip[0:i] + ipMask := net.CIDRMask(ones, bits) + ipMasked := net.ParseIP(ip).Mask(ipMask) + return ipMasked.String() } func scrubGeoFull(geo *openrtb2.Geo) *openrtb2.Geo { diff --git a/privacy/scrubber_test.go b/privacy/scrubber_test.go index 0691b2c7a2c..59e593fc167 100644 --- a/privacy/scrubber_test.go +++ b/privacy/scrubber_test.go @@ -2,6 +2,7 @@ package privacy import ( "encoding/json" + "github.com/prebid/prebid-server/config" "testing" "github.com/prebid/openrtb/v19/openrtb2" @@ -38,12 +39,12 @@ func TestScrubDevice(t *testing.T) { MACMD5: "", IFA: "", IP: "1.2.3.0", - IPv6: "2001:0db8:0000:0000:0000:ff00:0:0", + IPv6: "2001:1db8:2233:4400::", Geo: &openrtb2.Geo{}, }, id: ScrubStrategyDeviceIDAll, - ipv4: ScrubStrategyIPV4Lowest8, - ipv6: ScrubStrategyIPV6Lowest32, + ipv4: ScrubStrategyIPV4Subnet, + ipv6: ScrubStrategyIPV6Subnet, geo: ScrubStrategyGeoFull, }, { @@ -57,7 +58,7 @@ func TestScrubDevice(t *testing.T) { MACMD5: "", IFA: "", IP: "1.2.3.4", - IPv6: "2001:0db8:0000:0000:0000:ff00:0042:8329", + IPv6: "2001:1db8:2233:4455:6677:ff00:0042:8329", Geo: device.Geo, }, id: ScrubStrategyDeviceIDAll, @@ -76,16 +77,16 @@ func TestScrubDevice(t *testing.T) { MACMD5: "anyMACMD5", IFA: "anyIFA", IP: "1.2.3.0", - IPv6: "2001:0db8:0000:0000:0000:ff00:0042:8329", + IPv6: "2001:1db8:2233:4455:6677:ff00:0042:8329", Geo: device.Geo, }, id: ScrubStrategyDeviceIDNone, - ipv4: ScrubStrategyIPV4Lowest8, + ipv4: ScrubStrategyIPV4Subnet, ipv6: ScrubStrategyIPV6None, geo: ScrubStrategyGeoNone, }, { - description: "Isolated - IPv6 - Lowest 16", + description: "Isolated - IPv6", expected: &openrtb2.Device{ DIDMD5: "anyDIDMD5", DIDSHA1: "anyDIDSHA1", @@ -95,31 +96,12 @@ func TestScrubDevice(t *testing.T) { MACMD5: "anyMACMD5", IFA: "anyIFA", IP: "1.2.3.4", - IPv6: "2001:0db8:0000:0000:0000:ff00:0042:0", + IPv6: "2001:1db8:2233:4400::", Geo: device.Geo, }, id: ScrubStrategyDeviceIDNone, ipv4: ScrubStrategyIPV4None, - ipv6: ScrubStrategyIPV6Lowest16, - geo: ScrubStrategyGeoNone, - }, - { - description: "Isolated - IPv6 - Lowest 32", - expected: &openrtb2.Device{ - DIDMD5: "anyDIDMD5", - DIDSHA1: "anyDIDSHA1", - DPIDMD5: "anyDPIDMD5", - DPIDSHA1: "anyDPIDSHA1", - MACSHA1: "anyMACSHA1", - MACMD5: "anyMACMD5", - IFA: "anyIFA", - IP: "1.2.3.4", - IPv6: "2001:0db8:0000:0000:0000:ff00:0:0", - Geo: device.Geo, - }, - id: ScrubStrategyDeviceIDNone, - ipv4: ScrubStrategyIPV4None, - ipv6: ScrubStrategyIPV6Lowest32, + ipv6: ScrubStrategyIPV6Subnet, geo: ScrubStrategyGeoNone, }, { @@ -133,7 +115,7 @@ func TestScrubDevice(t *testing.T) { MACMD5: "anyMACMD5", IFA: "anyIFA", IP: "1.2.3.4", - IPv6: "2001:0db8:0000:0000:0000:ff00:0042:8329", + IPv6: "2001:1db8:2233:4455:6677:ff00:0042:8329", Geo: &openrtb2.Geo{ Lat: 123.46, Lon: 678.89, @@ -158,7 +140,7 @@ func TestScrubDevice(t *testing.T) { MACMD5: "anyMACMD5", IFA: "anyIFA", IP: "1.2.3.4", - IPv6: "2001:0db8:0000:0000:0000:ff00:0042:8329", + IPv6: "2001:1db8:2233:4455:6677:ff00:0042:8329", Geo: &openrtb2.Geo{}, }, id: ScrubStrategyDeviceIDNone, @@ -167,15 +149,16 @@ func TestScrubDevice(t *testing.T) { geo: ScrubStrategyGeoFull, }, } - + testIPMasking := getTestIPMasking() for _, test := range testCases { - result := NewScrubber().ScrubDevice(device, test.id, test.ipv4, test.ipv6, test.geo) + result := NewScrubber(testIPMasking.IPv6Config, testIPMasking.IPv4Config).ScrubDevice(device, test.id, test.ipv4, test.ipv6, test.geo) assert.Equal(t, test.expected, result, test.description) } } func TestScrubDeviceNil(t *testing.T) { - result := NewScrubber().ScrubDevice(nil, ScrubStrategyDeviceIDNone, ScrubStrategyIPV4None, ScrubStrategyIPV6None, ScrubStrategyGeoNone) + testIPMasking := getTestIPMasking() + result := NewScrubber(testIPMasking.IPv6Config, testIPMasking.IPv4Config).ScrubDevice(nil, ScrubStrategyDeviceIDNone, ScrubStrategyIPV4None, ScrubStrategyIPV6None, ScrubStrategyGeoNone) assert.Nil(t, result) } @@ -292,14 +275,16 @@ func TestScrubUser(t *testing.T) { }, } + testIPMasking := getTestIPMasking() for _, test := range testCases { - result := NewScrubber().ScrubUser(user, test.scrubUser, test.scrubGeo) + result := NewScrubber(testIPMasking.IPv6Config, testIPMasking.IPv4Config).ScrubUser(user, test.scrubUser, test.scrubGeo) assert.Equal(t, test.expected, result, test.description) } } func TestScrubUserNil(t *testing.T) { - result := NewScrubber().ScrubUser(nil, ScrubStrategyUserNone, ScrubStrategyGeoNone) + testIPMasking := getTestIPMasking() + result := NewScrubber(testIPMasking.IPv6Config, testIPMasking.IPv4Config).ScrubUser(nil, ScrubStrategyUserNone, ScrubStrategyGeoNone) assert.Nil(t, result) } @@ -336,7 +321,7 @@ func TestScrubRequest(t *testing.T) { }, Device: &openrtb2.Device{ IP: "1.2.3.4", - IPv6: "2001:0db8:0000:0000:0000:ff00:0042:8329", + IPv6: "2001:1db8:2233:4455:6677:ff00:0042:8329", Geo: device.Geo, }, }, @@ -354,7 +339,7 @@ func TestScrubRequest(t *testing.T) { }, Device: &openrtb2.Device{ IP: "1.2.3.4", - IPv6: "2001:0db8:0000:0000:0000:ff00:0042:8329", + IPv6: "2001:1db8:2233:4455:6677:ff00:0042:8329", Geo: device.Geo, }, }, @@ -431,7 +416,7 @@ func TestScrubRequest(t *testing.T) { MACSHA1: "anyMACSHA1", MACMD5: "anyMACMD5", IP: "1.2.3.0", - IPv6: "2001:0db8:0000:0000:0000:ff00:0:0", + IPv6: "2001:1db8:2233:4400::", Geo: &openrtb2.Geo{ Lat: 123.46, Lon: 678.89, Metro: "some metro", @@ -443,6 +428,7 @@ func TestScrubRequest(t *testing.T) { }, } + testIPMasking := getTestIPMasking() for _, test := range testCases { t.Run(test.description, func(t *testing.T) { bidRequest := &openrtb2.BidRequest{ @@ -462,127 +448,110 @@ func TestScrubRequest(t *testing.T) { } bidRequest.User.EIDs = []openrtb2.EID{{Source: "test"}} - result := NewScrubber().ScrubRequest(bidRequest, test.enforcement) + result := NewScrubber(testIPMasking.IPv6Config, testIPMasking.IPv4Config).ScrubRequest(bidRequest, test.enforcement) assert.Equal(t, test.expected, result, test.description) }) } } -func TestScrubIPV4(t *testing.T) { +func TestScrubIP(t *testing.T) { testCases := []struct { - IP string - cleanedIP string - description string + IP string + cleanedIP string + bits int + maskBits int }{ { - IP: "0.0.0.0", - cleanedIP: "0.0.0.0", - description: "Shouldn't do anything for a 0.0.0.0 IP address", + IP: "0:0:0:0:0:0:0:0", + cleanedIP: "::", + bits: 128, + maskBits: 56, }, { - IP: "192.127.111.134", - cleanedIP: "192.127.111.0", - description: "Should remove the lowest 8 bits", + IP: "", + cleanedIP: "", + bits: 128, + maskBits: 56, }, { - IP: "192.127.111.0", - cleanedIP: "192.127.111.0", - description: "Shouldn't change anything if the lowest 8 bits are already 0", + IP: "1111:2222:3333:4444:5555:6666:7777:8888", + cleanedIP: "1111:2222:3333:4400::", + bits: 128, + maskBits: 56, }, { - IP: "not an ip", - cleanedIP: "", - description: "Should return an empty string for a bad IP", + IP: "1111:2222:3333:4444:5555:6666:7777:8888", + cleanedIP: "1111:2222::", + bits: 128, + maskBits: 34, }, { - IP: "", - cleanedIP: "", - description: "Should return an empty string for a bad IP", - }, - } - - for _, test := range testCases { - result := scrubIPV4Lowest8(test.IP) - assert.Equal(t, test.cleanedIP, result, test.description) - } -} - -func TestScrubIPV6Lowest16Bits(t *testing.T) { - testCases := []struct { - IP string - cleanedIP string - description string - }{ - { - IP: "0:0:0:0", - cleanedIP: "0:0:0:0", - description: "Shouldn't do anything for a 0:0:0:0 IP address", + IP: "1111:0:3333:4444:5555:6666:7777:8888", + cleanedIP: "1111:0:3333:4400::", + bits: 128, + maskBits: 56, }, { - IP: "2001:0db8:0000:0000:0000:ff00:0042:8329", - cleanedIP: "2001:0db8:0000:0000:0000:ff00:0042:0", - description: "Should remove lowest 16 bits", + IP: "1111::6666:7777:8888", + cleanedIP: "1111::", + bits: 128, + maskBits: 56, }, { - IP: "2001:0db8:0000:0000:0000:ff00:0042:0", - cleanedIP: "2001:0db8:0000:0000:0000:ff00:0042:0", - description: "Shouldn't do anything if the lowest 16 bits are already 0", + IP: "2001:1db8:0000:0000:0000:ff00:0042:8329", + cleanedIP: "2001:1db8::ff00:0:0", + bits: 128, + maskBits: 96, }, { - IP: "not an ip", - cleanedIP: "", - description: "Should return an empty string for a bad IP", + IP: "2001:1db8:0000:0000:0000:ff00:0:0", + cleanedIP: "2001:1db8::ff00:0:0", + bits: 128, + maskBits: 96, }, { - IP: "", - cleanedIP: "", - description: "Should return an empty string for a bad IP", + IP: "2001:1db8:0000:0000:0000:ff00:0042:8329", + cleanedIP: "2001:1db8::ff00:42:0", + bits: 128, + maskBits: 112, }, - } - - for _, test := range testCases { - result := scrubIPV6Lowest16Bits(test.IP) - assert.Equal(t, test.cleanedIP, result, test.description) - } -} - -func TestScrubIPV6Lowest32Bits(t *testing.T) { - testCases := []struct { - IP string - cleanedIP string - description string - }{ { - IP: "0:0:0:0", - cleanedIP: "0:0:0:0", - description: "Shouldn't do anything for a 0:0:0:0 IP address", + IP: "2001:1db8:0000:0000:0000:ff00:0042:0", + cleanedIP: "2001:1db8::ff00:42:0", + bits: 128, + maskBits: 112, }, { - IP: "2001:0db8:0000:0000:0000:ff00:0042:8329", - cleanedIP: "2001:0db8:0000:0000:0000:ff00:0:0", - description: "Should remove lowest 32 bits", + IP: "127.0.0.1", + cleanedIP: "127.0.0.0", + bits: 32, + maskBits: 24, }, { - IP: "2001:0db8:0000:0000:0000:ff00:0:0", - cleanedIP: "2001:0db8:0000:0000:0000:ff00:0:0", - description: "Shouldn't do anything if the lowest 32 bits are already 0", + IP: "0.0.0.0", + cleanedIP: "0.0.0.0", + bits: 32, + maskBits: 24, }, - { - IP: "not an ip", - cleanedIP: "", - description: "Should return an empty string for a bad IP", + IP: "192.127.111.134", + cleanedIP: "192.127.111.0", + bits: 32, + maskBits: 24, }, { - IP: "", - cleanedIP: "", - description: "Should return an empty string for a bad IP", + IP: "192.127.111.0", + cleanedIP: "192.127.111.0", + bits: 32, + maskBits: 24, }, } - for _, test := range testCases { - result := scrubIPV6Lowest32Bits(test.IP) - assert.Equal(t, test.cleanedIP, result, test.description) + t.Run(test.IP, func(t *testing.T) { + // bits: ipv6 - 128, ipv4 - 32 + result := scrubIP(test.IP, test.maskBits, test.bits) + assert.Equal(t, test.cleanedIP, result) + }) } } @@ -739,7 +708,7 @@ func getTestDevice() *openrtb2.Device { MACMD5: "anyMACMD5", IFA: "anyIFA", IP: "1.2.3.4", - IPv6: "2001:0db8:0000:0000:0000:ff00:0042:8329", + IPv6: "2001:1db8:2233:4455:6677:ff00:0042:8329", Geo: &openrtb2.Geo{ Lat: 123.456, Lon: 678.89, @@ -748,5 +717,15 @@ func getTestDevice() *openrtb2.Device { ZIP: "some zip", }, } +} +func getTestIPMasking() config.AccountPrivacy { + return config.AccountPrivacy{ + IPv6Config: config.IPv6{ + 54, + }, + IPv4Config: config.IPv4{ + 24, + }, + } } diff --git a/util/iputil/parse.go b/util/iputil/parse.go index bcb00760e22..c226ece8e5e 100644 --- a/util/iputil/parse.go +++ b/util/iputil/parse.go @@ -15,6 +15,14 @@ const ( IPv6 IPVersion = 6 ) +const ( + IPv4BitSize = 32 + IPv6BitSize = 128 + + IPv4DefaultMaskingBitSize = 24 + IPv6DefaultMaskingBitSize = 56 +) + // ParseIP parses v as an ip address returning the result and version, or nil and unknown if invalid. func ParseIP(v string) (net.IP, IPVersion) { if ip := net.ParseIP(v); ip != nil { From 4c10fac42967ee040d437d60075d420d20b4a72f Mon Sep 17 00:00:00 2001 From: Jaydeep Mohite <30924180+pm-jaydeep-mohite@users.noreply.github.com> Date: Tue, 5 Sep 2023 22:43:51 +0530 Subject: [PATCH 102/268] Added float precision check in floor price comparision (#3042) * Added float precision check in floor price comparision * Fixed review comments --- floors/enforce.go | 2 +- floors/enforce_test.go | 66 +++++++++++++++++++++++++++++++++++++++++- floors/floors.go | 19 ++++++------ 3 files changed, 76 insertions(+), 11 deletions(-) diff --git a/floors/enforce.go b/floors/enforce.go index 1f50dd2b1d9..9318c9d278e 100644 --- a/floors/enforce.go +++ b/floors/enforce.go @@ -137,7 +137,7 @@ func enforceFloorToBids(bidRequestWrapper *openrtb_ext.RequestWrapper, seatBids } bidPrice := rate * bid.Bid.Price - if reqImp.BidFloor > bidPrice { + if (bidPrice + floorPrecision) < reqImp.BidFloor { rejectedBid := &entities.PbsOrtbSeatBid{ Currency: seatBid.Currency, Seat: seatBid.Seat, diff --git a/floors/enforce_test.go b/floors/enforce_test.go index bb5d44341ef..725ac22b193 100644 --- a/floors/enforce_test.go +++ b/floors/enforce_test.go @@ -196,6 +196,71 @@ func TestEnforceFloorToBids(t *testing.T) { }, expErrs: []error{}, }, + { + name: "Bids with price less than bidfloor with floorsPrecision", + args: args{ + bidRequestWrapper: func() *openrtb_ext.RequestWrapper { + bw := openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + ID: "some-request-id", + Imp: []openrtb2.Imp{ + {ID: "some-impression-id-1", BidFloor: 1, BidFloorCur: "USD"}, + {ID: "some-impression-id-2", BidFloor: 2, BidFloorCur: "USD"}, + }, + }, + } + bw.RebuildRequest() + return &bw + }(), + seatBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{ + "pubmatic": { + Bids: []*entities.PbsOrtbBid{ + {Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 0.998, ImpID: "some-impression-id-1"}}, + {Bid: &openrtb2.Bid{ID: "some-bid-2", Price: 1.5, DealID: "deal_Id", ImpID: "some-impression-id-2"}}, + }, + Seat: "pubmatic", + Currency: "USD", + }, + "appnexus": { + Bids: []*entities.PbsOrtbBid{ + {Bid: &openrtb2.Bid{ID: "some-bid-11", Price: 0.8, ImpID: "some-impression-id-1"}}, + {Bid: &openrtb2.Bid{ID: "some-bid-12", Price: 2.2, ImpID: "some-impression-id-2"}}, + }, + Seat: "appnexus", + Currency: "USD", + }, + }, + conversions: currency.Conversions(convert{}), + enforceDealFloors: false, + }, + expEligibleBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{ + "pubmatic": { + Bids: []*entities.PbsOrtbBid{ + {Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 0.998, ImpID: "some-impression-id-1"}}, + {Bid: &openrtb2.Bid{ID: "some-bid-2", Price: 1.5, DealID: "deal_Id", ImpID: "some-impression-id-2"}}, + }, + Seat: "pubmatic", + Currency: "USD", + }, + "appnexus": { + Bids: []*entities.PbsOrtbBid{ + {Bid: &openrtb2.Bid{ID: "some-bid-12", Price: 2.2, ImpID: "some-impression-id-2"}}, + }, + Seat: "appnexus", + Currency: "USD", + }, + }, + expRejectedBids: []*entities.PbsOrtbSeatBid{ + { + Seat: "appnexus", + Currency: "USD", + Bids: []*entities.PbsOrtbBid{ + {Bid: &openrtb2.Bid{ID: "some-bid-11", Price: 0.8, ImpID: "some-impression-id-1"}}, + }, + }, + }, + expErrs: []error{}, + }, { name: "Bids with different currency with enforceDealFloor true", args: args{ @@ -1154,7 +1219,6 @@ func TestUpdateEnforcePBS(t *testing.T) { t.Run(tt.name, func(t *testing.T) { got := updateEnforcePBS(tt.args.enforceFloors, tt.args.reqExt) assert.Equal(t, tt.want, got, tt.name) - }) } } diff --git a/floors/floors.go b/floors/floors.go index f9e13ec05fd..52591915058 100644 --- a/floors/floors.go +++ b/floors/floors.go @@ -16,15 +16,16 @@ type Price struct { } const ( - defaultCurrency string = "USD" - defaultDelimiter string = "|" - catchAll string = "*" - skipRateMin int = 0 - skipRateMax int = 100 - modelWeightMax int = 100 - modelWeightMin int = 1 - enforceRateMin int = 0 - enforceRateMax int = 100 + defaultCurrency string = "USD" + defaultDelimiter string = "|" + catchAll string = "*" + skipRateMin int = 0 + skipRateMax int = 100 + modelWeightMax int = 100 + modelWeightMin int = 1 + enforceRateMin int = 0 + enforceRateMax int = 100 + floorPrecision float64 = 0.01 ) // EnrichWithPriceFloors checks for floors enabled in account and request and selects floors data from dynamic fetched if present From 94dc670c3729221e5b2453dfef876c7ddda61892 Mon Sep 17 00:00:00 2001 From: ashishshinde-pubm <109787960+ashishshinde-pubm@users.noreply.github.com> Date: Tue, 5 Sep 2023 22:48:34 +0530 Subject: [PATCH 103/268] Fix panic observed in setSiteImplicitly function (#3053) * Issue_3052: Fix panic observed in setSiteImplicitly function * Move the site.nil check at top --- endpoints/openrtb2/auction.go | 19 ++--- endpoints/openrtb2/auction_test.go | 75 +++++++++++++------ .../invalid-whole/no-site-or-app.json | 2 +- 3 files changed, 63 insertions(+), 33 deletions(-) diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index b56b7fc55a4..6fe5aab9535 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -6,7 +6,6 @@ import ( "encoding/json" "errors" "fmt" - "github.com/prebid/prebid-server/privacy" "io" "net/http" "net/url" @@ -15,6 +14,8 @@ import ( "strings" "time" + "github.com/prebid/prebid-server/privacy" + "github.com/buger/jsonparser" "github.com/gofrs/uuid" "github.com/golang/glog" @@ -1966,8 +1967,12 @@ func setAuctionTypeImplicitly(r *openrtb_ext.RequestWrapper) { } func setSiteImplicitly(httpReq *http.Request, r *openrtb_ext.RequestWrapper) { + if r.Site == nil { + r.Site = &openrtb2.Site{} + } + referrerCandidate := httpReq.Referer() - if referrerCandidate == "" && r.Site != nil && r.Site.Page != "" { + if referrerCandidate == "" && r.Site.Page != "" { referrerCandidate = r.Site.Page // If http referer is disabled and thus has empty value - use site.page instead } @@ -1981,17 +1986,13 @@ func setSiteImplicitly(httpReq *http.Request, r *openrtb_ext.RequestWrapper) { } } - if r.Site != nil { - if siteExt, err := r.GetSiteExt(); err == nil && siteExt.GetAmp() == nil { - siteExt.SetAmp(¬Amp) - } + if siteExt, err := r.GetSiteExt(); err == nil && siteExt.GetAmp() == nil { + siteExt.SetAmp(¬Amp) } + } func setSitePageIfEmpty(site *openrtb2.Site, sitePage string) { - if site == nil { - site = &openrtb2.Site{} - } if site.Page == "" { site.Page = sitePage } diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index c42209e02ce..84e5cf4baf5 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -965,19 +965,22 @@ func TestImplicitDNTEndToEnd(t *testing.T) { func TestReferer(t *testing.T) { testCases := []struct { description string - givenSitePage string - givenSiteDomain string - givenPublisherDomain string givenReferer string expectedDomain string expectedPage string expectedPublisherDomain string + bidReq *openrtb_ext.RequestWrapper }{ { description: "site.page/domain are unchanged when site.page/domain and http referer are not set", expectedDomain: "", expectedPage: "", expectedPublisherDomain: "", + bidReq: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + Site: &openrtb2.Site{ + Publisher: &openrtb2.Publisher{}, + }, + }}, }, { description: "site.page/domain are derived from referer when neither is set and http referer is set", @@ -985,39 +988,73 @@ func TestReferer(t *testing.T) { expectedDomain: "test.somepage.com", expectedPublisherDomain: "somepage.com", expectedPage: "https://test.somepage.com", + bidReq: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + Site: &openrtb2.Site{ + Publisher: &openrtb2.Publisher{}, + }, + }}, }, { description: "site.domain is derived from site.page when site.page is set and http referer is not set", - givenSitePage: "https://test.somepage.com", expectedDomain: "test.somepage.com", expectedPublisherDomain: "somepage.com", expectedPage: "https://test.somepage.com", + bidReq: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + Site: &openrtb2.Site{ + Page: "https://test.somepage.com", + Publisher: &openrtb2.Publisher{}, + }, + }}, }, { description: "site.domain is derived from http referer when site.page and http referer are set", - givenSitePage: "https://test.somepage.com", givenReferer: "http://test.com", expectedDomain: "test.com", expectedPublisherDomain: "test.com", expectedPage: "https://test.somepage.com", + bidReq: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + Site: &openrtb2.Site{ + Page: "https://test.somepage.com", + Publisher: &openrtb2.Publisher{}, + }, + }}, }, { description: "site.page/domain are unchanged when site.page/domain and http referer are set", - givenSitePage: "https://test.somepage.com", - givenSiteDomain: "some.domain.com", givenReferer: "http://test.com", expectedDomain: "some.domain.com", expectedPublisherDomain: "test.com", expectedPage: "https://test.somepage.com", + bidReq: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + Site: &openrtb2.Site{ + Domain: "some.domain.com", + Page: "https://test.somepage.com", + Publisher: &openrtb2.Publisher{}, + }, + }}, }, { description: "Publisher domain shouldn't be overrwriten if already set", - givenSitePage: "https://test.somepage.com", - givenSiteDomain: "", - givenPublisherDomain: "differentpage.com", expectedDomain: "test.somepage.com", expectedPublisherDomain: "differentpage.com", expectedPage: "https://test.somepage.com", + bidReq: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + Site: &openrtb2.Site{ + Domain: "", + Page: "https://test.somepage.com", + Publisher: &openrtb2.Publisher{ + Domain: "differentpage.com", + }, + }, + }}, + }, + { + description: "request.site is nil", + givenReferer: "http://test.com", + expectedDomain: "test.com", + expectedPublisherDomain: "test.com", + expectedPage: "http://test.com", + bidReq: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{}}, }, } @@ -1025,20 +1062,12 @@ func TestReferer(t *testing.T) { httpReq := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(validRequest(t, "site.json"))) httpReq.Header.Set("Referer", test.givenReferer) - bidReq := &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ - Site: &openrtb2.Site{ - Domain: test.givenSiteDomain, - Page: test.givenSitePage, - Publisher: &openrtb2.Publisher{Domain: test.givenPublisherDomain}, - }, - }} - - setSiteImplicitly(httpReq, bidReq) + setSiteImplicitly(httpReq, test.bidReq) - assert.NotNil(t, bidReq.Site, test.description) - assert.Equal(t, test.expectedDomain, bidReq.Site.Domain, test.description) - assert.Equal(t, test.expectedPage, bidReq.Site.Page, test.description) - assert.Equal(t, test.expectedPublisherDomain, bidReq.Site.Publisher.Domain, test.description) + assert.NotNil(t, test.bidReq.Site, test.description) + assert.Equal(t, test.expectedDomain, test.bidReq.Site.Domain, test.description) + assert.Equal(t, test.expectedPage, test.bidReq.Site.Page, test.description) + assert.Equal(t, test.expectedPublisherDomain, test.bidReq.Site.Publisher.Domain, test.description) } } diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/no-site-or-app.json b/endpoints/openrtb2/sample-requests/invalid-whole/no-site-or-app.json index d21ca4a94ae..8ec2273ebec 100644 --- a/endpoints/openrtb2/sample-requests/invalid-whole/no-site-or-app.json +++ b/endpoints/openrtb2/sample-requests/invalid-whole/no-site-or-app.json @@ -19,5 +19,5 @@ ] }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: request.site or request.app must be defined, but not both.\n" + "expectedErrorMessage": "Invalid request: request.site should include at least one of request.site.id or request.site.page.\n" } From c35c4a90ee7d519bcd70c1a3b04ade051d78ccbd Mon Sep 17 00:00:00 2001 From: Maxime Liege <56251840+github-maxime-liege@users.noreply.github.com> Date: Tue, 5 Sep 2023 19:52:34 +0200 Subject: [PATCH 104/268] Add data field for custom renderers (#3059) --- .../exchangetest/request-ext-prebid-filtering.json | 10 ++++++++-- openrtb_ext/bid.go | 1 + openrtb_ext/request.go | 5 +++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/exchange/exchangetest/request-ext-prebid-filtering.json b/exchange/exchangetest/request-ext-prebid-filtering.json index 4355f51762c..8e85d8edfdc 100644 --- a/exchange/exchangetest/request-ext-prebid-filtering.json +++ b/exchange/exchangetest/request-ext-prebid-filtering.json @@ -65,7 +65,10 @@ "renderers": [ { "name": "test-name", - "version": "test-version" + "version": "test-version", + "data" : { + "complex": "data" + } } ] } @@ -121,7 +124,10 @@ "renderers": [ { "name": "test-name", - "version": "test-version" + "version": "test-version", + "data": { + "complex": "data" + } } ] } diff --git a/openrtb_ext/bid.go b/openrtb_ext/bid.go index 7dc620d46d7..85cfed5cbe7 100644 --- a/openrtb_ext/bid.go +++ b/openrtb_ext/bid.go @@ -66,6 +66,7 @@ type ExtBidPrebidMeta struct { PrimaryCategoryID string `json:"primaryCatId,omitempty"` RendererName string `json:"rendererName,omitempty"` RendererVersion string `json:"rendererVersion,omitempty"` + RendererData json.RawMessage `json:"rendererData,omitempty"` SecondaryCategoryIDs []string `json:"secondaryCatIds,omitempty"` } diff --git a/openrtb_ext/request.go b/openrtb_ext/request.go index 6f39f0be288..f5418ba4d1f 100644 --- a/openrtb_ext/request.go +++ b/openrtb_ext/request.go @@ -352,8 +352,9 @@ type ExtRequestSdk struct { } type ExtRequestSdkRenderer struct { - Name string `json:"name,omitempty"` - Version string `json:"version,omitempty"` + Name string `json:"name,omitempty"` + Version string `json:"version,omitempty"` + Data json.RawMessage `json:"data,omitempty"` } type ExtMultiBid struct { From 9eea8d002f4f6691673d0d497e1eae0ee754be31 Mon Sep 17 00:00:00 2001 From: ahmadlob <109217988+ahmadlob@users.noreply.github.com> Date: Wed, 6 Sep 2023 15:48:18 +0300 Subject: [PATCH 105/268] set-static-endpoint (#3058) --- static/bidder-info/taboola.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/bidder-info/taboola.yaml b/static/bidder-info/taboola.yaml index 348165a992c..436f746959a 100644 --- a/static/bidder-info/taboola.yaml +++ b/static/bidder-info/taboola.yaml @@ -1,4 +1,4 @@ -endpoint: "https://{{.MediaType}}.bidder.taboola.com/OpenRTB/PS/auction/{{.GvlID}}/{{.PublisherID}}" +endpoint: "https://{{.MediaType}}.bidder.taboola.com/OpenRTB/PS/auction?exchange={{.GvlID}}&publisher={{.PublisherID}}" maintainer: email: ps-team@taboola.com gvlVendorID: 42 From d6bca29665f441d81ce390004023d5707283fb46 Mon Sep 17 00:00:00 2001 From: Ahmet Faruk Karakus <65093478+ahmetfaruk59@users.noreply.github.com> Date: Thu, 7 Sep 2023 11:01:26 +0300 Subject: [PATCH 106/268] Huawei Ads: fix cta text empty and fill rate issue (#3070) --- adapters/huaweiads/huaweiads.go | 18 +++++++----------- .../exemplary/nativeIncludeVideo.json | 4 +--- .../exemplary/nativeSingleImage.json | 9 ++++----- .../exemplary/nativeThreeImage.json | 4 +--- .../exemplary/nativeThreeImageIncludeIcon.json | 4 +--- .../supplemental/bad_response_not_native.json | 4 +--- 6 files changed, 15 insertions(+), 28 deletions(-) diff --git a/adapters/huaweiads/huaweiads.go b/adapters/huaweiads/huaweiads.go index 071f0761bb3..2b7c3c2548d 100644 --- a/adapters/huaweiads/huaweiads.go +++ b/adapters/huaweiads/huaweiads.go @@ -185,6 +185,7 @@ type metaData struct { ApkInfo apkInfo `json:"apkInfo"` Duration int64 `json:"duration"` MediaFile mediaFile `json:"mediaFile"` + Cta string `json:"cta"` } type imageInfo struct { @@ -535,8 +536,7 @@ func getNativeFormat(adslot30 *adslot30, openRTBImp *openrtb2.Imp) error { // only compute the main image number, type = native1.ImageAssetTypeMain var numMainImage = 0 var numVideo = 0 - var width int64 - var height int64 + for _, asset := range nativePayload.Assets { // Only one of the {title,img,video,data} objects should be present in each object. if asset.Video != nil { @@ -547,19 +547,10 @@ func getNativeFormat(adslot30 *adslot30, openRTBImp *openrtb2.Imp) error { if asset.Img != nil { if asset.Img.Type == native1.ImageAssetTypeMain { numMainImage++ - if asset.Img.H != 0 && asset.Img.W != 0 { - width = asset.Img.W - height = asset.Img.H - } else if asset.Img.WMin != 0 && asset.Img.HMin != 0 { - width = asset.Img.WMin - height = asset.Img.HMin - } } continue } } - adslot30.W = width - adslot30.H = height var detailedCreativeTypeList = make([]string, 0, 2) if numVideo >= 1 { @@ -1169,6 +1160,11 @@ func (a *adapter) extractAdmNative(adType int32, content *content, bidType openr dataObject.Label = "desc" dataObject.Value = getDecodeValue(content.MetaData.Description) } + + if asset.Data.Type == native1.DataAssetTypeCTAText { + dataObject.Type = native1.DataAssetTypeCTAText + dataObject.Value = getDecodeValue(content.MetaData.Cta) + } responseAsset.Data = &dataObject } var id = asset.ID diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json index 8a7ca1b0752..24aad066b3d 100644 --- a/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json +++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json @@ -95,9 +95,7 @@ "detailedCreativeTypeList": [ "903" ], - "h": 200, - "test": 1, - "w": 200 + "test": 1 } ], "device": { diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json index 240098e038d..8e86675b4a6 100644 --- a/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json +++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json @@ -5,7 +5,7 @@ { "id": "test-imp-id", "native": { - "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"aurlsupport\":0,\"durlsupport\":0,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"privacy\":0,\"assets\":[{\"id\":100,\"title\":{\"len\":90},\"required\":1},{\"id\":103,\"img\":{\"type\":3,\"wmin\":200,\"hmin\":200},\"required\":1},{\"id\":105,\"data\":{\"type\":2,\"len\":90},\"required\":1}],\"ver\":\"1.2\"}", + "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"aurlsupport\":0,\"durlsupport\":0,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"privacy\":0,\"assets\":[{\"id\":101,\"title\":{\"len\":90},\"required\":1},{\"id\":102,\"img\":{\"type\":3,\"wmin\":200,\"hmin\":200},\"required\":1},{\"id\":103,\"data\":{\"type\":2,\"len\":90},\"required\":1},{\"id\":105,\"data\":{\"type\":12,\"len\":90}}],\"ver\":\"1.2\"}", "ver": "1.2" }, "ext": { @@ -93,9 +93,7 @@ "detailedCreativeTypeList": [ "901" ], - "h": 200, - "test": 1, - "w": 200 + "test": 1 } ], "device": { @@ -166,6 +164,7 @@ "appId": "101219405", "appPromotionChannel": "401721412", "clickUrl": "https://ads.huawei.com/usermgtportal/home/index.html#/", + "cta": "install", "duration": 6038, "description": "", "icon": [ @@ -300,7 +299,7 @@ "huaweiads" ], "crid": "58022259", - "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":100,\"title\":{\"text\":\"/test/\",\"len\":6}},{\"id\":103,\"img\":{\"type\":3,\"url\":\"http://image.jpg\",\"w\":720,\"h\":1280}},{\"id\":105,\"data\":{\"label\":\"desc\",\"value\":\"\"}}],\"link\":{\"url\":\"https://ads.huawei.com/usermgtportal/home/index.html#/\",\"clicktrackers\":[\"http://test/click\"]},\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"http://test/imp\"}]}", + "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":101,\"title\":{\"text\":\"/test/\",\"len\":6}},{\"id\":102,\"img\":{\"type\":3,\"url\":\"http://image.jpg\",\"w\":720,\"h\":1280}},{\"id\":103,\"data\":{\"label\":\"desc\",\"value\":\"\"}},{\"id\":105,\"data\":{\"type\":12,\"value\":\"install\"}}],\"link\":{\"url\":\"https://ads.huawei.com/usermgtportal/home/index.html#/\",\"clicktrackers\":[\"http://test/click\"]},\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"http://test/imp\"}]}", "id": "test-imp-id", "impid": "test-imp-id", "price": 2.8, diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json index 9b46072dd00..c29b2352d59 100644 --- a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json +++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json @@ -92,9 +92,7 @@ "detailedCreativeTypeList": [ "904" ], - "h": 200, - "test": 1, - "w": 200 + "test": 1 } ], "device": { diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json index f78f50e2f0f..5d3af50621a 100644 --- a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json +++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json @@ -93,9 +93,7 @@ "detailedCreativeTypeList": [ "904" ], - "h": 200, - "test": 1, - "w": 200 + "test": 1 } ], "device": { diff --git a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json index c38bc9f69b9..1466737008f 100644 --- a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json +++ b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json @@ -93,9 +93,7 @@ "test": 1, "detailedCreativeTypeList": [ "903" - ], - "h": 200, - "w": 200 + ] } ], "device": { From ea079a9e98363c8f54fae8a7e029c6d20bee1b35 Mon Sep 17 00:00:00 2001 From: Idan Botbol Date: Thu, 7 Sep 2023 11:44:58 +0300 Subject: [PATCH 107/268] Undertone: adding GPID support (#3078) Co-authored-by: Shahaf Sameach Co-authored-by: Shahaf Sameach <101515807+shahaf-undertone@users.noreply.github.com> --- adapters/undertone/undertone.go | 30 ++++++++++++------- .../exemplary/multi-imp-app-request.json | 8 +++-- .../exemplary/multi-imp-site-request.json | 8 +++-- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/adapters/undertone/undertone.go b/adapters/undertone/undertone.go index 62934fa5954..7f8dde35abb 100644 --- a/adapters/undertone/undertone.go +++ b/adapters/undertone/undertone.go @@ -26,6 +26,11 @@ type undertoneParams struct { Version string `json:"version"` } +type impExt struct { + Bidder *openrtb_ext.ExtImpUndertone `json:"bidder,omitempty"` + Gpid string `json:"gpid,omitempty"` +} + func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { bidder := &adapter{ endpoint: config.Endpoint, @@ -158,24 +163,29 @@ func getImpsAndPublisherId(bidRequest *openrtb2.BidRequest) ([]openrtb2.Imp, int var validImps []openrtb2.Imp for _, imp := range bidRequest.Imp { - var extImpBidder adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &extImpBidder); err != nil { - errs = append(errs, getInvalidImpErr(imp.ID, err)) - continue - } - - var extImpUndertone openrtb_ext.ExtImpUndertone - if err := json.Unmarshal(extImpBidder.Bidder, &extImpUndertone); err != nil { + var ext impExt + if err := json.Unmarshal(imp.Ext, &ext); err != nil { errs = append(errs, getInvalidImpErr(imp.ID, err)) continue } if publisherId == 0 { - publisherId = extImpUndertone.PublisherID + publisherId = ext.Bidder.PublisherID } - imp.TagID = strconv.Itoa(extImpUndertone.PlacementID) + imp.TagID = strconv.Itoa(ext.Bidder.PlacementID) imp.Ext = nil + + if ext.Gpid != "" { + ext.Bidder = nil + impExtJson, err := json.Marshal(&ext) + if err != nil { + errs = append(errs, getInvalidImpErr(imp.ID, err)) + continue + } + imp.Ext = impExtJson + } + validImps = append(validImps, imp) } diff --git a/adapters/undertone/undertonetest/exemplary/multi-imp-app-request.json b/adapters/undertone/undertonetest/exemplary/multi-imp-app-request.json index e6b4a83ae3a..71ad2ae199d 100644 --- a/adapters/undertone/undertonetest/exemplary/multi-imp-app-request.json +++ b/adapters/undertone/undertonetest/exemplary/multi-imp-app-request.json @@ -54,7 +54,8 @@ "bidder": { "publisherId": 1234, "placementId": 123456 - } + }, + "gpid": "gpid-value" } } ], @@ -116,7 +117,10 @@ 4 ] }, - "tagid": "123456" + "tagid": "123456", + "ext": { + "gpid": "gpid-value" + } } ], "app": { diff --git a/adapters/undertone/undertonetest/exemplary/multi-imp-site-request.json b/adapters/undertone/undertonetest/exemplary/multi-imp-site-request.json index 0de38caa986..9e59ffbca63 100644 --- a/adapters/undertone/undertonetest/exemplary/multi-imp-site-request.json +++ b/adapters/undertone/undertonetest/exemplary/multi-imp-site-request.json @@ -20,7 +20,8 @@ "bidder": { "publisherId": 1234, "placementId": 12345 - } + }, + "gpid": "gpid-value" } }, { @@ -87,7 +88,10 @@ } ] }, - "tagid": "12345" + "tagid": "12345", + "ext": { + "gpid": "gpid-value" + } }, { "id": "test-imp-video-id", From 9980b64f90ecfd532fc4d6173131928ae59c6428 Mon Sep 17 00:00:00 2001 From: Nikhil Vaidya <102963966+pm-nikhil-vaidya@users.noreply.github.com> Date: Thu, 7 Sep 2023 22:38:02 +0530 Subject: [PATCH 108/268] Fix: BidRequest updated by ProcessedAuction hook is getting overridden by requestwrapper utility (#3045) --- hooks/hookexecution/executor.go | 2 +- hooks/hookexecution/mocks_test.go | 14 +++++++++++--- hooks/hookstage/processedauctionrequest.go | 8 ++++---- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/hooks/hookexecution/executor.go b/hooks/hookexecution/executor.go index ce516630778..5074d4b9ab9 100644 --- a/hooks/hookexecution/executor.go +++ b/hooks/hookexecution/executor.go @@ -160,7 +160,7 @@ func (e *hookExecutor) ExecuteProcessedAuctionStage(request *openrtb_ext.Request stageName := hooks.StageProcessedAuctionRequest.String() executionCtx := e.newContext(stageName) - payload := hookstage.ProcessedAuctionRequestPayload{BidRequest: request.BidRequest} + payload := hookstage.ProcessedAuctionRequestPayload{RequestWrapper: request} outcome, _, contexts, reject := executeStage(executionCtx, plan, payload, handler, e.metricEngine) outcome.Entity = entityAuctionRequest diff --git a/hooks/hookexecution/mocks_test.go b/hooks/hookexecution/mocks_test.go index e8670ff89e8..ff543c38a07 100644 --- a/hooks/hookexecution/mocks_test.go +++ b/hooks/hookexecution/mocks_test.go @@ -131,7 +131,7 @@ func (e mockTimeoutHook) HandleProcessedAuctionHook(_ context.Context, _ hooksta time.Sleep(20 * time.Millisecond) c := hookstage.ChangeSet[hookstage.ProcessedAuctionRequestPayload]{} c.AddMutation(func(payload hookstage.ProcessedAuctionRequestPayload) (hookstage.ProcessedAuctionRequestPayload, error) { - payload.BidRequest.User.CustomData = "some-custom-data" + payload.RequestWrapper.User.CustomData = "some-custom-data" return payload, nil }, hookstage.MutationUpdate, "bidRequest", "user.customData") @@ -305,12 +305,20 @@ func (e mockUpdateBidRequestHook) HandleProcessedAuctionHook(_ context.Context, c := hookstage.ChangeSet[hookstage.ProcessedAuctionRequestPayload]{} c.AddMutation( func(payload hookstage.ProcessedAuctionRequestPayload) (hookstage.ProcessedAuctionRequestPayload, error) { - payload.BidRequest.User.Yob = 2000 + payload.RequestWrapper.User.Yob = 2000 + userExt, err := payload.RequestWrapper.GetUserExt() + if err != nil { + return payload, err + } + newPrebidExt := &openrtb_ext.ExtUserPrebid{ + BuyerUIDs: map[string]string{"some": "id"}, + } + userExt.SetPrebid(newPrebidExt) return payload, nil }, hookstage.MutationUpdate, "bidRequest", "user.yob", ).AddMutation( func(payload hookstage.ProcessedAuctionRequestPayload) (hookstage.ProcessedAuctionRequestPayload, error) { - payload.BidRequest.User.Consent = "true" + payload.RequestWrapper.User.Consent = "true" return payload, nil }, hookstage.MutationUpdate, "bidRequest", "user.consent", ) diff --git a/hooks/hookstage/processedauctionrequest.go b/hooks/hookstage/processedauctionrequest.go index 30cb0dab38d..fe06bc6fdbd 100644 --- a/hooks/hookstage/processedauctionrequest.go +++ b/hooks/hookstage/processedauctionrequest.go @@ -3,7 +3,7 @@ package hookstage import ( "context" - "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/openrtb_ext" ) // ProcessedAuctionRequest hooks are invoked after the request is parsed @@ -23,8 +23,8 @@ type ProcessedAuctionRequest interface { ) (HookResult[ProcessedAuctionRequestPayload], error) } -// ProcessedAuctionRequestPayload consists of the openrtb2.BidRequest object. -// Hooks are allowed to modify openrtb2.BidRequest using mutations. +// ProcessedAuctionRequestPayload consists of the openrtb_ext.RequestWrapper object. +// Hooks are allowed to modify openrtb_ext.RequestWrapper using mutations. type ProcessedAuctionRequestPayload struct { - BidRequest *openrtb2.BidRequest + RequestWrapper *openrtb_ext.RequestWrapper } From 01bd679d1fca8f30a831258c0690747081e7191f Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Fri, 8 Sep 2023 13:42:10 +0400 Subject: [PATCH 109/268] New adapter: Appstock (#3054) co-authored by @imedvedko --- exchange/adapter_builders.go | 1 + openrtb_ext/bidders.go | 2 ++ static/bidder-info/appstock.yaml | 16 ++++++++++++++++ static/bidder-params/appstock.json | 23 +++++++++++++++++++++++ 4 files changed, 42 insertions(+) create mode 100644 static/bidder-info/appstock.yaml create mode 100644 static/bidder-params/appstock.json diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 84b1f1afa1a..484fe59c45d 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -230,6 +230,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderApacdex: apacdex.Builder, openrtb_ext.BidderApplogy: applogy.Builder, openrtb_ext.BidderAppnexus: appnexus.Builder, + openrtb_ext.BidderAppstock: limelightDigital.Builder, openrtb_ext.BidderAppush: appush.Builder, openrtb_ext.BidderAudienceNetwork: audienceNetwork.Builder, openrtb_ext.BidderAutomatad: automatad.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index c60058ebb38..deeb1c58b6a 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -54,6 +54,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderApacdex, BidderApplogy, BidderAppnexus, + BidderAppstock, BidderAppush, BidderAudienceNetwork, BidderAutomatad, @@ -345,6 +346,7 @@ const ( BidderApacdex BidderName = "apacdex" BidderApplogy BidderName = "applogy" BidderAppnexus BidderName = "appnexus" + BidderAppstock BidderName = "appstock" BidderAppush BidderName = "appush" BidderAudienceNetwork BidderName = "audienceNetwork" BidderAutomatad BidderName = "automatad" diff --git a/static/bidder-info/appstock.yaml b/static/bidder-info/appstock.yaml new file mode 100644 index 00000000000..28f420e9e88 --- /dev/null +++ b/static/bidder-info/appstock.yaml @@ -0,0 +1,16 @@ +endpoint: "http://ads-pbs.pre.vr-tb.com/openrtb/{{.PublisherID}}?host={{.Host}}" +maintainer: + email: "engineering@project-limelight.com" +capabilities: + app: + mediaTypes: + - banner + - video + - audio + - native + site: + mediaTypes: + - banner + - video + - audio + - native diff --git a/static/bidder-params/appstock.json b/static/bidder-params/appstock.json new file mode 100644 index 00000000000..eb2251e4e47 --- /dev/null +++ b/static/bidder-params/appstock.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Appstock Adapter Params", + "description": "A schema which validates params accepted by the Appstock adapter", + "type": "object", + + "properties": { + "host": { + "type": "string", + "description": "Ad network's RTB host", + "format": "hostname", + "pattern": "^.+\\..+$" + }, + "publisherId": { + "type": ["integer", "string"], + "description": "Publisher ID", + "minimum": 1, + "pattern": "^[1-9][0-9]*$" + } + }, + + "required": ["host", "publisherId"] +} From a292b3a356a0f7edeedf21a2d484a46bfb161064 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Mon, 11 Sep 2023 10:58:44 +0530 Subject: [PATCH 110/268] Fix CheckResponseStatusCodeForErrors adapter response util (#3086) co-authored by @onkarvhanumante --- adapters/response.go | 4 +++- adapters/response_test.go | 36 ++++++++++++++++++++++++++---------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/adapters/response.go b/adapters/response.go index 080f46273cc..8b7d59bd2c0 100644 --- a/adapters/response.go +++ b/adapters/response.go @@ -15,7 +15,9 @@ func CheckResponseStatusCodeForErrors(response *ResponseData) error { } if response.StatusCode != http.StatusOK { - return fmt.Errorf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode) + return &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), + } } return nil diff --git a/adapters/response_test.go b/adapters/response_test.go index 824a295e73d..0651ff2646f 100644 --- a/adapters/response_test.go +++ b/adapters/response_test.go @@ -8,17 +8,33 @@ import ( ) func TestCheckResponseStatusCodeForErrors(t *testing.T) { - t.Run("bad_input", func(t *testing.T) { - err := CheckResponseStatusCodeForErrors(&ResponseData{StatusCode: 400}) - expectedErr := &errortypes.BadInput{Message: "Unexpected status code: 400. Run with request.debug = 1 for more info"} - assert.Equal(t, expectedErr.Error(), err.Error()) - }) + testCases := []struct { + name string + responseStatus int + expectedErr error + }{ + { + name: "bad_input", + responseStatus: 400, + expectedErr: &errortypes.BadInput{ + Message: "Unexpected status code: 400. Run with request.debug = 1 for more info", + }, + }, + { + name: "internal_server_error", + responseStatus: 500, + expectedErr: &errortypes.BadServerResponse{ + Message: "Unexpected status code: 500. Run with request.debug = 1 for more info", + }, + }, + } - t.Run("internal_server_error", func(t *testing.T) { - err := CheckResponseStatusCodeForErrors(&ResponseData{StatusCode: 500}) - expectedErrMessage := "Unexpected status code: 500. Run with request.debug = 1 for more info" - assert.Equal(t, expectedErrMessage, err.Error()) - }) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := CheckResponseStatusCodeForErrors(&ResponseData{StatusCode: tc.responseStatus}) + assert.Equal(t, tc.expectedErr, err) + }) + } } func TestIsResponseStatusCodeNoContent(t *testing.T) { From 71f76eb39e23d778e7ff3356711004775851e56e Mon Sep 17 00:00:00 2001 From: Irakli Gotsiridze Date: Mon, 11 Sep 2023 12:59:01 +0300 Subject: [PATCH 111/268] Sovrn: Adapter to accept ad unit codes (#3060) co-authored by @ikagotso --- adapters/sovrn/sovrn.go | 19 +++ .../sovrntest/supplemental/adunitcode.json | 125 ++++++++++++++++++ .../sovrn/sovrntest/supplemental/fpd.json | 3 +- .../supplemental/invalid-adunitcode.json | 123 +++++++++++++++++ openrtb_ext/imp_sovrn.go | 7 +- static/bidder-params/sovrn.json | 4 + 6 files changed, 276 insertions(+), 5 deletions(-) create mode 100644 adapters/sovrn/sovrntest/supplemental/adunitcode.json create mode 100644 adapters/sovrn/sovrntest/supplemental/invalid-adunitcode.json diff --git a/adapters/sovrn/sovrn.go b/adapters/sovrn/sovrn.go index 240224903a4..405e5ebf763 100644 --- a/adapters/sovrn/sovrn.go +++ b/adapters/sovrn/sovrn.go @@ -20,6 +20,11 @@ type SovrnAdapter struct { URI string } +type sovrnImpExt struct { + Bidder openrtb_ext.ExtImpSovrn `json:"bidder"` + AdUnitCode string `json:"adunitcode,omitempty"` +} + func (s *SovrnAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { headers := http.Header{} headers.Add("Content-Type", "application/json") @@ -74,6 +79,20 @@ func (s *SovrnAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapt imp.BidFloor = sovrnExt.BidFloor } + var impExtBuffer []byte + impExtBuffer, err = json.Marshal(&sovrnImpExt{ + Bidder: sovrnExt, + AdUnitCode: sovrnExt.AdUnitCode, + }) + if err != nil { + errs = append(errs, &errortypes.BadInput{ + Message: err.Error(), + }) + continue + } + + imp.Ext = impExtBuffer + // Validate video params if appropriate video := imp.Video if video != nil { diff --git a/adapters/sovrn/sovrntest/supplemental/adunitcode.json b/adapters/sovrn/sovrntest/supplemental/adunitcode.json new file mode 100644 index 00000000000..4719752058d --- /dev/null +++ b/adapters/sovrn/sovrntest/supplemental/adunitcode.json @@ -0,0 +1,125 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "tagid": "123456", + "adunitcode": "sovrn_auc" + } + } + } + ], + "device": { }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/awesome/site" + }, + "user": { + "buyeruid": "test_reader_id" + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": ["application/json"], + "Cookie": ["ljt_reader=test_reader_id"] + }, + "uri": "http://sovrn.com/test/endpoint", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "tagid": "123456", + "ext": { + "adunitcode": "sovrn_auc", + "bidder": { + "tagid": "123456", + "adunitcode": "sovrn_auc" + } + } + } + ], + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/awesome/site" + }, + "user": { + "buyeruid": "test_reader_id" + }, + "device": { } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "a_449642_554a13d3b9f348fba707cf83f0f63800", + "impid": "test-imp-id", + "price": 3.5, + "nurl": "http://sovrn.com/rtb/impression?bannerid=138743&campaignid=3699&zoneid=449642&cb=69493397&tid=a_449642_554a13d3b9f348fba707cf83f0f63800", + "adm": "some-test-ad", + "w": 300, + "h": 250 + } + ] + } + ] + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "a_449642_554a13d3b9f348fba707cf83f0f63800", + "impid": "test-imp-id", + "price": 3.5, + "adm": "some-test-ad", + "nurl": "http://sovrn.com/rtb/impression?bannerid=138743&campaignid=3699&zoneid=449642&cb=69493397&tid=a_449642_554a13d3b9f348fba707cf83f0f63800", + "w": 300, + "h": 250 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/sovrn/sovrntest/supplemental/fpd.json b/adapters/sovrn/sovrntest/supplemental/fpd.json index 005d159d740..e4368c13c2b 100644 --- a/adapters/sovrn/sovrntest/supplemental/fpd.json +++ b/adapters/sovrn/sovrntest/supplemental/fpd.json @@ -86,8 +86,7 @@ "tagid": "123456", "ext": { "bidder": { - "tagid": "123456", - "anotherid": "654321" + "tagid": "123456" } } } diff --git a/adapters/sovrn/sovrntest/supplemental/invalid-adunitcode.json b/adapters/sovrn/sovrntest/supplemental/invalid-adunitcode.json new file mode 100644 index 00000000000..fdb14371336 --- /dev/null +++ b/adapters/sovrn/sovrntest/supplemental/invalid-adunitcode.json @@ -0,0 +1,123 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "AdUnitCode": "sovrn_auc", + "bidder": { + "tagid": "123456" + } + } + } + ], + "device": { }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/awesome/site" + }, + "user": { + "buyeruid": "test_reader_id" + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": ["application/json"], + "Cookie": ["ljt_reader=test_reader_id"] + }, + "uri": "http://sovrn.com/test/endpoint", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "tagid": "123456", + "ext": { + "bidder": { + "tagid": "123456" + } + } + } + ], + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/awesome/site" + }, + "user": { + "buyeruid": "test_reader_id" + }, + "device": { } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "a_449642_554a13d3b9f348fba707cf83f0f63800", + "impid": "test-imp-id", + "price": 3.5, + "nurl": "http://sovrn.com/rtb/impression?bannerid=138743&campaignid=3699&zoneid=449642&cb=69493397&tid=a_449642_554a13d3b9f348fba707cf83f0f63800", + "adm": "some-test-ad", + "w": 300, + "h": 250 + } + ] + } + ] + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "a_449642_554a13d3b9f348fba707cf83f0f63800", + "impid": "test-imp-id", + "price": 3.5, + "adm": "some-test-ad", + "nurl": "http://sovrn.com/rtb/impression?bannerid=138743&campaignid=3699&zoneid=449642&cb=69493397&tid=a_449642_554a13d3b9f348fba707cf83f0f63800", + "w": 300, + "h": 250 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/openrtb_ext/imp_sovrn.go b/openrtb_ext/imp_sovrn.go index 38d2f785803..362463f9513 100644 --- a/openrtb_ext/imp_sovrn.go +++ b/openrtb_ext/imp_sovrn.go @@ -1,7 +1,8 @@ package openrtb_ext type ExtImpSovrn struct { - TagId string `json:"tagId,omitempty"` - Tagid string `json:"tagid,omitempty"` - BidFloor float64 `json:"bidfloor"` + TagId string `json:"tagId,omitempty"` + Tagid string `json:"tagid,omitempty"` + BidFloor float64 `json:"bidfloor,omitempty"` + AdUnitCode string `json:"adunitcode,omitempty"` } diff --git a/static/bidder-params/sovrn.json b/static/bidder-params/sovrn.json index 6b345b5562b..d821a808f97 100644 --- a/static/bidder-params/sovrn.json +++ b/static/bidder-params/sovrn.json @@ -16,6 +16,10 @@ "bidfloor": { "type": "number", "description": "The minimium acceptable bid, in CPM, using US Dollars" + }, + "adunitcode": { + "type": "string", + "description": "The string which identifies Ad Unit" } }, "oneOf": [ From 1323b355dc10716fe67a8ae620463f82a9f3505d Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Mon, 11 Sep 2023 16:54:41 -0400 Subject: [PATCH 112/268] Prebid Meta Data: Add RendererUrl (#3087) --- openrtb_ext/bid.go | 1 + 1 file changed, 1 insertion(+) diff --git a/openrtb_ext/bid.go b/openrtb_ext/bid.go index 85cfed5cbe7..2e190389212 100644 --- a/openrtb_ext/bid.go +++ b/openrtb_ext/bid.go @@ -67,6 +67,7 @@ type ExtBidPrebidMeta struct { RendererName string `json:"rendererName,omitempty"` RendererVersion string `json:"rendererVersion,omitempty"` RendererData json.RawMessage `json:"rendererData,omitempty"` + RendererUrl string `json:"rendererUrl,omitempty"` SecondaryCategoryIDs []string `json:"secondaryCatIds,omitempty"` } From fc5b00b4d44739b602798c36e738f108f35aa650 Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Mon, 11 Sep 2023 17:54:26 -0400 Subject: [PATCH 113/268] Activities: Back To Spec (#3081) --- endpoints/cookie_sync.go | 7 +- endpoints/cookie_sync_test.go | 35 +--- endpoints/openrtb2/amp_auction.go | 12 +- endpoints/openrtb2/auction.go | 11 +- endpoints/openrtb2/video_auction.go | 11 +- endpoints/openrtb2/video_auction_test.go | 14 -- endpoints/setuid.go | 9 +- exchange/exchange_test.go | 5 +- exchange/utils_test.go | 3 +- privacy/activitycontrol.go | 92 +++------- privacy/activitycontrol_test.go | 172 ++++-------------- privacy/component.go | 48 +---- privacy/component_test.go | 105 ++++------- privacy/rule.go | 5 + privacy/{rules.go => rule_condition.go} | 22 +-- .../{rules_test.go => rule_condition_test.go} | 40 ++-- 16 files changed, 134 insertions(+), 457 deletions(-) create mode 100644 privacy/rule.go rename privacy/{rules.go => rule_condition.go} (64%) rename privacy/{rules_test.go => rule_condition_test.go} (69%) diff --git a/endpoints/cookie_sync.go b/endpoints/cookie_sync.go index 50cb449193a..0321fea3328 100644 --- a/endpoints/cookie_sync.go +++ b/endpoints/cookie_sync.go @@ -149,12 +149,7 @@ func (c *cookieSyncEndpoint) parseRequest(r *http.Request) (usersync.Request, pr } } - activityControl, activitiesErr := privacy.NewActivityControl(&account.Privacy) - if activitiesErr != nil { - if errortypes.ContainsFatalError([]error{activitiesErr}) { - activityControl = privacy.ActivityControl{} - } - } + activityControl := privacy.NewActivityControl(&account.Privacy) syncTypeFilter, err := parseTypeFilter(request.FilterSettings) if err != nil { diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go index 45c27f0ea31..a674e9db537 100644 --- a/endpoints/cookie_sync_test.go +++ b/endpoints/cookie_sync_test.go @@ -974,38 +974,6 @@ func TestCookieSyncParseRequest(t *testing.T) { expectedError: errCookieSyncAccountBlocked.Error(), givenAccountRequired: true, }, - - { - description: "Account Defaults - Invalid Activities", - givenBody: strings.NewReader(`{` + - `"bidders":["a", "b"],` + - `"account":"ValidAccountInvalidActivities"` + - `}`), - givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, - givenCCPAEnabled: true, - givenConfig: config.UserSync{ - Cooperative: config.UserSyncCooperative{ - EnabledByDefault: false, - PriorityGroups: [][]string{{"a", "b", "c"}}, - }, - }, - expectedPrivacy: privacy.Policies{}, - expectedRequest: usersync.Request{ - Bidders: []string{"a", "b"}, - Cooperative: usersync.Cooperative{ - Enabled: false, - PriorityGroups: [][]string{{"a", "b", "c"}}, - }, - Limit: 0, - Privacy: usersyncPrivacy{ - gdprPermissions: &fakePermissions{}, - }, - SyncTypeFilter: usersync.SyncTypeFilter{ - IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), - Redirect: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), - }, - }, - }, } for _, test := range testCases { @@ -1934,8 +1902,7 @@ func TestCookieSyncActivityControlIntegration(t *testing.T) { for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - activities, err := privacy.NewActivityControl(test.accountPrivacy) - assert.NoError(t, err) + activities := privacy.NewActivityControl(test.accountPrivacy) up := usersyncPrivacy{ activityControl: activities, } diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index 142f7320e27..2879610d8e4 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -6,12 +6,13 @@ import ( "encoding/json" "errors" "fmt" - "github.com/prebid/prebid-server/privacy" "net/http" "net/url" "strings" "time" + "github.com/prebid/prebid-server/privacy" + "github.com/buger/jsonparser" "github.com/golang/glog" "github.com/julienschmidt/httprouter" @@ -229,12 +230,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h tcf2Config := gdpr.NewTCF2Config(deps.cfg.GDPR.TCF2, account.GDPR) - activities, activitiesErr := privacy.NewActivityControl(&account.Privacy) - if activitiesErr != nil { - errL = append(errL, activitiesErr) - writeError(errL, w, &labels) - return - } + activityControl := privacy.NewActivityControl(&account.Privacy) secGPC := r.Header.Get("Sec-GPC") @@ -253,7 +249,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h HookExecutor: hookExecutor, QueryParams: r.URL.Query(), TCF2Config: tcf2Config, - Activities: activities, + Activities: activityControl, TmaxAdjustments: deps.tmaxAdjustments, } diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 6fe5aab9535..aeb5c20e64e 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -194,14 +194,7 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http tcf2Config := gdpr.NewTCF2Config(deps.cfg.GDPR.TCF2, account.GDPR) - activities, activitiesErr := privacy.NewActivityControl(&account.Privacy) - if activitiesErr != nil { - errL = append(errL, activitiesErr) - if errortypes.ContainsFatalError(errL) { - writeError(errL, w, &labels) - return - } - } + activityControl := privacy.NewActivityControl(&account.Privacy) ctx := context.Background() @@ -252,7 +245,7 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http PubID: labels.PubID, HookExecutor: hookExecutor, TCF2Config: tcf2Config, - Activities: activities, + Activities: activityControl, TmaxAdjustments: deps.tmaxAdjustments, } auctionResponse, err := deps.ex.HoldAuction(ctx, auctionRequest, nil) diff --git a/endpoints/openrtb2/video_auction.go b/endpoints/openrtb2/video_auction.go index 5f848446333..a2a519fa8df 100644 --- a/endpoints/openrtb2/video_auction.go +++ b/endpoints/openrtb2/video_auction.go @@ -303,14 +303,7 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re return } - activities, activitiesErr := privacy.NewActivityControl(&account.Privacy) - if activitiesErr != nil { - errL = append(errL, activitiesErr) - if errortypes.ContainsFatalError(errL) { - handleError(&labels, w, errL, &vo, &debugLog) - return - } - } + activityControl := privacy.NewActivityControl(&account.Privacy) secGPC := r.Header.Get("Sec-GPC") auctionRequest := &exchange.AuctionRequest{ @@ -324,7 +317,7 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re PubID: labels.PubID, HookExecutor: hookexecution.EmptyHookExecutor{}, TmaxAdjustments: deps.tmaxAdjustments, - Activities: activities, + Activities: activityControl, } auctionResponse, err := deps.ex.HoldAuction(ctx, auctionRequest, &debugLog) diff --git a/endpoints/openrtb2/video_auction_test.go b/endpoints/openrtb2/video_auction_test.go index 3c2528e2aeb..da4522ebe0c 100644 --- a/endpoints/openrtb2/video_auction_test.go +++ b/endpoints/openrtb2/video_auction_test.go @@ -65,20 +65,6 @@ func TestVideoEndpointImpressionsNumber(t *testing.T) { assert.Equal(t, resp.AdPods[0].Targeting[0].HbDeal, "ABC_123", "If DealID exists in bid response, hb_deal targeting needs to be added to resp") } -func TestVideoEndpointInvalidPrivacyConfig(t *testing.T) { - ex := &mockExchangeVideo{} - reqBody := readVideoTestFile(t, "sample-requests/video/video_valid_sample.json") - req := httptest.NewRequest("POST", "/openrtb2/video", strings.NewReader(reqBody)) - recorder := httptest.NewRecorder() - - deps := mockDepsInvalidPrivacy(t, ex) - deps.VideoAuctionEndpoint(recorder, req, nil) - - respBytes := recorder.Body.Bytes() - expectedErrorMessage := "Critical error while running the video endpoint: unable to parse component: bidderA.BidderB.bidderC" - assert.Equal(t, expectedErrorMessage, string(respBytes), "error message is incorrect") -} - func TestVideoEndpointImpressionsDuration(t *testing.T) { ex := &mockExchangeVideo{} reqBody := readVideoTestFile(t, "sample-requests/video/video_valid_sample_different_durations.json") diff --git a/endpoints/setuid.go b/endpoints/setuid.go index 30a1cce2751..b9023cfca9b 100644 --- a/endpoints/setuid.go +++ b/endpoints/setuid.go @@ -104,14 +104,9 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use return } - activities, activitiesErr := privacy.NewActivityControl(&account.Privacy) - if activitiesErr != nil { - if errortypes.ContainsFatalError([]error{activitiesErr}) { - activities = privacy.ActivityControl{} - } - } + activityControl := privacy.NewActivityControl(&account.Privacy) - userSyncActivityAllowed := activities.Allow(privacy.ActivitySyncUser, + userSyncActivityAllowed := activityControl.Allow(privacy.ActivitySyncUser, privacy.Component{Type: privacy.ComponentTypeBidder, Name: bidderName}) if !userSyncActivityAllowed { w.WriteHeader(http.StatusUnavailableForLegalReasons) diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go index 919f8dceb54..8ca96880781 100644 --- a/exchange/exchange_test.go +++ b/exchange/exchange_test.go @@ -2352,10 +2352,7 @@ func runSpec(t *testing.T, filename string, spec *exchangeSpec) { impExtInfoMap[impID] = ImpExtInfo{} } - activityControl, err := privacy.NewActivityControl(spec.AccountPrivacy) - if err != nil { - t.Errorf("%s: Exchange returned an unexpected error. Got %s", filename, err.Error()) - } + activityControl := privacy.NewActivityControl(spec.AccountPrivacy) auctionRequest := &AuctionRequest{ BidRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: &spec.IncomingRequest.OrtbRequest}, diff --git a/exchange/utils_test.go b/exchange/utils_test.go index 1ab86fcd9e7..a1ca0a607ef 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -4364,8 +4364,7 @@ func TestCleanOpenRTBRequestsActivities(t *testing.T) { } for _, test := range testCases { - activities, err := privacy.NewActivityControl(&test.privacyConfig) - assert.NoError(t, err, "") + activities := privacy.NewActivityControl(&test.privacyConfig) auctionReq := AuctionRequest{ BidRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: test.req}, UserSyncs: &emptyUsersync{}, diff --git a/privacy/activitycontrol.go b/privacy/activitycontrol.go index 5d68ce71770..33c138f7ab3 100644 --- a/privacy/activitycontrol.go +++ b/privacy/activitycontrol.go @@ -18,66 +18,35 @@ type ActivityControl struct { plans map[Activity]ActivityPlan } -func NewActivityControl(privacyConf *config.AccountPrivacy) (ActivityControl, error) { +func NewActivityControl(cfg *config.AccountPrivacy) ActivityControl { ac := ActivityControl{} - var err error - if privacyConf == nil || privacyConf.AllowActivities == nil { - return ac, nil - } - - plans := make(map[Activity]ActivityPlan) - - plans[ActivitySyncUser], err = buildEnforcementPlan(privacyConf.AllowActivities.SyncUser) - if err != nil { - return ac, err - } - plans[ActivityFetchBids], err = buildEnforcementPlan(privacyConf.AllowActivities.FetchBids) - if err != nil { - return ac, err - } - plans[ActivityEnrichUserFPD], err = buildEnforcementPlan(privacyConf.AllowActivities.EnrichUserFPD) - if err != nil { - return ac, err - } - plans[ActivityReportAnalytics], err = buildEnforcementPlan(privacyConf.AllowActivities.ReportAnalytics) - if err != nil { - return ac, err - } - plans[ActivityTransmitUserFPD], err = buildEnforcementPlan(privacyConf.AllowActivities.TransmitUserFPD) - if err != nil { - return ac, err - } - plans[ActivityTransmitPreciseGeo], err = buildEnforcementPlan(privacyConf.AllowActivities.TransmitPreciseGeo) - if err != nil { - return ac, err - } - plans[ActivityTransmitUniqueRequestIds], err = buildEnforcementPlan(privacyConf.AllowActivities.TransmitUniqueRequestIds) - if err != nil { - return ac, err - } - plans[ActivityTransmitTids], err = buildEnforcementPlan(privacyConf.AllowActivities.TransmitTids) - if err != nil { - return ac, err + if cfg == nil || cfg.AllowActivities == nil { + return ac } + plans := make(map[Activity]ActivityPlan, 8) + plans[ActivitySyncUser] = buildPlan(cfg.AllowActivities.SyncUser) + plans[ActivityFetchBids] = buildPlan(cfg.AllowActivities.FetchBids) + plans[ActivityEnrichUserFPD] = buildPlan(cfg.AllowActivities.EnrichUserFPD) + plans[ActivityReportAnalytics] = buildPlan(cfg.AllowActivities.ReportAnalytics) + plans[ActivityTransmitUserFPD] = buildPlan(cfg.AllowActivities.TransmitUserFPD) + plans[ActivityTransmitPreciseGeo] = buildPlan(cfg.AllowActivities.TransmitPreciseGeo) + plans[ActivityTransmitUniqueRequestIds] = buildPlan(cfg.AllowActivities.TransmitUniqueRequestIds) + plans[ActivityTransmitTids] = buildPlan(cfg.AllowActivities.TransmitTids) ac.plans = plans - return ac, nil + return ac } -func buildEnforcementPlan(activity config.Activity) (ActivityPlan, error) { - ef := ActivityPlan{} - rules, err := activityRulesToEnforcementRules(activity.Rules) - if err != nil { - return ef, err +func buildPlan(activity config.Activity) ActivityPlan { + return ActivityPlan{ + rules: cfgToRules(activity.Rules), + defaultResult: cfgToDefaultResult(activity.Default), } - ef.defaultResult = activityDefaultToDefaultResult(activity.Default) - ef.rules = rules - return ef, nil } -func activityRulesToEnforcementRules(rules []config.ActivityRule) ([]Rule, error) { +func cfgToRules(rules []config.ActivityRule) []Rule { var enfRules []Rule for _, r := range rules { @@ -88,34 +57,17 @@ func activityRulesToEnforcementRules(rules []config.ActivityRule) ([]Rule, error result = ActivityDeny } - componentName, err := conditionToRuleComponentNames(r.Condition.ComponentName) - if err != nil { - return nil, err - } - - er := ComponentEnforcementRule{ + er := ConditionRule{ result: result, - componentName: componentName, + componentName: r.Condition.ComponentName, componentType: r.Condition.ComponentType, } enfRules = append(enfRules, er) } - return enfRules, nil -} - -func conditionToRuleComponentNames(conditions []string) ([]Component, error) { - sn := make([]Component, 0) - for _, condition := range conditions { - scope, err := ParseComponent(condition) - if err != nil { - return nil, err - } - sn = append(sn, scope) - } - return sn, nil + return enfRules } -func activityDefaultToDefaultResult(activityDefault *bool) bool { +func cfgToDefaultResult(activityDefault *bool) bool { if activityDefault == nil { return defaultActivityResult } diff --git a/privacy/activitycontrol_test.go b/privacy/activitycontrol_test.go index db5d588de44..11a9bdc7c2d 100644 --- a/privacy/activitycontrol_test.go +++ b/privacy/activitycontrol_test.go @@ -1,7 +1,6 @@ package privacy import ( - "errors" "testing" "github.com/prebid/prebid-server/config" @@ -14,136 +13,48 @@ func TestNewActivityControl(t *testing.T) { name string privacyConf config.AccountPrivacy activityControl ActivityControl - err error }{ { - name: "privacy_config_is_empty", + name: "empty", privacyConf: config.AccountPrivacy{}, activityControl: ActivityControl{plans: nil}, - err: nil, }, { - name: "privacy_config_is_specified_and_correct", + name: "specified_and_correct", privacyConf: config.AccountPrivacy{ AllowActivities: &config.AllowActivities{ - SyncUser: getDefaultActivityConfig(), - FetchBids: getDefaultActivityConfig(), - EnrichUserFPD: getDefaultActivityConfig(), - ReportAnalytics: getDefaultActivityConfig(), - TransmitUserFPD: getDefaultActivityConfig(), - TransmitPreciseGeo: getDefaultActivityConfig(), - TransmitUniqueRequestIds: getDefaultActivityConfig(), - TransmitTids: getDefaultActivityConfig(), + SyncUser: getTestActivityConfig(true), + FetchBids: getTestActivityConfig(true), + EnrichUserFPD: getTestActivityConfig(true), + ReportAnalytics: getTestActivityConfig(true), + TransmitUserFPD: getTestActivityConfig(true), + TransmitPreciseGeo: getTestActivityConfig(false), + TransmitUniqueRequestIds: getTestActivityConfig(true), + TransmitTids: getTestActivityConfig(true), }, }, activityControl: ActivityControl{plans: map[Activity]ActivityPlan{ - ActivitySyncUser: getDefaultActivityPlan(), - ActivityFetchBids: getDefaultActivityPlan(), - ActivityEnrichUserFPD: getDefaultActivityPlan(), - ActivityReportAnalytics: getDefaultActivityPlan(), - ActivityTransmitUserFPD: getDefaultActivityPlan(), - ActivityTransmitPreciseGeo: getDefaultActivityPlan(), - ActivityTransmitUniqueRequestIds: getDefaultActivityPlan(), - ActivityTransmitTids: getDefaultActivityPlan(), + ActivitySyncUser: getTestActivityPlan(ActivityAllow), + ActivityFetchBids: getTestActivityPlan(ActivityAllow), + ActivityEnrichUserFPD: getTestActivityPlan(ActivityAllow), + ActivityReportAnalytics: getTestActivityPlan(ActivityAllow), + ActivityTransmitUserFPD: getTestActivityPlan(ActivityAllow), + ActivityTransmitPreciseGeo: getTestActivityPlan(ActivityDeny), + ActivityTransmitUniqueRequestIds: getTestActivityPlan(ActivityAllow), + ActivityTransmitTids: getTestActivityPlan(ActivityAllow), }}, - err: nil, - }, - { - name: "privacy_config_is_specified_and_SyncUser_is_incorrect", - privacyConf: config.AccountPrivacy{ - AllowActivities: &config.AllowActivities{ - SyncUser: getIncorrectActivityConfig(), - }, - }, - activityControl: ActivityControl{plans: nil}, - err: errors.New("unable to parse component: bidder.bidderA.bidderB"), - }, - { - name: "privacy_config_is_specified_and_FetchBids_is_incorrect", - privacyConf: config.AccountPrivacy{ - AllowActivities: &config.AllowActivities{ - FetchBids: getIncorrectActivityConfig(), - }, - }, - activityControl: ActivityControl{plans: nil}, - err: errors.New("unable to parse component: bidder.bidderA.bidderB"), - }, - { - name: "privacy_config_is_specified_and_EnrichUserFPD_is_incorrect", - privacyConf: config.AccountPrivacy{ - AllowActivities: &config.AllowActivities{ - EnrichUserFPD: getIncorrectActivityConfig(), - }, - }, - activityControl: ActivityControl{plans: nil}, - err: errors.New("unable to parse component: bidder.bidderA.bidderB"), - }, - { - name: "privacy_config_is_specified_and_ReportAnalytics_is_incorrect", - privacyConf: config.AccountPrivacy{ - AllowActivities: &config.AllowActivities{ - ReportAnalytics: getIncorrectActivityConfig(), - }, - }, - activityControl: ActivityControl{plans: nil}, - err: errors.New("unable to parse component: bidder.bidderA.bidderB"), - }, - { - name: "privacy_config_is_specified_and_TransmitUserFPD_is_incorrect", - privacyConf: config.AccountPrivacy{ - AllowActivities: &config.AllowActivities{ - TransmitUserFPD: getIncorrectActivityConfig(), - }, - }, - activityControl: ActivityControl{plans: nil}, - err: errors.New("unable to parse component: bidder.bidderA.bidderB"), - }, - { - name: "privacy_config_is_specified_and_TransmitPreciseGeo_is_incorrect", - privacyConf: config.AccountPrivacy{ - AllowActivities: &config.AllowActivities{ - TransmitPreciseGeo: getIncorrectActivityConfig(), - }, - }, - activityControl: ActivityControl{plans: nil}, - err: errors.New("unable to parse component: bidder.bidderA.bidderB"), - }, - { - name: "privacy_config_is_specified_and_TransmitUniqueRequestIds_is_incorrect", - privacyConf: config.AccountPrivacy{ - AllowActivities: &config.AllowActivities{ - TransmitUniqueRequestIds: getIncorrectActivityConfig(), - }, - }, - activityControl: ActivityControl{plans: nil}, - err: errors.New("unable to parse component: bidder.bidderA.bidderB"), - }, - { - name: "privacy_config_is_specified_and_TransmitTids_is_incorrect", - privacyConf: config.AccountPrivacy{ - AllowActivities: &config.AllowActivities{ - TransmitTids: getIncorrectActivityConfig(), - }, - }, - activityControl: ActivityControl{plans: nil}, - err: errors.New("unable to parse component: bidder.bidderA.bidderB"), }, } for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - actualAC, actualErr := NewActivityControl(&test.privacyConf) - if test.err == nil { - assert.Equal(t, test.activityControl, actualAC) - assert.NoError(t, actualErr) - } else { - assert.EqualError(t, actualErr, test.err.Error()) - } + actualAC := NewActivityControl(&test.privacyConf) + assert.Equal(t, test.activityControl, actualAC) }) } } -func TestActivityDefaultToDefaultResult(t *testing.T) { +func TestCfgToDefaultResult(t *testing.T) { testCases := []struct { name string activityDefault *bool @@ -168,14 +79,13 @@ func TestActivityDefaultToDefaultResult(t *testing.T) { for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - actualResult := activityDefaultToDefaultResult(test.activityDefault) + actualResult := cfgToDefaultResult(test.activityDefault) assert.Equal(t, test.expectedResult, actualResult) }) } } -func TestAllowActivityControl(t *testing.T) { - +func TestActivityControlAllow(t *testing.T) { testCases := []struct { name string activityControl ActivityControl @@ -193,7 +103,7 @@ func TestAllowActivityControl(t *testing.T) { { name: "activity_not_defined", activityControl: ActivityControl{plans: map[Activity]ActivityPlan{ - ActivitySyncUser: getDefaultActivityPlan()}}, + ActivitySyncUser: getTestActivityPlan(ActivityAllow)}}, activity: ActivityFetchBids, target: Component{Type: "bidder", Name: "bidderA"}, activityResult: true, @@ -201,7 +111,7 @@ func TestAllowActivityControl(t *testing.T) { { name: "activity_defined_but_not_found_default_returned", activityControl: ActivityControl{plans: map[Activity]ActivityPlan{ - ActivityFetchBids: getDefaultActivityPlan()}}, + ActivityFetchBids: getTestActivityPlan(ActivityAllow)}}, activity: ActivityFetchBids, target: Component{Type: "bidder", Name: "bidderB"}, activityResult: true, @@ -209,7 +119,7 @@ func TestAllowActivityControl(t *testing.T) { { name: "activity_defined_and_allowed", activityControl: ActivityControl{plans: map[Activity]ActivityPlan{ - ActivityFetchBids: getDefaultActivityPlan()}}, + ActivityFetchBids: getTestActivityPlan(ActivityAllow)}}, activity: ActivityFetchBids, target: Component{Type: "bidder", Name: "bidderA"}, activityResult: true, @@ -225,13 +135,12 @@ func TestAllowActivityControl(t *testing.T) { } } -// constants -func getDefaultActivityConfig() config.Activity { +func getTestActivityConfig(allow bool) config.Activity { return config.Activity{ Default: ptrutil.ToPtr(true), Rules: []config.ActivityRule{ { - Allow: true, + Allow: allow, Condition: config.ActivityCondition{ ComponentName: []string{"bidderA"}, ComponentType: []string{"bidder"}, @@ -241,32 +150,15 @@ func getDefaultActivityConfig() config.Activity { } } -func getDefaultActivityPlan() ActivityPlan { +func getTestActivityPlan(result ActivityResult) ActivityPlan { return ActivityPlan{ defaultResult: true, rules: []Rule{ - ComponentEnforcementRule{ - result: ActivityAllow, - componentName: []Component{ - {Type: "bidder", Name: "bidderA"}, - }, + ConditionRule{ + result: result, + componentName: []string{"bidderA"}, componentType: []string{"bidder"}, }, }, } } - -func getIncorrectActivityConfig() config.Activity { - return config.Activity{ - Default: ptrutil.ToPtr(true), - Rules: []config.ActivityRule{ - { - Allow: true, - Condition: config.ActivityCondition{ - ComponentName: []string{"bidder.bidderA.bidderB"}, - ComponentType: []string{"bidder"}, - }, - }, - }, - } -} diff --git a/privacy/component.go b/privacy/component.go index a203c6bdb3b..33767938ab3 100644 --- a/privacy/component.go +++ b/privacy/component.go @@ -1,8 +1,6 @@ package privacy import ( - "errors" - "fmt" "strings" ) @@ -18,48 +16,10 @@ type Component struct { Name string } -func (c Component) Matches(target Component) bool { - return strings.EqualFold(c.Type, target.Type) && (c.Name == "*" || strings.EqualFold(c.Name, target.Name)) +func (c Component) MatchesName(v string) bool { + return strings.EqualFold(c.Name, v) } -var ErrComponentEmpty = errors.New("unable to parse empty component") - -func ParseComponent(v string) (Component, error) { - if len(v) == 0 { - return Component{}, ErrComponentEmpty - } - - split := strings.Split(v, ".") - - if len(split) == 2 { - if !validComponentType(split[0]) { - return Component{}, fmt.Errorf("unable to parse component (invalid type): %s", v) - } - return Component{ - Type: split[0], - Name: split[1], - }, nil - } - - if len(split) == 1 { - return Component{ - Type: ComponentTypeBidder, - Name: split[0], - }, nil - } - - return Component{}, fmt.Errorf("unable to parse component: %s", v) -} - -func validComponentType(t string) bool { - t = strings.ToLower(t) - - if t == ComponentTypeBidder || - t == ComponentTypeAnalytics || - t == ComponentTypeRealTimeData || - t == ComponentTypeGeneral { - return true - } - - return false +func (c Component) MatchesType(v string) bool { + return strings.EqualFold(c.Type, v) } diff --git a/privacy/component_test.go b/privacy/component_test.go index 38aa105d602..9d9d1644f5d 100644 --- a/privacy/component_test.go +++ b/privacy/component_test.go @@ -1,124 +1,87 @@ package privacy import ( - "errors" "testing" "github.com/stretchr/testify/assert" ) -func TestComponentMatches(t *testing.T) { +func TestComponentMatchesName(t *testing.T) { testCases := []struct { name string given Component - target Component + target string result bool }{ { - name: "full", + name: "match", given: Component{Type: "a", Name: "b"}, - target: Component{Type: "a", Name: "b"}, + target: "b", result: true, }, { - name: "name-wildcard", - given: Component{Type: "a", Name: "*"}, - target: Component{Type: "a", Name: "b"}, - result: true, - }, - { - name: "different", + name: "wrong-field", given: Component{Type: "a", Name: "b"}, - target: Component{Type: "foo", Name: "bar"}, + target: "a", result: false, }, { - name: "different-type", + name: "different-value", given: Component{Type: "a", Name: "b"}, - target: Component{Type: "foo", Name: "b"}, + target: "foo", result: false, }, { - name: "different-name", + name: "different-case", given: Component{Type: "a", Name: "b"}, - target: Component{Type: "a", Name: "foo"}, - result: false, + target: "B", + result: true, }, } for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - assert.Equal(t, test.result, test.given.Matches(test.target)) + assert.Equal(t, test.result, test.given.MatchesName(test.target)) }) } } -func TestParseComponent(t *testing.T) { +func TestComponentMatchesType(t *testing.T) { testCases := []struct { - name string - component string - expected Component - expectedError error + name string + given Component + target string + result bool }{ { - name: "empty", - component: "", - expected: Component{}, - expectedError: errors.New("unable to parse empty component"), - }, - { - name: "too-many-parts", - component: "bidder.bidderA.bidderB", - expected: Component{}, - expectedError: errors.New("unable to parse component: bidder.bidderA.bidderB"), - }, - { - name: "type-bidder", - component: "bidder.bidderA", - expected: Component{Type: "bidder", Name: "bidderA"}, - expectedError: nil, - }, - { - name: "type-analytics", - component: "analytics.bidderA", - expected: Component{Type: "analytics", Name: "bidderA"}, - expectedError: nil, - }, - { - name: "type-default", - component: "bidderA", - expected: Component{Type: "bidder", Name: "bidderA"}, - expectedError: nil, + name: "match", + given: Component{Type: "a", Name: "b"}, + target: "a", + result: true, }, { - name: "type-rtd", - component: "rtd.test", - expected: Component{Type: "rtd", Name: "test"}, - expectedError: nil, + name: "wrong-field", + given: Component{Type: "a", Name: "b"}, + target: "b", + result: false, }, { - name: "type-general", - component: "general.test", - expected: Component{Type: "general", Name: "test"}, - expectedError: nil, + name: "different-value", + given: Component{Type: "a", Name: "b"}, + target: "foo", + result: false, }, { - name: "type-invalid", - component: "invalid.test", - expected: Component{}, - expectedError: errors.New("unable to parse component (invalid type): invalid.test"), + name: "different-case", + given: Component{Type: "a", Name: "b"}, + target: "A", + result: true, }, } for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - actualSN, actualErr := ParseComponent(test.component) - if test.expectedError == nil { - assert.Equal(t, test.expected, actualSN) - assert.NoError(t, actualErr) - } else { - assert.EqualError(t, actualErr, test.expectedError.Error()) - } + assert.Equal(t, test.result, test.given.MatchesType(test.target)) }) } } diff --git a/privacy/rule.go b/privacy/rule.go new file mode 100644 index 00000000000..47d0913cff7 --- /dev/null +++ b/privacy/rule.go @@ -0,0 +1,5 @@ +package privacy + +type Rule interface { + Evaluate(target Component) ActivityResult +} diff --git a/privacy/rules.go b/privacy/rule_condition.go similarity index 64% rename from privacy/rules.go rename to privacy/rule_condition.go index 502e10efbad..705543e5473 100644 --- a/privacy/rules.go +++ b/privacy/rule_condition.go @@ -1,20 +1,12 @@ package privacy -import ( - "strings" -) - -type Rule interface { - Evaluate(target Component) ActivityResult -} - -type ComponentEnforcementRule struct { +type ConditionRule struct { result ActivityResult - componentName []Component + componentName []string componentType []string } -func (r ComponentEnforcementRule) Evaluate(target Component) ActivityResult { +func (r ConditionRule) Evaluate(target Component) ActivityResult { if matched := evaluateComponentName(target, r.componentName); !matched { return ActivityAbstain } @@ -26,7 +18,7 @@ func (r ComponentEnforcementRule) Evaluate(target Component) ActivityResult { return r.result } -func evaluateComponentName(target Component, componentNames []Component) bool { +func evaluateComponentName(target Component, componentNames []string) bool { // no clauses are considered a match if len(componentNames) == 0 { return true @@ -34,7 +26,7 @@ func evaluateComponentName(target Component, componentNames []Component) bool { // if there are clauses, at least one needs to match for _, n := range componentNames { - if n.Matches(target) { + if target.MatchesName(n) { return true } } @@ -49,8 +41,8 @@ func evaluateComponentType(target Component, componentTypes []string) bool { } // if there are clauses, at least one needs to match - for _, s := range componentTypes { - if strings.EqualFold(s, target.Type) { + for _, t := range componentTypes { + if target.MatchesType(t) { return true } } diff --git a/privacy/rules_test.go b/privacy/rule_condition_test.go similarity index 69% rename from privacy/rules_test.go rename to privacy/rule_condition_test.go index 7e80c9cee95..3a09b365f72 100644 --- a/privacy/rules_test.go +++ b/privacy/rule_condition_test.go @@ -9,17 +9,15 @@ import ( func TestComponentEnforcementRuleEvaluate(t *testing.T) { testCases := []struct { name string - componentRule ComponentEnforcementRule + componentRule ConditionRule target Component activityResult ActivityResult }{ { name: "activity_is_allowed", - componentRule: ComponentEnforcementRule{ - result: ActivityAllow, - componentName: []Component{ - {Type: "bidder", Name: "bidderA"}, - }, + componentRule: ConditionRule{ + result: ActivityAllow, + componentName: []string{"bidderA"}, componentType: []string{"bidder"}, }, target: Component{Type: "bidder", Name: "bidderA"}, @@ -27,11 +25,9 @@ func TestComponentEnforcementRuleEvaluate(t *testing.T) { }, { name: "activity_is_not_allowed", - componentRule: ComponentEnforcementRule{ - result: ActivityDeny, - componentName: []Component{ - {Type: "bidder", Name: "bidderA"}, - }, + componentRule: ConditionRule{ + result: ActivityDeny, + componentName: []string{"bidderA"}, componentType: []string{"bidder"}, }, target: Component{Type: "bidder", Name: "bidderA"}, @@ -39,11 +35,9 @@ func TestComponentEnforcementRuleEvaluate(t *testing.T) { }, { name: "abstain_both_clauses_do_not_match", - componentRule: ComponentEnforcementRule{ - result: ActivityAllow, - componentName: []Component{ - {Type: "bidder", Name: "bidderA"}, - }, + componentRule: ConditionRule{ + result: ActivityAllow, + componentName: []string{"bidderA"}, componentType: []string{"bidder"}, }, target: Component{Type: "bidder", Name: "bidderB"}, @@ -51,18 +45,16 @@ func TestComponentEnforcementRuleEvaluate(t *testing.T) { }, { name: "activity_is_not_allowed_componentName_only", - componentRule: ComponentEnforcementRule{ - result: ActivityAllow, - componentName: []Component{ - {Type: "bidder", Name: "bidderA"}, - }, + componentRule: ConditionRule{ + result: ActivityAllow, + componentName: []string{"bidderA"}, }, target: Component{Type: "bidder", Name: "bidderA"}, activityResult: ActivityAllow, }, { name: "activity_is_allowed_componentType_only", - componentRule: ComponentEnforcementRule{ + componentRule: ConditionRule{ result: ActivityAllow, componentType: []string{"bidder"}, }, @@ -71,7 +63,7 @@ func TestComponentEnforcementRuleEvaluate(t *testing.T) { }, { name: "no-conditions-allow", - componentRule: ComponentEnforcementRule{ + componentRule: ConditionRule{ result: ActivityAllow, }, target: Component{Type: "bidder", Name: "bidderA"}, @@ -79,7 +71,7 @@ func TestComponentEnforcementRuleEvaluate(t *testing.T) { }, { name: "no-conditions-deny", - componentRule: ComponentEnforcementRule{ + componentRule: ConditionRule{ result: ActivityDeny, }, target: Component{Type: "bidder", Name: "bidderA"}, From 4ec839e06a11566a37a26e89776c0dbd47a979db Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Tue, 12 Sep 2023 10:00:38 +0400 Subject: [PATCH 114/268] New adapter: GreedyGame (#3083) --- exchange/adapter_builders.go | 1 + openrtb_ext/bidders.go | 2 ++ static/bidder-info/greedygame.yaml | 16 ++++++++++++++++ static/bidder-params/greedygame.json | 23 +++++++++++++++++++++++ 4 files changed, 42 insertions(+) create mode 100644 static/bidder-info/greedygame.yaml create mode 100644 static/bidder-params/greedygame.json diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 484fe59c45d..c5e9dc4947b 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -287,6 +287,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderGamoshi: gamoshi.Builder, openrtb_ext.BidderGlobalsun: globalsun.Builder, openrtb_ext.BidderGothamads: gothamads.Builder, + openrtb_ext.BidderGreedygame: limelightDigital.Builder, openrtb_ext.BidderGrid: grid.Builder, openrtb_ext.BidderGumGum: gumgum.Builder, openrtb_ext.BidderHuaweiAds: huaweiads.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index deeb1c58b6a..11f01988013 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -111,6 +111,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderGamoshi, BidderGlobalsun, BidderGothamads, + BidderGreedygame, BidderGrid, BidderGumGum, BidderHuaweiAds, @@ -403,6 +404,7 @@ const ( BidderGamoshi BidderName = "gamoshi" BidderGlobalsun BidderName = "globalsun" BidderGothamads BidderName = "gothamads" + BidderGreedygame BidderName = "greedygame" BidderGrid BidderName = "grid" BidderGumGum BidderName = "gumgum" BidderHuaweiAds BidderName = "huaweiads" diff --git a/static/bidder-info/greedygame.yaml b/static/bidder-info/greedygame.yaml new file mode 100644 index 00000000000..5e73e1fe950 --- /dev/null +++ b/static/bidder-info/greedygame.yaml @@ -0,0 +1,16 @@ +endpoint: "http://ads-pbs.rtb-greedygame.com/openrtb/{{.PublisherID}}?host={{.Host}}" +maintainer: + email: "engineering@project-limelight.com" +capabilities: + app: + mediaTypes: + - banner + - video + - audio + - native + site: + mediaTypes: + - banner + - video + - audio + - native diff --git a/static/bidder-params/greedygame.json b/static/bidder-params/greedygame.json new file mode 100644 index 00000000000..2057c147d44 --- /dev/null +++ b/static/bidder-params/greedygame.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "GreedyGame Adapter Params", + "description": "A schema which validates params accepted by the GreedyGame adapter", + "type": "object", + + "properties": { + "host": { + "type": "string", + "description": "Ad network's RTB host", + "format": "hostname", + "pattern": "^.+\\..+$" + }, + "publisherId": { + "type": ["integer", "string"], + "description": "Publisher ID", + "minimum": 1, + "pattern": "^[1-9][0-9]*$" + } + }, + + "required": ["host", "publisherId"] +} From 2e056bfbc071292361b6c399ed8176ff369babc3 Mon Sep 17 00:00:00 2001 From: Pubmatic-Dhruv-Sonone <83747371+Pubmatic-Dhruv-Sonone@users.noreply.github.com> Date: Tue, 12 Sep 2023 19:14:15 +0530 Subject: [PATCH 115/268] Adjust imp.BidFloor using BidAdjustment (#3063) * BidAdjustment for imp.BidFloor * Adding function to check if adjustForBidAdjustment is enabled * Adding check for empty bidAdjustmentFactors --- config/account.go | 4 + exchange/exchange.go | 2 +- exchange/utils.go | 29 ++++- exchange/utils_test.go | 263 ++++++++++++++++++++++++++++++++++++++--- 4 files changed, 280 insertions(+), 18 deletions(-) diff --git a/config/account.go b/config/account.go index 038a8daaf9e..e5265072164 100644 --- a/config/account.go +++ b/config/account.go @@ -85,6 +85,10 @@ func (pf *AccountPriceFloors) validate(errs []error) []error { return errs } +func (pf *AccountPriceFloors) IsAdjustForBidAdjustmentEnabled() bool { + return pf.AdjustForBidAdjustment +} + // EnabledForChannelType indicates whether CCPA is turned on at the account level for the specified channel type // by using the channel type setting if defined or the general CCPA setting if defined; otherwise it returns nil func (a *AccountCCPA) EnabledForChannelType(channelType ChannelType) *bool { diff --git a/exchange/exchange.go b/exchange/exchange.go index 70d92c08fba..136f1040740 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -319,7 +319,7 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog Prebid: *requestExtPrebid, SChain: requestExt.GetSChain(), } - bidderRequests, privacyLabels, errs := e.requestSplitter.cleanOpenRTBRequests(ctx, *r, requestExtLegacy, gdprDefaultValue) + bidderRequests, privacyLabels, errs := e.requestSplitter.cleanOpenRTBRequests(ctx, *r, requestExtLegacy, gdprDefaultValue, bidAdjustmentFactors) errs = append(errs, floorErrs...) mergedBidAdj, err := bidadjustment.Merge(r.BidRequestWrapper, r.Account.BidAdjustments) diff --git a/exchange/utils.go b/exchange/utils.go index 267d928ca72..5731c9e4399 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -54,7 +54,7 @@ type requestSplitter struct { func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, auctionReq AuctionRequest, requestExt *openrtb_ext.ExtRequest, - gdprDefaultValue gdpr.Signal, + gdprDefaultValue gdpr.Signal, bidAdjustmentFactors map[string]float64, ) (allowedBidderRequests []BidderRequest, privacyLabels metrics.PrivacyLabels, errs []error) { req := auctionReq.BidRequestWrapper @@ -93,6 +93,11 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, } } + if auctionReq.Account.PriceFloors.IsAdjustForBidAdjustmentEnabled() { + //Apply BidAdjustmentFactor to imp.BidFloor + applyBidAdjustmentToFloor(allBidderRequests, bidAdjustmentFactors) + } + gdprSignal, err := getGDPR(req) if err != nil { errs = append(errs, err) @@ -1071,3 +1076,25 @@ func getPrebidMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { Message: errMsg, } } + +func applyBidAdjustmentToFloor(allBidderRequests []BidderRequest, bidAdjustmentFactors map[string]float64) { + + if len(bidAdjustmentFactors) == 0 { + return + } + + for _, bidderRequest := range allBidderRequests { + bidAdjustment := 1.0 + + if bidAdjustemntValue, ok := bidAdjustmentFactors[string(bidderRequest.BidderName)]; ok { + bidAdjustment = bidAdjustemntValue + } + + if bidAdjustment != 1.0 { + for index, imp := range bidderRequest.BidRequest.Imp { + imp.BidFloor = imp.BidFloor / bidAdjustment + bidderRequest.BidRequest.Imp[index] = imp + } + } + } +} diff --git a/exchange/utils_test.go b/exchange/utils_test.go index a1ca0a607ef..ee6dad1ad96 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -486,7 +486,7 @@ func TestCleanOpenRTBRequests(t *testing.T) { hostSChainNode: nil, bidderInfo: config.BidderInfos{}, } - bidderRequests, _, err := reqSplitter.cleanOpenRTBRequests(context.Background(), test.req, nil, gdpr.SignalNo) + bidderRequests, _, err := reqSplitter.cleanOpenRTBRequests(context.Background(), test.req, nil, gdpr.SignalNo, map[string]float64{}) if test.hasError { assert.NotNil(t, err, "Error shouldn't be nil") } else { @@ -552,7 +552,7 @@ func TestCleanOpenRTBRequestsWithFPD(t *testing.T) { bidderInfo: config.BidderInfos{}, } - bidderRequests, _, err := reqSplitter.cleanOpenRTBRequests(context.Background(), test.req, nil, gdpr.SignalNo) + bidderRequests, _, err := reqSplitter.cleanOpenRTBRequests(context.Background(), test.req, nil, gdpr.SignalNo, map[string]float64{}) assert.Empty(t, err, "No errors should be returned") for _, bidderRequest := range bidderRequests { bidderName := bidderRequest.BidderName @@ -867,7 +867,7 @@ func TestCleanOpenRTBRequestsWithBidResponses(t *testing.T) { bidderInfo: config.BidderInfos{}, } - actualBidderRequests, _, err := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, nil, gdpr.SignalNo) + actualBidderRequests, _, err := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, nil, gdpr.SignalNo, map[string]float64{}) assert.Empty(t, err, "No errors should be returned") assert.Len(t, actualBidderRequests, len(test.expectedBidderRequests), "result len doesn't match for testCase %s", test.description) for _, actualBidderRequest := range actualBidderRequests { @@ -1036,7 +1036,7 @@ func TestCleanOpenRTBRequestsCCPA(t *testing.T) { bidderInfo: config.BidderInfos{}, } - bidderRequests, privacyLabels, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, nil, gdpr.SignalNo) + bidderRequests, privacyLabels, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, nil, gdpr.SignalNo, map[string]float64{}) result := bidderRequests[0] assert.Nil(t, errs) @@ -1113,7 +1113,7 @@ func TestCleanOpenRTBRequestsCCPAErrors(t *testing.T) { bidderInfo: config.BidderInfos{}, } - _, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, &reqExtStruct, gdpr.SignalNo) + _, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, &reqExtStruct, gdpr.SignalNo, map[string]float64{}) assert.ElementsMatch(t, []error{test.expectError}, errs, test.description) } @@ -1172,7 +1172,7 @@ func TestCleanOpenRTBRequestsCOPPA(t *testing.T) { bidderInfo: config.BidderInfos{}, } - bidderRequests, privacyLabels, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, nil, gdpr.SignalNo) + bidderRequests, privacyLabels, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, nil, gdpr.SignalNo, map[string]float64{}) result := bidderRequests[0] assert.Nil(t, errs) @@ -1265,7 +1265,7 @@ func TestCleanOpenRTBRequestsSChain(t *testing.T) { bidderInfo: config.BidderInfos{}, } - bidderRequests, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, extRequest, gdpr.SignalNo) + bidderRequests, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, extRequest, gdpr.SignalNo, map[string]float64{}) if test.hasError == true { assert.NotNil(t, errs) assert.Len(t, bidderRequests, 0) @@ -1336,7 +1336,7 @@ func TestCleanOpenRTBRequestsBidderParams(t *testing.T) { bidderInfo: config.BidderInfos{}, } - bidderRequests, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, extRequest, gdpr.SignalNo) + bidderRequests, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, extRequest, gdpr.SignalNo, map[string]float64{}) if test.hasError == true { assert.NotNil(t, errs) assert.Len(t, bidderRequests, 0) @@ -1923,7 +1923,7 @@ func TestCleanOpenRTBRequestsLMT(t *testing.T) { bidderInfo: config.BidderInfos{}, } - results, privacyLabels, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, nil, gdpr.SignalNo) + results, privacyLabels, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, nil, gdpr.SignalNo, map[string]float64{}) result := results[0] assert.Nil(t, errs) @@ -2156,7 +2156,7 @@ func TestCleanOpenRTBRequestsGDPR(t *testing.T) { bidderInfo: config.BidderInfos{}, } - results, privacyLabels, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, nil, gdprDefaultValue) + results, privacyLabels, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, nil, gdprDefaultValue, map[string]float64{}) result := results[0] if test.expectError { @@ -2257,7 +2257,7 @@ func TestCleanOpenRTBRequestsGDPRBlockBidRequest(t *testing.T) { bidderInfo: config.BidderInfos{}, } - results, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, nil, gdpr.SignalNo) + results, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, nil, gdpr.SignalNo, map[string]float64{}) // extract bidder name from each request in the results bidders := []openrtb_ext.BidderName{} @@ -2344,7 +2344,7 @@ func TestCleanOpenRTBRequestsWithOpenRTBDowngrade(t *testing.T) { hostSChainNode: nil, bidderInfo: test.bidderInfos, } - bidderRequests, _, err := reqSplitter.cleanOpenRTBRequests(context.Background(), test.req, nil, gdpr.SignalNo) + bidderRequests, _, err := reqSplitter.cleanOpenRTBRequests(context.Background(), test.req, nil, gdpr.SignalNo, map[string]float64{}) assert.Nil(t, err, "Err should be nil") bidRequest := bidderRequests[0] assert.Equal(t, test.expectRegs, bidRequest.BidRequest.Regs) @@ -2605,7 +2605,8 @@ func newBidRequest(t *testing.T) *openrtb2.BidRequest { Geo: &openrtb2.Geo{Lat: 123.456}, }, Imp: []openrtb2.Imp{{ - ID: "some-imp-id", + BidFloor: 100, + ID: "some-imp-id", Banner: &openrtb2.Banner{ Format: []openrtb2.Format{{ W: 300, @@ -3100,7 +3101,7 @@ func TestCleanOpenRTBRequestsSChainMultipleBidders(t *testing.T) { hostSChainNode: nil, bidderInfo: config.BidderInfos{}, } - bidderRequests, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, extRequest, gdpr.SignalNo) + bidderRequests, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, extRequest, gdpr.SignalNo, map[string]float64{}) assert.Nil(t, errs) assert.Len(t, bidderRequests, 2, "Bid request count is not 2") @@ -3116,6 +3117,117 @@ func TestCleanOpenRTBRequestsSChainMultipleBidders(t *testing.T) { assert.Equal(t, axonixPrebidSchainsSchain, bidRequestSourceExts["axonix"], "Incorrect axonix bid request schain in source.ext") } +func TestCleanOpenRTBRequestsBidAdjustment(t *testing.T) { + tcf2Consent := "COzTVhaOzTVhaGvAAAENAiCIAP_AAH_AAAAAAEEUACCKAAA" + falseValue := false + testCases := []struct { + description string + gdprAccountEnabled *bool + gdprHostEnabled bool + gdpr string + gdprConsent string + gdprScrub bool + permissionsError error + gdprDefaultValue string + expectPrivacyLabels metrics.PrivacyLabels + expectError bool + bidAdjustmentFactor map[string]float64 + expectedImp []openrtb2.Imp + }{ + { + description: "BidFloor Adjustment Done for Appnexus", + gdprAccountEnabled: &falseValue, + gdprHostEnabled: true, + gdpr: "1", + gdprConsent: tcf2Consent, + gdprScrub: false, + gdprDefaultValue: "1", + expectPrivacyLabels: metrics.PrivacyLabels{ + GDPREnforced: false, + GDPRTCFVersion: "", + }, + bidAdjustmentFactor: map[string]float64{"appnexus": 0.50}, + expectedImp: []openrtb2.Imp{{ + BidFloor: 200, + ID: "some-imp-id", + Banner: &openrtb2.Banner{ + Format: []openrtb2.Format{{ + W: 300, + H: 250, + }, { + W: 300, + H: 600, + }}, + }, + Ext: json.RawMessage(`{"bidder":{"placementId":1}}`), + }}, + }, + { + description: "bidAjustement Not provided", + gdprAccountEnabled: &falseValue, + gdprHostEnabled: true, + gdpr: "1", + gdprConsent: tcf2Consent, + gdprScrub: false, + gdprDefaultValue: "1", + expectPrivacyLabels: metrics.PrivacyLabels{ + GDPREnforced: false, + GDPRTCFVersion: "", + }, + bidAdjustmentFactor: map[string]float64{}, + expectedImp: []openrtb2.Imp{{ + BidFloor: 100, + ID: "some-imp-id", + Banner: &openrtb2.Banner{ + Format: []openrtb2.Format{{ + W: 300, + H: 250, + }, { + W: 300, + H: 600, + }}, + }, + Ext: json.RawMessage(`{"bidder":{"placementId":1}}`), + }}, + }, + } + for _, test := range testCases { + req := newBidRequest(t) + accountConfig := config.Account{ + GDPR: config.AccountGDPR{ + Enabled: &falseValue, + }, + PriceFloors: config.AccountPriceFloors{ + AdjustForBidAdjustment: true, + }, + } + auctionReq := AuctionRequest{ + BidRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: req}, + UserSyncs: &emptyUsersync{}, + Account: accountConfig, + } + gdprPermissionsBuilder := fakePermissionsBuilder{ + permissions: &permissionsMock{ + allowAllBidders: true, + passGeo: !test.gdprScrub, + passID: !test.gdprScrub, + activitiesError: test.permissionsError, + }, + }.Builder + reqSplitter := &requestSplitter{ + bidderToSyncerKey: map[string]string{}, + me: &metrics.MetricsEngineMock{}, + gdprPermsBuilder: gdprPermissionsBuilder, + hostSChainNode: nil, + bidderInfo: config.BidderInfos{}, + } + results, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, nil, gdpr.SignalNo, test.bidAdjustmentFactor) + result := results[0] + assert.Nil(t, errs) + assert.Equal(t, test.expectedImp, result.BidRequest.Imp, test.description) + } +} + func TestApplyFPD(t *testing.T) { testCases := []struct { @@ -3450,7 +3562,7 @@ func TestCleanOpenRTBRequestsFilterBidderRequestExt(t *testing.T) { bidderInfo: config.BidderInfos{}, } - bidderRequests, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, extRequest, gdpr.SignalNo) + bidderRequests, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, extRequest, gdpr.SignalNo, map[string]float64{}) assert.Equal(t, test.wantError, len(errs) != 0, test.desc) sort.Slice(bidderRequests, func(i, j int) bool { return bidderRequests[i].BidderCoreName < bidderRequests[j].BidderCoreName @@ -4380,7 +4492,7 @@ func TestCleanOpenRTBRequestsActivities(t *testing.T) { } t.Run(test.name, func(t *testing.T) { - bidderRequests, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, nil, gdpr.SignalNo) + bidderRequests, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, nil, gdpr.SignalNo, map[string]float64{}) assert.Empty(t, errs) assert.Len(t, bidderRequests, test.expectedReqNumber) @@ -4440,3 +4552,122 @@ func getTransmitTIDActivityConfig(componentName string, allow bool) config.Accou }, } } + +func TestApplyBidAdjustmentToFloor(t *testing.T) { + type args struct { + allBidderRequests []BidderRequest + bidAdjustmentFactors map[string]float64 + } + tests := []struct { + name string + args args + expectedAllBidderRequests []BidderRequest + }{ + { + name: " bidAdjustmentFactor is empty", + args: args{ + allBidderRequests: []BidderRequest{ + { + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, + }, + BidderName: openrtb_ext.BidderName("appnexus"), + }, + }, + bidAdjustmentFactors: map[string]float64{}, + }, + expectedAllBidderRequests: []BidderRequest{ + { + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, + }, + BidderName: openrtb_ext.BidderName("appnexus"), + }, + }, + }, + { + name: "bidAdjustmentFactor not present for request bidder", + args: args{ + allBidderRequests: []BidderRequest{ + { + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, + }, + BidderName: openrtb_ext.BidderName("appnexus"), + }, + }, + bidAdjustmentFactors: map[string]float64{"pubmatic": 1.0}, + }, + expectedAllBidderRequests: []BidderRequest{ + { + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, + }, + BidderName: openrtb_ext.BidderName("appnexus"), + }, + }, + }, + { + name: "bidAdjustmentFactor present for request bidder", + args: args{ + allBidderRequests: []BidderRequest{ + { + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, + }, + BidderName: openrtb_ext.BidderName("appnexus"), + }, + }, + bidAdjustmentFactors: map[string]float64{"pubmatic": 1.0, "appnexus": 0.75}, + }, + expectedAllBidderRequests: []BidderRequest{ + { + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{BidFloor: 133.33333333333334}, {BidFloor: 200}}, + }, + BidderName: openrtb_ext.BidderName("appnexus"), + }, + }, + }, + { + name: "bidAdjustmentFactor present only for appnexus request bidder", + args: args{ + allBidderRequests: []BidderRequest{ + { + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, + }, + BidderName: openrtb_ext.BidderName("appnexus"), + }, + { + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, + }, + BidderName: openrtb_ext.BidderName("pubmatic"), + }, + }, + bidAdjustmentFactors: map[string]float64{"appnexus": 0.75}, + }, + expectedAllBidderRequests: []BidderRequest{ + { + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{BidFloor: 133.33333333333334}, {BidFloor: 200}}, + }, + BidderName: openrtb_ext.BidderName("appnexus"), + }, + { + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, + }, + BidderName: openrtb_ext.BidderName("pubmatic"), + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + applyBidAdjustmentToFloor(tt.args.allBidderRequests, tt.args.bidAdjustmentFactors) + assert.Equal(t, tt.expectedAllBidderRequests, tt.args.allBidderRequests, tt.name) + }) + } +} From 3d4eda522819c1db15bedc51c02acbd66eef6af0 Mon Sep 17 00:00:00 2001 From: guscarreon Date: Tue, 12 Sep 2023 09:44:46 -0400 Subject: [PATCH 116/268] release.yml run build before creating new tag (#3032) * release.yml should run sucessful build before creating new tag * Onkar's review * Don't use make * swaped validate and build commands * Remove unnecessary build command --- .github/workflows/release.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6ea29bd3d61..fd790699a14 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,9 +32,25 @@ jobs: outputs: hasWritePermission: ${{ steps.check.outputs.require-result }} + build-master: + name: Build master + needs: check-permission + if: contains(needs.check-permission.outputs.hasWritePermission, 'true') + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@master + with: + fetch-depth: 0 + repository: ${{ github.repository }} + ref: master + - name: Build and validate + run: | + ./validate.sh + publish-tag: name: Publish tag - needs: check-permission + needs: build-master if: contains(needs.check-permission.outputs.hasWritePermission, 'true') permissions: contents: write From 06a847e5e067c406a68b65404b202ac20fcf3dee Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Wed, 13 Sep 2023 11:34:51 -0400 Subject: [PATCH 117/268] Privacy Activities: Pass Request (#3064) --- endpoints/cookie_sync.go | 86 ++++---- endpoints/cookie_sync_test.go | 152 +++++++------- endpoints/setuid.go | 19 +- endpoints/setuid_test.go | 27 ++- exchange/utils.go | 9 +- macros/macros.go | 10 +- macros/macros_test.go | 2 +- privacy/activity.go | 11 +- privacy/activitycontrol.go | 38 +++- privacy/activitycontrol_test.go | 27 ++- privacy/gdpr/{policy.go => validate.go} | 6 - .../gdpr/{policy_test.go => validate_test.go} | 0 privacy/gpp/{gpp.go => sid.go} | 7 - privacy/gpp/{gpp_test.go => sid_test.go} | 0 privacy/policies.go | 14 +- privacy/rule.go | 2 +- privacy/rule_condition.go | 43 +++- privacy/rule_condition_test.go | 191 +++++++++++++++++- privacy/scrubber.go | 8 +- usersync/chooser_test.go | 9 +- usersync/syncer.go | 26 +-- usersync/syncer_test.go | 63 +++--- usersync/syncersbuilder_test.go | 4 +- 23 files changed, 514 insertions(+), 240 deletions(-) rename privacy/gdpr/{policy.go => validate.go} (68%) rename privacy/gdpr/{policy_test.go => validate_test.go} (100%) rename privacy/gpp/{gpp.go => sid.go} (76%) rename privacy/gpp/{gpp_test.go => sid_test.go} (100%) diff --git a/endpoints/cookie_sync.go b/endpoints/cookie_sync.go index 0321fea3328..0a81c2d5e9c 100644 --- a/endpoints/cookie_sync.go +++ b/endpoints/cookie_sync.go @@ -19,11 +19,11 @@ import ( "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/gdpr" + "github.com/prebid/prebid-server/macros" "github.com/prebid/prebid-server/metrics" "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/privacy" "github.com/prebid/prebid-server/privacy/ccpa" - gdprPrivacy "github.com/prebid/prebid-server/privacy/gdpr" gppPrivacy "github.com/prebid/prebid-server/privacy/gpp" "github.com/prebid/prebid-server/stored_requests" "github.com/prebid/prebid-server/usersync" @@ -84,7 +84,7 @@ type cookieSyncEndpoint struct { } func (c *cookieSyncEndpoint) Handle(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { - request, privacyPolicies, err := c.parseRequest(r) + request, privacyMacros, err := c.parseRequest(r) if err != nil { c.writeParseRequestErrorMetrics(err) c.handleError(w, err, http.StatusBadRequest) @@ -102,24 +102,24 @@ func (c *cookieSyncEndpoint) Handle(w http.ResponseWriter, r *http.Request, _ ht c.handleError(w, errCookieSyncOptOut, http.StatusUnauthorized) case usersync.StatusBlockedByGDPR: c.metrics.RecordCookieSync(metrics.CookieSyncGDPRHostCookieBlocked) - c.handleResponse(w, request.SyncTypeFilter, cookie, privacyPolicies, nil) + c.handleResponse(w, request.SyncTypeFilter, cookie, privacyMacros, nil) case usersync.StatusOK: c.metrics.RecordCookieSync(metrics.CookieSyncOK) c.writeSyncerMetrics(result.BiddersEvaluated) - c.handleResponse(w, request.SyncTypeFilter, cookie, privacyPolicies, result.SyncersChosen) + c.handleResponse(w, request.SyncTypeFilter, cookie, privacyMacros, result.SyncersChosen) } } -func (c *cookieSyncEndpoint) parseRequest(r *http.Request) (usersync.Request, privacy.Policies, error) { +func (c *cookieSyncEndpoint) parseRequest(r *http.Request) (usersync.Request, macros.UserSyncPrivacy, error) { defer r.Body.Close() body, err := io.ReadAll(r.Body) if err != nil { - return usersync.Request{}, privacy.Policies{}, errCookieSyncBody + return usersync.Request{}, macros.UserSyncPrivacy{}, errCookieSyncBody } request := cookieSyncRequest{} if err := json.Unmarshal(body, &request); err != nil { - return usersync.Request{}, privacy.Policies{}, fmt.Errorf("JSON parsing failed: %s", err.Error()) + return usersync.Request{}, macros.UserSyncPrivacy{}, fmt.Errorf("JSON parsing failed: %s", err.Error()) } if request.Account == "" { @@ -127,22 +127,22 @@ func (c *cookieSyncEndpoint) parseRequest(r *http.Request) (usersync.Request, pr } account, fetchErrs := accountService.GetAccount(context.Background(), c.config, c.accountsFetcher, request.Account, c.metrics) if len(fetchErrs) > 0 { - return usersync.Request{}, privacy.Policies{}, combineErrors(fetchErrs) + return usersync.Request{}, macros.UserSyncPrivacy{}, combineErrors(fetchErrs) } request = c.setLimit(request, account.CookieSync) request = c.setCooperativeSync(request, account.CookieSync) - privacyPolicies, gdprSignal, err := extractPrivacyPolicies(request, c.privacyConfig.gdprConfig.DefaultValue) + privacyMacros, gdprSignal, privacyPolicies, err := extractPrivacyPolicies(request, c.privacyConfig.gdprConfig.DefaultValue) if err != nil { - return usersync.Request{}, privacy.Policies{}, err + return usersync.Request{}, macros.UserSyncPrivacy{}, err } ccpaParsedPolicy := ccpa.ParsedPolicy{} if request.USPrivacy != "" { - parsedPolicy, err := privacyPolicies.CCPA.Parse(c.privacyConfig.bidderHashSet) + parsedPolicy, err := ccpa.Policy{Consent: request.USPrivacy}.Parse(c.privacyConfig.bidderHashSet) if err != nil { - privacyPolicies.CCPA.Consent = "" + privacyMacros.USPrivacy = "" } if c.privacyConfig.ccpaEnforce { ccpaParsedPolicy = parsedPolicy @@ -153,11 +153,11 @@ func (c *cookieSyncEndpoint) parseRequest(r *http.Request) (usersync.Request, pr syncTypeFilter, err := parseTypeFilter(request.FilterSettings) if err != nil { - return usersync.Request{}, privacy.Policies{}, err + return usersync.Request{}, macros.UserSyncPrivacy{}, err } gdprRequestInfo := gdpr.RequestInfo{ - Consent: privacyPolicies.GDPR.Consent, + Consent: privacyMacros.GDPRConsent, GDPRSignal: gdprSignal, } @@ -175,22 +175,23 @@ func (c *cookieSyncEndpoint) parseRequest(r *http.Request) (usersync.Request, pr gdprPermissions: gdprPerms, ccpaParsedPolicy: ccpaParsedPolicy, activityControl: activityControl, + activityRequest: privacy.NewRequestFromPolicies(privacyPolicies), }, SyncTypeFilter: syncTypeFilter, } - return rx, privacyPolicies, nil + return rx, privacyMacros, nil } -func extractPrivacyPolicies(request cookieSyncRequest, usersyncDefaultGDPRValue string) (privacy.Policies, gdpr.Signal, error) { +func extractPrivacyPolicies(request cookieSyncRequest, usersyncDefaultGDPRValue string) (macros.UserSyncPrivacy, gdpr.Signal, privacy.Policies, error) { // GDPR - gppSID, err := stringutil.StrToInt8Slice(request.GPPSid) + gppSID, err := stringutil.StrToInt8Slice(request.GPPSID) if err != nil { - return privacy.Policies{}, gdpr.SignalNo, err + return macros.UserSyncPrivacy{}, gdpr.SignalNo, privacy.Policies{}, err } gdprSignal, gdprString, err := extractGDPRSignal(request.GDPR, gppSID) if err != nil { - return privacy.Policies{}, gdpr.SignalNo, err + return macros.UserSyncPrivacy{}, gdpr.SignalNo, privacy.Policies{}, err } var gpp gpplib.GppContainer @@ -198,7 +199,7 @@ func extractPrivacyPolicies(request cookieSyncRequest, usersyncDefaultGDPRValue var err error gpp, err = gpplib.Parse(request.GPP) if err != nil { - return privacy.Policies{}, gdpr.SignalNo, err + return macros.UserSyncPrivacy{}, gdpr.SignalNo, privacy.Policies{}, err } } @@ -209,33 +210,33 @@ func extractPrivacyPolicies(request cookieSyncRequest, usersyncDefaultGDPRValue if gdprConsent == "" { if gdprSignal == gdpr.SignalYes { - return privacy.Policies{}, gdpr.SignalNo, errCookieSyncGDPRConsentMissing + return macros.UserSyncPrivacy{}, gdpr.SignalNo, privacy.Policies{}, errCookieSyncGDPRConsentMissing } if gdprSignal == gdpr.SignalAmbiguous && gdpr.SignalNormalize(gdprSignal, usersyncDefaultGDPRValue) == gdpr.SignalYes { - return privacy.Policies{}, gdpr.SignalNo, errCookieSyncGDPRConsentMissingSignalAmbiguous + return macros.UserSyncPrivacy{}, gdpr.SignalNo, privacy.Policies{}, errCookieSyncGDPRConsentMissingSignalAmbiguous } } // CCPA ccpaString, err := ccpa.SelectCCPAConsent(request.USPrivacy, gpp, gppSID) if err != nil { - return privacy.Policies{}, gdpr.SignalNo, err + return macros.UserSyncPrivacy{}, gdpr.SignalNo, privacy.Policies{}, err } - return privacy.Policies{ - GDPR: gdprPrivacy.Policy{ - Signal: gdprString, - Consent: gdprConsent, - }, - CCPA: ccpa.Policy{ - Consent: ccpaString, - }, - GPP: gppPrivacy.Policy{ - Consent: request.GPP, - RawSID: request.GPPSid, - }, - }, gdprSignal, nil + privacyMacros := macros.UserSyncPrivacy{ + GDPR: gdprString, + GDPRConsent: gdprConsent, + USPrivacy: ccpaString, + GPP: request.GPP, + GPPSID: request.GPPSID, + } + + privacyPolicies := privacy.Policies{ + GPPSID: gppSID, + } + + return privacyMacros, gdprSignal, privacyPolicies, nil } func extractGDPRSignal(requestGDPR *int, gppSID []int8) (gdpr.Signal, string, error) { @@ -396,7 +397,7 @@ func (c *cookieSyncEndpoint) writeSyncerMetrics(biddersEvaluated []usersync.Bidd } } -func (c *cookieSyncEndpoint) handleResponse(w http.ResponseWriter, tf usersync.SyncTypeFilter, co *usersync.Cookie, p privacy.Policies, s []usersync.SyncerChoice) { +func (c *cookieSyncEndpoint) handleResponse(w http.ResponseWriter, tf usersync.SyncTypeFilter, co *usersync.Cookie, m macros.UserSyncPrivacy, s []usersync.SyncerChoice) { status := "no_cookie" if co.HasAnyLiveSyncs() { status = "ok" @@ -409,7 +410,7 @@ func (c *cookieSyncEndpoint) handleResponse(w http.ResponseWriter, tf usersync.S for _, syncerChoice := range s { syncTypes := tf.ForBidder(syncerChoice.Bidder) - sync, err := syncerChoice.Syncer.GetSync(syncTypes, p) + sync, err := syncerChoice.Syncer.GetSync(syncTypes, m) if err != nil { glog.Errorf("Failed to get usersync info for %s: %v", syncerChoice.Bidder, err) continue @@ -460,7 +461,7 @@ type cookieSyncRequest struct { USPrivacy string `json:"us_privacy"` Limit int `json:"limit"` GPP string `json:"gpp"` - GPPSid string `json:"gpp_sid"` + GPPSID string `json:"gpp_sid"` CooperativeSync *bool `json:"coopSync"` FilterSettings *cookieSyncRequestFilterSettings `json:"filterSettings"` Account string `json:"account"` @@ -505,6 +506,7 @@ type usersyncPrivacy struct { gdprPermissions gdpr.Permissions ccpaParsedPolicy ccpa.ParsedPolicy activityControl privacy.ActivityControl + activityRequest privacy.ActivityRequest } func (p usersyncPrivacy) GDPRAllowsHostCookie() bool { @@ -523,6 +525,8 @@ func (p usersyncPrivacy) CCPAAllowsBidderSync(bidder string) bool { } func (p usersyncPrivacy) ActivityAllowsUserSync(bidder string) bool { - return p.activityControl.Allow(privacy.ActivitySyncUser, - privacy.Component{Type: privacy.ComponentTypeBidder, Name: bidder}) + return p.activityControl.Allow( + privacy.ActivitySyncUser, + privacy.Component{Type: privacy.ComponentTypeBidder, Name: bidder}, + p.activityRequest) } diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go index a674e9db537..68ab0ced44e 100644 --- a/endpoints/cookie_sync_test.go +++ b/endpoints/cookie_sync_test.go @@ -16,12 +16,11 @@ import ( "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/gdpr" + "github.com/prebid/prebid-server/macros" "github.com/prebid/prebid-server/metrics" "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/privacy" "github.com/prebid/prebid-server/privacy/ccpa" - gdprPrivacy "github.com/prebid/prebid-server/privacy/gdpr" - gppPrivacy "github.com/prebid/prebid-server/privacy/gpp" "github.com/prebid/prebid-server/usersync" "github.com/prebid/prebid-server/util/ptrutil" @@ -102,7 +101,7 @@ func TestCookieSyncHandle(t *testing.T) { syncTypeExpected := []usersync.SyncType{usersync.SyncTypeIFrame, usersync.SyncTypeRedirect} sync := usersync.Sync{URL: "aURL", Type: usersync.SyncTypeRedirect, SupportCORS: true} syncer := MockSyncer{} - syncer.On("GetSync", syncTypeExpected, privacy.Policies{}).Return(sync, nil).Maybe() + syncer.On("GetSync", syncTypeExpected, macros.UserSyncPrivacy{}).Return(sync, nil).Maybe() cookieWithSyncs := usersync.NewCookie() cookieWithSyncs.Sync("foo", "anyID") @@ -366,7 +365,7 @@ func TestExtractGDPRSignal(t *testing.T) { expected: testOutput{ gdprSignal: gdpr.SignalAmbiguous, gdprString: "2", - err: &errortypes.BadInput{"GDPR signal should be integer 0 or 1"}, + err: &errortypes.BadInput{Message: "GDPR signal should be integer 0 or 1"}, }, }, { @@ -398,8 +397,9 @@ func TestExtractPrivacyPolicies(t *testing.T) { usersyncDefaultGDPRValue string } type testOutput struct { - policies privacy.Policies + macros macros.UserSyncPrivacy gdprSignal gdpr.Signal + policies privacy.Policies err error } testCases := []struct { @@ -413,8 +413,9 @@ func TestExtractPrivacyPolicies(t *testing.T) { request: cookieSyncRequest{GPP: "malformedGPPString"}, }, expected: testOutput{ - policies: privacy.Policies{}, + macros: macros.UserSyncPrivacy{}, gdprSignal: gdpr.SignalNo, + policies: privacy.Policies{}, err: errors.New("error parsing GPP header, header must have type=3"), }, }, @@ -423,14 +424,15 @@ func TestExtractPrivacyPolicies(t *testing.T) { in: testInput{ request: cookieSyncRequest{ GPP: "DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN", - GPPSid: "malformed", + GPPSID: "malformed", USPrivacy: "1YYY", }, }, expected: testOutput{ - policies: privacy.Policies{}, + macros: macros.UserSyncPrivacy{}, gdprSignal: gdpr.SignalNo, - err: &strconv.NumError{"ParseInt", "malformed", strconv.ErrSyntax}, + policies: privacy.Policies{}, + err: &strconv.NumError{Func: "ParseInt", Num: "malformed", Err: strconv.ErrSyntax}, }, }, { @@ -438,13 +440,14 @@ func TestExtractPrivacyPolicies(t *testing.T) { in: testInput{ request: cookieSyncRequest{ GPP: "DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN", - GPPSid: "6", + GPPSID: "6", USPrivacy: "1YYY", }, }, expected: testOutput{ - policies: privacy.Policies{}, + macros: macros.UserSyncPrivacy{}, gdprSignal: gdpr.SignalNo, + policies: privacy.Policies{}, err: errors.New("request.us_privacy consent does not match uspv1"), }, }, @@ -453,40 +456,36 @@ func TestExtractPrivacyPolicies(t *testing.T) { in: testInput{ request: cookieSyncRequest{ GPP: "DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN", - GPPSid: "6", + GPPSID: "6", }, }, expected: testOutput{ - policies: privacy.Policies{ - GDPR: gdprPrivacy.Policy{ - Signal: "0", - Consent: "CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", - }, - CCPA: ccpa.Policy{ - Consent: "1YNN", - }, - GPP: gppPrivacy.Policy{ - Consent: "DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN", - RawSID: "6", - }, + macros: macros.UserSyncPrivacy{ + GDPR: "0", + GDPRConsent: "CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + USPrivacy: "1YNN", + GPP: "DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN", + GPPSID: "6", }, gdprSignal: gdpr.SignalNo, + policies: privacy.Policies{GPPSID: []int8{6}}, err: nil, }, }, } for _, tc := range testCases { - // run - outPolicies, outSignal, outErr := extractPrivacyPolicies(tc.in.request, tc.in.usersyncDefaultGDPRValue) - // assertions - assert.Equal(t, tc.expected.policies, outPolicies, tc.desc) + outMacros, outSignal, outPolicies, outErr := extractPrivacyPolicies(tc.in.request, tc.in.usersyncDefaultGDPRValue) + + assert.Equal(t, tc.expected.macros, outMacros, tc.desc) assert.Equal(t, tc.expected.gdprSignal, outSignal, tc.desc) + assert.Equal(t, tc.expected.policies, outPolicies, tc.desc) assert.Equal(t, tc.expected.err, outErr, tc.desc) } } func TestCookieSyncParseRequest(t *testing.T) { expectedCCPAParsedPolicy, _ := ccpa.Policy{Consent: "1NYN"}.Parse(map[string]struct{}{}) + emptyActivityPoliciesRequest := privacy.NewRequestFromPolicies(privacy.Policies{}) testCases := []struct { description string @@ -496,7 +495,7 @@ func TestCookieSyncParseRequest(t *testing.T) { givenCCPAEnabled bool givenAccountRequired bool expectedError string - expectedPrivacy privacy.Policies + expectedPrivacy macros.UserSyncPrivacy expectedRequest usersync.Request }{ @@ -521,18 +520,12 @@ func TestCookieSyncParseRequest(t *testing.T) { PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, - expectedPrivacy: privacy.Policies{ - GDPR: gdprPrivacy.Policy{ - Signal: "1", - Consent: "CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", - }, - CCPA: ccpa.Policy{ - Consent: "1NYN", - }, - GPP: gppPrivacy.Policy{ - Consent: "DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", - RawSID: "2", - }, + expectedPrivacy: macros.UserSyncPrivacy{ + GDPR: "1", + GDPRConsent: "CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + USPrivacy: "1NYN", + GPP: "DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", + GPPSID: "2", }, expectedRequest: usersync.Request{ Bidders: []string{"a", "b"}, @@ -544,6 +537,7 @@ func TestCookieSyncParseRequest(t *testing.T) { Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, ccpaParsedPolicy: expectedCCPAParsedPolicy, + activityRequest: privacy.NewRequestFromPolicies(privacy.Policies{GPPSID: []int8{2}}), }, SyncTypeFilter: usersync.SyncTypeFilter{ IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), @@ -568,14 +562,10 @@ func TestCookieSyncParseRequest(t *testing.T) { PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, - expectedPrivacy: privacy.Policies{ - GDPR: gdprPrivacy.Policy{ - Signal: "1", - Consent: "anyGDPRConsent", - }, - CCPA: ccpa.Policy{ - Consent: "1NYN", - }, + expectedPrivacy: macros.UserSyncPrivacy{ + GDPR: "1", + GDPRConsent: "anyGDPRConsent", + USPrivacy: "1NYN", }, expectedRequest: usersync.Request{ Bidders: []string{"a", "b"}, @@ -587,6 +577,7 @@ func TestCookieSyncParseRequest(t *testing.T) { Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, ccpaParsedPolicy: expectedCCPAParsedPolicy, + activityRequest: emptyActivityPoliciesRequest, }, SyncTypeFilter: usersync.SyncTypeFilter{ IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), @@ -599,10 +590,11 @@ func TestCookieSyncParseRequest(t *testing.T) { givenBody: strings.NewReader(`{}`), givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, givenCCPAEnabled: true, - expectedPrivacy: privacy.Policies{}, + expectedPrivacy: macros.UserSyncPrivacy{}, expectedRequest: usersync.Request{ Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, + activityRequest: emptyActivityPoliciesRequest, }, SyncTypeFilter: usersync.SyncTypeFilter{ IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), @@ -621,7 +613,7 @@ func TestCookieSyncParseRequest(t *testing.T) { PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, - expectedPrivacy: privacy.Policies{}, + expectedPrivacy: macros.UserSyncPrivacy{}, expectedRequest: usersync.Request{ Cooperative: usersync.Cooperative{ Enabled: true, @@ -629,6 +621,7 @@ func TestCookieSyncParseRequest(t *testing.T) { }, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, + activityRequest: emptyActivityPoliciesRequest, }, SyncTypeFilter: usersync.SyncTypeFilter{ IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), @@ -647,7 +640,7 @@ func TestCookieSyncParseRequest(t *testing.T) { PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, - expectedPrivacy: privacy.Policies{}, + expectedPrivacy: macros.UserSyncPrivacy{}, expectedRequest: usersync.Request{ Cooperative: usersync.Cooperative{ Enabled: false, @@ -655,6 +648,7 @@ func TestCookieSyncParseRequest(t *testing.T) { }, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, + activityRequest: emptyActivityPoliciesRequest, }, SyncTypeFilter: usersync.SyncTypeFilter{ IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), @@ -673,7 +667,7 @@ func TestCookieSyncParseRequest(t *testing.T) { PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, - expectedPrivacy: privacy.Policies{}, + expectedPrivacy: macros.UserSyncPrivacy{}, expectedRequest: usersync.Request{ Cooperative: usersync.Cooperative{ Enabled: false, @@ -681,6 +675,7 @@ func TestCookieSyncParseRequest(t *testing.T) { }, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, + activityRequest: emptyActivityPoliciesRequest, }, SyncTypeFilter: usersync.SyncTypeFilter{ IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), @@ -699,7 +694,7 @@ func TestCookieSyncParseRequest(t *testing.T) { PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, - expectedPrivacy: privacy.Policies{}, + expectedPrivacy: macros.UserSyncPrivacy{}, expectedRequest: usersync.Request{ Cooperative: usersync.Cooperative{ Enabled: false, @@ -707,6 +702,7 @@ func TestCookieSyncParseRequest(t *testing.T) { }, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, + activityRequest: emptyActivityPoliciesRequest, }, SyncTypeFilter: usersync.SyncTypeFilter{ IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), @@ -725,7 +721,7 @@ func TestCookieSyncParseRequest(t *testing.T) { PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, - expectedPrivacy: privacy.Policies{}, + expectedPrivacy: macros.UserSyncPrivacy{}, expectedRequest: usersync.Request{ Cooperative: usersync.Cooperative{ Enabled: true, @@ -733,6 +729,7 @@ func TestCookieSyncParseRequest(t *testing.T) { }, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, + activityRequest: emptyActivityPoliciesRequest, }, SyncTypeFilter: usersync.SyncTypeFilter{ IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), @@ -751,7 +748,7 @@ func TestCookieSyncParseRequest(t *testing.T) { PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, - expectedPrivacy: privacy.Policies{}, + expectedPrivacy: macros.UserSyncPrivacy{}, expectedRequest: usersync.Request{ Cooperative: usersync.Cooperative{ Enabled: true, @@ -759,6 +756,7 @@ func TestCookieSyncParseRequest(t *testing.T) { }, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, + activityRequest: emptyActivityPoliciesRequest, }, SyncTypeFilter: usersync.SyncTypeFilter{ IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), @@ -771,10 +769,11 @@ func TestCookieSyncParseRequest(t *testing.T) { givenBody: strings.NewReader(`{"us_privacy":"invalid"}`), givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, givenCCPAEnabled: true, - expectedPrivacy: privacy.Policies{}, + expectedPrivacy: macros.UserSyncPrivacy{}, expectedRequest: usersync.Request{ Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, + activityRequest: emptyActivityPoliciesRequest, }, SyncTypeFilter: usersync.SyncTypeFilter{ IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), @@ -787,13 +786,13 @@ func TestCookieSyncParseRequest(t *testing.T) { givenBody: strings.NewReader(`{"us_privacy":"1NYN"}`), givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, givenCCPAEnabled: false, - expectedPrivacy: privacy.Policies{ - CCPA: ccpa.Policy{ - Consent: "1NYN"}, + expectedPrivacy: macros.UserSyncPrivacy{ + USPrivacy: "1NYN", }, expectedRequest: usersync.Request{ Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, + activityRequest: emptyActivityPoliciesRequest, }, SyncTypeFilter: usersync.SyncTypeFilter{ IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), @@ -827,12 +826,13 @@ func TestCookieSyncParseRequest(t *testing.T) { givenBody: strings.NewReader(`{"gdpr":0}`), givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, givenCCPAEnabled: true, - expectedPrivacy: privacy.Policies{ - GDPR: gdprPrivacy.Policy{Signal: "0"}, + expectedPrivacy: macros.UserSyncPrivacy{ + GDPR: "0", }, expectedRequest: usersync.Request{ Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, + activityRequest: emptyActivityPoliciesRequest, }, SyncTypeFilter: usersync.SyncTypeFilter{ IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), @@ -852,12 +852,13 @@ func TestCookieSyncParseRequest(t *testing.T) { givenBody: strings.NewReader(`{}`), givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, givenCCPAEnabled: true, - expectedPrivacy: privacy.Policies{ - GDPR: gdprPrivacy.Policy{Signal: ""}, + expectedPrivacy: macros.UserSyncPrivacy{ + GDPR: "", }, expectedRequest: usersync.Request{ Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, + activityRequest: emptyActivityPoliciesRequest, }, SyncTypeFilter: usersync.SyncTypeFilter{ IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), @@ -893,7 +894,7 @@ func TestCookieSyncParseRequest(t *testing.T) { PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, - expectedPrivacy: privacy.Policies{}, + expectedPrivacy: macros.UserSyncPrivacy{}, expectedRequest: usersync.Request{ Bidders: []string{"a", "b"}, Cooperative: usersync.Cooperative{ @@ -903,6 +904,7 @@ func TestCookieSyncParseRequest(t *testing.T) { Limit: 30, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, + activityRequest: emptyActivityPoliciesRequest, }, SyncTypeFilter: usersync.SyncTypeFilter{ IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), @@ -924,7 +926,7 @@ func TestCookieSyncParseRequest(t *testing.T) { PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, - expectedPrivacy: privacy.Policies{}, + expectedPrivacy: macros.UserSyncPrivacy{}, expectedRequest: usersync.Request{ Bidders: []string{"a", "b"}, Cooperative: usersync.Cooperative{ @@ -934,6 +936,7 @@ func TestCookieSyncParseRequest(t *testing.T) { Limit: 20, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, + activityRequest: emptyActivityPoliciesRequest, }, SyncTypeFilter: usersync.SyncTypeFilter{ IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), @@ -955,7 +958,7 @@ func TestCookieSyncParseRequest(t *testing.T) { PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, - expectedPrivacy: privacy.Policies{}, + expectedPrivacy: macros.UserSyncPrivacy{}, expectedRequest: usersync.Request{ Bidders: []string{"a", "b"}, Cooperative: usersync.Cooperative{ @@ -965,6 +968,7 @@ func TestCookieSyncParseRequest(t *testing.T) { Limit: 20, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, + activityRequest: emptyActivityPoliciesRequest, }, SyncTypeFilter: usersync.SyncTypeFilter{ IFrame: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), @@ -1561,21 +1565,21 @@ func TestCookieSyncHandleResponse(t *testing.T) { Redirect: usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude), } syncTypeExpected := []usersync.SyncType{usersync.SyncTypeRedirect} - privacyPolicies := privacy.Policies{CCPA: ccpa.Policy{Consent: "anyConsent"}} + privacyMacros := macros.UserSyncPrivacy{USPrivacy: "anyConsent"} // The & in the URL is necessary to test proper JSON encoding. syncA := usersync.Sync{URL: "https://syncA.com/sync?a=1&b=2", Type: usersync.SyncTypeRedirect, SupportCORS: true} syncerA := MockSyncer{} - syncerA.On("GetSync", syncTypeExpected, privacyPolicies).Return(syncA, nil).Maybe() + syncerA.On("GetSync", syncTypeExpected, privacyMacros).Return(syncA, nil).Maybe() // The & in the URL is necessary to test proper JSON encoding. syncB := usersync.Sync{URL: "https://syncB.com/sync?a=1&b=2", Type: usersync.SyncTypeRedirect, SupportCORS: false} syncerB := MockSyncer{} - syncerB.On("GetSync", syncTypeExpected, privacyPolicies).Return(syncB, nil).Maybe() + syncerB.On("GetSync", syncTypeExpected, privacyMacros).Return(syncB, nil).Maybe() syncWithError := usersync.Sync{} syncerWithError := MockSyncer{} - syncerWithError.On("GetSync", syncTypeExpected, privacyPolicies).Return(syncWithError, errors.New("anyError")).Maybe() + syncerWithError.On("GetSync", syncTypeExpected, privacyMacros).Return(syncWithError, errors.New("anyError")).Maybe() testCases := []struct { description string @@ -1673,7 +1677,7 @@ func TestCookieSyncHandleResponse(t *testing.T) { writer := httptest.NewRecorder() endpoint := cookieSyncEndpoint{pbsAnalytics: &mockAnalytics} - endpoint.handleResponse(writer, syncTypeFilter, cookie, privacyPolicies, test.givenSyncersChosen) + endpoint.handleResponse(writer, syncTypeFilter, cookie, privacyMacros, test.givenSyncersChosen) if assert.Equal(t, writer.Code, http.StatusOK, test.description+":http_status") { assert.Equal(t, writer.Header().Get("Content-Type"), "application/json; charset=utf-8", test.description+":http_header") @@ -1988,8 +1992,8 @@ func (m *MockSyncer) SupportsType(syncTypes []usersync.SyncType) bool { return args.Bool(0) } -func (m *MockSyncer) GetSync(syncTypes []usersync.SyncType, privacyPolicies privacy.Policies) (usersync.Sync, error) { - args := m.Called(syncTypes, privacyPolicies) +func (m *MockSyncer) GetSync(syncTypes []usersync.SyncType, privacyMacros macros.UserSyncPrivacy) (usersync.Sync, error) { + args := m.Called(syncTypes, privacyMacros) return args.Get(0).(usersync.Sync), args.Error(1) } diff --git a/endpoints/setuid.go b/endpoints/setuid.go index b9023cfca9b..64178444e0d 100644 --- a/endpoints/setuid.go +++ b/endpoints/setuid.go @@ -106,8 +106,25 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use activityControl := privacy.NewActivityControl(&account.Privacy) + gppSID, err := stringutil.StrToInt8Slice(query.Get("gpp_sid")) + if err != nil { + err := fmt.Errorf("invalid gpp_sid encoding, must be a csv list of integers") + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) + metricsEngine.RecordSetUid(metrics.SetUidBadRequest) + so.Errors = []error{err} + so.Status = http.StatusBadRequest + return + } + + policies := privacy.Policies{ + GPPSID: gppSID, + } + userSyncActivityAllowed := activityControl.Allow(privacy.ActivitySyncUser, - privacy.Component{Type: privacy.ComponentTypeBidder, Name: bidderName}) + privacy.Component{Type: privacy.ComponentTypeBidder, Name: bidderName}, + privacy.NewRequestFromPolicies(policies)) + if !userSyncActivityAllowed { w.WriteHeader(http.StatusUnavailableForLegalReasons) return diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go index 05030cc7cf7..4f37eb77f8f 100644 --- a/endpoints/setuid_test.go +++ b/endpoints/setuid_test.go @@ -15,9 +15,9 @@ import ( "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/gdpr" + "github.com/prebid/prebid-server/macros" "github.com/prebid/prebid-server/metrics" "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/privacy" "github.com/prebid/prebid-server/usersync" "github.com/stretchr/testify/assert" @@ -217,8 +217,7 @@ func TestSetUIDEndpoint(t *testing.T) { description: "Sets uid for a bidder allowed by GDPR in GPP, throws warning because GDPR legacy values weren't used", }, { - uri: "/setuid?bidder=pubmatic&uid=123&gdpr=1&gdpr_consent=" + - "malformed", + uri: "/setuid?bidder=pubmatic&uid=123&gdpr=1&gdpr_consent=malformed", syncersBidderNameToKey: map[string]string{"pubmatic": "pubmatic"}, gdprAllowsHostCookies: true, gdprMalformed: true, @@ -306,6 +305,26 @@ func TestSetUIDEndpoint(t *testing.T) { expectedHeaders: map[string]string{"Content-Type": "text/html", "Content-Length": "0"}, description: "Set uid for valid bidder with valid account provided with invalid user sync activity", }, + { + description: "gppsid-valid", + uri: "/setuid?bidder=appnexus&uid=123&gpp_sid=100,101", // fake sids to avoid GDPR logic in this test + syncersBidderNameToKey: map[string]string{"appnexus": "appnexus"}, + existingSyncs: nil, + gdprAllowsHostCookies: true, + expectedSyncs: map[string]string{"appnexus": "123"}, + expectedStatusCode: http.StatusOK, + expectedHeaders: map[string]string{"Content-Type": "text/html", "Content-Length": "0"}, + }, + { + description: "gppsid-malformed", + uri: "/setuid?bidder=appnexus&uid=123&gpp_sid=malformed", + syncersBidderNameToKey: map[string]string{"appnexus": "appnexus"}, + existingSyncs: nil, + gdprAllowsHostCookies: true, + expectedSyncs: nil, + expectedStatusCode: http.StatusBadRequest, + expectedBody: "invalid gpp_sid encoding, must be a csv list of integers", + }, } analytics := analyticsConf.NewPBSAnalytics(&config.Analytics{}) @@ -1476,7 +1495,7 @@ func (s fakeSyncer) SupportsType(syncTypes []usersync.SyncType) bool { return true } -func (s fakeSyncer) GetSync(syncTypes []usersync.SyncType, privacyPolicies privacy.Policies) (usersync.Sync, error) { +func (s fakeSyncer) GetSync(syncTypes []usersync.SyncType, privacyMacros macros.UserSyncPrivacy) (usersync.Sync, error) { return usersync.Sync{}, nil } diff --git a/exchange/utils.go b/exchange/utils.go index 5731c9e4399..0becca21f6c 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -56,7 +56,6 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, requestExt *openrtb_ext.ExtRequest, gdprDefaultValue gdpr.Signal, bidAdjustmentFactors map[string]float64, ) (allowedBidderRequests []BidderRequest, privacyLabels metrics.PrivacyLabels, errs []error) { - req := auctionReq.BidRequestWrapper aliases, errs := parseAliases(req.BidRequest) if len(errs) > 0 { @@ -158,7 +157,7 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, // fetchBids activity scopedName := privacy.Component{Type: privacy.ComponentTypeBidder, Name: bidderRequest.BidderName.String()} - fetchBidsActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityFetchBids, scopedName) + fetchBidsActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityFetchBids, scopedName, privacy.NewRequestFromBidRequest(*req)) if !fetchBidsActivityAllowed { // skip the call to a bidder if fetchBids activity is not allowed // do not add this bidder to allowedBidderRequests @@ -178,7 +177,7 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, } } - passIDActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitUserFPD, scopedName) + passIDActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitUserFPD, scopedName, privacy.NewRequestFromBidRequest(*req)) if !passIDActivityAllowed { privacyEnforcement.UFPD = true } else { @@ -195,7 +194,7 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, privacyEnforcement.CCPA = ccpaEnforcer.ShouldEnforce(bidderRequest.BidderName.String()) } - passGeoActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitPreciseGeo, scopedName) + passGeoActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitPreciseGeo, scopedName, privacy.NewRequestFromBidRequest(*req)) if !passGeoActivityAllowed { privacyEnforcement.PreciseGeo = true } else { @@ -217,7 +216,7 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, applyFPD(auctionReq.FirstPartyData[bidderRequest.BidderName], bidderRequest.BidRequest) } - privacyEnforcement.TID = !auctionReq.Activities.Allow(privacy.ActivityTransmitTids, scopedName) + privacyEnforcement.TID = !auctionReq.Activities.Allow(privacy.ActivityTransmitTIDs, scopedName, privacy.NewRequestFromBidRequest(*req)) privacyEnforcement.Apply(bidderRequest.BidRequest, auctionReq.Account.Privacy) allowedBidderRequests = append(allowedBidderRequests, bidderRequest) diff --git a/macros/macros.go b/macros/macros.go index 7292e0c8bbc..609e72cdec7 100644 --- a/macros/macros.go +++ b/macros/macros.go @@ -5,7 +5,7 @@ import ( "text/template" ) -// EndpointTemplateParams specifies params for an endpoint template +// EndpointTemplateParams specifies macros for bidder endpoints. type EndpointTemplateParams struct { Host string PublisherID string @@ -17,8 +17,8 @@ type EndpointTemplateParams struct { GvlID string } -// UserSyncTemplateParams specifies params for an user sync URL template -type UserSyncTemplateParams struct { +// UserSyncPrivacy specifies privacy policy macros, represented as strings, for user sync urls. +type UserSyncPrivacy struct { GDPR string GDPRConsent string USPrivacy string @@ -30,10 +30,10 @@ type UserSyncTemplateParams struct { func ResolveMacros(aTemplate *template.Template, params interface{}) (string, error) { strBuf := bytes.Buffer{} - err := aTemplate.Execute(&strBuf, params) - if err != nil { + if err := aTemplate.Execute(&strBuf, params); err != nil { return "", err } + res := strBuf.String() return res, nil } diff --git a/macros/macros_test.go b/macros/macros_test.go index 055624b611f..db1b8be9a97 100644 --- a/macros/macros_test.go +++ b/macros/macros_test.go @@ -26,7 +26,7 @@ func TestResolveMacros(t *testing.T) { }, { givenTemplate: endpointTemplate, - givenParams: UserSyncTemplateParams{GDPR: "SomeGDPR", GDPRConsent: "SomeGDPRConsent"}, + givenParams: UserSyncPrivacy{GDPR: "SomeGDPR", GDPRConsent: "SomeGDPRConsent"}, expectedResult: "", expectedError: true, }, diff --git a/privacy/activity.go b/privacy/activity.go index 6ca48ae0b93..2309d0204a6 100644 --- a/privacy/activity.go +++ b/privacy/activity.go @@ -1,6 +1,7 @@ package privacy -// Activity defines privileges which can be controlled directly by the publisher or via privacy policies. +// Activity defines Prebid Server actions which can be controlled directly +// by the publisher or via privacy policies. type Activity int const ( @@ -10,8 +11,8 @@ const ( ActivityReportAnalytics ActivityTransmitUserFPD ActivityTransmitPreciseGeo - ActivityTransmitUniqueRequestIds - ActivityTransmitTids + ActivityTransmitUniqueRequestIDs + ActivityTransmitTIDs ) func (a Activity) String() string { @@ -28,9 +29,9 @@ func (a Activity) String() string { return "transmitUfpd" case ActivityTransmitPreciseGeo: return "transmitPreciseGeo" - case ActivityTransmitUniqueRequestIds: + case ActivityTransmitUniqueRequestIDs: return "transmitUniqueRequestIds" - case ActivityTransmitTids: + case ActivityTransmitTIDs: return "transmitTid" } diff --git a/privacy/activitycontrol.go b/privacy/activitycontrol.go index 33c138f7ab3..9d6668b3e44 100644 --- a/privacy/activitycontrol.go +++ b/privacy/activitycontrol.go @@ -2,6 +2,7 @@ package privacy import ( "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" ) type ActivityResult int @@ -14,6 +15,27 @@ const ( const defaultActivityResult = true +func NewRequestFromPolicies(p Policies) ActivityRequest { + return ActivityRequest{policies: &p} +} + +func NewRequestFromBidRequest(r openrtb_ext.RequestWrapper) ActivityRequest { + return ActivityRequest{bidRequest: &r} +} + +type ActivityRequest struct { + policies *Policies + bidRequest *openrtb_ext.RequestWrapper +} + +func (r ActivityRequest) IsPolicies() bool { + return r.policies != nil +} + +func (r ActivityRequest) IsBidRequest() bool { + return r.bidRequest != nil +} + type ActivityControl struct { plans map[Activity]ActivityPlan } @@ -32,8 +54,8 @@ func NewActivityControl(cfg *config.AccountPrivacy) ActivityControl { plans[ActivityReportAnalytics] = buildPlan(cfg.AllowActivities.ReportAnalytics) plans[ActivityTransmitUserFPD] = buildPlan(cfg.AllowActivities.TransmitUserFPD) plans[ActivityTransmitPreciseGeo] = buildPlan(cfg.AllowActivities.TransmitPreciseGeo) - plans[ActivityTransmitUniqueRequestIds] = buildPlan(cfg.AllowActivities.TransmitUniqueRequestIds) - plans[ActivityTransmitTids] = buildPlan(cfg.AllowActivities.TransmitTids) + plans[ActivityTransmitUniqueRequestIDs] = buildPlan(cfg.AllowActivities.TransmitUniqueRequestIds) + plans[ActivityTransmitTIDs] = buildPlan(cfg.AllowActivities.TransmitTids) ac.plans = plans return ac @@ -50,11 +72,9 @@ func cfgToRules(rules []config.ActivityRule) []Rule { var enfRules []Rule for _, r := range rules { - var result ActivityResult + result := ActivityDeny if r.Allow { result = ActivityAllow - } else { - result = ActivityDeny } er := ConditionRule{ @@ -74,14 +94,14 @@ func cfgToDefaultResult(activityDefault *bool) bool { return *activityDefault } -func (e ActivityControl) Allow(activity Activity, target Component) bool { +func (e ActivityControl) Allow(activity Activity, target Component, request ActivityRequest) bool { plan, planDefined := e.plans[activity] if !planDefined { return defaultActivityResult } - return plan.Evaluate(target) + return plan.Evaluate(target, request) } type ActivityPlan struct { @@ -89,9 +109,9 @@ type ActivityPlan struct { rules []Rule } -func (p ActivityPlan) Evaluate(target Component) bool { +func (p ActivityPlan) Evaluate(target Component, request ActivityRequest) bool { for _, rule := range p.rules { - result := rule.Evaluate(target) + result := rule.Evaluate(target, request) if result == ActivityDeny || result == ActivityAllow { return result == ActivityAllow } diff --git a/privacy/activitycontrol_test.go b/privacy/activitycontrol_test.go index 11a9bdc7c2d..743888df029 100644 --- a/privacy/activitycontrol_test.go +++ b/privacy/activitycontrol_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/util/ptrutil" "github.com/stretchr/testify/assert" ) @@ -40,8 +41,8 @@ func TestNewActivityControl(t *testing.T) { ActivityReportAnalytics: getTestActivityPlan(ActivityAllow), ActivityTransmitUserFPD: getTestActivityPlan(ActivityAllow), ActivityTransmitPreciseGeo: getTestActivityPlan(ActivityDeny), - ActivityTransmitUniqueRequestIds: getTestActivityPlan(ActivityAllow), - ActivityTransmitTids: getTestActivityPlan(ActivityAllow), + ActivityTransmitUniqueRequestIDs: getTestActivityPlan(ActivityAllow), + ActivityTransmitTIDs: getTestActivityPlan(ActivityAllow), }}, }, } @@ -128,13 +129,33 @@ func TestActivityControlAllow(t *testing.T) { for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - actualResult := test.activityControl.Allow(test.activity, test.target) + actualResult := test.activityControl.Allow(test.activity, test.target, ActivityRequest{}) assert.Equal(t, test.activityResult, actualResult) }) } } +func TestActivityRequest(t *testing.T) { + t.Run("empty", func(t *testing.T) { + r := ActivityRequest{} + assert.False(t, r.IsPolicies()) + assert.False(t, r.IsBidRequest()) + }) + + t.Run("policies", func(t *testing.T) { + r := NewRequestFromPolicies(Policies{}) + assert.True(t, r.IsPolicies()) + assert.False(t, r.IsBidRequest()) + }) + + t.Run("request", func(t *testing.T) { + r := NewRequestFromBidRequest(openrtb_ext.RequestWrapper{}) + assert.False(t, r.IsPolicies()) + assert.True(t, r.IsBidRequest()) + }) +} + func getTestActivityConfig(allow bool) config.Activity { return config.Activity{ Default: ptrutil.ToPtr(true), diff --git a/privacy/gdpr/policy.go b/privacy/gdpr/validate.go similarity index 68% rename from privacy/gdpr/policy.go rename to privacy/gdpr/validate.go index 0464a9ff979..662ad85286e 100644 --- a/privacy/gdpr/policy.go +++ b/privacy/gdpr/validate.go @@ -4,12 +4,6 @@ import ( "github.com/prebid/go-gdpr/vendorconsent" ) -// Policy represents the GDPR regulation for an OpenRTB bid request. -type Policy struct { - Signal string - Consent string -} - // ValidateConsent returns true if the consent string is empty or valid per the IAB TCF spec. func ValidateConsent(consent string) bool { _, err := vendorconsent.ParseString(consent) diff --git a/privacy/gdpr/policy_test.go b/privacy/gdpr/validate_test.go similarity index 100% rename from privacy/gdpr/policy_test.go rename to privacy/gdpr/validate_test.go diff --git a/privacy/gpp/gpp.go b/privacy/gpp/sid.go similarity index 76% rename from privacy/gpp/gpp.go rename to privacy/gpp/sid.go index 350004062e8..6e10eac94db 100644 --- a/privacy/gpp/gpp.go +++ b/privacy/gpp/sid.go @@ -5,13 +5,6 @@ import ( gppConstants "github.com/prebid/go-gpp/constants" ) -// Policy represents the GPP privacy string container. -// Currently just a placeholder until more expansive support is made. -type Policy struct { - Consent string - RawSID string // This is the CSV format ("2,6") that the IAB recommends for passing the SID(s) on a query string. -} - // IsSIDInList returns true if the 'sid' value is found in the gppSIDs array. Its logic is used in more than // one place in our codebase, therefore it was decided to make it its own function. func IsSIDInList(gppSIDs []int8, sid gppConstants.SectionID) bool { diff --git a/privacy/gpp/gpp_test.go b/privacy/gpp/sid_test.go similarity index 100% rename from privacy/gpp/gpp_test.go rename to privacy/gpp/sid_test.go diff --git a/privacy/policies.go b/privacy/policies.go index 214696e1d63..16fee92ccce 100644 --- a/privacy/policies.go +++ b/privacy/policies.go @@ -1,16 +1,6 @@ package privacy -import ( - "github.com/prebid/prebid-server/privacy/ccpa" - "github.com/prebid/prebid-server/privacy/gdpr" - "github.com/prebid/prebid-server/privacy/gpp" - "github.com/prebid/prebid-server/privacy/lmt" -) - -// Policies represents the privacy regulations for an OpenRTB bid request. +// Policies contains privacy signals and consent for non-OpenRTB activities. type Policies struct { - CCPA ccpa.Policy - GDPR gdpr.Policy - LMT lmt.Policy - GPP gpp.Policy + GPPSID []int8 } diff --git a/privacy/rule.go b/privacy/rule.go index 47d0913cff7..ef370f090ca 100644 --- a/privacy/rule.go +++ b/privacy/rule.go @@ -1,5 +1,5 @@ package privacy type Rule interface { - Evaluate(target Component) ActivityResult + Evaluate(target Component, request ActivityRequest) ActivityResult } diff --git a/privacy/rule_condition.go b/privacy/rule_condition.go index 705543e5473..2fc3450653d 100644 --- a/privacy/rule_condition.go +++ b/privacy/rule_condition.go @@ -1,12 +1,16 @@ package privacy +// noClausesDefinedResult represents the default return when there is no matching criteria specified. +const noClausesDefinedResult = true + type ConditionRule struct { result ActivityResult componentName []string componentType []string + gppSID []int8 } -func (r ConditionRule) Evaluate(target Component) ActivityResult { +func (r ConditionRule) Evaluate(target Component, request ActivityRequest) ActivityResult { if matched := evaluateComponentName(target, r.componentName); !matched { return ActivityAbstain } @@ -15,16 +19,19 @@ func (r ConditionRule) Evaluate(target Component) ActivityResult { return ActivityAbstain } + if matched := evaluateGPPSID(r.gppSID, request); !matched { + return ActivityAbstain + } + return r.result } func evaluateComponentName(target Component, componentNames []string) bool { // no clauses are considered a match if len(componentNames) == 0 { - return true + return noClausesDefinedResult } - // if there are clauses, at least one needs to match for _, n := range componentNames { if target.MatchesName(n) { return true @@ -35,9 +42,8 @@ func evaluateComponentName(target Component, componentNames []string) bool { } func evaluateComponentType(target Component, componentTypes []string) bool { - // no clauses are considered a match if len(componentTypes) == 0 { - return true + return noClausesDefinedResult } // if there are clauses, at least one needs to match @@ -49,3 +55,30 @@ func evaluateComponentType(target Component, componentTypes []string) bool { return false } + +func evaluateGPPSID(sid []int8, request ActivityRequest) bool { + if len(sid) == 0 { + return noClausesDefinedResult + } + + for _, x := range getGPPSID(request) { + for _, y := range sid { + if x == y { + return true + } + } + } + return false +} + +func getGPPSID(request ActivityRequest) []int8 { + if request.IsPolicies() { + return request.policies.GPPSID + } + + if request.IsBidRequest() && request.bidRequest.Regs != nil { + return request.bidRequest.Regs.GPPSID + } + + return nil +} diff --git a/privacy/rule_condition_test.go b/privacy/rule_condition_test.go index 3a09b365f72..bb1d81c00d2 100644 --- a/privacy/rule_condition_test.go +++ b/privacy/rule_condition_test.go @@ -3,6 +3,8 @@ package privacy import ( "testing" + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/openrtb_ext" "github.com/stretchr/testify/assert" ) @@ -43,6 +45,15 @@ func TestComponentEnforcementRuleEvaluate(t *testing.T) { target: Component{Type: "bidder", Name: "bidderB"}, activityResult: ActivityAbstain, }, + { + name: "abstain_gppsid", + componentRule: ConditionRule{ + result: ActivityAllow, + gppSID: []int8{1}, + }, + target: Component{Type: "bidder", Name: "bidderB"}, + activityResult: ActivityAbstain, + }, { name: "activity_is_not_allowed_componentName_only", componentRule: ConditionRule{ @@ -81,9 +92,187 @@ func TestComponentEnforcementRuleEvaluate(t *testing.T) { for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - actualResult := test.componentRule.Evaluate(test.target) + actualResult := test.componentRule.Evaluate(test.target, ActivityRequest{}) assert.Equal(t, test.activityResult, actualResult) + }) + } +} + +func TestEvaluateGPPSID(t *testing.T) { + testCases := []struct { + name string + sidCondition []int8 + sidRequest []int8 + expected bool + }{ + { + name: "condition-nil-request-nil", + sidCondition: nil, + sidRequest: nil, + expected: true, + }, + { + name: "condition-empty-request-nil", + sidCondition: []int8{}, + sidRequest: nil, + expected: true, + }, + { + name: "condition-nil-request-empty", + sidCondition: nil, + sidRequest: []int8{}, + expected: true, + }, + { + name: "condition-empty-request-empty", + sidCondition: []int8{}, + sidRequest: []int8{}, + expected: true, + }, + { + name: "condition-one-request-nil", + sidCondition: []int8{1}, + sidRequest: nil, + expected: false, + }, + { + name: "condition-many-request-nil", + sidCondition: []int8{1, 2}, + sidRequest: nil, + expected: false, + }, + { + name: "condition-one-request-empty", + sidCondition: []int8{1}, + sidRequest: []int8{}, + expected: false, + }, + { + name: "condition-many-request-empty", + sidCondition: []int8{1, 2}, + sidRequest: []int8{}, + expected: false, + }, + { + name: "condition-one-request-one-match", + sidCondition: []int8{1}, + sidRequest: []int8{1}, + expected: true, + }, + { + name: "condition-one-request-one-nomatch", + sidCondition: []int8{1}, + sidRequest: []int8{2}, + expected: false, + }, + { + name: "condition-one-request-many-match", + sidCondition: []int8{1}, + sidRequest: []int8{1, 2}, + expected: true, + }, + { + name: "condition-one-request-many-nomatch", + sidCondition: []int8{3}, + sidRequest: []int8{1, 2}, + expected: false, + }, + { + name: "condition-nil-request-one", + sidCondition: nil, + sidRequest: []int8{1}, + expected: true, + }, + { + name: "condition-nil-request-many", + sidCondition: nil, + sidRequest: []int8{1, 2}, + expected: true, + }, + { + name: "condition-empty-request-one", + sidCondition: []int8{}, + sidRequest: []int8{1}, + expected: true, + }, + { + name: "condition-empty-request-many", + sidCondition: []int8{}, + sidRequest: []int8{1, 2}, + expected: true, + }, + { + name: "condition-many-request-one-match", + sidCondition: []int8{1, 2}, + sidRequest: []int8{1}, + expected: true, + }, + { + name: "condition-many-request-one-nomatch", + sidCondition: []int8{1, 2}, + sidRequest: []int8{3}, + expected: false, + }, + { + name: "condition-many-request-many-match", + sidCondition: []int8{1, 2}, + sidRequest: []int8{1, 2}, + expected: true, + }, + { + name: "condition-many-request-many-nomatch", + sidCondition: []int8{1, 2}, + sidRequest: []int8{3, 4}, + expected: false, + }, + { + name: "condition-many-request-many-mixed", + sidCondition: []int8{1, 2}, + sidRequest: []int8{2, 3}, + expected: true, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + actualResult := evaluateGPPSID(test.sidCondition, NewRequestFromPolicies(Policies{GPPSID: test.sidRequest})) + assert.Equal(t, test.expected, actualResult) + }) + } +} +func TestGetGPPSID(t *testing.T) { + testCases := []struct { + name string + request ActivityRequest + expected []int8 + }{ + { + name: "empty", + request: ActivityRequest{}, + expected: nil, + }, + { + name: "policies", + request: ActivityRequest{policies: &Policies{GPPSID: []int8{1}}}, + expected: []int8{1}, + }, + { + name: "request-regs", + request: ActivityRequest{bidRequest: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{Regs: &openrtb2.Regs{GPPSID: []int8{1}}}}}, + expected: []int8{1}, + }, + { + name: "request-regs-nil", + request: ActivityRequest{bidRequest: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{Regs: nil}}}, + expected: nil, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + actualResult := getGPPSID(test.request) + assert.Equal(t, test.expected, actualResult) }) } } diff --git a/privacy/scrubber.go b/privacy/scrubber.go index 4cc90c825df..59b74a2532b 100644 --- a/privacy/scrubber.go +++ b/privacy/scrubber.go @@ -2,10 +2,11 @@ package privacy import ( "encoding/json" + "net" + "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/util/iputil" "github.com/prebid/prebid-server/util/ptrutil" - "net" "github.com/prebid/openrtb/v19/openrtb2" ) @@ -92,9 +93,11 @@ func (s scrubber) ScrubRequest(bidRequest *openrtb2.BidRequest, enforcement Enfo var userExtParsed map[string]json.RawMessage userExtModified := false + // expressed in two lines because IntelliJ cannot infer the generic type var userCopy *openrtb2.User userCopy = ptrutil.Clone(bidRequest.User) + // expressed in two lines because IntelliJ cannot infer the generic type var deviceCopy *openrtb2.Device deviceCopy = ptrutil.Clone(bidRequest.Device) @@ -152,8 +155,7 @@ func (s scrubber) ScrubRequest(bidRequest *openrtb2.BidRequest, enforcement Enfo if enforcement.TID { //remove source.tid and imp.ext.tid if bidRequest.Source != nil { - var sourceCopy *openrtb2.Source - sourceCopy = ptrutil.Clone(bidRequest.Source) + sourceCopy := ptrutil.Clone(bidRequest.Source) sourceCopy.TID = "" bidRequest.Source = sourceCopy } diff --git a/usersync/chooser_test.go b/usersync/chooser_test.go index adc217ae8f5..4f38002c988 100644 --- a/usersync/chooser_test.go +++ b/usersync/chooser_test.go @@ -1,11 +1,12 @@ package usersync import ( - "github.com/prebid/prebid-server/privacy" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" "testing" "time" + + "github.com/prebid/prebid-server/macros" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" ) func TestNewChooser(t *testing.T) { @@ -376,7 +377,7 @@ func (s fakeSyncer) SupportsType(syncTypes []SyncType) bool { return false } -func (fakeSyncer) GetSync(syncTypes []SyncType, privacyPolicies privacy.Policies) (Sync, error) { +func (fakeSyncer) GetSync([]SyncType, macros.UserSyncPrivacy) (Sync, error) { return Sync{}, nil } diff --git a/usersync/syncer.go b/usersync/syncer.go index fb14201f2dc..e561614f4a2 100644 --- a/usersync/syncer.go +++ b/usersync/syncer.go @@ -11,14 +11,13 @@ import ( validator "github.com/asaskevich/govalidator" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/privacy" ) var ( - errNoSyncTypesProvided = errors.New("no sync types provided") - errNoSyncTypesSupported = errors.New("no sync types supported") - errDefaultTypeMissingIFrame = errors.New("default is set to iframe but no iframe endpoint is configured") - errDefaultTypeMissingRedirect = errors.New("default is set to redirect but no redirect endpoint is configured") + ErrSyncerEndpointRequired = errors.New("at least one endpoint (iframe and/or redirect) is required") + ErrSyncerKeyRequired = errors.New("key is required") + errNoSyncTypesProvided = errors.New("no sync types provided") + errNoSyncTypesSupported = errors.New("no sync types supported") ) // Syncer represents the user sync configuration for a bidder or a shared set of bidders. @@ -35,7 +34,7 @@ type Syncer interface { // GetSync returns a user sync for the user's device to perform, or an error if the none of the // sync types are supported or if macro substitution fails. - GetSync(syncTypes []SyncType, privacyPolicies privacy.Policies) (Sync, error) + GetSync(syncTypes []SyncType, userSyncMacros macros.UserSyncPrivacy) (Sync, error) } // Sync represents a user sync to be performed by the user's device. @@ -58,9 +57,6 @@ const ( setuidSyncTypeRedirect = "i" // i = image response ) -var ErrSyncerEndpointRequired = errors.New("at least one endpoint (iframe and/or redirect) is required") -var ErrSyncerKeyRequired = errors.New("key is required") - // NewSyncer creates a new Syncer from the provided configuration, or return an error if macro substition // fails or an endpoint url is invalid. func NewSyncer(hostConfig config.UserSync, syncerConfig config.Syncer, bidder string) (Syncer, error) { @@ -170,7 +166,7 @@ func escapeTemplate(x string) string { return escaped.String() } -var templateTestValues = macros.UserSyncTemplateParams{ +var templateTestValues = macros.UserSyncPrivacy{ GDPR: "anyGDPR", GDPRConsent: "anyGDPRConsent", USPrivacy: "anyCCPAConsent", @@ -219,7 +215,7 @@ func (s standardSyncer) filterSupportedSyncTypes(syncTypes []SyncType) []SyncTyp return supported } -func (s standardSyncer) GetSync(syncTypes []SyncType, privacyPolicies privacy.Policies) (Sync, error) { +func (s standardSyncer) GetSync(syncTypes []SyncType, userSyncMacros macros.UserSyncPrivacy) (Sync, error) { syncType, err := s.chooseSyncType(syncTypes) if err != nil { return Sync{}, err @@ -227,13 +223,7 @@ func (s standardSyncer) GetSync(syncTypes []SyncType, privacyPolicies privacy.Po syncTemplate := s.chooseTemplate(syncType) - url, err := macros.ResolveMacros(syncTemplate, macros.UserSyncTemplateParams{ - GDPR: privacyPolicies.GDPR.Signal, - GDPRConsent: privacyPolicies.GDPR.Consent, - USPrivacy: privacyPolicies.CCPA.Consent, - GPP: privacyPolicies.GPP.Consent, - GPPSID: privacyPolicies.GPP.RawSID, - }) + url, err := macros.ResolveMacros(syncTemplate, userSyncMacros) if err != nil { return Sync{}, err } diff --git a/usersync/syncer_test.go b/usersync/syncer_test.go index c309b899358..72167addae5 100644 --- a/usersync/syncer_test.go +++ b/usersync/syncer_test.go @@ -6,9 +6,6 @@ import ( "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/privacy" - "github.com/prebid/prebid-server/privacy/ccpa" - "github.com/prebid/prebid-server/privacy/gdpr" "github.com/stretchr/testify/assert" ) @@ -16,7 +13,7 @@ func TestNewSyncer(t *testing.T) { var ( supportCORS = true hostConfig = config.UserSync{ExternalURL: "http://host.com", RedirectURL: "{{.ExternalURL}}/host"} - macroValues = macros.UserSyncTemplateParams{GDPR: "A", GDPRConsent: "B", USPrivacy: "C"} + macroValues = macros.UserSyncPrivacy{GDPR: "A", GDPRConsent: "B", USPrivacy: "C"} iframeConfig = &config.SyncerEndpoint{URL: "https://bidder.com/iframe?redirect={{.RedirectURL}}"} redirectConfig = &config.SyncerEndpoint{URL: "https://bidder.com/redirect?redirect={{.RedirectURL}}"} errParseConfig = &config.SyncerEndpoint{URL: "{{malformed}}"} @@ -186,7 +183,7 @@ func TestBuildTemplate(t *testing.T) { key = "anyKey" syncTypeValue = "x" hostConfig = config.UserSync{ExternalURL: "http://host.com", RedirectURL: "{{.ExternalURL}}/host"} - macroValues = macros.UserSyncTemplateParams{GDPR: "A", GDPRConsent: "B", USPrivacy: "C", GPP: "D", GPPSID: "1"} + macroValues = macros.UserSyncPrivacy{GDPR: "A", GDPRConsent: "B", USPrivacy: "C", GPP: "D", GPPSID: "1"} ) testCases := []struct { @@ -451,7 +448,7 @@ func TestValidateTemplate(t *testing.T) { { description: "Contains Unrecognized Macro", given: template.Must(template.New("test").Parse("invalid:{{.DoesNotExist}}")), - expectedError: "template: test:1:10: executing \"test\" at <.DoesNotExist>: can't evaluate field DoesNotExist in type macros.UserSyncTemplateParams", + expectedError: "template: test:1:10: executing \"test\" at <.DoesNotExist>: can't evaluate field DoesNotExist in type macros.UserSyncPrivacy", }, { description: "Not A Url", @@ -636,45 +633,45 @@ func TestSyncerGetSync(t *testing.T) { ) testCases := []struct { - description string - givenSyncer standardSyncer - givenSyncTypes []SyncType - givenPrivacyPolicies privacy.Policies - expectedError string - expectedSync Sync + description string + givenSyncer standardSyncer + givenSyncTypes []SyncType + givenMacros macros.UserSyncPrivacy + expectedError string + expectedSync Sync }{ { - description: "No Sync Types", - givenSyncer: standardSyncer{iframe: iframeTemplate, redirect: redirectTemplate}, - givenSyncTypes: []SyncType{}, - givenPrivacyPolicies: privacy.Policies{GDPR: gdpr.Policy{Signal: "A", Consent: "B"}, CCPA: ccpa.Policy{Consent: "C"}}, - expectedError: "no sync types provided", + description: "No Sync Types", + givenSyncer: standardSyncer{iframe: iframeTemplate, redirect: redirectTemplate}, + givenSyncTypes: []SyncType{}, + givenMacros: macros.UserSyncPrivacy{GDPR: "A", GDPRConsent: "B", USPrivacy: "C"}, + expectedError: "no sync types provided", }, { - description: "IFrame", - givenSyncer: standardSyncer{iframe: iframeTemplate, redirect: redirectTemplate}, - givenSyncTypes: []SyncType{SyncTypeIFrame}, - givenPrivacyPolicies: privacy.Policies{GDPR: gdpr.Policy{Signal: "A", Consent: "B"}, CCPA: ccpa.Policy{Consent: "C"}}, - expectedSync: Sync{URL: "iframe,gdpr:A,gdprconsent:B,ccpa:C", Type: SyncTypeIFrame, SupportCORS: false}, + description: "IFrame", + givenSyncer: standardSyncer{iframe: iframeTemplate, redirect: redirectTemplate}, + givenSyncTypes: []SyncType{SyncTypeIFrame}, + givenMacros: macros.UserSyncPrivacy{GDPR: "A", GDPRConsent: "B", USPrivacy: "C"}, + expectedSync: Sync{URL: "iframe,gdpr:A,gdprconsent:B,ccpa:C", Type: SyncTypeIFrame, SupportCORS: false}, }, { - description: "Redirect", - givenSyncer: standardSyncer{iframe: iframeTemplate, redirect: redirectTemplate}, - givenSyncTypes: []SyncType{SyncTypeRedirect}, - givenPrivacyPolicies: privacy.Policies{GDPR: gdpr.Policy{Signal: "A", Consent: "B"}, CCPA: ccpa.Policy{Consent: "C"}}, - expectedSync: Sync{URL: "redirect,gdpr:A,gdprconsent:B,ccpa:C", Type: SyncTypeRedirect, SupportCORS: false}, + description: "Redirect", + givenSyncer: standardSyncer{iframe: iframeTemplate, redirect: redirectTemplate}, + givenSyncTypes: []SyncType{SyncTypeRedirect}, + givenMacros: macros.UserSyncPrivacy{GDPR: "A", GDPRConsent: "B", USPrivacy: "C"}, + expectedSync: Sync{URL: "redirect,gdpr:A,gdprconsent:B,ccpa:C", Type: SyncTypeRedirect, SupportCORS: false}, }, { - description: "Macro Error", - givenSyncer: standardSyncer{iframe: malformedTemplate}, - givenSyncTypes: []SyncType{SyncTypeIFrame}, - givenPrivacyPolicies: privacy.Policies{GDPR: gdpr.Policy{Signal: "A", Consent: "B"}, CCPA: ccpa.Policy{Consent: "C"}}, - expectedError: "template: test:1:20: executing \"test\" at <.DoesNotExist>: can't evaluate field DoesNotExist in type macros.UserSyncTemplateParams", + description: "Macro Error", + givenSyncer: standardSyncer{iframe: malformedTemplate}, + givenSyncTypes: []SyncType{SyncTypeIFrame}, + givenMacros: macros.UserSyncPrivacy{GDPR: "A", GDPRConsent: "B", USPrivacy: "C"}, + expectedError: "template: test:1:20: executing \"test\" at <.DoesNotExist>: can't evaluate field DoesNotExist in type macros.UserSyncPrivacy", }, } for _, test := range testCases { - result, err := test.givenSyncer.GetSync(test.givenSyncTypes, test.givenPrivacyPolicies) + result, err := test.givenSyncer.GetSync(test.givenSyncTypes, test.givenMacros) if test.expectedError == "" { assert.NoError(t, err, test.description+":err") diff --git a/usersync/syncersbuilder_test.go b/usersync/syncersbuilder_test.go index fbc1863959b..15c53dba2a4 100644 --- a/usersync/syncersbuilder_test.go +++ b/usersync/syncersbuilder_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/privacy" + "github.com/prebid/prebid-server/macros" "github.com/stretchr/testify/assert" ) @@ -160,7 +160,7 @@ func TestBuildSyncers(t *testing.T) { assert.Empty(t, errs, test.description+":err") resultRenderedIFrameURLS := map[string]string{} for k, v := range result { - iframeRendered, err := v.GetSync([]SyncType{SyncTypeIFrame}, privacy.Policies{}) + iframeRendered, err := v.GetSync([]SyncType{SyncTypeIFrame}, macros.UserSyncPrivacy{}) if assert.NoError(t, err, test.description+"key:%s,:iframe_render", k) { resultRenderedIFrameURLS[k] = iframeRendered.URL } From 23342eee10e943999c59bab51b8ad7a53fb7dbbf Mon Sep 17 00:00:00 2001 From: PGAMSSP <142323401+PGAMSSP@users.noreply.github.com> Date: Fri, 15 Sep 2023 13:52:00 +0300 Subject: [PATCH 118/268] New adapter: PGAMSSP (#3035) --- adapters/pgamssp/params_test.go | 47 ++++++ adapters/pgamssp/pgamssp.go | 145 ++++++++++++++++++ adapters/pgamssp/pgamssp_test.go | 20 +++ .../pgamssptest/exemplary/endpointId.json | 125 +++++++++++++++ .../pgamssptest/exemplary/simple-banner.json | 125 +++++++++++++++ .../pgamssptest/exemplary/simple-native.json | 109 +++++++++++++ .../pgamssptest/exemplary/simple-video.json | 120 +++++++++++++++ .../exemplary/simple-web-banner.json | 125 +++++++++++++++ .../supplemental/bad_media_type.json | 82 ++++++++++ .../supplemental/bad_response.json | 84 ++++++++++ .../pgamssptest/supplemental/status-204.json | 79 ++++++++++ .../supplemental/status-not-200.json | 84 ++++++++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_pgamssp.go | 6 + static/bidder-info/pgamssp.yaml | 19 +++ static/bidder-params/pgamssp.json | 23 +++ 17 files changed, 1197 insertions(+) create mode 100644 adapters/pgamssp/params_test.go create mode 100644 adapters/pgamssp/pgamssp.go create mode 100644 adapters/pgamssp/pgamssp_test.go create mode 100644 adapters/pgamssp/pgamssptest/exemplary/endpointId.json create mode 100644 adapters/pgamssp/pgamssptest/exemplary/simple-banner.json create mode 100644 adapters/pgamssp/pgamssptest/exemplary/simple-native.json create mode 100644 adapters/pgamssp/pgamssptest/exemplary/simple-video.json create mode 100644 adapters/pgamssp/pgamssptest/exemplary/simple-web-banner.json create mode 100644 adapters/pgamssp/pgamssptest/supplemental/bad_media_type.json create mode 100644 adapters/pgamssp/pgamssptest/supplemental/bad_response.json create mode 100644 adapters/pgamssp/pgamssptest/supplemental/status-204.json create mode 100644 adapters/pgamssp/pgamssptest/supplemental/status-not-200.json create mode 100644 openrtb_ext/imp_pgamssp.go create mode 100644 static/bidder-info/pgamssp.yaml create mode 100644 static/bidder-params/pgamssp.json diff --git a/adapters/pgamssp/params_test.go b/adapters/pgamssp/params_test.go new file mode 100644 index 00000000000..3e603237535 --- /dev/null +++ b/adapters/pgamssp/params_test.go @@ -0,0 +1,47 @@ +package pgamssp + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range validParams { + if err := validator.Validate(openrtb_ext.BidderPGAMSsp, json.RawMessage(p)); err != nil { + t.Errorf("Schema rejected valid params: %s", p) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderPGAMSsp, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} + +var validParams = []string{ + `{"placementId": "test"}`, + `{"placementId": "1"}`, + `{"endpointId": "test"}`, + `{"endpointId": "1"}`, +} + +var invalidParams = []string{ + `{"placementId": 42}`, + `{"endpointId": 42}`, + `{"placementId": "1", "endpointId": "1"}`, +} diff --git a/adapters/pgamssp/pgamssp.go b/adapters/pgamssp/pgamssp.go new file mode 100644 index 00000000000..378b8e5cbf6 --- /dev/null +++ b/adapters/pgamssp/pgamssp.go @@ -0,0 +1,145 @@ +package pgamssp + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +type adapter struct { + endpoint string +} + +type reqBodyExt struct { + PGAMSspBidderExt reqBodyExtBidder `json:"bidder"` +} + +type reqBodyExtBidder struct { + Type string `json:"type"` + PlacementID string `json:"placementId,omitempty"` + EndpointID string `json:"endpointId,omitempty"` +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var err error + var adapterRequests []*adapters.RequestData + + reqCopy := *request + for _, imp := range request.Imp { + reqCopy.Imp = []openrtb2.Imp{imp} + + var bidderExt adapters.ExtImpBidder + var pgamExt openrtb_ext.ImpExtPgamSsp + + if err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { + return nil, []error{err} + } + if err = json.Unmarshal(bidderExt.Bidder, &pgamExt); err != nil { + return nil, []error{err} + } + + temp := reqBodyExt{PGAMSspBidderExt: reqBodyExtBidder{}} + + if pgamExt.PlacementID != "" { + temp.PGAMSspBidderExt.PlacementID = pgamExt.PlacementID + temp.PGAMSspBidderExt.Type = "publisher" + } else if pgamExt.EndpointID != "" { + temp.PGAMSspBidderExt.EndpointID = pgamExt.EndpointID + temp.PGAMSspBidderExt.Type = "network" + } + + finalyImpExt, err := json.Marshal(temp) + if err != nil { + return nil, []error{err} + } + + reqCopy.Imp[0].Ext = finalyImpExt + + adapterReq, err := a.makeRequest(&reqCopy) + if err != nil { + return nil, []error{err} + } + + if adapterReq != nil { + adapterRequests = append(adapterRequests, adapterReq) + } + } + return adapterRequests, nil +} + +func (a *adapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, error) { + reqJSON, err := json.Marshal(request) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + return &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: reqJSON, + Headers: headers, + }, err +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} + } + + var response openrtb2.BidResponse + if err := json.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + bidResponse.Currency = response.Cur + for _, seatBid := range response.SeatBid { + for i := range seatBid.Bid { + bidType, err := getBidMediaType(&seatBid.Bid[i]) + if err != nil { + return nil, []error{err} + } + + b := &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + } + return bidResponse, nil +} + +func getBidMediaType(bid *openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupAudio: + return openrtb_ext.BidTypeAudio, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + return "", fmt.Errorf("Unable to fetch mediaType in multi-format: %s", bid.ImpID) + } +} diff --git a/adapters/pgamssp/pgamssp_test.go b/adapters/pgamssp/pgamssp_test.go new file mode 100644 index 00000000000..596b813c888 --- /dev/null +++ b/adapters/pgamssp/pgamssp_test.go @@ -0,0 +1,20 @@ +package pgamssp + +import ( + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderPGAMSsp, config.Adapter{ + Endpoint: "http://test.com/pserver"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "pgamssptest", bidder) +} diff --git a/adapters/pgamssp/pgamssptest/exemplary/endpointId.json b/adapters/pgamssp/pgamssptest/exemplary/endpointId.json new file mode 100644 index 00000000000..72805db16ba --- /dev/null +++ b/adapters/pgamssp/pgamssptest/exemplary/endpointId.json @@ -0,0 +1,125 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://test.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test", + "type": "network" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "mtype": 1 + } + ], + "seat": "pgamssp" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/pgamssp/pgamssptest/exemplary/simple-banner.json b/adapters/pgamssp/pgamssptest/exemplary/simple-banner.json new file mode 100644 index 00000000000..3850c4492c2 --- /dev/null +++ b/adapters/pgamssp/pgamssptest/exemplary/simple-banner.json @@ -0,0 +1,125 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://test.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "mtype": 1 + } + ], + "seat": "pgamssp" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/pgamssp/pgamssptest/exemplary/simple-native.json b/adapters/pgamssp/pgamssptest/exemplary/simple-native.json new file mode 100644 index 00000000000..8796adacd8e --- /dev/null +++ b/adapters/pgamssp/pgamssptest/exemplary/simple-native.json @@ -0,0 +1,109 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://test.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "mtype": 4 + } + ], + "seat": "pgamssp" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/pgamssp/pgamssptest/exemplary/simple-video.json b/adapters/pgamssp/pgamssptest/exemplary/simple-video.json new file mode 100644 index 00000000000..a39d0111694 --- /dev/null +++ b/adapters/pgamssp/pgamssptest/exemplary/simple-video.json @@ -0,0 +1,120 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://test.com/pserver", + "body": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "00:01:00", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 2 + } + ], + "seat": "pgamssp" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "00:01:00", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/pgamssp/pgamssptest/exemplary/simple-web-banner.json b/adapters/pgamssp/pgamssptest/exemplary/simple-web-banner.json new file mode 100644 index 00000000000..fca8ce176ea --- /dev/null +++ b/adapters/pgamssp/pgamssptest/exemplary/simple-web-banner.json @@ -0,0 +1,125 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "site": { + "id": "1", + "domain": "test.com" + }, + "device": { + "ip": "123.123.123.123", + "ua": "Ubuntu" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://test.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "site": { + "id": "1", + "domain": "test.com" + }, + "device": { + "ip": "123.123.123.123", + "ua": "Ubuntu" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 468, + "h": 60, + "mtype": 1 + } + ], + "seat": "pgamssp" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 468, + "h": 60, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/pgamssp/pgamssptest/supplemental/bad_media_type.json b/adapters/pgamssp/pgamssptest/supplemental/bad_media_type.json new file mode 100644 index 00000000000..6f016367b33 --- /dev/null +++ b/adapters/pgamssp/pgamssptest/supplemental/bad_media_type.json @@ -0,0 +1,82 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://test.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "ext": {} + } + ], + "seat": "pgamssp" + } + ], + "cur": "USD" + } + } + }], + "expectedMakeBidsErrors": [ + { + "value": "Unable to fetch mediaType in multi-format: test-imp-id", + "comparison": "literal" + } + ] +} diff --git a/adapters/pgamssp/pgamssptest/supplemental/bad_response.json b/adapters/pgamssp/pgamssptest/supplemental/bad_response.json new file mode 100644 index 00000000000..8c9f6f523fe --- /dev/null +++ b/adapters/pgamssp/pgamssptest/supplemental/bad_response.json @@ -0,0 +1,84 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://test.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + } + }, + "mockResponse": { + "status": 200, + "body": "" + } + }], + "expectedMakeBidsErrors": [ + { + "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "comparison": "literal" + } + ] +} diff --git a/adapters/pgamssp/pgamssptest/supplemental/status-204.json b/adapters/pgamssp/pgamssptest/supplemental/status-204.json new file mode 100644 index 00000000000..3869591eb40 --- /dev/null +++ b/adapters/pgamssp/pgamssptest/supplemental/status-204.json @@ -0,0 +1,79 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://test.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + } + }, + "mockResponse": { + "status": 204, + "body": {} + } + }], + "expectedBidResponses": [] +} diff --git a/adapters/pgamssp/pgamssptest/supplemental/status-not-200.json b/adapters/pgamssp/pgamssptest/supplemental/status-not-200.json new file mode 100644 index 00000000000..0c9b3eec08b --- /dev/null +++ b/adapters/pgamssp/pgamssptest/supplemental/status-not-200.json @@ -0,0 +1,84 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://test.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + } + }, + "mockResponse": { + "status": 404, + "body": {} + } + }], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 404. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index c5e9dc4947b..f64b366d717 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -133,6 +133,7 @@ import ( "github.com/prebid/prebid-server/adapters/outbrain" "github.com/prebid/prebid-server/adapters/ownadx" "github.com/prebid/prebid-server/adapters/pangle" + "github.com/prebid/prebid-server/adapters/pgamssp" "github.com/prebid/prebid-server/adapters/pubmatic" "github.com/prebid/prebid-server/adapters/pubnative" "github.com/prebid/prebid-server/adapters/pulsepoint" @@ -338,6 +339,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderOwnAdx: ownadx.Builder, openrtb_ext.BidderPangle: pangle.Builder, openrtb_ext.BidderPGAM: adtelligent.Builder, + openrtb_ext.BidderPGAMSsp: pgamssp.Builder, openrtb_ext.BidderPubmatic: pubmatic.Builder, openrtb_ext.BidderPubnative: pubnative.Builder, openrtb_ext.BidderPulsepoint: pulsepoint.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 11f01988013..1fb90e974b0 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -162,6 +162,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderOwnAdx, BidderPangle, BidderPGAM, + BidderPGAMSsp, BidderPubmatic, BidderPubnative, BidderPulsepoint, @@ -455,6 +456,7 @@ const ( BidderOwnAdx BidderName = "ownadx" BidderPangle BidderName = "pangle" BidderPGAM BidderName = "pgam" + BidderPGAMSsp BidderName = "pgamssp" BidderPubmatic BidderName = "pubmatic" BidderPubnative BidderName = "pubnative" BidderPulsepoint BidderName = "pulsepoint" diff --git a/openrtb_ext/imp_pgamssp.go b/openrtb_ext/imp_pgamssp.go new file mode 100644 index 00000000000..56e4b8bf7ac --- /dev/null +++ b/openrtb_ext/imp_pgamssp.go @@ -0,0 +1,6 @@ +package openrtb_ext + +type ImpExtPgamSsp struct { + PlacementID string `json:"placementId"` + EndpointID string `json:"endpointId"` +} diff --git a/static/bidder-info/pgamssp.yaml b/static/bidder-info/pgamssp.yaml new file mode 100644 index 00000000000..a762d8f15d4 --- /dev/null +++ b/static/bidder-info/pgamssp.yaml @@ -0,0 +1,19 @@ +endpoint: "http://us-east.pgammedia.com/pserver" +maintainer: + email: "info@pgammedia.com" +capabilities: + site: + mediaTypes: + - banner + - video + - native + + app: + mediaTypes: + - banner + - video + - native +userSync: + redirect: + url: "https://cs.pgammedia.com/pserver?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir={{.RedirectURL}}" + userMacro: "[UID]" diff --git a/static/bidder-params/pgamssp.json b/static/bidder-params/pgamssp.json new file mode 100644 index 00000000000..9d060241908 --- /dev/null +++ b/static/bidder-params/pgamssp.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "PgamSSP Adapter Params", + "description": "A schema which validates params accepted by the PgamSSP adapter", + "type": "object", + + "properties": { + "placementId": { + "type": "string", + "minLength": 1, + "description": "Placement ID" + }, + "endpointId": { + "type": "string", + "minLength": 1, + "description": "Endpoint ID" + } + }, + "oneOf": [ + { "required": ["placementId"] }, + { "required": ["endpointId"] } + ] + } \ No newline at end of file From e8632b0ec81f301c29f384731edb14321fedb412 Mon Sep 17 00:00:00 2001 From: ecdrsvc <82906140+ecdrsvc@users.noreply.github.com> Date: Fri, 15 Sep 2023 06:52:44 -0400 Subject: [PATCH 119/268] New Adapter mabidder (#3080) --- adapters/mabidder/mabidder.go | 99 ++++++++++++++++ adapters/mabidder/mabidder_test.go | 21 ++++ .../exemplary/simple-app-banner.json | 110 ++++++++++++++++++ .../supplemental/bad-request-example.json | 74 ++++++++++++ .../supplemental/bad-response-malformed.json | 72 ++++++++++++ .../supplemental/bad-response-status-500.json | 74 ++++++++++++ .../supplemental/no-content-response.json | 69 +++++++++++ adapters/mabidder/params_test.go | 50 ++++++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_mabidder.go | 5 + static/bidder-info/mabidder.yaml | 11 ++ static/bidder-params/mabidder.json | 15 +++ 13 files changed, 604 insertions(+) create mode 100644 adapters/mabidder/mabidder.go create mode 100644 adapters/mabidder/mabidder_test.go create mode 100644 adapters/mabidder/mabiddertest/exemplary/simple-app-banner.json create mode 100644 adapters/mabidder/mabiddertest/supplemental/bad-request-example.json create mode 100644 adapters/mabidder/mabiddertest/supplemental/bad-response-malformed.json create mode 100644 adapters/mabidder/mabiddertest/supplemental/bad-response-status-500.json create mode 100644 adapters/mabidder/mabiddertest/supplemental/no-content-response.json create mode 100644 adapters/mabidder/params_test.go create mode 100644 openrtb_ext/imp_mabidder.go create mode 100644 static/bidder-info/mabidder.yaml create mode 100644 static/bidder-params/mabidder.json diff --git a/adapters/mabidder/mabidder.go b/adapters/mabidder/mabidder.go new file mode 100644 index 00000000000..184f068b333 --- /dev/null +++ b/adapters/mabidder/mabidder.go @@ -0,0 +1,99 @@ +package mabidder + +import ( + "encoding/json" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +type serverResponse struct { + Responses []bidResponse + PrivateIdStatus string `json:"-"` +} + +type bidResponse struct { + RequestID string `json:"requestId"` + Currency string `json:"currency"` + Width int32 `json:"width"` + Height int32 `json:"height"` + PlacementId string `json:"creativeId"` + Deal string `json:"dealId,omitempty"` + NetRevenue bool `json:"netRevenue"` + TimeToLiveSeconds int32 `json:"ttl"` + AdTag string `json:"ad"` + MediaType string `json:"mediaType"` + Meta meta `json:"meta"` + CPM float32 `json:"cpm"` +} + +type meta struct { + AdDomain []string `json:"advertiserDomains"` +} + +type adapter struct { + endpoint string +} + +// Builder builds a new instance of the Mabidder adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + requestJSON, err := json.Marshal(request) + if err != nil { + return nil, []error{err} + } + + requestData := &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: requestJSON, + } + + return []*adapters.RequestData{requestData}, nil +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} + } + + var response serverResponse + if err := json.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + for _, maBidResp := range response.Responses { + b := &adapters.TypedBid{ + Bid: &openrtb2.Bid{ + ID: maBidResp.RequestID, + ImpID: maBidResp.RequestID, + Price: float64(maBidResp.CPM), + AdM: maBidResp.AdTag, + W: int64(maBidResp.Width), + H: int64(maBidResp.Height), + CrID: maBidResp.PlacementId, + DealID: maBidResp.Deal, + ADomain: maBidResp.Meta.AdDomain, + }, + BidType: openrtb_ext.BidType(maBidResp.MediaType), + } + bidResponse.Bids = append(bidResponse.Bids, b) + if maBidResp.Currency != "" { + bidResponse.Currency = maBidResp.Currency + } + } + return bidResponse, nil +} diff --git a/adapters/mabidder/mabidder_test.go b/adapters/mabidder/mabidder_test.go new file mode 100644 index 00000000000..89cfd31633e --- /dev/null +++ b/adapters/mabidder/mabidder_test.go @@ -0,0 +1,21 @@ +package mabidder + +import ( + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderMabidder, config.Adapter{ + Endpoint: "https://prebid.ecdrsvc.com/pbs"}, + config.Server{ExternalUrl: "https://prebid.ecdrsvc.com/pbs", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "mabiddertest", bidder) +} diff --git a/adapters/mabidder/mabiddertest/exemplary/simple-app-banner.json b/adapters/mabidder/mabiddertest/exemplary/simple-app-banner.json new file mode 100644 index 00000000000..4d3cbdfd278 --- /dev/null +++ b/adapters/mabidder/mabiddertest/exemplary/simple-app-banner.json @@ -0,0 +1,110 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa":"87857b31-8942-4646-ae80-ab9c95bf3fab" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "ppid": "ppidtest" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://prebid.ecdrsvc.com/pbs", + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa":"87857b31-8942-4646-ae80-ab9c95bf3fab" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "ppid": "ppidtest" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "Responses": [ + { + "requestId": "1", + "currency": "CAD", + "width": 300, + "height": 250, + "creativeId": "6002677", + "dealId": "testdeal", + "netRevenue": false, + "ttl": 5, + "ad": "", + "meta": { + "advertiserDomains": [ + "https://www.loblaws.ca/" + ] + }, + "cpm": 3.5764000415802 + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "id": "test-request-id", + "bids": [ + { + "bid": { + "id": "1", + "impid": "1", + "price":3.5764000415802, + "adm": "", + "adomain": [ + "https://www.loblaws.ca/" + ], + "crid": "6002677", + "dealid": "testdeal", + "w": 300, + "h": 250 + } + } + ], + "cur": "USD" + } + ] +} diff --git a/adapters/mabidder/mabiddertest/supplemental/bad-request-example.json b/adapters/mabidder/mabiddertest/supplemental/bad-request-example.json new file mode 100644 index 00000000000..8ab37e13079 --- /dev/null +++ b/adapters/mabidder/mabiddertest/supplemental/bad-request-example.json @@ -0,0 +1,74 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa":"87857b31-8942-4646-ae80-ab9c95bf3fab" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "ppid": "mabidder-test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://prebid.ecdrsvc.com/pbs", + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa":"87857b31-8942-4646-ae80-ab9c95bf3fab" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "ppid": "mabidder-test" + } + } + } + ] + } + }, + "mockResponse": { + "status": 400, + "body": { + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/mabidder/mabiddertest/supplemental/bad-response-malformed.json b/adapters/mabidder/mabiddertest/supplemental/bad-response-malformed.json new file mode 100644 index 00000000000..f62ed2a7a61 --- /dev/null +++ b/adapters/mabidder/mabiddertest/supplemental/bad-response-malformed.json @@ -0,0 +1,72 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa":"87857b31-8942-4646-ae80-ab9c95bf3fab" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "ppid": "mabidder-test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://prebid.ecdrsvc.com/pbs", + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa":"87857b31-8942-4646-ae80-ab9c95bf3fab" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "ppid": "mabidder-test" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "unexpected end of JSON input", + "comparison": "literal" + } + ] +} diff --git a/adapters/mabidder/mabiddertest/supplemental/bad-response-status-500.json b/adapters/mabidder/mabiddertest/supplemental/bad-response-status-500.json new file mode 100644 index 00000000000..8ee59384071 --- /dev/null +++ b/adapters/mabidder/mabiddertest/supplemental/bad-response-status-500.json @@ -0,0 +1,74 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa":"87857b31-8942-4646-ae80-ab9c95bf3fab" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "ppid": "mabidder-test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://prebid.ecdrsvc.com/pbs", + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa":"87857b31-8942-4646-ae80-ab9c95bf3fab" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "ppid": "mabidder-test" + } + } + } + ] + } + }, + "mockResponse": { + "status": 500, + "body": { + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/mabidder/mabiddertest/supplemental/no-content-response.json b/adapters/mabidder/mabiddertest/supplemental/no-content-response.json new file mode 100644 index 00000000000..640e78dcec8 --- /dev/null +++ b/adapters/mabidder/mabiddertest/supplemental/no-content-response.json @@ -0,0 +1,69 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa":"87857b31-8942-4646-ae80-ab9c95bf3fab" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "ppid": "mabidder-test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://prebid.ecdrsvc.com/pbs", + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa":"87857b31-8942-4646-ae80-ab9c95bf3fab" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "ppid": "mabidder-test" + } + } + } + ] + } + }, + "mockResponse": { + "status": 204, + "body": { + } + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/mabidder/params_test.go b/adapters/mabidder/params_test.go new file mode 100644 index 00000000000..b0f3762d843 --- /dev/null +++ b/adapters/mabidder/params_test.go @@ -0,0 +1,50 @@ +package mabidder + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range validParams { + if err := validator.Validate(openrtb_ext.BidderMabidder, json.RawMessage(p)); err != nil { + t.Errorf("Schema rejected valid params: %s", p) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderMabidder, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} + +var validParams = []string{ + `{"ppid": ""}`, + `{"ppid": "testppid"}`, +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `4.2`, + `[]`, + `{}`, + `{"ppid": 42}`, +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index f64b366d717..395e4fbbc39 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -113,6 +113,7 @@ import ( "github.com/prebid/prebid-server/adapters/logan" "github.com/prebid/prebid-server/adapters/logicad" "github.com/prebid/prebid-server/adapters/lunamedia" + mabidder "github.com/prebid/prebid-server/adapters/mabidder" "github.com/prebid/prebid-server/adapters/madvertise" "github.com/prebid/prebid-server/adapters/marsmedia" "github.com/prebid/prebid-server/adapters/medianet" @@ -317,6 +318,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderLogan: logan.Builder, openrtb_ext.BidderLogicad: logicad.Builder, openrtb_ext.BidderLunaMedia: lunamedia.Builder, + openrtb_ext.BidderMabidder: mabidder.Builder, openrtb_ext.BidderMadvertise: madvertise.Builder, openrtb_ext.BidderMarsmedia: marsmedia.Builder, openrtb_ext.BidderMediafuse: appnexus.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 1fb90e974b0..e12316f7e72 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -140,6 +140,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderLogan, BidderLogicad, BidderLunaMedia, + BidderMabidder, BidderMadvertise, BidderMarsmedia, BidderMediafuse, @@ -434,6 +435,7 @@ const ( BidderLogan BidderName = "logan" BidderLogicad BidderName = "logicad" BidderLunaMedia BidderName = "lunamedia" + BidderMabidder BidderName = "mabidder" BidderMadvertise BidderName = "madvertise" BidderMarsmedia BidderName = "marsmedia" BidderMediafuse BidderName = "mediafuse" diff --git a/openrtb_ext/imp_mabidder.go b/openrtb_ext/imp_mabidder.go new file mode 100644 index 00000000000..796a4877215 --- /dev/null +++ b/openrtb_ext/imp_mabidder.go @@ -0,0 +1,5 @@ +package openrtb_ext + +type ImpExtMabidder struct { + Ppid string `json:"ppid"` +} diff --git a/static/bidder-info/mabidder.yaml b/static/bidder-info/mabidder.yaml new file mode 100644 index 00000000000..3f03fd87854 --- /dev/null +++ b/static/bidder-info/mabidder.yaml @@ -0,0 +1,11 @@ +endpoint: "https://prebid.ecdrsvc.com/pbs" +maintainer: + email: lmprebidadapter@loblaw.ca +endpointCompression: gzip +capabilities: + app: + mediaTypes: + - banner + site: + mediaTypes: + - banner \ No newline at end of file diff --git a/static/bidder-params/mabidder.json b/static/bidder-params/mabidder.json new file mode 100644 index 00000000000..f005e88e33d --- /dev/null +++ b/static/bidder-params/mabidder.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Mabidder Adapter Params", + "description": "A schema which validates params accepted by the Mabidder adapter", + "type": "object", + + "properties": { + "ppid": { + "type": "string", + "description": "Publisher Placement ID" + } + }, + + "required": ["ppid"] +} \ No newline at end of file From 8cc0b09feb562bba833c9ede3b358886f6a27aad Mon Sep 17 00:00:00 2001 From: AlexBVolcy <74930484+AlexBVolcy@users.noreply.github.com> Date: Mon, 18 Sep 2023 10:22:02 -0700 Subject: [PATCH 120/268] SetUID Error Handling Refactor (#3050) * Error handling refactor * Minor tweak * Revert back to original code --- endpoints/setuid.go | 62 +++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 36 deletions(-) diff --git a/endpoints/setuid.go b/endpoints/setuid.go index 64178444e0d..83425789647 100644 --- a/endpoints/setuid.go +++ b/endpoints/setuid.go @@ -50,9 +50,7 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use cookie := usersync.ReadCookie(r, decoder, &cfg.HostCookie) if !cookie.AllowSyncs() { - w.WriteHeader(http.StatusUnauthorized) - metricsEngine.RecordSetUid(metrics.SetUidOptOut) - so.Status = http.StatusUnauthorized + handleBadStatus(w, http.StatusUnauthorized, metrics.SetUidOptOut, nil, metricsEngine, &so) return } usersync.SyncHostCookie(r, cookie, &cfg.HostCookie) @@ -61,22 +59,14 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use syncer, bidderName, err := getSyncer(query, syncersByBidder) if err != nil { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte(err.Error())) - metricsEngine.RecordSetUid(metrics.SetUidSyncerUnknown) - so.Errors = []error{err} - so.Status = http.StatusBadRequest + handleBadStatus(w, http.StatusBadRequest, metrics.SetUidSyncerUnknown, err, metricsEngine, &so) return } so.Bidder = syncer.Key() responseFormat, err := getResponseFormat(query, syncer) if err != nil { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte(err.Error())) - metricsEngine.RecordSetUid(metrics.SetUidBadRequest) - so.Errors = []error{err} - so.Status = http.StatusBadRequest + handleBadStatus(w, http.StatusBadRequest, metrics.SetUidBadRequest, err, metricsEngine, &so) return } @@ -86,21 +76,19 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use } account, fetchErrs := accountService.GetAccount(context.Background(), cfg, accountsFetcher, accountID, metricsEngine) if len(fetchErrs) > 0 { - w.WriteHeader(http.StatusBadRequest) + var metricValue metrics.SetUidStatus err := combineErrors(fetchErrs) - w.Write([]byte(err.Error())) switch err { case errCookieSyncAccountBlocked: - metricsEngine.RecordSetUid(metrics.SetUidAccountBlocked) + metricValue = metrics.SetUidAccountBlocked case errCookieSyncAccountConfigMalformed: - metricsEngine.RecordSetUid(metrics.SetUidAccountConfigMalformed) + metricValue = metrics.SetUidAccountConfigMalformed case errCookieSyncAccountInvalid: - metricsEngine.RecordSetUid(metrics.SetUidAccountInvalid) + metricValue = metrics.SetUidAccountInvalid default: - metricsEngine.RecordSetUid(metrics.SetUidBadRequest) + metricValue = metrics.SetUidBadRequest } - so.Errors = []error{err} - so.Status = http.StatusBadRequest + handleBadStatus(w, http.StatusBadRequest, metricValue, err, metricsEngine, &so) return } @@ -134,11 +122,7 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use if err != nil { // Only exit if non-warning if !errortypes.IsWarning(err) { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte(err.Error())) - metricsEngine.RecordSetUid(metrics.SetUidBadRequest) - so.Errors = []error{err} - so.Status = http.StatusBadRequest + handleBadStatus(w, http.StatusBadRequest, metrics.SetUidBadRequest, err, metricsEngine, &so) return } w.Write([]byte("Warning: " + err.Error())) @@ -147,16 +131,14 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use tcf2Cfg := tcf2CfgBuilder(cfg.GDPR.TCF2, account.GDPR) if shouldReturn, status, body := preventSyncsGDPR(gdprRequestInfo, gdprPermsBuilder, tcf2Cfg); shouldReturn { - w.WriteHeader(status) - w.Write([]byte(body)) + var metricValue metrics.SetUidStatus switch status { case http.StatusBadRequest: - metricsEngine.RecordSetUid(metrics.SetUidBadRequest) + metricValue = metrics.SetUidBadRequest case http.StatusUnavailableForLegalReasons: - metricsEngine.RecordSetUid(metrics.SetUidGDPRHostCookieBlocked) + metricValue = metrics.SetUidGDPRHostCookieBlocked } - so.Errors = []error{errors.New(body)} - so.Status = status + handleBadStatus(w, status, metricValue, errors.New(body), metricsEngine, &so) return } @@ -179,10 +161,7 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use // Write Cookie encodedCookie, err := cookie.PrepareCookieForWrite(&cfg.HostCookie, encoder) if err != nil { - w.WriteHeader(http.StatusBadRequest) - metricsEngine.RecordSetUid(metrics.SetUidBadRequest) - so.Errors = []error{err} - so.Status = http.StatusBadRequest + handleBadStatus(w, http.StatusBadRequest, metrics.SetUidBadRequest, err, metricsEngine, &so) return } usersync.WriteCookie(w, encodedCookie, &cfg.HostCookie, setSiteCookie) @@ -422,3 +401,14 @@ func preventSyncsGDPR(gdprRequestInfo gdpr.RequestInfo, permsBuilder gdpr.Permis return true, http.StatusUnavailableForLegalReasons, "The gdpr_consent string prevents cookies from being saved" } + +func handleBadStatus(w http.ResponseWriter, status int, metricValue metrics.SetUidStatus, err error, me metrics.MetricsEngine, so *analytics.SetUIDObject) { + w.WriteHeader(status) + me.RecordSetUid(metricValue) + so.Status = status + + if err != nil { + so.Errors = []error{err} + w.Write([]byte(err.Error())) + } +} From f54d3749d8131639b5ce8ea70d37eaa9528c93ef Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Mon, 18 Sep 2023 16:35:04 -0400 Subject: [PATCH 121/268] Bidder Info Endpoint: Base Adapter Only Filter (#3088) * Base Adapters Only * Fix Tpyo --- endpoints/info/bidders.go | 113 +++++++-- endpoints/info/bidders_test.go | 448 +++++++++++++++++++++++++-------- 2 files changed, 433 insertions(+), 128 deletions(-) diff --git a/endpoints/info/bidders.go b/endpoints/info/bidders.go index 989f70b848f..9984abe216d 100644 --- a/endpoints/info/bidders.go +++ b/endpoints/info/bidders.go @@ -11,7 +11,8 @@ import ( "github.com/prebid/prebid-server/config" ) -var invalidEnabledOnly = []byte(`Invalid value for 'enabledonly' query param, must be of boolean type`) +var invalidEnabledOnlyMsg = []byte(`Invalid value for 'enabledonly' query param, must be of boolean type`) +var invalidBaseAdaptersOnlyMsg = []byte(`Invalid value for 'baseadaptersonly' query param, must be of boolean type`) // NewBiddersEndpoint builds a handler for the /info/bidders endpoint. func NewBiddersEndpoint(bidders config.BidderInfos, aliases map[string]string) httprouter.Handle { @@ -20,43 +21,74 @@ func NewBiddersEndpoint(bidders config.BidderInfos, aliases map[string]string) h glog.Fatalf("error creating /info/bidders endpoint all bidders response: %v", err) } + responseAllBaseOnly, err := prepareBiddersResponseAllBaseOnly(bidders) + if err != nil { + glog.Fatalf("error creating /info/bidders endpoint all bidders (base adapters only) response: %v", err) + } + responseEnabledOnly, err := prepareBiddersResponseEnabledOnly(bidders, aliases) if err != nil { glog.Fatalf("error creating /info/bidders endpoint enabled only response: %v", err) } + responseEnabledOnlyBaseOnly, err := prepareBiddersResponseEnabledOnlyBaseOnly(bidders) + if err != nil { + glog.Fatalf("error creating /info/bidders endpoint enabled only (base adapters only) response: %v", err) + } + return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { - var writeErr error - switch readEnabledOnly(r) { - case "true": - w.Header().Set("Content-Type", "application/json") - _, writeErr = w.Write(responseEnabledOnly) - case "false": - w.Header().Set("Content-Type", "application/json") - _, writeErr = w.Write(responseAll) - default: - w.WriteHeader(http.StatusBadRequest) - _, writeErr = w.Write(invalidEnabledOnly) + enabledOnly, baseAdaptersOnly, errMsg := readQueryFlags(r) + if errMsg != nil { + writeBadRequest(w, errMsg) + return } - if writeErr != nil { - glog.Errorf("error writing response to /info/bidders: %v", writeErr) + var response []byte + switch { + case !enabledOnly && !baseAdaptersOnly: + response = responseAll + case !enabledOnly && baseAdaptersOnly: + response = responseAllBaseOnly + case enabledOnly && !baseAdaptersOnly: + response = responseEnabledOnly + case enabledOnly && baseAdaptersOnly: + response = responseEnabledOnlyBaseOnly } + writeResponse(w, response) + } +} + +func readQueryFlags(r *http.Request) (enabledOnly, baseAdaptersOnly bool, errMsg []byte) { + enabledOnly, ok := readQueryFlag(r, "enabledonly") + if !ok { + return false, false, invalidEnabledOnlyMsg + } + + baseAdapterOnly, ok := readQueryFlag(r, "baseadaptersonly") + if !ok { + return false, false, invalidBaseAdaptersOnlyMsg } + + return enabledOnly, baseAdapterOnly, nil } -func readEnabledOnly(r *http.Request) string { +func readQueryFlag(r *http.Request, queryParam string) (flag, ok bool) { q := r.URL.Query() - v, exists := q["enabledonly"] + v, exists := q[queryParam] if !exists || len(v) == 0 { - // if the enabledOnly query parameter is not specified, default to false to match - // previous behavior of returning all adapters regardless of their enabled status. - return "false" + return false, true } - return strings.ToLower(v[0]) + switch strings.ToLower(v[0]) { + case "true": + return true, true + case "false": + return false, true + default: + return false, false + } } func prepareBiddersResponseAll(bidders config.BidderInfos, aliases map[string]string) ([]byte, error) { @@ -71,7 +103,19 @@ func prepareBiddersResponseAll(bidders config.BidderInfos, aliases map[string]st } sort.Strings(bidderNames) + return json.Marshal(bidderNames) +} +func prepareBiddersResponseAllBaseOnly(bidders config.BidderInfos) ([]byte, error) { + bidderNames := make([]string, 0, len(bidders)) + + for name, info := range bidders { + if len(info.AliasOf) == 0 { + bidderNames = append(bidderNames, name) + } + } + + sort.Strings(bidderNames) return json.Marshal(bidderNames) } @@ -94,3 +138,32 @@ func prepareBiddersResponseEnabledOnly(bidders config.BidderInfos, aliases map[s return json.Marshal(bidderNames) } + +func prepareBiddersResponseEnabledOnlyBaseOnly(bidders config.BidderInfos) ([]byte, error) { + bidderNames := make([]string, 0, len(bidders)) + + for name, info := range bidders { + if info.IsEnabled() && len(info.AliasOf) == 0 { + bidderNames = append(bidderNames, name) + } + } + + sort.Strings(bidderNames) + return json.Marshal(bidderNames) +} + +func writeBadRequest(w http.ResponseWriter, data []byte) { + w.WriteHeader(http.StatusBadRequest) + writeWithErrorHandling(w, data) +} + +func writeResponse(w http.ResponseWriter, data []byte) { + w.Header().Set("Content-Type", "application/json") + writeWithErrorHandling(w, data) +} + +func writeWithErrorHandling(w http.ResponseWriter, data []byte) { + if _, err := w.Write(data); err != nil { + glog.Errorf("error writing response to /info/bidders: %v", err) + } +} diff --git a/endpoints/info/bidders_test.go b/endpoints/info/bidders_test.go index 8aec0972f74..1f483e5de27 100644 --- a/endpoints/info/bidders_test.go +++ b/endpoints/info/bidders_test.go @@ -12,238 +12,470 @@ import ( func TestPrepareBiddersResponseAll(t *testing.T) { var ( - enabled = config.BidderInfo{Disabled: false} - disabled = config.BidderInfo{Disabled: true} + enabledCore = config.BidderInfo{Disabled: false} + enabledAlias = config.BidderInfo{Disabled: false, AliasOf: "something"} + disabledCore = config.BidderInfo{Disabled: true} + disabledAlias = config.BidderInfo{Disabled: true, AliasOf: "something"} ) testCases := []struct { - description string + name string + givenBidders config.BidderInfos + givenRequestAliases map[string]string + expected string + }{ + { + name: "none", + givenBidders: config.BidderInfos{}, + givenRequestAliases: nil, + expected: `[]`, + }, + { + name: "core-one-enabled", + givenBidders: config.BidderInfos{"a": enabledCore}, + givenRequestAliases: nil, + expected: `["a"]`, + }, + { + name: "core-one-disabled", + givenBidders: config.BidderInfos{"a": disabledCore}, + givenRequestAliases: nil, + expected: `["a"]`, + }, + { + name: "core-one-mixed", + givenBidders: config.BidderInfos{"a": disabledCore, "b": enabledCore}, + givenRequestAliases: nil, + expected: `["a","b"]`, + }, + { + name: "core-one-mixed-sorted", + givenBidders: config.BidderInfos{"z": enabledCore, "a": enabledCore}, + givenRequestAliases: nil, + expected: `["a","z"]`, + }, + { + name: "alias-one", + givenBidders: config.BidderInfos{"a": enabledAlias}, + givenRequestAliases: nil, + expected: `["a"]`, + }, + { + name: "alias-mixed", + givenBidders: config.BidderInfos{"a": disabledCore, "b": disabledAlias, "c": enabledCore, "d": enabledAlias}, + givenRequestAliases: nil, + expected: `["a","b","c","d"]`, + }, + { + name: "alias-mixed-sorted", + givenBidders: config.BidderInfos{"z": enabledAlias, "a": enabledCore}, + givenRequestAliases: nil, + expected: `["a","z"]`, + }, + { + name: "defaultrequest-one", + givenBidders: config.BidderInfos{"a": enabledCore}, + givenRequestAliases: map[string]string{"b": "a"}, + expected: `["a","b"]`, + }, + { + name: "defaultrequest-mixed", + givenBidders: config.BidderInfos{"a": enabledCore, "b": disabledCore}, + givenRequestAliases: map[string]string{"x": "a", "y": "b"}, + expected: `["a","b","x","y"]`, + }, + { + name: "defaultrequest-mixed-sorted", + givenBidders: config.BidderInfos{"z": enabledCore}, + givenRequestAliases: map[string]string{"a": "z"}, + expected: `["a","z"]`, + }, + { + name: "mixed", + givenBidders: config.BidderInfos{"a": disabledCore, "b": disabledAlias, "c": enabledCore, "d": enabledAlias}, + givenRequestAliases: map[string]string{"z": "a"}, + expected: `["a","b","c","d","z"]`, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + result, err := prepareBiddersResponseAll(test.givenBidders, test.givenRequestAliases) + assert.NoError(t, err) + assert.Equal(t, []byte(test.expected), result) + }) + } +} + +func TestPrepareBiddersResponseAllBaseOnly(t *testing.T) { + var ( + enabledCore = config.BidderInfo{Disabled: false} + enabledAlias = config.BidderInfo{Disabled: false, AliasOf: "something"} + disabledCore = config.BidderInfo{Disabled: true} + disabledAlias = config.BidderInfo{Disabled: true, AliasOf: "something"} + ) + + testCases := []struct { + name string givenBidders config.BidderInfos - givenAliases map[string]string expected string }{ { - description: "None", + name: "none", givenBidders: config.BidderInfos{}, - givenAliases: nil, expected: `[]`, }, { - description: "Core Bidders Only - One - Enabled", - givenBidders: config.BidderInfos{"a": enabled}, - givenAliases: nil, + name: "core-one-enabled", + givenBidders: config.BidderInfos{"a": enabledCore}, expected: `["a"]`, }, { - description: "Core Bidders Only - One - Disabled", - givenBidders: config.BidderInfos{"a": disabled}, - givenAliases: nil, + name: "core-one-disabled", + givenBidders: config.BidderInfos{"a": disabledCore}, expected: `["a"]`, }, { - description: "Core Bidders Only - Many", - givenBidders: config.BidderInfos{"a": enabled, "b": enabled}, - givenAliases: nil, + name: "core-one-mixed", + givenBidders: config.BidderInfos{"a": disabledCore, "b": enabledCore}, expected: `["a","b"]`, }, { - description: "Core Bidders Only - Many - Mixed", - givenBidders: config.BidderInfos{"a": disabled, "b": enabled}, - givenAliases: nil, - expected: `["a","b"]`, + name: "core-one-mixed-sorted", + givenBidders: config.BidderInfos{"z": enabledCore, "a": enabledCore}, + expected: `["a","z"]`, }, { - description: "Core Bidders Only - Many - Sorted", - givenBidders: config.BidderInfos{"b": enabled, "a": enabled}, - givenAliases: nil, - expected: `["a","b"]`, + name: "alias-one", + givenBidders: config.BidderInfos{"a": enabledAlias}, + expected: `[]`, }, { - description: "With Aliases - One", - givenBidders: config.BidderInfos{"a": enabled}, - givenAliases: map[string]string{"b": "a"}, - expected: `["a","b"]`, + name: "alias-mixed", + givenBidders: config.BidderInfos{"a": disabledCore, "b": disabledAlias, "c": enabledCore, "d": enabledAlias}, + expected: `["a","c"]`, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + result, err := prepareBiddersResponseAllBaseOnly(test.givenBidders) + assert.NoError(t, err) + assert.Equal(t, []byte(test.expected), result) + }) + } +} + +func TestPrepareBiddersResponseEnabledOnly(t *testing.T) { + var ( + enabledCore = config.BidderInfo{Disabled: false} + enabledAlias = config.BidderInfo{Disabled: false, AliasOf: "something"} + disabledCore = config.BidderInfo{Disabled: true} + disabledAlias = config.BidderInfo{Disabled: true, AliasOf: "something"} + ) + + testCases := []struct { + name string + givenBidders config.BidderInfos + givenRequestAliases map[string]string + expected string + }{ + { + name: "none", + givenBidders: config.BidderInfos{}, + givenRequestAliases: nil, + expected: `[]`, }, { - description: "With Aliases - Many", - givenBidders: config.BidderInfos{"a": enabled, "b": disabled}, - givenAliases: map[string]string{"x": "a", "y": "b"}, - expected: `["a","b","x","y"]`, + name: "core-one-enabled", + givenBidders: config.BidderInfos{"a": enabledCore}, + givenRequestAliases: nil, + expected: `["a"]`, }, { - description: "With Aliases - Sorted", - givenBidders: config.BidderInfos{"z": enabled}, - givenAliases: map[string]string{"a": "z"}, - expected: `["a","z"]`, + name: "core-one-disabled", + givenBidders: config.BidderInfos{"a": disabledCore}, + givenRequestAliases: nil, + expected: `[]`, + }, + { + name: "core-one-mixed", + givenBidders: config.BidderInfos{"a": disabledCore, "b": enabledCore}, + givenRequestAliases: nil, + expected: `["b"]`, + }, + { + name: "core-one-mixed-sorted", + givenBidders: config.BidderInfos{"z": enabledCore, "a": enabledCore}, + givenRequestAliases: nil, + expected: `["a","z"]`, + }, + { + name: "alias-one", + givenBidders: config.BidderInfos{"a": enabledAlias}, + givenRequestAliases: nil, + expected: `["a"]`, + }, + { + name: "alias-mixed", + givenBidders: config.BidderInfos{"a": disabledCore, "b": disabledAlias, "c": enabledCore, "d": enabledAlias}, + givenRequestAliases: nil, + expected: `["c","d"]`, + }, + { + name: "alias-mixed-sorted", + givenBidders: config.BidderInfos{"z": enabledAlias, "a": enabledCore}, + givenRequestAliases: nil, + expected: `["a","z"]`, + }, + { + name: "defaultrequest-one", + givenBidders: config.BidderInfos{"a": enabledCore}, + givenRequestAliases: map[string]string{"b": "a"}, + expected: `["a","b"]`, + }, + { + name: "defaultrequest-mixed", + givenBidders: config.BidderInfos{"a": enabledCore, "b": disabledCore}, + givenRequestAliases: map[string]string{"x": "a", "y": "b"}, + expected: `["a","x"]`, + }, + { + name: "defaultrequest-mixed-sorted", + givenBidders: config.BidderInfos{"z": enabledCore}, + givenRequestAliases: map[string]string{"a": "z"}, + expected: `["a","z"]`, + }, + { + name: "mixed", + givenBidders: config.BidderInfos{"a": disabledCore, "b": disabledAlias, "c": enabledCore, "d": enabledAlias}, + givenRequestAliases: map[string]string{"z": "a"}, + expected: `["c","d"]`, }, } for _, test := range testCases { - result, err := prepareBiddersResponseAll(test.givenBidders, test.givenAliases) - - assert.NoError(t, err, test.description) - assert.Equal(t, []byte(test.expected), result, test.description) + t.Run(test.name, func(t *testing.T) { + result, err := prepareBiddersResponseEnabledOnly(test.givenBidders, test.givenRequestAliases) + assert.NoError(t, err) + assert.Equal(t, []byte(test.expected), result) + }) } } -func TestPrepareBiddersResponseEnabledOnly(t *testing.T) { +func TestPrepareBiddersResponseEnabledOnlyBaseOnly(t *testing.T) { var ( - enabled = config.BidderInfo{Disabled: false} - disabled = config.BidderInfo{Disabled: true} + enabledCore = config.BidderInfo{Disabled: false} + enabledAlias = config.BidderInfo{Disabled: false, AliasOf: "something"} + disabledCore = config.BidderInfo{Disabled: true} + disabledAlias = config.BidderInfo{Disabled: true, AliasOf: "something"} ) testCases := []struct { - description string + name string givenBidders config.BidderInfos - givenAliases map[string]string expected string }{ { - description: "None", + name: "none", givenBidders: config.BidderInfos{}, - givenAliases: nil, expected: `[]`, }, { - description: "Core Bidders Only - One - Enabled", - givenBidders: config.BidderInfos{"a": enabled}, - givenAliases: nil, + name: "core-one-enabled", + givenBidders: config.BidderInfos{"a": enabledCore}, expected: `["a"]`, }, { - description: "Core Bidders Only - One - Disabled", - givenBidders: config.BidderInfos{"a": disabled}, - givenAliases: nil, + name: "core-one-disabled", + givenBidders: config.BidderInfos{"a": disabledCore}, expected: `[]`, }, { - description: "Core Bidders Only - Many", - givenBidders: config.BidderInfos{"a": enabled, "b": enabled}, - givenAliases: nil, - expected: `["a","b"]`, - }, - { - description: "Core Bidders Only - Many - Mixed", - givenBidders: config.BidderInfos{"a": disabled, "b": enabled}, - givenAliases: nil, + name: "core-one-mixed", + givenBidders: config.BidderInfos{"a": disabledCore, "b": enabledCore}, expected: `["b"]`, }, { - description: "Core Bidders Only - Many - Sorted", - givenBidders: config.BidderInfos{"b": enabled, "a": enabled}, - givenAliases: nil, - expected: `["a","b"]`, + name: "core-one-mixed-sorted", + givenBidders: config.BidderInfos{"z": enabledCore, "a": enabledCore}, + expected: `["a","z"]`, }, { - description: "With Aliases - One", - givenBidders: config.BidderInfos{"a": enabled}, - givenAliases: map[string]string{"b": "a"}, - expected: `["a","b"]`, + name: "alias-one", + givenBidders: config.BidderInfos{"a": enabledAlias}, + expected: `[]`, }, { - description: "With Aliases - Many", - givenBidders: config.BidderInfos{"a": enabled, "b": disabled}, - givenAliases: map[string]string{"x": "a", "y": "b"}, - expected: `["a","x"]`, + name: "alias-many", + givenBidders: config.BidderInfos{"a": enabledAlias, "b": enabledAlias}, + expected: `[]`, }, { - description: "With Aliases - Sorted", - givenBidders: config.BidderInfos{"z": enabled}, - givenAliases: map[string]string{"a": "z"}, - expected: `["a","z"]`, + name: "mixed", + givenBidders: config.BidderInfos{"a": disabledCore, "b": disabledAlias, "c": enabledCore, "d": enabledAlias}, + expected: `["c"]`, }, } for _, test := range testCases { - result, err := prepareBiddersResponseEnabledOnly(test.givenBidders, test.givenAliases) - - assert.NoError(t, err, test.description) - assert.Equal(t, []byte(test.expected), result, test.description) + t.Run(test.name, func(t *testing.T) { + result, err := prepareBiddersResponseEnabledOnlyBaseOnly(test.givenBidders) + assert.NoError(t, err) + assert.Equal(t, []byte(test.expected), result) + }) } } func TestBiddersHandler(t *testing.T) { var ( - enabled = config.BidderInfo{Disabled: false} - disabled = config.BidderInfo{Disabled: true} + enabledCore = config.BidderInfo{Disabled: false} + enabledAlias = config.BidderInfo{Disabled: false, AliasOf: "something"} + disabledCore = config.BidderInfo{Disabled: true} + disabledAlias = config.BidderInfo{Disabled: true, AliasOf: "something"} ) - bidders := config.BidderInfos{"a": enabled, "b": disabled} - aliases := map[string]string{"x": "a", "y": "b"} + bidders := config.BidderInfos{"a": enabledCore, "b": enabledAlias, "c": disabledCore, "d": disabledAlias} + aliases := map[string]string{"x": "a", "y": "c"} testCases := []struct { - description string + name string givenURL string expectedStatus int expectedBody string expectedHeaders http.Header }{ { - description: "No Query Parameters - Backwards Compatibility", + name: "simple", givenURL: "/info/bidders", expectedStatus: http.StatusOK, - expectedBody: `["a","b","x","y"]`, + expectedBody: `["a","b","c","d","x","y"]`, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, }, { - description: "Enabled Only - False", + name: "enabledonly-false", givenURL: "/info/bidders?enabledonly=false", expectedStatus: http.StatusOK, - expectedBody: `["a","b","x","y"]`, + expectedBody: `["a","b","c","d","x","y"]`, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, }, { - description: "Enabled Only - False - Case Insensitive", + name: "enabledonly-false-caseinsensitive", givenURL: "/info/bidders?enabledonly=fAlSe", expectedStatus: http.StatusOK, - expectedBody: `["a","b","x","y"]`, + expectedBody: `["a","b","c","d","x","y"]`, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, }, { - description: "Enabled Only - True", + name: "enabledonly-true", givenURL: "/info/bidders?enabledonly=true", expectedStatus: http.StatusOK, - expectedBody: `["a","x"]`, + expectedBody: `["a","b","x"]`, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, }, { - description: "Enabled Only - True - Case Insensitive", + name: "enabledonly-true-caseinsensitive", givenURL: "/info/bidders?enabledonly=TrUe", expectedStatus: http.StatusOK, - expectedBody: `["a","x"]`, + expectedBody: `["a","b","x"]`, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, }, { - description: "Enabled Only - Invalid", + name: "enabledonly-invalid", givenURL: "/info/bidders?enabledonly=foo", expectedStatus: http.StatusBadRequest, expectedBody: `Invalid value for 'enabledonly' query param, must be of boolean type`, expectedHeaders: http.Header{}, }, { - description: "Enabled Only - Missing Value", + name: "enabledonly-missing", givenURL: "/info/bidders?enabledonly=", expectedStatus: http.StatusBadRequest, expectedBody: `Invalid value for 'enabledonly' query param, must be of boolean type`, expectedHeaders: http.Header{}, }, + { + name: "baseonly-false", + givenURL: "/info/bidders?baseadaptersonly=false", + expectedStatus: http.StatusOK, + expectedBody: `["a","b","c","d","x","y"]`, + expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, + }, + { + name: "baseonly-false-caseinsensitive", + givenURL: "/info/bidders?baseadaptersonly=fAlSe", + expectedStatus: http.StatusOK, + expectedBody: `["a","b","c","d","x","y"]`, + expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, + }, + { + name: "baseonly-true", + givenURL: "/info/bidders?baseadaptersonly=true", + expectedStatus: http.StatusOK, + expectedBody: `["a","c"]`, + expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, + }, + { + name: "baseonly-true-caseinsensitive", + givenURL: "/info/bidders?baseadaptersonly=TrUe", + expectedStatus: http.StatusOK, + expectedBody: `["a","c"]`, + expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, + }, + { + name: "baseonly-invalid", + givenURL: "/info/bidders?baseadaptersonly=foo", + expectedStatus: http.StatusBadRequest, + expectedBody: `Invalid value for 'baseadaptersonly' query param, must be of boolean type`, + expectedHeaders: http.Header{}, + }, + { + name: "baseonly-missing", + givenURL: "/info/bidders?baseadaptersonly=", + expectedStatus: http.StatusBadRequest, + expectedBody: `Invalid value for 'baseadaptersonly' query param, must be of boolean type`, + expectedHeaders: http.Header{}, + }, + { + name: "enabledonly-true-baseonly-false", + givenURL: "/info/bidders?enabledonly=true&baseadaptersonly=false", + expectedStatus: http.StatusOK, + expectedBody: `["a","b","x"]`, + expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, + }, + { + name: "enabledonly-false-baseonly-true", + givenURL: "/info/bidders?enabledonly=false&baseadaptersonly=true", + expectedStatus: http.StatusOK, + expectedBody: `["a","c"]`, + expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, + }, + { + name: "enabledonly-true-baseonly-true", + givenURL: "/info/bidders?enabledonly=true&baseadaptersonly=true", + expectedStatus: http.StatusOK, + expectedBody: `["a"]`, + expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, + }, } for _, test := range testCases { - handler := NewBiddersEndpoint(bidders, aliases) + t.Run(test.name, func(t *testing.T) { + handler := NewBiddersEndpoint(bidders, aliases) - request := httptest.NewRequest("GET", test.givenURL, nil) + request := httptest.NewRequest("GET", test.givenURL, nil) - responseRecorder := httptest.NewRecorder() - handler(responseRecorder, request, nil) + responseRecorder := httptest.NewRecorder() + handler(responseRecorder, request, nil) - result := responseRecorder.Result() - assert.Equal(t, result.StatusCode, test.expectedStatus) + result := responseRecorder.Result() + assert.Equal(t, result.StatusCode, test.expectedStatus) - resultBody, _ := io.ReadAll(result.Body) - assert.Equal(t, []byte(test.expectedBody), resultBody) + resultBody, _ := io.ReadAll(result.Body) + assert.Equal(t, []byte(test.expectedBody), resultBody) - resultHeaders := result.Header - assert.Equal(t, test.expectedHeaders, resultHeaders) + resultHeaders := result.Header + assert.Equal(t, test.expectedHeaders, resultHeaders) + }) } } From b96e2f785b7a120da448361df5708f12a7fe53ba Mon Sep 17 00:00:00 2001 From: AlexBVolcy <74930484+AlexBVolcy@users.noreply.github.com> Date: Tue, 19 Sep 2023 11:14:20 -0700 Subject: [PATCH 122/268] Priority Bidder Ejection (#2952) * Priority Bidder Code * Tweak Priority Ejector to update pri groups * Fallback Ejector * Opt out non prioity key support for oldest ejector * Simplified removeElementFromPriorityGroup * Add ejector specific tests * Ejector refactor, remove fallback, add tests * Fix validate merge fail * Address comments * Update IsSyncerPriority, update Pri Ejector * Update ejector logic * Implement TieEjector logic * Minor tweaks * Update IsSyncerPriority logic * One line update to pri ejector * Clean up, add tests * Sole element > MaxCookieSize edge case * Pass syncerByBidder, add new test * Return unaltered cookie and 200 * Just return 200 and warning, cookie unchanged --- config/config.go | 2 + config/usersync.go | 10 +- endpoints/cookie_sync.go | 3 +- endpoints/cookie_sync_test.go | 25 +- endpoints/setuid.go | 28 ++- endpoints/setuid_test.go | 212 +++++++++++++++- pbs/usersync.go | 3 +- router/router.go | 1 + usersync/cookie.go | 32 +-- usersync/cookie_test.go | 143 ++++++++--- usersync/ejector.go | 127 ++++++++++ usersync/ejector_test.go | 444 ++++++++++++++++++++++++++++++++++ 12 files changed, 943 insertions(+), 87 deletions(-) create mode 100644 usersync/ejector.go create mode 100644 usersync/ejector_test.go diff --git a/config/config.go b/config/config.go index e564c34ae3a..f503d0fcb59 100644 --- a/config/config.go +++ b/config/config.go @@ -944,6 +944,8 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { v.SetDefault("event.timeout_ms", 1000) + v.SetDefault("user_sync.priority_groups", [][]string{}) + v.SetDefault("accounts.filesystem.enabled", false) v.SetDefault("accounts.filesystem.directorypath", "./stored_requests/data/by_id") v.SetDefault("accounts.in_memory_cache.type", "none") diff --git a/config/usersync.go b/config/usersync.go index 27badbcb815..d490853d08e 100644 --- a/config/usersync.go +++ b/config/usersync.go @@ -2,13 +2,13 @@ package config // UserSync specifies the static global user sync configuration. type UserSync struct { - Cooperative UserSyncCooperative `mapstructure:"coop_sync"` - ExternalURL string `mapstructure:"external_url"` - RedirectURL string `mapstructure:"redirect_url"` + Cooperative UserSyncCooperative `mapstructure:"coop_sync"` + ExternalURL string `mapstructure:"external_url"` + RedirectURL string `mapstructure:"redirect_url"` + PriorityGroups [][]string `mapstructure:"priority_groups"` } // UserSyncCooperative specifies the static global default cooperative cookie sync type UserSyncCooperative struct { - EnabledByDefault bool `mapstructure:"default"` - PriorityGroups [][]string `mapstructure:"priority_groups"` + EnabledByDefault bool `mapstructure:"default"` } diff --git a/endpoints/cookie_sync.go b/endpoints/cookie_sync.go index 0a81c2d5e9c..250d5fd07d3 100644 --- a/endpoints/cookie_sync.go +++ b/endpoints/cookie_sync.go @@ -39,6 +39,7 @@ var ( errCookieSyncAccountBlocked = errors.New("account is disabled, please reach out to the prebid server host") errCookieSyncAccountConfigMalformed = errors.New("account config is malformed and could not be read") errCookieSyncAccountInvalid = errors.New("account must be valid if provided, please reach out to the prebid server host") + errSyncerIsNotPriority = errors.New("syncer key is not a priority, and there are only priority elements left") ) var cookieSyncBidderFilterAllowAll = usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude) @@ -168,7 +169,7 @@ func (c *cookieSyncEndpoint) parseRequest(r *http.Request) (usersync.Request, ma Bidders: request.Bidders, Cooperative: usersync.Cooperative{ Enabled: (request.CooperativeSync != nil && *request.CooperativeSync) || (request.CooperativeSync == nil && c.config.UserSync.Cooperative.EnabledByDefault), - PriorityGroups: c.config.UserSync.Cooperative.PriorityGroups, + PriorityGroups: c.config.UserSync.PriorityGroups, }, Limit: request.Limit, Privacy: usersyncPrivacy{ diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go index 68ab0ced44e..29fe74b273c 100644 --- a/endpoints/cookie_sync_test.go +++ b/endpoints/cookie_sync_test.go @@ -515,9 +515,9 @@ func TestCookieSyncParseRequest(t *testing.T) { givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, givenCCPAEnabled: true, givenConfig: config.UserSync{ + PriorityGroups: [][]string{{"a", "b", "c"}}, Cooperative: config.UserSyncCooperative{ EnabledByDefault: false, - PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, expectedPrivacy: macros.UserSyncPrivacy{ @@ -557,9 +557,9 @@ func TestCookieSyncParseRequest(t *testing.T) { givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, givenCCPAEnabled: true, givenConfig: config.UserSync{ + PriorityGroups: [][]string{{"a", "b", "c"}}, Cooperative: config.UserSyncCooperative{ EnabledByDefault: false, - PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, expectedPrivacy: macros.UserSyncPrivacy{ @@ -608,9 +608,9 @@ func TestCookieSyncParseRequest(t *testing.T) { givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, givenCCPAEnabled: true, givenConfig: config.UserSync{ + PriorityGroups: [][]string{{"a", "b", "c"}}, Cooperative: config.UserSyncCooperative{ EnabledByDefault: true, - PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, expectedPrivacy: macros.UserSyncPrivacy{}, @@ -635,9 +635,9 @@ func TestCookieSyncParseRequest(t *testing.T) { givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, givenCCPAEnabled: true, givenConfig: config.UserSync{ + PriorityGroups: [][]string{{"a", "b", "c"}}, Cooperative: config.UserSyncCooperative{ EnabledByDefault: false, - PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, expectedPrivacy: macros.UserSyncPrivacy{}, @@ -662,9 +662,9 @@ func TestCookieSyncParseRequest(t *testing.T) { givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, givenCCPAEnabled: true, givenConfig: config.UserSync{ + PriorityGroups: [][]string{{"a", "b", "c"}}, Cooperative: config.UserSyncCooperative{ EnabledByDefault: true, - PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, expectedPrivacy: macros.UserSyncPrivacy{}, @@ -689,9 +689,9 @@ func TestCookieSyncParseRequest(t *testing.T) { givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, givenCCPAEnabled: true, givenConfig: config.UserSync{ + PriorityGroups: [][]string{{"a", "b", "c"}}, Cooperative: config.UserSyncCooperative{ EnabledByDefault: false, - PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, expectedPrivacy: macros.UserSyncPrivacy{}, @@ -716,9 +716,9 @@ func TestCookieSyncParseRequest(t *testing.T) { givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, givenCCPAEnabled: true, givenConfig: config.UserSync{ + PriorityGroups: [][]string{{"a", "b", "c"}}, Cooperative: config.UserSyncCooperative{ EnabledByDefault: true, - PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, expectedPrivacy: macros.UserSyncPrivacy{}, @@ -743,9 +743,9 @@ func TestCookieSyncParseRequest(t *testing.T) { givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, givenCCPAEnabled: true, givenConfig: config.UserSync{ + PriorityGroups: [][]string{{"a", "b", "c"}}, Cooperative: config.UserSyncCooperative{ EnabledByDefault: false, - PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, expectedPrivacy: macros.UserSyncPrivacy{}, @@ -890,9 +890,8 @@ func TestCookieSyncParseRequest(t *testing.T) { givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, givenCCPAEnabled: true, givenConfig: config.UserSync{ - Cooperative: config.UserSyncCooperative{ - PriorityGroups: [][]string{{"a", "b", "c"}}, - }, + PriorityGroups: [][]string{{"a", "b", "c"}}, + Cooperative: config.UserSyncCooperative{}, }, expectedPrivacy: macros.UserSyncPrivacy{}, expectedRequest: usersync.Request{ @@ -921,9 +920,9 @@ func TestCookieSyncParseRequest(t *testing.T) { givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, givenCCPAEnabled: true, givenConfig: config.UserSync{ + PriorityGroups: [][]string{{"a", "b", "c"}}, Cooperative: config.UserSyncCooperative{ EnabledByDefault: false, - PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, expectedPrivacy: macros.UserSyncPrivacy{}, @@ -953,9 +952,9 @@ func TestCookieSyncParseRequest(t *testing.T) { givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, givenCCPAEnabled: true, givenConfig: config.UserSync{ + PriorityGroups: [][]string{{"a", "b", "c"}}, Cooperative: config.UserSyncCooperative{ EnabledByDefault: false, - PriorityGroups: [][]string{{"a", "b", "c"}}, }, }, expectedPrivacy: macros.UserSyncPrivacy{}, diff --git a/endpoints/setuid.go b/endpoints/setuid.go index 83425789647..520a133b51e 100644 --- a/endpoints/setuid.go +++ b/endpoints/setuid.go @@ -158,11 +158,22 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use setSiteCookie := siteCookieCheck(r.UserAgent()) + // Priority Ejector Set Up + priorityEjector := &usersync.PriorityBidderEjector{PriorityGroups: cfg.UserSync.PriorityGroups, TieEjector: &usersync.OldestEjector{}, SyncersByBidder: syncersByBidder} + priorityEjector.IsSyncerPriority = isSyncerPriority(bidderName, cfg.UserSync.PriorityGroups) + // Write Cookie - encodedCookie, err := cookie.PrepareCookieForWrite(&cfg.HostCookie, encoder) + encodedCookie, err := cookie.PrepareCookieForWrite(&cfg.HostCookie, encoder, priorityEjector) if err != nil { - handleBadStatus(w, http.StatusBadRequest, metrics.SetUidBadRequest, err, metricsEngine, &so) - return + if err.Error() == errSyncerIsNotPriority.Error() { + w.WriteHeader(http.StatusOK) + w.Write([]byte("Warning: " + err.Error() + ", cookie not updated")) + so.Status = http.StatusOK + return + } else { + handleBadStatus(w, http.StatusBadRequest, metrics.SetUidBadRequest, err, metricsEngine, &so) + return + } } usersync.WriteCookie(w, encodedCookie, &cfg.HostCookie, setSiteCookie) @@ -326,6 +337,17 @@ func getSyncer(query url.Values, syncersByBidder map[string]usersync.Syncer) (us return syncer, bidder, nil } +func isSyncerPriority(bidderNameFromSyncerQuery string, priorityGroups [][]string) bool { + for _, group := range priorityGroups { + for _, bidder := range group { + if bidderNameFromSyncerQuery == bidder { + return true + } + } + } + return false +} + // getResponseFormat reads the format query parameter or falls back to the syncer's default. // Returns either "b" (iframe), "i" (redirect), or an empty string "" (legacy behavior of an // empty response body with no content type). diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go index 4f37eb77f8f..897538c35e5 100644 --- a/endpoints/setuid_test.go +++ b/endpoints/setuid_test.go @@ -8,6 +8,7 @@ import ( "net/http/httptest" "net/url" "regexp" + "strings" "testing" "time" @@ -332,7 +333,7 @@ func TestSetUIDEndpoint(t *testing.T) { for _, test := range testCases { response := doRequest(makeRequest(test.uri, test.existingSyncs), analytics, metrics, - test.syncersBidderNameToKey, test.gdprAllowsHostCookies, test.gdprReturnsError, test.gdprMalformed, false) + test.syncersBidderNameToKey, test.gdprAllowsHostCookies, test.gdprReturnsError, test.gdprMalformed, false, 0, nil) assert.Equal(t, test.expectedStatusCode, response.Code, "Test Case: %s. /setuid returned unexpected error code", test.description) if test.expectedSyncs != nil { @@ -359,6 +360,135 @@ func TestSetUIDEndpoint(t *testing.T) { } } +func TestSetUIDPriorityEjection(t *testing.T) { + decoder := usersync.Base64Decoder{} + analytics := analyticsConf.NewPBSAnalytics(&config.Analytics{}) + syncersByBidder := map[string]string{ + "pubmatic": "pubmatic", + "syncer1": "syncer1", + "syncer2": "syncer2", + "syncer3": "syncer3", + "syncer4": "syncer4", + "mismatchedBidderName": "syncer5", + "syncerToEject": "syncerToEject", + } + + testCases := []struct { + description string + uri string + givenExistingSyncs []string + givenPriorityGroups [][]string + givenMaxCookieSize int + expectedStatusCode int + expectedSyncer string + expectedUID string + expectedNumOfElements int + expectedWarning string + }{ + { + description: "Cookie empty, expect bidder to be synced, no ejection", + uri: "/setuid?bidder=pubmatic&uid=123", + givenPriorityGroups: [][]string{}, + givenMaxCookieSize: 500, + expectedSyncer: "pubmatic", + expectedUID: "123", + expectedNumOfElements: 1, + expectedStatusCode: http.StatusOK, + }, + { + description: "Cookie full, no priority groups, one ejection", + uri: "/setuid?bidder=pubmatic&uid=123", + givenExistingSyncs: []string{"syncer1", "syncer2", "syncer3", "syncer4"}, + givenPriorityGroups: [][]string{}, + givenMaxCookieSize: 500, + expectedUID: "123", + expectedSyncer: "pubmatic", + expectedNumOfElements: 4, + expectedStatusCode: http.StatusOK, + }, + { + description: "Cookie full, eject lowest priority element", + uri: "/setuid?bidder=pubmatic&uid=123", + givenExistingSyncs: []string{"syncer2", "syncer3", "syncer4", "syncerToEject"}, + givenPriorityGroups: [][]string{{"pubmatic", "syncer2", "syncer3", "syncer4"}, {"syncerToEject"}}, + givenMaxCookieSize: 500, + expectedUID: "123", + expectedSyncer: "pubmatic", + expectedNumOfElements: 4, + expectedStatusCode: http.StatusOK, + }, + { + description: "Cookie full, all elements same priority, one ejection", + uri: "/setuid?bidder=pubmatic&uid=123", + givenExistingSyncs: []string{"syncer1", "syncer2", "syncer3", "syncer5"}, + givenPriorityGroups: [][]string{{"pubmatic", "syncer1", "syncer2", "syncer3", "mismatchedBidderName"}}, + givenMaxCookieSize: 500, + expectedUID: "123", + expectedSyncer: "pubmatic", + expectedNumOfElements: 4, + expectedStatusCode: http.StatusOK, + }, + { + description: "There are only priority elements left, but the bidder being synced isn't one", + uri: "/setuid?bidder=pubmatic&uid=123", + givenExistingSyncs: []string{"syncer1", "syncer2", "syncer3", "syncer4"}, + givenPriorityGroups: [][]string{{"syncer1", "syncer2", "syncer3", "syncer4"}}, + givenMaxCookieSize: 500, + expectedStatusCode: http.StatusOK, + expectedWarning: "Warning: syncer key is not a priority, and there are only priority elements left, cookie not updated", + }, + { + description: "Uid that's trying to be synced is bigger than MaxCookieSize", + uri: "/setuid?bidder=pubmatic&uid=123", + givenMaxCookieSize: 1, + expectedStatusCode: http.StatusBadRequest, + }, + } + for _, test := range testCases { + request := httptest.NewRequest("GET", test.uri, nil) + + // Cookie Set Up + cookie := usersync.NewCookie() + for _, key := range test.givenExistingSyncs { + cookie.Sync(key, "111") + } + httpCookie, err := ToHTTPCookie(cookie) + assert.NoError(t, err) + request.AddCookie(httpCookie) + + // Make Request to /setuid + response := doRequest(request, analytics, &metricsConf.NilMetricsEngine{}, syncersByBidder, true, false, false, false, test.givenMaxCookieSize, test.givenPriorityGroups) + + if test.expectedWarning != "" { + assert.Equal(t, test.expectedWarning, response.Body.String(), test.description) + } else if test.expectedSyncer != "" { + // Get Cookie From Header + var cookieHeader string + for k, v := range response.Result().Header { + if k == "Set-Cookie" { + cookieHeader = v[0] + } + } + encodedCookieValue := getUIDFromHeader(cookieHeader) + + // Check That Bidder On Request was Synced, it's UID matches, and that the right number of elements are present after ejection + decodedCookie := decoder.Decode(encodedCookieValue) + decodedCookieUIDs := decodedCookie.GetUIDs() + + assert.Equal(t, test.expectedUID, decodedCookieUIDs[test.expectedSyncer], test.description) + assert.Equal(t, test.expectedNumOfElements, len(decodedCookieUIDs), test.description) + + // Specific test case handling where we eject the lowest priority element + if len(test.givenPriorityGroups) == 2 { + syncer := test.givenPriorityGroups[len(test.givenPriorityGroups)-1][0] + _, syncerExists := decodedCookieUIDs[syncer] + assert.False(t, syncerExists, test.description) + } + } + assert.Equal(t, test.expectedStatusCode, response.Result().StatusCode, test.description) + } +} + func TestParseSignalFromGPPSID(t *testing.T) { type testOutput struct { signal gdpr.Signal @@ -1214,7 +1344,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { for _, v := range test.cookies { addCookie(req, v) } - response := doRequest(req, analyticsEngine, metricsEngine, test.syncersBidderNameToKey, test.gdprAllowsHostCookies, false, false, test.cfgAccountRequired) + response := doRequest(req, analyticsEngine, metricsEngine, test.syncersBidderNameToKey, test.gdprAllowsHostCookies, false, false, test.cfgAccountRequired, 0, nil) assert.Equal(t, test.expectedResponseCode, response.Code, test.description) analyticsEngine.AssertExpectations(t) @@ -1230,7 +1360,7 @@ func TestOptedOut(t *testing.T) { syncersBidderNameToKey := map[string]string{"pubmatic": "pubmatic"} analytics := analyticsConf.NewPBSAnalytics(&config.Analytics{}) metrics := &metricsConf.NilMetricsEngine{} - response := doRequest(request, analytics, metrics, syncersBidderNameToKey, true, false, false, false) + response := doRequest(request, analytics, metrics, syncersBidderNameToKey, true, false, false, false, 0, nil) assert.Equal(t, http.StatusUnauthorized, response.Code) } @@ -1341,6 +1471,56 @@ func TestGetResponseFormat(t *testing.T) { } } +func TestIsSyncerPriority(t *testing.T) { + testCases := []struct { + name string + givenBidderNameFromSyncerQuery string + givenPriorityGroups [][]string + expected bool + }{ + { + name: "bidder-name-is-priority", + givenBidderNameFromSyncerQuery: "priorityBidder", + givenPriorityGroups: [][]string{ + {"priorityBidder"}, + {"2", "3"}, + }, + expected: true, + }, + { + name: "bidder-name-is-not-priority", + givenBidderNameFromSyncerQuery: "notPriorityBidderName", + givenPriorityGroups: [][]string{ + {"1"}, + {"2", "3"}, + }, + expected: false, + }, + { + name: "no-bidder-name-given", + givenBidderNameFromSyncerQuery: "", + givenPriorityGroups: [][]string{ + {"1"}, + {"2", "3"}, + }, + expected: false, + }, + { + name: "no-priority-groups-given", + givenBidderNameFromSyncerQuery: "bidderName", + givenPriorityGroups: [][]string{}, + expected: false, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + isPriority := isSyncerPriority(test.givenBidderNameFromSyncerQuery, test.givenPriorityGroups) + assert.Equal(t, test.expected, isPriority) + }) + } +} + func assertHasSyncs(t *testing.T, testCase string, resp *httptest.ResponseRecorder, syncs map[string]string) { t.Helper() cookie := parseCookieString(t, resp) @@ -1366,13 +1546,19 @@ func makeRequest(uri string, existingSyncs map[string]string) *http.Request { return request } -func doRequest(req *http.Request, analytics analytics.PBSAnalyticsModule, metrics metrics.MetricsEngine, syncersBidderNameToKey map[string]string, gdprAllowsHostCookies, gdprReturnsError, gdprReturnsMalformedError, cfgAccountRequired bool) *httptest.ResponseRecorder { +func doRequest(req *http.Request, analytics analytics.PBSAnalyticsModule, metrics metrics.MetricsEngine, syncersBidderNameToKey map[string]string, gdprAllowsHostCookies, gdprReturnsError, gdprReturnsMalformedError, cfgAccountRequired bool, maxCookieSize int, priorityGroups [][]string) *httptest.ResponseRecorder { cfg := config.Configuration{ AccountRequired: cfgAccountRequired, BlacklistedAcctMap: map[string]bool{ "blocked_acct": true, }, AccountDefaults: config.Account{}, + UserSync: config.UserSync{ + PriorityGroups: priorityGroups, + }, + HostCookie: config.HostCookie{ + MaxCookieSizeBytes: maxCookieSize, + }, } cfg.MarshalAccountDefaults() @@ -1395,6 +1581,10 @@ func doRequest(req *http.Request, analytics analytics.PBSAnalyticsModule, metric syncersByBidder := make(map[string]usersync.Syncer) for bidderName, syncerKey := range syncersBidderNameToKey { syncersByBidder[bidderName] = fakeSyncer{key: syncerKey, defaultSyncType: usersync.SyncTypeIFrame} + if priorityGroups == nil { + cfg.UserSync.PriorityGroups = [][]string{{}} + cfg.UserSync.PriorityGroups[0] = append(cfg.UserSync.PriorityGroups[0], bidderName) + } } fakeAccountsFetcher := FakeAccountsFetcher{AccountData: map[string]json.RawMessage{ @@ -1513,3 +1703,17 @@ func ToHTTPCookie(cookie *usersync.Cookie) (*http.Cookie, error) { Path: "/", }, nil } + +func getUIDFromHeader(setCookieHeader string) string { + cookies := strings.Split(setCookieHeader, ";") + for _, cookie := range cookies { + trimmedCookie := strings.TrimSpace(cookie) + if strings.HasPrefix(trimmedCookie, "uids=") { + parts := strings.SplitN(trimmedCookie, "=", 2) + if len(parts) == 2 { + return parts[1] + } + } + } + return "" +} diff --git a/pbs/usersync.go b/pbs/usersync.go index 7b468cb039d..a5b49f6db03 100644 --- a/pbs/usersync.go +++ b/pbs/usersync.go @@ -22,6 +22,7 @@ type UserSyncDeps struct { ExternalUrl string RecaptchaSecret string HostCookieConfig *config.HostCookie + PriorityGroups [][]string } // Struct for parsing json in google's response @@ -81,7 +82,7 @@ func (deps *UserSyncDeps) OptOut(w http.ResponseWriter, r *http.Request, _ httpr pc.SetOptOut(optout != "") // Write Cookie - encodedCookie, err := pc.PrepareCookieForWrite(deps.HostCookieConfig, encoder) + encodedCookie, err := encoder.Encode(pc) if err != nil { w.WriteHeader(http.StatusBadRequest) return diff --git a/router/router.go b/router/router.go index f7270445ff4..f2b1f7e7447 100644 --- a/router/router.go +++ b/router/router.go @@ -274,6 +274,7 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R HostCookieConfig: &(cfg.HostCookie), ExternalUrl: cfg.ExternalURL, RecaptchaSecret: cfg.RecaptchaSecret, + PriorityGroups: cfg.UserSync.PriorityGroups, } r.GET("/setuid", endpoints.NewSetUIDEndpoint(cfg, syncersByBidder, gdprPermsBuilder, tcf2CfgBuilder, pbsAnalytics, accounts, r.MetricsEngine)) diff --git a/usersync/cookie.go b/usersync/cookie.go index c0eb898c5ea..94ada94ed75 100644 --- a/usersync/cookie.go +++ b/usersync/cookie.go @@ -4,7 +4,6 @@ import ( "encoding/json" "errors" "net/http" - "sort" "time" "github.com/prebid/prebid-server/config" @@ -58,10 +57,7 @@ func ReadCookie(r *http.Request, decoder Decoder, host *config.HostCookie) *Cook } // PrepareCookieForWrite ejects UIDs as long as the cookie is too full -func (cookie *Cookie) PrepareCookieForWrite(cfg *config.HostCookie, encoder Encoder) (string, error) { - uuidKeys := sortUIDs(cookie.uids) - - i := 0 +func (cookie *Cookie) PrepareCookieForWrite(cfg *config.HostCookie, encoder Encoder, ejector Ejector) (string, error) { for len(cookie.uids) > 0 { encodedCookie, err := encoder.Encode(cookie) if err != nil { @@ -80,12 +76,15 @@ func (cookie *Cookie) PrepareCookieForWrite(cfg *config.HostCookie, encoder Enco isCookieTooBig := cookieSize > cfg.MaxCookieSizeBytes && cfg.MaxCookieSizeBytes > 0 if !isCookieTooBig { return encodedCookie, nil + } else if len(cookie.uids) == 1 { + return "", errors.New("uid that's trying to be synced is bigger than MaxCookieSize") } - uidToDelete := uuidKeys[i] + uidToDelete, err := ejector.Choose(cookie.uids) + if err != nil { + return encodedCookie, err + } delete(cookie.uids, uidToDelete) - - i++ } return "", nil } @@ -132,23 +131,6 @@ func (cookie *Cookie) Sync(key string, uid string) error { return nil } -// sortUIDs is used to get a list of uids sorted from oldest to newest -// This list is used to eject oldest uids from the cookie -// This will be incorporated with a more complex ejection framework in a future PR -func sortUIDs(uids map[string]UIDEntry) []string { - if len(uids) > 0 { - uuidKeys := make([]string, 0, len(uids)) - for key := range uids { - uuidKeys = append(uuidKeys, key) - } - sort.SliceStable(uuidKeys, func(i, j int) bool { - return uids[uuidKeys[i]].Expires.Before(uids[uuidKeys[j]].Expires) - }) - return uuidKeys - } - return nil -} - // SyncHostCookie syncs the request cookie with the host cookie func SyncHostCookie(r *http.Request, requestCookie *Cookie, host *config.HostCookie) { if uid, _, _ := requestCookie.GetUID(host.Family); uid == "" && host.CookieName != "" { diff --git a/usersync/cookie_test.go b/usersync/cookie_test.go index 5b86df54441..340069767b1 100644 --- a/usersync/cookie_test.go +++ b/usersync/cookie_test.go @@ -380,82 +380,155 @@ func TestWriteCookieUserAgent(t *testing.T) { func TestPrepareCookieForWrite(t *testing.T) { encoder := Base64Encoder{} decoder := Base64Decoder{} - cookieToSend := &Cookie{ + + mainCookie := &Cookie{ + uids: map[string]UIDEntry{ + "mainUID": newTempId("1234567890123456789012345678901234567890123456", 7), + "2": newTempId("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 6), + "3": newTempId("123456789012345678901234567896123456789012345678", 5), + "4": newTempId("aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ", 4), + "5": newTempId("12345678901234567890123456789012345678901234567890", 3), + "6": newTempId("abcdefghij", 2), + "7": newTempId("abcdefghijklmnopqrstuvwxy", 1), + }, + optOut: false, + } + + errorCookie := &Cookie{ uids: map[string]UIDEntry{ - "1": newTempId("1234567890123456789012345678901234567890123456", 7), - "7": newTempId("abcdefghijklmnopqrstuvwxy", 1), - "2": newTempId("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 6), - "3": newTempId("123456789012345678901234567896123456789012345678", 5), - "4": newTempId("aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ", 4), - "5": newTempId("12345678901234567890123456789012345678901234567890", 3), - "6": newTempId("abcdefghij", 2), + "syncerNotPriority": newTempId("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 7), + "2": newTempId("1234567890123456789012345678901234567890123456", 7), // Priority Element }, optOut: false, } + ejector := &PriorityBidderEjector{ + PriorityGroups: [][]string{ + {"mainUID"}, + {"2", "3"}, + {"4", "5", "6"}, + {"7"}, + }, + SyncersByBidder: map[string]Syncer{ + "mainUID": fakeSyncer{ + key: "mainUID", + }, + "2": fakeSyncer{ + key: "2", + }, + "3": fakeSyncer{ + key: "3", + }, + "4": fakeSyncer{ + key: "4", + }, + "5": fakeSyncer{ + key: "5", + }, + "6": fakeSyncer{ + key: "6", + }, + "mistmatchedBidder": fakeSyncer{ + key: "7", + }, + }, + TieEjector: &OldestEjector{}, + } + testCases := []struct { name string givenMaxCookieSize int + givenCookieToSend *Cookie + givenIsSyncerPriority bool expectedRemainingUidKeys []string + expectedError error }{ { - name: "no-uids-ejected", - givenMaxCookieSize: 2000, + name: "no-uids-ejected", + givenMaxCookieSize: 2000, + givenCookieToSend: mainCookie, + givenIsSyncerPriority: true, expectedRemainingUidKeys: []string{ - "1", "2", "3", "4", "5", "6", "7", + "mainUID", "2", "3", "4", "5", "6", "7", }, }, { - name: "no-uids-ejected-2", - givenMaxCookieSize: 0, + name: "invalid-max-size", + givenMaxCookieSize: -100, + givenCookieToSend: mainCookie, expectedRemainingUidKeys: []string{ - "1", "2", "3", "4", "5", "6", "7", + "mainUID", "2", "3", "4", "5", "6", "7", }, }, { - name: "one-uid-ejected", - givenMaxCookieSize: 900, + name: "syncer-is-not-priority", + givenMaxCookieSize: 100, + givenCookieToSend: errorCookie, + givenIsSyncerPriority: false, + expectedError: errors.New("syncer key is not a priority, and there are only priority elements left"), + }, + { + name: "no-uids-ejected-2", + givenMaxCookieSize: 0, + givenCookieToSend: mainCookie, + givenIsSyncerPriority: true, expectedRemainingUidKeys: []string{ - "1", "2", "3", "4", "5", "6", + "mainUID", "2", "3", "4", "5", "6", "7", }, }, { - name: "four-uids-ejected", - givenMaxCookieSize: 500, + name: "one-uid-ejected", + givenMaxCookieSize: 900, + givenCookieToSend: mainCookie, + givenIsSyncerPriority: true, expectedRemainingUidKeys: []string{ - "1", "2", "3", + "mainUID", "2", "3", "4", "5", "6", }, }, { - name: "all-but-one-uids-ejected", - givenMaxCookieSize: 300, + name: "four-uids-ejected", + givenMaxCookieSize: 500, + givenCookieToSend: mainCookie, + givenIsSyncerPriority: true, expectedRemainingUidKeys: []string{ - "1", + "mainUID", "2", "3", }, }, { - name: "all-uids-ejected", - givenMaxCookieSize: 100, - expectedRemainingUidKeys: []string{}, + name: "all-but-one-uids-ejected", + givenMaxCookieSize: 300, + givenCookieToSend: mainCookie, + givenIsSyncerPriority: true, + expectedRemainingUidKeys: []string{ + "mainUID", + }, }, { - name: "invalid-max-size", - givenMaxCookieSize: -100, + name: "only-main-uid-left", + givenMaxCookieSize: 100, + givenCookieToSend: mainCookie, + expectedError: errors.New("uid that's trying to be synced is bigger than MaxCookieSize"), expectedRemainingUidKeys: []string{}, }, } for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - encodedCookie, err := cookieToSend.PrepareCookieForWrite(&config.HostCookie{MaxCookieSizeBytes: test.givenMaxCookieSize}, encoder) - assert.NoError(t, err) - decodedCookie := decoder.Decode(encodedCookie) + ejector.IsSyncerPriority = test.givenIsSyncerPriority + encodedCookie, err := test.givenCookieToSend.PrepareCookieForWrite(&config.HostCookie{MaxCookieSizeBytes: test.givenMaxCookieSize}, encoder, ejector) + + if test.expectedError != nil { + assert.Equal(t, test.expectedError, err) + } else { + assert.NoError(t, err) + decodedCookie := decoder.Decode(encodedCookie) - for _, key := range test.expectedRemainingUidKeys { - _, ok := decodedCookie.uids[key] - assert.Equal(t, true, ok) + for _, key := range test.expectedRemainingUidKeys { + _, ok := decodedCookie.uids[key] + assert.Equal(t, true, ok) + } + assert.Equal(t, len(decodedCookie.uids), len(test.expectedRemainingUidKeys)) } - assert.Equal(t, len(decodedCookie.uids), len(test.expectedRemainingUidKeys)) }) } } diff --git a/usersync/ejector.go b/usersync/ejector.go new file mode 100644 index 00000000000..84299f72c12 --- /dev/null +++ b/usersync/ejector.go @@ -0,0 +1,127 @@ +package usersync + +import ( + "errors" + "time" +) + +type Ejector interface { + Choose(uids map[string]UIDEntry) (string, error) +} + +type OldestEjector struct{} + +type PriorityBidderEjector struct { + PriorityGroups [][]string + SyncersByBidder map[string]Syncer + IsSyncerPriority bool + TieEjector Ejector +} + +// Choose method for oldest ejector will return the oldest uid +func (o *OldestEjector) Choose(uids map[string]UIDEntry) (string, error) { + var oldestElement string + var oldestDate time.Time = time.Unix(1<<63-62135596801, 999999999) // Max value for time + + for key, value := range uids { + if value.Expires.Before(oldestDate) { + oldestElement = key + oldestDate = value.Expires + } + } + return oldestElement, nil +} + +// Choose method for priority ejector will return the oldest lowest priority element +func (p *PriorityBidderEjector) Choose(uids map[string]UIDEntry) (string, error) { + nonPriorityUids := getNonPriorityUids(uids, p.PriorityGroups, p.SyncersByBidder) + if err := p.checkSyncerPriority(nonPriorityUids); err != nil { + return "", err + } + + if len(nonPriorityUids) > 0 { + return p.TieEjector.Choose(nonPriorityUids) + } + + lowestPriorityGroup := p.PriorityGroups[len(p.PriorityGroups)-1] + if len(lowestPriorityGroup) == 1 { + uidToDelete := lowestPriorityGroup[0] + p.PriorityGroups = removeElementFromPriorityGroup(p.PriorityGroups, uidToDelete) + return uidToDelete, nil + } + + lowestPriorityUids := getPriorityUids(lowestPriorityGroup, uids, p.SyncersByBidder) + uidToDelete, err := p.TieEjector.Choose(lowestPriorityUids) + if err != nil { + return "", err + } + p.PriorityGroups = removeElementFromPriorityGroup(p.PriorityGroups, uidToDelete) + return uidToDelete, nil +} + +// updatePriorityGroup will remove the selected element from the priority groups, and will remove the entire priority group if it's empty +func removeElementFromPriorityGroup(priorityGroups [][]string, oldestElement string) [][]string { + lowestPriorityGroup := priorityGroups[len(priorityGroups)-1] + if len(lowestPriorityGroup) <= 1 { + return priorityGroups[:len(priorityGroups)-1] + } + + for index, elem := range lowestPriorityGroup { + if elem == oldestElement { + updatedPriorityGroup := append(lowestPriorityGroup[:index], lowestPriorityGroup[index+1:]...) + priorityGroups[len(priorityGroups)-1] = updatedPriorityGroup + return priorityGroups + } + } + return priorityGroups +} + +func getNonPriorityUids(uids map[string]UIDEntry, priorityGroups [][]string, syncersByBidder map[string]Syncer) map[string]UIDEntry { + // If no priority groups, then all keys in uids are non-priority + if len(priorityGroups) == 0 { + return uids + } + + // Create map of keys that are a priority + isPriority := make(map[string]bool) + for _, group := range priorityGroups { + for _, bidder := range group { + if bidderSyncer, ok := syncersByBidder[bidder]; ok { + isPriority[bidderSyncer.Key()] = true + } + } + } + + // Create a map for non-priority uids + nonPriorityUIDs := make(map[string]UIDEntry) + + // Loop over uids and populate the nonPriorityUIDs map with non-priority keys + for key, value := range uids { + if _, found := isPriority[key]; !found { + nonPriorityUIDs[key] = value + } + } + + return nonPriorityUIDs +} + +func getPriorityUids(lowestPriorityGroup []string, uids map[string]UIDEntry, syncersByBidder map[string]Syncer) map[string]UIDEntry { + lowestPriorityUIDs := make(map[string]UIDEntry) + + // Loop over lowestPriorityGroup and populate the lowestPriorityUIDs map + for _, bidder := range lowestPriorityGroup { + if bidderSyncer, ok := syncersByBidder[bidder]; ok { + if uidEntry, exists := uids[bidderSyncer.Key()]; exists { + lowestPriorityUIDs[bidderSyncer.Key()] = uidEntry + } + } + } + return lowestPriorityUIDs +} + +func (p *PriorityBidderEjector) checkSyncerPriority(nonPriorityUids map[string]UIDEntry) error { + if len(nonPriorityUids) == 1 && !p.IsSyncerPriority && len(p.PriorityGroups) > 0 { + return errors.New("syncer key is not a priority, and there are only priority elements left") + } + return nil +} diff --git a/usersync/ejector_test.go b/usersync/ejector_test.go new file mode 100644 index 00000000000..d13e7484b40 --- /dev/null +++ b/usersync/ejector_test.go @@ -0,0 +1,444 @@ +package usersync + +import ( + "errors" + "reflect" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestPriorityEjector(t *testing.T) { + testCases := []struct { + name string + givenUids map[string]UIDEntry + givenEjector Ejector + expected string + expectedError error + }{ + { + name: "one-lowest-priority-element", + givenUids: map[string]UIDEntry{ + "highestPrioritySyncer": { + UID: "123", + Expires: time.Now().Add((90 * 24 * time.Hour)), + }, + "lowestPriority": { + UID: "456", + Expires: time.Now(), + }, + }, + givenEjector: &PriorityBidderEjector{ + PriorityGroups: [][]string{ + {"highestPriorityBidder"}, + {"lowestPriority"}, + }, + SyncersByBidder: map[string]Syncer{ + "highestPriorityBidder": fakeSyncer{ + key: "highestPrioritySyncer", + }, + "lowestPriority": fakeSyncer{ + key: "lowestPriority", + }, + }, + IsSyncerPriority: true, + }, + expected: "lowestPriority", + }, + { + name: "multiple-uids-same-priority", + givenUids: map[string]UIDEntry{ + "newerButSamePriority": { + UID: "123", + Expires: time.Now().Add((90 * 24 * time.Hour)), + }, + "olderButSamePriority": { + UID: "456", + Expires: time.Now(), + }, + }, + givenEjector: &PriorityBidderEjector{ + PriorityGroups: [][]string{ + {"newerButSamePriority", "olderButSamePriority"}, + }, + SyncersByBidder: map[string]Syncer{ + "newerButSamePriority": fakeSyncer{ + key: "newerButSamePriority", + }, + "olderButSamePriority": fakeSyncer{ + key: "olderButSamePriority", + }, + }, + IsSyncerPriority: true, + TieEjector: &OldestEjector{}, + }, + expected: "olderButSamePriority", + }, + { + name: "non-priority-uids-present", + givenUids: map[string]UIDEntry{ + "higherPriority": { + UID: "123", + Expires: time.Now().Add((90 * 24 * time.Hour)), + }, + "lowestPriority": { + UID: "456", + Expires: time.Now(), + }, + "oldestNonPriority": { + UID: "456", + Expires: time.Now(), + }, + "newestNonPriority": { + UID: "123", + Expires: time.Now().Add((90 * 24 * time.Hour)), + }, + }, + givenEjector: &PriorityBidderEjector{ + PriorityGroups: [][]string{ + {"higherPriority"}, + {"lowestPriority"}, + }, + SyncersByBidder: map[string]Syncer{ + "higherPriority": fakeSyncer{ + key: "higherPriority", + }, + "lowestPriority": fakeSyncer{ + key: "lowestPriority", + }, + "oldestNonPriority": fakeSyncer{ + key: "oldestNonPriority", + }, + "newestNonPriority": fakeSyncer{ + key: "newestNonPriority", + }, + }, + IsSyncerPriority: true, + TieEjector: &OldestEjector{}, + }, + expected: "oldestNonPriority", + }, + { + name: "empty-priority-groups", + givenUids: map[string]UIDEntry{ + "oldestNonPriority": { + UID: "456", + Expires: time.Now(), + }, + "newestNonPriority": { + UID: "123", + Expires: time.Now().Add((90 * 24 * time.Hour)), + }, + }, + givenEjector: &PriorityBidderEjector{ + SyncersByBidder: map[string]Syncer{ + "oldestNonPriority": fakeSyncer{ + key: "oldestNonPriority", + }, + "newestNonPriority": fakeSyncer{ + key: "newestNonPriority", + }, + }, + IsSyncerPriority: false, + TieEjector: &OldestEjector{}, + }, + expected: "oldestNonPriority", + }, + { + name: "one-priority-element", + givenUids: map[string]UIDEntry{ + "onlyPriorityElement": { + UID: "123", + Expires: time.Now().Add((90 * 24 * time.Hour)), + }, + }, + givenEjector: &PriorityBidderEjector{ + PriorityGroups: [][]string{ + {"onlyPriorityElement"}, + }, + SyncersByBidder: map[string]Syncer{ + "onlyPriorityElement": fakeSyncer{ + key: "onlyPriorityElement", + }, + }, + IsSyncerPriority: true, + }, + expected: "onlyPriorityElement", + }, + { + name: "syncer-is-not-priority", + givenUids: map[string]UIDEntry{ + "onlyPriorityElement": { + UID: "123", + Expires: time.Now().Add((90 * 24 * time.Hour)), + }, + "syncer": { + UID: "456", + Expires: time.Now().Add((90 * 24 * time.Hour)), + }, + }, + givenEjector: &PriorityBidderEjector{ + PriorityGroups: [][]string{ + {"onlyPriorityElement"}, + }, + SyncersByBidder: map[string]Syncer{ + "onlyPriorityElement": fakeSyncer{ + key: "onlyPriorityElement", + }, + }, + IsSyncerPriority: false, + }, + expectedError: errors.New("syncer key is not a priority, and there are only priority elements left"), + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + uidToDelete, err := test.givenEjector.Choose(test.givenUids) + if test.expectedError != nil { + assert.Equal(t, test.expectedError, err) + } else { + assert.NoError(t, err) + assert.Equal(t, test.expected, uidToDelete) + } + }) + } +} + +func TestOldestEjector(t *testing.T) { + testCases := []struct { + name string + givenUids map[string]UIDEntry + expected string + }{ + { + name: "multiple-elements", + givenUids: map[string]UIDEntry{ + "newestElement": { + UID: "123", + Expires: time.Now().Add((90 * 24 * time.Hour)), + }, + "oldestElement": { + UID: "456", + Expires: time.Now(), + }, + }, + expected: "oldestElement", + }, + { + name: "one-element", + givenUids: map[string]UIDEntry{ + "onlyElement": { + UID: "123", + Expires: time.Now().Add((90 * 24 * time.Hour)), + }, + }, + expected: "onlyElement", + }, + { + name: "no-elements", + givenUids: map[string]UIDEntry{}, + expected: "", + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + ejector := OldestEjector{} + oldestElement, err := ejector.Choose(test.givenUids) + assert.NoError(t, err) + assert.Equal(t, test.expected, oldestElement) + }) + } +} + +func TestGetNonPriorityUids(t *testing.T) { + syncersByBidder := map[string]Syncer{ + "syncerKey1": fakeSyncer{ + key: "syncerKey1", + }, + "syncerKey2": fakeSyncer{ + key: "syncerKey2", + }, + "syncerKey3": fakeSyncer{ + key: "syncerKey3", + }, + } + + testCases := []struct { + name string + givenUids map[string]UIDEntry + givenPriorityGroups [][]string + expected map[string]UIDEntry + }{ + { + name: "one-priority-group", + givenUids: map[string]UIDEntry{ + "syncerKey1": { + UID: "123", + }, + "syncerKey2": { + UID: "456", + }, + "syncerKey3": { + UID: "789", + }, + }, + givenPriorityGroups: [][]string{ + {"syncerKey1"}, + }, + expected: map[string]UIDEntry{ + "syncerKey2": { + UID: "456", + }, + "syncerKey3": { + UID: "789", + }, + }, + }, + { + name: "multiple-priority-groups", + givenUids: map[string]UIDEntry{ + "syncerKey1": { + UID: "123", + }, + "syncerKey2": { + UID: "456", + }, + "syncerKey3": { + UID: "789", + }, + }, + givenPriorityGroups: [][]string{ + {"syncerKey1"}, + {"syncerKey2"}, + }, + expected: map[string]UIDEntry{ + "syncerKey3": { + UID: "789", + }, + }, + }, + { + name: "no-priority-groups", + givenUids: map[string]UIDEntry{ + "syncerKey1": { + UID: "123", + }, + "syncerKey2": { + UID: "456", + }, + "syncerKey3": { + UID: "789", + }, + }, + expected: map[string]UIDEntry{ + "syncerKey1": { + UID: "123", + }, + "syncerKey2": { + UID: "456", + }, + "syncerKey3": { + UID: "789", + }, + }, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + uids := getNonPriorityUids(test.givenUids, test.givenPriorityGroups, syncersByBidder) + assert.Equal(t, true, reflect.DeepEqual(test.expected, uids)) + }) + } +} + +func TestGetPriorityUids(t *testing.T) { + syncersByBidder := map[string]Syncer{ + "syncerKey1": fakeSyncer{ + key: "syncerKey1", + }, + "syncerKey2": fakeSyncer{ + key: "syncerKey2", + }, + "syncerKey3": fakeSyncer{ + key: "syncerKey3", + }, + } + + testCases := []struct { + name string + givenUids map[string]UIDEntry + givenLowestPriorityGroup []string + expected map[string]UIDEntry + }{ + { + name: "one-priority-element", + givenUids: map[string]UIDEntry{ + "syncerKey1": { + UID: "123", + }, + "syncerKey2": { + UID: "456", + }, + "syncerKey3": { + UID: "789", + }, + }, + givenLowestPriorityGroup: []string{"syncerKey1"}, + expected: map[string]UIDEntry{ + "syncerKey1": { + UID: "123", + }, + }, + }, + { + name: "multiple-priority-elements", + givenUids: map[string]UIDEntry{ + "syncerKey1": { + UID: "123", + }, + "syncerKey2": { + UID: "456", + }, + "syncerKey3": { + UID: "789", + }, + }, + givenLowestPriorityGroup: []string{"syncerKey1", "syncerKey2"}, + expected: map[string]UIDEntry{ + "syncerKey1": { + UID: "123", + }, + "syncerKey2": { + UID: "456", + }, + }, + }, + { + name: "no-priority-elements", + givenUids: map[string]UIDEntry{ + "syncerKey1": { + UID: "123", + }, + "syncerKey2": { + UID: "456", + }, + "syncerKey3": { + UID: "789", + }, + }, + givenLowestPriorityGroup: []string{}, + expected: map[string]UIDEntry{}, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + uids := getPriorityUids(test.givenLowestPriorityGroup, test.givenUids, syncersByBidder) + assert.Equal(t, true, reflect.DeepEqual(test.expected, uids)) + }) + } +} From 48e627532b593f686f559f662538d960330b7987 Mon Sep 17 00:00:00 2001 From: Mina Naguib Date: Wed, 20 Sep 2023 14:22:40 -0400 Subject: [PATCH 123/268] DOOH support (#2758) --- adapters/infoawarebidder.go | 24 +- adapters/infoawarebidder_test.go | 30 ++- config/account.go | 6 +- config/account_test.go | 21 +- config/bidderinfo.go | 24 +- config/bidderinfo_test.go | 61 ++++- .../test/bidder-info-valid/stroeerCore.yaml | 4 + endpoints/info/bidders_detail.go | 7 + endpoints/info/bidders_detail_test.go | 2 + endpoints/openrtb2/auction.go | 92 ++++++-- endpoints/openrtb2/auction_test.go | 209 +++++++++++++++++- ...r-app.json => no-site-or-app-or-dooh.json} | 2 +- .../invalid-whole/site-app-both.json | 4 +- .../invalid-whole/site-dooh-both.json | 27 +++ .../valid-whole/exemplary/dooh.json | 53 +++++ exchange/utils.go | 9 +- metrics/metrics.go | 12 +- openrtb_ext/request_wrapper.go | 99 +++++++++ openrtb_ext/request_wrapper_test.go | 140 ++++++++++++ 19 files changed, 774 insertions(+), 52 deletions(-) rename endpoints/openrtb2/sample-requests/invalid-whole/{no-site-or-app.json => no-site-or-app-or-dooh.json} (85%) create mode 100644 endpoints/openrtb2/sample-requests/invalid-whole/site-dooh-both.json create mode 100644 endpoints/openrtb2/sample-requests/valid-whole/exemplary/dooh.json diff --git a/adapters/infoawarebidder.go b/adapters/infoawarebidder.go index 321a87a3bec..538a46ae05c 100644 --- a/adapters/infoawarebidder.go +++ b/adapters/infoawarebidder.go @@ -13,7 +13,7 @@ import ( // media types defined in the static/bidder-info/{bidder}.yaml file. // // It adjusts incoming requests in the following ways: -// 1. If App or Site traffic is not supported by the info file, then requests from +// 1. If App, Site or DOOH traffic is not supported by the info file, then requests from // those sources will be rejected before the delegate is called. // 2. If a given MediaType is not supported for the platform, then it will be set // to nil before the request is forwarded to the delegate. @@ -24,7 +24,7 @@ type InfoAwareBidder struct { info parsedBidderInfo } -// BuildInfoAwareBidder wraps a bidder to enforce site, app, and media type support. +// BuildInfoAwareBidder wraps a bidder to enforce inventory {site, app, dooh} and media type support. func BuildInfoAwareBidder(bidder Bidder, info config.BidderInfo) Bidder { return &InfoAwareBidder{ Bidder: bidder, @@ -47,6 +47,12 @@ func (i *InfoAwareBidder) MakeRequests(request *openrtb2.BidRequest, reqInfo *Ex } allowedMediaTypes = i.info.app } + if request.DOOH != nil { + if !i.info.dooh.enabled { + return nil, []error{&errortypes.Warning{Message: "this bidder does not support dooh requests"}} + } + allowedMediaTypes = i.info.dooh + } // Filtering imps is quite expensive (array filter with large, non-pointer elements)... but should be rare, // because it only happens if the publisher makes a really bad request. @@ -136,6 +142,7 @@ func filterImps(imps []openrtb2.Imp, numToFilter int) ([]openrtb2.Imp, []error) type parsedBidderInfo struct { app parsedSupports site parsedSupports + dooh parsedSupports } type parsedSupports struct { @@ -148,13 +155,22 @@ type parsedSupports struct { func parseBidderInfo(info config.BidderInfo) parsedBidderInfo { var parsedInfo parsedBidderInfo - if info.Capabilities != nil && info.Capabilities.App != nil { + + if info.Capabilities == nil { + return parsedInfo + } + + if info.Capabilities.App != nil { parsedInfo.app.enabled = true parsedInfo.app.banner, parsedInfo.app.video, parsedInfo.app.audio, parsedInfo.app.native = parseAllowedTypes(info.Capabilities.App.MediaTypes) } - if info.Capabilities != nil && info.Capabilities.Site != nil { + if info.Capabilities.Site != nil { parsedInfo.site.enabled = true parsedInfo.site.banner, parsedInfo.site.video, parsedInfo.site.audio, parsedInfo.site.native = parseAllowedTypes(info.Capabilities.Site.MediaTypes) } + if info.Capabilities.DOOH != nil { + parsedInfo.dooh.enabled = true + parsedInfo.dooh.banner, parsedInfo.dooh.video, parsedInfo.dooh.audio, parsedInfo.dooh.native = parseAllowedTypes(info.Capabilities.DOOH.MediaTypes) + } return parsedInfo } diff --git a/adapters/infoawarebidder_test.go b/adapters/infoawarebidder_test.go index f42716bc1d6..87d9d4d442a 100644 --- a/adapters/infoawarebidder_test.go +++ b/adapters/infoawarebidder_test.go @@ -10,6 +10,7 @@ import ( "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/openrtb_ext" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestAppNotSupported(t *testing.T) { @@ -56,6 +57,26 @@ func TestSiteNotSupported(t *testing.T) { assert.Len(t, bids, 0) } +func TestDOOHNotSupported(t *testing.T) { + bidder := &mockBidder{} + info := config.BidderInfo{ + Capabilities: &config.CapabilitiesInfo{ + Site: &config.PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}, + }, + }, + } + constrained := adapters.BuildInfoAwareBidder(bidder, info) + bids, errs := constrained.MakeRequests(&openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{ID: "imp-1", Banner: &openrtb2.Banner{}}}, + DOOH: &openrtb2.DOOH{}, + }, &adapters.ExtraRequestInfo{}) + require.Len(t, errs, 1) + assert.EqualError(t, errs[0], "this bidder does not support dooh requests") + assert.IsType(t, &errortypes.Warning{}, errs[0]) + assert.Len(t, bids, 0) +} + func TestImpFiltering(t *testing.T) { bidder := &mockBidder{} info := config.BidderInfo{ @@ -66,6 +87,9 @@ func TestImpFiltering(t *testing.T) { App: &config.PlatformInfo{ MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}, }, + DOOH: &config.PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeNative}, + }, }, } @@ -153,10 +177,10 @@ func TestImpFiltering(t *testing.T) { description: "All imps with correct media type, MakeRequest() call expected", inBidRequest: &openrtb2.BidRequest{ Imp: []openrtb2.Imp{ - {ID: "imp-1", Video: &openrtb2.Video{}}, - {ID: "imp-2", Video: &openrtb2.Video{}}, + {ID: "imp-1", Native: &openrtb2.Native{}}, + {ID: "imp-2", Native: &openrtb2.Native{}}, }, - Site: &openrtb2.Site{}, + DOOH: &openrtb2.DOOH{}, }, expectedErrors: nil, expectedImpLen: 2, diff --git a/config/account.go b/config/account.go index e5265072164..4b0ceeef0cf 100644 --- a/config/account.go +++ b/config/account.go @@ -20,6 +20,7 @@ const ( ChannelApp ChannelType = "app" ChannelVideo ChannelType = "video" ChannelWeb ChannelType = "web" + ChannelDOOH ChannelType = "dooh" ) // Account represents a publisher account configuration @@ -251,6 +252,7 @@ type AccountChannel struct { App *bool `mapstructure:"app" json:"app,omitempty"` Video *bool `mapstructure:"video" json:"video,omitempty"` Web *bool `mapstructure:"web" json:"web,omitempty"` + DOOH *bool `mapstructure:"dooh" json:"dooh,omitempty"` } // GetByChannelType looks up the account integration enabled setting for the specified channel type @@ -266,6 +268,8 @@ func (a *AccountChannel) GetByChannelType(channelType ChannelType) *bool { channelEnabled = a.Video case ChannelWeb: channelEnabled = a.Web + case ChannelDOOH: + channelEnabled = a.DOOH } return channelEnabled @@ -296,7 +300,7 @@ func (m AccountModules) ModuleConfig(id string) (json.RawMessage, error) { } func (a *AccountChannel) IsSet() bool { - return a.AMP != nil || a.App != nil || a.Video != nil || a.Web != nil + return a.AMP != nil || a.App != nil || a.Video != nil || a.Web != nil || a.DOOH != nil } type AccountPrivacy struct { diff --git a/config/account_test.go b/config/account_test.go index 31d9796a622..58f2a52e645 100644 --- a/config/account_test.go +++ b/config/account_test.go @@ -205,6 +205,7 @@ func TestAccountChannelGetByChannelType(t *testing.T) { giveAppEnabled *bool giveVideoEnabled *bool giveWebEnabled *bool + giveDOOHEnabled *bool giveChannelType ChannelType wantEnabled *bool }{ @@ -276,6 +277,23 @@ func TestAccountChannelGetByChannelType(t *testing.T) { giveChannelType: ChannelWeb, wantEnabled: &trueValue, }, + { + description: "DOOH channel setting unspecified, returns nil", + giveChannelType: ChannelDOOH, + wantEnabled: nil, + }, + { + description: "DOOH channel disabled, returns false", + giveDOOHEnabled: &falseValue, + giveChannelType: ChannelDOOH, + wantEnabled: &falseValue, + }, + { + description: "DOOH channel enabled, returns true", + giveDOOHEnabled: &trueValue, + giveChannelType: ChannelDOOH, + wantEnabled: &trueValue, + }, } for _, tt := range tests { @@ -284,6 +302,7 @@ func TestAccountChannelGetByChannelType(t *testing.T) { App: tt.giveAppEnabled, Video: tt.giveVideoEnabled, Web: tt.giveWebEnabled, + DOOH: tt.giveDOOHEnabled, } result := accountChannel.GetByChannelType(tt.giveChannelType) @@ -836,7 +855,7 @@ func TestAccountChannelIsSet(t *testing.T) { }{ { name: "AccountChannelSetAllFields", - givenAccountChannel: &AccountChannel{AMP: &trueBool, App: &falseBool, Video: &falseBool, Web: &falseBool}, + givenAccountChannel: &AccountChannel{AMP: &trueBool, App: &falseBool, Video: &falseBool, Web: &falseBool, DOOH: &falseBool}, expected: true, }, { diff --git a/config/bidderinfo.go b/config/bidderinfo.go index 96d6fd15bfc..0027e4d21d0 100644 --- a/config/bidderinfo.go +++ b/config/bidderinfo.go @@ -78,6 +78,7 @@ type MaintainerInfo struct { type CapabilitiesInfo struct { App *PlatformInfo `yaml:"app" mapstructure:"app"` Site *PlatformInfo `yaml:"site" mapstructure:"site"` + DOOH *PlatformInfo `yaml:"dooh" mapstructure:"dooh"` } // PlatformInfo specifies the supported media types for a bidder. @@ -461,7 +462,9 @@ func validateAliasCapabilities(aliasBidderInfo BidderInfo, infos BidderInfos, bi return fmt.Errorf("capabilities for alias: %s should be a subset of capabilities for parent bidder: %s", bidderName, aliasBidderInfo.AliasOf) } - if (aliasBidderInfo.Capabilities.App != nil && parentBidder.Capabilities.App == nil) || (aliasBidderInfo.Capabilities.Site != nil && parentBidder.Capabilities.Site == nil) { + if (aliasBidderInfo.Capabilities.App != nil && parentBidder.Capabilities.App == nil) || + (aliasBidderInfo.Capabilities.Site != nil && parentBidder.Capabilities.Site == nil) || + (aliasBidderInfo.Capabilities.DOOH != nil && parentBidder.Capabilities.DOOH == nil) { return fmt.Errorf("capabilities for alias: %s should be a subset of capabilities for parent bidder: %s", bidderName, aliasBidderInfo.AliasOf) } @@ -476,6 +479,12 @@ func validateAliasCapabilities(aliasBidderInfo BidderInfo, infos BidderInfos, bi return err } } + + if aliasBidderInfo.Capabilities.DOOH != nil && parentBidder.Capabilities.DOOH != nil { + if err := isAliasPlatformInfoSubsetOfParent(*parentBidder.Capabilities.DOOH, *aliasBidderInfo.Capabilities.DOOH, bidderName, aliasBidderInfo.AliasOf); err != nil { + return err + } + } } return nil @@ -501,8 +510,8 @@ func validateCapabilities(info *CapabilitiesInfo, bidderName string) error { return fmt.Errorf("missing required field: capabilities for adapter: %s", bidderName) } - if info.App == nil && info.Site == nil { - return fmt.Errorf("at least one of capabilities.site or capabilities.app must exist for adapter: %s", bidderName) + if info.App == nil && info.Site == nil && info.DOOH == nil { + return fmt.Errorf("at least one of capabilities.site, capabilities.app, or capabilities.dooh must exist for adapter: %s", bidderName) } if info.App != nil { @@ -513,9 +522,16 @@ func validateCapabilities(info *CapabilitiesInfo, bidderName string) error { if info.Site != nil { if err := validatePlatformInfo(info.Site); err != nil { - return fmt.Errorf("capabilities.site failed validation: %v, for adapter: %s", err, bidderName) + return fmt.Errorf("capabilities.site failed validation: %v for adapter: %s", err, bidderName) } } + + if info.DOOH != nil { + if err := validatePlatformInfo(info.DOOH); err != nil { + return fmt.Errorf("capabilities.dooh failed validation: %v for adapter: %s", err, bidderName) + } + } + return nil } diff --git a/config/bidderinfo_test.go b/config/bidderinfo_test.go index 77625c0cdd0..438ed5af776 100644 --- a/config/bidderinfo_test.go +++ b/config/bidderinfo_test.go @@ -31,6 +31,9 @@ capabilities: - banner - video - native + dooh: + mediaTypes: + - banner modifyingVastXmlAllowed: true debug: allow: true @@ -92,6 +95,9 @@ func TestLoadBidderInfoFromDisk(t *testing.T) { Site: &PlatformInfo{ MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative}, }, + DOOH: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo}, + }, }, Syncer: &Syncer{ Key: "foo", @@ -176,6 +182,9 @@ func TestProcessBidderInfo(t *testing.T) { Site: &PlatformInfo{ MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative}, }, + DOOH: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}, + }, }, Debug: &DebugInfo{ Allow: true, @@ -225,6 +234,9 @@ func TestProcessBidderInfo(t *testing.T) { Site: &PlatformInfo{ MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative}, }, + DOOH: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}, + }, }, Debug: &DebugInfo{ Allow: true, @@ -533,7 +545,7 @@ func TestBidderInfoValidationPositive(t *testing.T) { Endpoint: "http://bidderB.com/openrtb2", PlatformID: "B", Maintainer: &MaintainerInfo{ - Email: "maintainer@bidderA.com", + Email: "maintainer@bidderB.com", }, GVLVendorID: 2, Capabilities: &CapabilitiesInfo{ @@ -569,6 +581,23 @@ func TestBidderInfoValidationPositive(t *testing.T) { }, AliasOf: "bidderB", }, + "bidderD": BidderInfo{ + Endpoint: "http://bidderD.com/openrtb2", + PlatformID: "D", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderD.com", + }, + GVLVendorID: 3, + Capabilities: &CapabilitiesInfo{ + DOOH: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + openrtb_ext.BidTypeNative, + openrtb_ext.BidTypeBanner, + }, + }, + }, + }, } errs := bidderInfos.validate(make([]error, 0)) assert.Len(t, errs, 0, "All bidder infos should be correct") @@ -769,7 +798,7 @@ func TestBidderInfoValidationNegative(t *testing.T) { }, }, { - "One bidder missing capabilities site and app", + "One bidder missing capabilities site and app and dooh", BidderInfos{ "bidderA": BidderInfo{ Endpoint: "http://bidderA.com/openrtb2", @@ -780,7 +809,7 @@ func TestBidderInfoValidationNegative(t *testing.T) { }, }, []error{ - errors.New("at least one of capabilities.site or capabilities.app must exist for adapter: bidderA"), + errors.New("at least one of capabilities.site, capabilities.app, or capabilities.dooh must exist for adapter: bidderA"), }, }, { @@ -804,6 +833,27 @@ func TestBidderInfoValidationNegative(t *testing.T) { errors.New("capabilities.app failed validation: unrecognized media type at index 0: incorrect for adapter: bidderA"), }, }, + { + "One bidder incorrect capabilities for dooh", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + DOOH: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + "incorrect", + }, + }, + }, + }, + }, + []error{ + errors.New("capabilities.dooh failed validation: unrecognized media type at index 0: incorrect for adapter: bidderA"), + }, + }, { "One bidder nil capabilities", BidderInfos{ @@ -1008,7 +1058,7 @@ func TestBidderInfoValidationNegative(t *testing.T) { }, }, []error{ - errors.New("at least one of capabilities.site or capabilities.app must exist for adapter: bidderA"), + errors.New("at least one of capabilities.site, capabilities.app, or capabilities.dooh must exist for adapter: bidderA"), errors.New("capabilities for alias: bidderB should be a subset of capabilities for parent bidder: bidderA"), }, }, @@ -1687,6 +1737,9 @@ func TestReadFullYamlBidderConfig(t *testing.T) { Site: &PlatformInfo{ MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative}, }, + DOOH: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}, + }, }, ModifyingVastXmlAllowed: true, Debug: &DebugInfo{ diff --git a/config/test/bidder-info-valid/stroeerCore.yaml b/config/test/bidder-info-valid/stroeerCore.yaml index 0a1b3059cd4..ef95d2388a5 100644 --- a/config/test/bidder-info-valid/stroeerCore.yaml +++ b/config/test/bidder-info-valid/stroeerCore.yaml @@ -11,6 +11,10 @@ capabilities: - banner - video - native + dooh: + mediaTypes: + - banner + - video userSync: key: "foo" default: "iframe" diff --git a/endpoints/info/bidders_detail.go b/endpoints/info/bidders_detail.go index 1446e3ac22a..9b8d42686ae 100644 --- a/endpoints/info/bidders_detail.go +++ b/endpoints/info/bidders_detail.go @@ -122,6 +122,7 @@ type maintainer struct { type capabilities struct { App *platform `json:"app,omitempty"` Site *platform `json:"site,omitempty"` + DOOH *platform `json:"dooh,omitempty"` } type platform struct { @@ -157,6 +158,12 @@ func mapDetailFromConfig(c config.BidderInfo) bidderDetail { MediaTypes: mapMediaTypes(c.Capabilities.Site.MediaTypes), } } + + if c.Capabilities.DOOH != nil { + bidderDetail.Capabilities.DOOH = &platform{ + MediaTypes: mapMediaTypes(c.Capabilities.DOOH.MediaTypes), + } + } } } else { bidderDetail.Status = statusDisabled diff --git a/endpoints/info/bidders_detail_test.go b/endpoints/info/bidders_detail_test.go index 47e5a0688a8..3be24acfdba 100644 --- a/endpoints/info/bidders_detail_test.go +++ b/endpoints/info/bidders_detail_test.go @@ -225,6 +225,7 @@ func TestMapDetailFromConfig(t *testing.T) { Capabilities: &config.CapabilitiesInfo{ App: &config.PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}}, Site: &config.PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeVideo}}, + DOOH: &config.PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeNative}}, }, }, expected: bidderDetail{ @@ -236,6 +237,7 @@ func TestMapDetailFromConfig(t *testing.T) { Capabilities: &capabilities{ App: &platform{MediaTypes: []string{"banner"}}, Site: &platform{MediaTypes: []string{"video"}}, + DOOH: &platform{MediaTypes: []string{"native"}}, }, AliasOf: "", }, diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index aeb5c20e64e..375756cc565 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -69,13 +69,16 @@ var ( ) var accountIdSearchPath = [...]struct { - isApp bool - key []string + isApp bool + isDOOH bool + key []string }{ - {true, []string{"app", "publisher", "ext", openrtb_ext.PrebidExtKey, "parentAccount"}}, - {true, []string{"app", "publisher", "id"}}, - {false, []string{"site", "publisher", "ext", openrtb_ext.PrebidExtKey, "parentAccount"}}, - {false, []string{"site", "publisher", "id"}}, + {true, false, []string{"app", "publisher", "ext", openrtb_ext.PrebidExtKey, "parentAccount"}}, + {true, false, []string{"app", "publisher", "id"}}, + {false, false, []string{"site", "publisher", "ext", openrtb_ext.PrebidExtKey, "parentAccount"}}, + {false, false, []string{"site", "publisher", "id"}}, + {false, true, []string{"dooh", "publisher", "ext", openrtb_ext.PrebidExtKey, "parentAccount"}}, + {false, true, []string{"dooh", "publisher", "id"}}, } func NewEndpoint( @@ -457,12 +460,16 @@ func (deps *endpointDeps) parseRequest(httpRequest *http.Request, labels *metric return } - accountId, isAppReq, errs := getAccountIdFromRawRequest(hasStoredBidRequest, storedRequests[storedBidRequestId], requestJson) + accountId, isAppReq, isDOOHReq, errs := getAccountIdFromRawRequest(hasStoredBidRequest, storedRequests[storedBidRequestId], requestJson) // fill labels here in order to pass correct metrics in case of errors if isAppReq { labels.Source = metrics.DemandApp labels.RType = metrics.ReqTypeORTB2App labels.PubID = accountId + } else if isDOOHReq { + labels.Source = metrics.DemandDOOH + labels.RType = metrics.ReqTypeORTB2DOOH + labels.PubID = accountId } else { // is Site request labels.Source = metrics.DemandWeb labels.PubID = accountId @@ -804,8 +811,8 @@ func (deps *endpointDeps) validateRequest(req *openrtb_ext.RequestWrapper, isAmp return []error{err} } - if (req.Site == nil && req.App == nil) || (req.Site != nil && req.App != nil) { - return append(errL, errors.New("request.site or request.app must be defined, but not both.")) + if err := validateExactlyOneInventoryType(req); err != nil { + return []error{err} } if errs := validateRequestExt(req); len(errs) != 0 { @@ -823,6 +830,9 @@ func (deps *endpointDeps) validateRequest(req *openrtb_ext.RequestWrapper, isAmp return append(errL, err) } + if err := deps.validateDOOH(req); err != nil { + return append(errL, err) + } var gpp gpplib.GppContainer if req.BidRequest.Regs != nil && len(req.BidRequest.Regs.GPP) > 0 { gpp, err = gpplib.Parse(req.BidRequest.Regs.GPP) @@ -1747,6 +1757,18 @@ func (deps *endpointDeps) validateApp(req *openrtb_ext.RequestWrapper) error { return err } +func (deps *endpointDeps) validateDOOH(req *openrtb_ext.RequestWrapper) error { + if req.DOOH == nil { + return nil + } + + if req.DOOH.ID == "" && len(req.DOOH.VenueType) == 0 { + return errors.New("request.dooh should include at least one of request.dooh.id or request.dooh.venuetype.") + } + + return nil +} + func (deps *endpointDeps) validateUser(req *openrtb_ext.RequestWrapper, aliases map[string]string, gpp gpplib.GppContainer) []error { var errL []error @@ -1872,6 +1894,30 @@ func validateDevice(device *openrtb2.Device) error { return nil } +func validateExactlyOneInventoryType(reqWrapper *openrtb_ext.RequestWrapper) error { + + // Prep for mutual exclusion check + invTypeNumMatches := 0 + if reqWrapper.Site != nil { + invTypeNumMatches++ + } + if reqWrapper.App != nil { + invTypeNumMatches++ + } + if reqWrapper.DOOH != nil { + invTypeNumMatches++ + } + + if invTypeNumMatches == 0 { + return errors.New("One of request.site or request.app or request.dooh must be defined") + } else if invTypeNumMatches >= 2 { + return errors.New("No more than one of request.site or request.app or request.dooh can be defined") + } else { + return nil + } + +} + func validateOrFillChannel(reqWrapper *openrtb_ext.RequestWrapper, isAmp bool) error { requestExt, err := reqWrapper.GetRequestExt() if err != nil { @@ -1934,9 +1980,9 @@ func (deps *endpointDeps) setFieldsImplicitly(httpReq *http.Request, r *openrtb_ setDeviceImplicitly(httpReq, r, deps.privateNetworkIPValidator) - // Per the OpenRTB spec: A bid request must not contain both a Site and an App object. If neither are - // present, we'll assume it's a site request. - if r.App == nil { + // Per the OpenRTB spec: A bid request must not contain more than one of Site|App|DOOH + // Assume it's a site request if it's not declared as one of the other values + if r.App == nil && r.DOOH == nil { setSiteImplicitly(httpReq, r) } @@ -2325,43 +2371,43 @@ func getAccountID(pub *openrtb2.Publisher) string { return metrics.PublisherUnknown } -func getAccountIdFromRawRequest(hasStoredRequest bool, storedRequest json.RawMessage, originalRequest []byte) (string, bool, []error) { +func getAccountIdFromRawRequest(hasStoredRequest bool, storedRequest json.RawMessage, originalRequest []byte) (string, bool, bool, []error) { request := originalRequest if hasStoredRequest { request = storedRequest } - accountId, isAppReq, err := searchAccountId(request) + accountId, isAppReq, isDOOHReq, err := searchAccountId(request) if err != nil { - return "", isAppReq, []error{err} + return "", isAppReq, isDOOHReq, []error{err} } // In case the stored request did not have account data we specifically search it in the original request if accountId == "" && hasStoredRequest { - accountId, _, err = searchAccountId(originalRequest) + accountId, _, _, err = searchAccountId(originalRequest) if err != nil { - return "", isAppReq, []error{err} + return "", isAppReq, isDOOHReq, []error{err} } } if accountId == "" { - return metrics.PublisherUnknown, isAppReq, nil + return metrics.PublisherUnknown, isAppReq, isDOOHReq, nil } - return accountId, isAppReq, nil + return accountId, isAppReq, isDOOHReq, nil } -func searchAccountId(request []byte) (string, bool, error) { +func searchAccountId(request []byte) (string, bool, bool, error) { for _, path := range accountIdSearchPath { accountId, exists, err := getStringValueFromRequest(request, path.key) if err != nil { - return "", path.isApp, err + return "", path.isApp, path.isDOOH, err } if exists { - return accountId, path.isApp, nil + return accountId, path.isApp, path.isDOOH, nil } } - return "", false, nil + return "", false, false, nil } func getStringValueFromRequest(request []byte, key []string) (string, bool, error) { diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index 84e5cf4baf5..f60fd98e926 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -205,7 +205,7 @@ func runEndToEndTest(t *testing.T, auctionEndpointHandler httprouter.Handle, tes err = json.Unmarshal(test.ExpectedBidResponse, &expectedBidResponse) if assert.NoError(t, err, "Could not unmarshal expected bidResponse taken from test file.\n Test file: %s\n Error:%s\n", testFile, err) { err = json.Unmarshal([]byte(actualJsonBidResponse), &actualBidResponse) - if assert.NoError(t, err, "Could not unmarshal actual bidResponse from auction.\n Test file: %s\n Error:%s\n", testFile, err) { + if assert.NoError(t, err, "Could not unmarshal actual bidResponse from auction.\n Test file: %s\n Error:%s\n actualJsonBidResponse: %s", testFile, err, actualJsonBidResponse) { assertBidResponseEqual(t, testFile, expectedBidResponse, actualBidResponse) } } @@ -1541,6 +1541,81 @@ func TestMergeBidderParamsImpExtPrebid(t *testing.T) { } } +func TestValidateExactlyOneInventoryType(t *testing.T) { + + testCases := []struct { + description string + givenRequestWrapper *openrtb_ext.RequestWrapper + expectedError error + }{ + { + description: "None provided - invalid", + givenRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{}}, + expectedError: errors.New("One of request.site or request.app or request.dooh must be defined"), + }, + { + description: "Only site provided", + givenRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + Site: &openrtb2.Site{}, + }}, + expectedError: nil, + }, + { + description: "Only app provided", + givenRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + App: &openrtb2.App{}, + }}, + expectedError: nil, + }, + { + description: "Only dooh provided", + givenRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + DOOH: &openrtb2.DOOH{}, + }}, + expectedError: nil, + }, + { + description: "Two provided (site+app) - invalid", + givenRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + Site: &openrtb2.Site{}, + App: &openrtb2.App{}, + }}, + expectedError: errors.New("No more than one of request.site or request.app or request.dooh can be defined"), + }, + { + description: "Two provided (site+dooh) - invalid", + givenRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + Site: &openrtb2.Site{}, + DOOH: &openrtb2.DOOH{}, + }}, + expectedError: errors.New("No more than one of request.site or request.app or request.dooh can be defined"), + }, + { + description: "Two provided (app+dooh) - invalid", + givenRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + App: &openrtb2.App{}, + DOOH: &openrtb2.DOOH{}, + }}, + expectedError: errors.New("No more than one of request.site or request.app or request.dooh can be defined"), + }, + { + description: "Three provided - invalid", + givenRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + Site: &openrtb2.Site{}, + App: &openrtb2.App{}, + DOOH: &openrtb2.DOOH{}, + }}, + expectedError: errors.New("No more than one of request.site or request.app or request.dooh can be defined"), + }, + } + + for _, test := range testCases { + error := validateExactlyOneInventoryType(test.givenRequestWrapper) + assert.Equalf(t, test.expectedError, error, "Error doesn't match: %s\n", test.description) + } + +} + func TestValidateRequest(t *testing.T) { deps := &endpointDeps{ fakeUUIDGenerator{}, @@ -1725,6 +1800,66 @@ func TestValidateRequest(t *testing.T) { expectedErrorList: []error{}, expectedChannelObject: &openrtb_ext.ExtRequestPrebidChannel{Name: appChannel, Version: ""}, }, + { + description: "Minimum required site attributes missing", + givenRequestWrapper: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + ID: "Some-ID", + Site: &openrtb2.Site{}, + Imp: []openrtb2.Imp{ + { + ID: "Some-Imp-ID", + Banner: &openrtb2.Banner{ + Format: []openrtb2.Format{ + { + W: 600, + H: 500, + }, + { + W: 300, + H: 600, + }, + }, + }, + Ext: []byte(`{"appnexus":{"placementId": 12345678}}`), + }, + }, + }, + }, + expectedErrorList: []error{ + errors.New("request.site should include at least one of request.site.id or request.site.page."), + }, + }, + { + description: "Minimum required DOOH attributes missing", + givenRequestWrapper: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + ID: "Some-ID", + DOOH: &openrtb2.DOOH{}, + Imp: []openrtb2.Imp{ + { + ID: "Some-Imp-ID", + Banner: &openrtb2.Banner{ + Format: []openrtb2.Format{ + { + W: 600, + H: 500, + }, + { + W: 300, + H: 600, + }, + }, + }, + Ext: []byte(`{"appnexus":{"placementId": 12345678}}`), + }, + }, + }, + }, + expectedErrorList: []error{ + errors.New("request.dooh should include at least one of request.dooh.id or request.dooh.venuetype."), + }, + }, } for _, test := range testCases { @@ -3237,6 +3372,78 @@ func TestMapSChains(t *testing.T) { } } +func TestSearchAccountID(t *testing.T) { + // Correctness for lookup within Publisher object left to TestGetAccountID + // This however tests the expected lookup paths in outer site, app and dooh + testCases := []struct { + description string + request []byte + expectedAccID string + expectedError error + expectedIsAppReq bool + expectedIsSiteReq bool + expectedIsDOOHReq bool + }{ + { + description: "No publisher available", + request: []byte(`{}`), + expectedAccID: "", + expectedError: nil, + expectedIsAppReq: false, + expectedIsDOOHReq: false, + }, + { + description: "Publisher.ID doesn't exist", + request: []byte(`{"site":{"publisher":{}}}`), + expectedAccID: "", + expectedError: nil, + expectedIsAppReq: false, + expectedIsDOOHReq: false, + }, + { + description: "Publisher.ID not a string", + request: []byte(`{"site":{"publisher":{"id":42}}}`), + expectedAccID: "", + expectedError: errors.New("site.publisher.id must be a string"), + expectedIsAppReq: false, + expectedIsDOOHReq: false, + }, + { + description: "Publisher available in request.site", + request: []byte(`{"site":{"publisher":{"id":"42"}}}`), + expectedAccID: "42", + expectedError: nil, + expectedIsAppReq: false, + expectedIsDOOHReq: false, + }, + { + description: "Publisher available in request.app", + request: []byte(`{"app":{"publisher":{"id":"42"}}}`), + expectedAccID: "42", + expectedError: nil, + expectedIsAppReq: true, + expectedIsDOOHReq: false, + }, + { + description: "Publisher available in request.dooh", + request: []byte(`{"dooh":{"publisher":{"id":"42"}}}`), + expectedAccID: "42", + expectedError: nil, + expectedIsAppReq: false, + expectedIsDOOHReq: true, + }, + } + + for _, test := range testCases { + accountId, isAppReq, isDOOHReq, err := searchAccountId(test.request) + assert.Equal(t, test.expectedAccID, accountId, "searchAccountID should return expected account ID for test case: %s", test.description) + assert.Equal(t, test.expectedIsAppReq, isAppReq, "searchAccountID should return expected isAppReq for test case: %s", test.description) + assert.Equal(t, test.expectedIsDOOHReq, isDOOHReq, "searchAccountID should return expected isDOOHReq for test case: %s", test.description) + assert.Equal(t, test.expectedError, err, "searchAccountID should return expected error for test case: %s", test.description) + } + +} + func TestGetAccountID(t *testing.T) { testPubID := "test-pub" testParentAccount := "test-account" diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/no-site-or-app.json b/endpoints/openrtb2/sample-requests/invalid-whole/no-site-or-app-or-dooh.json similarity index 85% rename from endpoints/openrtb2/sample-requests/invalid-whole/no-site-or-app.json rename to endpoints/openrtb2/sample-requests/invalid-whole/no-site-or-app-or-dooh.json index 8ec2273ebec..c883979c98d 100644 --- a/endpoints/openrtb2/sample-requests/invalid-whole/no-site-or-app.json +++ b/endpoints/openrtb2/sample-requests/invalid-whole/no-site-or-app-or-dooh.json @@ -1,5 +1,5 @@ { - "description": "Request does not come with site field nor app field", + "description": "Request does not come with site nor app nor dooh field", "mockBidRequest": { "id": "req-id", "imp": [ diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/site-app-both.json b/endpoints/openrtb2/sample-requests/invalid-whole/site-app-both.json index 5bc3054c356..255ea59e498 100644 --- a/endpoints/openrtb2/sample-requests/invalid-whole/site-app-both.json +++ b/endpoints/openrtb2/sample-requests/invalid-whole/site-app-both.json @@ -1,5 +1,5 @@ { - "description": "Bid request comes with both site and app fields, it should only come with one or the other", + "description": "Bid request comes with both site and app fields, it should only come with one", "mockBidRequest": { "id": "req-id", "site": { @@ -23,5 +23,5 @@ ] }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: request.site or request.app must be defined, but not both.\n" + "expectedErrorMessage": "Invalid request: No more than one of request.site or request.app or request.dooh can be defined\n" } diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/site-dooh-both.json b/endpoints/openrtb2/sample-requests/invalid-whole/site-dooh-both.json new file mode 100644 index 00000000000..d4760d12a99 --- /dev/null +++ b/endpoints/openrtb2/sample-requests/invalid-whole/site-dooh-both.json @@ -0,0 +1,27 @@ +{ + "description": "Bid request comes with both site and dooh fields, it should only come with one", + "mockBidRequest": { + "id": "req-id", + "site": { + "page": "test.mysite.com" + }, + "dooh": {}, + "imp": [ + { + "id": "imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "appnexus": { + "placementId": 12883451 + } + } + } + ] + }, + "expectedReturnCode": 400, + "expectedErrorMessage": "Invalid request: No more than one of request.site or request.app or request.dooh can be defined\n" +} diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/dooh.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/dooh.json new file mode 100644 index 00000000000..faa9a7f6646 --- /dev/null +++ b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/dooh.json @@ -0,0 +1,53 @@ +{ + "description": "Simple DOOH request", + "config": { + "mockBidders": [ + {"bidderName": "appnexus", "currency": "USD", "price": 0.00} + ] + }, + "mockBidRequest": { + "id": "some-request-id", + "dooh": { + "id": "12345" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "format": [ + { + "w": 1920, + "h": 1080 + } + ] + }, + "ext": { + "appnexus": { + "placementId": 12883451 + } + } + } + ], + "tmax": 500, + "ext": {} + }, + "expectedBidResponse": { + "id": "some-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "appnexus-bid", + "impid": "some-impression-id", + "price": 0 + } + ], + "seat": "appnexus" + } + ], + "bidid": "test bid id", + "cur": "USD", + "nbr": 0 + }, + "expectedReturnCode": 200 +} diff --git a/exchange/utils.go b/exchange/utils.go index 0becca21f6c..6c47bcaa9c0 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -29,10 +29,11 @@ import ( ) var channelTypeMap = map[metrics.RequestType]config.ChannelType{ - metrics.ReqTypeAMP: config.ChannelAMP, - metrics.ReqTypeORTB2App: config.ChannelApp, - metrics.ReqTypeVideo: config.ChannelVideo, - metrics.ReqTypeORTB2Web: config.ChannelWeb, + metrics.ReqTypeAMP: config.ChannelAMP, + metrics.ReqTypeORTB2App: config.ChannelApp, + metrics.ReqTypeVideo: config.ChannelVideo, + metrics.ReqTypeORTB2Web: config.ChannelWeb, + metrics.ReqTypeORTB2DOOH: config.ChannelDOOH, } const unknownBidder string = "" diff --git a/metrics/metrics.go b/metrics/metrics.go index c30f81675a0..d39c06d7869 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -164,6 +164,7 @@ const PublisherUnknown = "unknown" const ( DemandWeb DemandSource = "web" DemandApp DemandSource = "app" + DemandDOOH DemandSource = "dooh" DemandUnknown DemandSource = "unknown" ) @@ -171,22 +172,25 @@ func DemandTypes() []DemandSource { return []DemandSource{ DemandWeb, DemandApp, + DemandDOOH, DemandUnknown, } } // The request types (endpoints) const ( - ReqTypeORTB2Web RequestType = "openrtb2-web" - ReqTypeORTB2App RequestType = "openrtb2-app" - ReqTypeAMP RequestType = "amp" - ReqTypeVideo RequestType = "video" + ReqTypeORTB2Web RequestType = "openrtb2-web" + ReqTypeORTB2App RequestType = "openrtb2-app" + ReqTypeORTB2DOOH RequestType = "openrtb2-dooh" + ReqTypeAMP RequestType = "amp" + ReqTypeVideo RequestType = "video" ) func RequestTypes() []RequestType { return []RequestType{ ReqTypeORTB2Web, ReqTypeORTB2App, + ReqTypeORTB2DOOH, ReqTypeAMP, ReqTypeVideo, } diff --git a/openrtb_ext/request_wrapper.go b/openrtb_ext/request_wrapper.go index 5f5636d602a..f4ef69b0523 100644 --- a/openrtb_ext/request_wrapper.go +++ b/openrtb_ext/request_wrapper.go @@ -42,6 +42,7 @@ type RequestWrapper struct { appExt *AppExt regExt *RegExt siteExt *SiteExt + doohExt *DOOHExt sourceExt *SourceExt } @@ -160,6 +161,17 @@ func (rw *RequestWrapper) GetSiteExt() (*SiteExt, error) { return rw.siteExt, rw.siteExt.unmarshal(rw.Site.Ext) } +func (rw *RequestWrapper) GetDOOHExt() (*DOOHExt, error) { + if rw.doohExt != nil { + return rw.doohExt, nil + } + rw.doohExt = &DOOHExt{} + if rw.BidRequest == nil || rw.DOOH == nil || rw.DOOH.Ext == nil { + return rw.doohExt, rw.doohExt.unmarshal(json.RawMessage{}) + } + return rw.doohExt, rw.doohExt.unmarshal(rw.DOOH.Ext) +} + func (rw *RequestWrapper) GetSourceExt() (*SourceExt, error) { if rw.sourceExt != nil { return rw.sourceExt, nil @@ -197,6 +209,9 @@ func (rw *RequestWrapper) RebuildRequest() error { if err := rw.rebuildSiteExt(); err != nil { return err } + if err := rw.rebuildDOOHExt(); err != nil { + return err + } if err := rw.rebuildSourceExt(); err != nil { return err } @@ -297,6 +312,25 @@ func (rw *RequestWrapper) rebuildAppExt() error { return nil } +func (rw *RequestWrapper) rebuildDOOHExt() error { + if rw.doohExt == nil || !rw.doohExt.Dirty() { + return nil + } + + doohJson, err := rw.doohExt.marshal() + if err != nil { + return err + } + + if doohJson != nil && rw.DOOH == nil { + rw.DOOH = &openrtb2.DOOH{Ext: doohJson} + } else if rw.DOOH != nil { + rw.DOOH.Ext = doohJson + } + + return nil +} + func (rw *RequestWrapper) rebuildRegExt() error { if rw.regExt == nil || !rw.regExt.Dirty() { return nil @@ -370,6 +404,7 @@ func (rw *RequestWrapper) Clone() *RequestWrapper { clone.appExt = rw.appExt.Clone() clone.regExt = rw.regExt.Clone() clone.siteExt = rw.siteExt.Clone() + clone.doohExt = rw.doohExt.Clone() clone.sourceExt = rw.sourceExt.Clone() return &clone @@ -1040,6 +1075,70 @@ func (ae *AppExt) Clone() *AppExt { return &clone } +// --------------------------------------------------------------- +// DOOHExt provides an interface for request.dooh.ext +// This is currently a placeholder for consistency with others - no useful attributes and getters/setters exist yet +// --------------------------------------------------------------- + +type DOOHExt struct { + ext map[string]json.RawMessage + extDirty bool +} + +func (de *DOOHExt) unmarshal(extJson json.RawMessage) error { + if len(de.ext) != 0 || de.Dirty() { + return nil + } + + de.ext = make(map[string]json.RawMessage) + + if len(extJson) == 0 { + return nil + } + + if err := json.Unmarshal(extJson, &de.ext); err != nil { + return err + } + + return nil +} + +func (de *DOOHExt) marshal() (json.RawMessage, error) { + de.extDirty = false + if len(de.ext) == 0 { + return nil, nil + } + return json.Marshal(de.ext) +} + +func (de *DOOHExt) Dirty() bool { + return de.extDirty +} + +func (de *DOOHExt) GetExt() map[string]json.RawMessage { + ext := make(map[string]json.RawMessage) + for k, v := range de.ext { + ext[k] = v + } + return ext +} + +func (de *DOOHExt) SetExt(ext map[string]json.RawMessage) { + de.ext = ext + de.extDirty = true +} + +func (de *DOOHExt) Clone() *DOOHExt { + if de == nil { + return nil + } + + clone := *de + clone.ext = maputil.Clone(de.ext) + + return &clone +} + // --------------------------------------------------------------- // RegExt provides an interface for request.regs.ext // --------------------------------------------------------------- diff --git a/openrtb_ext/request_wrapper_test.go b/openrtb_ext/request_wrapper_test.go index e02dd741519..afa047e6909 100644 --- a/openrtb_ext/request_wrapper_test.go +++ b/openrtb_ext/request_wrapper_test.go @@ -41,6 +41,7 @@ func TestCloneRequestWrapper(t *testing.T) { appExt: &AppExt{prebidDirty: true}, regExt: &RegExt{usPrivacy: "foo"}, siteExt: &SiteExt{amp: ptrutil.ToPtr[int8](1)}, + doohExt: &DOOHExt{}, sourceExt: &SourceExt{schainDirty: true}, }, reqWrapCopy: &RequestWrapper{ @@ -60,6 +61,7 @@ func TestCloneRequestWrapper(t *testing.T) { appExt: &AppExt{prebidDirty: true}, regExt: &RegExt{usPrivacy: "foo"}, siteExt: &SiteExt{amp: ptrutil.ToPtr[int8](1)}, + doohExt: &DOOHExt{}, sourceExt: &SourceExt{schainDirty: true}, }, mutator: func(t *testing.T, reqWrap *RequestWrapper) {}, @@ -83,6 +85,7 @@ func TestCloneRequestWrapper(t *testing.T) { appExt: &AppExt{prebidDirty: true}, regExt: &RegExt{usPrivacy: "foo"}, siteExt: &SiteExt{amp: ptrutil.ToPtr[int8](1)}, + doohExt: &DOOHExt{}, sourceExt: &SourceExt{schainDirty: true}, }, reqWrapCopy: &RequestWrapper{ @@ -102,6 +105,7 @@ func TestCloneRequestWrapper(t *testing.T) { appExt: &AppExt{prebidDirty: true}, regExt: &RegExt{usPrivacy: "foo"}, siteExt: &SiteExt{amp: ptrutil.ToPtr[int8](1)}, + doohExt: &DOOHExt{}, sourceExt: &SourceExt{schainDirty: true}, }, mutator: func(t *testing.T, reqWrap *RequestWrapper) { @@ -115,6 +119,7 @@ func TestCloneRequestWrapper(t *testing.T) { reqWrap.appExt = nil reqWrap.regExt = nil reqWrap.siteExt = nil + reqWrap.doohExt = nil reqWrap.sourceExt = nil }, }, @@ -1206,6 +1211,141 @@ func TestCloneAppExt(t *testing.T) { } } +func TestRebuildDOOHExt(t *testing.T) { + // These permutations look a bit wonky + // Since DOOHExt currently exists for consistency but there isn't a single field + // expected - hence unable to test dirty and variations + // Once one is established, updated the permutations below similar to TestRebuildAppExt example + testCases := []struct { + description string + request openrtb2.BidRequest + requestDOOHExtWrapper DOOHExt + expectedRequest openrtb2.BidRequest + }{ + { + description: "Nil - Not Dirty", + request: openrtb2.BidRequest{}, + requestDOOHExtWrapper: DOOHExt{}, + expectedRequest: openrtb2.BidRequest{}, + }, + { + description: "Nil - Dirty", + request: openrtb2.BidRequest{}, + requestDOOHExtWrapper: DOOHExt{}, + expectedRequest: openrtb2.BidRequest{DOOH: nil}, + }, + { + description: "Nil - Dirty - No Change", + request: openrtb2.BidRequest{}, + requestDOOHExtWrapper: DOOHExt{}, + expectedRequest: openrtb2.BidRequest{}, + }, + { + description: "Empty - Not Dirty", + request: openrtb2.BidRequest{DOOH: &openrtb2.DOOH{}}, + requestDOOHExtWrapper: DOOHExt{}, + expectedRequest: openrtb2.BidRequest{DOOH: &openrtb2.DOOH{}}, + }, + { + description: "Empty - Dirty", + request: openrtb2.BidRequest{DOOH: &openrtb2.DOOH{}}, + requestDOOHExtWrapper: DOOHExt{}, + expectedRequest: openrtb2.BidRequest{DOOH: &openrtb2.DOOH{}}, + }, + { + description: "Empty - Dirty - No Change", + request: openrtb2.BidRequest{DOOH: &openrtb2.DOOH{}}, + requestDOOHExtWrapper: DOOHExt{}, + expectedRequest: openrtb2.BidRequest{DOOH: &openrtb2.DOOH{}}, + }, + { + description: "Populated - Not Dirty", + request: openrtb2.BidRequest{DOOH: &openrtb2.DOOH{Ext: json.RawMessage(`{}`)}}, + requestDOOHExtWrapper: DOOHExt{}, + expectedRequest: openrtb2.BidRequest{DOOH: &openrtb2.DOOH{Ext: json.RawMessage(`{}`)}}, + }, + { + description: "Populated - Dirty", + request: openrtb2.BidRequest{DOOH: &openrtb2.DOOH{Ext: json.RawMessage(`{}`)}}, + requestDOOHExtWrapper: DOOHExt{}, + expectedRequest: openrtb2.BidRequest{DOOH: &openrtb2.DOOH{Ext: json.RawMessage(`{}`)}}, + }, + { + description: "Populated - Dirty - No Change", + request: openrtb2.BidRequest{DOOH: &openrtb2.DOOH{Ext: json.RawMessage(`{}`)}}, + requestDOOHExtWrapper: DOOHExt{}, + expectedRequest: openrtb2.BidRequest{DOOH: &openrtb2.DOOH{Ext: json.RawMessage(`{}`)}}, + }, + { + description: "Populated - Dirty - Cleared", + request: openrtb2.BidRequest{DOOH: &openrtb2.DOOH{Ext: json.RawMessage(`{}`)}}, + requestDOOHExtWrapper: DOOHExt{}, + expectedRequest: openrtb2.BidRequest{DOOH: &openrtb2.DOOH{Ext: json.RawMessage(`{}`)}}, + }, + } + + for _, test := range testCases { + // create required filed in the test loop to keep test declaration easier to read + test.requestDOOHExtWrapper.ext = make(map[string]json.RawMessage) + + w := RequestWrapper{BidRequest: &test.request, doohExt: &test.requestDOOHExtWrapper} + w.RebuildRequest() + assert.Equal(t, test.expectedRequest, *w.BidRequest, test.description) + } +} + +func TestCloneDOOHExt(t *testing.T) { + testCases := []struct { + name string + DOOHExt *DOOHExt + DOOHExtCopy *DOOHExt // manual copy of above ext object to verify against + mutator func(t *testing.T, DOOHExt *DOOHExt) // function to modify the Ext object + }{ + { + name: "Nil", // Verify the nil case + DOOHExt: nil, + DOOHExtCopy: nil, + mutator: func(t *testing.T, DOOHExt *DOOHExt) {}, + }, + { + name: "NoMutate", + DOOHExt: &DOOHExt{ + ext: map[string]json.RawMessage{"A": json.RawMessage(`X`), "B": json.RawMessage(`Y`)}, + extDirty: true, + }, + DOOHExtCopy: &DOOHExt{ + ext: map[string]json.RawMessage{"A": json.RawMessage(`X`), "B": json.RawMessage(`Y`)}, + extDirty: true, + }, + mutator: func(t *testing.T, DOOHExt *DOOHExt) {}, + }, + { + name: "General", + DOOHExt: &DOOHExt{ + ext: map[string]json.RawMessage{"A": json.RawMessage(`X`), "B": json.RawMessage(`Y`)}, + extDirty: true, + }, + DOOHExtCopy: &DOOHExt{ + ext: map[string]json.RawMessage{"A": json.RawMessage(`X`), "B": json.RawMessage(`Y`)}, + extDirty: true, + }, + mutator: func(t *testing.T, DOOHExt *DOOHExt) { + DOOHExt.ext["A"] = json.RawMessage(`"string"`) + DOOHExt.ext["C"] = json.RawMessage(`{}`) + DOOHExt.extDirty = false + }, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + clone := test.DOOHExt.Clone() + test.mutator(t, test.DOOHExt) + assert.Equal(t, test.DOOHExtCopy, clone) + }) + } +} + func TestCloneRegExt(t *testing.T) { testCases := []struct { name string From db871196800b91de615cb101c8af9fe385b99f9a Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Thu, 21 Sep 2023 00:03:29 +0530 Subject: [PATCH 124/268] Record tmax timeout error in adapter error metric (#3104) --- errortypes/code.go | 1 + errortypes/errortypes.go | 19 +++++++++++++++++++ exchange/bidder.go | 4 +--- exchange/bidder_test.go | 4 ++-- exchange/exchange.go | 2 ++ metrics/metrics.go | 1 + 6 files changed, 26 insertions(+), 5 deletions(-) diff --git a/errortypes/code.go b/errortypes/code.go index c68eb19607a..ef8287f2d7d 100644 --- a/errortypes/code.go +++ b/errortypes/code.go @@ -14,6 +14,7 @@ const ( NoConversionRateErrorCode MalformedAcctErrorCode ModuleRejectionErrorCode + TmaxTimeoutErrorCode ) // Defines numeric codes for well-known warnings. diff --git a/errortypes/errortypes.go b/errortypes/errortypes.go index aff0482280e..01a5cca4af7 100644 --- a/errortypes/errortypes.go +++ b/errortypes/errortypes.go @@ -20,6 +20,25 @@ func (err *Timeout) Severity() Severity { return SeverityFatal } +// TmaxTimeout should be used to flag that remaining tmax duration is not enough to get response from bidder +// +// TmaxTimeout will not be written to the app log, since it's not an actionable item for the Prebid Server hosts. +type TmaxTimeout struct { + Message string +} + +func (err *TmaxTimeout) Error() string { + return err.Message +} + +func (err *TmaxTimeout) Code() int { + return TmaxTimeoutErrorCode +} + +func (err *TmaxTimeout) Severity() Severity { + return SeverityFatal +} + // BadInput should be used when returning errors which are caused by bad input. // It should _not_ be used if the error is a server-side issue (e.g. failed to send the external request). // diff --git a/exchange/bidder.go b/exchange/bidder.go index 838c46f73d1..dfdb7cdf85f 100644 --- a/exchange/bidder.go +++ b/exchange/bidder.go @@ -88,8 +88,6 @@ const ( Gzip string = "GZIP" ) -var errTmaxTimeout = errors.New("exceeded tmax duration") - // AdaptBidder converts an adapters.Bidder into an exchange.AdaptedBidder. // // The name refers to the "Adapter" architecture pattern, and should not be confused with a Prebid "Adapter" @@ -551,7 +549,7 @@ func (bidder *bidderAdapter) doRequestImpl(ctx context.Context, req *adapters.Re bidder.me.RecordTMaxTimeout() return &httpCallInfo{ request: req, - err: errTmaxTimeout, + err: &errortypes.TmaxTimeout{Message: "exceeded tmax duration"}, } } } diff --git a/exchange/bidder_test.go b/exchange/bidder_test.go index e2d476c0411..65f6b795247 100644 --- a/exchange/bidder_test.go +++ b/exchange/bidder_test.go @@ -3221,7 +3221,7 @@ func TestDoRequestImplWithTmax(t *testing.T) { ctxDeadline: time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC), description: "returns-tmax-timeout-error", tmaxAdjustments: &TmaxAdjustmentsPreprocessed{IsEnforced: true, PBSResponsePreparationDuration: 100, BidderNetworkLatencyBuffer: 10, BidderResponseDurationMin: 5000}, - assertFn: func(err error) { assert.Equal(t, errTmaxTimeout, err) }, + assertFn: func(err error) { assert.Equal(t, &errortypes.TmaxTimeout{Message: "exceeded tmax duration"}, err) }, }, { ctxDeadline: time.Now().Add(5 * time.Second), @@ -3296,7 +3296,7 @@ func TestDoRequestImplWithTmaxTimeout(t *testing.T) { ctxDeadline: time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC), description: "returns-tmax-timeout-error", tmaxAdjustments: &TmaxAdjustmentsPreprocessed{IsEnforced: true, PBSResponsePreparationDuration: 100, BidderNetworkLatencyBuffer: 10, BidderResponseDurationMin: 5000}, - assertFn: func(err error) { assert.Equal(t, errTmaxTimeout, err) }, + assertFn: func(err error) { assert.Equal(t, &errortypes.TmaxTimeout{Message: "exceeded tmax duration"}, err) }, }, } for _, test := range tests { diff --git a/exchange/exchange.go b/exchange/exchange.go index 136f1040740..7544b4a7020 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -844,6 +844,8 @@ func errorsToMetric(errs []error) map[metrics.AdapterError]struct{} { ret[metrics.AdapterErrorFailedToRequestBids] = s case errortypes.AlternateBidderCodeWarningCode: ret[metrics.AdapterErrorValidation] = s + case errortypes.TmaxTimeoutErrorCode: + ret[metrics.AdapterErrorTmaxTimeout] = s default: ret[metrics.AdapterErrorUnknown] = s } diff --git a/metrics/metrics.go b/metrics/metrics.go index d39c06d7869..a73019bed5e 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -271,6 +271,7 @@ const ( AdapterErrorTimeout AdapterError = "timeout" AdapterErrorFailedToRequestBids AdapterError = "failedtorequestbid" AdapterErrorValidation AdapterError = "validation" + AdapterErrorTmaxTimeout AdapterError = "tmaxtimeout" AdapterErrorUnknown AdapterError = "unknown_error" ) From 55302c6d9e4f8806f2044560d301f0043da08873 Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Wed, 20 Sep 2023 17:35:54 -0400 Subject: [PATCH 125/268] Cleanup Prometheus Type Conversions (#3106) --- metrics/prometheus/preload.go | 30 ++++--- metrics/prometheus/type_conversion.go | 123 +------------------------- 2 files changed, 17 insertions(+), 136 deletions(-) diff --git a/metrics/prometheus/preload.go b/metrics/prometheus/preload.go index dae7c14dc5b..59f70cfb9fb 100644 --- a/metrics/prometheus/preload.go +++ b/metrics/prometheus/preload.go @@ -2,28 +2,30 @@ package prometheusmetrics import ( "github.com/prebid/prebid-server/metrics" + "github.com/prebid/prebid-server/openrtb_ext" "github.com/prometheus/client_golang/prometheus" ) func preloadLabelValues(m *Metrics, syncerKeys []string, moduleStageNames map[string][]string) { var ( - setUidStatusValues = setUidStatusesAsString() - adapterErrorValues = adapterErrorsAsString() - adapterValues = adaptersAsString() + adapterErrorValues = enumAsString(metrics.AdapterErrors()) + adapterValues = enumAsString(openrtb_ext.CoreBidderNames()) bidTypeValues = []string{markupDeliveryAdm, markupDeliveryNurl} boolValues = boolValuesAsString() - cacheResultValues = cacheResultsAsString() + cacheResultValues = enumAsString(metrics.CacheResults()) connectionErrorValues = []string{connectionAcceptError, connectionCloseError} - cookieValues = cookieTypesAsString() - cookieSyncStatusValues = cookieSyncStatusesAsString() - overheadTypes = overheadTypesAsString() - requestTypeValues = requestTypesAsString() - requestStatusValues = requestStatusesAsString() - storedDataFetchTypeValues = storedDataFetchTypesAsString() - storedDataErrorValues = storedDataErrorsAsString() - syncerRequestStatusValues = syncerRequestStatusesAsString() - syncerSetsStatusValues = syncerSetStatusesAsString() + cookieSyncStatusValues = enumAsString(metrics.CookieSyncStatuses()) + cookieValues = enumAsString(metrics.CookieTypes()) + overheadTypes = enumAsString(metrics.OverheadTypes()) + requestStatusValues = enumAsString(metrics.RequestStatuses()) + requestTypeValues = enumAsString(metrics.RequestTypes()) + setUidStatusValues = enumAsString(metrics.SetUidStatuses()) sourceValues = []string{sourceRequest} + storedDataErrorValues = enumAsString(metrics.StoredDataErrors()) + storedDataFetchTypeValues = enumAsString(metrics.StoredDataFetchTypes()) + syncerRequestStatusValues = enumAsString(metrics.SyncerRequestStatuses()) + syncerSetsStatusValues = enumAsString(metrics.SyncerSetUidStatuses()) + tcfVersionValues = enumAsString(metrics.TCFVersions()) ) preloadLabelValuesForCounter(m.connectionsError, map[string][]string{ @@ -224,7 +226,7 @@ func preloadLabelValues(m *Metrics, syncerKeys []string, moduleStageNames map[st preloadLabelValuesForCounter(m.privacyTCF, map[string][]string{ sourceLabel: sourceValues, - versionLabel: tcfVersionsAsString(), + versionLabel: tcfVersionValues, }) if !m.metricsDisabled.AdapterGDPRRequestBlocked { diff --git a/metrics/prometheus/type_conversion.go b/metrics/prometheus/type_conversion.go index 07e4e89c43d..0ae5366b3f7 100644 --- a/metrics/prometheus/type_conversion.go +++ b/metrics/prometheus/type_conversion.go @@ -2,22 +2,9 @@ package prometheusmetrics import ( "strconv" - - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" ) -func adaptersAsString() []string { - values := openrtb_ext.CoreBidderNames() - valuesAsString := make([]string, len(values)) - for i, v := range values { - valuesAsString[i] = string(v) - } - return valuesAsString -} - -func adapterErrorsAsString() []string { - values := metrics.AdapterErrors() +func enumAsString[T ~string](values []T) []string { valuesAsString := make([]string, len(values)) for i, v := range values { valuesAsString[i] = string(v) @@ -31,111 +18,3 @@ func boolValuesAsString() []string { strconv.FormatBool(false), } } - -func cacheResultsAsString() []string { - values := metrics.CacheResults() - valuesAsString := make([]string, len(values)) - for i, v := range values { - valuesAsString[i] = string(v) - } - return valuesAsString -} - -func cookieTypesAsString() []string { - values := metrics.CookieTypes() - valuesAsString := make([]string, len(values)) - for i, v := range values { - valuesAsString[i] = string(v) - } - return valuesAsString -} - -func cookieSyncStatusesAsString() []string { - values := metrics.CookieSyncStatuses() - valuesAsString := make([]string, len(values)) - for i, v := range values { - valuesAsString[i] = string(v) - } - return valuesAsString -} - -func requestStatusesAsString() []string { - values := metrics.RequestStatuses() - valuesAsString := make([]string, len(values)) - for i, v := range values { - valuesAsString[i] = string(v) - } - return valuesAsString -} - -func syncerRequestStatusesAsString() []string { - values := metrics.SyncerRequestStatuses() - valuesAsString := make([]string, len(values)) - for i, v := range values { - valuesAsString[i] = string(v) - } - return valuesAsString -} - -func overheadTypesAsString() []string { - overheadTypes := metrics.OverheadTypes() - overheadTypesAsString := make([]string, len(overheadTypes)) - for i, ot := range overheadTypes { - overheadTypesAsString[i] = ot.String() - } - return overheadTypesAsString -} - -func syncerSetStatusesAsString() []string { - values := metrics.SyncerSetUidStatuses() - valuesAsString := make([]string, len(values)) - for i, v := range values { - valuesAsString[i] = string(v) - } - return valuesAsString -} - -func requestTypesAsString() []string { - values := metrics.RequestTypes() - valuesAsString := make([]string, len(values)) - for i, v := range values { - valuesAsString[i] = string(v) - } - return valuesAsString -} - -func setUidStatusesAsString() []string { - values := metrics.SetUidStatuses() - valuesAsString := make([]string, len(values)) - for i, v := range values { - valuesAsString[i] = string(v) - } - return valuesAsString -} - -func storedDataFetchTypesAsString() []string { - values := metrics.StoredDataFetchTypes() - valuesAsString := make([]string, len(values)) - for i, v := range values { - valuesAsString[i] = string(v) - } - return valuesAsString -} - -func storedDataErrorsAsString() []string { - values := metrics.StoredDataErrors() - valuesAsString := make([]string, len(values)) - for i, v := range values { - valuesAsString[i] = string(v) - } - return valuesAsString -} - -func tcfVersionsAsString() []string { - values := metrics.TCFVersions() - valuesAsString := make([]string, len(values)) - for i, v := range values { - valuesAsString[i] = string(v) - } - return valuesAsString -} From b9c2614798d16dbb27841dc6a1c6103566a04b49 Mon Sep 17 00:00:00 2001 From: Ashish Garg Date: Mon, 25 Sep 2023 22:22:54 +0530 Subject: [PATCH 126/268] make case insensitive comparison in auction request (#3113) --- endpoints/openrtb2/auction.go | 21 +-- endpoints/openrtb2/auction_test.go | 78 ++++++++-- .../exemplary/all-ext-case-insensitive.json | 140 ++++++++++++++++++ .../valid-whole/exemplary/all-ext.json | 86 ++++++----- .../exemplary/simple-case-insensitive.json | 61 ++++++++ .../valid-whole/exemplary/simple.json | 40 ++--- exchange/exchange_test.go | 6 +- exchange/utils.go | 3 +- 8 files changed, 355 insertions(+), 80 deletions(-) create mode 100644 endpoints/openrtb2/sample-requests/valid-whole/exemplary/all-ext-case-insensitive.json create mode 100644 endpoints/openrtb2/sample-requests/valid-whole/exemplary/simple-case-insensitive.json diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 375756cc565..f419ca341ee 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -1520,12 +1520,12 @@ func (deps *endpointDeps) validateImpExt(imp *openrtb_ext.ImpWrapper, aliases ma errL := []error{} for bidder, ext := range prebid.Bidder { - coreBidder := bidder + coreBidder, _ := openrtb_ext.NormalizeBidderName(bidder) if tmp, isAlias := aliases[bidder]; isAlias { - coreBidder = tmp + coreBidder = openrtb_ext.BidderName(tmp) } - if coreBidderNormalized, isValid := deps.bidderMap[coreBidder]; isValid { + if coreBidderNormalized, isValid := deps.bidderMap[coreBidder.String()]; isValid { if err := deps.paramsValidator.Validate(coreBidderNormalized, ext); err != nil { return []error{fmt.Errorf("request.imp[%d].ext.prebid.bidder.%s failed validation.\n%v", impIndex, bidder, err)} } @@ -1585,18 +1585,21 @@ func (deps *endpointDeps) parseBidExt(req *openrtb_ext.RequestWrapper) error { } func (deps *endpointDeps) validateAliases(aliases map[string]string) error { - for alias, coreBidder := range aliases { - if _, isCoreBidderDisabled := deps.disabledBidders[coreBidder]; isCoreBidderDisabled { - return fmt.Errorf("request.ext.prebid.aliases.%s refers to disabled bidder: %s", alias, coreBidder) + for alias, bidderName := range aliases { + normalisedBidderName, _ := openrtb_ext.NormalizeBidderName(bidderName) + coreBidderName := normalisedBidderName.String() + if _, isCoreBidderDisabled := deps.disabledBidders[coreBidderName]; isCoreBidderDisabled { + return fmt.Errorf("request.ext.prebid.aliases.%s refers to disabled bidder: %s", alias, bidderName) } - if _, isCoreBidder := deps.bidderMap[coreBidder]; !isCoreBidder { - return fmt.Errorf("request.ext.prebid.aliases.%s refers to unknown bidder: %s", alias, coreBidder) + if _, isCoreBidder := deps.bidderMap[coreBidderName]; !isCoreBidder { + return fmt.Errorf("request.ext.prebid.aliases.%s refers to unknown bidder: %s", alias, bidderName) } - if alias == coreBidder { + if alias == coreBidderName { return fmt.Errorf("request.ext.prebid.aliases.%s defines a no-op alias. Choose a different alias, or remove this entry.", alias) } + aliases[alias] = coreBidderName } return nil } diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index f60fd98e926..08637df2493 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -2968,19 +2968,21 @@ func TestValidateImpExt(t *testing.T) { for _, group := range testGroups { for _, test := range group.testCases { - imp := &openrtb2.Imp{Ext: test.impExt} - impWrapper := &openrtb_ext.ImpWrapper{Imp: imp} + t.Run(test.description, func(t *testing.T) { + imp := &openrtb2.Imp{Ext: test.impExt} + impWrapper := &openrtb_ext.ImpWrapper{Imp: imp} - errs := deps.validateImpExt(impWrapper, nil, 0, false, nil) + errs := deps.validateImpExt(impWrapper, nil, 0, false, nil) - assert.NoError(t, impWrapper.RebuildImp(), test.description+":rebuild_imp") + assert.NoError(t, impWrapper.RebuildImp(), test.description+":rebuild_imp") - if len(test.expectedImpExt) > 0 { - assert.JSONEq(t, test.expectedImpExt, string(imp.Ext), "imp.ext JSON does not match expected. Test: %s. %s\n", group.description, test.description) - } else { - assert.Empty(t, imp.Ext, "imp.ext expected to be empty but was: %s. Test: %s. %s\n", string(imp.Ext), group.description, test.description) - } - assert.Equal(t, test.expectedErrs, errs, "errs slice does not match expected. Test: %s. %s\n", group.description, test.description) + if len(test.expectedImpExt) > 0 { + assert.JSONEq(t, test.expectedImpExt, string(imp.Ext), "imp.ext JSON does not match expected. Test: %s. %s\n", group.description, test.description) + } else { + assert.Empty(t, imp.Ext, "imp.ext expected to be empty but was: %s. Test: %s. %s\n", string(imp.Ext), group.description, test.description) + } + assert.Equal(t, test.expectedErrs, errs, "errs slice does not match expected. Test: %s. %s\n", group.description, test.description) + }) } } } @@ -5978,3 +5980,59 @@ func TestSetSeatNonBidRaw(t *testing.T) { }) } } + +func TestValidateAliases(t *testing.T) { + deps := &endpointDeps{ + disabledBidders: map[string]string{"rubicon": "rubicon"}, + bidderMap: map[string]openrtb_ext.BidderName{"appnexus": openrtb_ext.BidderName("appnexus")}, + } + + testCases := []struct { + description string + aliases map[string]string + expectedAliases map[string]string + expectedError error + }{ + { + description: "valid case", + aliases: map[string]string{"test": "appnexus"}, + expectedAliases: map[string]string{"test": "appnexus"}, + expectedError: nil, + }, + { + description: "valid case - case insensitive", + aliases: map[string]string{"test": "Appnexus"}, + expectedAliases: map[string]string{"test": "appnexus"}, + expectedError: nil, + }, + { + description: "disabled bidder", + aliases: map[string]string{"test": "rubicon"}, + expectedAliases: nil, + expectedError: errors.New("request.ext.prebid.aliases.test refers to disabled bidder: rubicon"), + }, + { + description: "coreBidderName not found", + aliases: map[string]string{"test": "anyBidder"}, + expectedAliases: nil, + expectedError: errors.New("request.ext.prebid.aliases.test refers to unknown bidder: anyBidder"), + }, + { + description: "alias name is coreBidder name", + aliases: map[string]string{"appnexus": "appnexus"}, + expectedAliases: nil, + expectedError: errors.New("request.ext.prebid.aliases.appnexus defines a no-op alias. Choose a different alias, or remove this entry."), + }, + } + + for _, testCase := range testCases { + t.Run(testCase.description, func(t *testing.T) { + err := deps.validateAliases(testCase.aliases) + if err != nil { + assert.Equal(t, testCase.expectedError, err) + } else { + assert.ObjectsAreEqualValues(testCase.expectedAliases, map[string]string{"test": "appnexus"}) + } + }) + } +} diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/all-ext-case-insensitive.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/all-ext-case-insensitive.json new file mode 100644 index 00000000000..20997076af2 --- /dev/null +++ b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/all-ext-case-insensitive.json @@ -0,0 +1,140 @@ +{ + "description": "This demonstrates all extension in case insensitive.", + "config": { + "mockBidders": [ + { + "bidderName": "appnexus", + "currency": "USD", + "price": 1.00 + }, + { + "bidderName": "rubicon", + "currency": "USD", + "price": 1.00 + } + ] + }, + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "ext": { + "consent": "gdpr-consent-string", + "prebid": { + "buyeruids": { + "appnexus": "override-appnexus-id-in-cookie" + } + } + } + }, + "regs": { + "ext": { + "gdpr": 1, + "us_privacy": "1NYN" + } + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "appnexus": { + "placementId": 12883451 + }, + "districtm": { + "placementId": 105 + }, + "rubicon": { + "accountId": 1001, + "siteId": 113932, + "zoneId": 535510 + } + } + } + ], + "tmax": 500, + "ext": { + "prebid": { + "aliases": { + "districtm": "Appnexus" + }, + "bidadjustmentfactors": { + "appnexus": 1.01, + "districtm": 0.98, + "rubicon": 0.99 + }, + "cache": { + "bids": {} + }, + "channel": { + "name": "video", + "version": "1.0" + }, + "targeting": { + "includewinners": false, + "pricegranularity": { + "precision": 2, + "ranges": [ + { + "max": 20, + "increment": 0.10 + } + ] + } + } + } + } + }, + "expectedBidResponse": { + "id": "some-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "appnexus-bid", + "impid": "some-impression-id", + "price": 1.01 + } + ], + "seat": "appnexus" + }, + { + "bid": [ + { + "id": "appnexus-bid", + "impid": "some-impression-id", + "price": 0.98 + } + ], + "seat": "districtm" + }, + { + "bid": [ + { + "id": "rubicon-bid", + "impid": "some-impression-id", + "price": 0.99 + } + ], + "seat": "rubicon" + } + ], + "bidid": "test bid id", + "cur": "USD", + "nbr": 0 + }, + "expectedReturnCode": 200 +} \ No newline at end of file diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/all-ext.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/all-ext.json index 8f64fd2a5fd..02dc6160d49 100644 --- a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/all-ext.json +++ b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/all-ext.json @@ -2,8 +2,16 @@ "description": "This demonstrates all of the OpenRTB extensions supported by Prebid Server. Very few requests will need all of these at once.", "config": { "mockBidders": [ - {"bidderName": "appnexus", "currency": "USD", "price": 1.00}, - {"bidderName": "rubicon", "currency": "USD", "price": 1.00} + { + "bidderName": "appnexus", + "currency": "USD", + "price": 1.00 + }, + { + "bidderName": "rubicon", + "currency": "USD", + "price": 1.00 + } ] }, "mockBidRequest": { @@ -91,42 +99,42 @@ } }, "expectedBidResponse": { - "id":"some-request-id", - "seatbid": [ - { - "bid": [ - { - "id": "appnexus-bid", - "impid": "some-impression-id", - "price": 1.01 - } - ], - "seat": "appnexus" - }, - { - "bid": [ - { - "id": "appnexus-bid", - "impid": "some-impression-id", - "price": 0.98 - } - ], - "seat": "districtm" - }, - { - "bid": [ - { - "id": "rubicon-bid", - "impid": "some-impression-id", - "price": 0.99 - } - ], - "seat": "rubicon" - } - ], - "bidid":"test bid id", - "cur":"USD", - "nbr":0 + "id": "some-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "appnexus-bid", + "impid": "some-impression-id", + "price": 1.01 + } + ], + "seat": "appnexus" + }, + { + "bid": [ + { + "id": "appnexus-bid", + "impid": "some-impression-id", + "price": 0.98 + } + ], + "seat": "districtm" + }, + { + "bid": [ + { + "id": "rubicon-bid", + "impid": "some-impression-id", + "price": 0.99 + } + ], + "seat": "rubicon" + } + ], + "bidid": "test bid id", + "cur": "USD", + "nbr": 0 }, "expectedReturnCode": 200 -} +} \ No newline at end of file diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/simple-case-insensitive.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/simple-case-insensitive.json new file mode 100644 index 00000000000..9b66a59d0a5 --- /dev/null +++ b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/simple-case-insensitive.json @@ -0,0 +1,61 @@ +{ + "description": "Simple request - bidder case insensitive", + "config": { + "mockBidders": [ + { + "bidderName": "appnexus", + "currency": "USD", + "price": 0.00 + } + ] + }, + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "Appnexus": { + "placementId": 12883451 + } + } + } + ], + "tmax": 500, + "ext": {} + }, + "expectedBidResponse": { + "id": "some-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "appnexus-bid", + "impid": "some-impression-id", + "price": 0 + } + ], + "seat": "Appnexus" + } + ], + "bidid": "test bid id", + "cur": "USD", + "nbr": 0 + }, + "expectedReturnCode": 200 +} \ No newline at end of file diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/simple.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/simple.json index ba9079d4675..5a7dbd20747 100644 --- a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/simple.json +++ b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/simple.json @@ -2,7 +2,11 @@ "description": "Simple request", "config": { "mockBidders": [ - {"bidderName": "appnexus", "currency": "USD", "price": 0.00} + { + "bidderName": "appnexus", + "currency": "USD", + "price": 0.00 + } ] }, "mockBidRequest": { @@ -36,22 +40,22 @@ "ext": {} }, "expectedBidResponse": { - "id":"some-request-id", - "seatbid": [ - { - "bid": [ - { - "id": "appnexus-bid", - "impid": "some-impression-id", - "price": 0 - } - ], - "seat": "appnexus" - } - ], - "bidid":"test bid id", - "cur":"USD", - "nbr":0 + "id": "some-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "appnexus-bid", + "impid": "some-impression-id", + "price": 0 + } + ], + "seat": "appnexus" + } + ], + "bidid": "test bid id", + "cur": "USD", + "nbr": 0 }, "expectedReturnCode": 200 -} +} \ No newline at end of file diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go index 8ca96880781..c4b85ebeb1f 100644 --- a/exchange/exchange_test.go +++ b/exchange/exchange_test.go @@ -769,7 +769,7 @@ func TestAdapterCurrency(t *testing.T) { categoriesFetcher: nilCategoryFetcher{}, bidIDGenerator: &mockBidIDGenerator{false, false}, adapterMap: map[openrtb_ext.BidderName]AdaptedBidder{ - openrtb_ext.BidderName("foo"): AdaptBidder(mockBidder, nil, &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, openrtb_ext.BidderName("foo"), nil, ""), + openrtb_ext.BidderName("appnexus"): AdaptBidder(mockBidder, nil, &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, openrtb_ext.BidderName("appnexus"), nil, ""), }, } e.requestSplitter = requestSplitter{ @@ -783,7 +783,7 @@ func TestAdapterCurrency(t *testing.T) { Imp: []openrtb2.Imp{{ ID: "some-impression-id", Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}, {W: 300, H: 600}}}, - Ext: json.RawMessage(`{"prebid":{"bidder":{"foo":{"placementId":1}}}}`), + Ext: json.RawMessage(`{"prebid":{"bidder":{"appnexus":{"placementId":1}}}}`), }}, Site: &openrtb2.Site{ Page: "prebid.org", @@ -805,7 +805,7 @@ func TestAdapterCurrency(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "some-request-id", response.ID, "Response ID") assert.Empty(t, response.SeatBid, "Response Bids") - assert.Contains(t, string(response.Ext), `"errors":{"foo":[{"code":5,"message":"The adapter failed to generate any bid requests, but also failed to generate an error explaining why"}]}`, "Response Ext") + assert.Contains(t, string(response.Ext), `"errors":{"appnexus":[{"code":5,"message":"The adapter failed to generate any bid requests, but also failed to generate an error explaining why"}]}`, "Response Ext") // Test Currency Converter Properly Passed To Adapter if assert.NotNil(t, mockBidder.lastExtraRequestInfo, "Currency Conversion Argument") { diff --git a/exchange/utils.go b/exchange/utils.go index 6c47bcaa9c0..0a38e487632 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -762,10 +762,11 @@ func setUserExtWithCopy(request *openrtb2.BidRequest, userExtJSON json.RawMessag // resolveBidder returns the known BidderName associated with bidder, if bidder is an alias. If it's not an alias, the bidder is returned. func resolveBidder(bidder string, aliases map[string]string) openrtb_ext.BidderName { + normalisedBidderName, _ := openrtb_ext.NormalizeBidderName(bidder) if coreBidder, ok := aliases[bidder]; ok { return openrtb_ext.BidderName(coreBidder) } - return openrtb_ext.BidderName(bidder) + return normalisedBidderName } // parseAliases parses the aliases from the BidRequest From a91e40c8429a224a186cb998f99e35e97432d43d Mon Sep 17 00:00:00 2001 From: freemmy Date: Tue, 26 Sep 2023 12:51:19 +0700 Subject: [PATCH 127/268] Silvermob: host validation (us, eu, apac) (#3110) --- adapters/silvermob/silvermob.go | 14 ++++- .../supplemental/invalid-host.json | 53 +++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 adapters/silvermob/silvermobtest/supplemental/invalid-host.json diff --git a/adapters/silvermob/silvermob.go b/adapters/silvermob/silvermob.go index 9130ab4d96a..d4a1b55b45f 100644 --- a/adapters/silvermob/silvermob.go +++ b/adapters/silvermob/silvermob.go @@ -18,6 +18,10 @@ type SilverMobAdapter struct { endpoint *template.Template } +func isValidHost(host string) bool { + return host == "eu" || host == "us" || host == "apac" +} + // Builder builds a new instance of the SilverMob adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { template, err := template.New("endpointTemplate").Parse(config.Endpoint) @@ -121,8 +125,14 @@ func (a *SilverMobAdapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.Ext } func (a *SilverMobAdapter) buildEndpointURL(params *openrtb_ext.ExtSilverMob) (string, error) { - endpointParams := macros.EndpointTemplateParams{ZoneID: params.ZoneID, Host: params.Host} - return macros.ResolveMacros(a.endpoint, endpointParams) + if isValidHost(params.Host) { + endpointParams := macros.EndpointTemplateParams{ZoneID: params.ZoneID, Host: params.Host} + return macros.ResolveMacros(a.endpoint, endpointParams) + } else { + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("invalid host %s", params.Host), + } + } } func (a *SilverMobAdapter) MakeBids( diff --git a/adapters/silvermob/silvermobtest/supplemental/invalid-host.json b/adapters/silvermob/silvermobtest/supplemental/invalid-host.json new file mode 100644 index 00000000000..f8b2cd3442f --- /dev/null +++ b/adapters/silvermob/silvermobtest/supplemental/invalid-host.json @@ -0,0 +1,53 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "banner": { + "w":320, + "h":50 + }, + "ext": { + "bidder": { + "host": "some_host", + "zoneid": "0" + } + } + } + ] + }, + "httpCalls": [ + ], + "expectedBidResponses": [ + ], + "expectedMakeRequestsErrors": [ + { + "value": "invalid host some_host", + "comparison": "literal" + } + ] + } \ No newline at end of file From 63170b8484c6a1eb35194d0d04b22c5b76126c9f Mon Sep 17 00:00:00 2001 From: Ashish Garg Date: Tue, 26 Sep 2023 11:26:52 +0530 Subject: [PATCH 128/268] make bidderInfo endpoint case insensitive (#3136) co-authored by @gargcreation1992 --- endpoints/info/bidders_detail.go | 20 ++++++++- endpoints/info/bidders_detail_test.go | 62 +++++++++++++++++---------- 2 files changed, 59 insertions(+), 23 deletions(-) diff --git a/endpoints/info/bidders_detail.go b/endpoints/info/bidders_detail.go index 9b8d42686ae..d9dc776f50d 100644 --- a/endpoints/info/bidders_detail.go +++ b/endpoints/info/bidders_detail.go @@ -27,7 +27,11 @@ func NewBiddersDetailEndpoint(bidders config.BidderInfos, aliases map[string]str return func(w http.ResponseWriter, _ *http.Request, ps httprouter.Params) { bidder := ps.ByName("bidderName") - if response, ok := responses[bidder]; ok { + coreBidderName, found := getNormalisedBidderName(bidder, aliases) + if !found { + w.WriteHeader(http.StatusNotFound) + } + if response, ok := responses[coreBidderName]; ok { w.Header().Set("Content-Type", "application/json") if _, err := w.Write(response); err != nil { glog.Errorf("error writing response to /info/bidders/%s: %v", bidder, err) @@ -38,6 +42,20 @@ func NewBiddersDetailEndpoint(bidders config.BidderInfos, aliases map[string]str } } +func getNormalisedBidderName(bidderName string, aliases map[string]string) (string, bool) { + if strings.ToLower(bidderName) == "all" { + return "all", true + } + coreBidderName, ok := openrtb_ext.NormalizeBidderName(bidderName) + if !ok { //check default aliases if not found in coreBidders + if _, isDefaultAlias := aliases[bidderName]; isDefaultAlias { + return bidderName, true + } + return "", false + } + return coreBidderName.String(), true +} + func prepareBiddersDetailResponse(bidders config.BidderInfos, aliases map[string]string) (map[string][]byte, error) { details, err := mapDetails(bidders, aliases) if err != nil { diff --git a/endpoints/info/bidders_detail_test.go b/endpoints/info/bidders_detail_test.go index 3be24acfdba..435d0cec92c 100644 --- a/endpoints/info/bidders_detail_test.go +++ b/endpoints/info/bidders_detail_test.go @@ -2,6 +2,7 @@ package info import ( "bytes" + "fmt" "io" "net/http" "net/http/httptest" @@ -365,22 +366,22 @@ func TestMapMediaTypes(t *testing.T) { func TestBiddersDetailHandler(t *testing.T) { bidderAInfo := config.BidderInfo{Endpoint: "https://secureEndpoint.com", Disabled: false, Maintainer: &config.MaintainerInfo{Email: "bidderA"}} bidderAResponse := []byte(`{"status":"ACTIVE","usesHttps":true,"maintainer":{"email":"bidderA"}}`) - aliasAResponse := []byte(`{"status":"ACTIVE","usesHttps":true,"maintainer":{"email":"bidderA"},"aliasOf":"a"}`) + aliasAResponse := []byte(`{"status":"ACTIVE","usesHttps":true,"maintainer":{"email":"bidderA"},"aliasOf":"appnexus"}`) bidderBInfo := config.BidderInfo{Endpoint: "http://unsecureEndpoint.com", Disabled: false, Maintainer: &config.MaintainerInfo{Email: "bidderB"}} bidderBResponse := []byte(`{"status":"ACTIVE","usesHttps":false,"maintainer":{"email":"bidderB"}}`) allResponse := bytes.Buffer{} - allResponse.WriteString(`{"a":`) - allResponse.Write(bidderAResponse) - allResponse.WriteString(`,"aAlias":`) + allResponse.WriteString(`{"aAlias":`) allResponse.Write(aliasAResponse) - allResponse.WriteString(`,"b":`) + allResponse.WriteString(`,"appnexus":`) + allResponse.Write(bidderAResponse) + allResponse.WriteString(`,"rubicon":`) allResponse.Write(bidderBResponse) allResponse.WriteString(`}`) - bidders := config.BidderInfos{"a": bidderAInfo, "b": bidderBInfo} - aliases := map[string]string{"aAlias": "a"} + bidders := config.BidderInfos{"appnexus": bidderAInfo, "rubicon": bidderBInfo} + aliases := map[string]string{"aAlias": "appnexus"} handler := NewBiddersDetailEndpoint(bidders, aliases) @@ -393,14 +394,21 @@ func TestBiddersDetailHandler(t *testing.T) { }{ { description: "Bidder A", - givenBidder: "a", + givenBidder: "appnexus", expectedStatus: http.StatusOK, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, expectedResponse: bidderAResponse, }, { description: "Bidder B", - givenBidder: "b", + givenBidder: "rubicon", + expectedStatus: http.StatusOK, + expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, + expectedResponse: bidderBResponse, + }, + { + description: "Bidder B - case insensitive", + givenBidder: "RUBICON", expectedStatus: http.StatusOK, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, expectedResponse: bidderBResponse, @@ -412,6 +420,13 @@ func TestBiddersDetailHandler(t *testing.T) { expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, expectedResponse: aliasAResponse, }, + { + description: "Bidder A Alias - case insensitive", + givenBidder: "aAlias", + expectedStatus: http.StatusOK, + expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, + expectedResponse: aliasAResponse, + }, { description: "All Bidders", givenBidder: "all", @@ -420,11 +435,11 @@ func TestBiddersDetailHandler(t *testing.T) { expectedResponse: allResponse.Bytes(), }, { - description: "All Bidders - Wrong Case", - givenBidder: "ALL", - expectedStatus: http.StatusNotFound, - expectedHeaders: http.Header{}, - expectedResponse: []byte{}, + description: "All Bidders - Case insensitive", + givenBidder: "All", + expectedStatus: http.StatusOK, + expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, + expectedResponse: allResponse.Bytes(), }, { description: "Invalid Bidder", @@ -436,16 +451,19 @@ func TestBiddersDetailHandler(t *testing.T) { } for _, test := range testCases { - responseRecorder := httptest.NewRecorder() - handler(responseRecorder, nil, httprouter.Params{{"bidderName", test.givenBidder}}) + t.Run(test.description, func(t *testing.T) { + responseRecorder := httptest.NewRecorder() + handler(responseRecorder, nil, httprouter.Params{{"bidderName", test.givenBidder}}) - result := responseRecorder.Result() - assert.Equal(t, result.StatusCode, test.expectedStatus, test.description+":statuscode") + result := responseRecorder.Result() + assert.Equal(t, result.StatusCode, test.expectedStatus, test.description+":statuscode") - resultBody, _ := io.ReadAll(result.Body) - assert.Equal(t, test.expectedResponse, resultBody, test.description+":body") + resultBody, _ := io.ReadAll(result.Body) + fmt.Println(string(test.expectedResponse)) + assert.Equal(t, test.expectedResponse, resultBody, test.description+":body") - resultHeaders := result.Header - assert.Equal(t, test.expectedHeaders, resultHeaders, test.description+":headers") + resultHeaders := result.Header + assert.Equal(t, test.expectedHeaders, resultHeaders, test.description+":headers") + }) } } From bc81af56826c90d262a1848f7a503daff4fe4a24 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Tue, 26 Sep 2023 11:28:47 +0530 Subject: [PATCH 129/268] extract directory name only if file is not removed and file is in adapters directory (#3145) co-authored by @onkarvhanumante --- .github/workflows/adapter-code-coverage.yml | 14 +++++++------- .github/workflows/helpers/pull-request-utils.js | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/adapter-code-coverage.yml b/.github/workflows/adapter-code-coverage.yml index 5b5dc9331e5..b4c3f0745d6 100644 --- a/.github/workflows/adapter-code-coverage.yml +++ b/.github/workflows/adapter-code-coverage.yml @@ -28,9 +28,9 @@ jobs: result-encoding: string script: | const utils = require('./.github/workflows/helpers/pull-request-utils.js') - function directoryExtractor(filepath) { - // extract directory name from filepath of the form adapters//*.go - if (filepath.startsWith("adapters/") && filepath.split("/").length > 2) { + function directoryExtractor(filepath, status) { + // extract directory name only if file is not removed and file is in adapters directory + if (status != "removed" && filepath.startsWith("adapters/") && filepath.split("/").length > 2) { return filepath.split("/")[1] } return "" @@ -41,7 +41,7 @@ jobs: - name: Run coverage tests id: run_coverage - if: ${{ steps.get_directories.outputs.result }} != "" + if: steps.get_directories.outputs.result != '' run: | directories=$(echo '${{ steps.get_directories.outputs.result }}' | jq -r '.[]') go mod download @@ -74,7 +74,7 @@ jobs: repository: prebid/prebid-server - name: Commit coverage files to coverage-preview branch - if: ${{ steps.run_coverage.outputs.coverage_dir }} != "" + if: steps.run_coverage.outputs.coverage_dir != '' id: commit_coverage run: | directory=.github/preview/${{ github.run_id }}_$(date +%s) @@ -88,11 +88,11 @@ jobs: echo "remote_coverage_preview_dir=${directory}" >> $GITHUB_OUTPUT - name: Checkout master branch - if: ${{ steps.get_directories.outputs.result }} != "" + if: steps.get_directories.outputs.result != '' run: git checkout master - name: Add coverage summary to pull request - if: ${{ steps.run_coverage.outputs.coverage_dir }} != "" && ${{ steps.commit_coverage.outputs.remote_coverage_preview_dir }} != "" + if: steps.run_coverage.outputs.coverage_dir != '' && steps.commit_coverage.outputs.remote_coverage_preview_dir != '' uses: actions/github-script@v6 with: script: | diff --git a/.github/workflows/helpers/pull-request-utils.js b/.github/workflows/helpers/pull-request-utils.js index 78ab0bb2bc5..941ae5b6953 100644 --- a/.github/workflows/helpers/pull-request-utils.js +++ b/.github/workflows/helpers/pull-request-utils.js @@ -213,8 +213,8 @@ class diffHelper { }) const directories = [] - for (const { filename } of data) { - const directory = directoryExtractor(filename) + for (const { filename, status } of data) { + const directory = directoryExtractor(filename, status) if (directory != "" && !directories.includes(directory)) { directories.push(directory) } From 00bdbef5368b68e3bcbe0a12f797e79e2ba80d32 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Tue, 26 Sep 2023 11:33:23 +0530 Subject: [PATCH 130/268] Support case insensitive bidder name in ext.prebid.storedbidresponse.bidder (#3139) --- endpoints/openrtb2/auction.go | 7 +++- endpoints/openrtb2/auction_test.go | 13 ++++++- ...ored-bid-resp-insensitive-bidder-name.json | 39 +++++++++++++++++++ stored_responses/stored_responses.go | 7 +++- 4 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-insensitive-bidder-name.json diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index f419ca341ee..d8b5c41b018 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -2486,7 +2486,12 @@ func validateStoredBidRespAndImpExtBidders(bidderExts map[string]json.RawMessage } for bidderName := range bidResponses { - if _, present := bidderExts[bidderName]; !present { + bidder := bidderName + normalizedCoreBidder, ok := openrtb_ext.NormalizeBidderName(bidder) + if ok { + bidder = normalizedCoreBidder.String() + } + if _, present := bidderExts[bidder]; !present { return generateStoredBidResponseValidationError(impId) } } diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index 08637df2493..c071d6b0950 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -4954,9 +4954,11 @@ func TestParseRequestStoredResponses(t *testing.T) { func TestParseRequestStoredBidResponses(t *testing.T) { bidRespId1 := json.RawMessage(`{"id": "resp_id1", "seatbid": [{"bid": [{"id": "bid_id1"}], "seat": "testBidder1"}], "bidid": "123", "cur": "USD"}`) bidRespId2 := json.RawMessage(`{"id": "resp_id2", "seatbid": [{"bid": [{"id": "bid_id2"}], "seat": "testBidder2"}], "bidid": "124", "cur": "USD"}`) + bidRespId3 := json.RawMessage(`{"id": "resp_id3", "seatbid": [{"bid": [{"id": "bid_id3"}], "seat": "APPNEXUS"}], "bidid": "125", "cur": "USD"}`) mockStoredBidResponses := map[string]json.RawMessage{ "bidResponseId1": bidRespId1, "bidResponseId2": bidRespId2, + "bidResponseId3": bidRespId3, } tests := []struct { @@ -4974,6 +4976,14 @@ func TestParseRequestStoredBidResponses(t *testing.T) { }, expectedErrorCount: 0, }, + { + name: "req imp has valid stored bid response with case insensitive bidder name", + givenRequestBody: validRequest(t, "imp-with-stored-bid-resp-insensitive-bidder-name.json"), + expectedStoredBidResponses: map[string]map[string]json.RawMessage{ + "imp-id3": {"APPNEXUS": bidRespId3}, + }, + expectedErrorCount: 0, + }, { name: "req has two imps with valid stored bid responses", givenRequestBody: validRequest(t, "req-two-imps-stored-bid-responses.json"), @@ -5014,7 +5024,7 @@ func TestParseRequestStoredBidResponses(t *testing.T) { map[string]string{}, false, []byte{}, - map[string]openrtb_ext.BidderName{"testBidder1": "testBidder1", "testBidder2": "testBidder2"}, + map[string]openrtb_ext.BidderName{"testBidder1": "testBidder1", "testBidder2": "testBidder2", "appnexus": "appnexus"}, nil, nil, hardcodedResponseIPValidator{response: true}, @@ -5027,7 +5037,6 @@ func TestParseRequestStoredBidResponses(t *testing.T) { req := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(test.givenRequestBody)) _, _, _, storedBidResponses, _, _, errL := deps.parseRequest(req, &metrics.Labels{}, hookExecutor) - if test.expectedErrorCount == 0 { assert.Equal(t, test.expectedStoredBidResponses, storedBidResponses, "stored responses should match") } else { diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-insensitive-bidder-name.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-insensitive-bidder-name.json new file mode 100644 index 00000000000..e7b688d4d83 --- /dev/null +++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-insensitive-bidder-name.json @@ -0,0 +1,39 @@ +{ + "description": "request with impression with stored bid response with sensitive bidder name", + "mockBidRequest": { + "id": "request-with-stored-resp", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "imp-id3", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "appnexus": { + "placementId": 12883451 + }, + "prebid": { + "storedbidresponse": [ + { + "bidder": "APPNEXUS", + "id": "bidResponseId3" + } + ] + } + } + } + ], + "user": { + "yob": 1989 + } + }, + "expectedReturnCode": 200 +} \ No newline at end of file diff --git a/stored_responses/stored_responses.go b/stored_responses/stored_responses.go index 19b010fb12d..6a5da01deba 100644 --- a/stored_responses/stored_responses.go +++ b/stored_responses/stored_responses.go @@ -97,8 +97,13 @@ func extractStoredResponsesIds(impInfo []ImpExtPrebidData, if len(bidderResp.ID) == 0 || len(bidderResp.Bidder) == 0 { return nil, nil, nil, nil, fmt.Errorf("request.imp[%d] has ext.prebid.storedbidresponse specified, but \"id\" or/and \"bidder\" fields are missing ", index) } + bidderName := bidderResp.Bidder + normalizedCoreBidder, ok := openrtb_ext.NormalizeBidderName(bidderResp.Bidder) + if ok { + bidderName = normalizedCoreBidder.String() + } //check if bidder is valid/exists - if _, isValid := bidderMap[bidderResp.Bidder]; !isValid { + if _, isValid := bidderMap[bidderName]; !isValid { return nil, nil, nil, nil, fmt.Errorf("request.imp[impId: %s].ext.prebid.bidder contains unknown bidder: %s. Did you forget an alias in request.ext.prebid.aliases?", impId, bidderResp.Bidder) } // bidder is unique per one bid stored response From 940355c3061527c362e1b742f67f00428c461c55 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Tue, 26 Sep 2023 11:36:38 +0530 Subject: [PATCH 131/268] Support case insensitive bidder name in adjustment factors (#3140) --- endpoints/openrtb2/auction.go | 9 +- ...r-adjustment-factors-case-insensitive.json | 119 ++++++++++++++++++ 2 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 endpoints/openrtb2/sample-requests/valid-whole/exemplary/bidder-adjustment-factors-case-insensitive.json diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index d8b5c41b018..bede06217e4 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -964,7 +964,14 @@ func (deps *endpointDeps) validateBidAdjustmentFactors(adjustmentFactors map[str if adjustmentFactor <= 0 { return fmt.Errorf("request.ext.prebid.bidadjustmentfactors.%s must be a positive number. Got %f", bidderToAdjust, adjustmentFactor) } - if _, isBidder := deps.bidderMap[bidderToAdjust]; !isBidder { + + bidderName := bidderToAdjust + normalizedCoreBidder, ok := openrtb_ext.NormalizeBidderName(bidderToAdjust) + if ok { + bidderName = normalizedCoreBidder.String() + } + + if _, isBidder := deps.bidderMap[bidderName]; !isBidder { if _, isAlias := aliases[bidderToAdjust]; !isAlias { return fmt.Errorf("request.ext.prebid.bidadjustmentfactors.%s is not a known bidder or alias", bidderToAdjust) } diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/bidder-adjustment-factors-case-insensitive.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/bidder-adjustment-factors-case-insensitive.json new file mode 100644 index 00000000000..2fa4f37cc88 --- /dev/null +++ b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/bidder-adjustment-factors-case-insensitive.json @@ -0,0 +1,119 @@ +{ + "description": "This demonstrates bid adjustment factors with case insensitive bidder names", + "config": { + "mockBidders": [ + { + "bidderName": "appnexus", + "currency": "USD", + "price": 1.00 + }, + { + "bidderName": "rubicon", + "currency": "USD", + "price": 1.00 + } + ] + }, + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "ext": { + "consent": "gdpr-consent-string" + } + }, + "regs": { + "ext": { + "gdpr": 1, + "us_privacy": "1NYN" + } + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "APPNEXUS": { + "placementId": 12883451 + }, + "districtm": { + "placementId": 105 + } + } + } + ], + "tmax": 500, + "ext": { + "prebid": { + "aliases": { + "districtm": "APPNEXUS" + }, + "bidadjustmentfactors": { + "APPNEXUS": 1.01, + "districtm": 0.98 + }, + "cache": { + "bids": {} + }, + "channel": { + "name": "video", + "version": "1.0" + }, + "targeting": { + "includewinners": false, + "pricegranularity": { + "precision": 2, + "ranges": [ + { + "max": 20, + "increment": 0.10 + } + ] + } + } + } + } + }, + "expectedBidResponse": { + "id": "some-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "appnexus-bid", + "impid": "some-impression-id", + "price": 1.01 + } + ], + "seat": "APPNEXUS" + }, + { + "bid": [ + { + "id": "appnexus-bid", + "impid": "some-impression-id", + "price": 0.98 + } + ], + "seat": "districtm" + } + ], + "bidid": "test bid id", + "cur": "USD", + "nbr": 0 + }, + "expectedReturnCode": 200 +} \ No newline at end of file From 27498c8584b5c96d86a10b8873b835a2009a4ac0 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Tue, 26 Sep 2023 11:37:14 +0530 Subject: [PATCH 132/268] Support case insensitive bidder name in ext.prebid.data.eidpermissions.bidders (#3141) --- endpoints/openrtb2/auction.go | 7 +- ...idpermissions-insensitive-bidder-name.json | 109 ++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 endpoints/openrtb2/sample-requests/valid-whole/exemplary/eidpermissions-insensitive-bidder-name.json diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index bede06217e4..810741982ef 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -1020,7 +1020,12 @@ func validateBidders(bidders []string, knownBidders map[string]openrtb_ext.Bidde return errors.New(`bidder wildcard "*" mixed with specific bidders`) } } else { - _, isCoreBidder := knownBidders[bidder] + bidderName := bidder + normalizedCoreBidder, ok := openrtb_ext.NormalizeBidderName(bidderName) + if ok { + bidderName = normalizedCoreBidder.String() + } + _, isCoreBidder := knownBidders[bidderName] _, isAlias := knownAliases[bidder] if !isCoreBidder && !isAlias { return fmt.Errorf(`unrecognized bidder "%v"`, bidder) diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/eidpermissions-insensitive-bidder-name.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/eidpermissions-insensitive-bidder-name.json new file mode 100644 index 00000000000..b06b2593e26 --- /dev/null +++ b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/eidpermissions-insensitive-bidder-name.json @@ -0,0 +1,109 @@ +{ + "description": "This demonstrates ext.prebid.data.eidpermissions.bidders with case insensitive bidder names", + "config": { + "mockBidders": [ + { + "bidderName": "appnexus", + "currency": "USD", + "price": 1.00 + }, + { + "bidderName": "rubicon", + "currency": "USD", + "price": 1.00 + } + ] + }, + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "ext": { + "consent": "gdpr-consent-string" + } + }, + "regs": { + "ext": { + "gdpr": 1, + "us_privacy": "1NYN" + } + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "APPNEXUS": { + "placementId": 12883451 + } + } + } + ], + "tmax": 500, + "ext": { + "prebid": { + "data": { + "eidpermissions": [ + { + "source": "source1", + "bidders": [ + "APPNEXUS" + ] + } + ] + }, + "cache": { + "bids": {} + }, + "channel": { + "name": "video", + "version": "1.0" + }, + "targeting": { + "includewinners": false, + "pricegranularity": { + "precision": 2, + "ranges": [ + { + "max": 20, + "increment": 0.10 + } + ] + } + } + } + } + }, + "expectedBidResponse": { + "id": "some-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "appnexus-bid", + "impid": "some-impression-id", + "price": 1 + } + ], + "seat": "APPNEXUS" + } + ], + "bidid": "test bid id", + "cur": "USD", + "nbr": 0 + }, + "expectedReturnCode": 200 +} \ No newline at end of file From 6738217a311ec4f53b10f09ddaf98d619268fd49 Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Tue, 26 Sep 2023 03:43:57 -0400 Subject: [PATCH 133/268] Remove Adapter: RhythmOne (#3129) --- adapters/rhythmone/params_test.go | 57 ----- adapters/rhythmone/rhythmone.go | 150 ------------- adapters/rhythmone/rhythmone_test.go | 20 -- .../exemplary/banner-and-video-app.json | 211 ------------------ .../exemplary/banner-and-video-gdpr.json | 182 --------------- .../exemplary/banner-and-video-site.json | 190 ---------------- .../exemplary/banner-and-video.json | 191 ---------------- .../exemplary/simple-banner.json | 114 ---------- .../rhythmonetest/exemplary/simple-video.json | 109 --------- .../supplemental/missing-extension.json | 34 --- .../exemplary/simple-banner-both-ids.json | 2 +- .../risetest/exemplary/simple-banner.json | 2 +- .../rise/risetest/exemplary/simple-video.json | 2 +- .../risetest/supplemental/missing-mtype.json | 4 +- exchange/adapter_builders.go | 2 - exchange/adapter_util.go | 1 + openrtb_ext/bidders.go | 2 - openrtb_ext/imp_rhythmone.go | 9 - static/bidder-info/rhythmone.yaml | 17 -- static/bidder-params/rhythmone.json | 24 -- 20 files changed, 6 insertions(+), 1317 deletions(-) delete mode 100644 adapters/rhythmone/params_test.go delete mode 100644 adapters/rhythmone/rhythmone.go delete mode 100644 adapters/rhythmone/rhythmone_test.go delete mode 100644 adapters/rhythmone/rhythmonetest/exemplary/banner-and-video-app.json delete mode 100644 adapters/rhythmone/rhythmonetest/exemplary/banner-and-video-gdpr.json delete mode 100644 adapters/rhythmone/rhythmonetest/exemplary/banner-and-video-site.json delete mode 100644 adapters/rhythmone/rhythmonetest/exemplary/banner-and-video.json delete mode 100644 adapters/rhythmone/rhythmonetest/exemplary/simple-banner.json delete mode 100644 adapters/rhythmone/rhythmonetest/exemplary/simple-video.json delete mode 100644 adapters/rhythmone/rhythmonetest/supplemental/missing-extension.json delete mode 100644 openrtb_ext/imp_rhythmone.go delete mode 100644 static/bidder-info/rhythmone.yaml delete mode 100644 static/bidder-params/rhythmone.json diff --git a/adapters/rhythmone/params_test.go b/adapters/rhythmone/params_test.go deleted file mode 100644 index 7d8cad47d53..00000000000 --- a/adapters/rhythmone/params_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package rhythmone - -import ( - "encoding/json" - "testing" - - "github.com/prebid/prebid-server/openrtb_ext" -) - -func TestValidParams(t *testing.T) { - validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") - if err != nil { - t.Fatalf("Failed to fetch the json-schemas. %v", err) - } - - for _, validParam := range validParams { - if err := validator.Validate(openrtb_ext.BidderRhythmone, json.RawMessage(validParam)); err != nil { - t.Errorf("Schema rejected rhythmone params: %s", validParam) - } - } -} - -func TestInvalidParams(t *testing.T) { - validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") - if err != nil { - t.Fatalf("Failed to fetch the json-schemas. %v", err) - } - - for _, invalidParam := range invalidParams { - if err := validator.Validate(openrtb_ext.BidderRhythmone, json.RawMessage(invalidParam)); err == nil { - t.Errorf("Schema allowed unexpected params: %s", invalidParam) - } - } -} - -var validParams = []string{ - `{"placementId":"123", "zone":"12345", "path":"34567"}`, -} - -var invalidParams = []string{ - `{"placementId":"123", "zone":"12345", "path":34567}`, - `{"placementId":"123", "zone":12345, "path":"34567"}`, - `{"placementId":123, "zone":"12345", "path":"34567"}`, - `{"placementId":123, "zone":12345, "path":34567}`, - `{"placementId":123, "zone":12345, "path":"34567"}`, - `{"appId":"123", "bidfloor":0.01}`, - `{"publisherName": 100}`, - `{"placementId": 1234}`, - `{"zone": true}`, - ``, - `null`, - `nil`, - `true`, - `9`, - `[]`, - `{}`, -} diff --git a/adapters/rhythmone/rhythmone.go b/adapters/rhythmone/rhythmone.go deleted file mode 100644 index 0ac07a77252..00000000000 --- a/adapters/rhythmone/rhythmone.go +++ /dev/null @@ -1,150 +0,0 @@ -package rhythmone - -import ( - "encoding/json" - "fmt" - - "net/http" - - "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" -) - -type RhythmoneAdapter struct { - endPoint string -} - -func (a *RhythmoneAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - errs := make([]error, 0, len(request.Imp)) - - var uri string - request, uri, errs = a.preProcess(request, errs) - if request != nil { - reqJSON, err := json.Marshal(request) - if err != nil { - errs = append(errs, err) - return nil, errs - } - if uri != "" { - headers := http.Header{} - headers.Add("Content-Type", "application/json;charset=utf-8") - headers.Add("Accept", "application/json") - return []*adapters.RequestData{{ - Method: "POST", - Uri: uri, - Body: reqJSON, - Headers: headers, - }}, errs - } - } - return nil, errs -} - -func (a *RhythmoneAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { - if response.StatusCode == http.StatusNoContent { - return nil, nil - } - - if response.StatusCode == http.StatusBadRequest { - return nil, []error{&errortypes.BadInput{ - Message: fmt.Sprintf("unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), - }} - } - - if response.StatusCode != http.StatusOK { - return nil, []error{&errortypes.BadServerResponse{ - Message: fmt.Sprintf("unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), - }} - } - var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { - return nil, []error{&errortypes.BadServerResponse{ - Message: fmt.Sprintf("bad server response: %d. ", err), - }} - } - - var errs []error - bidResponse := adapters.NewBidderResponseWithBidsCapacity(5) - - for _, sb := range bidResp.SeatBid { - for i := range sb.Bid { - bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ - Bid: &sb.Bid[i], - BidType: getMediaTypeForImp(sb.Bid[i].ImpID, internalRequest.Imp), - }) - } - } - return bidResponse, errs -} - -func getMediaTypeForImp(impId string, imps []openrtb2.Imp) openrtb_ext.BidType { - mediaType := openrtb_ext.BidTypeBanner - for _, imp := range imps { - if imp.ID == impId { - if imp.Banner != nil { - mediaType = openrtb_ext.BidTypeBanner - } else if imp.Video != nil { - mediaType = openrtb_ext.BidTypeVideo - } - return mediaType - } - } - return mediaType -} - -// Builder builds a new instance of the Rythomone adapter for the given bidder with the given config. -func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { - bidder := &RhythmoneAdapter{ - endPoint: config.Endpoint, - } - return bidder, nil -} - -func (a *RhythmoneAdapter) preProcess(req *openrtb2.BidRequest, errors []error) (*openrtb2.BidRequest, string, []error) { - numRequests := len(req.Imp) - var uri string = "" - for i := 0; i < numRequests; i++ { - imp := req.Imp[i] - var bidderExt adapters.ExtImpBidder - err := json.Unmarshal(imp.Ext, &bidderExt) - if err != nil { - err = &errortypes.BadInput{ - Message: fmt.Sprintf("ext data not provided in imp id=%s. Abort all Request", imp.ID), - } - errors = append(errors, err) - return nil, "", errors - } - var rhythmoneExt openrtb_ext.ExtImpRhythmone - err = json.Unmarshal(bidderExt.Bidder, &rhythmoneExt) - if err != nil { - err = &errortypes.BadInput{ - Message: fmt.Sprintf("placementId | zone | path not provided in imp id=%s. Abort all Request", imp.ID), - } - errors = append(errors, err) - return nil, "", errors - } - rhythmoneExt.S2S = true - rhythmoneExtCopy, err := json.Marshal(&rhythmoneExt) - if err != nil { - errors = append(errors, err) - return nil, "", errors - } - bidderExtCopy := struct { - Bidder json.RawMessage `json:"bidder,omitempty"` - }{rhythmoneExtCopy} - impExtCopy, err := json.Marshal(&bidderExtCopy) - if err != nil { - errors = append(errors, err) - return nil, "", errors - } - imp.Ext = impExtCopy - req.Imp[i] = imp - if uri == "" { - uri = fmt.Sprintf("%s/%s/0/%s?z=%s&s2s=%s", a.endPoint, rhythmoneExt.PlacementId, rhythmoneExt.Path, rhythmoneExt.Zone, "true") - } - } - return req, uri, errors -} diff --git a/adapters/rhythmone/rhythmone_test.go b/adapters/rhythmone/rhythmone_test.go deleted file mode 100644 index 0492241dce6..00000000000 --- a/adapters/rhythmone/rhythmone_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package rhythmone - -import ( - "testing" - - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" -) - -func TestJsonSamples(t *testing.T) { - bidder, buildErr := Builder(openrtb_ext.BidderRhythmone, config.Adapter{ - Endpoint: "http://tag.1rx.io/rmp"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - if buildErr != nil { - t.Fatalf("Builder returned unexpected error %v", buildErr) - } - - adapterstest.RunJSONBidderTest(t, "rhythmonetest", bidder) -} diff --git a/adapters/rhythmone/rhythmonetest/exemplary/banner-and-video-app.json b/adapters/rhythmone/rhythmonetest/exemplary/banner-and-video-app.json deleted file mode 100644 index 11e89c37007..00000000000 --- a/adapters/rhythmone/rhythmonetest/exemplary/banner-and-video-app.json +++ /dev/null @@ -1,211 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 300 - } - ] - }, - "ext": { - "bidder": { - "placementId": "72721", - "path": "mvo", - "zone": "1r" - } - } - }, - { - "id": "test-imp-video-id", - "video": { - "mimes": ["video/mp4"], - "minduration": 1, - "maxduration": 2, - "protocols": [1, 2, 5], - "w": 1020, - "h": 780, - "startdelay": 1, - "placement": 1, - "playbackmethod": [2], - "delivery": [1], - "api": [1, 2, 3, 4] - }, - "ext": { - "bidder": { - "placementId": "72721", - "path": "mvo", - "zone": "1r" - } - } - } - ], - "app": { - "id": "agltb3B1Yi1pbmNyDAsSA0FwcBiJkfIUDA", - "name": "Yahoo Weather", - "bundle": "12345", - "storeurl": "https://itunes.apple.com/id628677149", - "cat": ["IAB15", "IAB15-10"], - "ver": "1.0.2", - "publisher": { - "id": "1" - } - }, - "device": { - "dnt": 0, - "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 6_1 like Mac OS X) AppleWebKit / 534.46(KHTML, like Gecko) Version / 5.1 Mobile / 9 A334 Safari / 7534.48 .3", - "ip": "123.145.167.189", - "ifa": "AA000DFE74168477C70D291f574D344790E0BB11", - "carrier": "VERIZON", - "language": "en", - "make": "Apple", - "model": "iPhone", - "os": "iOS", - "osv": "6.1", - "js": 1, - "connectiontype": 3, - "devicetype": 1 - } - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://tag.1rx.io/rmp/72721/0/mvo?z=1r&s2s=true", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 300 - } - ] - }, - "ext": { - "bidder": { - "placementId": "72721", - "zone": "1r", - "path": "mvo", - "S2S": true - } - } - }, - { - "id": "test-imp-video-id", - "video": { - "mimes": ["video/mp4"], - "minduration": 1, - "maxduration": 2, - "protocols": [1, 2, 5], - "w": 1020, - "h": 780, - "startdelay": 1, - "placement": 1, - "playbackmethod": [2], - "delivery": [1], - "api": [1, 2, 3, 4] - }, - "ext": { - "bidder": { - "placementId": "72721", - "zone": "1r", - "path": "mvo", - "S2S": true - } - } - } - ], - "app": { - "id": "agltb3B1Yi1pbmNyDAsSA0FwcBiJkfIUDA", - "name": "Yahoo Weather", - "bundle": "12345", - "storeurl": "https://itunes.apple.com/id628677149", - "cat": ["IAB15", "IAB15-10"], - "ver": "1.0.2", - "publisher": { - "id": "1" - } - }, - "device": { - "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 6_1 like Mac OS X) AppleWebKit / 534.46(KHTML, like Gecko) Version / 5.1 Mobile / 9 A334 Safari / 7534.48 .3", - "ip": "123.145.167.189", - "devicetype": 1, - "make": "Apple", - "model": "iPhone", - "os": "iOS", - "osv": "6.1", - "js": 1, - "dnt": 0, - "language": "en", - "carrier": "VERIZON", - "connectiontype": 3, - "ifa": "AA000DFE74168477C70D291f574D344790E0BB11" - } - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "958", - "bid": [ - { - "id": "7706636740145184841", - "impid": "test-imp-video-id", - "price": 0.5, - "adid": "29681110", - "adm": "some-test-ad", - "adomain": ["yahoo.com"], - "cid": "958", - "crid": "29681110", - "h": 576, - "w": 1024 - } - ] - } - ], - "bidid": "5778926625248726496", - "cur": "USD" - } - } - } - ], - "expectedBidResponses": [ - { - "bids": [ - { - "bid": { - "id": "7706636740145184841", - "impid": "test-imp-video-id", - "price": 0.5, - "adm": "some-test-ad", - "adid": "29681110", - "adomain": ["yahoo.com"], - "cid": "958", - "crid": "29681110", - "w": 1024, - "h": 576 - }, - "type": "video" - } - ] - } - ] -} diff --git a/adapters/rhythmone/rhythmonetest/exemplary/banner-and-video-gdpr.json b/adapters/rhythmone/rhythmonetest/exemplary/banner-and-video-gdpr.json deleted file mode 100644 index d6546179c24..00000000000 --- a/adapters/rhythmone/rhythmonetest/exemplary/banner-and-video-gdpr.json +++ /dev/null @@ -1,182 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 300 - } - ] - }, - "ext": { - "bidder": { - "placementId": "72721", - "path": "mvo", - "zone": "1r" - } - } - }, - { - "id": "test-imp-video-id", - "video": { - "mimes": ["video/mp4"], - "minduration": 1, - "maxduration": 2, - "protocols": [1, 2, 5], - "w": 1020, - "h": 780, - "startdelay": 1, - "placement": 1, - "playbackmethod": [2], - "delivery": [1], - "api": [1, 2, 3, 4] - }, - "ext": { - "bidder": { - "placementId": "72721", - "path": "mvo", - "zone": "1r" - } - } - } - ], - "user": { - "id": "eyJ0ZW1wVUlEcyI6eyJhZGZvcm0iOnsidWlkIjoiMzA5MTMwOTUxNjQ5NDA1MjcxIiwiZXhwaXJlcyI6IjIwMTgtMDYtMjBUMTE6NDA6MzUuODAwNTE0NzQ3KzA1OjMwIn0sImFkbnhzIjp7InVpZCI6IjM1MTUzMjg2MTAyNjMxNjQ0ODQiLCJleHBpcmVzIjoiMjAxOC0wNi0xOFQxODoxMjoxNy4wMTExMzg2MDgrMDU6MzAifX0sImJkYXkiOiIyMDE4LTA2LTA0VDE4OjEyOjE3LjAxMTEzMDg3NSswNTozMCJ9", - "ext": { - "consent": "BOPVK28OPVK28ABABAENA8-AAAADkCNQCGoQAAQ" - } - }, - "regs": { - "ext": { - "gdpr": 1 - } - } - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://tag.1rx.io/rmp/72721/0/mvo?z=1r&s2s=true", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 300 - } - ] - }, - "ext": { - "bidder": { - "placementId": "72721", - "zone": "1r", - "path": "mvo", - "S2S": true - } - } - }, - { - "id": "test-imp-video-id", - "video": { - "mimes": ["video/mp4"], - "minduration": 1, - "maxduration": 2, - "protocols": [1, 2, 5], - "w": 1020, - "h": 780, - "startdelay": 1, - "placement": 1, - "playbackmethod": [2], - "delivery": [1], - "api": [1, 2, 3, 4] - }, - "ext": { - "bidder": { - "placementId": "72721", - "zone": "1r", - "path": "mvo", - "S2S": true - } - } - } - ], - "user": { - "id": "eyJ0ZW1wVUlEcyI6eyJhZGZvcm0iOnsidWlkIjoiMzA5MTMwOTUxNjQ5NDA1MjcxIiwiZXhwaXJlcyI6IjIwMTgtMDYtMjBUMTE6NDA6MzUuODAwNTE0NzQ3KzA1OjMwIn0sImFkbnhzIjp7InVpZCI6IjM1MTUzMjg2MTAyNjMxNjQ0ODQiLCJleHBpcmVzIjoiMjAxOC0wNi0xOFQxODoxMjoxNy4wMTExMzg2MDgrMDU6MzAifX0sImJkYXkiOiIyMDE4LTA2LTA0VDE4OjEyOjE3LjAxMTEzMDg3NSswNTozMCJ9", - "ext": { - "consent": "BOPVK28OPVK28ABABAENA8-AAAADkCNQCGoQAAQ" - } - }, - "regs": { - "ext": { - "gdpr": 1 - } - } - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "958", - "bid": [ - { - "id": "7706636740145184841", - "impid": "test-imp-video-id", - "price": 0.5, - "adid": "29681110", - "adm": "some-test-ad", - "adomain": ["yahoo.com"], - "cid": "958", - "crid": "29681110", - "h": 576, - "w": 1024 - } - ] - } - ], - "bidid": "5778926625248726496", - "cur": "USD" - } - } - } - ], - - "expectedBidResponses": [ - { - "bids": [ - { - "bid": { - "id": "7706636740145184841", - "impid": "test-imp-video-id", - "price": 0.5, - "adm": "some-test-ad", - "adid": "29681110", - "adomain": ["yahoo.com"], - "cid": "958", - "crid": "29681110", - "w": 1024, - "h": 576 - }, - "type": "video" - } - ] - } - ] -} diff --git a/adapters/rhythmone/rhythmonetest/exemplary/banner-and-video-site.json b/adapters/rhythmone/rhythmonetest/exemplary/banner-and-video-site.json deleted file mode 100644 index 223ebee5fb0..00000000000 --- a/adapters/rhythmone/rhythmonetest/exemplary/banner-and-video-site.json +++ /dev/null @@ -1,190 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 300 - } - ] - }, - "ext": { - "bidder": { - "placementId": "72721", - "path": "mvo", - "zone": "1r" - } - } - }, - { - "id": "test-imp-video-id", - "video": { - "mimes": ["video/mp4"], - "minduration": 1, - "maxduration": 2, - "protocols": [1, 2, 5], - "w": 1020, - "h": 780, - "startdelay": 1, - "placement": 1, - "playbackmethod": [2], - "delivery": [1], - "api": [1, 2, 3, 4] - }, - "ext": { - "bidder": { - "placementId": "72721", - "path": "mvo", - "zone": "1r" - } - } - } - ], - "site": { - "id": "102855", - "cat": ["IAB3-1"], - "domain": "www.foobar.com", - "page": "http://www.foobar.com/1234.html ", - "publisher": { - "id": "8953", - "name": "foobar.com", - "cat": ["IAB3-1"], - "domain": "foobar.com" - } - }, - "device": { - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13 (KHTML, like Gecko) Version / 5.1 .7 Safari / 534.57 .2", - "ip": "123.145.167.10" - } - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://tag.1rx.io/rmp/72721/0/mvo?z=1r&s2s=true", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 300 - } - ] - }, - "ext": { - "bidder": { - "placementId": "72721", - "zone": "1r", - "path": "mvo", - "S2S": true - } - } - }, - { - "id": "test-imp-video-id", - "video": { - "mimes": ["video/mp4"], - "minduration": 1, - "maxduration": 2, - "protocols": [1, 2, 5], - "w": 1020, - "h": 780, - "startdelay": 1, - "placement": 1, - "playbackmethod": [2], - "delivery": [1], - "api": [1, 2, 3, 4] - }, - "ext": { - "bidder": { - "placementId": "72721", - "zone": "1r", - "path": "mvo", - "S2S": true - } - } - } - ], - "site": { - "id": "102855", - "cat": ["IAB3-1"], - "domain": "www.foobar.com", - "page": "http://www.foobar.com/1234.html ", - "publisher": { - "id": "8953", - "name": "foobar.com", - "cat": ["IAB3-1"], - "domain": "foobar.com" - } - }, - "device": { - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13 (KHTML, like Gecko) Version / 5.1 .7 Safari / 534.57 .2", - "ip": "123.145.167.10" - } - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "958", - "bid": [ - { - "id": "7706636740145184841", - "impid": "test-imp-video-id", - "price": 0.5, - "adid": "29681110", - "adm": "some-test-ad", - "adomain": ["yahoo.com"], - "cid": "958", - "crid": "29681110", - "h": 576, - "w": 1024 - } - ] - } - ], - "bidid": "5778926625248726496", - "cur": "USD" - } - } - } - ], - - "expectedBidResponses": [ - { - "bids": [{ - "bid": { - "id": "7706636740145184841", - "impid": "test-imp-video-id", - "price": 0.5, - "adm": "some-test-ad", - "adid": "29681110", - "adomain": ["yahoo.com"], - "cid": "958", - "crid": "29681110", - "w": 1024, - "h": 576 - }, - "type": "video" - }] - } - ] -} diff --git a/adapters/rhythmone/rhythmonetest/exemplary/banner-and-video.json b/adapters/rhythmone/rhythmonetest/exemplary/banner-and-video.json deleted file mode 100644 index ae400a2d53c..00000000000 --- a/adapters/rhythmone/rhythmonetest/exemplary/banner-and-video.json +++ /dev/null @@ -1,191 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 300 - } - ] - }, - "ext": { - "bidder": { - "placementId": "72721", - "path": "mvo", - "zone": "1r" - } - } - }, - { - "id": "test-imp-video-id", - "video": { - "mimes": [ - "video/mp4" - ], - "minduration": 1, - "maxduration": 2, - "protocols": [ - 1, - 2, - 5 - ], - "w": 1020, - "h": 780, - "startdelay": 1, - "placement": 1, - "playbackmethod": [ - 2 - ], - "delivery": [ - 1 - ], - "api": [ - 1, - 2, - 3, - 4 - ] - }, - "ext": { - "bidder": { - "placementId": "72721", - "path": "mvo", - "zone": "1r" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://tag.1rx.io/rmp/72721/0/mvo?z=1r&s2s=true", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 300 - } - ] - }, - "ext": { - "bidder": { - "placementId": "72721", - "zone": "1r", - "path": "mvo", - "S2S": true - } - } - }, - { - "id": "test-imp-video-id", - "video": { - "mimes": [ - "video/mp4" - ], - "minduration": 1, - "maxduration": 2, - "protocols": [ - 1, - 2, - 5 - ], - "w": 1020, - "h": 780, - "startdelay": 1, - "placement": 1, - "playbackmethod": [ - 2 - ], - "delivery": [ - 1 - ], - "api": [ - 1, - 2, - 3, - 4 - ] - }, - "ext": { - "bidder": { - "placementId": "72721", - "zone": "1r", - "path": "mvo", - "S2S": true - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "958", - "bid": [ - { - "id": "7706636740145184841", - "impid": "test-imp-video-id", - "price": 0.500000, - "adid": "29681110", - "adm": "some-test-ad", - "adomain": [ - "yahoo.com" - ], - "cid": "958", - "crid": "29681110", - "h": 576, - "w": 1024 - } - ] - } - ], - "bidid": "5778926625248726496", - "cur": "USD" - } - } - } - ], - "expectedBidResponses": [ - { - "bids": [{ - "bid": { - "id": "7706636740145184841", - "impid": "test-imp-video-id", - "price": 0.5, - "adm": "some-test-ad", - "adid": "29681110", - "adomain": [ - "yahoo.com" - ], - "cid": "958", - "crid": "29681110", - "w": 1024, - "h": 576 - }, - "type": "video" - }] - } - ] -} \ No newline at end of file diff --git a/adapters/rhythmone/rhythmonetest/exemplary/simple-banner.json b/adapters/rhythmone/rhythmonetest/exemplary/simple-banner.json deleted file mode 100644 index d2acf3612af..00000000000 --- a/adapters/rhythmone/rhythmonetest/exemplary/simple-banner.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 300 - } - ] - }, - "ext": { - "bidder": { - "placementId": "72721", - "path": "mvo", - "zone": "1r" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://tag.1rx.io/rmp/72721/0/mvo?z=1r&s2s=true", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 300 - } - ] - }, - "ext": { - "bidder": { - "placementId": "72721", - "zone": "1r", - "path": "mvo", - "S2S": true - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "Rhythmone", - "bid": [ - { - "id": "7706636740145184841", - "impid": "test-imp-id", - "price": 0.500000, - "adid": "29681110", - "adm": "some-test-ad", - "adomain": [ - "yahoo.com" - ], - "cid": "958", - "crid": "29681110", - "h": 250, - "w": 300 - } - ] - } - ], - "bidid": "5778926625248726496", - "cur": "USD" - } - } - } - ], - "expectedBidResponses": [ - { - "bids": [{ - "bid": { - "id": "7706636740145184841", - "impid": "test-imp-id", - "price": 0.5, - "adm": "some-test-ad", - "adid": "29681110", - "adomain": [ - "yahoo.com" - ], - "cid": "958", - "crid": "29681110", - "w": 300, - "h": 250 - }, - "type": "banner" - }] - } - ] -} \ No newline at end of file diff --git a/adapters/rhythmone/rhythmonetest/exemplary/simple-video.json b/adapters/rhythmone/rhythmonetest/exemplary/simple-video.json deleted file mode 100644 index 6b86a9e39ee..00000000000 --- a/adapters/rhythmone/rhythmonetest/exemplary/simple-video.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "video": { - "mimes": [ - "video/mp4" - ], - "minduration": 1, - "maxduration": 2, - "protocols": [1,3,5], - "w": 1020, - "h": 780, - "startdelay": 1, - "placement": 1, - "playbackmethod": [2], - "delivery": [1], - "api": [1,2,3,4] - }, - "ext": { - "bidder": { - "placementId": "72721", - "path": "mvo", - "zone": "1r" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://tag.1rx.io/rmp/72721/0/mvo?z=1r&s2s=true", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "video": { - "mimes": [ - "video/mp4" - ], - "minduration": 1, - "maxduration": 2, - "protocols": [1,3,5], - "w": 1020, - "h": 780, - "startdelay": 1, - "placement": 1, - "playbackmethod": [2], - "delivery": [1], - "api": [1,2,3,4] - }, - "ext": { - "bidder": { - "placementId": "72721", - "zone": "1r", - "path": "mvo", - "S2S": true - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "cur": "USD", - "seatbid": [ - { - "seat": "Rhythmone", - "bid": [ - { - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id", - "price": 0.500000, - "adm": "some-test-ad", - "crid": "crid_10", - "w": 1024, - "h": 576 - } - ] - } - ] - } - } - } - ], - "expectedBidResponses": [ - { - "bids": [{ - "bid": { - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id", - "price": 0.5, - "adm": "some-test-ad", - "crid": "crid_10", - "w": 1024, - "h": 576 - }, - "type": "video" - }] - } - ] -} \ No newline at end of file diff --git a/adapters/rhythmone/rhythmonetest/supplemental/missing-extension.json b/adapters/rhythmone/rhythmonetest/supplemental/missing-extension.json deleted file mode 100644 index d313a1759d4..00000000000 --- a/adapters/rhythmone/rhythmonetest/supplemental/missing-extension.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-missing-ext-id", - "video": { - "mimes": [ - "video/mp4" - ], - "minduration": 1, - "maxduration": 2, - "maxextended": 30, - "minbitrate": 300, - "maxbitrate": 1500, - "protocols": [1,2,5], - "w": 1020, - "h": 780, - "startdelay": 1, - "placement": 1, - "playbackmethod": [2], - "delivery": [1], - "api": [1,2,3,4] - } - } - ] - }, - "expectedMakeRequestsErrors": [ - { - "value": "ext data not provided in imp id=test-missing-ext-id. Abort all Request", - "comparison": "literal" - } - ] -} \ No newline at end of file diff --git a/adapters/rise/risetest/exemplary/simple-banner-both-ids.json b/adapters/rise/risetest/exemplary/simple-banner-both-ids.json index cb6bbfa779f..99f9e1f211f 100644 --- a/adapters/rise/risetest/exemplary/simple-banner-both-ids.json +++ b/adapters/rise/risetest/exemplary/simple-banner-both-ids.json @@ -66,7 +66,7 @@ "id": "test-request-id", "seatbid": [ { - "seat": "Rhythmone", + "seat": "958", "bid": [ { "id": "7706636740145184841", diff --git a/adapters/rise/risetest/exemplary/simple-banner.json b/adapters/rise/risetest/exemplary/simple-banner.json index 13e965d1e2f..1fba0f398cb 100644 --- a/adapters/rise/risetest/exemplary/simple-banner.json +++ b/adapters/rise/risetest/exemplary/simple-banner.json @@ -64,7 +64,7 @@ "id": "test-request-id", "seatbid": [ { - "seat": "Rhythmone", + "seat": "958", "bid": [ { "id": "7706636740145184841", diff --git a/adapters/rise/risetest/exemplary/simple-video.json b/adapters/rise/risetest/exemplary/simple-video.json index 921736a6295..0854c06c59f 100644 --- a/adapters/rise/risetest/exemplary/simple-video.json +++ b/adapters/rise/risetest/exemplary/simple-video.json @@ -71,7 +71,7 @@ "cur": "USD", "seatbid": [ { - "seat": "Rhythmone", + "seat": "958", "bid": [ { "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", diff --git a/adapters/rise/risetest/supplemental/missing-mtype.json b/adapters/rise/risetest/supplemental/missing-mtype.json index 5693f25ad83..79fe4b38406 100644 --- a/adapters/rise/risetest/supplemental/missing-mtype.json +++ b/adapters/rise/risetest/supplemental/missing-mtype.json @@ -71,7 +71,7 @@ "cur": "USD", "seatbid": [ { - "seat": "Rhythmone", + "seat": "958", "bid": [ { "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", @@ -85,7 +85,7 @@ ] }, { - "seat": "Rhythmone", + "seat": "958", "bid": [ { "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 395e4fbbc39..825eff56353 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -140,7 +140,6 @@ import ( "github.com/prebid/prebid-server/adapters/pulsepoint" "github.com/prebid/prebid-server/adapters/pwbid" "github.com/prebid/prebid-server/adapters/revcontent" - "github.com/prebid/prebid-server/adapters/rhythmone" "github.com/prebid/prebid-server/adapters/richaudience" "github.com/prebid/prebid-server/adapters/rise" "github.com/prebid/prebid-server/adapters/rtbhouse" @@ -348,7 +347,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderPWBid: pwbid.Builder, openrtb_ext.BidderQuantumdex: apacdex.Builder, openrtb_ext.BidderRevcontent: revcontent.Builder, - openrtb_ext.BidderRhythmone: rhythmone.Builder, openrtb_ext.BidderRichaudience: richaudience.Builder, openrtb_ext.BidderRise: rise.Builder, openrtb_ext.BidderRTBHouse: rtbhouse.Builder, diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index ee9a066aa58..5a3b8a4ce99 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -118,6 +118,7 @@ func GetDisabledBidderWarningMessages(infos config.BidderInfos) map[string]strin "groupm": `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`, "verizonmedia": `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`, "brightroll": `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`, + "rhythmone": `Bidder "rhythmone" is no longer available in Prebid Server. Please update your configuration.`, } return mergeRemovedAndDisabledBidderWarningMessages(removed, infos) diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index e12316f7e72..f6636a00a48 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -170,7 +170,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderPWBid, BidderQuantumdex, BidderRevcontent, - BidderRhythmone, BidderRichaudience, BidderRise, BidderRTBHouse, @@ -465,7 +464,6 @@ const ( BidderPWBid BidderName = "pwbid" BidderQuantumdex BidderName = "quantumdex" BidderRevcontent BidderName = "revcontent" - BidderRhythmone BidderName = "rhythmone" BidderRichaudience BidderName = "richaudience" BidderRise BidderName = "rise" BidderRTBHouse BidderName = "rtbhouse" diff --git a/openrtb_ext/imp_rhythmone.go b/openrtb_ext/imp_rhythmone.go deleted file mode 100644 index 526a2843b53..00000000000 --- a/openrtb_ext/imp_rhythmone.go +++ /dev/null @@ -1,9 +0,0 @@ -package openrtb_ext - -// ExtImpRhythmone defines the contract for bidrequest.imp[i].ext.prebid.bidder.rhythmone -type ExtImpRhythmone struct { - PlacementId string `json:"placementId"` - Zone string `json:"zone"` - Path string `json:"path"` - S2S bool -} diff --git a/static/bidder-info/rhythmone.yaml b/static/bidder-info/rhythmone.yaml deleted file mode 100644 index 529eae12628..00000000000 --- a/static/bidder-info/rhythmone.yaml +++ /dev/null @@ -1,17 +0,0 @@ -endpoint: "http://tag.1rx.io/rmp" -maintainer: - email: "support@rhythmone.com" -gvlVendorID: 36 -capabilities: - app: - mediaTypes: - - banner - - video - site: - mediaTypes: - - banner - - video -userSync: - redirect: - url: "https://sync.1rx.io/usersync2/rmphb?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir={{.RedirectURL}}" - userMacro: "[RX_UUID]" \ No newline at end of file diff --git a/static/bidder-params/rhythmone.json b/static/bidder-params/rhythmone.json deleted file mode 100644 index 01366b45607..00000000000 --- a/static/bidder-params/rhythmone.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Rhythmone Adapter Params", - "description": "A schema which validates params accepted by the Rhythmone adapter", - "type": "object", - "properties": { - "placementId": { - "type": "string", - "description": "An ID which is used to frame Rhythmone ad tag", - "minLength": 1 - }, - "path": { - "type": "string", - "description": "An ID which is used to frame Rhythmone ad tag", - "minLength": 1 - }, - "zone": { - "type": "string", - "description": "An ID which is used to frame Rhythmone ad tag", - "minLength": 1 - } - }, - "required": ["placementId", "path", "zone"] -} From 18edf18b9f0cf28f2c441f47299c3b50ee02caa8 Mon Sep 17 00:00:00 2001 From: Ashish Garg Date: Tue, 26 Sep 2023 13:36:19 +0530 Subject: [PATCH 134/268] make NormalizeBidderName to do faster lookup (#3138) --- openrtb_ext/bidders.go | 5 +++-- openrtb_ext/bidders_test.go | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index f6636a00a48..c2c0725b5e7 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -238,6 +238,7 @@ func SetAliasBidderName(aliasBidderName string, parentBidderName BidderName) err aliasBidder := BidderName(aliasBidderName) coreBidderNames = append(coreBidderNames, aliasBidder) aliasBidderToParent[aliasBidder] = parentBidderName + bidderNameLookup[strings.ToLower(aliasBidderName)] = aliasBidder return nil } @@ -562,11 +563,11 @@ var bidderNameLookup = func() map[string]BidderName { lookup[bidderNameLower] = name } return lookup -} +}() func NormalizeBidderName(name string) (BidderName, bool) { nameLower := strings.ToLower(name) - bidderName, exists := bidderNameLookup()[nameLower] + bidderName, exists := bidderNameLookup[nameLower] return bidderName, exists } diff --git a/openrtb_ext/bidders_test.go b/openrtb_ext/bidders_test.go index 2176c28e184..98404a205b1 100644 --- a/openrtb_ext/bidders_test.go +++ b/openrtb_ext/bidders_test.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "os" + "strings" "testing" "testing/fstest" @@ -148,6 +149,7 @@ func TestSetAliasBidderName(t *testing.T) { } else { assert.Contains(t, CoreBidderNames(), BidderName(test.aliasBidderName)) assert.Contains(t, aliasBidderToParent, BidderName(test.aliasBidderName)) + assert.Contains(t, bidderNameLookup, strings.ToLower(test.aliasBidderName)) } } From d10ccf6f36e104ce0aa9f4a03066999e30ea5769 Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Tue, 26 Sep 2023 04:38:08 -0400 Subject: [PATCH 135/268] Remove Adapter: Applogy (#3130) Co-authored-by: Ashish Garg --- adapters/applogy/applogy.go | 163 ---------------- adapters/applogy/applogy_test.go | 20 -- .../applogytest/exemplary/simple-banner.json | 170 ---------------- .../applogytest/exemplary/simple-native.json | 164 ---------------- .../applogytest/exemplary/simple-video.json | 182 ------------------ .../applogytest/supplemental/all-failed.json | 16 -- .../supplemental/invalid-params.json | 133 ------------- .../applogytest/supplemental/status-204.json | 42 ---- .../applogytest/supplemental/status-400.json | 45 ----- .../applogytest/supplemental/status-502.json | 45 ----- .../hooks/amp_bidder_reject.json | 20 +- .../hooks/amp_bidder_response_reject.json | 20 +- .../hooks/auction_bidder_reject.json | 10 +- .../hooks/auction_bidder_response_reject.json | 10 +- exchange/adapter_builders.go | 2 - exchange/adapter_util.go | 1 + openrtb_ext/bidders.go | 2 - openrtb_ext/imp_applogy.go | 5 - static/bidder-info/applogy.yaml | 14 -- static/bidder-params/applogy.json | 13 -- 20 files changed, 31 insertions(+), 1046 deletions(-) delete mode 100644 adapters/applogy/applogy.go delete mode 100644 adapters/applogy/applogy_test.go delete mode 100644 adapters/applogy/applogytest/exemplary/simple-banner.json delete mode 100644 adapters/applogy/applogytest/exemplary/simple-native.json delete mode 100644 adapters/applogy/applogytest/exemplary/simple-video.json delete mode 100644 adapters/applogy/applogytest/supplemental/all-failed.json delete mode 100644 adapters/applogy/applogytest/supplemental/invalid-params.json delete mode 100644 adapters/applogy/applogytest/supplemental/status-204.json delete mode 100644 adapters/applogy/applogytest/supplemental/status-400.json delete mode 100644 adapters/applogy/applogytest/supplemental/status-502.json delete mode 100644 openrtb_ext/imp_applogy.go delete mode 100644 static/bidder-info/applogy.yaml delete mode 100644 static/bidder-params/applogy.json diff --git a/adapters/applogy/applogy.go b/adapters/applogy/applogy.go deleted file mode 100644 index 14826ec1873..00000000000 --- a/adapters/applogy/applogy.go +++ /dev/null @@ -1,163 +0,0 @@ -package applogy - -import ( - "encoding/json" - "errors" - "net/http" - "strconv" - - "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" -) - -type ApplogyAdapter struct { - endpoint string -} - -func (a *ApplogyAdapter) MakeRequests(request *openrtb2.BidRequest, _ *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - headers := http.Header{} - headers.Add("Content-Type", "application/json;charset=utf-8") - headers.Add("Accept", "application/json") - impressions := request.Imp - result := make([]*adapters.RequestData, 0, len(impressions)) - errs := make([]error, 0, len(impressions)) - - for _, impression := range impressions { - if impression.Banner == nil && impression.Video == nil && impression.Native == nil { - errs = append(errs, &errortypes.BadInput{ - Message: "Applogy only supports banner, video or native ads", - }) - continue - } - if impression.Banner != nil { - if impression.Banner.W == nil || impression.Banner.H == nil || *impression.Banner.W == 0 || *impression.Banner.H == 0 { - if len(impression.Banner.Format) == 0 { - errs = append(errs, &errortypes.BadInput{ - Message: "banner size information missing", - }) - continue - } - banner := *impression.Banner - banner.W = openrtb2.Int64Ptr(banner.Format[0].W) - banner.H = openrtb2.Int64Ptr(banner.Format[0].H) - impression.Banner = &banner - } - } - if len(impression.Ext) == 0 { - errs = append(errs, errors.New("impression extensions required")) - continue - } - var bidderExt adapters.ExtImpBidder - err := json.Unmarshal(impression.Ext, &bidderExt) - if err != nil { - errs = append(errs, err) - continue - } - if len(bidderExt.Bidder) == 0 { - errs = append(errs, errors.New("bidder required")) - continue - } - var impressionExt openrtb_ext.ExtImpApplogy - err = json.Unmarshal(bidderExt.Bidder, &impressionExt) - if err != nil { - errs = append(errs, err) - continue - } - if impressionExt.Token == "" { - errs = append(errs, errors.New("Applogy token required")) - continue - } - request.Imp = []openrtb2.Imp{impression} - body, err := json.Marshal(request) - if err != nil { - errs = append(errs, err) - continue - } - result = append(result, &adapters.RequestData{ - Method: "POST", - Uri: a.endpoint + "/" + impressionExt.Token, - Body: body, - Headers: headers, - }) - } - - request.Imp = impressions - - if len(result) == 0 { - return nil, errs - } - return result, errs -} - -func (a *ApplogyAdapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { - var errs []error - - switch responseData.StatusCode { - case http.StatusNoContent: - return nil, nil - case http.StatusBadRequest: - return nil, []error{&errortypes.BadInput{ - Message: "unexpected status code: " + strconv.Itoa(responseData.StatusCode), - }} - case http.StatusOK: - break - default: - return nil, []error{&errortypes.BadServerResponse{ - Message: "unexpected status code: " + strconv.Itoa(responseData.StatusCode), - }} - } - - var bidResponse openrtb2.BidResponse - err := json.Unmarshal(responseData.Body, &bidResponse) - if err != nil { - return nil, []error{&errortypes.BadServerResponse{ - Message: err.Error(), - }} - } - - response := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) - - for _, seatBid := range bidResponse.SeatBid { - for _, bid := range seatBid.Bid { - bid := bid // pin https://github.com/kyoh86/scopelint#whats-this - var bidType openrtb_ext.BidType - for _, impression := range request.Imp { - if impression.ID != bid.ImpID { - continue - } - switch { - case impression.Banner != nil: - bidType = openrtb_ext.BidTypeBanner - case impression.Video != nil: - bidType = openrtb_ext.BidTypeVideo - case impression.Native != nil: - bidType = openrtb_ext.BidTypeNative - } - break - } - if bidType == "" { - errs = append(errs, &errortypes.BadServerResponse{ - Message: "ignoring bid id=" + bid.ID + ", request doesn't contain any valid impression with id=" + bid.ImpID, - }) - continue - } - response.Bids = append(response.Bids, &adapters.TypedBid{ - Bid: &bid, - BidType: bidType, - }) - } - } - - return response, errs -} - -// Builder builds a new instance of the Applogy adapter for the given bidder with the given config. -func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { - bidder := &ApplogyAdapter{ - endpoint: config.Endpoint, - } - return bidder, nil -} diff --git a/adapters/applogy/applogy_test.go b/adapters/applogy/applogy_test.go deleted file mode 100644 index 1144f44c83c..00000000000 --- a/adapters/applogy/applogy_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package applogy - -import ( - "testing" - - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" -) - -func TestJsonSamples(t *testing.T) { - bidder, buildErr := Builder(openrtb_ext.BidderApplogy, config.Adapter{ - Endpoint: "http://example.com/prebid"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - if buildErr != nil { - t.Fatalf("Builder returned unexpected error %v", buildErr) - } - - adapterstest.RunJSONBidderTest(t, "applogytest", bidder) -} diff --git a/adapters/applogy/applogytest/exemplary/simple-banner.json b/adapters/applogy/applogytest/exemplary/simple-banner.json deleted file mode 100644 index a3926dea623..00000000000 --- a/adapters/applogy/applogytest/exemplary/simple-banner.json +++ /dev/null @@ -1,170 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-1", - "banner": { - "format": [{ - "h": 250, - "w": 300 - }] - }, - "ext": { - "bidder": { - "token": "test-token-1" - } - } - }, { - "id": "test-impression-id-2", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "token": "test-token-1" - } - } - }, { - "id": "test-impression-id-3", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "token": "test-token-2" - } - } - }] - }, - "httpCalls": [{ - "expectedRequest": { - "uri": "http://example.com/prebid/test-token-1", - "body": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-1", - "banner": { - "format": [{ - "h": 250, - "w": 300 - }], - "h": 250, - "w": 300 - }, - "ext": { - "bidder": { - "token": "test-token-1" - } - } - }] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-response-id", - "seatbid": [{ - "bid": [{ - "id": "test-bid-id-1", - "impid": "test-impression-id-1", - "price": 1 - }] - }] - } - } - }, { - "expectedRequest": { - "uri": "http://example.com/prebid/test-token-1", - "body": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-2", - "banner": { - "h": 250, - "w": 300 - }, - "ext": { - "bidder": { - "token": "test-token-1" - } - } - }] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-response-id-2", - "seatbid": [{ - "bid": [{ - "id": "test-bid-id-2", - "impid": "test-impression-id-2", - "price": 2 - }] - }] - } - } - }, { - "expectedRequest": { - "uri": "http://example.com/prebid/test-token-2", - "body": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-3", - "banner": { - "h": 250, - "w": 300 - }, - "ext": { - "bidder": { - "token": "test-token-2" - } - } - }] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-response-id-3", - "seatbid": [{ - "bid": [{ - "id": "test-bid-id-3", - "impid": "test-impression-id-3", - "price": 3 - }] - }] - } - } - }], - "expectedBidResponses": [{ - "bids": [{ - "bid": { - "id": "test-bid-id-1", - "impid": "test-impression-id-1", - "price": 1 - }, - "type": "banner" - }] - }, { - "bids": [{ - "bid": { - "id": "test-bid-id-2", - "impid": "test-impression-id-2", - "price": 2 - }, - "type": "banner" - }] - }, { - "bids": [{ - "bid": { - "id": "test-bid-id-3", - "impid": "test-impression-id-3", - "price": 3 - }, - "type": "banner" - }] - }] -} diff --git a/adapters/applogy/applogytest/exemplary/simple-native.json b/adapters/applogy/applogytest/exemplary/simple-native.json deleted file mode 100644 index 84565ec5575..00000000000 --- a/adapters/applogy/applogytest/exemplary/simple-native.json +++ /dev/null @@ -1,164 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-1", - "native": { - "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}", - "ver": "1.1" - }, - "ext": { - "bidder": { - "token": "test-token-1" - } - } - }, { - "id": "test-impression-id-2", - "native": { - "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}", - "ver": "1.1" - }, - "ext": { - "bidder": { - "token": "test-token-1" - } - } - }, { - "id": "test-impression-id-3", - "native": { - "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}", - "ver": "1.1" - }, - "ext": { - "bidder": { - "token": "test-token-2" - } - } - }] - }, - "httpCalls": [{ - "expectedRequest": { - "uri": "http://example.com/prebid/test-token-1", - "body": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-1", - "native": { - "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}", - "ver": "1.1" - }, - "ext": { - "bidder": { - "token": "test-token-1" - } - } - }] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-response-id", - "seatbid": [{ - "bid": [{ - "id": "test-bid-id-1", - "impid": "test-impression-id-1", - "price": 1 - }] - }] - } - } - }, { - "expectedRequest": { - "uri": "http://example.com/prebid/test-token-1", - "body": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-2", - "native": { - "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}", - "ver": "1.1" - }, - "ext": { - "bidder": { - "token": "test-token-1" - } - } - }] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-response-id-2", - "seatbid": [{ - "bid": [{ - "id": "test-bid-id-2", - "impid": "test-impression-id-2", - "price": 2 - }] - }] - } - } - }, { - "expectedRequest": { - "uri": "http://example.com/prebid/test-token-2", - "body": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-3", - "native": { - "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}", - "ver": "1.1" - }, - "ext": { - "bidder": { - "token": "test-token-2" - } - } - }] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-response-id-3", - "seatbid": [{ - "bid": [{ - "id": "test-bid-id-3", - "impid": "test-impression-id-3", - "price": 3 - }] - }] - } - } - }], - "expectedBidResponses": [{ - "bids": [{ - "bid": { - "id": "test-bid-id-1", - "impid": "test-impression-id-1", - "price": 1 - }, - "type": "native" - }] - }, { - "bids": [{ - "bid": { - "id": "test-bid-id-2", - "impid": "test-impression-id-2", - "price": 2 - }, - "type": "native" - }] - }, { - "bids": [{ - "bid": { - "id": "test-bid-id-3", - "impid": "test-impression-id-3", - "price": 3 - }, - "type": "native" - }] - }] -} diff --git a/adapters/applogy/applogytest/exemplary/simple-video.json b/adapters/applogy/applogytest/exemplary/simple-video.json deleted file mode 100644 index 30237cccd10..00000000000 --- a/adapters/applogy/applogytest/exemplary/simple-video.json +++ /dev/null @@ -1,182 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-1", - "video": { - "w": 900, - "h": 250, - "mimes": [ - "video/mp4" - ] - }, - "ext": { - "bidder": { - "token": "test-token-1" - } - } - }, { - "id": "test-impression-id-2", - "video": { - "w": 900, - "h": 250, - "mimes": [ - "video/mp4" - ] - }, - "ext": { - "bidder": { - "token": "test-token-1" - } - } - }, { - "id": "test-impression-id-3", - "video": { - "w": 900, - "h": 250, - "mimes": [ - "video/mp4" - ] - }, - "ext": { - "bidder": { - "token": "test-token-2" - } - } - }] - }, - "httpCalls": [{ - "expectedRequest": { - "uri": "http://example.com/prebid/test-token-1", - "body": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-1", - "video": { - "w": 900, - "h": 250, - "mimes": [ - "video/mp4" - ] - }, - "ext": { - "bidder": { - "token": "test-token-1" - } - } - }] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-response-id", - "seatbid": [{ - "bid": [{ - "id": "test-bid-id-1", - "impid": "test-impression-id-1", - "price": 1 - }] - }] - } - } - }, { - "expectedRequest": { - "uri": "http://example.com/prebid/test-token-1", - "body": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-2", - "video": { - "w": 900, - "h": 250, - "mimes": [ - "video/mp4" - ] - }, - "ext": { - "bidder": { - "token": "test-token-1" - } - } - }] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-response-id-2", - "seatbid": [{ - "bid": [{ - "id": "test-bid-id-2", - "impid": "test-impression-id-2", - "price": 2 - }] - }] - } - } - }, { - "expectedRequest": { - "uri": "http://example.com/prebid/test-token-2", - "body": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-3", - "video": { - "w": 900, - "h": 250, - "mimes": [ - "video/mp4" - ] - }, - "ext": { - "bidder": { - "token": "test-token-2" - } - } - }] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-response-id-3", - "seatbid": [{ - "bid": [{ - "id": "test-bid-id-3", - "impid": "test-impression-id-3", - "price": 3 - }] - }] - } - } - }], - "expectedBidResponses": [{ - "bids": [{ - "bid": { - "id": "test-bid-id-1", - "impid": "test-impression-id-1", - "price": 1 - }, - "type": "video" - }] - }, { - "bids": [{ - "bid": { - "id": "test-bid-id-2", - "impid": "test-impression-id-2", - "price": 2 - }, - "type": "video" - }] - }, { - "bids": [{ - "bid": { - "id": "test-bid-id-3", - "impid": "test-impression-id-3", - "price": 3 - }, - "type": "video" - }] - }] -} diff --git a/adapters/applogy/applogytest/supplemental/all-failed.json b/adapters/applogy/applogytest/supplemental/all-failed.json deleted file mode 100644 index 7f0244afcfb..00000000000 --- a/adapters/applogy/applogytest/supplemental/all-failed.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-1", - "banner": { - "w": 300, - "h": 250 - } - }] - }, - "expectedMakeRequestsErrors": [{ - "value": "impression extensions required", - "comparison": "literal" - }] -} diff --git a/adapters/applogy/applogytest/supplemental/invalid-params.json b/adapters/applogy/applogytest/supplemental/invalid-params.json deleted file mode 100644 index 6b5d5e3224d..00000000000 --- a/adapters/applogy/applogytest/supplemental/invalid-params.json +++ /dev/null @@ -1,133 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-1", - "banner": {} - }, { - "id": "test-impression-id-2", - "banner": { - "w": 300, - "h": 250 - } - }, { - "id": "test-impression-id-3", - "banner": { - "w": 300, - "h": 250 - }, - "ext": {} - }, { - "id": "test-impression-id-4" - }, { - "id": "test-impression-id-5", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "token": "test-token-5" - } - } - }, { - "id": "test-impression-id-0", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": "invalid bidder" - } - }, { - "id": "test-impression-id-0", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": {} - } - }, { - "id": "test-impression-id-0", - "banner": { - "w": 300, - "h": 250 - }, - "ext": "invalid ext" - }] - }, - "httpCalls": [{ - "expectedRequest": { - "uri": "http://example.com/prebid/test-token-5", - "body": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-5", - "banner": { - "h": 250, - "w": 300 - }, - "ext": { - "bidder": { - "token": "test-token-5" - } - } - }] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-response-id", - "seatbid": [{ - "bid": [{ - "id": "test-bid-id-5", - "impid": "test-impression-id-5", - "price": 5 - }, { - "id": "test-bid-id-6", - "impid": "test-impression-id-6", - "price": 6 - }] - }] - } - } - }], - "expectedBidResponses": [{ - "bids": [{ - "bid": { - "id": "test-bid-id-5", - "impid": "test-impression-id-5", - "price": 5 - }, - "type": "banner" - }] - }], - "expectedMakeRequestsErrors": [{ - "value": "banner size information missing", - "comparison": "literal" - }, { - "value": "impression extensions required", - "comparison": "literal" - }, { - "value": "bidder required", - "comparison": "literal" - }, { - "value": "Applogy only supports banner, video or native ads", - "comparison": "literal" - }, { - "value": "json: cannot unmarshal string into Go value of type openrtb_ext.ExtImpApplogy", - "comparison": "literal" - }, { - "value": "Applogy token required", - "comparison": "literal" - }, { - "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", - "comparison": "literal" - }], - "expectedMakeBidsErrors": [{ - "value": "ignoring bid id=test-bid-id-6, request doesn't contain any valid impression with id=test-impression-id-6", - "comparison": "literal" - }] -} diff --git a/adapters/applogy/applogytest/supplemental/status-204.json b/adapters/applogy/applogytest/supplemental/status-204.json deleted file mode 100644 index 1c849b4fa3a..00000000000 --- a/adapters/applogy/applogytest/supplemental/status-204.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-1", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "token": "test-token-1" - } - } - }] - }, - "httpCalls": [{ - "expectedRequest": { - "uri": "http://example.com/prebid/test-token-1", - "body": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-1", - "banner": { - "h": 250, - "w": 300 - }, - "ext": { - "bidder": { - "token": "test-token-1" - } - } - }] - } - }, - "mockResponse": { - "status": 204, - "body": {} - } - }], - "expectedBidResponses": [] -} diff --git a/adapters/applogy/applogytest/supplemental/status-400.json b/adapters/applogy/applogytest/supplemental/status-400.json deleted file mode 100644 index 95e271bae8e..00000000000 --- a/adapters/applogy/applogytest/supplemental/status-400.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-1", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "token": "test-token-1" - } - } - }] - }, - "httpCalls": [{ - "expectedRequest": { - "uri": "http://example.com/prebid/test-token-1", - "body": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-1", - "banner": { - "h": 250, - "w": 300 - }, - "ext": { - "bidder": { - "token": "test-token-1" - } - } - }] - } - }, - "mockResponse": { - "status": 400, - "body": {} - } - }], - "expectedMakeBidsErrors": [{ - "value": "unexpected status code: 400", - "comparison": "literal" - }] -} diff --git a/adapters/applogy/applogytest/supplemental/status-502.json b/adapters/applogy/applogytest/supplemental/status-502.json deleted file mode 100644 index c0b1641653a..00000000000 --- a/adapters/applogy/applogytest/supplemental/status-502.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-1", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "token": "test-token-1" - } - } - }] - }, - "httpCalls": [{ - "expectedRequest": { - "uri": "http://example.com/prebid/test-token-1", - "body": { - "id": "test-request-id", - "imp": [{ - "id": "test-impression-id-1", - "banner": { - "h": 250, - "w": 300 - }, - "ext": { - "bidder": { - "token": "test-token-1" - } - } - }] - } - }, - "mockResponse": { - "status": 502, - "body": {} - } - }], - "expectedMakeBidsErrors": [{ - "value": "unexpected status code: 502", - "comparison": "literal" - }] -} diff --git a/endpoints/openrtb2/sample-requests/hooks/amp_bidder_reject.json b/endpoints/openrtb2/sample-requests/hooks/amp_bidder_reject.json index c3ce226ff9c..7fc1e7d8721 100644 --- a/endpoints/openrtb2/sample-requests/hooks/amp_bidder_reject.json +++ b/endpoints/openrtb2/sample-requests/hooks/amp_bidder_reject.json @@ -4,7 +4,7 @@ "config": { "mockBidders": [ {"bidderName": "appnexus", "currency": "USD", "price": 2}, - {"bidderName": "applogy", "currency": "USD", "price": 1} + {"bidderName": "rubicon", "currency": "USD", "price": 1} ] }, "mockBidRequest": { @@ -29,7 +29,7 @@ "appnexus": { "placementId": 12883451 }, - "applogy": { + "rubicon": { "placementId": 12883451 } } @@ -42,23 +42,23 @@ "debug": true, "aliases": { "unknown": "appnexus", - "foo": "applogy" + "foo": "rubicon" } } } }, "expectedAmpResponse": { "targeting": { - "hb_bidder": "applogy", - "hb_bidder_applogy": "applogy", + "hb_bidder": "rubicon", + "hb_bidder_rubicon": "rubicon", "hb_cache_host": "www.pbcserver.com", - "hb_cache_host_applog": "www.pbcserver.com", + "hb_cache_host_rubico": "www.pbcserver.com", "hb_cache_id": "0", - "hb_cache_id_applogy": "0", + "hb_cache_id_rubicon": "0", "hb_cache_path": "/pbcache/endpoint", - "hb_cache_path_applog": "/pbcache/endpoint", + "hb_cache_path_rubico": "/pbcache/endpoint", "hb_pb": "1.00", - "hb_pb_applogy": "1.00" + "hb_pb_rubicon": "1.00" }, "ortb2": { "ext": { @@ -103,7 +103,7 @@ ] }, { - "entity": "applogy", + "entity": "rubicon", "groups": [ { "invocation_results": [ diff --git a/endpoints/openrtb2/sample-requests/hooks/amp_bidder_response_reject.json b/endpoints/openrtb2/sample-requests/hooks/amp_bidder_response_reject.json index fe654304c4f..4e38b5a2f2d 100644 --- a/endpoints/openrtb2/sample-requests/hooks/amp_bidder_response_reject.json +++ b/endpoints/openrtb2/sample-requests/hooks/amp_bidder_response_reject.json @@ -4,7 +4,7 @@ "config": { "mockBidders": [ {"bidderName": "appnexus", "currency": "USD", "price": 2}, - {"bidderName": "applogy", "currency": "USD", "price": 1} + {"bidderName": "rubicon", "currency": "USD", "price": 1} ] }, "mockBidRequest": { @@ -29,7 +29,7 @@ "appnexus": { "placementId": 12883451 }, - "applogy": { + "rubicon": { "placementId": 12883451 } } @@ -42,23 +42,23 @@ "debug": true, "aliases": { "unknown": "appnexus", - "foo": "applogy" + "foo": "rubicon" } } } }, "expectedAmpResponse": { "targeting": { - "hb_bidder": "applogy", - "hb_bidder_applogy": "applogy", + "hb_bidder": "rubicon", + "hb_bidder_rubicon": "rubicon", "hb_cache_host": "www.pbcserver.com", - "hb_cache_host_applog": "www.pbcserver.com", + "hb_cache_host_rubico": "www.pbcserver.com", "hb_cache_id": "0", - "hb_cache_id_applogy": "0", + "hb_cache_id_rubicon": "0", "hb_cache_path": "/pbcache/endpoint", - "hb_cache_path_applog": "/pbcache/endpoint", + "hb_cache_path_rubico": "/pbcache/endpoint", "hb_pb": "1.00", - "hb_pb_applogy": "1.00" + "hb_pb_rubicon": "1.00" }, "ortb2": { "ext": { @@ -103,7 +103,7 @@ ] }, { - "entity": "applogy", + "entity": "rubicon", "groups": [ { "invocation_results": [ diff --git a/endpoints/openrtb2/sample-requests/hooks/auction_bidder_reject.json b/endpoints/openrtb2/sample-requests/hooks/auction_bidder_reject.json index bece42277ef..94769e4f6cd 100644 --- a/endpoints/openrtb2/sample-requests/hooks/auction_bidder_reject.json +++ b/endpoints/openrtb2/sample-requests/hooks/auction_bidder_reject.json @@ -3,7 +3,7 @@ "config": { "mockBidders": [ {"bidderName": "appnexus", "currency": "USD", "price": 0.00}, - {"bidderName": "applogy", "currency": "USD", "price": 0.00} + {"bidderName": "rubicon", "currency": "USD", "price": 0.00} ] }, "mockBidRequest": { @@ -26,7 +26,7 @@ "appnexus": { "placementId": 12883451 }, - "applogy": { + "rubicon": { "placementId": 12883451 } } @@ -49,12 +49,12 @@ { "bid": [ { - "id": "applogy-bid", + "id": "rubicon-bid", "impid": "some-impression-id", "price": 0 } ], - "seat": "applogy" + "seat": "rubicon" } ], "ext": { @@ -99,7 +99,7 @@ ] }, { - "entity": "applogy", + "entity": "rubicon", "groups": [ { "invocation_results": [ diff --git a/endpoints/openrtb2/sample-requests/hooks/auction_bidder_response_reject.json b/endpoints/openrtb2/sample-requests/hooks/auction_bidder_response_reject.json index 32743d67b75..6198e3e23bc 100644 --- a/endpoints/openrtb2/sample-requests/hooks/auction_bidder_response_reject.json +++ b/endpoints/openrtb2/sample-requests/hooks/auction_bidder_response_reject.json @@ -3,7 +3,7 @@ "config": { "mockBidders": [ {"bidderName": "appnexus", "currency": "USD", "price": 0.00}, - {"bidderName": "applogy", "currency": "USD", "price": 0.00} + {"bidderName": "rubicon", "currency": "USD", "price": 0.00} ] }, "mockBidRequest": { @@ -26,7 +26,7 @@ "appnexus": { "placementId": 12883451 }, - "applogy": { + "rubicon": { "placementId": 12883451 } } @@ -49,12 +49,12 @@ { "bid": [ { - "id": "applogy-bid", + "id": "rubicon-bid", "impid": "some-impression-id", "price": 0 } ], - "seat": "applogy" + "seat": "rubicon" } ], "ext": { @@ -99,7 +99,7 @@ ] }, { - "entity": "applogy", + "entity": "rubicon", "groups": [ { "invocation_results": [ diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 825eff56353..8e80070bd79 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -34,7 +34,6 @@ import ( "github.com/prebid/prebid-server/adapters/algorix" "github.com/prebid/prebid-server/adapters/amx" "github.com/prebid/prebid-server/adapters/apacdex" - "github.com/prebid/prebid-server/adapters/applogy" "github.com/prebid/prebid-server/adapters/appnexus" "github.com/prebid/prebid-server/adapters/appush" "github.com/prebid/prebid-server/adapters/audienceNetwork" @@ -229,7 +228,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderAlgorix: algorix.Builder, openrtb_ext.BidderAMX: amx.Builder, openrtb_ext.BidderApacdex: apacdex.Builder, - openrtb_ext.BidderApplogy: applogy.Builder, openrtb_ext.BidderAppnexus: appnexus.Builder, openrtb_ext.BidderAppstock: limelightDigital.Builder, openrtb_ext.BidderAppush: appush.Builder, diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index 5a3b8a4ce99..f6c1ffe8b55 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -118,6 +118,7 @@ func GetDisabledBidderWarningMessages(infos config.BidderInfos) map[string]strin "groupm": `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`, "verizonmedia": `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`, "brightroll": `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`, + "applogy": `Bidder "applogy" is no longer available in Prebid Server. Please update your configuration.`, "rhythmone": `Bidder "rhythmone" is no longer available in Prebid Server. Please update your configuration.`, } diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index c2c0725b5e7..e3379358012 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -52,7 +52,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderAlgorix, BidderAMX, BidderApacdex, - BidderApplogy, BidderAppnexus, BidderAppstock, BidderAppush, @@ -347,7 +346,6 @@ const ( BidderAlgorix BidderName = "algorix" BidderAMX BidderName = "amx" BidderApacdex BidderName = "apacdex" - BidderApplogy BidderName = "applogy" BidderAppnexus BidderName = "appnexus" BidderAppstock BidderName = "appstock" BidderAppush BidderName = "appush" diff --git a/openrtb_ext/imp_applogy.go b/openrtb_ext/imp_applogy.go deleted file mode 100644 index 45774a05afb..00000000000 --- a/openrtb_ext/imp_applogy.go +++ /dev/null @@ -1,5 +0,0 @@ -package openrtb_ext - -type ExtImpApplogy struct { - Token string `json:"token"` -} diff --git a/static/bidder-info/applogy.yaml b/static/bidder-info/applogy.yaml deleted file mode 100644 index 62a70a17f28..00000000000 --- a/static/bidder-info/applogy.yaml +++ /dev/null @@ -1,14 +0,0 @@ -endpoint: "http://rtb.applogy.com/v1/prebid" -maintainer: - email: work@applogy.com -capabilities: - app: - mediaTypes: - - banner - - video - - native - site: - mediaTypes: - - banner - - video - - native diff --git a/static/bidder-params/applogy.json b/static/bidder-params/applogy.json deleted file mode 100644 index 2650640c115..00000000000 --- a/static/bidder-params/applogy.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Applogy Adapter Params", - "description": "A schema which validates params accepted by the Applogy adapter", - "type": "object", - "properties": { - "token": { - "type": "string", - "description": "Applogy token" - } - }, - "required": ["token"] -} From aff482fb9476391e899feffd929503b3042bb810 Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Tue, 26 Sep 2023 05:08:07 -0400 Subject: [PATCH 136/268] Remove Adapter: Define Media (#3132) Co-authored-by: Ashish Garg --- adapters/definemedia/definemedia.go | 109 ------- adapters/definemedia/definemedia_test.go | 21 -- .../exemplary/sample-conative-banner.json | 270 ------------------ .../exemplary/sample-conative-native.json | 257 ----------------- .../supplemental/nobid-response.json | 222 -------------- .../supplemental/nocontent-response.json | 219 -------------- .../supplemental/status_400.json | 224 --------------- .../supplemental/status_418.json | 224 --------------- .../supplemental/unmarshal-error.json | 224 --------------- .../supplemental/unsupported-type.json | 250 ---------------- adapters/definemedia/params_test.go | 48 ---- exchange/adapter_builders.go | 2 - exchange/adapter_util.go | 1 + openrtb_ext/bidders.go | 2 - openrtb_ext/imp_definemedia.go | 6 - static/bidder-info/definemedia.yaml | 10 - static/bidder-params/definemedia.json | 19 -- 17 files changed, 1 insertion(+), 2107 deletions(-) delete mode 100644 adapters/definemedia/definemedia.go delete mode 100644 adapters/definemedia/definemedia_test.go delete mode 100644 adapters/definemedia/definemediatest/exemplary/sample-conative-banner.json delete mode 100644 adapters/definemedia/definemediatest/exemplary/sample-conative-native.json delete mode 100644 adapters/definemedia/definemediatest/supplemental/nobid-response.json delete mode 100644 adapters/definemedia/definemediatest/supplemental/nocontent-response.json delete mode 100644 adapters/definemedia/definemediatest/supplemental/status_400.json delete mode 100644 adapters/definemedia/definemediatest/supplemental/status_418.json delete mode 100644 adapters/definemedia/definemediatest/supplemental/unmarshal-error.json delete mode 100644 adapters/definemedia/definemediatest/supplemental/unsupported-type.json delete mode 100644 adapters/definemedia/params_test.go delete mode 100644 openrtb_ext/imp_definemedia.go delete mode 100644 static/bidder-info/definemedia.yaml delete mode 100644 static/bidder-params/definemedia.json diff --git a/adapters/definemedia/definemedia.go b/adapters/definemedia/definemedia.go deleted file mode 100644 index 3e014e3c16d..00000000000 --- a/adapters/definemedia/definemedia.go +++ /dev/null @@ -1,109 +0,0 @@ -package definemedia - -import ( - "encoding/json" - "fmt" - "net/http" - - "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" -) - -type adapter struct { - endpoint string -} - -// Builder builds a new instance of the Foo adapter for the given bidder with the given config. -func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { - bidder := &adapter{ - endpoint: config.Endpoint, - } - return bidder, nil -} - -// MakeRequests makes the HTTP requests which should be made to fetch bids. -func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - var errors []error - requestJSON, err := json.Marshal(request) - if err != nil { - errors = append(errors, err) - return nil, errors - } - - requestData := &adapters.RequestData{ - Method: "POST", - Uri: a.endpoint, - Body: requestJSON, - } - - return []*adapters.RequestData{requestData}, errors - -} - -func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { - if response.StatusCode == http.StatusNoContent { - return nil, nil - } - - if response.StatusCode == http.StatusBadRequest { - return nil, []error{&errortypes.BadInput{ - Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), - }} - } - - if response.StatusCode != http.StatusOK { - return nil, []error{&errortypes.BadServerResponse{ - Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), - }} - } - - var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { - return nil, []error{err} - } - - bidsCapacity := 1 - if len(bidResp.SeatBid) > 0 { - bidsCapacity = len(bidResp.SeatBid[0].Bid) - } - bidResponse := adapters.NewBidderResponseWithBidsCapacity(bidsCapacity) - var errors []error - for _, sb := range bidResp.SeatBid { - for i, bid := range sb.Bid { - bidType, err := getMediaTypeForBid(bid) - if err != nil { - errors = append(errors, err) - continue - } - bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ - Bid: &sb.Bid[i], - BidType: bidType, - }) - - } - } - - return bidResponse, errors -} - -func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { - if bid.Ext != nil { - var bidExt openrtb_ext.ExtBid - err := json.Unmarshal(bid.Ext, &bidExt) - if err == nil && bidExt.Prebid != nil { - if (bidExt.Prebid.Type == openrtb_ext.BidTypeBanner) || (bidExt.Prebid.Type == openrtb_ext.BidTypeNative) { - return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type)) - } - return "", &errortypes.BadServerResponse{ - Message: fmt.Sprintf("Invalid mediatype in the impression"), - } - } - } - - return "", &errortypes.BadServerResponse{ - Message: fmt.Sprintf("Failed to parse impression \"%s\" mediatype", bid.ImpID), - } -} diff --git a/adapters/definemedia/definemedia_test.go b/adapters/definemedia/definemedia_test.go deleted file mode 100644 index 3ed0cb938b8..00000000000 --- a/adapters/definemedia/definemedia_test.go +++ /dev/null @@ -1,21 +0,0 @@ -package definemedia - -import ( - "testing" - - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" -) - -func TestJsonSamples(t *testing.T) { - bidder, buildErr := Builder(openrtb_ext.BidderDefinemedia, config.Adapter{ - Endpoint: "https://rtb.conative.network/openrtb2/auction"}, - config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - if buildErr != nil { - t.Fatalf("Builder returned unexpected error %v", buildErr) - } - - adapterstest.RunJSONBidderTest(t, "definemediatest", bidder) -} diff --git a/adapters/definemedia/definemediatest/exemplary/sample-conative-banner.json b/adapters/definemedia/definemediatest/exemplary/sample-conative-banner.json deleted file mode 100644 index a7d7e411f78..00000000000 --- a/adapters/definemedia/definemediatest/exemplary/sample-conative-banner.json +++ /dev/null @@ -1,270 +0,0 @@ -{ - "mockBidRequest": { - "imp": [ - { - "ext": { - "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9", - "prebid": { - "bidder": { - "definemedia": { - "mandantId": 12 - } - } - } - }, - "id": "div-gpt-ad-1460505748561-0", - "banner": { - "topframe": 1, - "format": [ - { - "w": 300, - "h": 250 - } - ] - } - } - ], - "site": { - "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", - "domain": "localhost:8080", - "publisher": { - "domain": "localhost:8080", - "id": "1" - } - }, - "device": { - "w": 1098, - "h": 1169, - "dnt": 0, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "language": "de", - "sua": { - "source": 2, - "platform": { - "brand": "macOS", - "version": [ - "12", - "3", - "1" - ] - }, - "browsers": [ - { - "brand": "Not?A_Brand", - "version": [ - "8", - "0", - "0", - "0" - ] - }, - { - "brand": "Chromium", - "version": [ - "108", - "0", - "5359", - "124" - ] - }, - { - "brand": "Google Chrome", - "version": [ - "108", - "0", - "5359", - "124" - ] - } - ], - "mobile": 0, - "model": "", - "bitness": "64", - "architecture": "x86" - } - }, - "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", - "test": 0, - "source": { - "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" - }, - "ext": { - "prebid": { - "auctiontimestamp": 1671449004622, - "targeting": { - "includewinners": true, - "includebidderkeys": false - }, - "debug": true, - "channel": { - "name": "pbjs", - "version": "v7.28.0" - } - } - }, - "tmax": 1000 - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://rtb.conative.network/openrtb2/auction", - "body": { - "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", - "imp": [ - { - "id": "div-gpt-ad-1460505748561-0", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ], - "topframe": 1 - }, - "ext": { - "prebid": { - "bidder": { - "definemedia": { - "mandantId": 12 - } - } - }, - "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9" - } - } - ], - "site": { - "domain": "localhost:8080", - "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", - "publisher": { - "id": "1", - "domain": "localhost:8080" - } - }, - "device": { - "dnt": 0, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "sua": { - "browsers": [ - { - "brand": "Not?A_Brand", - "version": [ - "8", - "0", - "0", - "0" - ] - }, - { - "brand": "Chromium", - "version": [ - "108", - "0", - "5359", - "124" - ] - }, - { - "brand": "Google Chrome", - "version": [ - "108", - "0", - "5359", - "124" - ] - } - ], - "platform": { - "brand": "macOS", - "version": [ - "12", - "3", - "1" - ] - }, - "mobile": 0, - "architecture": "x86", - "bitness": "64", - "source": 2 - }, - "h": 1169, - "w": 1098, - "language": "de" - }, - "tmax": 1000, - "source": { - "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" - }, - "ext": { - "prebid": { - "auctiontimestamp": 1.671449004622e+12, - "channel": { - "name": "pbjs", - "version": "v7.28.0" - }, - "debug": true, - "targeting": { - "includebidderkeys": false, - "includewinners": true - } - } - } - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "bid": [ - { - "id": "46189656-7e2e-477d-b7f2-e05de224bb89", - "impid": "div-gpt-ad-1460505748561-0", - "price": 100, - "adm": "{banner html}", - "adomain": [ - "test.com" - ], - "crid": "test-creative-id", - "ext": { - "prebid": { - "type": "banner" - } - } - } - ] - } - ], - "cur": "USD" - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "46189656-7e2e-477d-b7f2-e05de224bb89", - "impid": "div-gpt-ad-1460505748561-0", - "price": 100, - "adm": "{banner html}", - "crid": "test-creative-id", - "adomain": [ - "test.com" - ], - "ext": { - "prebid": { - "type": "banner" - } - } - }, - "type": "banner" - } - ] - } - ] -} \ No newline at end of file diff --git a/adapters/definemedia/definemediatest/exemplary/sample-conative-native.json b/adapters/definemedia/definemediatest/exemplary/sample-conative-native.json deleted file mode 100644 index 4fe56a4c22e..00000000000 --- a/adapters/definemedia/definemediatest/exemplary/sample-conative-native.json +++ /dev/null @@ -1,257 +0,0 @@ -{ - "mockBidRequest": { - "imp": [ - { - "ext": { - "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9", - "prebid": { - "bidder": { - "definemedia": { - "mandantId": 12 - } - } - } - }, - "id": "div-gpt-ad-1460505748561-0", - "native": {} - } - ], - "site": { - "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", - "domain": "localhost:8080", - "publisher": { - "domain": "localhost:8080", - "id": "1" - } - }, - "device": { - "w": 1098, - "h": 1169, - "dnt": 0, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "language": "de", - "sua": { - "source": 2, - "platform": { - "brand": "macOS", - "version": [ - "12", - "3", - "1" - ] - }, - "browsers": [ - { - "brand": "Not?A_Brand", - "version": [ - "8", - "0", - "0", - "0" - ] - }, - { - "brand": "Chromium", - "version": [ - "108", - "0", - "5359", - "124" - ] - }, - { - "brand": "Google Chrome", - "version": [ - "108", - "0", - "5359", - "124" - ] - } - ], - "mobile": 0, - "model": "", - "bitness": "64", - "architecture": "x86" - } - }, - "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", - "test": 0, - "source": { - "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" - }, - "ext": { - "prebid": { - "auctiontimestamp": 1671449004622, - "targeting": { - "includewinners": true, - "includebidderkeys": false - }, - "debug": true, - "channel": { - "name": "pbjs", - "version": "v7.28.0" - } - } - }, - "tmax": 1000 - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://rtb.conative.network/openrtb2/auction", - "body": { - "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", - "imp": [ - { - "id": "div-gpt-ad-1460505748561-0", - "native": { - "request": "" - }, - "ext": { - "prebid": { - "bidder": { - "definemedia": { - "mandantId": 12 - } - } - }, - "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9" - } - } - ], - "site": { - "domain": "localhost:8080", - "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", - "publisher": { - "id": "1", - "domain": "localhost:8080" - } - }, - "device": { - "dnt": 0, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "sua": { - "browsers": [ - { - "brand": "Not?A_Brand", - "version": [ - "8", - "0", - "0", - "0" - ] - }, - { - "brand": "Chromium", - "version": [ - "108", - "0", - "5359", - "124" - ] - }, - { - "brand": "Google Chrome", - "version": [ - "108", - "0", - "5359", - "124" - ] - } - ], - "platform": { - "brand": "macOS", - "version": [ - "12", - "3", - "1" - ] - }, - "mobile": 0, - "architecture": "x86", - "bitness": "64", - "source": 2 - }, - "h": 1169, - "w": 1098, - "language": "de" - }, - "tmax": 1000, - "source": { - "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" - }, - "ext": { - "prebid": { - "auctiontimestamp": 1.671449004622e+12, - "channel": { - "name": "pbjs", - "version": "v7.28.0" - }, - "debug": true, - "targeting": { - "includebidderkeys": false, - "includewinners": true - } - } - } - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "bid": [ - { - "id": "46189656-7e2e-477d-b7f2-e05de224bb89", - "impid": "div-gpt-ad-1460505748561-0", - "price": 100, - "adm": "{\n \"ver\": \"1.1\",\n \"imptrackers\": [\"http://imptracker.com\"],\n \"jstracker\": \"\u003cscript\u003etrack()\u003c/script\u003e\",\n \"link\": {\n \"url\": \"http://i.am.a/URL\"\n },\n \"assets\": [\n {\n \"id\": 123,\n \"required\": 1,\n \"title\": {\n \"text\": \"Learn about this awesome thing\"\n }\n },\n {\n \"id\": 124,\n \"required\": 1,\n \"img\": {\n \"url\": \"http://www.myads.com/thumbnail1.png\"\n }\n },\n {\n \"id\": 128,\n \"required\": 1,\n \"img\": {\n \"url\": \"http://www.myads.com/largethumb1.png\"\n }\n },\n {\n \"id\": 126,\n \"required\": 1,\n \"data\": {\n \"value\": \"My Brand\"\n }\n },\n {\n \"id\": 127,\n \"required\": 1,\n \"data\": {\n \"value\": \"Learn all about this awesome story of someone using my product.\"\n }\n },\n {\n \"id\": 4,\n \"video\": {\n \"vasttag\": \"\u003cVAST version=\\\"2.0\\\"\u003e\u003c/VAST\u003e\"\n }\n },\n {\n \"id\": 5,\n \"link\": {\n \"url\": \"http://landing.com\",\n \"clicktrackers\": [\"http://tracker.com\"],\n \"fallback\": \"http://fallback.com\"\n }\n }\n ]\n}", - "adomain": [ - "test.com" - ], - "crid": "test-creative-id", - "ext": { - "prebid": { - "type": "native" - } - } - } - ] - } - ], - "cur": "USD" - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "46189656-7e2e-477d-b7f2-e05de224bb89", - "impid": "div-gpt-ad-1460505748561-0", - "price": 100, - - "adm": "{\n \"ver\": \"1.1\",\n \"imptrackers\": [\"http://imptracker.com\"],\n \"jstracker\": \"\u003cscript\u003etrack()\u003c/script\u003e\",\n \"link\": {\n \"url\": \"http://i.am.a/URL\"\n },\n \"assets\": [\n {\n \"id\": 123,\n \"required\": 1,\n \"title\": {\n \"text\": \"Learn about this awesome thing\"\n }\n },\n {\n \"id\": 124,\n \"required\": 1,\n \"img\": {\n \"url\": \"http://www.myads.com/thumbnail1.png\"\n }\n },\n {\n \"id\": 128,\n \"required\": 1,\n \"img\": {\n \"url\": \"http://www.myads.com/largethumb1.png\"\n }\n },\n {\n \"id\": 126,\n \"required\": 1,\n \"data\": {\n \"value\": \"My Brand\"\n }\n },\n {\n \"id\": 127,\n \"required\": 1,\n \"data\": {\n \"value\": \"Learn all about this awesome story of someone using my product.\"\n }\n },\n {\n \"id\": 4,\n \"video\": {\n \"vasttag\": \"\u003cVAST version=\\\"2.0\\\"\u003e\u003c/VAST\u003e\"\n }\n },\n {\n \"id\": 5,\n \"link\": {\n \"url\": \"http://landing.com\",\n \"clicktrackers\": [\"http://tracker.com\"],\n \"fallback\": \"http://fallback.com\"\n }\n }\n ]\n}", - "crid": "test-creative-id", - "adomain": [ - "test.com" - ], - "ext": { - "prebid": { - "type": "native" - } - } - }, - "type": "native" - } - ] - } - ] -} \ No newline at end of file diff --git a/adapters/definemedia/definemediatest/supplemental/nobid-response.json b/adapters/definemedia/definemediatest/supplemental/nobid-response.json deleted file mode 100644 index aaa942da76e..00000000000 --- a/adapters/definemedia/definemediatest/supplemental/nobid-response.json +++ /dev/null @@ -1,222 +0,0 @@ -{ - "mockBidRequest": { - "imp": [ - { - "ext": { - "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9", - "prebid": { - "bidder": { - "definemedia": {} - } - } - }, - "id": "div-gpt-ad-1460505748561-0", - "banner": { - "topframe": 1, - "format": [ - { - "w": 300, - "h": 250 - } - ] - } - } - ], - "site": { - "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", - "domain": "localhost:8080", - "publisher": { - "domain": "localhost:8080", - "id": "1" - } - }, - "device": { - "w": 1098, - "h": 1169, - "dnt": 0, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "language": "de", - "sua": { - "source": 2, - "platform": { - "brand": "macOS", - "version": [ - "12", - "3", - "1" - ] - }, - "browsers": [ - { - "brand": "Not?A_Brand", - "version": [ - "8", - "0", - "0", - "0" - ] - }, - { - "brand": "Chromium", - "version": [ - "108", - "0", - "5359", - "124" - ] - }, - { - "brand": "Google Chrome", - "version": [ - "108", - "0", - "5359", - "124" - ] - } - ], - "mobile": 0, - "model": "", - "bitness": "64", - "architecture": "x86" - } - }, - "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", - "test": 0, - "source": { - "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" - }, - "ext": { - "prebid": { - "auctiontimestamp": 1671449004622, - "targeting": { - "includewinners": true, - "includebidderkeys": false - }, - "debug": true, - "channel": { - "name": "pbjs", - "version": "v7.28.0" - } - } - }, - "tmax": 1000 - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://rtb.conative.network/openrtb2/auction", - "body": { - "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", - "imp": [ - { - "id": "div-gpt-ad-1460505748561-0", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ], - "topframe": 1 - }, - "ext": { - "prebid": { - "bidder": { - "definemedia": {} - } - }, - "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9" - } - } - ], - "site": { - "domain": "localhost:8080", - "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", - "publisher": { - "id": "1", - "domain": "localhost:8080" - } - }, - "device": { - "dnt": 0, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "sua": { - "browsers": [ - { - "brand": "Not?A_Brand", - "version": [ - "8", - "0", - "0", - "0" - ] - }, - { - "brand": "Chromium", - "version": [ - "108", - "0", - "5359", - "124" - ] - }, - { - "brand": "Google Chrome", - "version": [ - "108", - "0", - "5359", - "124" - ] - } - ], - "platform": { - "brand": "macOS", - "version": [ - "12", - "3", - "1" - ] - }, - "mobile": 0, - "architecture": "x86", - "bitness": "64", - "source": 2 - }, - "h": 1169, - "w": 1098, - "language": "de" - }, - "tmax": 1000, - "source": { - "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" - }, - "ext": { - "prebid": { - "auctiontimestamp": 1.671449004622e+12, - "channel": { - "name": "pbjs", - "version": "v7.28.0" - }, - "debug": true, - "targeting": { - "includebidderkeys": false, - "includewinners": true - } - } - } - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": null, - "cur": null - } - } - } - ], - "expectedBidResponses": [{"currency":"USD","bids":[]}] - } diff --git a/adapters/definemedia/definemediatest/supplemental/nocontent-response.json b/adapters/definemedia/definemediatest/supplemental/nocontent-response.json deleted file mode 100644 index 147d2185e1f..00000000000 --- a/adapters/definemedia/definemediatest/supplemental/nocontent-response.json +++ /dev/null @@ -1,219 +0,0 @@ -{ - "mockBidRequest": { - "imp": [ - { - "ext": { - "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9", - "prebid": { - "bidder": { - "definemedia": {} - } - } - }, - "id": "div-gpt-ad-1460505748561-0", - "banner": { - "topframe": 1, - "format": [ - { - "w": 300, - "h": 250 - } - ] - } - } - ], - "site": { - "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", - "domain": "localhost:8080", - "publisher": { - "domain": "localhost:8080", - "id": "1" - } - }, - "device": { - "w": 1098, - "h": 1169, - "dnt": 0, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "language": "de", - "sua": { - "source": 2, - "platform": { - "brand": "macOS", - "version": [ - "12", - "3", - "1" - ] - }, - "browsers": [ - { - "brand": "Not?A_Brand", - "version": [ - "8", - "0", - "0", - "0" - ] - }, - { - "brand": "Chromium", - "version": [ - "108", - "0", - "5359", - "124" - ] - }, - { - "brand": "Google Chrome", - "version": [ - "108", - "0", - "5359", - "124" - ] - } - ], - "mobile": 0, - "model": "", - "bitness": "64", - "architecture": "x86" - } - }, - "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", - "test": 0, - "source": { - "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" - }, - "ext": { - "prebid": { - "auctiontimestamp": 1671449004622, - "targeting": { - "includewinners": true, - "includebidderkeys": false - }, - "debug": true, - "channel": { - "name": "pbjs", - "version": "v7.28.0" - } - } - }, - "tmax": 1000 - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://rtb.conative.network/openrtb2/auction", - "body": { - "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", - "imp": [ - { - "id": "div-gpt-ad-1460505748561-0", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ], - "topframe": 1 - }, - "ext": { - "prebid": { - "bidder": { - "definemedia": {} - } - }, - "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9" - } - } - ], - "site": { - "domain": "localhost:8080", - "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", - "publisher": { - "id": "1", - "domain": "localhost:8080" - } - }, - "device": { - "dnt": 0, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "sua": { - "browsers": [ - { - "brand": "Not?A_Brand", - "version": [ - "8", - "0", - "0", - "0" - ] - }, - { - "brand": "Chromium", - "version": [ - "108", - "0", - "5359", - "124" - ] - }, - { - "brand": "Google Chrome", - "version": [ - "108", - "0", - "5359", - "124" - ] - } - ], - "platform": { - "brand": "macOS", - "version": [ - "12", - "3", - "1" - ] - }, - "mobile": 0, - "architecture": "x86", - "bitness": "64", - "source": 2 - }, - "h": 1169, - "w": 1098, - "language": "de" - }, - "tmax": 1000, - "source": { - "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" - }, - "ext": { - "prebid": { - "auctiontimestamp": 1.671449004622e+12, - "channel": { - "name": "pbjs", - "version": "v7.28.0" - }, - "debug": true, - "targeting": { - "includebidderkeys": false, - "includewinners": true - } - } - } - } - }, - "mockResponse": { - "status": 204, - "body": {} - } - } - ], - "expectedBidResponses": [], - "expectedMakeBidsErrors": [] - } \ No newline at end of file diff --git a/adapters/definemedia/definemediatest/supplemental/status_400.json b/adapters/definemedia/definemediatest/supplemental/status_400.json deleted file mode 100644 index ec772bf8428..00000000000 --- a/adapters/definemedia/definemediatest/supplemental/status_400.json +++ /dev/null @@ -1,224 +0,0 @@ -{ - "mockBidRequest": { - "imp": [ - { - "ext": { - "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9", - "prebid": { - "bidder": { - "definemedia": {} - } - } - }, - "id": "div-gpt-ad-1460505748561-0", - "banner": { - "topframe": 1, - "format": [ - { - "w": 300, - "h": 250 - } - ] - } - } - ], - "site": { - "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", - "domain": "localhost:8080", - "publisher": { - "domain": "localhost:8080", - "id": "1" - } - }, - "device": { - "w": 1098, - "h": 1169, - "dnt": 0, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "language": "de", - "sua": { - "source": 2, - "platform": { - "brand": "macOS", - "version": [ - "12", - "3", - "1" - ] - }, - "browsers": [ - { - "brand": "Not?A_Brand", - "version": [ - "8", - "0", - "0", - "0" - ] - }, - { - "brand": "Chromium", - "version": [ - "108", - "0", - "5359", - "124" - ] - }, - { - "brand": "Google Chrome", - "version": [ - "108", - "0", - "5359", - "124" - ] - } - ], - "mobile": 0, - "model": "", - "bitness": "64", - "architecture": "x86" - } - }, - "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", - "test": 0, - "source": { - "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" - }, - "ext": { - "prebid": { - "auctiontimestamp": 1671449004622, - "targeting": { - "includewinners": true, - "includebidderkeys": false - }, - "debug": true, - "channel": { - "name": "pbjs", - "version": "v7.28.0" - } - } - }, - "tmax": 1000 - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://rtb.conative.network/openrtb2/auction", - "body": { - "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", - "imp": [ - { - "id": "div-gpt-ad-1460505748561-0", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ], - "topframe": 1 - }, - "ext": { - "prebid": { - "bidder": { - "definemedia": {} - } - }, - "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9" - } - } - ], - "site": { - "domain": "localhost:8080", - "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", - "publisher": { - "id": "1", - "domain": "localhost:8080" - } - }, - "device": { - "dnt": 0, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "sua": { - "browsers": [ - { - "brand": "Not?A_Brand", - "version": [ - "8", - "0", - "0", - "0" - ] - }, - { - "brand": "Chromium", - "version": [ - "108", - "0", - "5359", - "124" - ] - }, - { - "brand": "Google Chrome", - "version": [ - "108", - "0", - "5359", - "124" - ] - } - ], - "platform": { - "brand": "macOS", - "version": [ - "12", - "3", - "1" - ] - }, - "mobile": 0, - "architecture": "x86", - "bitness": "64", - "source": 2 - }, - "h": 1169, - "w": 1098, - "language": "de" - }, - "tmax": 1000, - "source": { - "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" - }, - "ext": { - "prebid": { - "auctiontimestamp": 1.671449004622e+12, - "channel": { - "name": "pbjs", - "version": "v7.28.0" - }, - "debug": true, - "targeting": { - "includebidderkeys": false, - "includewinners": true - } - } - } - } - }, - "mockResponse": { - "status": 400, - "body": {} - } - } - ], - "expectedBidResponses": [], - "expectedMakeBidsErrors": [ - { - "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", - "comparison": "literal" - } - ] - } \ No newline at end of file diff --git a/adapters/definemedia/definemediatest/supplemental/status_418.json b/adapters/definemedia/definemediatest/supplemental/status_418.json deleted file mode 100644 index 6e82f90476e..00000000000 --- a/adapters/definemedia/definemediatest/supplemental/status_418.json +++ /dev/null @@ -1,224 +0,0 @@ -{ - "mockBidRequest": { - "imp": [ - { - "ext": { - "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9", - "prebid": { - "bidder": { - "definemedia": {} - } - } - }, - "id": "div-gpt-ad-1460505748561-0", - "banner": { - "topframe": 1, - "format": [ - { - "w": 300, - "h": 250 - } - ] - } - } - ], - "site": { - "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", - "domain": "localhost:8080", - "publisher": { - "domain": "localhost:8080", - "id": "1" - } - }, - "device": { - "w": 1098, - "h": 1169, - "dnt": 0, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "language": "de", - "sua": { - "source": 2, - "platform": { - "brand": "macOS", - "version": [ - "12", - "3", - "1" - ] - }, - "browsers": [ - { - "brand": "Not?A_Brand", - "version": [ - "8", - "0", - "0", - "0" - ] - }, - { - "brand": "Chromium", - "version": [ - "108", - "0", - "5359", - "124" - ] - }, - { - "brand": "Google Chrome", - "version": [ - "108", - "0", - "5359", - "124" - ] - } - ], - "mobile": 0, - "model": "", - "bitness": "64", - "architecture": "x86" - } - }, - "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", - "test": 0, - "source": { - "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" - }, - "ext": { - "prebid": { - "auctiontimestamp": 1671449004622, - "targeting": { - "includewinners": true, - "includebidderkeys": false - }, - "debug": true, - "channel": { - "name": "pbjs", - "version": "v7.28.0" - } - } - }, - "tmax": 1000 - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://rtb.conative.network/openrtb2/auction", - "body": { - "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", - "imp": [ - { - "id": "div-gpt-ad-1460505748561-0", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ], - "topframe": 1 - }, - "ext": { - "prebid": { - "bidder": { - "definemedia": {} - } - }, - "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9" - } - } - ], - "site": { - "domain": "localhost:8080", - "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", - "publisher": { - "id": "1", - "domain": "localhost:8080" - } - }, - "device": { - "dnt": 0, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "sua": { - "browsers": [ - { - "brand": "Not?A_Brand", - "version": [ - "8", - "0", - "0", - "0" - ] - }, - { - "brand": "Chromium", - "version": [ - "108", - "0", - "5359", - "124" - ] - }, - { - "brand": "Google Chrome", - "version": [ - "108", - "0", - "5359", - "124" - ] - } - ], - "platform": { - "brand": "macOS", - "version": [ - "12", - "3", - "1" - ] - }, - "mobile": 0, - "architecture": "x86", - "bitness": "64", - "source": 2 - }, - "h": 1169, - "w": 1098, - "language": "de" - }, - "tmax": 1000, - "source": { - "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" - }, - "ext": { - "prebid": { - "auctiontimestamp": 1.671449004622e+12, - "channel": { - "name": "pbjs", - "version": "v7.28.0" - }, - "debug": true, - "targeting": { - "includebidderkeys": false, - "includewinners": true - } - } - } - } - }, - "mockResponse": { - "status": 418, - "body": {} - } - } - ], - "expectedBidResponses": [], - "expectedMakeBidsErrors": [ - { - "value": "Unexpected status code: 418. Run with request.debug = 1 for more info", - "comparison": "literal" - } - ] - } \ No newline at end of file diff --git a/adapters/definemedia/definemediatest/supplemental/unmarshal-error.json b/adapters/definemedia/definemediatest/supplemental/unmarshal-error.json deleted file mode 100644 index 396d6821c36..00000000000 --- a/adapters/definemedia/definemediatest/supplemental/unmarshal-error.json +++ /dev/null @@ -1,224 +0,0 @@ -{ - "mockBidRequest": { - "imp": [ - { - "ext": { - "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9", - "prebid": { - "bidder": { - "definemedia": {} - } - } - }, - "id": "div-gpt-ad-1460505748561-0", - "banner": { - "topframe": 1, - "format": [ - { - "w": 300, - "h": 250 - } - ] - } - } - ], - "site": { - "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", - "domain": "localhost:8080", - "publisher": { - "domain": "localhost:8080", - "id": "1" - } - }, - "device": { - "w": 1098, - "h": 1169, - "dnt": 0, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "language": "de", - "sua": { - "source": 2, - "platform": { - "brand": "macOS", - "version": [ - "12", - "3", - "1" - ] - }, - "browsers": [ - { - "brand": "Not?A_Brand", - "version": [ - "8", - "0", - "0", - "0" - ] - }, - { - "brand": "Chromium", - "version": [ - "108", - "0", - "5359", - "124" - ] - }, - { - "brand": "Google Chrome", - "version": [ - "108", - "0", - "5359", - "124" - ] - } - ], - "mobile": 0, - "model": "", - "bitness": "64", - "architecture": "x86" - } - }, - "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", - "test": 0, - "source": { - "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" - }, - "ext": { - "prebid": { - "auctiontimestamp": 1671449004622, - "targeting": { - "includewinners": true, - "includebidderkeys": false - }, - "debug": true, - "channel": { - "name": "pbjs", - "version": "v7.28.0" - } - } - }, - "tmax": 1000 - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://rtb.conative.network/openrtb2/auction", - "body": { - "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", - "imp": [ - { - "id": "div-gpt-ad-1460505748561-0", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ], - "topframe": 1 - }, - "ext": { - "prebid": { - "bidder": { - "definemedia": {} - } - }, - "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9" - } - } - ], - "site": { - "domain": "localhost:8080", - "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", - "publisher": { - "id": "1", - "domain": "localhost:8080" - } - }, - "device": { - "dnt": 0, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "sua": { - "browsers": [ - { - "brand": "Not?A_Brand", - "version": [ - "8", - "0", - "0", - "0" - ] - }, - { - "brand": "Chromium", - "version": [ - "108", - "0", - "5359", - "124" - ] - }, - { - "brand": "Google Chrome", - "version": [ - "108", - "0", - "5359", - "124" - ] - } - ], - "platform": { - "brand": "macOS", - "version": [ - "12", - "3", - "1" - ] - }, - "mobile": 0, - "architecture": "x86", - "bitness": "64", - "source": 2 - }, - "h": 1169, - "w": 1098, - "language": "de" - }, - "tmax": 1000, - "source": { - "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" - }, - "ext": { - "prebid": { - "auctiontimestamp": 1.671449004622e+12, - "channel": { - "name": "pbjs", - "version": "v7.28.0" - }, - "debug": true, - "targeting": { - "includebidderkeys": false, - "includewinners": true - } - } - } - } - }, - "mockResponse": { - "status": 200, - "body": "fail for unmarshall" - } - } - ], - "expectedBidResponses": [], - "expectedMakeBidsErrors": [ - { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", - "comparison": "literal" - } - ] - } \ No newline at end of file diff --git a/adapters/definemedia/definemediatest/supplemental/unsupported-type.json b/adapters/definemedia/definemediatest/supplemental/unsupported-type.json deleted file mode 100644 index 91bfbc413c1..00000000000 --- a/adapters/definemedia/definemediatest/supplemental/unsupported-type.json +++ /dev/null @@ -1,250 +0,0 @@ -{ - "mockBidRequest": { - "imp": [ - { - "ext": { - "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9", - "prebid": { - "bidder": { - "definemedia": {} - } - } - }, - "id": "div-gpt-ad-1460505748561-0", - "video": { - "w": 300, - "h": 250, - "maxduration": 60, - "minduration": 1, - "api": [1, 2, 5, 6, 7], - "mimes": ["video/mp4"], - "placement": 4, - "protocols": [2] - } - } - ], - "site": { - "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", - "domain": "localhost:8080", - "publisher": { - "domain": "localhost:8080", - "id": "1" - } - }, - "device": { - "w": 1098, - "h": 1169, - "dnt": 0, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "language": "de", - "sua": { - "source": 2, - "platform": { - "brand": "macOS", - "version": [ - "12", - "3", - "1" - ] - }, - "browsers": [ - { - "brand": "Not?A_Brand", - "version": [ - "8", - "0", - "0", - "0" - ] - }, - { - "brand": "Chromium", - "version": [ - "108", - "0", - "5359", - "124" - ] - }, - { - "brand": "Google Chrome", - "version": [ - "108", - "0", - "5359", - "124" - ] - } - ], - "mobile": 0, - "model": "", - "bitness": "64", - "architecture": "x86" - } - }, - "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", - "test": 0, - "source": { - "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" - }, - "ext": { - "prebid": { - "auctiontimestamp": 1671449004622, - "targeting": { - "includewinners": true, - "includebidderkeys": false - }, - "debug": true, - "channel": { - "name": "pbjs", - "version": "v7.28.0" - } - } - }, - "tmax": 1000 - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://rtb.conative.network/openrtb2/auction", - "body": { - "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", - "imp": [ - { - "id": "div-gpt-ad-1460505748561-0", - "video": { - "w": 300, - "h": 250, - "maxduration": 60, - "minduration": 1, - "api": [1, 2, 5, 6, 7], - "mimes": ["video/mp4"], - "placement": 4, - "protocols": [2] - }, - "ext": { - "prebid": { - "bidder": { - "definemedia": {} - } - }, - "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9" - } - } - ], - "site": { - "domain": "localhost:8080", - "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", - "publisher": { - "id": "1", - "domain": "localhost:8080" - } - }, - "device": { - "dnt": 0, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", - "sua": { - "browsers": [ - { - "brand": "Not?A_Brand", - "version": [ - "8", - "0", - "0", - "0" - ] - }, - { - "brand": "Chromium", - "version": [ - "108", - "0", - "5359", - "124" - ] - }, - { - "brand": "Google Chrome", - "version": [ - "108", - "0", - "5359", - "124" - ] - } - ], - "platform": { - "brand": "macOS", - "version": [ - "12", - "3", - "1" - ] - }, - "mobile": 0, - "architecture": "x86", - "bitness": "64", - "source": 2 - }, - "h": 1169, - "w": 1098, - "language": "de" - }, - "tmax": 1000, - "source": { - "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" - }, - "ext": { - "prebid": { - "auctiontimestamp": 1.671449004622e+12, - "channel": { - "name": "pbjs", - "version": "v7.28.0" - }, - "debug": true, - "targeting": { - "includebidderkeys": false, - "includewinners": true - } - } - } - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "bid": [ - { - "id": "46189656-7e2e-477d-b7f2-e05de224bb89", - "impid": "div-gpt-ad-1460505748561-0", - "price": 100, - "adm": "{banner html}", - "adomain": [ - "test.com" - ], - "crid": "test-creative-id", - "ext": { - "prebid": { - "type": "video" - } - } - } - ] - } - ], - "cur": "USD" - } - } - } - ], - "expectedBidResponses": [{"currency":"USD","bids":[]}], - "expectedMakeBidsErrors": [ - { - "value": "Invalid mediatype in the impression", - "comparison": "literal" - } - ] -} diff --git a/adapters/definemedia/params_test.go b/adapters/definemedia/params_test.go deleted file mode 100644 index 63ef5272669..00000000000 --- a/adapters/definemedia/params_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package definemedia - -import ( - "encoding/json" - "testing" - - "github.com/prebid/prebid-server/openrtb_ext" -) - -func TestValidParams(t *testing.T) { - validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") - if err != nil { - t.Fatalf("Failed to fetch the json schema. %v", err) - } - - for _, p := range validParams { - if err := validator.Validate(openrtb_ext.BidderDefinemedia, json.RawMessage(p)); err != nil { - t.Errorf("Schema rejected valid params: %s", p) - } - } -} - -func TestInvalidParams(t *testing.T) { - validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") - if err != nil { - t.Fatalf("Failed to fetch the json schema. %v", err) - } - - for _, p := range invalidParams { - if err := validator.Validate(openrtb_ext.BidderDefinemedia, json.RawMessage(p)); err == nil { - t.Errorf("Schema allowed invalid params: %s", p) - } - } -} - -var validParams = []string{ - `{"mandantId":123}`, - `{"mandantId":123, "adslotId":456}`, -} - -var invalidParams = []string{ - `{"mandantId": "42"}`, - `{"MandantId": "42"}`, - `{"mandantId":123, "adslotId":"456"}`, - `{"adslotId":456}`, - `{"adslotId":"456"}`, - `{}`, -} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 8e80070bd79..7f1b6ea8342 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -71,7 +71,6 @@ import ( "github.com/prebid/prebid-server/adapters/datablocks" "github.com/prebid/prebid-server/adapters/decenterads" "github.com/prebid/prebid-server/adapters/deepintent" - "github.com/prebid/prebid-server/adapters/definemedia" "github.com/prebid/prebid-server/adapters/dianomi" "github.com/prebid/prebid-server/adapters/dmx" evolution "github.com/prebid/prebid-server/adapters/e_volution" @@ -267,7 +266,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderDatablocks: datablocks.Builder, openrtb_ext.BidderDecenterAds: decenterads.Builder, openrtb_ext.BidderDeepintent: deepintent.Builder, - openrtb_ext.BidderDefinemedia: definemedia.Builder, openrtb_ext.BidderDianomi: dianomi.Builder, openrtb_ext.BidderDmx: dmx.Builder, openrtb_ext.BidderEmtv: emtv.Builder, diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index f6c1ffe8b55..b3fc177b3ac 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -118,6 +118,7 @@ func GetDisabledBidderWarningMessages(infos config.BidderInfos) map[string]strin "groupm": `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`, "verizonmedia": `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`, "brightroll": `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`, + "definemedia": `Bidder "definemedia" is no longer available in Prebid Server. Please update your configuration.`, "applogy": `Bidder "applogy" is no longer available in Prebid Server. Please update your configuration.`, "rhythmone": `Bidder "rhythmone" is no longer available in Prebid Server. Please update your configuration.`, } diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index e3379358012..7dd8093d617 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -91,7 +91,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderDatablocks, BidderDecenterAds, BidderDeepintent, - BidderDefinemedia, BidderDianomi, BidderDmx, BidderEmtv, @@ -385,7 +384,6 @@ const ( BidderDatablocks BidderName = "datablocks" BidderDecenterAds BidderName = "decenterads" BidderDeepintent BidderName = "deepintent" - BidderDefinemedia BidderName = "definemedia" BidderDianomi BidderName = "dianomi" BidderDmx BidderName = "dmx" BidderEmtv BidderName = "emtv" diff --git a/openrtb_ext/imp_definemedia.go b/openrtb_ext/imp_definemedia.go deleted file mode 100644 index aa94bf5de63..00000000000 --- a/openrtb_ext/imp_definemedia.go +++ /dev/null @@ -1,6 +0,0 @@ -package openrtb_ext - -type ImpExtDefinemedia struct { - MandantID int64 `json:"mandantId"` - AdslotID int64 `json:"adslotId"` -} diff --git a/static/bidder-info/definemedia.yaml b/static/bidder-info/definemedia.yaml deleted file mode 100644 index d79c3835a58..00000000000 --- a/static/bidder-info/definemedia.yaml +++ /dev/null @@ -1,10 +0,0 @@ -endpoint: "https://rtb.conative.network/openrtb2/auction" -maintainer: - email: "d.joest@definemedia.de" - gvlVendorID: 440 # GDPR vendor list ID -capabilities: - - site: - mediaTypes: - - banner - - native diff --git a/static/bidder-params/definemedia.json b/static/bidder-params/definemedia.json deleted file mode 100644 index bf5566b4c89..00000000000 --- a/static/bidder-params/definemedia.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Define Media Adapter Params", - "description": "A schema which validates params accepted by the DM adapter", - "type": "object", - - "properties": { - "mandantId": { - "type": "integer", - "description": "The DEFINE-MEDIA mandant id. This is a unique identifier for your account. Please contact your account manager for more information." - }, - - "adslotId":{ - "type": "integer", - "description": "The adslot id. This is a unique identifier for your adslot and may change on subparts on a website. Please contact your account manager for more information." - } - }, - "required": ["mandantId"] - } \ No newline at end of file From 10d854cd3fcae8cd3b41cd59ae2f84890b8a4805 Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Tue, 26 Sep 2023 05:30:30 -0400 Subject: [PATCH 137/268] Remove Adapter: Kubient (#3133) Co-authored-by: Ashish Garg --- adapters/kubient/kubient.go | 149 ------------------ adapters/kubient/kubient_test.go | 20 --- .../kubient/kubienttest/exemplary/banner.json | 103 ------------ .../kubient/kubienttest/exemplary/video.json | 93 ----------- .../supplemental/bad_response.json | 61 ------- .../supplemental/missing-zoneid.json | 31 ---- .../kubienttest/supplemental/no-imps.json | 12 -- .../kubienttest/supplemental/status_204.json | 58 ------- .../kubienttest/supplemental/status_400.json | 63 -------- exchange/adapter_builders.go | 2 - exchange/adapter_util.go | 1 + openrtb_ext/bidders.go | 2 - openrtb_ext/imp_kubient.go | 6 - static/bidder-info/kubient.yaml | 13 -- static/bidder-params/kubient.json | 13 -- 15 files changed, 1 insertion(+), 626 deletions(-) delete mode 100644 adapters/kubient/kubient.go delete mode 100644 adapters/kubient/kubient_test.go delete mode 100644 adapters/kubient/kubienttest/exemplary/banner.json delete mode 100644 adapters/kubient/kubienttest/exemplary/video.json delete mode 100644 adapters/kubient/kubienttest/supplemental/bad_response.json delete mode 100644 adapters/kubient/kubienttest/supplemental/missing-zoneid.json delete mode 100644 adapters/kubient/kubienttest/supplemental/no-imps.json delete mode 100644 adapters/kubient/kubienttest/supplemental/status_204.json delete mode 100644 adapters/kubient/kubienttest/supplemental/status_400.json delete mode 100644 openrtb_ext/imp_kubient.go delete mode 100644 static/bidder-info/kubient.yaml delete mode 100644 static/bidder-params/kubient.json diff --git a/adapters/kubient/kubient.go b/adapters/kubient/kubient.go deleted file mode 100644 index 8a3a7baa65a..00000000000 --- a/adapters/kubient/kubient.go +++ /dev/null @@ -1,149 +0,0 @@ -package kubient - -import ( - "encoding/json" - "fmt" - "net/http" - - "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" - - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/errortypes" -) - -// Builder builds a new instance of the Kubient adapter for the given bidder with the given config. -func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { - bidder := &KubientAdapter{ - endpoint: config.Endpoint, - } - return bidder, nil -} - -// Implements Bidder interface. -type KubientAdapter struct { - endpoint string -} - -// MakeRequests prepares the HTTP requests which should be made to fetch bids. -func (adapter *KubientAdapter) MakeRequests( - openRTBRequest *openrtb2.BidRequest, - reqInfo *adapters.ExtraRequestInfo, -) ([]*adapters.RequestData, []error) { - if len(openRTBRequest.Imp) == 0 { - return nil, []error{&errortypes.BadInput{ - Message: "No impression in the bid request", - }} - } - errs := make([]error, 0, len(openRTBRequest.Imp)) - hasErrors := false - for _, impObj := range openRTBRequest.Imp { - err := checkImpExt(impObj) - if err != nil { - errs = append(errs, err) - hasErrors = true - } - } - if hasErrors { - return nil, errs - } - openRTBRequestJSON, err := json.Marshal(openRTBRequest) - if err != nil { - errs = append(errs, err) - return nil, errs - } - - headers := http.Header{} - headers.Add("Content-Type", "application/json;charset=utf-8") - requestsToBidder := []*adapters.RequestData{{ - Method: "POST", - Uri: adapter.endpoint, - Body: openRTBRequestJSON, - Headers: headers, - }} - return requestsToBidder, errs -} - -func checkImpExt(impObj openrtb2.Imp) error { - var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(impObj.Ext, &bidderExt); err != nil { - return &errortypes.BadInput{ - Message: "ext.bidder not provided", - } - } - var kubientExt openrtb_ext.ExtImpKubient - if err := json.Unmarshal(bidderExt.Bidder, &kubientExt); err != nil { - return &errortypes.BadInput{ - Message: "ext.bidder.zoneid is not provided", - } - } - if kubientExt.ZoneID == "" { - return &errortypes.BadInput{ - Message: "zoneid is empty", - } - } - return nil -} - -// MakeBids makes the bids -func (adapter *KubientAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { - var errs []error - - if response.StatusCode == http.StatusNoContent { - return nil, nil - } - - if response.StatusCode == http.StatusBadRequest { - return nil, []error{&errortypes.BadInput{ - Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), - }} - } - - if response.StatusCode != http.StatusOK { - return nil, []error{&errortypes.BadServerResponse{ - Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), - }} - } - - var bidResp openrtb2.BidResponse - - if err := json.Unmarshal(response.Body, &bidResp); err != nil { - return nil, []error{err} - } - - bidResponse := adapters.NewBidderResponseWithBidsCapacity(5) - - for _, sb := range bidResp.SeatBid { - for i := range sb.Bid { - bidType, err := getMediaTypeForImp(sb.Bid[i].ImpID, internalRequest.Imp) - if err != nil { - errs = append(errs, err) - } else { - b := &adapters.TypedBid{ - Bid: &sb.Bid[i], - BidType: bidType, - } - bidResponse.Bids = append(bidResponse.Bids, b) - } - } - } - return bidResponse, errs -} - -func getMediaTypeForImp(impID string, imps []openrtb2.Imp) (openrtb_ext.BidType, error) { - mediaType := openrtb_ext.BidTypeBanner - for _, imp := range imps { - if imp.ID == impID { - if imp.Banner == nil && imp.Video != nil { - mediaType = openrtb_ext.BidTypeVideo - } - return mediaType, nil - } - } - - // This shouldnt happen. Lets handle it just incase by returning an error. - return "", &errortypes.BadInput{ - Message: fmt.Sprintf("Failed to find impression \"%s\" ", impID), - } -} diff --git a/adapters/kubient/kubient_test.go b/adapters/kubient/kubient_test.go deleted file mode 100644 index 292bb20641a..00000000000 --- a/adapters/kubient/kubient_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package kubient - -import ( - "testing" - - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" -) - -func TestJsonSamples(t *testing.T) { - bidder, buildErr := Builder(openrtb_ext.BidderKubient, config.Adapter{ - Endpoint: "http://127.0.0.1:5000/bid"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - if buildErr != nil { - t.Fatalf("Builder returned unexpected error %v", buildErr) - } - - adapterstest.RunJSONBidderTest(t, "kubienttest", bidder) -} diff --git a/adapters/kubient/kubienttest/exemplary/banner.json b/adapters/kubient/kubienttest/exemplary/banner.json deleted file mode 100644 index abcfc05c041..00000000000 --- a/adapters/kubient/kubienttest/exemplary/banner.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-banner-request-id", - "imp": [ - { - "id": "test-imp-banner-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "ext": { - "bidder": { - "zoneid": "9042" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://127.0.0.1:5000/bid", - "body": { - "id": "test-banner-request-id", - "imp": [ - { - "id": "test-imp-banner-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "ext": { - "bidder": { - "zoneid": "9042" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-banner-request-id", - "seatbid": [ - { - "seat": "772", - "bid": [{ - "id": "7706636740145184841", - "impid": "test-imp-banner-id", - "price": 0.500000, - "adid": "29681110", - "adm": "some-test-ad", - "adomain": ["advertsite.com"], - "cid": "772", - "crid": "29681110", - "h": 576, - "w": 1024 - }] - } - ], - "bidid": "5778926625248726496", - "cur": "USD" - } - } - } - ], - "expectedBidResponses": [ - { - "bids": [{ - "bid": { - "id": "7706636740145184841", - "impid": "test-imp-banner-id", - "price": 0.5, - "adm": "some-test-ad", - "adid": "29681110", - "adomain": ["advertsite.com"], - "cid": "772", - "crid": "29681110", - "w": 1024, - "h": 576 - }, - "type": "banner" - }] - } - ] -} diff --git a/adapters/kubient/kubienttest/exemplary/video.json b/adapters/kubient/kubienttest/exemplary/video.json deleted file mode 100644 index 69de5935f48..00000000000 --- a/adapters/kubient/kubienttest/exemplary/video.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-video-request-id", - "imp": [ - { - "id": "test-imp-video-id", - "video": { - "mimes": ["video/mp4"], - "protocols": [2, 5], - "w": 1024, - "h": 576 - }, - "ext": { - "bidder": { - "zoneid": "9010" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://127.0.0.1:5000/bid", - "body": { - "id": "test-video-request-id", - "imp": [ - { - "id": "test-imp-video-id", - "video": { - "mimes": ["video/mp4"], - "protocols": [2, 5], - "w": 1024, - "h": 576 - }, - "ext": { - "bidder": { - "zoneid": "9010" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "ssp-response-id", - "seatbid": [ - { - "seat": "83", - "bid": [{ - "id": "7706636740145184841", - "impid": "test-imp-video-id", - "price": 0.500000, - "adid": "29681110", - "adm": "some-video-ad", - "adomain": ["advertsite.com"], - "cid": "958", - "crid": "29681110", - "h": 576, - "w": 1024 - }] - } - ], - "bidid": "5778926625248726496", - "cur": "USD" - } - } - } - ], - - "expectedBidResponses": [ - { - "bids": [{ - "bid": { - "id": "7706636740145184841", - "impid": "test-imp-video-id", - "price": 0.5, - "adm": "some-video-ad", - "adid": "29681110", - "adomain": ["advertsite.com"], - "cid": "958", - "crid": "29681110", - "w": 1024, - "h": 576 - }, - "type": "video" - }] - } - ] - -} diff --git a/adapters/kubient/kubienttest/supplemental/bad_response.json b/adapters/kubient/kubienttest/supplemental/bad_response.json deleted file mode 100644 index 832dc975088..00000000000 --- a/adapters/kubient/kubienttest/supplemental/bad_response.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": { - "zoneid": "23" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://127.0.0.1:5000/bid", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": { - "zoneid": "23" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": "{\"id\"data.lost" - } - } - ], - "expectedMakeBidsErrors": [ - { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", - "comparison": "literal" - } - ] -} diff --git a/adapters/kubient/kubienttest/supplemental/missing-zoneid.json b/adapters/kubient/kubienttest/supplemental/missing-zoneid.json deleted file mode 100644 index cfd616621e2..00000000000 --- a/adapters/kubient/kubienttest/supplemental/missing-zoneid.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-missing-req-param-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "ext": { - "bidder": {} - } - } - ] - }, - "expectedMakeRequestsErrors": [ - { - "value": "zoneid is empty", - "comparison": "literal" - } - ] -} diff --git a/adapters/kubient/kubienttest/supplemental/no-imps.json b/adapters/kubient/kubienttest/supplemental/no-imps.json deleted file mode 100644 index 189adf9a932..00000000000 --- a/adapters/kubient/kubienttest/supplemental/no-imps.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-no-imp-request-id", - "imp": [] - }, - "expectedMakeRequestsErrors": [ - { - "value": "No impression in the bid request", - "comparison": "literal" - } - ] -} \ No newline at end of file diff --git a/adapters/kubient/kubienttest/supplemental/status_204.json b/adapters/kubient/kubienttest/supplemental/status_204.json deleted file mode 100644 index 6794d58be6c..00000000000 --- a/adapters/kubient/kubienttest/supplemental/status_204.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": { - "zoneid": "203" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://127.0.0.1:5000/bid", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": { - "zoneid": "203" - } - } - } - ] - } - }, - "mockResponse": { - "status": 204, - "body": {} - } - } - ], - - "expectedBidResponses": [] -} diff --git a/adapters/kubient/kubienttest/supplemental/status_400.json b/adapters/kubient/kubienttest/supplemental/status_400.json deleted file mode 100644 index 29438cc3b8b..00000000000 --- a/adapters/kubient/kubienttest/supplemental/status_400.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": { - "zoneid": "102" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://127.0.0.1:5000/bid", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": { - "zoneid": "102" - } - } - } - ] - } - }, - "mockResponse": { - "status": 400, - "body": {} - } - } - ], - - "expectedMakeBidsErrors": [ - { - "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", - "comparison": "literal" - } - ] -} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 7f1b6ea8342..122cc6f25a9 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -103,7 +103,6 @@ import ( "github.com/prebid/prebid-server/adapters/kidoz" "github.com/prebid/prebid-server/adapters/kiviads" "github.com/prebid/prebid-server/adapters/krushmedia" - "github.com/prebid/prebid-server/adapters/kubient" "github.com/prebid/prebid-server/adapters/liftoff" "github.com/prebid/prebid-server/adapters/limelightDigital" lmkiviads "github.com/prebid/prebid-server/adapters/lm_kiviads" @@ -306,7 +305,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderKiviads: kiviads.Builder, openrtb_ext.BidderLmKiviads: lmkiviads.Builder, openrtb_ext.BidderKrushmedia: krushmedia.Builder, - openrtb_ext.BidderKubient: kubient.Builder, openrtb_ext.BidderLiftoff: liftoff.Builder, openrtb_ext.BidderLimelightDigital: limelightDigital.Builder, openrtb_ext.BidderLockerDome: lockerdome.Builder, diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index b3fc177b3ac..5464d328eed 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -118,6 +118,7 @@ func GetDisabledBidderWarningMessages(infos config.BidderInfos) map[string]strin "groupm": `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`, "verizonmedia": `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`, "brightroll": `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`, + "kubient": `Bidder "kubient" is no longer available in Prebid Server. Please update your configuration.`, "definemedia": `Bidder "definemedia" is no longer available in Prebid Server. Please update your configuration.`, "applogy": `Bidder "applogy" is no longer available in Prebid Server. Please update your configuration.`, "rhythmone": `Bidder "rhythmone" is no longer available in Prebid Server. Please update your configuration.`, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 7dd8093d617..c60ea13e81f 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -131,7 +131,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderKiviads, BidderLmKiviads, BidderKrushmedia, - BidderKubient, BidderLiftoff, BidderLimelightDigital, BidderLockerDome, @@ -424,7 +423,6 @@ const ( BidderKiviads BidderName = "kiviads" BidderLmKiviads BidderName = "lm_kiviads" BidderKrushmedia BidderName = "krushmedia" - BidderKubient BidderName = "kubient" BidderLiftoff BidderName = "liftoff" BidderLimelightDigital BidderName = "limelightDigital" BidderLockerDome BidderName = "lockerdome" diff --git a/openrtb_ext/imp_kubient.go b/openrtb_ext/imp_kubient.go deleted file mode 100644 index 59dd3d2aaab..00000000000 --- a/openrtb_ext/imp_kubient.go +++ /dev/null @@ -1,6 +0,0 @@ -package openrtb_ext - -// ExtImpKubient defines the contract for bidrequest.imp[i].ext.prebid.bidder.kubient -type ExtImpKubient struct { - ZoneID string `json:"zoneid"` -} diff --git a/static/bidder-info/kubient.yaml b/static/bidder-info/kubient.yaml deleted file mode 100644 index 15c2708bcb3..00000000000 --- a/static/bidder-info/kubient.yaml +++ /dev/null @@ -1,13 +0,0 @@ -endpoint: "https://kssp.kbntx.ch/prebid" -maintainer: - email: "prebid@kubient.com" -capabilities: - app: - mediaTypes: - - banner - - video - site: - mediaTypes: - - banner - - video - diff --git a/static/bidder-params/kubient.json b/static/bidder-params/kubient.json deleted file mode 100644 index 9b975289a7b..00000000000 --- a/static/bidder-params/kubient.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Kubient Adapter Params", - "description": "A schema which validates params accepted by the Kubient adapter", - "type": "object", - "properties": { - "zoneid": { - "type": "string", - "description": "Zone ID identifies Kubient placement ID.", - "minLength": 1 - } - } -} From 03779e3624f443d90bf987307239d02044f1646c Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Tue, 26 Sep 2023 06:57:10 -0400 Subject: [PATCH 138/268] Remove Adapter: NinthDecimal (#3142) Co-authored-by: Ashish Garg --- adapters/ninthdecimal/ninthdecimal.go | 241 ------------------ adapters/ninthdecimal/ninthdecimal_test.go | 28 -- .../ninthdecimaltest/exemplary/banner.json | 95 ------- .../ninthdecimaltest/exemplary/video.json | 83 ------ .../supplemental/checkImp.json | 14 - .../ninthdecimaltest/supplemental/compat.json | 80 ------ .../ninthdecimaltest/supplemental/ext.json | 33 --- .../supplemental/missingpub.json | 35 --- .../supplemental/responseCode.json | 78 ------ .../supplemental/responsebid.json | 79 ------ .../ninthdecimaltest/supplemental/site.json | 103 -------- .../ninthdecimaltest/supplemental/size.json | 28 -- adapters/ninthdecimal/params_test.go | 45 ---- exchange/adapter_builders.go | 2 - exchange/adapter_util.go | 1 + openrtb_ext/bidders.go | 2 - openrtb_ext/imp_ninthdecimal.go | 6 - static/bidder-info/ninthdecimal.yaml | 18 -- static/bidder-params/ninthdecimal.json | 18 -- 19 files changed, 1 insertion(+), 988 deletions(-) delete mode 100755 adapters/ninthdecimal/ninthdecimal.go delete mode 100755 adapters/ninthdecimal/ninthdecimal_test.go delete mode 100644 adapters/ninthdecimal/ninthdecimaltest/exemplary/banner.json delete mode 100644 adapters/ninthdecimal/ninthdecimaltest/exemplary/video.json delete mode 100644 adapters/ninthdecimal/ninthdecimaltest/supplemental/checkImp.json delete mode 100644 adapters/ninthdecimal/ninthdecimaltest/supplemental/compat.json delete mode 100644 adapters/ninthdecimal/ninthdecimaltest/supplemental/ext.json delete mode 100644 adapters/ninthdecimal/ninthdecimaltest/supplemental/missingpub.json delete mode 100644 adapters/ninthdecimal/ninthdecimaltest/supplemental/responseCode.json delete mode 100644 adapters/ninthdecimal/ninthdecimaltest/supplemental/responsebid.json delete mode 100644 adapters/ninthdecimal/ninthdecimaltest/supplemental/site.json delete mode 100644 adapters/ninthdecimal/ninthdecimaltest/supplemental/size.json delete mode 100755 adapters/ninthdecimal/params_test.go delete mode 100755 openrtb_ext/imp_ninthdecimal.go delete mode 100755 static/bidder-info/ninthdecimal.yaml delete mode 100755 static/bidder-params/ninthdecimal.json diff --git a/adapters/ninthdecimal/ninthdecimal.go b/adapters/ninthdecimal/ninthdecimal.go deleted file mode 100755 index 70dd60ab9fe..00000000000 --- a/adapters/ninthdecimal/ninthdecimal.go +++ /dev/null @@ -1,241 +0,0 @@ -package ninthdecimal - -import ( - "encoding/json" - "fmt" - "net/http" - "text/template" - - "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" -) - -type NinthDecimalAdapter struct { - EndpointTemplate *template.Template -} - -// MakeRequests prepares request information for prebid-server core -func (adapter *NinthDecimalAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - errs := make([]error, 0, len(request.Imp)) - if len(request.Imp) == 0 { - errs = append(errs, &errortypes.BadInput{Message: "No impression in the bid request"}) - return nil, errs - } - pub2impressions, imps, err := getImpressionsInfo(request.Imp) - if len(imps) == 0 { - return nil, err - } - errs = append(errs, err...) - - if len(pub2impressions) == 0 { - return nil, errs - } - - result := make([]*adapters.RequestData, 0, len(pub2impressions)) - for k, imps := range pub2impressions { - bidRequest, err := adapter.buildAdapterRequest(request, &k, imps) - if err != nil { - errs = append(errs, err) - return nil, errs - } else { - result = append(result, bidRequest) - } - } - return result, errs -} - -// getImpressionsInfo checks each impression for validity and returns impressions copy with corresponding exts -func getImpressionsInfo(imps []openrtb2.Imp) (map[openrtb_ext.ExtImpNinthDecimal][]openrtb2.Imp, []openrtb2.Imp, []error) { - errors := make([]error, 0, len(imps)) - resImps := make([]openrtb2.Imp, 0, len(imps)) - res := make(map[openrtb_ext.ExtImpNinthDecimal][]openrtb2.Imp) - - for _, imp := range imps { - impExt, err := getImpressionExt(&imp) - if err != nil { - errors = append(errors, err) - continue - } - if err := validateImpression(impExt); err != nil { - errors = append(errors, err) - continue - } - //dispatchImpressions - //Group impressions by NinthDecimal-specific parameters `pubid - if err := compatImpression(&imp); err != nil { - errors = append(errors, err) - continue - } - if res[*impExt] == nil { - res[*impExt] = make([]openrtb2.Imp, 0) - } - res[*impExt] = append(res[*impExt], imp) - resImps = append(resImps, imp) - } - return res, resImps, errors -} - -func validateImpression(impExt *openrtb_ext.ExtImpNinthDecimal) error { - if impExt.PublisherID == "" { - return &errortypes.BadInput{Message: "No pubid value provided"} - } - return nil -} - -// Alter impression info to comply with NinthDecimal platform requirements -func compatImpression(imp *openrtb2.Imp) error { - imp.Ext = nil //do not forward ext to NinthDecimal platform - if imp.Banner != nil { - return compatBannerImpression(imp) - } - return nil -} - -func compatBannerImpression(imp *openrtb2.Imp) error { - // Create a copy of the banner, since imp is a shallow copy of the original. - - bannerCopy := *imp.Banner - banner := &bannerCopy - //As banner.w/h are required fields for NinthDecimal platform - take the first format entry - if banner.W == nil || banner.H == nil { - if len(banner.Format) == 0 { - return &errortypes.BadInput{Message: "Expected at least one banner.format entry or explicit w/h"} - } - format := banner.Format[0] - banner.Format = banner.Format[1:] - banner.W = &format.W - banner.H = &format.H - imp.Banner = banner - } - return nil -} - -func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpNinthDecimal, error) { - var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { - return nil, &errortypes.BadInput{ - Message: err.Error(), - } - } - var NinthDecimalExt openrtb_ext.ExtImpNinthDecimal - if err := json.Unmarshal(bidderExt.Bidder, &NinthDecimalExt); err != nil { - return nil, &errortypes.BadInput{ - Message: err.Error(), - } - } - return &NinthDecimalExt, nil -} - -func (adapter *NinthDecimalAdapter) buildAdapterRequest(prebidBidRequest *openrtb2.BidRequest, params *openrtb_ext.ExtImpNinthDecimal, imps []openrtb2.Imp) (*adapters.RequestData, error) { - newBidRequest := createBidRequest(prebidBidRequest, params, imps) - reqJSON, err := json.Marshal(newBidRequest) - if err != nil { - return nil, err - } - - headers := http.Header{} - headers.Add("Content-Type", "application/json;charset=utf-8") - headers.Add("Accept", "application/json") - headers.Add("x-openrtb-version", "2.5") - - url, err := adapter.buildEndpointURL(params) - if err != nil { - return nil, err - } - - return &adapters.RequestData{ - Method: "POST", - Uri: url, - Body: reqJSON, - Headers: headers}, nil -} - -func createBidRequest(prebidBidRequest *openrtb2.BidRequest, params *openrtb_ext.ExtImpNinthDecimal, imps []openrtb2.Imp) *openrtb2.BidRequest { - bidRequest := *prebidBidRequest - bidRequest.Imp = imps - for idx := range bidRequest.Imp { - imp := &bidRequest.Imp[idx] - imp.TagID = params.Placement - } - if bidRequest.Site != nil { - // Need to copy Site as Request is a shallow copy - siteCopy := *bidRequest.Site - bidRequest.Site = &siteCopy - bidRequest.Site.Publisher = nil - bidRequest.Site.Domain = "" - } - if bidRequest.App != nil { - // Need to copy App as Request is a shallow copy - appCopy := *bidRequest.App - bidRequest.App = &appCopy - bidRequest.App.Publisher = nil - } - return &bidRequest -} - -// Builds enpoint url based on adapter-specific pub settings from imp.ext -func (adapter *NinthDecimalAdapter) buildEndpointURL(params *openrtb_ext.ExtImpNinthDecimal) (string, error) { - endpointParams := macros.EndpointTemplateParams{PublisherID: params.PublisherID} - return macros.ResolveMacros(adapter.EndpointTemplate, endpointParams) -} - -// MakeBids translates NinthDecimal bid response to prebid-server specific format -func (adapter *NinthDecimalAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { - var msg = "" - if response.StatusCode == http.StatusNoContent { - return nil, nil - } - if response.StatusCode != http.StatusOK { - msg = fmt.Sprintf("Unexpected http status code: %d", response.StatusCode) - return nil, []error{&errortypes.BadServerResponse{Message: msg}} - - } - var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { - msg = fmt.Sprintf("Bad server response: %d", err) - return nil, []error{&errortypes.BadServerResponse{Message: msg}} - } - if len(bidResp.SeatBid) != 1 { - var msg = fmt.Sprintf("Invalid SeatBids count: %d", len(bidResp.SeatBid)) - return nil, []error{&errortypes.BadServerResponse{Message: msg}} - } - - seatBid := bidResp.SeatBid[0] - bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(bidResp.SeatBid[0].Bid)) - - for i := 0; i < len(seatBid.Bid); i++ { - bid := seatBid.Bid[i] - bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ - Bid: &bid, - BidType: getMediaTypeForImpID(bid.ImpID, internalRequest.Imp), - }) - } - return bidResponse, nil -} - -// getMediaTypeForImp figures out which media type this bid is for -func getMediaTypeForImpID(impID string, imps []openrtb2.Imp) openrtb_ext.BidType { - for _, imp := range imps { - if imp.ID == impID && imp.Video != nil { - return openrtb_ext.BidTypeVideo - } - } - return openrtb_ext.BidTypeBanner -} - -// Builder builds a new instance of the NinthDecimal adapter for the given bidder with the given config. -func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { - template, err := template.New("endpointTemplate").Parse(config.Endpoint) - if err != nil { - return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) - } - - bidder := &NinthDecimalAdapter{ - EndpointTemplate: template, - } - return bidder, nil -} diff --git a/adapters/ninthdecimal/ninthdecimal_test.go b/adapters/ninthdecimal/ninthdecimal_test.go deleted file mode 100755 index 8932ac22f58..00000000000 --- a/adapters/ninthdecimal/ninthdecimal_test.go +++ /dev/null @@ -1,28 +0,0 @@ -package ninthdecimal - -import ( - "testing" - - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/stretchr/testify/assert" -) - -func TestJsonSamples(t *testing.T) { - bidder, buildErr := Builder(openrtb_ext.BidderNinthDecimal, config.Adapter{ - Endpoint: "http://rtb.ninthdecimal.com/xp/get?pubid={{.PublisherID}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - if buildErr != nil { - t.Fatalf("Builder returned unexpected error %v", buildErr) - } - - adapterstest.RunJSONBidderTest(t, "ninthdecimaltest", bidder) -} - -func TestEndpointTemplateMalformed(t *testing.T) { - _, buildErr := Builder(openrtb_ext.BidderNinthDecimal, config.Adapter{ - Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - assert.Error(t, buildErr) -} diff --git a/adapters/ninthdecimal/ninthdecimaltest/exemplary/banner.json b/adapters/ninthdecimal/ninthdecimaltest/exemplary/banner.json deleted file mode 100644 index d2184fa06b6..00000000000 --- a/adapters/ninthdecimal/ninthdecimaltest/exemplary/banner.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "mockBidRequest": { - "id": "testid", - "imp": [ - { - "id": "testimpid", - "banner": { - "format": [ - { - "w": 320, - "h": 250 - }, - { - "w": 320, - "h": 300 - } - ], - "w": 320, - "h": 250 - }, - "ext": { - "bidder": { - "pubid": "19f1b372c7548ec1fe734d2c9f8dc688", - "placement": "dummyplacement" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://rtb.ninthdecimal.com/xp/get?pubid=19f1b372c7548ec1fe734d2c9f8dc688", - "body":{ - "id": "testid", - "imp": [{ - "id": "testimpid", - "tagid": "dummyplacement", - "banner": { - "format": [{ - "w": 320, - "h": 250 - }, { - "w": 320, - "h": 300 - }], - "w": 320, - "h": 250 - } - - }] - } - }, - "mockResponse": { - "status": 200, - "body": { - "seatbid": [ - { - "bid": [ - { - "crid": "24080", - "adid": "2068416", - "price": 0.01, - "id": "testid", - "impid": "testimpid", - "cid": "8048" - } - ] - } - ] - } - } - } - ], - - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "crid": "24080", - "adid": "2068416", - "price": 0.01, - "id": "testid", - "impid": "testimpid", - "cid": "8048" - }, - "type": "banner" - } - ] - } - ] -} diff --git a/adapters/ninthdecimal/ninthdecimaltest/exemplary/video.json b/adapters/ninthdecimal/ninthdecimaltest/exemplary/video.json deleted file mode 100644 index 4ad093e0648..00000000000 --- a/adapters/ninthdecimal/ninthdecimaltest/exemplary/video.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "mockBidRequest": { - "id": "testid", - "imp": [ - { - "id": "testimpid", - "video": { - "mimes": [ - "video/mp4" - ], - "w": 640, - "h": 480 - }, - "ext": { - "bidder": { - "pubid": "19f1b372c7548ec1fe734d2c9f8dc688", - "placement": "dummyplacement" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://rtb.ninthdecimal.com/xp/get?pubid=19f1b372c7548ec1fe734d2c9f8dc688", - "body":{ - "id": "testid", - "imp": [{ - "id": "testimpid", - "tagid": "dummyplacement", - "video": { - "mimes": [ - "video/mp4" - ], - "w": 640, - "h": 480 - } - }] - } - }, - "mockResponse": { - "status": 200, - "body": { - "seatbid": [ - { - "bid": [ - { - "crid": "24080", - "adid": "2068416", - "price": 0.01, - "id": "testid", - "impid": "testimpid", - "cid": "8048" - } - ] - } - ] - } - } - } - ], - - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "crid": "24080", - "adid": "2068416", - "price": 0.01, - "id": "testid", - "impid": "testimpid", - "cid": "8048" - }, - "type": "video" - } - ] - } - ] -} \ No newline at end of file diff --git a/adapters/ninthdecimal/ninthdecimaltest/supplemental/checkImp.json b/adapters/ninthdecimal/ninthdecimaltest/supplemental/checkImp.json deleted file mode 100644 index ca48812b4df..00000000000 --- a/adapters/ninthdecimal/ninthdecimaltest/supplemental/checkImp.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "mockBidRequest": { - "id": "testid", - "site": { - "id": "test", - "domain": "test.com" - } - }, - "expectedMakeRequestsErrors": [ - { - "value": "No impression in the bid request", - "comparison": "literal" - }] - } \ No newline at end of file diff --git a/adapters/ninthdecimal/ninthdecimaltest/supplemental/compat.json b/adapters/ninthdecimal/ninthdecimaltest/supplemental/compat.json deleted file mode 100644 index ff33b59cff9..00000000000 --- a/adapters/ninthdecimal/ninthdecimaltest/supplemental/compat.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "mockBidRequest": { - "id": "testid", - "imp": [ - { - "id": "testimpid", - "banner": { - "format": [{ - "w": 320, - "h": 250 - }] - }, - "ext": { - "bidder": { - "pubid": "19f1b372c7548ec1fe734d2c9f8dc688", - "placement": "dummyplacement" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://rtb.ninthdecimal.com/xp/get?pubid=19f1b372c7548ec1fe734d2c9f8dc688", - "body":{ - "id": "testid", - "imp": [{ - "banner": { - "h": 250, - "w": 320 - }, - "id": "testimpid", - "tagid": "dummyplacement" - - }] - } - }, - "mockResponse": { - "status": 200, - "body": { - "seatbid": [ - { - "bid": [ - { - "crid": "24080", - "adid": "2068416", - "price": 0.01, - "id": "testid", - "impid": "testimpid", - "cid": "8048" - } - ] - } - ] - } - } - } - ], - - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "crid": "24080", - "adid": "2068416", - "price": 0.01, - "id": "testid", - "impid": "testimpid", - "cid": "8048" - }, - "type": "banner" - } - ] - } - ] -} diff --git a/adapters/ninthdecimal/ninthdecimaltest/supplemental/ext.json b/adapters/ninthdecimal/ninthdecimaltest/supplemental/ext.json deleted file mode 100644 index 3cfb878bd47..00000000000 --- a/adapters/ninthdecimal/ninthdecimaltest/supplemental/ext.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "mockBidRequest": { - "id": "testid", - "imp": [ - { - "id": "testimpid", - "banner": { - "format": [ - { - "w": 320, - "h": 250 - }, - { - "w": 320, - "h": 300 - } - ], - "w": 320, - "h": 250 - }, - "ext": { - "pubid": "19f1b372c7548ec1fe734d2c9f8dc688", - "placement": "dummyplacement" - } - } - ] - }, -"expectedMakeRequestsErrors": [ - { - "value": "unexpected end of JSON input", - "comparison": "literal" - }] -} \ No newline at end of file diff --git a/adapters/ninthdecimal/ninthdecimaltest/supplemental/missingpub.json b/adapters/ninthdecimal/ninthdecimaltest/supplemental/missingpub.json deleted file mode 100644 index b088917afa3..00000000000 --- a/adapters/ninthdecimal/ninthdecimaltest/supplemental/missingpub.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "mockBidRequest": { - "id": "testid", - "imp": [ - { - "id": "testimpid", - "banner": { - "format": [ - { - "w": 320, - "h": 250 - }, - { - "w": 320, - "h": 300 - } - ], - "w": 320, - "h": 250 - }, - "ext": { - "bidder": { - "pubid": "", - "placement": "dummyplacement" - } - } - } - ] - }, - "expectedMakeRequestsErrors": [ - { - "value": "No pubid value provided", - "comparison": "literal" - }] - } \ No newline at end of file diff --git a/adapters/ninthdecimal/ninthdecimaltest/supplemental/responseCode.json b/adapters/ninthdecimal/ninthdecimaltest/supplemental/responseCode.json deleted file mode 100644 index a68db2b823e..00000000000 --- a/adapters/ninthdecimal/ninthdecimaltest/supplemental/responseCode.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "mockBidRequest": { - "id": "testid", - "site": { - "id": "test" - }, - "imp": [ - { - "id": "testimpid", - "banner": { - "format": [ - { - "w": 320, - "h": 250 - }, - { - "w": 320, - "h": 300 - } - ], - "w": 320, - "h": 250 - }, - "ext": { - "bidder": { - "pubid": "yu", - "placement": "dummyplacement" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://rtb.ninthdecimal.com/xp/get?pubid=yu", - "body": { - "id": "testid", - "imp": [ - { - "banner": { - "format": [ - { - "h": 250, - "w": 320 - }, - { - "h": 300, - "w": 320 - } - ], - "h": 250, - "w": 320 - }, - "id": "testimpid", - "tagid": "dummyplacement" - } - ], - "site": { - "id": "test" - } - } - }, - "mockResponse": { - "body": { - "seatbid": [] - } - } - } - - ], - "expectedMakeBidsErrors": [ - { - "value": "Unexpected http status code: 0", - "comparison": "literal" - } - ] -} \ No newline at end of file diff --git a/adapters/ninthdecimal/ninthdecimaltest/supplemental/responsebid.json b/adapters/ninthdecimal/ninthdecimaltest/supplemental/responsebid.json deleted file mode 100644 index c03aa1b2d89..00000000000 --- a/adapters/ninthdecimal/ninthdecimaltest/supplemental/responsebid.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "mockBidRequest": { - "id": "testid", - "site": { - "id": "test" - }, - "imp": [ - { - "id": "testimpid", - "banner": { - "format": [ - { - "w": 320, - "h": 250 - }, - { - "w": 320, - "h": 300 - } - ], - "w": 320, - "h": 250 - }, - "ext": { - "bidder": { - "pubid": "yu", - "placement": "dummyplacement" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://rtb.ninthdecimal.com/xp/get?pubid=yu", - "body": { - "id": "testid", - "imp": [ - { - "banner": { - "format": [ - { - "h": 250, - "w": 320 - }, - { - "h": 300, - "w": 320 - } - ], - "h": 250, - "w": 320 - }, - "id": "testimpid", - "tagid": "dummyplacement" - } - ], - "site": { - "id": "test" - } - } - }, - "mockResponse": { - "status":200, - "body": { - "seatbid": [] - } - } - } - - ], - "expectedMakeBidsErrors": [ - { - "value": "Invalid SeatBids count: 0", - "comparison": "literal" - } - ] -} \ No newline at end of file diff --git a/adapters/ninthdecimal/ninthdecimaltest/supplemental/site.json b/adapters/ninthdecimal/ninthdecimaltest/supplemental/site.json deleted file mode 100644 index a3e160e4bd8..00000000000 --- a/adapters/ninthdecimal/ninthdecimaltest/supplemental/site.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "mockBidRequest": { - "id": "testid", - "site": { - "id": "test" - }, - "imp": [ - { - "id": "testimpid", - "banner": { - "format": [ - { - "w": 320, - "h": 250 - }, - { - "w": 320, - "h": 300 - } - ], - "w": 320, - "h": 250 - }, - "ext": { - "bidder": { - "pubid": "19f1b372c7548ec1fe734d2c9f8dc688", - "placement": "dummyplacement" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://rtb.ninthdecimal.com/xp/get?pubid=19f1b372c7548ec1fe734d2c9f8dc688", - "body": { - "id": "testid", - "imp": [ - { - "banner": { - "format": [ - { - "h": 250, - "w": 320 - }, - { - "h": 300, - "w": 320 - } - ], - "h": 250, - "w": 320 - }, - "id": "testimpid", - "tagid": "dummyplacement" - } - ], - "site": { - "id": "test" - } - } - }, - "mockResponse": { - "status": 200, - "body": { - "seatbid": [ - { - "bid": [ - { - "crid": "24080", - "adid": "2068416", - "price": 0.01, - "id": "testid", - "impid": "testimpid", - "cid": "8048" - } - ] - } - ] - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "crid": "24080", - "adid": "2068416", - "price": 0.01, - "id": "testid", - "impid": "testimpid", - "cid": "8048" - }, - "type": "banner" - } - ] - } - ] -} \ No newline at end of file diff --git a/adapters/ninthdecimal/ninthdecimaltest/supplemental/size.json b/adapters/ninthdecimal/ninthdecimaltest/supplemental/size.json deleted file mode 100644 index 77228559eee..00000000000 --- a/adapters/ninthdecimal/ninthdecimaltest/supplemental/size.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "mockBidRequest": { - "id": "testid", - "site": { - "id": "test", - "domain": "test.com" - }, - "imp": [ - { - "id": "testimpid", - "banner": { - - }, - "ext": { - "bidder": { - "pubid": "19f1b372c7548ec1fe734d2c9f8dc688", - "placement": "dummyplacement" - } - } - } - ] - }, - "expectedMakeRequestsErrors": [ - { - "value": "Expected at least one banner.format entry or explicit w/h", - "comparison": "literal" - }] -} \ No newline at end of file diff --git a/adapters/ninthdecimal/params_test.go b/adapters/ninthdecimal/params_test.go deleted file mode 100755 index 8d3ef3d706f..00000000000 --- a/adapters/ninthdecimal/params_test.go +++ /dev/null @@ -1,45 +0,0 @@ -package ninthdecimal - -import ( - "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" - "testing" -) - -func TestValidParams(t *testing.T) { - validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") - if err != nil { - t.Fatalf("Failed to fetch the json-schemas. %v", err) - } - - for _, validParam := range validParams { - if err := validator.Validate(openrtb_ext.BidderNinthDecimal, json.RawMessage(validParam)); err != nil { - t.Errorf("Schema rejected NinthDecimal params: %s", validParam) - } - } -} - -func TestInvalidParams(t *testing.T) { - validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") - if err != nil { - t.Fatalf("Failed to fetch the json-schemas. %v", err) - } - - for _, invalidParam := range invalidParams { - if err := validator.Validate(openrtb_ext.BidderNinthDecimal, json.RawMessage(invalidParam)); err == nil { - t.Errorf("Schema allowed unexpected params: %s", invalidParam) - } - } -} - -var validParams = []string{ - `{"pubid": "19f1b372c7548ec1fe734d2c9f8dc688"}`, -} - -var invalidParams = []string{ - `{"publisher": "19f1b372c7548ec1fe734d2c9f8dc688"}`, - `nil`, - ``, - `[]`, - `true`, -} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 122cc6f25a9..527e4c87b4e 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -121,7 +121,6 @@ import ( "github.com/prebid/prebid-server/adapters/motorik" "github.com/prebid/prebid-server/adapters/nanointeractive" "github.com/prebid/prebid-server/adapters/nextmillennium" - "github.com/prebid/prebid-server/adapters/ninthdecimal" "github.com/prebid/prebid-server/adapters/nobid" "github.com/prebid/prebid-server/adapters/onetag" "github.com/prebid/prebid-server/adapters/openweb" @@ -323,7 +322,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderMotorik: motorik.Builder, openrtb_ext.BidderNanoInteractive: nanointeractive.Builder, openrtb_ext.BidderNextMillennium: nextmillennium.Builder, - openrtb_ext.BidderNinthDecimal: ninthdecimal.Builder, openrtb_ext.BidderNoBid: nobid.Builder, openrtb_ext.BidderOneTag: onetag.Builder, openrtb_ext.BidderOpenWeb: openweb.Builder, diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index 5464d328eed..11300d479d2 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -118,6 +118,7 @@ func GetDisabledBidderWarningMessages(infos config.BidderInfos) map[string]strin "groupm": `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`, "verizonmedia": `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`, "brightroll": `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`, + "ninthdecimal": `Bidder "ninthdecimal" is no longer available in Prebid Server. Please update your configuration.`, "kubient": `Bidder "kubient" is no longer available in Prebid Server. Please update your configuration.`, "definemedia": `Bidder "definemedia" is no longer available in Prebid Server. Please update your configuration.`, "applogy": `Bidder "applogy" is no longer available in Prebid Server. Please update your configuration.`, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index c60ea13e81f..049ce11d462 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -149,7 +149,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderMotorik, BidderNanoInteractive, BidderNextMillennium, - BidderNinthDecimal, BidderNoBid, BidderOneTag, BidderOpenWeb, @@ -441,7 +440,6 @@ const ( BidderMotorik BidderName = "motorik" BidderNanoInteractive BidderName = "nanointeractive" BidderNextMillennium BidderName = "nextmillennium" - BidderNinthDecimal BidderName = "ninthdecimal" BidderNoBid BidderName = "nobid" BidderOneTag BidderName = "onetag" BidderOpenWeb BidderName = "openweb" diff --git a/openrtb_ext/imp_ninthdecimal.go b/openrtb_ext/imp_ninthdecimal.go deleted file mode 100755 index 8fb794dbdf2..00000000000 --- a/openrtb_ext/imp_ninthdecimal.go +++ /dev/null @@ -1,6 +0,0 @@ -package openrtb_ext - -type ExtImpNinthDecimal struct { - PublisherID string `json:"pubid"` - Placement string `json:"placement,omitempty"` -} diff --git a/static/bidder-info/ninthdecimal.yaml b/static/bidder-info/ninthdecimal.yaml deleted file mode 100755 index 8a4d7b8d299..00000000000 --- a/static/bidder-info/ninthdecimal.yaml +++ /dev/null @@ -1,18 +0,0 @@ -endpoint: "http://rtb.ninthdecimal.com/xp/get?pubid={{.PublisherID}}" -maintainer: - email: "abudig@ninthdecimal.com" -capabilities: - site: - mediaTypes: - - banner - - video - - app: - mediaTypes: - - banner - - video -userSync: - iframe: - url: "https://rtb.ninthdecimal.com/xp/user-sync?acctid={aid}&&redirect={{.RedirectURL}}" - userMacro: "$UID" - diff --git a/static/bidder-params/ninthdecimal.json b/static/bidder-params/ninthdecimal.json deleted file mode 100755 index f230361d77e..00000000000 --- a/static/bidder-params/ninthdecimal.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "NinthDecimal Adapter Params", - "description": "A schema which validates params accepted by the NinthDecimal adapter", - "type": "object", - "properties": { - "pubid": { - "type": "string", - "description": "An id used to identify NinthDecimal publisher.", - "minLength": 8 - }, - "placement": { - "type": "string", - "description": "A placement created on adserver." - } - }, - "required": ["pubid"] -} From e3cf3c38b8efd82ac7efe59e137179713c61b804 Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Tue, 26 Sep 2023 07:10:35 -0400 Subject: [PATCH 139/268] Remove Adapter: Yeahmobi (#3143) Co-authored-by: Ashish Garg --- adapters/yeahmobi/params_test.go | 47 ----- adapters/yeahmobi/yeahmobi.go | 189 ------------------ adapters/yeahmobi/yeahmobi_test.go | 28 --- .../yeahmobitest/exemplary/no-bid.json | 51 ----- .../yeahmobitest/exemplary/simple-banner.json | 81 -------- .../exemplary/simple-native-1.1.json | 82 -------- .../yeahmobitest/exemplary/simple-native.json | 82 -------- .../yeahmobitest/exemplary/simple-video.json | 89 --------- .../supplemental/bad_imp_ext.json | 21 -- .../supplemental/bad_imp_ext_bidder.json | 23 --- .../supplemental/bad_response.json | 55 ----- .../yeahmobitest/supplemental/status_400.json | 55 ----- .../yeahmobitest/supplemental/status_500.json | 55 ----- exchange/adapter_builders.go | 2 - exchange/adapter_util.go | 1 + openrtb_ext/bidders.go | 2 - openrtb_ext/imp_yeahmobi.go | 7 - static/bidder-info/yeahmobi.yaml | 9 - static/bidder-params/yeahmobi.json | 21 -- 19 files changed, 1 insertion(+), 899 deletions(-) delete mode 100644 adapters/yeahmobi/params_test.go delete mode 100644 adapters/yeahmobi/yeahmobi.go delete mode 100644 adapters/yeahmobi/yeahmobi_test.go delete mode 100644 adapters/yeahmobi/yeahmobitest/exemplary/no-bid.json delete mode 100644 adapters/yeahmobi/yeahmobitest/exemplary/simple-banner.json delete mode 100644 adapters/yeahmobi/yeahmobitest/exemplary/simple-native-1.1.json delete mode 100644 adapters/yeahmobi/yeahmobitest/exemplary/simple-native.json delete mode 100644 adapters/yeahmobi/yeahmobitest/exemplary/simple-video.json delete mode 100644 adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext.json delete mode 100644 adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext_bidder.json delete mode 100644 adapters/yeahmobi/yeahmobitest/supplemental/bad_response.json delete mode 100644 adapters/yeahmobi/yeahmobitest/supplemental/status_400.json delete mode 100644 adapters/yeahmobi/yeahmobitest/supplemental/status_500.json delete mode 100644 openrtb_ext/imp_yeahmobi.go delete mode 100644 static/bidder-info/yeahmobi.yaml delete mode 100644 static/bidder-params/yeahmobi.json diff --git a/adapters/yeahmobi/params_test.go b/adapters/yeahmobi/params_test.go deleted file mode 100644 index 997bf93a53f..00000000000 --- a/adapters/yeahmobi/params_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package yeahmobi - -import ( - "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" - "testing" -) - -func TestValidParams(t *testing.T) { - validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") - if err != nil { - t.Fatalf("Failed to fetch the json-schemas. %v", err) - } - - for _, validParam := range validParams { - if err := validator.Validate(openrtb_ext.BidderYeahmobi, json.RawMessage(validParam)); err != nil { - t.Errorf("Schema rejected yeahmobi params: %s", validParam) - } - } -} - -// TestInvalidParams makes sure that the yeahmobi schema rejects all the imp.ext fields we don't support. -func TestInvalidParams(t *testing.T) { - validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") - if err != nil { - t.Fatalf("Failed to fetch the json-schemas. %v", err) - } - - for _, invalidParam := range invalidParams { - if err := validator.Validate(openrtb_ext.BidderYeahmobi, json.RawMessage(invalidParam)); err == nil { - t.Errorf("Schema allowed unexpected params: %s", invalidParam) - } - } -} - -var validParams = []string{ - `{"pubId": "11233", "zoneId": "sin"}`, - `{"pubId": "11244", "zoneId": "iad"}`, -} - -var invalidParams = []string{ - `{"pubId": "11233"}`, - `{"zoneId": "aaa"}`, - `{"pubId": 123, "zoneId": "sin"}`, - `{"pubId": "", "zoneId": "iad"}`, - `{"pubId": "11233", "zoneId": ""}`, -} diff --git a/adapters/yeahmobi/yeahmobi.go b/adapters/yeahmobi/yeahmobi.go deleted file mode 100644 index d25b2eab541..00000000000 --- a/adapters/yeahmobi/yeahmobi.go +++ /dev/null @@ -1,189 +0,0 @@ -package yeahmobi - -import ( - "encoding/json" - "fmt" - "net/http" - "net/url" - "text/template" - - "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" -) - -type YeahmobiAdapter struct { - EndpointTemplate *template.Template -} - -// Builder builds a new instance of the Yeahmobi adapter for the given bidder with the given config. -func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { - template, err := template.New("endpointTemplate").Parse(config.Endpoint) - if err != nil { - return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) - } - - bidder := &YeahmobiAdapter{ - EndpointTemplate: template, - } - return bidder, nil -} - -func (adapter *YeahmobiAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - var adapterRequests []*adapters.RequestData - - adapterRequest, errs := adapter.makeRequest(request) - if errs == nil { - adapterRequests = append(adapterRequests, adapterRequest) - } - - return adapterRequests, errs -} - -func (adapter *YeahmobiAdapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, []error) { - var errs []error - - yeahmobiExt, errs := getYeahmobiExt(request) - - if yeahmobiExt == nil { - return nil, errs - } - endPoint, err := adapter.getEndpoint(yeahmobiExt) - if err != nil { - return nil, append(errs, err) - } - transform(request) - reqBody, err := json.Marshal(request) - - if err != nil { - return nil, append(errs, err) - } - - headers := http.Header{} - headers.Add("Content-Type", "application/json;charset=utf-8") - - return &adapters.RequestData{ - Method: "POST", - Uri: endPoint, - Body: reqBody, - Headers: headers, - }, errs -} - -func transform(request *openrtb2.BidRequest) { - for i, imp := range request.Imp { - if imp.Native != nil { - var nativeRequest map[string]interface{} - nativeCopyRequest := make(map[string]interface{}) - err := json.Unmarshal([]byte(request.Imp[i].Native.Request), &nativeRequest) - //just ignore the bad native request - if err == nil { - _, exists := nativeRequest["native"] - if exists { - continue - } - - nativeCopyRequest["native"] = nativeRequest - nativeReqByte, err := json.Marshal(nativeCopyRequest) - //just ignore the bad native request - if err != nil { - continue - } - - nativeCopy := *request.Imp[i].Native - nativeCopy.Request = string(nativeReqByte) - request.Imp[i].Native = &nativeCopy - } - } - } -} - -func getYeahmobiExt(request *openrtb2.BidRequest) (*openrtb_ext.ExtImpYeahmobi, []error) { - var extImpYeahmobi openrtb_ext.ExtImpYeahmobi - var errs []error - - for _, imp := range request.Imp { - var extBidder adapters.ExtImpBidder - err := json.Unmarshal(imp.Ext, &extBidder) - if err != nil { - errs = append(errs, err) - continue - } - err = json.Unmarshal(extBidder.Bidder, &extImpYeahmobi) - if err != nil { - errs = append(errs, err) - continue - } - break - } - - return &extImpYeahmobi, errs - -} - -func (adapter *YeahmobiAdapter) getEndpoint(ext *openrtb_ext.ExtImpYeahmobi) (string, error) { - return macros.ResolveMacros(adapter.EndpointTemplate, macros.EndpointTemplateParams{Host: "gw-" + url.QueryEscape(ext.ZoneId) + "-bid.yeahtargeter.com"}) -} - -// MakeBids make the bids for the bid response. -func (a *YeahmobiAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { - if response.StatusCode == http.StatusNoContent { - return nil, nil - } - - if response.StatusCode == http.StatusBadRequest { - return nil, []error{&errortypes.BadInput{ - Message: fmt.Sprintf("Unexpected status code: %d.", response.StatusCode), - }} - } - - if response.StatusCode != http.StatusOK { - return nil, []error{&errortypes.BadServerResponse{ - Message: fmt.Sprintf("Unexpected status code: %d.", response.StatusCode), - }} - } - - var bidResp openrtb2.BidResponse - - if err := json.Unmarshal(response.Body, &bidResp); err != nil { - return nil, []error{err} - } - - bidResponse := adapters.NewBidderResponseWithBidsCapacity(1) - - for _, sb := range bidResp.SeatBid { - for i := range sb.Bid { - var mediaType = getBidType(sb.Bid[i].ImpID, internalRequest.Imp) - bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ - Bid: &sb.Bid[i], - BidType: mediaType, - }) - } - } - return bidResponse, nil - -} - -func getBidType(impId string, imps []openrtb2.Imp) openrtb_ext.BidType { - bidType := openrtb_ext.BidTypeBanner - for _, imp := range imps { - if imp.ID == impId { - if imp.Banner != nil { - break - } - if imp.Video != nil { - bidType = openrtb_ext.BidTypeVideo - break - } - if imp.Native != nil { - bidType = openrtb_ext.BidTypeNative - break - } - - } - } - return bidType -} diff --git a/adapters/yeahmobi/yeahmobi_test.go b/adapters/yeahmobi/yeahmobi_test.go deleted file mode 100644 index 0b1c39ef214..00000000000 --- a/adapters/yeahmobi/yeahmobi_test.go +++ /dev/null @@ -1,28 +0,0 @@ -package yeahmobi - -import ( - "testing" - - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/stretchr/testify/assert" -) - -func TestJsonSamples(t *testing.T) { - bidder, buildErr := Builder(openrtb_ext.BidderYeahmobi, config.Adapter{ - Endpoint: "https://{{.Host}}/prebid/bid"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - if buildErr != nil { - t.Fatalf("Builder returned unexpected error %v", buildErr) - } - - adapterstest.RunJSONBidderTest(t, "yeahmobitest", bidder) -} - -func TestEndpointTemplateMalformed(t *testing.T) { - _, buildErr := Builder(openrtb_ext.BidderYeahmobi, config.Adapter{ - Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - assert.Error(t, buildErr) -} diff --git a/adapters/yeahmobi/yeahmobitest/exemplary/no-bid.json b/adapters/yeahmobi/yeahmobitest/exemplary/no-bid.json deleted file mode 100644 index 723cc40e664..00000000000 --- a/adapters/yeahmobi/yeahmobitest/exemplary/no-bid.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [{"w": 300, "h": 50}] - }, - "ext": { - "bidder": { - "pubId": "fake-pub-id", - "zoneId": "sin" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://gw-sin-bid.yeahtargeter.com/prebid/bid", - "body": { - "id": "test-request-id", - "imp": [ - { - "id":"test-imp-id", - "banner": { - "format": [{"w": 300, "h": 50}] - }, - "ext": { - "bidder": { - "pubId": "fake-pub-id", - "zoneId": "sin" - } - } - } - ] - } - }, - "mockResponse": { - "status": 204, - "body": {} - } - } - ], - - "expectedBidResponses": [] - -} diff --git a/adapters/yeahmobi/yeahmobitest/exemplary/simple-banner.json b/adapters/yeahmobi/yeahmobitest/exemplary/simple-banner.json deleted file mode 100644 index 7499a7874e7..00000000000 --- a/adapters/yeahmobi/yeahmobitest/exemplary/simple-banner.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [{"w": 300, "h": 50}] - }, - "ext": { - "bidder": { - "pubId": "fake-pub-id", - "zoneId": "sin" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://gw-sin-bid.yeahtargeter.com/prebid/bid", - "body": { - "id": "test-request-id", - "imp": [ - { - "id":"test-imp-id", - "banner": { - "format": [{"w": 300, "h": 50}] - }, - "ext": { - "bidder": { - "pubId": "fake-pub-id", - "zoneId": "sin" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "ttx", - "bid": [{ - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id", - "price": 1.2, - "adm": "some-ads", - "crid": "crid_testid" - }] - } - ], - "cur": "USD" - } - } - } - ], - - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id", - "price": 1.2, - "adm": "some-ads", - "crid": "crid_testid" - }, - "type": "banner" - } - ] - } - ] -} diff --git a/adapters/yeahmobi/yeahmobitest/exemplary/simple-native-1.1.json b/adapters/yeahmobi/yeahmobitest/exemplary/simple-native-1.1.json deleted file mode 100644 index 7e93eb68246..00000000000 --- a/adapters/yeahmobi/yeahmobitest/exemplary/simple-native-1.1.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "native": { - "request": "{\"native\":{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":2,\"required\":1,\"title\":{\"len\":90}},{\"id\":6,\"required\":1,\"img\":{\"type\":3,\"wmin\":128,\"hmin\":128,\"mimes\":[\"image/jpg\",\"image/jpeg\",\"image/png\"]}},{\"id\":7,\"required\":1,\"data\":{\"type\":2,\"len\":120}}]}}", - "ver": "1.2" - }, - "ext": { - "bidder": { - "pubId": "fake-pub-id", - "zoneId": "sin" - } - } - } - ] - }, - "httpcalls": [ - { - "expectedRequest": { - "uri": "https://gw-sin-bid.yeahtargeter.com/prebid/bid", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "native": { - "request": "{\"native\":{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":2,\"required\":1,\"title\":{\"len\":90}},{\"id\":6,\"required\":1,\"img\":{\"type\":3,\"wmin\":128,\"hmin\":128,\"mimes\":[\"image/jpg\",\"image/jpeg\",\"image/png\"]}},{\"id\":7,\"required\":1,\"data\":{\"type\":2,\"len\":120}}]}}", - "ver": "1.2" - }, - "ext": { - "bidder": { - "pubId": "fake-pub-id", - "zoneId": "sin" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "bid": [ - { - "id": "8400d766-58b3-47d4-80d7-6658b337d403", - "impid": "test-imp-id", - "price": 1.2, - "adm": "some ads", - "crid": "crid_testid" - } - ] - } - ] - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "8400d766-58b3-47d4-80d7-6658b337d403", - "impid": "test-imp-id", - "price": 1.2, - "adm": "some ads", - "crid": "crid_testid" - - }, - "type": "native" - } - ] - } - ] -} diff --git a/adapters/yeahmobi/yeahmobitest/exemplary/simple-native.json b/adapters/yeahmobi/yeahmobitest/exemplary/simple-native.json deleted file mode 100644 index 894e835bc07..00000000000 --- a/adapters/yeahmobi/yeahmobitest/exemplary/simple-native.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "native": { - "request": "{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":2,\"required\":1,\"title\":{\"len\":90}},{\"id\":6,\"required\":1,\"img\":{\"type\":3,\"wmin\":128,\"hmin\":128,\"mimes\":[\"image/jpg\",\"image/jpeg\",\"image/png\"]}},{\"id\":7,\"required\":1,\"data\":{\"type\":2,\"len\":120}}]}", - "ver": "1.2" - }, - "ext": { - "bidder": { - "pubId": "fake-pub-id", - "zoneId": "sin" - } - } - } - ] - }, - "httpcalls": [ - { - "expectedRequest": { - "uri": "https://gw-sin-bid.yeahtargeter.com/prebid/bid", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "native": { - "request": "{\"native\":{\"assets\":[{\"id\":2,\"required\":1,\"title\":{\"len\":90}},{\"id\":6,\"img\":{\"hmin\":128,\"mimes\":[\"image/jpg\",\"image/jpeg\",\"image/png\"],\"type\":3,\"wmin\":128},\"required\":1},{\"data\":{\"len\":120,\"type\":2},\"id\":7,\"required\":1}],\"context\":1,\"plcmtcnt\":1,\"plcmttype\":4,\"ver\":\"1.2\"}}", - "ver": "1.2" - }, - "ext": { - "bidder": { - "pubId": "fake-pub-id", - "zoneId": "sin" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "bid": [ - { - "id": "8400d766-58b3-47d4-80d7-6658b337d403", - "impid": "test-imp-id", - "price": 1.2, - "adm": "some ads", - "crid": "crid_testid" - } - ] - } - ] - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "8400d766-58b3-47d4-80d7-6658b337d403", - "impid": "test-imp-id", - "price": 1.2, - "adm": "some ads", - "crid": "crid_testid" - - }, - "type": "native" - } - ] - } - ] -} diff --git a/adapters/yeahmobi/yeahmobitest/exemplary/simple-video.json b/adapters/yeahmobi/yeahmobitest/exemplary/simple-video.json deleted file mode 100644 index b040d31b5f6..00000000000 --- a/adapters/yeahmobi/yeahmobitest/exemplary/simple-video.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 300, - "h": 250, - "mimes": [ - "video/mp4" - ] - }, - "ext": { - "bidder": { - "pubId": "fake-pub-id", - "zoneId": "sin" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://gw-sin-bid.yeahtargeter.com/prebid/bid", - "body": { - "id": "test-request-id", - "imp": [ - { - "id":"test-imp-id", - "video": { - "w": 300, - "h": 250, - "mimes": [ - "video/mp4" - ] - }, - "ext": { - "bidder": { - "pubId": "fake-pub-id", - "zoneId": "sin" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "ttx", - "bid": [{ - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id", - "price": 1.2, - "adm": "some-ads", - "crid": "crid_testid" - }] - } - ], - "cur": "USD" - } - } - } - ], - - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id", - "price": 1.2, - "adm": "some-ads", - "crid": "crid_testid" - }, - "type": "video" - } - ] - } - ] -} diff --git a/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext.json b/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext.json deleted file mode 100644 index 444e1e7a8d8..00000000000 --- a/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [{"w": 300, "h": 50}] - }, - "ext": "aaa" - } - ] - }, - - "expectedMakeRequestsErrors": [ - { - "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", - "comparison": "literal" - } - ] -} diff --git a/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext_bidder.json b/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext_bidder.json deleted file mode 100644 index 89697d37141..00000000000 --- a/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext_bidder.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [{"w": 300, "h": 50}] - }, - "ext": { - "bidder": "aa" - } - } - ] - }, - - "expectedMakeRequestsErrors": [ - { - "value": "json: cannot unmarshal string into Go value of type openrtb_ext.ExtImpYeahmobi", - "comparison": "literal" - } - ] -} diff --git a/adapters/yeahmobi/yeahmobitest/supplemental/bad_response.json b/adapters/yeahmobi/yeahmobitest/supplemental/bad_response.json deleted file mode 100644 index 0d77e5af93a..00000000000 --- a/adapters/yeahmobi/yeahmobitest/supplemental/bad_response.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [{"w": 300, "h": 50}] - }, - "ext": { - "bidder": { - "pubId": "fake-pub-id", - "zoneId": "sin" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://gw-sin-bid.yeahtargeter.com/prebid/bid", - "body": { - "id": "test-request-id", - "imp": [ - { - "id":"test-imp-id", - "banner": { - "format": [{"w": 300, "h": 50}] - }, - "ext": { - "bidder": { - "pubId": "fake-pub-id", - "zoneId": "sin" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": "{\"id\":test-request-id" - } - } - ], - - "expectedMakeBidsErrors": [ - { - "comparison": "literal", - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse" - } - ] -} diff --git a/adapters/yeahmobi/yeahmobitest/supplemental/status_400.json b/adapters/yeahmobi/yeahmobitest/supplemental/status_400.json deleted file mode 100644 index 74bb869218c..00000000000 --- a/adapters/yeahmobi/yeahmobitest/supplemental/status_400.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [{"w": 300, "h": 50}] - }, - "ext": { - "bidder": { - "pubId": "fake-pub-id", - "zoneId": "sin" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://gw-sin-bid.yeahtargeter.com/prebid/bid", - "body": { - "id": "test-request-id", - "imp": [ - { - "id":"test-imp-id", - "banner": { - "format": [{"w": 300, "h": 50}] - }, - "ext": { - "bidder": { - "pubId": "fake-pub-id", - "zoneId": "sin" - } - } - } - ] - } - }, - "mockResponse": { - "status": 400, - "body": {} - } - } - ], - - "expectedMakeBidsErrors": [ - { - "comparison": "literal", - "value": "Unexpected status code: 400." - } - ] -} diff --git a/adapters/yeahmobi/yeahmobitest/supplemental/status_500.json b/adapters/yeahmobi/yeahmobitest/supplemental/status_500.json deleted file mode 100644 index 2d3264de897..00000000000 --- a/adapters/yeahmobi/yeahmobitest/supplemental/status_500.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [{"w": 300, "h": 50}] - }, - "ext": { - "bidder": { - "pubId": "fake-pub-id", - "zoneId": "sin" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://gw-sin-bid.yeahtargeter.com/prebid/bid", - "body": { - "id": "test-request-id", - "imp": [ - { - "id":"test-imp-id", - "banner": { - "format": [{"w": 300, "h": 50}] - }, - "ext": { - "bidder": { - "pubId": "fake-pub-id", - "zoneId": "sin" - } - } - } - ] - } - }, - "mockResponse": { - "status": 500, - "body": {} - } - } - ], - - "expectedMakeBidsErrors": [ - { - "comparison": "literal", - "value": "Unexpected status code: 500." - } - ] -} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 527e4c87b4e..d2cb777b18a 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -177,7 +177,6 @@ import ( "github.com/prebid/prebid-server/adapters/vrtcal" "github.com/prebid/prebid-server/adapters/xeworks" "github.com/prebid/prebid-server/adapters/yahooAds" - "github.com/prebid/prebid-server/adapters/yeahmobi" "github.com/prebid/prebid-server/adapters/yieldlab" "github.com/prebid/prebid-server/adapters/yieldmo" "github.com/prebid/prebid-server/adapters/yieldone" @@ -388,7 +387,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderYahooAds: yahooAds.Builder, openrtb_ext.BidderYahooAdvertising: yahooAds.Builder, openrtb_ext.BidderYahooSSP: yahooAds.Builder, - openrtb_ext.BidderYeahmobi: yeahmobi.Builder, openrtb_ext.BidderYieldlab: yieldlab.Builder, openrtb_ext.BidderYieldmo: yieldmo.Builder, openrtb_ext.BidderYieldone: yieldone.Builder, diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index 11300d479d2..7b762eb6794 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -118,6 +118,7 @@ func GetDisabledBidderWarningMessages(infos config.BidderInfos) map[string]strin "groupm": `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`, "verizonmedia": `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`, "brightroll": `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`, + "yeahmobi": `Bidder "yeahmobi" is no longer available in Prebid Server. Please update your configuration.`, "ninthdecimal": `Bidder "ninthdecimal" is no longer available in Prebid Server. Please update your configuration.`, "kubient": `Bidder "kubient" is no longer available in Prebid Server. Please update your configuration.`, "definemedia": `Bidder "definemedia" is no longer available in Prebid Server. Please update your configuration.`, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 049ce11d462..0af0badef41 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -215,7 +215,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderYahooAds, BidderYahooAdvertising, BidderYahooSSP, - BidderYeahmobi, BidderYieldlab, BidderYieldmo, BidderYieldone, @@ -506,7 +505,6 @@ const ( BidderYahooAds BidderName = "yahooAds" BidderYahooAdvertising BidderName = "yahooAdvertising" BidderYahooSSP BidderName = "yahoossp" - BidderYeahmobi BidderName = "yeahmobi" BidderYieldlab BidderName = "yieldlab" BidderYieldmo BidderName = "yieldmo" BidderYieldone BidderName = "yieldone" diff --git a/openrtb_ext/imp_yeahmobi.go b/openrtb_ext/imp_yeahmobi.go deleted file mode 100644 index 16948d807c4..00000000000 --- a/openrtb_ext/imp_yeahmobi.go +++ /dev/null @@ -1,7 +0,0 @@ -package openrtb_ext - -// ExtImpYeahmobi defines the contract for bidrequest.imp[i].ext.prebid.bidder.yeahmobi -type ExtImpYeahmobi struct { - PubId string `json:"pubId"` - ZoneId string `json:"zoneId"` -} diff --git a/static/bidder-info/yeahmobi.yaml b/static/bidder-info/yeahmobi.yaml deleted file mode 100644 index ae41464f6fa..00000000000 --- a/static/bidder-info/yeahmobi.yaml +++ /dev/null @@ -1,9 +0,0 @@ -endpoint: "https://{{.Host}}/prebid/bid" -maintainer: - email: "junping.zhao@yeahmobi.com" -capabilities: - app: - mediaTypes: - - banner - - video - - native diff --git a/static/bidder-params/yeahmobi.json b/static/bidder-params/yeahmobi.json deleted file mode 100644 index fe26fa7255a..00000000000 --- a/static/bidder-params/yeahmobi.json +++ /dev/null @@ -1,21 +0,0 @@ - -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Yeahmobi Adapter Params", - "description": "A schema which validates params accepted by the Yeahmobi adapter", - - "type": "object", - "properties": { - "pubId": { - "type": "string", - "description": "Publisher ID", - "minLength": 1 - }, - "zoneId": { - "type": "string", - "description": "Zone Id", - "minLength": 1 - } - }, - "required": ["pubId", "zoneId"] -} \ No newline at end of file From f2230c88b4dc0985c6a8dc7fde08b2189cd64167 Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Tue, 26 Sep 2023 07:23:39 -0400 Subject: [PATCH 140/268] Remove Adapter: engageBDR (#3131) Co-authored-by: Ashish Garg --- adapters/engagebdr/engagebdr.go | 151 ----------------- adapters/engagebdr/engagebdr_test.go | 20 --- .../engagebdrtest/exemplary/banner.json | 97 ----------- .../engagebdrtest/exemplary/multi-banner.json | 154 ----------------- .../engagebdrtest/exemplary/multi-video.json | 159 ------------------ .../engagebdrtest/exemplary/native.json | 95 ----------- .../engagebdrtest/exemplary/video.json | 100 ----------- .../engagebdrtest/supplemental/audio.json | 25 --- .../supplemental/multi-1-invalid-imp.json | 111 ------------ .../supplemental/no-imp-ext-bidder.json | 24 --- .../supplemental/no-imp-ext.json | 22 --- .../supplemental/no-imp-sspid.json | 26 --- .../engagebdrtest/supplemental/no-imp.json | 15 -- .../supplemental/response-500.json | 52 ------ adapters/engagebdr/params_test.go | 50 ------ exchange/adapter_builders.go | 2 - exchange/adapter_util.go | 1 + openrtb_ext/bidders.go | 2 - openrtb_ext/imp_engagebdr.go | 6 - static/bidder-info/engagebdr.yaml | 14 -- static/bidder-params/engagebdr.json | 14 -- 21 files changed, 1 insertion(+), 1139 deletions(-) delete mode 100644 adapters/engagebdr/engagebdr.go delete mode 100644 adapters/engagebdr/engagebdr_test.go delete mode 100644 adapters/engagebdr/engagebdrtest/exemplary/banner.json delete mode 100644 adapters/engagebdr/engagebdrtest/exemplary/multi-banner.json delete mode 100644 adapters/engagebdr/engagebdrtest/exemplary/multi-video.json delete mode 100644 adapters/engagebdr/engagebdrtest/exemplary/native.json delete mode 100644 adapters/engagebdr/engagebdrtest/exemplary/video.json delete mode 100644 adapters/engagebdr/engagebdrtest/supplemental/audio.json delete mode 100644 adapters/engagebdr/engagebdrtest/supplemental/multi-1-invalid-imp.json delete mode 100644 adapters/engagebdr/engagebdrtest/supplemental/no-imp-ext-bidder.json delete mode 100644 adapters/engagebdr/engagebdrtest/supplemental/no-imp-ext.json delete mode 100644 adapters/engagebdr/engagebdrtest/supplemental/no-imp-sspid.json delete mode 100644 adapters/engagebdr/engagebdrtest/supplemental/no-imp.json delete mode 100644 adapters/engagebdr/engagebdrtest/supplemental/response-500.json delete mode 100644 adapters/engagebdr/params_test.go delete mode 100644 openrtb_ext/imp_engagebdr.go delete mode 100644 static/bidder-info/engagebdr.yaml delete mode 100644 static/bidder-params/engagebdr.json diff --git a/adapters/engagebdr/engagebdr.go b/adapters/engagebdr/engagebdr.go deleted file mode 100644 index eb0160172a0..00000000000 --- a/adapters/engagebdr/engagebdr.go +++ /dev/null @@ -1,151 +0,0 @@ -package engagebdr - -import ( - "encoding/json" - "net/http" - - "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" - - "fmt" - - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/errortypes" -) - -type EngageBDRAdapter struct { - URI string -} - -func (adapter *EngageBDRAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - - errors := make([]error, 0, len(request.Imp)) - - if request.Imp == nil || len(request.Imp) == 0 { - errors = append(errors, &errortypes.BadInput{ - Message: fmt.Sprintf("Invalid BidRequest. No valid imp."), - }) - return nil, errors - } - - // EngageBDR uses different sspid parameters for banner and video. - sspidImps := make(map[string][]openrtb2.Imp) - for _, imp := range request.Imp { - - if imp.Audio != nil { - errors = append(errors, &errortypes.BadInput{ - Message: fmt.Sprintf("Ignoring imp id=%s, invalid MediaType. EngageBDR only supports Banner, Video and Native.", imp.ID), - }) - continue - } - - var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { - errors = append(errors, &errortypes.BadInput{ - Message: fmt.Sprintf("Ignoring imp id=%s, error while decoding extImpBidder, err: %s.", imp.ID, err), - }) - continue - } - impExt := openrtb_ext.ExtImpEngageBDR{} - err := json.Unmarshal(bidderExt.Bidder, &impExt) - if err != nil { - errors = append(errors, &errortypes.BadInput{ - Message: fmt.Sprintf("Ignoring imp id=%s, error while decoding impExt, err: %s.", imp.ID, err), - }) - continue - } - if impExt.Sspid == "" { - errors = append(errors, &errortypes.BadInput{ - Message: fmt.Sprintf("Ignoring imp id=%s, no sspid present.", imp.ID), - }) - continue - } - sspidImps[impExt.Sspid] = append(sspidImps[impExt.Sspid], imp) - } - - var adapterRequests []*adapters.RequestData - - headers := http.Header{} - headers.Add("Content-Type", "application/json;charset=utf-8") - - for sspid, imps := range sspidImps { - if len(imps) > 0 { - // Make a copy as we don't want to change the original request - reqCopy := *request - reqCopy.Imp = imps - reqJSON, err := json.Marshal(reqCopy) - if err != nil { - errors = append(errors, err) - return nil, errors - } - adapterReq := adapters.RequestData{ - Method: "POST", - Uri: adapter.URI + "?zoneid=" + sspid, - Body: reqJSON, - Headers: headers, - } - adapterRequests = append(adapterRequests, &adapterReq) - } - } - - return adapterRequests, errors -} - -func (adapter *EngageBDRAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { - if response.StatusCode == http.StatusNoContent { - return nil, nil - } - - if response.StatusCode == http.StatusBadRequest { - return nil, []error{&errortypes.BadInput{ - Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), - }} - } - - if response.StatusCode != http.StatusOK { - return nil, []error{&errortypes.BadServerResponse{ - Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), - }} - } - - var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { - return nil, []error{err} - } - - bidResponse := adapters.NewBidderResponseWithBidsCapacity(5) - - for _, sb := range bidResp.SeatBid { - for i := range sb.Bid { - bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ - Bid: &sb.Bid[i], - BidType: getMediaTypeForImp(sb.Bid[i].ImpID, internalRequest.Imp), - }) - } - } - return bidResponse, nil -} - -func getMediaTypeForImp(impId string, imps []openrtb2.Imp) openrtb_ext.BidType { - mediaType := openrtb_ext.BidTypeBanner - for _, imp := range imps { - if imp.ID == impId { - if imp.Video != nil { - mediaType = openrtb_ext.BidTypeVideo - } else if imp.Native != nil { - mediaType = openrtb_ext.BidTypeNative - } - return mediaType - } - } - return mediaType -} - -// Builder builds a new instance of the EngageBDR adapter for the given bidder with the given config. -func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { - bidder := &EngageBDRAdapter{ - URI: config.Endpoint, - } - return bidder, nil -} diff --git a/adapters/engagebdr/engagebdr_test.go b/adapters/engagebdr/engagebdr_test.go deleted file mode 100644 index 0877750cb19..00000000000 --- a/adapters/engagebdr/engagebdr_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package engagebdr - -import ( - "testing" - - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" -) - -func TestJsonSamples(t *testing.T) { - bidder, buildErr := Builder(openrtb_ext.BidderEngageBDR, config.Adapter{ - Endpoint: "http://dsp.bnmla.com/hb"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - if buildErr != nil { - t.Fatalf("Builder returned unexpected error %v", buildErr) - } - - adapterstest.RunJSONBidderTest(t, "engagebdrtest", bidder) -} diff --git a/adapters/engagebdr/engagebdrtest/exemplary/banner.json b/adapters/engagebdr/engagebdrtest/exemplary/banner.json deleted file mode 100644 index 92b79e8f349..00000000000 --- a/adapters/engagebdr/engagebdrtest/exemplary/banner.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "sspid": "99999" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://dsp.bnmla.com/hb?zoneid=99999", - "body":{ - "id": "test-request-id", - "imp": [{ - "id": "test-imp-id", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "sspid":"99999" - } - } - }] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "bid": [ - { - "id" : "test-imp-id", - "impid": "test-imp-id", - "price": 9.81, - "adid": "abcde-12345", - "adm": "
", - "adomain": [ - "advertiserdomain.com" - ], - "iurl": "http://match.bnmla.com/usersync?sspid=59&redir=", - "cid": "campaign1", - "crid": "abcde-12345", - "w": 300, - "h": 250 - } - ], - "seat": "test-request-id" - } - ], - "bidid": "test-request-id", - "cur": "USD" - } - } - } - ], - - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "test-imp-id", - "impid": "test-imp-id", - "price": 9.81, - "adid": "abcde-12345", - "adm": "
", - "adomain": ["advertiserdomain.com"], - "iurl": "http://match.bnmla.com/usersync?sspid=59&redir=", - "cid": "campaign1", - "crid": "abcde-12345", - "w": 300, - "h": 250 - }, - "type": "banner" - } - ] - } - ] -} - diff --git a/adapters/engagebdr/engagebdrtest/exemplary/multi-banner.json b/adapters/engagebdr/engagebdrtest/exemplary/multi-banner.json deleted file mode 100644 index d11e38c46fc..00000000000 --- a/adapters/engagebdr/engagebdrtest/exemplary/multi-banner.json +++ /dev/null @@ -1,154 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "sspid": "99999" - } - } - }, - { - "id": "test-imp-id-2", - "banner": { - "w": 320, - "h": 50 - }, - "ext": { - "bidder": { - "sspid": "99999" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://dsp.bnmla.com/hb?zoneid=99999", - "body":{ - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "sspid":"99999" - } - } - }, - { - "id": "test-imp-id-2", - "banner": { - "w": 320, - "h": 50 - }, - "ext": { - "bidder": { - "sspid":"99999" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "bid": [ - { - "id" : "test-imp-id", - "impid": "test-imp-id", - "price": 9.81, - "adid": "abcde-12345", - "adm": "
", - "adomain": [ - "advertiserdomain.com" - ], - "iurl": "http://match.bnmla.com/usersync?sspid=59&redir=", - "cid": "campaign1", - "crid": "abcde-12345", - "w": 300, - "h": 250 - }, - { - "id" : "test-imp-id-2", - "impid": "test-imp-id-2", - "price": 7.50, - "adid": "abcde-12345-2", - "adm": "
", - "adomain": [ - "advertiserdomain.com" - ], - "iurl": "http://match.bnmla.com/usersync?sspid=59&redir=", - "cid": "campaign1", - "crid": "abcde-12345-2", - "w": 320, - "h": 50 - } - ], - "seat": "test-request-id" - } - ], - "bidid": "test-request-id", - "cur": "USD" - } - } - } - ], - - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "test-imp-id", - "impid": "test-imp-id", - "price": 9.81, - "adid": "abcde-12345", - "adm": "
", - "adomain": ["advertiserdomain.com"], - "iurl": "http://match.bnmla.com/usersync?sspid=59&redir=", - "cid": "campaign1", - "crid": "abcde-12345", - "w": 300, - "h": 250 - }, - "type": "banner" - }, - { - "bid": { - "id": "test-imp-id-2", - "impid": "test-imp-id-2", - "price": 7.50, - "adid": "abcde-12345-2", - "adm": "
", - "adomain": ["advertiserdomain.com"], - "iurl": "http://match.bnmla.com/usersync?sspid=59&redir=", - "cid": "campaign1", - "crid": "abcde-12345-2", - "w": 320, - "h": 50 - }, - "type": "banner" - } - ] - } - ] -} - diff --git a/adapters/engagebdr/engagebdrtest/exemplary/multi-video.json b/adapters/engagebdr/engagebdrtest/exemplary/multi-video.json deleted file mode 100644 index 9506c963578..00000000000 --- a/adapters/engagebdr/engagebdrtest/exemplary/multi-video.json +++ /dev/null @@ -1,159 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 300, - "mimes": null, - "h": 250 - }, - "ext": { - "bidder": { - "sspid": "99998" - } - } - }, - { - "id": "test-imp-id-2", - "video": { - "w": 320, - "mimes": null, - "h": 50 - }, - "ext": { - "bidder": { - "sspid": "99998" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://dsp.bnmla.com/hb?zoneid=99998", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 300, - "mimes": null, - "h": 250 - }, - "ext": { - "bidder": { - "sspid": "99998" - } - } - }, - { - "id": "test-imp-id-2", - "video": { - "w": 320, - "mimes": null, - "h": 50 - }, - "ext": { - "bidder": { - "sspid": "99998" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "bid": [ - { - "id": "test-imp-id", - "impid": "test-imp-id", - "price": 9.81, - "adid": "abcde-12345", - "adm": "\nStatic VASTStatic VAST Tag", - "adomain": [ - "advertiserdomain.com" - ], - "iurl": "https://cdn0.bnmla.com/vtest.xml", - "cid": "campaign1", - "crid": "abcde-12345", - "w": 300, - "h": 250 - }, - { - "id": "test-imp-id-2", - "impid": "test-imp-id-2", - "price": 7.81, - "adid": "abcde-12345-2", - "adm": "\nStatic VASTStatic VAST Tag", - "adomain": [ - "advertiserdomain.com" - ], - "iurl": "https://cdn0.bnmla.com/vtest.xml", - "cid": "campaign1", - "crid": "abcde-12345-2", - "w": 320, - "h": 50 - } - ], - "seat": "test-request-id" - } - ], - "bidid": "test-request-id", - "cur": "USD" - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "test-imp-id", - "impid": "test-imp-id", - "price": 9.81, - "adid": "abcde-12345", - "adm": "\nStatic VASTStatic VAST Tag", - "adomain": [ - "advertiserdomain.com" - ], - "iurl": "https://cdn0.bnmla.com/vtest.xml", - "cid": "campaign1", - "crid": "abcde-12345", - "w": 300, - "h": 250 - }, - "type": "video" - }, - { - "bid": { - "id": "test-imp-id-2", - "impid": "test-imp-id-2", - "price": 7.81, - "adid": "abcde-12345-2", - "adm": "\nStatic VASTStatic VAST Tag", - "adomain": [ - "advertiserdomain.com" - ], - "iurl": "https://cdn0.bnmla.com/vtest.xml", - "cid": "campaign1", - "crid": "abcde-12345-2", - "w": 320, - "h": 50 - }, - "type": "video" - } - ] - } - ] -} diff --git a/adapters/engagebdr/engagebdrtest/exemplary/native.json b/adapters/engagebdr/engagebdrtest/exemplary/native.json deleted file mode 100644 index 963194fb8bd..00000000000 --- a/adapters/engagebdr/engagebdrtest/exemplary/native.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "native": { - "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}", - "ver":"1.1" - }, - "ext": { - "bidder": { - "sspid": "99997" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://dsp.bnmla.com/hb?zoneid=99997", - "body":{ - "id": "test-request-id", - "imp": [{ - "id": "test-imp-id", - "native": { - "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}", - "ver":"1.1" - }, - "ext": { - "bidder": { - "sspid":"99997" - } - } - }] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "bid": [ - { - "id" : "test-imp-id", - "impid": "test-imp-id", - "price": 9.81, - "adid": "abcde-12345", - "adm": "{\"native\":{\"link\":{\"url\":\"https://rtb-use.mfadsrvr.com/click/ESoNneAwqCPnn97YSh0EoJzPUnSmqwdERCYPCdrHr1_TJz_V-x2xjMgxcROeooIH5fe1exAsWt2aqg1ESQEVQM8i0TpI1QBcV4V87Uzmf_XfAR6-6xqvqfGuDs-pJDWqAYz0P0OtHlrvVztlMdWu6JT9_GAtVAnB9gp0JchRJLSqr1h_GRZwuNUri7NvveTD7m8ZUHKNFldKPwHCbom120NFFn2Z3a6v0owsZfIgOff-1YyvZ9WkzVr3755kGRT_D1FUy3r2kurY8HdfeTiRuZAajluniEkJql7yGlS6hVfQ3vT3X93BKIo1F_A3o4bfywT49tM-3l2X8vwlc-w9X-B5VudQPJ8kboJZ2OuaD5AN///\"},\"assets\":[{\"id\":0,\"title\":{\"text\":\"4 Signs Your Heart Is Quietly Failing You\"},\"required\":1},{\"id\":3,\"img\":{\"w\":1200,\"h\":627,\"url\":\"https://de9a11s35xj3d.cloudfront.net/5922785fd53de8084607850abdaace4f.jpg\"}},{\"id\":4,\"data\":{\"value\":\"PhysioTru\"}},{\"id\":6,\"data\":{\"value\":\"\\n How To Avoid A Heart Attack (Do This For 7 Seconds Twice A Day)\\n \"}}],\"imptrackers\":[\"https://rtb-use.mfadsrvr.com/imp_c2s/v1/ESoNneAwqCPnn97YSh0EoJzPUnSmqwdERCYPCdrHr1_TJz_V-x2xjMgxcROeooIH5fe1exAsWt2aqg1ESQEVQM8i0TpI1QBcV4V87Uzmf_XfAR6-6xqvqfGuDs-pJDWqAYz0P0OtHlrvVztlMdWu6JT9_GAtVAnB9gp0JchRJLSqr1h_GRZwuNUri7NvveTD7m8ZUHKNFldKPwHCbom120NFFn2Z3a6v0owsZfIgOff-1YyvZ9WkzVr3755kGRT_D1FUy3r2kurY8HdfeTiRuZAajluniEkJql7yGlS6hVfQ3vT3X93BKIo1F_A3o4bfywT49tM-3l2X8vwlc-w9X-B5VudQPJ8kboJZ2OuaD5AN/${AUCTION_PRICE}\"],\"ver\":1}}", - "adomain": [ - "advertiserdomain.com" - ], - "cid": "campaign1", - "crid": "abcde-12345", - "w": 300, - "h": 250 - } - ], - "seat": "test-request-id" - } - ], - "bidid": "test-request-id", - "cur": "USD" - } - } - } - ], - - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "test-imp-id", - "impid": "test-imp-id", - "price": 9.81, - "adid": "abcde-12345", - "adm": "{\"native\":{\"link\":{\"url\":\"https://rtb-use.mfadsrvr.com/click/ESoNneAwqCPnn97YSh0EoJzPUnSmqwdERCYPCdrHr1_TJz_V-x2xjMgxcROeooIH5fe1exAsWt2aqg1ESQEVQM8i0TpI1QBcV4V87Uzmf_XfAR6-6xqvqfGuDs-pJDWqAYz0P0OtHlrvVztlMdWu6JT9_GAtVAnB9gp0JchRJLSqr1h_GRZwuNUri7NvveTD7m8ZUHKNFldKPwHCbom120NFFn2Z3a6v0owsZfIgOff-1YyvZ9WkzVr3755kGRT_D1FUy3r2kurY8HdfeTiRuZAajluniEkJql7yGlS6hVfQ3vT3X93BKIo1F_A3o4bfywT49tM-3l2X8vwlc-w9X-B5VudQPJ8kboJZ2OuaD5AN///\"},\"assets\":[{\"id\":0,\"title\":{\"text\":\"4 Signs Your Heart Is Quietly Failing You\"},\"required\":1},{\"id\":3,\"img\":{\"w\":1200,\"h\":627,\"url\":\"https://de9a11s35xj3d.cloudfront.net/5922785fd53de8084607850abdaace4f.jpg\"}},{\"id\":4,\"data\":{\"value\":\"PhysioTru\"}},{\"id\":6,\"data\":{\"value\":\"\\n How To Avoid A Heart Attack (Do This For 7 Seconds Twice A Day)\\n \"}}],\"imptrackers\":[\"https://rtb-use.mfadsrvr.com/imp_c2s/v1/ESoNneAwqCPnn97YSh0EoJzPUnSmqwdERCYPCdrHr1_TJz_V-x2xjMgxcROeooIH5fe1exAsWt2aqg1ESQEVQM8i0TpI1QBcV4V87Uzmf_XfAR6-6xqvqfGuDs-pJDWqAYz0P0OtHlrvVztlMdWu6JT9_GAtVAnB9gp0JchRJLSqr1h_GRZwuNUri7NvveTD7m8ZUHKNFldKPwHCbom120NFFn2Z3a6v0owsZfIgOff-1YyvZ9WkzVr3755kGRT_D1FUy3r2kurY8HdfeTiRuZAajluniEkJql7yGlS6hVfQ3vT3X93BKIo1F_A3o4bfywT49tM-3l2X8vwlc-w9X-B5VudQPJ8kboJZ2OuaD5AN/${AUCTION_PRICE}\"],\"ver\":1}}", - "adomain": ["advertiserdomain.com"], - "cid": "campaign1", - "crid": "abcde-12345", - "w": 300, - "h": 250 - }, - "type": "native" - } - ] - } - ] -} - diff --git a/adapters/engagebdr/engagebdrtest/exemplary/video.json b/adapters/engagebdr/engagebdrtest/exemplary/video.json deleted file mode 100644 index 53c00dc4523..00000000000 --- a/adapters/engagebdr/engagebdrtest/exemplary/video.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 300, - "mimes": null, - "h": 250 - }, - "ext": { - "bidder": { - "sspid":"99998" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://dsp.bnmla.com/hb?zoneid=99998", - "body":{ - "id": "test-request-id", - "imp": [{ - "id": "test-imp-id", - "video": { - "w": 300, - "mimes": null, - "h": 250 - }, - "ext": { - "bidder": { - "sspid":"99998" - } - } - }] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "bid": [ - { - "id": "test-imp-id", - "impid": "test-imp-id", - "price": 9.81, - "adid": "abcde-12345", - "adm": "\nStatic VASTStatic VAST Tag", - "adomain":[ - "advertiserdomain.com" - ], - "iurl": "https://cdn0.bnmla.com/vtest.xml", - "cid": "campaign1", - "crid": "abcde-12345", - "w": 300, - "h": 250 - } - ], - "seat": "test-request-id" - } - ], - "bidid": "test-request-id", - "cur": "USD" - } - } - } - ], - - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "test-imp-id", - "impid": "test-imp-id", - "price": 9.81, - "adid": "abcde-12345", - "adm": "\nStatic VASTStatic VAST Tag", - "adomain": ["advertiserdomain.com"], - "iurl": "https://cdn0.bnmla.com/vtest.xml", - "cid": "campaign1", - "crid": "abcde-12345", - "w": 300, - "h": 250 - }, - "type": "video" - } - ] - - } - ] -} - diff --git a/adapters/engagebdr/engagebdrtest/supplemental/audio.json b/adapters/engagebdr/engagebdrtest/supplemental/audio.json deleted file mode 100644 index e03fdb50aa4..00000000000 --- a/adapters/engagebdr/engagebdrtest/supplemental/audio.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "audio": { - }, - "ext": { - "bidder": { - "sspid": "99996" - } - } - } - ] - }, - - "expectedMakeRequestsErrors": [ - { - "value": "Ignoring imp id=test-imp-id, invalid MediaType. EngageBDR only supports Banner, Video and Native.", - "comparison": "literal" - } - ] -} - diff --git a/adapters/engagebdr/engagebdrtest/supplemental/multi-1-invalid-imp.json b/adapters/engagebdr/engagebdrtest/supplemental/multi-1-invalid-imp.json deleted file mode 100644 index a2cd79c9deb..00000000000 --- a/adapters/engagebdr/engagebdrtest/supplemental/multi-1-invalid-imp.json +++ /dev/null @@ -1,111 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "sspid": "99999" - } - } - }, - { - "id": "test-imp-id-2", - "banner": { - "w": 320, - "h": 50 - }, - "ext": { - } - } - ] - }, - "expectedMakeRequestsErrors": [ - { - "value": "Ignoring imp id=test-imp-id-2, error while decoding impExt, err: unexpected end of JSON input.", - "comparison": "literal" - } - ], - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://dsp.bnmla.com/hb?zoneid=99999", - "body":{ - "id": "test-request-id", - "imp": [{ - "id": "test-imp-id", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "sspid":"99999" - } - } - }] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "bid": [ - { - "id" : "test-imp-id", - "impid": "test-imp-id", - "price": 9.81, - "adid": "abcde-12345", - "adm": "
", - "adomain": [ - "advertiserdomain.com" - ], - "iurl": "http://match.bnmla.com/usersync?sspid=59&redir=", - "cid": "campaign1", - "crid": "abcde-12345", - "w": 300, - "h": 250 - } - ], - "seat": "test-request-id" - } - ], - "bidid": "test-request-id", - "cur": "USD" - } - } - } - ], - - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "test-imp-id", - "impid": "test-imp-id", - "price": 9.81, - "adid": "abcde-12345", - "adm": "
", - "adomain": ["advertiserdomain.com"], - "iurl": "http://match.bnmla.com/usersync?sspid=59&redir=", - "cid": "campaign1", - "crid": "abcde-12345", - "w": 300, - "h": 250 - }, - "type": "banner" - } - ] - } - ] -} - diff --git a/adapters/engagebdr/engagebdrtest/supplemental/no-imp-ext-bidder.json b/adapters/engagebdr/engagebdrtest/supplemental/no-imp-ext-bidder.json deleted file mode 100644 index 9aa8177fc8b..00000000000 --- a/adapters/engagebdr/engagebdrtest/supplemental/no-imp-ext-bidder.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - } - } - ] - }, - - "expectedMakeRequestsErrors": [ - { - "value": "Ignoring imp id=test-imp-id, error while decoding impExt, err: unexpected end of JSON input.", - "comparison": "literal" - } - ] -} - diff --git a/adapters/engagebdr/engagebdrtest/supplemental/no-imp-ext.json b/adapters/engagebdr/engagebdrtest/supplemental/no-imp-ext.json deleted file mode 100644 index 04e167fd671..00000000000 --- a/adapters/engagebdr/engagebdrtest/supplemental/no-imp-ext.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "w": 300, - "h": 250 - } - } - ] - }, - - "expectedMakeRequestsErrors": [ - { - "value": "Ignoring imp id=test-imp-id, error while decoding extImpBidder, err: unexpected end of JSON input.", - "comparison": "literal" - } - ] -} - diff --git a/adapters/engagebdr/engagebdrtest/supplemental/no-imp-sspid.json b/adapters/engagebdr/engagebdrtest/supplemental/no-imp-sspid.json deleted file mode 100644 index d193bf779fc..00000000000 --- a/adapters/engagebdr/engagebdrtest/supplemental/no-imp-sspid.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - } - } - } - ] - }, - - "expectedMakeRequestsErrors": [ - { - "value": "Ignoring imp id=test-imp-id, no sspid present.", - "comparison": "literal" - } - ] -} - diff --git a/adapters/engagebdr/engagebdrtest/supplemental/no-imp.json b/adapters/engagebdr/engagebdrtest/supplemental/no-imp.json deleted file mode 100644 index c5b0fa96042..00000000000 --- a/adapters/engagebdr/engagebdrtest/supplemental/no-imp.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - ] - }, - - "expectedMakeRequestsErrors": [ - { - "value": "Invalid BidRequest. No valid imp.", - "comparison": "literal" - } - ] -} - diff --git a/adapters/engagebdr/engagebdrtest/supplemental/response-500.json b/adapters/engagebdr/engagebdrtest/supplemental/response-500.json deleted file mode 100644 index ce750770a63..00000000000 --- a/adapters/engagebdr/engagebdrtest/supplemental/response-500.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "sspid": "99999" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://dsp.bnmla.com/hb?zoneid=99999", - "body":{ - "id": "test-request-id", - "imp": [{ - "id": "test-imp-id", - "banner": { - "w": 300, - "h": 250 - }, - "ext": { - "bidder": { - "sspid":"99999" - } - } - }] - } - }, - "mockResponse": { - "status": 500 - } - } - ], - "expectedMakeBidsErrors": [ - { - "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", - "comparison": "literal" - } - ] -} - diff --git a/adapters/engagebdr/params_test.go b/adapters/engagebdr/params_test.go deleted file mode 100644 index c797d04ecc8..00000000000 --- a/adapters/engagebdr/params_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package engagebdr - -import ( - "encoding/json" - "testing" - - "github.com/prebid/prebid-server/openrtb_ext" -) - -func TestValidParams(t *testing.T) { - validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") - if err != nil { - t.Fatalf("Failed to fetch the json-schemas. %v", err) - } - - for _, validParam := range validParams { - if err := validator.Validate(openrtb_ext.BidderEngageBDR, json.RawMessage(validParam)); err != nil { - t.Errorf("Schema rejected beachfront params: %s", validParam) - } - } -} - -func TestInvalidParams(t *testing.T) { - validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") - if err != nil { - t.Fatalf("Failed to fetch the json-schemas. %v", err) - } - - for _, invalidParam := range invalidParams { - if err := validator.Validate(openrtb_ext.BidderEngageBDR, json.RawMessage(invalidParam)); err == nil { - t.Errorf("Schema allowed unexpected params: %s", invalidParam) - } - } -} - -var validParams = []string{ - `{"sspid":"12345"}`, -} - -var invalidParams = []string{ - ``, - `null`, - `true`, - `5`, - `4.2`, - `[]`, - `{}`, - `{"sspid":null}`, - `{"appId":"11bc5dd5-7421-4dd8-c926-40fa653bec76"}`, -} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index d2cb777b18a..3a2f871e199 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -75,7 +75,6 @@ import ( "github.com/prebid/prebid-server/adapters/dmx" evolution "github.com/prebid/prebid-server/adapters/e_volution" "github.com/prebid/prebid-server/adapters/emtv" - "github.com/prebid/prebid-server/adapters/engagebdr" "github.com/prebid/prebid-server/adapters/eplanning" "github.com/prebid/prebid-server/adapters/epom" "github.com/prebid/prebid-server/adapters/flipp" @@ -267,7 +266,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderDmx: dmx.Builder, openrtb_ext.BidderEmtv: emtv.Builder, openrtb_ext.BidderEmxDigital: cadentaperturemx.Builder, - openrtb_ext.BidderEngageBDR: engagebdr.Builder, openrtb_ext.BidderEPlanning: eplanning.Builder, openrtb_ext.BidderEpom: epom.Builder, openrtb_ext.BidderEpsilon: conversant.Builder, diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index 7b762eb6794..8ce6f0df67c 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -118,6 +118,7 @@ func GetDisabledBidderWarningMessages(infos config.BidderInfos) map[string]strin "groupm": `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`, "verizonmedia": `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`, "brightroll": `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`, + "engagebdr": `Bidder "engagebdr" is no longer available in Prebid Server. Please update your configuration.`, "yeahmobi": `Bidder "yeahmobi" is no longer available in Prebid Server. Please update your configuration.`, "ninthdecimal": `Bidder "ninthdecimal" is no longer available in Prebid Server. Please update your configuration.`, "kubient": `Bidder "kubient" is no longer available in Prebid Server. Please update your configuration.`, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 0af0badef41..34c01f1ce32 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -95,7 +95,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderDmx, BidderEmtv, BidderEmxDigital, - BidderEngageBDR, BidderEPlanning, BidderEpom, BidderEpsilon, @@ -385,7 +384,6 @@ const ( BidderDmx BidderName = "dmx" BidderEmtv BidderName = "emtv" BidderEmxDigital BidderName = "emx_digital" - BidderEngageBDR BidderName = "engagebdr" BidderEPlanning BidderName = "eplanning" BidderEpsilon BidderName = "epsilon" BidderEpom BidderName = "epom" diff --git a/openrtb_ext/imp_engagebdr.go b/openrtb_ext/imp_engagebdr.go deleted file mode 100644 index db500111a78..00000000000 --- a/openrtb_ext/imp_engagebdr.go +++ /dev/null @@ -1,6 +0,0 @@ -package openrtb_ext - -// ExtImpEngageBDR defines the contract for bidrequest.imp[i].ext.prebid.bidder.engagebdr -type ExtImpEngageBDR struct { - Sspid string `json:"sspid"` -} diff --git a/static/bidder-info/engagebdr.yaml b/static/bidder-info/engagebdr.yaml deleted file mode 100644 index 8218040c605..00000000000 --- a/static/bidder-info/engagebdr.yaml +++ /dev/null @@ -1,14 +0,0 @@ -endpoint: "http://dsp.bnmla.com/hb" -maintainer: - email: "tech@engagebdr.com" -capabilities: - app: - mediaTypes: - - banner - - video - - native -userSync: - iframe: - url: "https://match.bnmla.com/usersync/s2s_sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}" - userMacro: "${UUID}" - diff --git a/static/bidder-params/engagebdr.json b/static/bidder-params/engagebdr.json deleted file mode 100644 index 4f987004045..00000000000 --- a/static/bidder-params/engagebdr.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "EngageBDR Adapter Params", - "description": "A schema which validates params accepted by the EngageBDR adapter", - "type": "object", - "properties": { - "sspid": { - "type": "string", - "description": "SSPID parameter", - "pattern": "^[0-9]+$" - } - }, - "required": ["sspid"] -} From 0d96c9d1799b3634cd587fdca8ed0d71f6541f1b Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Tue, 26 Sep 2023 07:57:27 -0400 Subject: [PATCH 141/268] Remove Adapter: Nano Interactive (#3134) Co-authored-by: Ashish Garg --- adapters/nanointeractive/nanointeractive.go | 164 ------------------ .../nanointeractive/nanointeractive_test.go | 20 --- .../exemplary/simple-banner.json | 88 ---------- .../supplemental/bad_response.json | 63 ------- .../supplemental/invalid-params.json | 81 --------- .../supplemental/multi-param.json | 149 ---------------- .../supplemental/status_204.json | 58 ------- .../supplemental/status_400.json | 63 ------- .../supplemental/status_418.json | 63 ------- adapters/nanointeractive/params_test.go | 63 ------- exchange/adapter_builders.go | 2 - exchange/adapter_util.go | 33 ++-- openrtb_ext/bidders.go | 2 - openrtb_ext/imp_nanointeractive.go | 10 -- static/bidder-info/nanointeractive.yaml | 15 -- static/bidder-params/nanointeractive.json | 32 ---- 16 files changed, 17 insertions(+), 889 deletions(-) delete mode 100644 adapters/nanointeractive/nanointeractive.go delete mode 100644 adapters/nanointeractive/nanointeractive_test.go delete mode 100644 adapters/nanointeractive/nanointeractivetest/exemplary/simple-banner.json delete mode 100644 adapters/nanointeractive/nanointeractivetest/supplemental/bad_response.json delete mode 100644 adapters/nanointeractive/nanointeractivetest/supplemental/invalid-params.json delete mode 100644 adapters/nanointeractive/nanointeractivetest/supplemental/multi-param.json delete mode 100644 adapters/nanointeractive/nanointeractivetest/supplemental/status_204.json delete mode 100644 adapters/nanointeractive/nanointeractivetest/supplemental/status_400.json delete mode 100644 adapters/nanointeractive/nanointeractivetest/supplemental/status_418.json delete mode 100644 adapters/nanointeractive/params_test.go delete mode 100644 openrtb_ext/imp_nanointeractive.go delete mode 100644 static/bidder-info/nanointeractive.yaml delete mode 100644 static/bidder-params/nanointeractive.json diff --git a/adapters/nanointeractive/nanointeractive.go b/adapters/nanointeractive/nanointeractive.go deleted file mode 100644 index d8e3c709525..00000000000 --- a/adapters/nanointeractive/nanointeractive.go +++ /dev/null @@ -1,164 +0,0 @@ -package nanointeractive - -import ( - "encoding/json" - "fmt" - "net/http" - - "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" -) - -type NanoInteractiveAdapter struct { - endpoint string -} - -func (a *NanoInteractiveAdapter) MakeRequests(bidRequest *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - - var errs []error - var validImps []openrtb2.Imp - - var adapterRequests []*adapters.RequestData - var referer string = "" - - for i := 0; i < len(bidRequest.Imp); i++ { - - ref, err := checkImp(&bidRequest.Imp[i]) - - // If the parsing is failed, remove imp and add the error. - if err != nil { - errs = append(errs, err) - continue - } - if referer == "" && ref != "" { - referer = ref - } - validImps = append(validImps, bidRequest.Imp[i]) - } - - if len(validImps) == 0 { - errs = append(errs, fmt.Errorf("no impressions in the bid request")) - return nil, errs - } - - // set referer origin - if referer != "" { - if bidRequest.Site == nil { - bidRequest.Site = &openrtb2.Site{} - } - bidRequest.Site.Ref = referer - } - - bidRequest.Imp = validImps - - reqJSON, err := json.Marshal(bidRequest) - if err != nil { - errs = append(errs, err) - return nil, errs - } - - headers := http.Header{} - headers.Add("Content-Type", "application/json;charset=utf-8") - headers.Add("Accept", "application/json") - headers.Add("x-openrtb-version", "2.5") - if bidRequest.Device != nil { - headers.Add("User-Agent", bidRequest.Device.UA) - headers.Add("X-Forwarded-For", bidRequest.Device.IP) - } - if bidRequest.Site != nil { - headers.Add("Referer", bidRequest.Site.Page) - } - - // set user's cookie - if bidRequest.User != nil && bidRequest.User.BuyerUID != "" { - headers.Add("Cookie", "Nano="+bidRequest.User.BuyerUID) - } - - adapterRequests = append(adapterRequests, &adapters.RequestData{ - Method: "POST", - Uri: a.endpoint, - Body: reqJSON, - Headers: headers, - }) - - return adapterRequests, errs -} - -func (a *NanoInteractiveAdapter) MakeBids( - internalRequest *openrtb2.BidRequest, - externalRequest *adapters.RequestData, - response *adapters.ResponseData) (*adapters.BidderResponse, []error) { - - if response.StatusCode == http.StatusNoContent { - return nil, nil - } else if response.StatusCode == http.StatusBadRequest { - return nil, []error{&errortypes.BadInput{ - Message: "Invalid request.", - }} - } else if response.StatusCode != http.StatusOK { - return nil, []error{&errortypes.BadServerResponse{ - Message: fmt.Sprintf("unexpected HTTP status %d.", response.StatusCode), - }} - } - - var openRtbBidResponse openrtb2.BidResponse - - if err := json.Unmarshal(response.Body, &openRtbBidResponse); err != nil { - return nil, []error{&errortypes.BadServerResponse{ - Message: fmt.Sprintf("bad server body response"), - }} - } - - bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(openRtbBidResponse.SeatBid[0].Bid)) - bidResponse.Currency = openRtbBidResponse.Cur - - sb := openRtbBidResponse.SeatBid[0] - for i := 0; i < len(sb.Bid); i++ { - if !(sb.Bid[i].Price > 0) { - continue - } - bid := sb.Bid[i] - bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ - Bid: &bid, - BidType: openrtb_ext.BidTypeBanner, - }) - } - return bidResponse, nil -} - -func checkImp(imp *openrtb2.Imp) (string, error) { - // We support only banner impression - if imp.Banner == nil { - return "", fmt.Errorf("invalid MediaType. NanoInteractive only supports Banner type. ImpID=%s", imp.ID) - } - - var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { - return "", fmt.Errorf("ext not provided; ImpID=%s", imp.ID) - } - - var nanoExt openrtb_ext.ExtImpNanoInteractive - if err := json.Unmarshal(bidderExt.Bidder, &nanoExt); err != nil { - return "", fmt.Errorf("ext.bidder not provided; ImpID=%s", imp.ID) - } - if nanoExt.Pid == "" { - return "", fmt.Errorf("pid is empty; ImpID=%s", imp.ID) - } - - if nanoExt.Ref != "" { - return string(nanoExt.Ref), nil - } - - return "", nil -} - -// Builder builds a new instance of the NanoInteractive adapter for the given bidder with the given config. -func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { - bidder := &NanoInteractiveAdapter{ - endpoint: config.Endpoint, - } - return bidder, nil -} diff --git a/adapters/nanointeractive/nanointeractive_test.go b/adapters/nanointeractive/nanointeractive_test.go deleted file mode 100644 index fb108b8dd58..00000000000 --- a/adapters/nanointeractive/nanointeractive_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package nanointeractive - -import ( - "testing" - - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" -) - -func TestJsonSamples(t *testing.T) { - bidder, buildErr := Builder(openrtb_ext.BidderNanoInteractive, config.Adapter{ - Endpoint: "https://ad.audiencemanager.de/hbs"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - if buildErr != nil { - t.Fatalf("Builder returned unexpected error %v", buildErr) - } - - adapterstest.RunJSONBidderTest(t, "nanointeractivetest", bidder) -} diff --git a/adapters/nanointeractive/nanointeractivetest/exemplary/simple-banner.json b/adapters/nanointeractive/nanointeractivetest/exemplary/simple-banner.json deleted file mode 100644 index 727010b93fe..00000000000 --- a/adapters/nanointeractive/nanointeractivetest/exemplary/simple-banner.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [{"w": 300, "h": 250}] - }, - "ext": { - "bidder": { - "pid": "58bfec94eb0a1916fa380163" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://ad.audiencemanager.de/hbs", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [{ "w": 300,"h": 250} - ] - }, - "ext": { - "bidder": { - "pid": "58bfec94eb0a1916fa380163" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "nanointeractive", - "bid": [{ - "id": "1", - "impid": "test-imp-id", - "price": 0.4580126, - "adm": "", - "adid": "test_ad_id", - "adomain": ["audiencemanager.de"], - "cid": "test_cid", - "crid": "test_banner_crid", - "h": 250, - "w": 300 - }] - } - ], - "bidid": "5a7789eg2662b524d8d7264a96", - "cur": "EUR" - } - } - } - ], - - "expectedBidResponses": [ - { - "bids": [{ - "bid": { - "id": "1", - "impid": "test-imp-id", - "price": 0.4580126, - "adm": "", - "adid": "test_ad_id", - "adomain": ["audiencemanager.de"], - "cid": "test_cid", - "crid": "test_banner_crid", - "h": 250, - "w": 300 - }, - "type": "banner" - }] - } - ] -} diff --git a/adapters/nanointeractive/nanointeractivetest/supplemental/bad_response.json b/adapters/nanointeractive/nanointeractivetest/supplemental/bad_response.json deleted file mode 100644 index 587c952a042..00000000000 --- a/adapters/nanointeractive/nanointeractivetest/supplemental/bad_response.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": { - "pid": "213" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://ad.audiencemanager.de/hbs", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": { - "pid": "213" - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": "{\"id\"data.lost" - } - } - ], - - "expectedMakeBidsErrors": [ - { - "value": "bad server body response", - "comparison": "literal" - } - ] -} diff --git a/adapters/nanointeractive/nanointeractivetest/supplemental/invalid-params.json b/adapters/nanointeractive/nanointeractivetest/supplemental/invalid-params.json deleted file mode 100644 index 631dc99e5a8..00000000000 --- a/adapters/nanointeractive/nanointeractivetest/supplemental/invalid-params.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id-1", - "banner": {}, - "ext": { - "bidder": {} - } - }, - { - "id": "test-imp-id-2", - "banner": { - "format": [{"w": 300, "h": 250}] - }, - "ext": { - - } - }, - { - "id": "test-imp-id-3", - "banner": { - "format": [{"w": 300, "h": 250}] - } - }, - { - "id": "test-imp-id-4", - "video": {}, - "ext": { - "bidder": {} - } - }, - { - "id": "test-imp-id-5", - "audio": { - "startdelay": 0, - "api": [] - }, - "ext": { - "bidder": {} - } - } - ], - "site": { - "id": "siteID", - "publisher": { - "id": "1234" - } - }, - "device": { - "os": "android" - } - }, - "expectedMakeRequestsErrors": [ - { - "value": "pid is empty; ImpID=test-imp-id-1", - "comparison": "literal" - }, - { - "value": "ext.bidder not provided; ImpID=test-imp-id-2", - "comparison": "literal" - }, - { - "value": "ext not provided; ImpID=test-imp-id-3", - "comparison": "literal" - }, - { - "value": "invalid MediaType. NanoInteractive only supports Banner type. ImpID=test-imp-id-4", - "comparison": "literal" - }, - { - "value": "invalid MediaType. NanoInteractive only supports Banner type. ImpID=test-imp-id-5", - "comparison": "literal" - }, - { - "value": "no impressions in the bid request", - "comparison": "literal" - } - ] -} diff --git a/adapters/nanointeractive/nanointeractivetest/supplemental/multi-param.json b/adapters/nanointeractive/nanointeractivetest/supplemental/multi-param.json deleted file mode 100644 index 4f501901e2a..00000000000 --- a/adapters/nanointeractive/nanointeractivetest/supplemental/multi-param.json +++ /dev/null @@ -1,149 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [{"w": 300, "h": 250}] - }, - "ext": { - "bidder": { - "pid": "58bfec94eb0a1916fa380163", - "ref": "https://nanointeractive.com" - } - } - }, - { - "id": "test-imp-id2", - "banner": { - "format": [{"w": 300, "h": 250}] - }, - "ext": { - "bidder": { - "pid": "58bfec94eb0a1916fa380163", - "nq": ["search query"], - "category": "Automotive", - "subId": "a23", - "ref": "https://nanointeractive.com" - } - } - } - ], - "device": { - "ip": "127.0.0.1", - "ua": "user_agent" - }, - "user": { - "buyeruid": "userId" - } - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://ad.audiencemanager.de/hbs", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [{ "w": 300,"h": 250} - ] - }, - "ext": { - "bidder": { - "pid": "58bfec94eb0a1916fa380163", - "ref": "https://nanointeractive.com" - } - } - }, - { - "id": "test-imp-id2", - "banner": { - "format": [{ "w": 300,"h": 250} - ] - }, - "ext": { - "bidder": { - "pid": "58bfec94eb0a1916fa380163", - "nq": ["search query"], - "category": "Automotive", - "subId": "a23", - "ref": "https://nanointeractive.com" - } - } - } - ], - "site": { - "ref": "https://nanointeractive.com" - }, - "device": { - "ip": "127.0.0.1", - "ua": "user_agent" - }, - "user": { - "buyeruid": "userId" - } - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "nanointeractive", - "bid": [{ - "id": "1", - "impid": "test-imp-id", - "price": 0.4580126, - "adm": "", - "adid": "test_ad_id", - "adomain": ["audiencemanager.de"], - "cid": "test_cid", - "crid": "test_banner_crid", - "h": 250, - "w": 300 - },{ - "id": "2", - "impid": "test-imp-id2", - "price": 0, - "adm": "", - "adid": "test_ad_id", - "adomain": ["audiencemanager.de"], - "cid": "test_cid", - "crid": "test_banner_crid", - "h": 250, - "w": 300 - }] - } - ], - "bidid": "5a7789eg2662b524d8d7264a96", - "cur": "EUR" - } - } - } - ], - - "expectedBidResponses": [ - { - "bids": [{ - "bid": { - "id": "1", - "impid": "test-imp-id", - "price": 0.4580126, - "adm": "", - "adid": "test_ad_id", - "adomain": ["audiencemanager.de"], - "cid": "test_cid", - "crid": "test_banner_crid", - "h": 250, - "w": 300 - }, - "type": "banner" - }] - } - ] -} diff --git a/adapters/nanointeractive/nanointeractivetest/supplemental/status_204.json b/adapters/nanointeractive/nanointeractivetest/supplemental/status_204.json deleted file mode 100644 index ed4d8ff38b8..00000000000 --- a/adapters/nanointeractive/nanointeractivetest/supplemental/status_204.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": { - "pid": "123" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://ad.audiencemanager.de/hbs", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": { - "pid": "123" - } - } - } - ] - } - }, - "mockResponse": { - "status": 204, - "body": {} - } - } - ], - - "expectedBidResponses": [] -} diff --git a/adapters/nanointeractive/nanointeractivetest/supplemental/status_400.json b/adapters/nanointeractive/nanointeractivetest/supplemental/status_400.json deleted file mode 100644 index f02bd478656..00000000000 --- a/adapters/nanointeractive/nanointeractivetest/supplemental/status_400.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": { - "pid": "123" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://ad.audiencemanager.de/hbs", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": { - "pid": "123" - } - } - } - ] - } - }, - "mockResponse": { - "status": 400, - "body": {} - } - } - ], - - "expectedMakeBidsErrors": [ - { - "value": "Invalid request.", - "comparison": "literal" - } - ] -} diff --git a/adapters/nanointeractive/nanointeractivetest/supplemental/status_418.json b/adapters/nanointeractive/nanointeractivetest/supplemental/status_418.json deleted file mode 100644 index b7ed65da2af..00000000000 --- a/adapters/nanointeractive/nanointeractivetest/supplemental/status_418.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": { - "pid": "123" - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://ad.audiencemanager.de/hbs", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": { - "pid": "123" - } - } - } - ] - } - }, - "mockResponse": { - "status": 418, - "body": {} - } - } - ], - - "expectedMakeBidsErrors": [ - { - "value": "unexpected HTTP status 418.", - "comparison": "literal" - } - ] -} diff --git a/adapters/nanointeractive/params_test.go b/adapters/nanointeractive/params_test.go deleted file mode 100644 index a50425c770b..00000000000 --- a/adapters/nanointeractive/params_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package nanointeractive - -import ( - "encoding/json" - "testing" - - "github.com/prebid/prebid-server/openrtb_ext" -) - -// This file actually intends to test static/bidder-params/nanointeractive.json -// -// These also validate the format of the external API: request.imp[i].ext.prebid.bidder.nanointeracive - -// TestValidParams makes sure that the NanoInteractive schema accepts all imp.ext fields which we intend to support. -func TestValidParams(t *testing.T) { - validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") - if err != nil { - t.Fatalf("Failed to fetch the json-schemas. %v", err) - } - - for _, validParam := range validParams { - if err := validator.Validate(openrtb_ext.BidderNanoInteractive, json.RawMessage(validParam)); err != nil { - t.Errorf("Schema rejected NanoInteractive params: %s", validParam) - } - } -} - -// TestInvalidParams makes sure that the Marsmedia schema rejects all the imp.ext fields we don't support. -func TestInvalidParams(t *testing.T) { - validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") - if err != nil { - t.Fatalf("Failed to fetch the json-schemas. %v", err) - } - - for _, invalidParam := range invalidParams { - if err := validator.Validate(openrtb_ext.BidderNanoInteractive, json.RawMessage(invalidParam)); err == nil { - t.Errorf("Schema allowed unexpected params: %s", invalidParam) - } - } -} - -var validParams = []string{ - `{"pid": "dafad098"}`, - `{"pid":"dfasfda","nq":["search query"]}`, - `{"pid":"dfasfda","nq":["search query"],"subId":"any string value","category":"any string value"}`, -} - -var invalidParams = []string{ - `{"pid":123}`, - `{"pid":"12323","nq":"search query not an array"}`, - `{"pid":"12323","category":1}`, - `{"pid":"12323","subId":23}`, - ``, - `null`, - `true`, - `9`, - `1.2`, - `[]`, - `{}`, - `placementId`, - `zone`, - `zoneId`, -} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 3a2f871e199..c5b4b1134cc 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -118,7 +118,6 @@ import ( "github.com/prebid/prebid-server/adapters/mobfoxpb" "github.com/prebid/prebid-server/adapters/mobilefuse" "github.com/prebid/prebid-server/adapters/motorik" - "github.com/prebid/prebid-server/adapters/nanointeractive" "github.com/prebid/prebid-server/adapters/nextmillennium" "github.com/prebid/prebid-server/adapters/nobid" "github.com/prebid/prebid-server/adapters/onetag" @@ -317,7 +316,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderMobfoxpb: mobfoxpb.Builder, openrtb_ext.BidderMobileFuse: mobilefuse.Builder, openrtb_ext.BidderMotorik: motorik.Builder, - openrtb_ext.BidderNanoInteractive: nanointeractive.Builder, openrtb_ext.BidderNextMillennium: nextmillennium.Builder, openrtb_ext.BidderNoBid: nobid.Builder, openrtb_ext.BidderOneTag: onetag.Builder, diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index 8ce6f0df67c..2337f7f6bbb 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -109,22 +109,23 @@ func GetActiveBidders(infos config.BidderInfos) map[string]openrtb_ext.BidderNam func GetDisabledBidderWarningMessages(infos config.BidderInfos) map[string]string { removed := map[string]string{ - "lifestreet": `Bidder "lifestreet" is no longer available in Prebid Server. Please update your configuration.`, - "adagio": `Bidder "adagio" is no longer available in Prebid Server. Please update your configuration.`, - "somoaudience": `Bidder "somoaudience" is no longer available in Prebid Server. Please update your configuration.`, - "yssp": `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahooAds" in your configuration.`, - "andbeyondmedia": `Bidder "andbeyondmedia" is no longer available in Prebid Server. If you're looking to use the AndBeyond.Media SSP adapter, please rename it to "beyondmedia" in your configuration.`, - "oftmedia": `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`, - "groupm": `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`, - "verizonmedia": `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`, - "brightroll": `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`, - "engagebdr": `Bidder "engagebdr" is no longer available in Prebid Server. Please update your configuration.`, - "yeahmobi": `Bidder "yeahmobi" is no longer available in Prebid Server. Please update your configuration.`, - "ninthdecimal": `Bidder "ninthdecimal" is no longer available in Prebid Server. Please update your configuration.`, - "kubient": `Bidder "kubient" is no longer available in Prebid Server. Please update your configuration.`, - "definemedia": `Bidder "definemedia" is no longer available in Prebid Server. Please update your configuration.`, - "applogy": `Bidder "applogy" is no longer available in Prebid Server. Please update your configuration.`, - "rhythmone": `Bidder "rhythmone" is no longer available in Prebid Server. Please update your configuration.`, + "lifestreet": `Bidder "lifestreet" is no longer available in Prebid Server. Please update your configuration.`, + "adagio": `Bidder "adagio" is no longer available in Prebid Server. Please update your configuration.`, + "somoaudience": `Bidder "somoaudience" is no longer available in Prebid Server. Please update your configuration.`, + "yssp": `Bidder "yssp" is no longer available in Prebid Server. If you're looking to use the Yahoo SSP adapter, please rename it to "yahooAds" in your configuration.`, + "andbeyondmedia": `Bidder "andbeyondmedia" is no longer available in Prebid Server. If you're looking to use the AndBeyond.Media SSP adapter, please rename it to "beyondmedia" in your configuration.`, + "oftmedia": `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`, + "groupm": `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`, + "verizonmedia": `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`, + "brightroll": `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`, + "engagebdr": `Bidder "engagebdr" is no longer available in Prebid Server. Please update your configuration.`, + "yeahmobi": `Bidder "yeahmobi" is no longer available in Prebid Server. Please update your configuration.`, + "ninthdecimal": `Bidder "ninthdecimal" is no longer available in Prebid Server. Please update your configuration.`, + "kubient": `Bidder "kubient" is no longer available in Prebid Server. Please update your configuration.`, + "definemedia": `Bidder "definemedia" is no longer available in Prebid Server. Please update your configuration.`, + "applogy": `Bidder "applogy" is no longer available in Prebid Server. Please update your configuration.`, + "rhythmone": `Bidder "rhythmone" is no longer available in Prebid Server. Please update your configuration.`, + "nanointeractive": `Bidder "nanointeractive" is no longer available in Prebid Server. Please update your configuration.`, } return mergeRemovedAndDisabledBidderWarningMessages(removed, infos) diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 34c01f1ce32..67f43ec62dd 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -146,7 +146,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderMobfoxpb, BidderMobileFuse, BidderMotorik, - BidderNanoInteractive, BidderNextMillennium, BidderNoBid, BidderOneTag, @@ -435,7 +434,6 @@ const ( BidderMobfoxpb BidderName = "mobfoxpb" BidderMobileFuse BidderName = "mobilefuse" BidderMotorik BidderName = "motorik" - BidderNanoInteractive BidderName = "nanointeractive" BidderNextMillennium BidderName = "nextmillennium" BidderNoBid BidderName = "nobid" BidderOneTag BidderName = "onetag" diff --git a/openrtb_ext/imp_nanointeractive.go b/openrtb_ext/imp_nanointeractive.go deleted file mode 100644 index b381fab8eb7..00000000000 --- a/openrtb_ext/imp_nanointeractive.go +++ /dev/null @@ -1,10 +0,0 @@ -package openrtb_ext - -// ExtImpNanoInteractive defines the contract for bidrequest.imp[i].ext.prebid.bidder.nanointeractive -type ExtImpNanoInteractive struct { - Pid string `json:"pid"` - Nq []string `json:"nq,omitempty"` - Category string `json:"category,omitempty"` - SubId string `json:"subId,omitempty"` - Ref string `json:"ref,omitempty"` -} diff --git a/static/bidder-info/nanointeractive.yaml b/static/bidder-info/nanointeractive.yaml deleted file mode 100644 index 639c5450d2e..00000000000 --- a/static/bidder-info/nanointeractive.yaml +++ /dev/null @@ -1,15 +0,0 @@ -endpoint: "https://ad.audiencemanager.de/hbs" -maintainer: - email: "development@nanointeractive.com" -gvlVendorID: 72 -capabilities: - app: - mediaTypes: - - banner - site: - mediaTypes: - - banner -userSync: - redirect: - url: "https://ad.audiencemanager.de/hbs/cookie_sync?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirectUri={{.RedirectURL}}" - userMacro: "$UID" diff --git a/static/bidder-params/nanointeractive.json b/static/bidder-params/nanointeractive.json deleted file mode 100644 index aacd3154a92..00000000000 --- a/static/bidder-params/nanointeractive.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "NanoInteractive Adapter Params", - "description": "A schema which validates params accepted by the NanoInteractive adapter", - "type": "object", - "properties": { - "pid": { - "type": "string", - "description": "Placement id" - }, - "nq": { - "type": "array", - "items": { - "type": "string" - }, - "description": "search queries" - }, - "category": { - "type": "string", - "description": "IAB Category" - }, - "subId": { - "type": "string", - "description": "any segment value provided by publisher" - }, - "ref" : { - "type": "string", - "description": "referer" - } - }, - "required": ["pid"] -} From efdda05e3316c64d358898e6c1f55aba512a63bd Mon Sep 17 00:00:00 2001 From: Brian Sardo <1168933+bsardo@users.noreply.github.com> Date: Wed, 27 Sep 2023 09:09:41 -0400 Subject: [PATCH 142/268] Remove Config Backwards Compatibility: File System Stored Requests (#3124) --- config/config.go | 14 -------------- config/config_test.go | 27 --------------------------- 2 files changed, 41 deletions(-) diff --git a/config/config.go b/config/config.go index f503d0fcb59..dd7671c1412 100644 --- a/config/config.go +++ b/config/config.go @@ -1069,7 +1069,6 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { v.ReadInConfig() // Migrate config settings to maintain compatibility with old configs - migrateConfig(v) migrateConfigPurposeOneTreatment(v) migrateConfigSpecialFeature1(v) migrateConfigTCF2PurposeFlags(v) @@ -1135,19 +1134,6 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { } } -func migrateConfig(v *viper.Viper) { - // if stored_requests.filesystem is not a map in conf file as expected from defaults, - // means we have old-style settings; migrate them to new filesystem map to avoid breaking viper - if _, ok := v.Get("stored_requests.filesystem").(map[string]interface{}); !ok { - glog.Warning("stored_requests.filesystem should be changed to stored_requests.filesystem.enabled") - glog.Warning("stored_requests.directorypath should be changed to stored_requests.filesystem.directorypath") - m := v.GetStringMap("stored_requests.filesystem") - m["enabled"] = v.GetBool("stored_requests.filesystem") - m["directorypath"] = v.GetString("stored_requests.directorypath") - v.Set("stored_requests.filesystem", m) - } -} - func migrateConfigCompression(v *viper.Viper) { oldField := "enable_gzip" newField := "compression.response.enable_gzip" diff --git a/config/config_test.go b/config/config_test.go index 057ed06ecc4..325c59f6802 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -492,12 +492,6 @@ tmax_adjustments: pbs_response_preparation_duration_ms: 100 `) -var oldStoredRequestsConfig = []byte(` -stored_requests: - filesystem: true - directorypath: "/somepath" -`) - func cmpStrings(t *testing.T, key, expected, actual string) { t.Helper() assert.Equal(t, expected, actual, "%s: %s != %s", key, expected, actual) @@ -818,36 +812,15 @@ func TestValidateConfig(t *testing.T) { assert.Nil(t, err, "OpenRTB filesystem config should work. %v", err) } -func TestMigrateConfig(t *testing.T) { - v := viper.New() - SetupViper(v, "", bidderInfos) - v.Set("gdpr.default_value", "0") - v.SetConfigType("yaml") - v.ReadConfig(bytes.NewBuffer(oldStoredRequestsConfig)) - migrateConfig(v) - cfg, err := New(v, bidderInfos, mockNormalizeBidderName) - assert.NoError(t, err, "Setting up config should work but it doesn't") - cmpBools(t, "stored_requests.filesystem.enabled", true, cfg.StoredRequests.Files.Enabled) - cmpStrings(t, "stored_requests.filesystem.path", "/somepath", cfg.StoredRequests.Files.Path) -} - func TestMigrateConfigFromEnv(t *testing.T) { - if oldval, ok := os.LookupEnv("PBS_STORED_REQUESTS_FILESYSTEM"); ok { - defer os.Setenv("PBS_STORED_REQUESTS_FILESYSTEM", oldval) - } else { - defer os.Unsetenv("PBS_STORED_REQUESTS_FILESYSTEM") - } - if oldval, ok := os.LookupEnv("PBS_ADAPTERS_BIDDER1_ENDPOINT"); ok { defer os.Setenv("PBS_ADAPTERS_BIDDER1_ENDPOINT", oldval) } else { defer os.Unsetenv("PBS_ADAPTERS_BIDDER1_ENDPOINT") } - os.Setenv("PBS_STORED_REQUESTS_FILESYSTEM", "true") os.Setenv("PBS_ADAPTERS_BIDDER1_ENDPOINT", "http://bidder1_override.com") cfg, _ := newDefaultConfig(t) - cmpBools(t, "stored_requests.filesystem.enabled", true, cfg.StoredRequests.Files.Enabled) cmpStrings(t, "adapters.bidder1.endpoint", "http://bidder1_override.com", cfg.BidderInfos["bidder1"].Endpoint) } From 0c8f79b02890482e6e7d8a197807668ffc63ee4d Mon Sep 17 00:00:00 2001 From: Brian Sardo <1168933+bsardo@users.noreply.github.com> Date: Wed, 27 Sep 2023 13:31:21 -0400 Subject: [PATCH 143/268] Remove Config Backwards Compatibility: Enable Events (#3135) --- account/account.go | 16 ---------- account/account_test.go | 64 --------------------------------------- config/account.go | 1 - config/config.go | 36 +++------------------- config/config_test.go | 57 ++-------------------------------- config/events.go | 9 ++---- config/events_test.go | 47 +++------------------------- endpoints/events/event.go | 2 +- exchange/events.go | 4 +-- exchange/exchange_test.go | 2 +- 10 files changed, 17 insertions(+), 221 deletions(-) diff --git a/account/account.go b/account/account.go index 156ad5e6d39..36b6da51c38 100644 --- a/account/account.go +++ b/account/account.go @@ -111,9 +111,6 @@ func GetAccount(ctx context.Context, cfg *config.Configuration, fetcher stored_r account.Privacy.IPv4Config.AnonKeepBits = iputil.IPv4DefaultMaskingBitSize } - // set the value of events.enabled field based on deprecated events_enabled field and ensure backward compatibility - deprecateEventsEnabledField(account) - return account, nil } @@ -264,16 +261,3 @@ func useGDPRChannelEnabled(account *config.Account) bool { func useCCPAChannelEnabled(account *config.Account) bool { return account.CCPA.ChannelEnabled.IsSet() && !account.CCPA.IntegrationEnabled.IsSet() } - -// deprecateEventsEnabledField is responsible for ensuring backwards compatibility of "events_enabled" field. -// This function favors "events.enabled" field over deprecated "events_enabled" field, if values for both are set. -// If only deprecated "events_enabled" field is set then it sets the same value to "events.enabled" field. -func deprecateEventsEnabledField(account *config.Account) { - if account != nil { - if account.Events.Enabled == nil { - account.Events.Enabled = account.EventsEnabled - } - // assign the old value to the new value so old and new are always the same even though the new value is what is used in the application code. - account.EventsEnabled = account.Events.Enabled - } -} diff --git a/account/account_test.go b/account/account_test.go index d2694abc5a1..b527dee149f 100644 --- a/account/account_test.go +++ b/account/account_test.go @@ -13,7 +13,6 @@ import ( "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/stored_requests" "github.com/prebid/prebid-server/util/iputil" - "github.com/prebid/prebid-server/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) @@ -590,66 +589,3 @@ func TestAccountUpgradeStatusGetAccount(t *testing.T) { }) } } - -func TestDeprecateEventsEnabledField(t *testing.T) { - testCases := []struct { - name string - account *config.Account - want *bool - }{ - { - name: "account is nil", - account: nil, - want: nil, - }, - { - name: "account.EventsEnabled is nil, account.Events.Enabled is nil", - account: &config.Account{ - EventsEnabled: nil, - Events: config.Events{ - Enabled: nil, - }, - }, - want: nil, - }, - { - name: "account.EventsEnabled is nil, account.Events.Enabled is non-nil", - account: &config.Account{ - EventsEnabled: nil, - Events: config.Events{ - Enabled: ptrutil.ToPtr(true), - }, - }, - want: ptrutil.ToPtr(true), - }, - { - name: "account.EventsEnabled is non-nil, account.Events.Enabled is nil", - account: &config.Account{ - EventsEnabled: ptrutil.ToPtr(true), - Events: config.Events{ - Enabled: nil, - }, - }, - want: ptrutil.ToPtr(true), - }, - { - name: "account.EventsEnabled is non-nil, account.Events.Enabled is non-nil", - account: &config.Account{ - EventsEnabled: ptrutil.ToPtr(false), - Events: config.Events{ - Enabled: ptrutil.ToPtr(true), - }, - }, - want: ptrutil.ToPtr(true), - }, - } - - for _, test := range testCases { - t.Run(test.name, func(t *testing.T) { - deprecateEventsEnabledField(test.account) - if test.account != nil { - assert.Equal(t, test.want, test.account.Events.Enabled) - } - }) - } -} diff --git a/config/account.go b/config/account.go index 4b0ceeef0cf..d57fdb90773 100644 --- a/config/account.go +++ b/config/account.go @@ -28,7 +28,6 @@ type Account struct { ID string `mapstructure:"id" json:"id"` Disabled bool `mapstructure:"disabled" json:"disabled"` CacheTTL DefaultTTLs `mapstructure:"cache_ttl" json:"cache_ttl"` - EventsEnabled *bool `mapstructure:"events_enabled" json:"events_enabled"` // Deprecated: Use events.enabled instead. CCPA AccountCCPA `mapstructure:"ccpa" json:"ccpa"` GDPR AccountGDPR `mapstructure:"gdpr" json:"gdpr"` DebugAllow bool `mapstructure:"debug_allow" json:"debug_allow"` diff --git a/config/config.go b/config/config.go index dd7671c1412..9c2ef700f75 100644 --- a/config/config.go +++ b/config/config.go @@ -15,7 +15,6 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/ptrutil" "github.com/spf13/viper" ) @@ -141,12 +140,12 @@ func (cfg *Configuration) validate(v *viper.Viper) []error { glog.Warning(`With account_defaults.disabled=true, host-defined accounts must exist and have "disabled":false. All other requests will be rejected.`) } - if cfg.PriceFloors.Enabled { - glog.Warning(`cfg.PriceFloors.Enabled will currently not do anything as price floors feature is still under development.`) + if cfg.AccountDefaults.Events.Enabled { + glog.Warning(`account_defaults.events has no effect as the feature is under development.`) } - if len(cfg.AccountDefaults.Events.VASTEvents) > 0 { - errs = append(errs, errors.New("account_defaults.Events.VASTEvents has no effect as the feature is under development.")) + if cfg.PriceFloors.Enabled { + glog.Warning(`cfg.PriceFloors.Enabled will currently not do anything as price floors feature is still under development.`) } errs = cfg.Experiment.validate(errs) @@ -695,9 +694,6 @@ func New(v *viper.Viper, bidderInfos BidderInfos, normalizeBidderName func(strin // Update account defaults and generate base json for patch c.AccountDefaults.CacheTTL = c.CacheURL.DefaultTTLs // comment this out to set explicitly in config - // Update the deprecated and new events enabled values for account defaults. - c.AccountDefaults.EventsEnabled, c.AccountDefaults.Events.Enabled = migrateConfigEventsEnabled(c.AccountDefaults.EventsEnabled, c.AccountDefaults.Events.Enabled) - if err := c.MarshalAccountDefaults(); err != nil { return nil, err } @@ -1019,7 +1015,6 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { v.SetDefault("account_defaults.price_floors.use_dynamic_data", false) v.SetDefault("account_defaults.price_floors.max_rules", 100) v.SetDefault("account_defaults.price_floors.max_schema_dims", 3) - v.SetDefault("account_defaults.events_enabled", false) v.SetDefault("account_defaults.privacy.ipv6.anon_keep_bits", 56) v.SetDefault("account_defaults.privacy.ipv4.anon_keep_bits", 24) @@ -1118,6 +1113,7 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { // Defaults for account_defaults.events.default_url v.SetDefault("account_defaults.events.default_url", "https://PBS_HOST/event?t=##PBS-EVENTTYPE##&vtype=##PBS-VASTEVENT##&b=##PBS-BIDID##&f=i&a=##PBS-ACCOUNTID##&ts=##PBS-TIMESTAMP##&bidder=##PBS-BIDDER##&int=##PBS-INTEGRATION##&mt=##PBS-MEDIATYPE##&ch=##PBS-CHANNEL##&aid=##PBS-AUCTIONID##&l=##PBS-LINEID##") + v.SetDefault("account_defaults.events.enabled", false) v.SetDefault("experiment.adscert.mode", "off") v.SetDefault("experiment.adscert.inprocess.origin", "") @@ -1396,28 +1392,6 @@ func migrateConfigDatabaseConnection(v *viper.Viper) { } } -// migrateConfigEventsEnabled is responsible for ensuring backward compatibility of events_enabled field. -// This function copies the value of newField "events.enabled" and set it to the oldField "events_enabled". -// This is necessary to achieve the desired order of precedence favoring the account values over the host values -// given the account fetcher JSON merge mechanics. -func migrateConfigEventsEnabled(oldFieldValue *bool, newFieldValue *bool) (updatedOldFieldValue, updatedNewFieldValue *bool) { - newField := "account_defaults.events.enabled" - oldField := "account_defaults.events_enabled" - - updatedOldFieldValue = oldFieldValue - if oldFieldValue != nil { - glog.Warningf("%s is deprecated and should be changed to %s", oldField, newField) - } - if newFieldValue != nil { - if oldFieldValue != nil { - glog.Warningf("using %s and ignoring deprecated %s", newField, oldField) - } - updatedOldFieldValue = ptrutil.ToPtr(*newFieldValue) - } - - return updatedOldFieldValue, nil -} - func isConfigInfoPresent(v *viper.Viper, prefix string, fields []string) bool { prefix = prefix + "." for _, field := range fields { diff --git a/config/config_test.go b/config/config_test.go index 325c59f6802..5cc6fd65f51 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -12,7 +12,6 @@ import ( "github.com/prebid/go-gdpr/consentconstants" "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/ptrutil" "github.com/spf13/viper" "github.com/stretchr/testify/assert" ) @@ -191,8 +190,7 @@ func TestDefaults(t *testing.T) { cmpBools(t, "account_defaults.price_floors.use_dynamic_data", false, cfg.AccountDefaults.PriceFloors.UseDynamicData) cmpInts(t, "account_defaults.price_floors.max_rules", 100, cfg.AccountDefaults.PriceFloors.MaxRule) cmpInts(t, "account_defaults.price_floors.max_schema_dims", 3, cfg.AccountDefaults.PriceFloors.MaxSchemaDims) - cmpBools(t, "account_defaults.events_enabled", *cfg.AccountDefaults.EventsEnabled, false) - cmpNils(t, "account_defaults.events.enabled", cfg.AccountDefaults.Events.Enabled) + cmpBools(t, "account_defaults.events.enabled", false, cfg.AccountDefaults.Events.Enabled) cmpBools(t, "hooks.enabled", false, cfg.Hooks.Enabled) cmpStrings(t, "validations.banner_creative_max_size", "skip", cfg.Validations.BannerCreativeMaxSize) @@ -469,7 +467,6 @@ hooks: price_floors: enabled: true account_defaults: - events_enabled: false events: enabled: true price_floors: @@ -582,8 +579,7 @@ func TestFullConfig(t *testing.T) { cmpBools(t, "account_defaults.price_floors.use_dynamic_data", true, cfg.AccountDefaults.PriceFloors.UseDynamicData) cmpInts(t, "account_defaults.price_floors.max_rules", 120, cfg.AccountDefaults.PriceFloors.MaxRule) cmpInts(t, "account_defaults.price_floors.max_schema_dims", 5, cfg.AccountDefaults.PriceFloors.MaxSchemaDims) - cmpBools(t, "account_defaults.events_enabled", *cfg.AccountDefaults.EventsEnabled, true) - cmpNils(t, "account_defaults.events.enabled", cfg.AccountDefaults.Events.Enabled) + cmpBools(t, "account_defaults.events.enabled", true, cfg.AccountDefaults.Events.Enabled) cmpInts(t, "account_defaults.privacy.ipv6.anon_keep_bits", 50, cfg.AccountDefaults.Privacy.IPv6Config.AnonKeepBits) cmpInts(t, "account_defaults.privacy.ipv4.anon_keep_bits", 20, cfg.AccountDefaults.Privacy.IPv4Config.AnonKeepBits) @@ -3287,52 +3283,3 @@ func TestTCF2FeatureOneVendorException(t *testing.T) { assert.Equal(t, tt.wantIsVendorException, value, tt.description) } } - -func TestMigrateConfigEventsEnabled(t *testing.T) { - testCases := []struct { - name string - oldFieldValue *bool - newFieldValue *bool - expectedOldFieldValue *bool - expectedNewFieldValue *bool - }{ - { - name: "Both old and new fields are nil", - oldFieldValue: nil, - newFieldValue: nil, - expectedOldFieldValue: nil, - expectedNewFieldValue: nil, - }, - { - name: "Only old field is set", - oldFieldValue: ptrutil.ToPtr(true), - newFieldValue: nil, - expectedOldFieldValue: ptrutil.ToPtr(true), - expectedNewFieldValue: nil, - }, - { - name: "Only new field is set", - oldFieldValue: nil, - newFieldValue: ptrutil.ToPtr(true), - expectedOldFieldValue: ptrutil.ToPtr(true), - expectedNewFieldValue: nil, - }, - { - name: "Both old and new fields are set, override old field with new field value", - oldFieldValue: ptrutil.ToPtr(false), - newFieldValue: ptrutil.ToPtr(true), - expectedOldFieldValue: ptrutil.ToPtr(true), - expectedNewFieldValue: nil, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - updatedOldFieldValue, updatedNewFieldValue := migrateConfigEventsEnabled(tc.oldFieldValue, tc.newFieldValue) - - assert.Equal(t, tc.expectedOldFieldValue, updatedOldFieldValue) - assert.Nil(t, updatedNewFieldValue) - assert.Nil(t, tc.expectedNewFieldValue) - }) - } -} diff --git a/config/events.go b/config/events.go index 83d2df4b58d..cf3139d83ca 100644 --- a/config/events.go +++ b/config/events.go @@ -61,14 +61,14 @@ type VASTEvent struct { // within the VAST XML // Don't enable this feature. It is still under developmment. Please follow https://github.com/prebid/prebid-server/issues/1725 for more updates type Events struct { - Enabled *bool `mapstructure:"enabled" json:"enabled"` + Enabled bool `mapstructure:"enabled" json:"enabled"` DefaultURL string `mapstructure:"default_url" json:"default_url"` VASTEvents []VASTEvent `mapstructure:"vast_events" json:"vast_events,omitempty"` } // validate verifies the events object and returns error if at least one is invalid. func (e Events) validate(errs []error) []error { - if e.IsEnabled() { + if e.Enabled { if !isValidURL(e.DefaultURL) { return append(errs, errors.New("Invalid events.default_url")) } @@ -147,8 +147,3 @@ func isValidURL(eventURL string) bool { func (e VASTEvent) isTrackingEvent() bool { return e.CreateElement == TrackingVASTElement } - -// IsEnabled function returns the value of events.enabled field -func (e Events) IsEnabled() bool { - return e.Enabled != nil && *e.Enabled -} diff --git a/config/events_test.go b/config/events_test.go index 4baa9066dec..b4c196e9fa9 100644 --- a/config/events_test.go +++ b/config/events_test.go @@ -3,7 +3,6 @@ package config import ( "testing" - "github.com/prebid/prebid-server/util/ptrutil" "github.com/stretchr/testify/assert" ) @@ -262,29 +261,22 @@ func TestValidate(t *testing.T) { { description: "Empty default URL", events: Events{ - Enabled: ptrutil.ToPtr(true), + Enabled: true, }, expectErr: true, }, { description: "Events are disabled. Skips validations", events: Events{ - Enabled: ptrutil.ToPtr(false), + Enabled: false, DefaultURL: "", }, expectErr: false, }, - { - description: "Events are nil. Skip validations", - events: Events{ - Enabled: nil, - }, - expectErr: false, - }, { description: "No VAST Events and default URL present", events: Events{ - Enabled: ptrutil.ToPtr(true), + Enabled: true, DefaultURL: "http://prebid.org", }, expectErr: false, @@ -292,7 +284,7 @@ func TestValidate(t *testing.T) { { description: "Invalid VAST Event", events: Events{ - Enabled: ptrutil.ToPtr(true), + Enabled: true, DefaultURL: "http://prebid.org", VASTEvents: []VASTEvent{ {}, @@ -335,34 +327,3 @@ func TestValidateVASTEvents(t *testing.T) { assert.Equal(t, !test.expectErr, err == nil, test.description) } } - -func TestIsEnabled(t *testing.T) { - testCases := []struct { - name string - events Events - expected bool - }{ - { - name: "nil pointer", - events: Events{}, - expected: false, - }, - { - name: "event false", - events: Events{Enabled: ptrutil.ToPtr(false)}, - expected: false, - }, - { - name: "event true", - events: Events{Enabled: ptrutil.ToPtr(true)}, - expected: true, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - actual := tc.events.IsEnabled() - assert.Equal(t, tc.expected, actual) - }) - } -} diff --git a/endpoints/events/event.go b/endpoints/events/event.go index 089d5606552..e8084f1b273 100644 --- a/endpoints/events/event.go +++ b/endpoints/events/event.go @@ -108,7 +108,7 @@ func (e *eventEndpoint) Handle(w http.ResponseWriter, r *http.Request, _ httprou } // Check if events are enabled for the account - if !account.Events.IsEnabled() { + if !account.Events.Enabled { w.WriteHeader(http.StatusUnauthorized) w.Write([]byte(fmt.Sprintf("Account '%s' doesn't support events", eventRequest.AccountID))) return diff --git a/exchange/events.go b/exchange/events.go index fd52d6b676a..e4f6b0d503f 100644 --- a/exchange/events.go +++ b/exchange/events.go @@ -28,7 +28,7 @@ type eventTracking struct { func getEventTracking(requestExtPrebid *openrtb_ext.ExtRequestPrebid, ts time.Time, account *config.Account, bidderInfos config.BidderInfos, externalURL string) *eventTracking { return &eventTracking{ accountID: account.ID, - enabledForAccount: account.Events.IsEnabled(), + enabledForAccount: account.Events.Enabled, enabledForRequest: requestExtPrebid != nil && requestExtPrebid.Events != nil, auctionTimestampMs: ts.UnixNano() / 1e+6, integrationType: getIntegrationType(requestExtPrebid), @@ -130,7 +130,7 @@ func (ev *eventTracking) makeEventURL(evType analytics.EventType, pbsBid *entiti }) } -// isEnabled checks if events are enabled by default or on account/request level +// isEventAllowed checks if events are enabled by default or on account/request level func (ev *eventTracking) isEventAllowed() bool { return ev.enabledForAccount || ev.enabledForRequest } diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go index c4b85ebeb1f..6e6e8afe76e 100644 --- a/exchange/exchange_test.go +++ b/exchange/exchange_test.go @@ -2359,7 +2359,7 @@ func runSpec(t *testing.T, filename string, spec *exchangeSpec) { Account: config.Account{ ID: "testaccount", Events: config.Events{ - Enabled: &spec.EventsEnabled, + Enabled: spec.EventsEnabled, }, DebugAllow: true, PriceFloors: config.AccountPriceFloors{Enabled: spec.AccountFloorsEnabled}, From fc3694436c499e6c584bee946df46422cf432eef Mon Sep 17 00:00:00 2001 From: Brian Sardo <1168933+bsardo@users.noreply.github.com> Date: Wed, 27 Sep 2023 15:31:03 -0400 Subject: [PATCH 144/268] Remove Config Backwards Compatibility: Enable GZIP (#3125) --- config/config.go | 18 ----------- config/config_test.go | 71 ------------------------------------------- server/server_test.go | 1 - 3 files changed, 90 deletions(-) diff --git a/config/config.go b/config/config.go index 9c2ef700f75..df4d53f1813 100644 --- a/config/config.go +++ b/config/config.go @@ -28,7 +28,6 @@ type Configuration struct { Client HTTPClient `mapstructure:"http_client"` CacheClient HTTPClient `mapstructure:"http_client_cache"` AdminPort int `mapstructure:"admin_port"` - EnableGzip bool `mapstructure:"enable_gzip"` Compression Compression `mapstructure:"compression"` // GarbageCollectorThreshold allocates virtual memory (in bytes) which is not used by PBS but // serves as a hack to trigger the garbage collector only when the heap reaches at least this size. @@ -1068,7 +1067,6 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { migrateConfigSpecialFeature1(v) migrateConfigTCF2PurposeFlags(v) migrateConfigDatabaseConnection(v) - migrateConfigCompression(v) // These defaults must be set after the migrate functions because those functions look for the presence of these // config fields and there isn't a way to detect presence of a config field using the viper package if a default @@ -1109,8 +1107,6 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { v.SetDefault("gdpr.tcf2.special_feature1.vendor_exceptions", []openrtb_ext.BidderName{}) v.SetDefault("price_floors.enabled", false) - v.SetDefault("enable_gzip", false) - // Defaults for account_defaults.events.default_url v.SetDefault("account_defaults.events.default_url", "https://PBS_HOST/event?t=##PBS-EVENTTYPE##&vtype=##PBS-VASTEVENT##&b=##PBS-BIDID##&f=i&a=##PBS-ACCOUNTID##&ts=##PBS-TIMESTAMP##&bidder=##PBS-BIDDER##&int=##PBS-INTEGRATION##&mt=##PBS-MEDIATYPE##&ch=##PBS-CHANNEL##&aid=##PBS-AUCTIONID##&l=##PBS-LINEID##") v.SetDefault("account_defaults.events.enabled", false) @@ -1130,20 +1126,6 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { } } -func migrateConfigCompression(v *viper.Viper) { - oldField := "enable_gzip" - newField := "compression.response.enable_gzip" - if v.IsSet(oldField) { - oldConfig := v.GetBool(oldField) - if v.IsSet(newField) { - glog.Warningf("using %s and ignoring deprecated %s", newField, oldField) - } else { - glog.Warningf("%s is deprecated and should be changed to %s", oldField, newField) - v.Set(newField, oldConfig) - } - } -} - func migrateConfigPurposeOneTreatment(v *viper.Viper) { if oldConfig, ok := v.Get("gdpr.tcf2.purpose_one_treatement").(map[string]interface{}); ok { if v.IsSet("gdpr.tcf2.purpose_one_treatment") { diff --git a/config/config_test.go b/config/config_test.go index 5cc6fd65f51..69bd12134da 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -179,7 +179,6 @@ func TestDefaults(t *testing.T) { cmpBools(t, "price_floors.enabled", false, cfg.PriceFloors.Enabled) // Assert compression related defaults - cmpBools(t, "enable_gzip", false, cfg.EnableGzip) cmpBools(t, "compression.request.enable_gzip", false, cfg.Compression.Request.GZIP) cmpBools(t, "compression.response.enable_gzip", false, cfg.Compression.Response.GZIP) @@ -384,7 +383,6 @@ external_url: http://prebid-server.prebid.org/ host: prebid-server.prebid.org port: 1234 admin_port: 5678 -enable_gzip: false compression: request: enable_gzip: true @@ -585,7 +583,6 @@ func TestFullConfig(t *testing.T) { cmpInts(t, "account_defaults.privacy.ipv4.anon_keep_bits", 20, cfg.AccountDefaults.Privacy.IPv4Config.AnonKeepBits) // Assert compression related defaults - cmpBools(t, "enable_gzip", false, cfg.EnableGzip) cmpBools(t, "compression.request.enable_gzip", true, cfg.Compression.Request.GZIP) cmpBools(t, "compression.response.enable_gzip", false, cfg.Compression.Response.GZIP) @@ -2566,74 +2563,6 @@ func TestMigrateConfigDatabaseQueryParams(t *testing.T) { assert.Equal(t, want_queries.poll_for_updates_amp_query, v.GetString("stored_responses.database.poll_for_updates.amp_query")) } -func TestMigrateConfigCompression(t *testing.T) { - testCases := []struct { - desc string - config []byte - wantEnableGZIP bool - wantReqGZIPEnabled bool - wantRespGZIPEnabled bool - }{ - - { - desc: "New config and old config not set", - config: []byte{}, - wantEnableGZIP: false, - wantReqGZIPEnabled: false, - wantRespGZIPEnabled: false, - }, - { - desc: "Old config set, new config not set", - config: []byte(` - enable_gzip: true - `), - wantEnableGZIP: true, - wantRespGZIPEnabled: true, - wantReqGZIPEnabled: false, - }, - { - desc: "Old config not set, new config set", - config: []byte(` - compression: - response: - enable_gzip: true - request: - enable_gzip: false - `), - wantEnableGZIP: false, - wantRespGZIPEnabled: true, - wantReqGZIPEnabled: false, - }, - { - desc: "Old config set and new config set", - config: []byte(` - enable_gzip: true - compression: - response: - enable_gzip: false - request: - enable_gzip: true - `), - wantEnableGZIP: true, - wantRespGZIPEnabled: false, - wantReqGZIPEnabled: true, - }, - } - - for _, test := range testCases { - v := viper.New() - v.SetConfigType("yaml") - err := v.ReadConfig(bytes.NewBuffer(test.config)) - assert.NoError(t, err) - - migrateConfigCompression(v) - - assert.Equal(t, test.wantEnableGZIP, v.GetBool("enable_gzip"), test.desc) - assert.Equal(t, test.wantReqGZIPEnabled, v.GetBool("compression.request.enable_gzip"), test.desc) - assert.Equal(t, test.wantRespGZIPEnabled, v.GetBool("compression.response.enable_gzip"), test.desc) - } -} - func TestIsConfigInfoPresent(t *testing.T) { configPrefix1Field2Only := []byte(` prefix1: diff --git a/server/server_test.go b/server/server_test.go index 23b45656d7d..7af892d3567 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -192,7 +192,6 @@ func TestListen(t *testing.T) { Port: 8000, UnixSocketEnable: false, UnixSocketName: "prebid_socket", - EnableGzip: false, } ) From f879f63f62a8f722393cb9ae608a1c83df9349a3 Mon Sep 17 00:00:00 2001 From: Brian Sardo <1168933+bsardo@users.noreply.github.com> Date: Thu, 28 Sep 2023 15:04:33 -0400 Subject: [PATCH 145/268] Remove Config Backwards Compatibility: DB Connection Info (#3146) --- config/config.go | 281 +++----------- config/config_test.go | 875 ------------------------------------------ 2 files changed, 57 insertions(+), 1099 deletions(-) diff --git a/config/config.go b/config/config.go index df4d53f1813..b083719e956 100644 --- a/config/config.go +++ b/config/config.go @@ -889,6 +889,25 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { v.SetDefault("category_mapping.filesystem.enabled", true) v.SetDefault("category_mapping.filesystem.directorypath", "./static/category-mapping") v.SetDefault("category_mapping.http.endpoint", "") + v.SetDefault("stored_requests.database.connection.driver", "") + v.SetDefault("stored_requests.database.connection.dbname", "") + v.SetDefault("stored_requests.database.connection.host", "") + v.SetDefault("stored_requests.database.connection.port", 0) + v.SetDefault("stored_requests.database.connection.user", "") + v.SetDefault("stored_requests.database.connection.password", "") + v.SetDefault("stored_requests.database.connection.query_string", "") + v.SetDefault("stored_requests.database.connection.tls.root_cert", "") + v.SetDefault("stored_requests.database.connection.tls.client_cert", "") + v.SetDefault("stored_requests.database.connection.tls.client_key", "") + v.SetDefault("stored_requests.database.fetcher.query", "") + v.SetDefault("stored_requests.database.fetcher.amp_query", "") + v.SetDefault("stored_requests.database.initialize_caches.timeout_ms", 0) + v.SetDefault("stored_requests.database.initialize_caches.query", "") + v.SetDefault("stored_requests.database.initialize_caches.amp_query", "") + v.SetDefault("stored_requests.database.poll_for_updates.refresh_rate_seconds", 0) + v.SetDefault("stored_requests.database.poll_for_updates.timeout_ms", 0) + v.SetDefault("stored_requests.database.poll_for_updates.query", "") + v.SetDefault("stored_requests.database.poll_for_updates.amp_query", "") v.SetDefault("stored_requests.filesystem.enabled", false) v.SetDefault("stored_requests.filesystem.directorypath", "./stored_requests/data/by_id") v.SetDefault("stored_requests.directorypath", "./stored_requests/data/by_id") @@ -906,6 +925,25 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { v.SetDefault("stored_requests.http_events.timeout_ms", 0) // stored_video is short for stored_video_requests. // PBS is not in the business of storing video content beyond the normal prebid cache system. + v.SetDefault("stored_video_req.database.connection.driver", "") + v.SetDefault("stored_video_req.database.connection.dbname", "") + v.SetDefault("stored_video_req.database.connection.host", "") + v.SetDefault("stored_video_req.database.connection.port", 0) + v.SetDefault("stored_video_req.database.connection.user", "") + v.SetDefault("stored_video_req.database.connection.password", "") + v.SetDefault("stored_video_req.database.connection.query_string", "") + v.SetDefault("stored_video_req.database.connection.tls.root_cert", "") + v.SetDefault("stored_video_req.database.connection.tls.client_cert", "") + v.SetDefault("stored_video_req.database.connection.tls.client_key", "") + v.SetDefault("stored_video_req.database.fetcher.query", "") + v.SetDefault("stored_video_req.database.fetcher.amp_query", "") + v.SetDefault("stored_video_req.database.initialize_caches.timeout_ms", 0) + v.SetDefault("stored_video_req.database.initialize_caches.query", "") + v.SetDefault("stored_video_req.database.initialize_caches.amp_query", "") + v.SetDefault("stored_video_req.database.poll_for_updates.refresh_rate_seconds", 0) + v.SetDefault("stored_video_req.database.poll_for_updates.timeout_ms", 0) + v.SetDefault("stored_video_req.database.poll_for_updates.query", "") + v.SetDefault("stored_video_req.database.poll_for_updates.amp_query", "") v.SetDefault("stored_video_req.filesystem.enabled", false) v.SetDefault("stored_video_req.filesystem.directorypath", "") v.SetDefault("stored_video_req.http.endpoint", "") @@ -919,6 +957,25 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { v.SetDefault("stored_video_req.http_events.endpoint", "") v.SetDefault("stored_video_req.http_events.refresh_rate_seconds", 0) v.SetDefault("stored_video_req.http_events.timeout_ms", 0) + v.SetDefault("stored_responses.database.connection.driver", "") + v.SetDefault("stored_responses.database.connection.dbname", "") + v.SetDefault("stored_responses.database.connection.host", "") + v.SetDefault("stored_responses.database.connection.port", 0) + v.SetDefault("stored_responses.database.connection.user", "") + v.SetDefault("stored_responses.database.connection.password", "") + v.SetDefault("stored_responses.database.connection.query_string", "") + v.SetDefault("stored_responses.database.connection.tls.root_cert", "") + v.SetDefault("stored_responses.database.connection.tls.client_cert", "") + v.SetDefault("stored_responses.database.connection.tls.client_key", "") + v.SetDefault("stored_responses.database.fetcher.query", "") + v.SetDefault("stored_responses.database.fetcher.amp_query", "") + v.SetDefault("stored_responses.database.initialize_caches.timeout_ms", 0) + v.SetDefault("stored_responses.database.initialize_caches.query", "") + v.SetDefault("stored_responses.database.initialize_caches.amp_query", "") + v.SetDefault("stored_responses.database.poll_for_updates.refresh_rate_seconds", 0) + v.SetDefault("stored_responses.database.poll_for_updates.timeout_ms", 0) + v.SetDefault("stored_responses.database.poll_for_updates.query", "") + v.SetDefault("stored_responses.database.poll_for_updates.amp_query", "") v.SetDefault("stored_responses.filesystem.enabled", false) v.SetDefault("stored_responses.filesystem.directorypath", "") v.SetDefault("stored_responses.http.endpoint", "") @@ -1053,8 +1110,6 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { v.SetDefault("request_validation.ipv4_private_networks", []string{"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "169.254.0.0/16", "127.0.0.0/8"}) v.SetDefault("request_validation.ipv6_private_networks", []string{"::1/128", "fc00::/7", "fe80::/10", "ff00::/8", "2001:db8::/32"}) - bindDatabaseEnvVars(v) - // Set environment variable support: v.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) v.SetTypeByDefaultValue(true) @@ -1066,7 +1121,6 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { migrateConfigPurposeOneTreatment(v) migrateConfigSpecialFeature1(v) migrateConfigTCF2PurposeFlags(v) - migrateConfigDatabaseConnection(v) // These defaults must be set after the migrate functions because those functions look for the presence of these // config fields and there isn't a way to detect presence of a config field using the viper package if a default @@ -1207,173 +1261,6 @@ func migrateConfigTCF2PurposeEnabledFlags(v *viper.Viper) { } } -func migrateConfigDatabaseConnection(v *viper.Viper) { - - type QueryParamMigration struct { - old string - new string - } - - type QueryMigration struct { - name string - params []QueryParamMigration - } - - type Migration struct { - old string - new string - fields []string - queryMigrations []QueryMigration - } - - queryParamMigrations := struct { - RequestIdList QueryParamMigration - ImpIdList QueryParamMigration - IdList QueryParamMigration - LastUpdated QueryParamMigration - }{ - RequestIdList: QueryParamMigration{ - old: "%REQUEST_ID_LIST%", - new: "$REQUEST_ID_LIST", - }, - ImpIdList: QueryParamMigration{ - old: "%IMP_ID_LIST%", - new: "$IMP_ID_LIST", - }, - IdList: QueryParamMigration{ - old: "%ID_LIST%", - new: "$ID_LIST", - }, - LastUpdated: QueryParamMigration{ - old: "$1", - new: "$LAST_UPDATED", - }, - } - - queryMigrations := []QueryMigration{ - { - name: "fetcher.query", - params: []QueryParamMigration{queryParamMigrations.RequestIdList, queryParamMigrations.ImpIdList, queryParamMigrations.IdList}, - }, - { - name: "fetcher.amp_query", - params: []QueryParamMigration{queryParamMigrations.RequestIdList, queryParamMigrations.ImpIdList, queryParamMigrations.IdList}, - }, - { - name: "poll_for_updates.query", - params: []QueryParamMigration{queryParamMigrations.LastUpdated}, - }, - { - name: "poll_for_updates.amp_query", - params: []QueryParamMigration{queryParamMigrations.LastUpdated}, - }, - } - - migrations := []Migration{ - { - old: "stored_requests.postgres", - new: "stored_requests.database", - fields: []string{ - "connection.dbname", - "connection.host", - "connection.port", - "connection.user", - "connection.password", - "fetcher.query", - "fetcher.amp_query", - "initialize_caches.timeout_ms", - "initialize_caches.query", - "initialize_caches.amp_query", - "poll_for_updates.refresh_rate_seconds", - "poll_for_updates.timeout_ms", - "poll_for_updates.query", - "poll_for_updates.amp_query", - }, - queryMigrations: queryMigrations, - }, - { - old: "stored_video_req.postgres", - new: "stored_video_req.database", - fields: []string{ - "connection.dbname", - "connection.host", - "connection.port", - "connection.user", - "connection.password", - "fetcher.query", - "initialize_caches.timeout_ms", - "initialize_caches.query", - "poll_for_updates.refresh_rate_seconds", - "poll_for_updates.timeout_ms", - "poll_for_updates.query", - }, - queryMigrations: queryMigrations, - }, - { - old: "stored_responses.postgres", - new: "stored_responses.database", - fields: []string{ - "connection.dbname", - "connection.host", - "connection.port", - "connection.user", - "connection.password", - "fetcher.query", - "initialize_caches.timeout_ms", - "initialize_caches.query", - "poll_for_updates.refresh_rate_seconds", - "poll_for_updates.timeout_ms", - "poll_for_updates.query", - }, - queryMigrations: queryMigrations, - }, - } - - for _, migration := range migrations { - driverField := migration.new + ".connection.driver" - newConfigInfoPresent := isConfigInfoPresent(v, migration.new, migration.fields) - oldConfigInfoPresent := isConfigInfoPresent(v, migration.old, migration.fields) - - if !newConfigInfoPresent && oldConfigInfoPresent { - glog.Warning(fmt.Sprintf("%s is deprecated and should be changed to %s", migration.old, migration.new)) - glog.Warning(fmt.Sprintf("%s is not set, using default (postgres)", driverField)) - v.Set(driverField, "postgres") - - for _, field := range migration.fields { - oldField := migration.old + "." + field - newField := migration.new + "." + field - if v.IsSet(oldField) { - glog.Warning(fmt.Sprintf("%s is deprecated and should be changed to %s", oldField, newField)) - v.Set(newField, v.Get(oldField)) - } - } - - for _, queryMigration := range migration.queryMigrations { - oldQueryField := migration.old + "." + queryMigration.name - newQueryField := migration.new + "." + queryMigration.name - queryString := v.GetString(oldQueryField) - for _, queryParam := range queryMigration.params { - if strings.Contains(queryString, queryParam.old) { - glog.Warning(fmt.Sprintf("Query param %s for %s is deprecated and should be changed to %s", queryParam.old, oldQueryField, queryParam.new)) - queryString = strings.ReplaceAll(queryString, queryParam.old, queryParam.new) - v.Set(newQueryField, queryString) - } - } - } - } else if newConfigInfoPresent && oldConfigInfoPresent { - glog.Warning(fmt.Sprintf("using %s and ignoring deprecated %s", migration.new, migration.old)) - - for _, field := range migration.fields { - oldField := migration.old + "." + field - newField := migration.new + "." + field - if v.IsSet(oldField) { - glog.Warning(fmt.Sprintf("using %s and ignoring deprecated %s", newField, oldField)) - } - } - } - } -} - func isConfigInfoPresent(v *viper.Viper, prefix string, fields []string) bool { prefix = prefix + "." for _, field := range fields { @@ -1385,60 +1272,6 @@ func isConfigInfoPresent(v *viper.Viper, prefix string, fields []string) bool { return false } -func bindDatabaseEnvVars(v *viper.Viper) { - v.BindEnv("stored_requests.database.connection.driver") - v.BindEnv("stored_requests.database.connection.dbname") - v.BindEnv("stored_requests.database.connection.host") - v.BindEnv("stored_requests.database.connection.port") - v.BindEnv("stored_requests.database.connection.user") - v.BindEnv("stored_requests.database.connection.password") - v.BindEnv("stored_requests.database.connection.query_string") - v.BindEnv("stored_requests.database.connection.tls.root_cert") - v.BindEnv("stored_requests.database.connection.tls.client_cert") - v.BindEnv("stored_requests.database.connection.tls.client_key") - v.BindEnv("stored_requests.database.fetcher.query") - v.BindEnv("stored_requests.database.fetcher.amp_query") - v.BindEnv("stored_requests.database.initialize_caches.timeout_ms") - v.BindEnv("stored_requests.database.initialize_caches.query") - v.BindEnv("stored_requests.database.initialize_caches.amp_query") - v.BindEnv("stored_requests.database.poll_for_updates.refresh_rate_seconds") - v.BindEnv("stored_requests.database.poll_for_updates.timeout_ms") - v.BindEnv("stored_requests.database.poll_for_updates.query") - v.BindEnv("stored_requests.database.poll_for_updates.amp_query") - v.BindEnv("stored_video_req.database.connection.driver") - v.BindEnv("stored_video_req.database.connection.dbname") - v.BindEnv("stored_video_req.database.connection.host") - v.BindEnv("stored_video_req.database.connection.port") - v.BindEnv("stored_video_req.database.connection.user") - v.BindEnv("stored_video_req.database.connection.password") - v.BindEnv("stored_video_req.database.connection.query_string") - v.BindEnv("stored_video_req.database.connection.tls.root_cert") - v.BindEnv("stored_video_req.database.connection.tls.client_cert") - v.BindEnv("stored_video_req.database.connection.tls.client_key") - v.BindEnv("stored_video_req.database.fetcher.query") - v.BindEnv("stored_video_req.database.initialize_caches.timeout_ms") - v.BindEnv("stored_video_req.database.initialize_caches.query") - v.BindEnv("stored_video_req.database.poll_for_updates.refresh_rate_seconds") - v.BindEnv("stored_video_req.database.poll_for_updates.timeout_ms") - v.BindEnv("stored_video_req.database.poll_for_updates.query") - v.BindEnv("stored_responses.database.connection.driver") - v.BindEnv("stored_responses.database.connection.dbname") - v.BindEnv("stored_responses.database.connection.host") - v.BindEnv("stored_responses.database.connection.port") - v.BindEnv("stored_responses.database.connection.user") - v.BindEnv("stored_responses.database.connection.password") - v.BindEnv("stored_responses.database.connection.query_string") - v.BindEnv("stored_responses.database.connection.tls.root_cert") - v.BindEnv("stored_responses.database.connection.tls.client_cert") - v.BindEnv("stored_responses.database.connection.tls.client_key") - v.BindEnv("stored_responses.database.fetcher.query") - v.BindEnv("stored_responses.database.initialize_caches.timeout_ms") - v.BindEnv("stored_responses.database.initialize_caches.query") - v.BindEnv("stored_responses.database.poll_for_updates.refresh_rate_seconds") - v.BindEnv("stored_responses.database.poll_for_updates.timeout_ms") - v.BindEnv("stored_responses.database.poll_for_updates.query") -} - func setBidderDefaults(v *viper.Viper, bidder string) { adapterCfgPrefix := "adapters." + bidder v.BindEnv(adapterCfgPrefix + ".disabled") diff --git a/config/config_test.go b/config/config_test.go index 69bd12134da..9fc85715c6a 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -5,8 +5,6 @@ import ( "errors" "net" "os" - "strconv" - "strings" "testing" "time" @@ -1690,879 +1688,6 @@ func TestMigrateConfigTCF2EnforcePurposeFlags(t *testing.T) { } } -func TestMigrateConfigDatabaseConnection(t *testing.T) { - type configs struct { - old []byte - new []byte - both []byte - } - - // Stored Requests Config Migration - storedReqestsConfigs := configs{ - old: []byte(` - stored_requests: - postgres: - connection: - dbname: "old_connection_dbname" - host: "old_connection_host" - port: 1000 - user: "old_connection_user" - password: "old_connection_password" - fetcher: - query: "old_fetcher_query" - amp_query: "old_fetcher_amp_query" - initialize_caches: - timeout_ms: 1000 - query: "old_initialize_caches_query" - amp_query: "old_initialize_caches_amp_query" - poll_for_updates: - refresh_rate_seconds: 1000 - timeout_ms: 1000 - query: "old_poll_for_updates_query" - amp_query: "old_poll_for_updates_amp_query" - `), - new: []byte(` - stored_requests: - database: - connection: - dbname: "new_connection_dbname" - host: "new_connection_host" - port: 2000 - user: "new_connection_user" - password: "new_connection_password" - fetcher: - query: "new_fetcher_query" - amp_query: "new_fetcher_amp_query" - initialize_caches: - timeout_ms: 2000 - query: "new_initialize_caches_query" - amp_query: "new_initialize_caches_amp_query" - poll_for_updates: - refresh_rate_seconds: 2000 - timeout_ms: 2000 - query: "new_poll_for_updates_query" - amp_query: "new_poll_for_updates_amp_query" - `), - both: []byte(` - stored_requests: - postgres: - connection: - dbname: "old_connection_dbname" - host: "old_connection_host" - port: 1000 - user: "old_connection_user" - password: "old_connection_password" - fetcher: - query: "old_fetcher_query" - amp_query: "old_fetcher_amp_query" - initialize_caches: - timeout_ms: 1000 - query: "old_initialize_caches_query" - amp_query: "old_initialize_caches_amp_query" - poll_for_updates: - refresh_rate_seconds: 1000 - timeout_ms: 1000 - query: "old_poll_for_updates_query" - amp_query: "old_poll_for_updates_amp_query" - database: - connection: - dbname: "new_connection_dbname" - host: "new_connection_host" - port: 2000 - user: "new_connection_user" - password: "new_connection_password" - fetcher: - query: "new_fetcher_query" - amp_query: "new_fetcher_amp_query" - initialize_caches: - timeout_ms: 2000 - query: "new_initialize_caches_query" - amp_query: "new_initialize_caches_amp_query" - poll_for_updates: - refresh_rate_seconds: 2000 - timeout_ms: 2000 - query: "new_poll_for_updates_query" - amp_query: "new_poll_for_updates_amp_query" - `), - } - - storedRequestsTests := []struct { - description string - config []byte - - want_connection_dbname string - want_connection_host string - want_connection_port int - want_connection_user string - want_connection_password string - want_fetcher_query string - want_fetcher_amp_query string - want_initialize_caches_timeout_ms int - want_initialize_caches_query string - want_initialize_caches_amp_query string - want_poll_for_updates_refresh_rate_seconds int - want_poll_for_updates_timeout_ms int - want_poll_for_updates_query string - want_poll_for_updates_amp_query string - }{ - { - description: "New config and old config not set", - config: []byte{}, - }, - { - description: "New config not set, old config set", - config: storedReqestsConfigs.old, - - want_connection_dbname: "old_connection_dbname", - want_connection_host: "old_connection_host", - want_connection_port: 1000, - want_connection_user: "old_connection_user", - want_connection_password: "old_connection_password", - want_fetcher_query: "old_fetcher_query", - want_fetcher_amp_query: "old_fetcher_amp_query", - want_initialize_caches_timeout_ms: 1000, - want_initialize_caches_query: "old_initialize_caches_query", - want_initialize_caches_amp_query: "old_initialize_caches_amp_query", - want_poll_for_updates_refresh_rate_seconds: 1000, - want_poll_for_updates_timeout_ms: 1000, - want_poll_for_updates_query: "old_poll_for_updates_query", - want_poll_for_updates_amp_query: "old_poll_for_updates_amp_query", - }, - { - description: "New config set, old config not set", - config: storedReqestsConfigs.new, - - want_connection_dbname: "new_connection_dbname", - want_connection_host: "new_connection_host", - want_connection_port: 2000, - want_connection_user: "new_connection_user", - want_connection_password: "new_connection_password", - want_fetcher_query: "new_fetcher_query", - want_fetcher_amp_query: "new_fetcher_amp_query", - want_initialize_caches_timeout_ms: 2000, - want_initialize_caches_query: "new_initialize_caches_query", - want_initialize_caches_amp_query: "new_initialize_caches_amp_query", - want_poll_for_updates_refresh_rate_seconds: 2000, - want_poll_for_updates_timeout_ms: 2000, - want_poll_for_updates_query: "new_poll_for_updates_query", - want_poll_for_updates_amp_query: "new_poll_for_updates_amp_query", - }, - { - description: "New config and old config set", - config: storedReqestsConfigs.both, - - want_connection_dbname: "new_connection_dbname", - want_connection_host: "new_connection_host", - want_connection_port: 2000, - want_connection_user: "new_connection_user", - want_connection_password: "new_connection_password", - want_fetcher_query: "new_fetcher_query", - want_fetcher_amp_query: "new_fetcher_amp_query", - want_initialize_caches_timeout_ms: 2000, - want_initialize_caches_query: "new_initialize_caches_query", - want_initialize_caches_amp_query: "new_initialize_caches_amp_query", - want_poll_for_updates_refresh_rate_seconds: 2000, - want_poll_for_updates_timeout_ms: 2000, - want_poll_for_updates_query: "new_poll_for_updates_query", - want_poll_for_updates_amp_query: "new_poll_for_updates_amp_query", - }, - } - - for _, tt := range storedRequestsTests { - v := viper.New() - v.SetConfigType("yaml") - v.ReadConfig(bytes.NewBuffer(tt.config)) - - migrateConfigDatabaseConnection(v) - - if len(tt.config) > 0 { - assert.Equal(t, tt.want_connection_dbname, v.GetString("stored_requests.database.connection.dbname"), tt.description) - assert.Equal(t, tt.want_connection_host, v.GetString("stored_requests.database.connection.host"), tt.description) - assert.Equal(t, tt.want_connection_port, v.GetInt("stored_requests.database.connection.port"), tt.description) - assert.Equal(t, tt.want_connection_user, v.GetString("stored_requests.database.connection.user"), tt.description) - assert.Equal(t, tt.want_connection_password, v.GetString("stored_requests.database.connection.password"), tt.description) - assert.Equal(t, tt.want_fetcher_query, v.GetString("stored_requests.database.fetcher.query"), tt.description) - assert.Equal(t, tt.want_fetcher_amp_query, v.GetString("stored_requests.database.fetcher.amp_query"), tt.description) - assert.Equal(t, tt.want_initialize_caches_timeout_ms, v.GetInt("stored_requests.database.initialize_caches.timeout_ms"), tt.description) - assert.Equal(t, tt.want_initialize_caches_query, v.GetString("stored_requests.database.initialize_caches.query"), tt.description) - assert.Equal(t, tt.want_initialize_caches_amp_query, v.GetString("stored_requests.database.initialize_caches.amp_query"), tt.description) - assert.Equal(t, tt.want_poll_for_updates_refresh_rate_seconds, v.GetInt("stored_requests.database.poll_for_updates.refresh_rate_seconds"), tt.description) - assert.Equal(t, tt.want_poll_for_updates_timeout_ms, v.GetInt("stored_requests.database.poll_for_updates.timeout_ms"), tt.description) - assert.Equal(t, tt.want_poll_for_updates_query, v.GetString("stored_requests.database.poll_for_updates.query"), tt.description) - assert.Equal(t, tt.want_poll_for_updates_amp_query, v.GetString("stored_requests.database.poll_for_updates.amp_query"), tt.description) - } else { - assert.Nil(t, v.Get("stored_requests.database.connection.dbname"), tt.description) - assert.Nil(t, v.Get("stored_requests.database.connection.host"), tt.description) - assert.Nil(t, v.Get("stored_requests.database.connection.port"), tt.description) - assert.Nil(t, v.Get("stored_requests.database.connection.user"), tt.description) - assert.Nil(t, v.Get("stored_requests.database.connection.password"), tt.description) - assert.Nil(t, v.Get("stored_requests.database.fetcher.query"), tt.description) - assert.Nil(t, v.Get("stored_requests.database.fetcher.amp_query"), tt.description) - assert.Nil(t, v.Get("stored_requests.database.initialize_caches.timeout_ms"), tt.description) - assert.Nil(t, v.Get("stored_requests.database.initialize_caches.query"), tt.description) - assert.Nil(t, v.Get("stored_requests.database.initialize_caches.amp_query"), tt.description) - assert.Nil(t, v.Get("stored_requests.database.poll_for_updates.refresh_rate_seconds"), tt.description) - assert.Nil(t, v.Get("stored_requests.database.poll_for_updates.timeout_ms"), tt.description) - assert.Nil(t, v.Get("stored_requests.database.poll_for_updates.query"), tt.description) - assert.Nil(t, v.Get("stored_requests.database.poll_for_updates.amp_query"), tt.description) - } - } - - // Stored Video Reqs Config Migration - storedVideoReqsConfigs := configs{ - old: []byte(` - stored_video_req: - postgres: - connection: - dbname: "old_connection_dbname" - host: "old_connection_host" - port: 1000 - user: "old_connection_user" - password: "old_connection_password" - fetcher: - query: "old_fetcher_query" - initialize_caches: - timeout_ms: 1000 - query: "old_initialize_caches_query" - poll_for_updates: - refresh_rate_seconds: 1000 - timeout_ms: 1000 - query: "old_poll_for_updates_query" - `), - new: []byte(` - stored_video_req: - database: - connection: - dbname: "new_connection_dbname" - host: "new_connection_host" - port: 2000 - user: "new_connection_user" - password: "new_connection_password" - fetcher: - query: "new_fetcher_query" - initialize_caches: - timeout_ms: 2000 - query: "new_initialize_caches_query" - poll_for_updates: - refresh_rate_seconds: 2000 - timeout_ms: 2000 - query: "new_poll_for_updates_query" - `), - both: []byte(` - stored_video_req: - postgres: - connection: - dbname: "old_connection_dbname" - host: "old_connection_host" - port: 1000 - user: "old_connection_user" - password: "old_connection_password" - fetcher: - query: "old_fetcher_query" - initialize_caches: - timeout_ms: 1000 - query: "old_initialize_caches_query" - poll_for_updates: - refresh_rate_seconds: 1000 - timeout_ms: 1000 - query: "old_poll_for_updates_query" - database: - connection: - dbname: "new_connection_dbname" - host: "new_connection_host" - port: 2000 - user: "new_connection_user" - password: "new_connection_password" - fetcher: - query: "new_fetcher_query" - initialize_caches: - timeout_ms: 2000 - query: "new_initialize_caches_query" - poll_for_updates: - refresh_rate_seconds: 2000 - timeout_ms: 2000 - query: "new_poll_for_updates_query" - `), - } - - storedVideoReqsTests := []struct { - description string - config []byte - - want_connection_dbname string - want_connection_host string - want_connection_port int - want_connection_user string - want_connection_password string - want_fetcher_query string - want_initialize_caches_timeout_ms int - want_initialize_caches_query string - want_poll_for_updates_refresh_rate_seconds int - want_poll_for_updates_timeout_ms int - want_poll_for_updates_query string - }{ - { - description: "New config and old config not set", - config: []byte{}, - }, - { - description: "New config not set, old config set", - config: storedVideoReqsConfigs.old, - - want_connection_dbname: "old_connection_dbname", - want_connection_host: "old_connection_host", - want_connection_port: 1000, - want_connection_user: "old_connection_user", - want_connection_password: "old_connection_password", - want_fetcher_query: "old_fetcher_query", - want_initialize_caches_timeout_ms: 1000, - want_initialize_caches_query: "old_initialize_caches_query", - want_poll_for_updates_refresh_rate_seconds: 1000, - want_poll_for_updates_timeout_ms: 1000, - want_poll_for_updates_query: "old_poll_for_updates_query", - }, - { - description: "New config set, old config not set", - config: storedVideoReqsConfigs.new, - - want_connection_dbname: "new_connection_dbname", - want_connection_host: "new_connection_host", - want_connection_port: 2000, - want_connection_user: "new_connection_user", - want_connection_password: "new_connection_password", - want_fetcher_query: "new_fetcher_query", - want_initialize_caches_timeout_ms: 2000, - want_initialize_caches_query: "new_initialize_caches_query", - want_poll_for_updates_refresh_rate_seconds: 2000, - want_poll_for_updates_timeout_ms: 2000, - want_poll_for_updates_query: "new_poll_for_updates_query", - }, - { - description: "New config and old config set", - config: storedVideoReqsConfigs.both, - - want_connection_dbname: "new_connection_dbname", - want_connection_host: "new_connection_host", - want_connection_port: 2000, - want_connection_user: "new_connection_user", - want_connection_password: "new_connection_password", - want_fetcher_query: "new_fetcher_query", - want_initialize_caches_timeout_ms: 2000, - want_initialize_caches_query: "new_initialize_caches_query", - want_poll_for_updates_refresh_rate_seconds: 2000, - want_poll_for_updates_timeout_ms: 2000, - want_poll_for_updates_query: "new_poll_for_updates_query", - }, - } - - for _, tt := range storedVideoReqsTests { - v := viper.New() - v.SetConfigType("yaml") - v.ReadConfig(bytes.NewBuffer(tt.config)) - - migrateConfigDatabaseConnection(v) - - if len(tt.config) > 0 { - assert.Equal(t, tt.want_connection_dbname, v.Get("stored_video_req.database.connection.dbname").(string), tt.description) - assert.Equal(t, tt.want_connection_host, v.Get("stored_video_req.database.connection.host").(string), tt.description) - assert.Equal(t, tt.want_connection_port, v.Get("stored_video_req.database.connection.port").(int), tt.description) - assert.Equal(t, tt.want_connection_user, v.Get("stored_video_req.database.connection.user").(string), tt.description) - assert.Equal(t, tt.want_connection_password, v.Get("stored_video_req.database.connection.password").(string), tt.description) - assert.Equal(t, tt.want_fetcher_query, v.Get("stored_video_req.database.fetcher.query").(string), tt.description) - assert.Equal(t, tt.want_initialize_caches_timeout_ms, v.Get("stored_video_req.database.initialize_caches.timeout_ms").(int), tt.description) - assert.Equal(t, tt.want_initialize_caches_query, v.Get("stored_video_req.database.initialize_caches.query").(string), tt.description) - assert.Equal(t, tt.want_poll_for_updates_refresh_rate_seconds, v.Get("stored_video_req.database.poll_for_updates.refresh_rate_seconds").(int), tt.description) - assert.Equal(t, tt.want_poll_for_updates_timeout_ms, v.Get("stored_video_req.database.poll_for_updates.timeout_ms").(int), tt.description) - assert.Equal(t, tt.want_poll_for_updates_query, v.Get("stored_video_req.database.poll_for_updates.query").(string), tt.description) - } else { - assert.Nil(t, v.Get("stored_video_req.database.connection.dbname"), tt.description) - assert.Nil(t, v.Get("stored_video_req.database.connection.host"), tt.description) - assert.Nil(t, v.Get("stored_video_req.database.connection.port"), tt.description) - assert.Nil(t, v.Get("stored_video_req.database.connection.user"), tt.description) - assert.Nil(t, v.Get("stored_video_req.database.connection.password"), tt.description) - assert.Nil(t, v.Get("stored_video_req.database.fetcher.query"), tt.description) - assert.Nil(t, v.Get("stored_video_req.database.initialize_caches.timeout_ms"), tt.description) - assert.Nil(t, v.Get("stored_video_req.database.initialize_caches.query"), tt.description) - assert.Nil(t, v.Get("stored_video_req.database.poll_for_updates.refresh_rate_seconds"), tt.description) - assert.Nil(t, v.Get("stored_video_req.database.poll_for_updates.timeout_ms"), tt.description) - assert.Nil(t, v.Get("stored_video_req.database.poll_for_updates.query"), tt.description) - } - } - - // Stored Responses Config Migration - storedResponsesConfigs := configs{ - old: []byte(` - stored_responses: - postgres: - connection: - dbname: "old_connection_dbname" - host: "old_connection_host" - port: 1000 - user: "old_connection_user" - password: "old_connection_password" - fetcher: - query: "old_fetcher_query" - initialize_caches: - timeout_ms: 1000 - query: "old_initialize_caches_query" - poll_for_updates: - refresh_rate_seconds: 1000 - timeout_ms: 1000 - query: "old_poll_for_updates_query" - `), - new: []byte(` - stored_responses: - database: - connection: - dbname: "new_connection_dbname" - host: "new_connection_host" - port: 2000 - user: "new_connection_user" - password: "new_connection_password" - fetcher: - query: "new_fetcher_query" - initialize_caches: - timeout_ms: 2000 - query: "new_initialize_caches_query" - poll_for_updates: - refresh_rate_seconds: 2000 - timeout_ms: 2000 - query: "new_poll_for_updates_query" - `), - both: []byte(` - stored_responses: - postgres: - connection: - dbname: "old_connection_dbname" - host: "old_connection_host" - port: 1000 - user: "old_connection_user" - password: "old_connection_password" - fetcher: - query: "old_fetcher_query" - initialize_caches: - timeout_ms: 1000 - query: "old_initialize_caches_query" - poll_for_updates: - refresh_rate_seconds: 1000 - timeout_ms: 1000 - query: "old_poll_for_updates_query" - database: - connection: - dbname: "new_connection_dbname" - host: "new_connection_host" - port: 2000 - user: "new_connection_user" - password: "new_connection_password" - fetcher: - query: "new_fetcher_query" - initialize_caches: - timeout_ms: 2000 - query: "new_initialize_caches_query" - poll_for_updates: - refresh_rate_seconds: 2000 - timeout_ms: 2000 - query: "new_poll_for_updates_query" - `), - } - - storedResponsesTests := []struct { - description string - config []byte - - want_connection_dbname string - want_connection_host string - want_connection_port int - want_connection_user string - want_connection_password string - want_fetcher_query string - want_initialize_caches_timeout_ms int - want_initialize_caches_query string - want_poll_for_updates_refresh_rate_seconds int - want_poll_for_updates_timeout_ms int - want_poll_for_updates_query string - }{ - { - description: "New config and old config not set", - config: []byte{}, - }, - { - description: "New config not set, old config set", - config: storedResponsesConfigs.old, - - want_connection_dbname: "old_connection_dbname", - want_connection_host: "old_connection_host", - want_connection_port: 1000, - want_connection_user: "old_connection_user", - want_connection_password: "old_connection_password", - want_fetcher_query: "old_fetcher_query", - want_initialize_caches_timeout_ms: 1000, - want_initialize_caches_query: "old_initialize_caches_query", - want_poll_for_updates_refresh_rate_seconds: 1000, - want_poll_for_updates_timeout_ms: 1000, - want_poll_for_updates_query: "old_poll_for_updates_query", - }, - { - description: "New config set, old config not set", - config: storedResponsesConfigs.new, - - want_connection_dbname: "new_connection_dbname", - want_connection_host: "new_connection_host", - want_connection_port: 2000, - want_connection_user: "new_connection_user", - want_connection_password: "new_connection_password", - want_fetcher_query: "new_fetcher_query", - want_initialize_caches_timeout_ms: 2000, - want_initialize_caches_query: "new_initialize_caches_query", - want_poll_for_updates_refresh_rate_seconds: 2000, - want_poll_for_updates_timeout_ms: 2000, - want_poll_for_updates_query: "new_poll_for_updates_query", - }, - { - description: "New config and old config set", - config: storedResponsesConfigs.both, - - want_connection_dbname: "new_connection_dbname", - want_connection_host: "new_connection_host", - want_connection_port: 2000, - want_connection_user: "new_connection_user", - want_connection_password: "new_connection_password", - want_fetcher_query: "new_fetcher_query", - want_initialize_caches_timeout_ms: 2000, - want_initialize_caches_query: "new_initialize_caches_query", - want_poll_for_updates_refresh_rate_seconds: 2000, - want_poll_for_updates_timeout_ms: 2000, - want_poll_for_updates_query: "new_poll_for_updates_query", - }, - } - - for _, tt := range storedResponsesTests { - v := viper.New() - v.SetConfigType("yaml") - v.ReadConfig(bytes.NewBuffer(tt.config)) - - migrateConfigDatabaseConnection(v) - - if len(tt.config) > 0 { - assert.Equal(t, tt.want_connection_dbname, v.Get("stored_responses.database.connection.dbname").(string), tt.description) - assert.Equal(t, tt.want_connection_host, v.Get("stored_responses.database.connection.host").(string), tt.description) - assert.Equal(t, tt.want_connection_port, v.Get("stored_responses.database.connection.port").(int), tt.description) - assert.Equal(t, tt.want_connection_user, v.Get("stored_responses.database.connection.user").(string), tt.description) - assert.Equal(t, tt.want_connection_password, v.Get("stored_responses.database.connection.password").(string), tt.description) - assert.Equal(t, tt.want_fetcher_query, v.Get("stored_responses.database.fetcher.query").(string), tt.description) - assert.Equal(t, tt.want_initialize_caches_timeout_ms, v.Get("stored_responses.database.initialize_caches.timeout_ms").(int), tt.description) - assert.Equal(t, tt.want_initialize_caches_query, v.Get("stored_responses.database.initialize_caches.query").(string), tt.description) - assert.Equal(t, tt.want_poll_for_updates_refresh_rate_seconds, v.Get("stored_responses.database.poll_for_updates.refresh_rate_seconds").(int), tt.description) - assert.Equal(t, tt.want_poll_for_updates_timeout_ms, v.Get("stored_responses.database.poll_for_updates.timeout_ms").(int), tt.description) - assert.Equal(t, tt.want_poll_for_updates_query, v.Get("stored_responses.database.poll_for_updates.query").(string), tt.description) - } else { - assert.Nil(t, v.Get("stored_responses.database.connection.dbname"), tt.description) - assert.Nil(t, v.Get("stored_responses.database.connection.host"), tt.description) - assert.Nil(t, v.Get("stored_responses.database.connection.port"), tt.description) - assert.Nil(t, v.Get("stored_responses.database.connection.user"), tt.description) - assert.Nil(t, v.Get("stored_responses.database.connection.password"), tt.description) - assert.Nil(t, v.Get("stored_responses.database.fetcher.query"), tt.description) - assert.Nil(t, v.Get("stored_responses.database.initialize_caches.timeout_ms"), tt.description) - assert.Nil(t, v.Get("stored_responses.database.initialize_caches.query"), tt.description) - assert.Nil(t, v.Get("stored_responses.database.poll_for_updates.refresh_rate_seconds"), tt.description) - assert.Nil(t, v.Get("stored_responses.database.poll_for_updates.timeout_ms"), tt.description) - assert.Nil(t, v.Get("stored_responses.database.poll_for_updates.query"), tt.description) - } - } -} - -func TestMigrateConfigDatabaseConnectionUsingEnvVars(t *testing.T) { - tests := []struct { - description string - prefix string - setDatabaseEnvVars bool - setPostgresEnvVars bool - }{ - { - description: "stored requests old config set", - prefix: "stored_requests", - setPostgresEnvVars: true, - }, - { - description: "stored requests new config set", - prefix: "stored_requests", - setDatabaseEnvVars: true, - }, - { - description: "stored requests old and new config set", - prefix: "stored_requests", - setDatabaseEnvVars: true, - setPostgresEnvVars: true, - }, - { - description: "stored video requests old config set", - prefix: "stored_video_req", - setPostgresEnvVars: true, - }, - { - description: "stored video requests new config set", - prefix: "stored_video_req", - setDatabaseEnvVars: true, - }, - { - description: "stored video requests old and new config set", - prefix: "stored_video_req", - setDatabaseEnvVars: true, - setPostgresEnvVars: true, - }, - { - description: "stored responses old config set", - prefix: "stored_responses", - setPostgresEnvVars: true, - }, - { - description: "stored responses new config set", - prefix: "stored_responses", - setDatabaseEnvVars: true, - }, - { - description: "stored responses old and new config set", - prefix: "stored_responses", - setDatabaseEnvVars: true, - setPostgresEnvVars: true, - }, - } - - pgValues := map[string]string{ - "CONNECTION_DBNAME": "pg-dbname", - "CONNECTION_HOST": "pg-host", - "CONNECTION_PORT": "1", - "CONNECTION_USER": "pg-user", - "CONNECTION_PASSWORD": "pg-password", - "FETCHER_QUERY": "pg-fetcher-query", - "FETCHER_AMP_QUERY": "pg-fetcher-amp-query", - "INITIALIZE_CACHES_TIMEOUT_MS": "2", - "INITIALIZE_CACHES_QUERY": "pg-init-caches-query", - "INITIALIZE_CACHES_AMP_QUERY": "pg-init-caches-amp-query", - "POLL_FOR_UPDATES_REFRESH_RATE_SECONDS": "3", - "POLL_FOR_UPDATES_TIMEOUT_MS": "4", - "POLL_FOR_UPDATES_QUERY": "pg-poll-query $LAST_UPDATED", - "POLL_FOR_UPDATES_AMP_QUERY": "pg-poll-amp-query $LAST_UPDATED", - } - dbValues := map[string]string{ - "CONNECTION_DBNAME": "db-dbname", - "CONNECTION_HOST": "db-host", - "CONNECTION_PORT": "5", - "CONNECTION_USER": "db-user", - "CONNECTION_PASSWORD": "db-password", - "FETCHER_QUERY": "db-fetcher-query", - "FETCHER_AMP_QUERY": "db-fetcher-amp-query", - "INITIALIZE_CACHES_TIMEOUT_MS": "6", - "INITIALIZE_CACHES_QUERY": "db-init-caches-query", - "INITIALIZE_CACHES_AMP_QUERY": "db-init-caches-amp-query", - "POLL_FOR_UPDATES_REFRESH_RATE_SECONDS": "7", - "POLL_FOR_UPDATES_TIMEOUT_MS": "8", - "POLL_FOR_UPDATES_QUERY": "db-poll-query $LAST_UPDATED", - "POLL_FOR_UPDATES_AMP_QUERY": "db-poll-amp-query $LAST_UPDATED", - } - - for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - prefix := "PBS_" + strings.ToUpper(tt.prefix) - - // validation rules require in memory cache type to not be "none" - // given that we want to set the poll for update queries to non-empty values - envVarName := prefix + "_IN_MEMORY_CACHE_TYPE" - if oldval, ok := os.LookupEnv(envVarName); ok { - defer os.Setenv(envVarName, oldval) - } else { - defer os.Unsetenv(envVarName) - } - os.Setenv(envVarName, "unbounded") - - if tt.setPostgresEnvVars { - for suffix, v := range pgValues { - envVarName := prefix + "_POSTGRES_" + suffix - if oldval, ok := os.LookupEnv(envVarName); ok { - defer os.Setenv(envVarName, oldval) - } else { - defer os.Unsetenv(envVarName) - } - os.Setenv(envVarName, v) - } - } - if tt.setDatabaseEnvVars { - for suffix, v := range dbValues { - envVarName := prefix + "_DATABASE_" + suffix - if oldval, ok := os.LookupEnv(envVarName); ok { - defer os.Setenv(envVarName, oldval) - } else { - defer os.Unsetenv(envVarName) - } - os.Setenv(envVarName, v) - } - } - - c, _ := newDefaultConfig(t) - - expectedDatabaseValues := map[string]string{} - if tt.setDatabaseEnvVars { - expectedDatabaseValues = dbValues - } else if tt.setPostgresEnvVars { - expectedDatabaseValues = pgValues - } - - if tt.prefix == "stored_requests" { - assert.Equal(t, expectedDatabaseValues["CONNECTION_DBNAME"], c.StoredRequests.Database.ConnectionInfo.Database, tt.description) - assert.Equal(t, expectedDatabaseValues["CONNECTION_HOST"], c.StoredRequests.Database.ConnectionInfo.Host, tt.description) - assert.Equal(t, expectedDatabaseValues["CONNECTION_PORT"], strconv.Itoa(c.StoredRequests.Database.ConnectionInfo.Port), tt.description) - assert.Equal(t, expectedDatabaseValues["CONNECTION_USER"], c.StoredRequests.Database.ConnectionInfo.Username, tt.description) - assert.Equal(t, expectedDatabaseValues["CONNECTION_PASSWORD"], c.StoredRequests.Database.ConnectionInfo.Password, tt.description) - assert.Equal(t, expectedDatabaseValues["FETCHER_QUERY"], c.StoredRequests.Database.FetcherQueries.QueryTemplate, tt.description) - assert.Equal(t, expectedDatabaseValues["INITIALIZE_CACHES_TIMEOUT_MS"], strconv.Itoa(c.StoredRequests.Database.CacheInitialization.Timeout), tt.description) - assert.Equal(t, expectedDatabaseValues["INITIALIZE_CACHES_QUERY"], c.StoredRequests.Database.CacheInitialization.Query, tt.description) - assert.Equal(t, expectedDatabaseValues["POLL_FOR_UPDATES_REFRESH_RATE_SECONDS"], strconv.Itoa(c.StoredRequests.Database.PollUpdates.RefreshRate), tt.description) - assert.Equal(t, expectedDatabaseValues["POLL_FOR_UPDATES_TIMEOUT_MS"], strconv.Itoa(c.StoredRequests.Database.PollUpdates.Timeout), tt.description) - assert.Equal(t, expectedDatabaseValues["POLL_FOR_UPDATES_QUERY"], c.StoredRequests.Database.PollUpdates.Query, tt.description) - // AMP queries are only migrated for stored requests - assert.Equal(t, expectedDatabaseValues["FETCHER_AMP_QUERY"], c.StoredRequests.Database.FetcherQueries.AmpQueryTemplate, tt.description) - assert.Equal(t, expectedDatabaseValues["INITIALIZE_CACHES_AMP_QUERY"], c.StoredRequests.Database.CacheInitialization.AmpQuery, tt.description) - assert.Equal(t, expectedDatabaseValues["POLL_FOR_UPDATES_AMP_QUERY"], c.StoredRequests.Database.PollUpdates.AmpQuery, tt.description) - } else if tt.prefix == "stored_video_req" { - assert.Equal(t, expectedDatabaseValues["CONNECTION_DBNAME"], c.StoredVideo.Database.ConnectionInfo.Database, tt.description) - assert.Equal(t, expectedDatabaseValues["CONNECTION_HOST"], c.StoredVideo.Database.ConnectionInfo.Host, tt.description) - assert.Equal(t, expectedDatabaseValues["CONNECTION_PORT"], strconv.Itoa(c.StoredVideo.Database.ConnectionInfo.Port), tt.description) - assert.Equal(t, expectedDatabaseValues["CONNECTION_USER"], c.StoredVideo.Database.ConnectionInfo.Username, tt.description) - assert.Equal(t, expectedDatabaseValues["CONNECTION_PASSWORD"], c.StoredVideo.Database.ConnectionInfo.Password, tt.description) - assert.Equal(t, expectedDatabaseValues["FETCHER_QUERY"], c.StoredVideo.Database.FetcherQueries.QueryTemplate, tt.description) - assert.Equal(t, expectedDatabaseValues["INITIALIZE_CACHES_TIMEOUT_MS"], strconv.Itoa(c.StoredVideo.Database.CacheInitialization.Timeout), tt.description) - assert.Equal(t, expectedDatabaseValues["INITIALIZE_CACHES_QUERY"], c.StoredVideo.Database.CacheInitialization.Query, tt.description) - assert.Equal(t, expectedDatabaseValues["POLL_FOR_UPDATES_REFRESH_RATE_SECONDS"], strconv.Itoa(c.StoredVideo.Database.PollUpdates.RefreshRate), tt.description) - assert.Equal(t, expectedDatabaseValues["POLL_FOR_UPDATES_TIMEOUT_MS"], strconv.Itoa(c.StoredVideo.Database.PollUpdates.Timeout), tt.description) - assert.Equal(t, expectedDatabaseValues["POLL_FOR_UPDATES_QUERY"], c.StoredVideo.Database.PollUpdates.Query, tt.description) - assert.Empty(t, c.StoredVideo.Database.FetcherQueries.AmpQueryTemplate, tt.description) - assert.Empty(t, c.StoredVideo.Database.CacheInitialization.AmpQuery, tt.description) - assert.Empty(t, c.StoredVideo.Database.PollUpdates.AmpQuery, tt.description) - } else { - assert.Equal(t, expectedDatabaseValues["CONNECTION_DBNAME"], c.StoredResponses.Database.ConnectionInfo.Database, tt.description) - assert.Equal(t, expectedDatabaseValues["CONNECTION_HOST"], c.StoredResponses.Database.ConnectionInfo.Host, tt.description) - assert.Equal(t, expectedDatabaseValues["CONNECTION_PORT"], strconv.Itoa(c.StoredResponses.Database.ConnectionInfo.Port), tt.description) - assert.Equal(t, expectedDatabaseValues["CONNECTION_USER"], c.StoredResponses.Database.ConnectionInfo.Username, tt.description) - assert.Equal(t, expectedDatabaseValues["CONNECTION_PASSWORD"], c.StoredResponses.Database.ConnectionInfo.Password, tt.description) - assert.Equal(t, expectedDatabaseValues["FETCHER_QUERY"], c.StoredResponses.Database.FetcherQueries.QueryTemplate, tt.description) - assert.Equal(t, expectedDatabaseValues["INITIALIZE_CACHES_TIMEOUT_MS"], strconv.Itoa(c.StoredResponses.Database.CacheInitialization.Timeout), tt.description) - assert.Equal(t, expectedDatabaseValues["INITIALIZE_CACHES_QUERY"], c.StoredResponses.Database.CacheInitialization.Query, tt.description) - assert.Equal(t, expectedDatabaseValues["POLL_FOR_UPDATES_REFRESH_RATE_SECONDS"], strconv.Itoa(c.StoredResponses.Database.PollUpdates.RefreshRate), tt.description) - assert.Equal(t, expectedDatabaseValues["POLL_FOR_UPDATES_TIMEOUT_MS"], strconv.Itoa(c.StoredResponses.Database.PollUpdates.Timeout), tt.description) - assert.Equal(t, expectedDatabaseValues["POLL_FOR_UPDATES_QUERY"], c.StoredResponses.Database.PollUpdates.Query, tt.description) - assert.Empty(t, c.StoredResponses.Database.FetcherQueries.AmpQueryTemplate, tt.description) - assert.Empty(t, c.StoredResponses.Database.CacheInitialization.AmpQuery, tt.description) - assert.Empty(t, c.StoredResponses.Database.PollUpdates.AmpQuery, tt.description) - } - }) - } -} - -func TestMigrateConfigDatabaseQueryParams(t *testing.T) { - - config := []byte(` - stored_requests: - postgres: - fetcher: - query: - SELECT * FROM Table1 WHERE id in (%REQUEST_ID_LIST%) - UNION ALL - SELECT * FROM Table2 WHERE id in (%IMP_ID_LIST%) - UNION ALL - SELECT * FROM Table3 WHERE id in (%ID_LIST%) - amp_query: - SELECT * FROM Table1 WHERE id in (%REQUEST_ID_LIST%) - UNION ALL - SELECT * FROM Table2 WHERE id in (%IMP_ID_LIST%) - UNION ALL - SELECT * FROM Table3 WHERE id in (%ID_LIST%) - poll_for_updates: - query: "SELECT * FROM Table1 WHERE last_updated > $1 UNION ALL SELECT * FROM Table2 WHERE last_updated > $1" - amp_query: "SELECT * FROM Table1 WHERE last_updated > $1 UNION ALL SELECT * FROM Table2 WHERE last_updated > $1" - stored_video_req: - postgres: - fetcher: - query: - SELECT * FROM Table1 WHERE id in (%REQUEST_ID_LIST%) - UNION ALL - SELECT * FROM Table2 WHERE id in (%IMP_ID_LIST%) - UNION ALL - SELECT * FROM Table3 WHERE id in (%ID_LIST%) - amp_query: - SELECT * FROM Table1 WHERE id in (%REQUEST_ID_LIST%) - UNION ALL - SELECT * FROM Table2 WHERE id in (%IMP_ID_LIST%) - UNION ALL - SELECT * FROM Table3 WHERE id in (%ID_LIST%) - poll_for_updates: - query: "SELECT * FROM Table1 WHERE last_updated > $1 UNION ALL SELECT * FROM Table2 WHERE last_updated > $1" - amp_query: "SELECT * FROM Table1 WHERE last_updated > $1 UNION ALL SELECT * FROM Table2 WHERE last_updated > $1" - stored_responses: - postgres: - fetcher: - query: - SELECT * FROM Table1 WHERE id in (%REQUEST_ID_LIST%) - UNION ALL - SELECT * FROM Table2 WHERE id in (%IMP_ID_LIST%) - UNION ALL - SELECT * FROM Table3 WHERE id in (%ID_LIST%) - amp_query: - SELECT * FROM Table1 WHERE id in (%REQUEST_ID_LIST%) - UNION ALL - SELECT * FROM Table2 WHERE id in (%IMP_ID_LIST%) - UNION ALL - SELECT * FROM Table3 WHERE id in (%ID_LIST%) - poll_for_updates: - query: "SELECT * FROM Table1 WHERE last_updated > $1 UNION ALL SELECT * FROM Table2 WHERE last_updated > $1" - amp_query: "SELECT * FROM Table1 WHERE last_updated > $1 UNION ALL SELECT * FROM Table2 WHERE last_updated > $1" - `) - - want_queries := struct { - fetcher_query string - fetcher_amp_query string - poll_for_updates_query string - poll_for_updates_amp_query string - }{ - fetcher_query: "SELECT * FROM Table1 WHERE id in ($REQUEST_ID_LIST) " + - "UNION ALL " + - "SELECT * FROM Table2 WHERE id in ($IMP_ID_LIST) " + - "UNION ALL " + - "SELECT * FROM Table3 WHERE id in ($ID_LIST)", - fetcher_amp_query: "SELECT * FROM Table1 WHERE id in ($REQUEST_ID_LIST) " + - "UNION ALL " + - "SELECT * FROM Table2 WHERE id in ($IMP_ID_LIST) " + - "UNION ALL " + - "SELECT * FROM Table3 WHERE id in ($ID_LIST)", - poll_for_updates_query: "SELECT * FROM Table1 WHERE last_updated > $LAST_UPDATED UNION ALL SELECT * FROM Table2 WHERE last_updated > $LAST_UPDATED", - poll_for_updates_amp_query: "SELECT * FROM Table1 WHERE last_updated > $LAST_UPDATED UNION ALL SELECT * FROM Table2 WHERE last_updated > $LAST_UPDATED", - } - - v := viper.New() - v.SetConfigType("yaml") - err := v.ReadConfig(bytes.NewBuffer(config)) - assert.NoError(t, err) - - migrateConfigDatabaseConnection(v) - - // stored_requests queries - assert.Equal(t, want_queries.fetcher_query, v.GetString("stored_requests.database.fetcher.query")) - assert.Equal(t, want_queries.fetcher_amp_query, v.GetString("stored_requests.database.fetcher.amp_query")) - assert.Equal(t, want_queries.poll_for_updates_query, v.GetString("stored_requests.database.poll_for_updates.query")) - assert.Equal(t, want_queries.poll_for_updates_amp_query, v.GetString("stored_requests.database.poll_for_updates.amp_query")) - - // stored_video_req queries - assert.Equal(t, want_queries.fetcher_query, v.GetString("stored_video_req.database.fetcher.query")) - assert.Equal(t, want_queries.fetcher_amp_query, v.GetString("stored_video_req.database.fetcher.amp_query")) - assert.Equal(t, want_queries.poll_for_updates_query, v.GetString("stored_video_req.database.poll_for_updates.query")) - assert.Equal(t, want_queries.poll_for_updates_amp_query, v.GetString("stored_video_req.database.poll_for_updates.amp_query")) - - // stored_responses queries - assert.Equal(t, want_queries.fetcher_query, v.GetString("stored_responses.database.fetcher.query")) - assert.Equal(t, want_queries.fetcher_amp_query, v.GetString("stored_responses.database.fetcher.amp_query")) - assert.Equal(t, want_queries.poll_for_updates_query, v.GetString("stored_responses.database.poll_for_updates.query")) - assert.Equal(t, want_queries.poll_for_updates_amp_query, v.GetString("stored_responses.database.poll_for_updates.amp_query")) -} - func TestIsConfigInfoPresent(t *testing.T) { configPrefix1Field2Only := []byte(` prefix1: From 0d488eea2c4f1f9d8835e52d597838b176a453ab Mon Sep 17 00:00:00 2001 From: Mohammad Nurul Islam Shihan <93646635+ishihanvcs@users.noreply.github.com> Date: Fri, 29 Sep 2023 12:36:59 +0600 Subject: [PATCH 146/268] ImproveDigital: updates (#3077) --- adapters/improvedigital/improvedigital.go | 98 +++++--- .../exemplary/app-multi.json | 105 +++++++++ .../improvedigitaltest/exemplary/audio.json | 169 ++++++++++++++ .../improvedigitaltest/exemplary/native.json | 12 +- .../exemplary/site-multi.json | 111 +++++++++ .../missing_and_unsupported_mtype.json | 215 ++++++++++++++++++ static/bidder-info/improvedigital.yaml | 4 +- 7 files changed, 685 insertions(+), 29 deletions(-) create mode 100644 adapters/improvedigital/improvedigitaltest/exemplary/audio.json create mode 100644 adapters/improvedigital/improvedigitaltest/supplemental/missing_and_unsupported_mtype.json diff --git a/adapters/improvedigital/improvedigital.go b/adapters/improvedigital/improvedigital.go index b934ac753a0..c26a200a486 100644 --- a/adapters/improvedigital/improvedigital.go +++ b/adapters/improvedigital/improvedigital.go @@ -3,19 +3,18 @@ package improvedigital import ( "encoding/json" "fmt" - "net/http" - "strconv" - "strings" - "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/adapters" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/openrtb_ext" + "net/http" + "regexp" + "strconv" + "strings" ) const ( - buyingTypeRTB = "rtb" isRewardedInventory = "is_rewarded_inventory" stateRewardedInventoryEnable = "1" consentProvidersSettingsInputKey = "ConsentedProvidersSettings" @@ -43,6 +42,8 @@ type ImpExtBidder struct { } } +var dealDetectionRegEx = regexp.MustCompile("(classic|deal)") + // MakeRequests makes the HTTP requests which should be made to fetch bids. func (a *ImprovedigitalAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { numRequests := len(request.Imp) @@ -119,6 +120,7 @@ func (a *ImprovedigitalAdapter) MakeBids(internalRequest *openrtb2.BidRequest, e } var bidResp openrtb2.BidResponse + var impMap = make(map[string]openrtb2.Imp) if err := json.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -134,7 +136,6 @@ func (a *ImprovedigitalAdapter) MakeBids(internalRequest *openrtb2.BidRequest, e } seatBid := bidResp.SeatBid[0] - if len(seatBid.Bid) == 0 { return nil, nil } @@ -142,10 +143,14 @@ func (a *ImprovedigitalAdapter) MakeBids(internalRequest *openrtb2.BidRequest, e bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(seatBid.Bid)) bidResponse.Currency = bidResp.Cur + for i := range internalRequest.Imp { + impMap[internalRequest.Imp[i].ID] = internalRequest.Imp[i] + } + for i := range seatBid.Bid { bid := seatBid.Bid[i] - bidType, err := getMediaTypeForImp(bid.ImpID, internalRequest.Imp) + bidType, err := getBidType(bid, impMap) if err != nil { return nil, []error{err} } @@ -158,7 +163,7 @@ func (a *ImprovedigitalAdapter) MakeBids(internalRequest *openrtb2.BidRequest, e } bidExtImprovedigital := bidExt.Improvedigital - if bidExtImprovedigital.LineItemID != 0 && bidExtImprovedigital.BuyingType != "" && bidExtImprovedigital.BuyingType != buyingTypeRTB { + if bidExtImprovedigital.LineItemID != 0 && dealDetectionRegEx.MatchString(bidExtImprovedigital.BuyingType) { bid.DealID = strconv.Itoa(bidExtImprovedigital.LineItemID) } } @@ -169,7 +174,6 @@ func (a *ImprovedigitalAdapter) MakeBids(internalRequest *openrtb2.BidRequest, e }) } return bidResponse, nil - } // Builder builds a new instance of the Improvedigital adapter for the given bidder with the given config. @@ -180,31 +184,73 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co return bidder, nil } -func getMediaTypeForImp(impID string, imps []openrtb2.Imp) (openrtb_ext.BidType, error) { - for _, imp := range imps { - if imp.ID == impID { - if imp.Banner != nil { - return openrtb_ext.BidTypeBanner, nil - } - - if imp.Video != nil { - return openrtb_ext.BidTypeVideo, nil - } +func getBidType(bid openrtb2.Bid, impMap map[string]openrtb2.Imp) (openrtb_ext.BidType, error) { + // there must be a matching imp against bid.ImpID + imp, found := impMap[bid.ImpID] + if !found { + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Failed to find impression for ID: \"%s\"", bid.ImpID), + } + } - if imp.Native != nil { - return openrtb_ext.BidTypeNative, nil + // if MType is not set in server response, try to determine it + if bid.MType == 0 { + if !isMultiFormatImp(imp) { + // Not a bid for multi format impression. So, determine MType from impression + if imp.Banner != nil { + bid.MType = openrtb2.MarkupBanner + } else if imp.Video != nil { + bid.MType = openrtb2.MarkupVideo + } else if imp.Audio != nil { + bid.MType = openrtb2.MarkupAudio + } else if imp.Native != nil { + bid.MType = openrtb2.MarkupNative + } else { // This should not happen. + // Let's handle it just in case by returning an error. + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Could not determine MType from impression with ID: \"%s\"", bid.ImpID), + } } - + } else { return "", &errortypes.BadServerResponse{ - Message: fmt.Sprintf("Unknown impression type for ID: \"%s\"", impID), + Message: fmt.Sprintf("Bid must have non-zero MType for multi format impression with ID: \"%s\"", bid.ImpID), } } } - // This shouldnt happen. Lets handle it just incase by returning an error. - return "", &errortypes.BadServerResponse{ - Message: fmt.Sprintf("Failed to find impression for ID: \"%s\"", impID), + // map MType to BidType + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupAudio: + return openrtb_ext.BidTypeAudio, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + // This shouldn't happen. Let's handle it just in case by returning an error. + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unsupported MType %d for impression with ID: \"%s\"", bid.MType, bid.ImpID), + } + } +} + +func isMultiFormatImp(imp openrtb2.Imp) bool { + formatCount := 0 + if imp.Banner != nil { + formatCount++ + } + if imp.Video != nil { + formatCount++ + } + if imp.Audio != nil { + formatCount++ + } + if imp.Native != nil { + formatCount++ } + return formatCount > 1 } // This method responsible to clone request and convert additional consent providers string to array when additional consent provider found diff --git a/adapters/improvedigital/improvedigitaltest/exemplary/app-multi.json b/adapters/improvedigital/improvedigitaltest/exemplary/app-multi.json index 6963e82f9c4..425435049db 100644 --- a/adapters/improvedigital/improvedigitaltest/exemplary/app-multi.json +++ b/adapters/improvedigital/improvedigitaltest/exemplary/app-multi.json @@ -40,6 +40,28 @@ "placementId": 13244 } } + }, + { + "id": "test-multi-format-id-with-mtype", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "placementId": 13244 + } + } } ] }, @@ -159,6 +181,71 @@ "cur": "USD" } } + }, + { + "expectedRequest": { + "uri": "http://localhost/pbs", + "body": { + "id": "test-request-id", + "app": { + "id": "appID", + "publisher": { + "id": "uniq_pub_id" + } + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36" + }, + "imp": [ + { + "id": "test-multi-format-id-with-mtype", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "placementId": 13244 + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "improvedigital", + "bid": [ + { + "id": "randomid2", + "impid": "test-multi-format-id-with-mtype", + "price": 0.5, + "adm": "some-test-ad-vast", + "crid": "1234567", + "w": 1920, + "h": 1080, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } } ], "expectedBidResponses": [ @@ -197,6 +284,24 @@ "type": "video" } ] + }, + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid2", + "impid": "test-multi-format-id-with-mtype", + "price": 0.5, + "adm": "some-test-ad-vast", + "crid": "1234567", + "w": 1920, + "h": 1080, + "mtype": 1 + }, + "type": "banner" + } + ] } ] } diff --git a/adapters/improvedigital/improvedigitaltest/exemplary/audio.json b/adapters/improvedigital/improvedigitaltest/exemplary/audio.json new file mode 100644 index 00000000000..9ddbf799517 --- /dev/null +++ b/adapters/improvedigital/improvedigitaltest/exemplary/audio.json @@ -0,0 +1,169 @@ +{ + "mockBidRequest": { + "id": "26f14780-8ef8-4f41-b70c-c4d062237df6", + "source": { + "tid": "26f14780-8ef8-4f41-b70c-c4d062237df6", + "ext": { + "schain": { + "ver": "1.0", + "complete": 1, + "nodes": [ + { "asi": "example.com", "hp": 1, "sid": "1234abc" } + ] + } + } + }, + "tmax": 1000, + "imp": [ + { + "id": "audio", + "audio": { + "mimes": ["audio/mp3"], + "protocols": [2, 5] + }, + "ext": { + "bidder": { + "placementId": 13244 + } + } + } + ], + "ext": { + "prebid": { + "targeting": { + "includewinners": true, + "includebidderkeys": false + } + } + }, + "site": { + "publisher": { "id": "pubid" }, + "page": "example.com" + }, + "device": { "w": 1581, "h": 922, "ip": "1.1.1.1" }, + "regs": { "ext": { "gdpr": 0 } }, + "user": { + "ext": { + "consent": "XYZ" + } + } + }, + "httpcalls": [ + { + "expectedRequest": { + "uri": "http://localhost/pbs", + "body": { + "id": "26f14780-8ef8-4f41-b70c-c4d062237df6", + "imp": [ + { + "id": "audio", + "audio": { + "mimes": ["audio/mp3"], + "protocols": [2, 5] + }, + "ext": { + "bidder": { + "placementId": 13244 + } + } + } + ], + "site": { + "page": "example.com", + "publisher": { "id": "pubid" } + }, + "device": { + "ip": "1.1.1.1", + "h": 922, + "w": 1581 + }, + "user": { + "ext": { + "consent": "XYZ" + } + }, + "tmax": 1000, + "source": { + "tid": "26f14780-8ef8-4f41-b70c-c4d062237df6", + "ext": { + "schain": { + "ver": "1.0", + "complete": 1, + "nodes": [ + { + "asi": "example.com", + "hp": 1, + "sid": "1234abc" + } + ] + } + } + }, + "regs": { "ext": { "gdpr": 0 } }, + "ext": { + "prebid": { + "targeting": { + "includewinners": true, + "includebidderkeys": false + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "26f14780-8ef8-4f41-b70c-c4d062237df6", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "ext": { + "improvedigital": { + "brand_name": "AdvertiserABC", + "bidder_id": 301 + } + }, + "crid": "14065", + "id": "d4f04449-ba04-4d7c-bb34-dc0fc5240f59", + "price": 0.01, + "adm": "some-test-ad-vast", + "adomain": ["example.com"], + "impid": "audio", + "cid": "25076" + } + ], + "seat": "improvedigital" + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "d4f04449-ba04-4d7c-bb34-dc0fc5240f59", + "impid": "audio", + "price": 0.01, + "adm": "some-test-ad-vast", + "adomain": ["example.com"], + "cid": "25076", + "crid": "14065", + "ext": { + "improvedigital": { + "brand_name": "AdvertiserABC", + "bidder_id": 301 + } + } + }, + "type": "audio" + } + ] + } + ] +} diff --git a/adapters/improvedigital/improvedigitaltest/exemplary/native.json b/adapters/improvedigital/improvedigitaltest/exemplary/native.json index 3309b35a753..3865d40383b 100644 --- a/adapters/improvedigital/improvedigitaltest/exemplary/native.json +++ b/adapters/improvedigital/improvedigitaltest/exemplary/native.json @@ -17,7 +17,11 @@ "imp": [ { "id": "native", - "ext": { "improvedigital": { "placementId": 1234 } }, + "ext": { + "bidder": { + "placementId": 1234 + } + }, "native": { "request": "{\"context\":1,\"plcmttype\":1,\"eventtrackers\":[{\"event\":1,\"methods\":[1]}],\"assets\":[{\"required\":1,\"title\":{\"len\":80}},{\"required\":1,\"data\":{\"type\":2}},{\"required\":0,\"data\":{\"type\":12}},{\"required\":0,\"img\":{\"type\":3,\"wmin\":300,\"hmin\":225,\"ext\":{\"aspectratios\":[\"4:3\"]}}},{\"required\":0,\"img\":{\"type\":1,\"w\":128,\"h\":128}},{\"required\":0,\"data\":{\"type\":3}},{\"required\":0,\"data\":{\"type\":6}}]}", "ver": "1.2" @@ -57,7 +61,11 @@ "request": "{\"context\":1,\"plcmttype\":1,\"eventtrackers\":[{\"event\":1,\"methods\":[1]}],\"assets\":[{\"required\":1,\"title\":{\"len\":80}},{\"required\":1,\"data\":{\"type\":2}},{\"required\":0,\"data\":{\"type\":12}},{\"required\":0,\"img\":{\"type\":3,\"wmin\":300,\"hmin\":225,\"ext\":{\"aspectratios\":[\"4:3\"]}}},{\"required\":0,\"img\":{\"type\":1,\"w\":128,\"h\":128}},{\"required\":0,\"data\":{\"type\":3}},{\"required\":0,\"data\":{\"type\":6}}]}", "ver": "1.2" }, - "ext": { "improvedigital": { "placementId": 1234 } } + "ext": { + "bidder": { + "placementId": 1234 + } + } } ], "site": { diff --git a/adapters/improvedigital/improvedigitaltest/exemplary/site-multi.json b/adapters/improvedigital/improvedigitaltest/exemplary/site-multi.json index 0945b4c0f69..d7131a54577 100644 --- a/adapters/improvedigital/improvedigitaltest/exemplary/site-multi.json +++ b/adapters/improvedigital/improvedigitaltest/exemplary/site-multi.json @@ -42,6 +42,28 @@ "placementId": 13244 } } + }, + { + "id": "test-multi-format-id-with-mtype", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "placementId": 13245 + } + } } ] }, @@ -166,6 +188,75 @@ "cur": "USD" } } + }, + { + "expectedRequest": { + "uri": "http://localhost/pbs", + "body": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url", + "domain": "good.site", + "publisher": { + "id": "uniq_pub_id" + }, + "keywords": "omgword", + "ext": { + "amp": 0 + } + }, + "imp": [ + { + "id": "test-multi-format-id-with-mtype", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "placementId": 13245 + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "improvedigital", + "bid": [ + { + "id": "randomid1", + "impid": "test-multi-format-id-with-mtype", + "price": 0.5, + "adid": "12345678", + "adm": "some-test-ad-html", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } } ], @@ -205,6 +296,26 @@ "type": "video" } ] + }, + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid1", + "impid": "test-multi-format-id-with-mtype", + "price": 0.5, + "adm": "some-test-ad-html", + "adid": "12345678", + "cid": "987", + "crid": "12345678", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] } ] } diff --git a/adapters/improvedigital/improvedigitaltest/supplemental/missing_and_unsupported_mtype.json b/adapters/improvedigital/improvedigitaltest/supplemental/missing_and_unsupported_mtype.json new file mode 100644 index 00000000000..ad82321a401 --- /dev/null +++ b/adapters/improvedigital/improvedigitaltest/supplemental/missing_and_unsupported_mtype.json @@ -0,0 +1,215 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": 13245 + } + } + }, + { + "id": "test-multi-format-id-without-mtype", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "placementId": 13244 + } + } + }, + { + "id": "test-unsupported-format-id-without-mtype", + "ext": { + "bidder": { + "placementId": 13244 + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/pbs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": 13245 + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "seat": "improvedigital", + "bid": [{ + "id": "randomid", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 5 + }] + }], + "cur": "USD" + } + } + }, + { + "expectedRequest": { + "uri": "http://localhost/pbs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-multi-format-id-without-mtype", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "placementId": 13244 + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "improvedigital", + "bid": [ + { + "id": "randomid2", + "impid": "test-multi-format-id-without-mtype", + "price": 0.5, + "adm": "some-test-ad-vast", + "crid": "1234567", + "w": 1920, + "h": 1080 + } + ] + } + ], + "cur": "USD" + } + } + }, + { + "expectedRequest": { + "uri": "http://localhost/pbs", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-unsupported-format-id-without-mtype", + "ext": { + "bidder": { + "placementId": 13244 + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "improvedigital", + "bid": [ + { + "id": "randomid3", + "impid": "test-unsupported-format-id-without-mtype", + "price": 0.5, + "adm": "some-test-ad-vast", + "crid": "1234567", + "w": 1920, + "h": 1080 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + + "expectedMakeBidsErrors": [ + { + "value": "Unsupported MType 5 for impression with ID: \"test-imp-id\"", + "comparison": "literal" + }, + { + "value": "Bid must have non-zero MType for multi format impression with ID: \"test-multi-format-id-without-mtype\"", + "comparison": "literal" + }, + { + "value": "Could not determine MType from impression with ID: \"test-unsupported-format-id-without-mtype\"", + "comparison": "literal" + } + ] +} diff --git a/static/bidder-info/improvedigital.yaml b/static/bidder-info/improvedigital.yaml index d14356cde0e..4cd30d7c6b2 100644 --- a/static/bidder-info/improvedigital.yaml +++ b/static/bidder-info/improvedigital.yaml @@ -7,14 +7,16 @@ capabilities: mediaTypes: - banner - video + - audio - native site: mediaTypes: - banner - video + - audio - native userSync: redirect: - url: "https://ad.360yield.com/server_match?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}" + url: "https://ad.360yield.com/server_match?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&r={{.RedirectURL}}" userMacro: "{PUB_USER_ID}" endpointCompression: "GZIP" \ No newline at end of file From 6a361780558326ab962383aa954a0f684261d689 Mon Sep 17 00:00:00 2001 From: Arne Schulz Date: Fri, 29 Sep 2023 10:09:43 +0200 Subject: [PATCH 147/268] [ORBIDDER] add user sync redirect url (#3118) --- static/bidder-info/orbidder.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/static/bidder-info/orbidder.yaml b/static/bidder-info/orbidder.yaml index 705d35a5a20..74348c75d7f 100644 --- a/static/bidder-info/orbidder.yaml +++ b/static/bidder-info/orbidder.yaml @@ -10,3 +10,7 @@ capabilities: mediaTypes: - banner - native +userSync: + redirect: + url: "https://orbidder.otto.de/pbs-usersync?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&redirect={{.RedirectURL}}" + userMacro: "[ODN_ID]" \ No newline at end of file From 4ad946bb56e59b71dc01c7caf3954f1bd4d6f0e7 Mon Sep 17 00:00:00 2001 From: Mikael Lundin Date: Fri, 29 Sep 2023 10:14:35 +0200 Subject: [PATCH 148/268] Adnuntius: Add Price Type (#3084) --- adapters/adnuntius/adnuntius.go | 46 ++++++-- .../supplemental/check-gross-bids.json | 103 ++++++++++++++++++ .../supplemental/check-net-bids.json | 103 ++++++++++++++++++ .../supplemental/check-price-type-error.json | 38 +++++++ openrtb_ext/imp_adnuntius.go | 1 + static/bidder-params/adnuntius.json | 8 ++ 6 files changed, 292 insertions(+), 7 deletions(-) create mode 100644 adapters/adnuntius/adnuntiustest/supplemental/check-gross-bids.json create mode 100644 adapters/adnuntius/adnuntiustest/supplemental/check-net-bids.json create mode 100644 adapters/adnuntius/adnuntiustest/supplemental/check-price-type-error.json diff --git a/adapters/adnuntius/adnuntius.go b/adapters/adnuntius/adnuntius.go index 3f91d7403f0..fd667ddc506 100644 --- a/adapters/adnuntius/adnuntius.go +++ b/adapters/adnuntius/adnuntius.go @@ -39,6 +39,12 @@ type Ad struct { Amount float64 Currency string } + NetBid struct { + Amount float64 + } + GrossBid struct { + Amount float64 + } DealID string `json:"dealId,omitempty"` AdId string CreativeWidth string @@ -194,6 +200,7 @@ func (a *adapter) generateRequests(ortbRequest openrtb2.BidRequest) ([]*adapters Message: fmt.Sprintf("ignoring imp id=%s, Adnuntius supports only Banner", imp.ID), }} } + var bidderExt adapters.ExtImpBidder if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, []error{&errortypes.BadInput{ @@ -204,7 +211,7 @@ func (a *adapter) generateRequests(ortbRequest openrtb2.BidRequest) ([]*adapters var adnuntiusExt openrtb_ext.ImpExtAdnunitus if err := json.Unmarshal(bidderExt.Bidder, &adnuntiusExt); err != nil { return nil, []error{&errortypes.BadInput{ - Message: fmt.Sprintf("Error unmarshalling ExtImpBmtm: %s", err.Error()), + Message: fmt.Sprintf("Error unmarshalling ExtImpValues: %s", err.Error()), }} } @@ -328,7 +335,7 @@ func getGDPR(request *openrtb2.BidRequest) (string, string, error) { return gdpr, consent, nil } -func generateAdResponse(ad Ad, impId string, html string, request *openrtb2.BidRequest) (*openrtb2.Bid, []error) { +func generateAdResponse(ad Ad, imp openrtb2.Imp, html string, request *openrtb2.BidRequest) (*openrtb2.Bid, []error) { creativeWidth, widthErr := strconv.ParseInt(ad.CreativeWidth, 10, 64) if widthErr != nil { @@ -344,6 +351,31 @@ func generateAdResponse(ad Ad, impId string, html string, request *openrtb2.BidR }} } + price := ad.Bid.Amount + + var bidderExt adapters.ExtImpBidder + if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Error unmarshalling ExtImpBidder: %s", err.Error()), + }} + } + + var adnuntiusExt openrtb_ext.ImpExtAdnunitus + if err := json.Unmarshal(bidderExt.Bidder, &adnuntiusExt); err != nil { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Error unmarshalling ExtImpValues: %s", err.Error()), + }} + } + + if adnuntiusExt.BidType != "" { + if strings.EqualFold(string(adnuntiusExt.BidType), "net") { + price = ad.NetBid.Amount + } + if strings.EqualFold(string(adnuntiusExt.BidType), "gross") { + price = ad.GrossBid.Amount + } + } + adDomain := []string{} for _, url := range ad.DestinationUrls { domainArray := strings.Split(url, "/") @@ -353,14 +385,14 @@ func generateAdResponse(ad Ad, impId string, html string, request *openrtb2.BidR bid := openrtb2.Bid{ ID: ad.AdId, - ImpID: impId, + ImpID: imp.ID, W: creativeWidth, H: creativeHeight, AdID: ad.AdId, DealID: ad.DealID, CID: ad.LineItemId, CrID: ad.CreativeId, - Price: ad.Bid.Amount * 1000, + Price: price * 1000, AdM: html, ADomain: adDomain, } @@ -377,7 +409,7 @@ func generateBidResponse(adnResponse *AdnResponse, request *openrtb2.BidRequest) adunitMap[adnRespAdunit.TargetId] = adnRespAdunit } - for i, imp := range request.Imp { + for _, imp := range request.Imp { auId, _, _, err := jsonparser.Get(imp.Ext, "bidder", "auId") if err != nil { @@ -394,7 +426,7 @@ func generateBidResponse(adnResponse *AdnResponse, request *openrtb2.BidRequest) ad := adunit.Ads[0] currency = ad.Bid.Currency - adBid, err := generateAdResponse(ad, request.Imp[i].ID, adunit.Html, request) + adBid, err := generateAdResponse(ad, imp, adunit.Html, request) if err != nil { return nil, []error{&errortypes.BadInput{ Message: fmt.Sprintf("Error at ad generation"), @@ -407,7 +439,7 @@ func generateBidResponse(adnResponse *AdnResponse, request *openrtb2.BidRequest) }) for _, deal := range adunit.Deals { - dealBid, err := generateAdResponse(deal, request.Imp[i].ID, deal.Html, request) + dealBid, err := generateAdResponse(deal, imp, deal.Html, request) if err != nil { return nil, []error{&errortypes.BadInput{ Message: fmt.Sprintf("Error at ad generation"), diff --git a/adapters/adnuntius/adnuntiustest/supplemental/check-gross-bids.json b/adapters/adnuntius/adnuntiustest/supplemental/check-gross-bids.json new file mode 100644 index 00000000000..d6301fe71cf --- /dev/null +++ b/adapters/adnuntius/adnuntiustest/supplemental/check-gross-bids.json @@ -0,0 +1,103 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "id": "1kjh3429kjh295jkl" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "auId": "123", + "bidType": "gross" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://whatever.url?format=json&tzo=0", + "body": { + "adUnits": [ + { + "auId": "123", + "targetId": "123-test-imp-id", + "dimensions": [[300,250],[300,600]] + } + ], + "metaData": { + "usi": "1kjh3429kjh295jkl" + }, + "context": "unknown" + } + }, + "mockResponse": { + "status": 200, + "body": { + "adUnits": [ + { + "auId": "0000000000000123", + "targetId": "123-test-imp-id", + "html": "", + "responseId": "adn-rsp-900646517", + "ads": [ + { + "destinationUrls": { + "url": "http://www.google.com" + }, + "bid": { "amount": 20.0, "currency": "NOK" }, + "grossBid": {"amount": 0.1, "currency": "NOK"}, + "netBid": {"amount": 0.075, "currency": "NOK"}, + "adId": "adn-id-1559784094", + "creativeWidth": "980", + "creativeHeight": "240", + "creativeId": "jn9hpzvlsf8cpdmm", + "lineItemId": "q7y9qm5b0xt9htrv" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "adn-id-1559784094", + "impid": "test-imp-id", + "price": 100, + "adm": "", + "adid": "adn-id-1559784094", + "adomain": [ + "google.com" + ], + "cid": "q7y9qm5b0xt9htrv", + "crid": "jn9hpzvlsf8cpdmm", + "w": 980, + "h": 240 + }, + "type": "banner" + } + ], + "currency": "NOK" + } + ] +} diff --git a/adapters/adnuntius/adnuntiustest/supplemental/check-net-bids.json b/adapters/adnuntius/adnuntiustest/supplemental/check-net-bids.json new file mode 100644 index 00000000000..ebb25b2b7ad --- /dev/null +++ b/adapters/adnuntius/adnuntiustest/supplemental/check-net-bids.json @@ -0,0 +1,103 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "id": "1kjh3429kjh295jkl" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "auId": "123", + "bidType": "net" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://whatever.url?format=json&tzo=0", + "body": { + "adUnits": [ + { + "auId": "123", + "targetId": "123-test-imp-id", + "dimensions": [[300,250],[300,600]] + } + ], + "metaData": { + "usi": "1kjh3429kjh295jkl" + }, + "context": "unknown" + } + }, + "mockResponse": { + "status": 200, + "body": { + "adUnits": [ + { + "auId": "0000000000000123", + "targetId": "123-test-imp-id", + "html": "", + "responseId": "adn-rsp-900646517", + "ads": [ + { + "destinationUrls": { + "url": "http://www.google.com" + }, + "bid": { "amount": 20.0, "currency": "NOK" }, + "grossBid": {"amount": 0.1, "currency": "NOK"}, + "netBid": {"amount": 0.075, "currency": "NOK"}, + "adId": "adn-id-1559784094", + "creativeWidth": "980", + "creativeHeight": "240", + "creativeId": "jn9hpzvlsf8cpdmm", + "lineItemId": "q7y9qm5b0xt9htrv" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "adn-id-1559784094", + "impid": "test-imp-id", + "price": 75, + "adm": "", + "adid": "adn-id-1559784094", + "adomain": [ + "google.com" + ], + "cid": "q7y9qm5b0xt9htrv", + "crid": "jn9hpzvlsf8cpdmm", + "w": 980, + "h": 240 + }, + "type": "banner" + } + ], + "currency": "NOK" + } + ] +} diff --git a/adapters/adnuntius/adnuntiustest/supplemental/check-price-type-error.json b/adapters/adnuntius/adnuntiustest/supplemental/check-price-type-error.json new file mode 100644 index 00000000000..89016087a43 --- /dev/null +++ b/adapters/adnuntius/adnuntiustest/supplemental/check-price-type-error.json @@ -0,0 +1,38 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "id": "1kjh3429kjh295jkl" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "auId": "123", + "bidType": 123 + } + } + } + ] + }, + "httpCalls": [], + "expectedMakeRequestsErrors": [ + { + "value": "Error unmarshalling ExtImpValues: json: cannot unmarshal number into Go struct field ImpExtAdnunitus.bidType of type string", + "comparison": "literal" + } + ] +} diff --git a/openrtb_ext/imp_adnuntius.go b/openrtb_ext/imp_adnuntius.go index 86023c48231..49833e90f1d 100644 --- a/openrtb_ext/imp_adnuntius.go +++ b/openrtb_ext/imp_adnuntius.go @@ -5,4 +5,5 @@ type ImpExtAdnunitus struct { Network string `json:"network"` NoCookies bool `json:"noCookies"` MaxDeals int `json:"maxDeals"` + BidType string `json:"bidType,omitempty"` } diff --git a/static/bidder-params/adnuntius.json b/static/bidder-params/adnuntius.json index ff975501edb..f7ab32d2f48 100644 --- a/static/bidder-params/adnuntius.json +++ b/static/bidder-params/adnuntius.json @@ -9,6 +9,10 @@ "type": "string", "description": "Placement ID" }, + "maxDeals": { + "type": "integer", + "description": "Specify how many deals that you want to return from the auction." + }, "network": { "type": "string", "description": "Network if required" @@ -16,6 +20,10 @@ "noCookies": { "type": "boolean", "description": "Disable cookies being set by the ad server." + }, + "bidType": { + "type": "string", + "description": "Allows you to specify Net or Gross bids." } }, From 9e14c0905241bff942d566321a251b1986a74ea6 Mon Sep 17 00:00:00 2001 From: SerhiiNahornyi Date: Fri, 29 Sep 2023 11:32:12 +0300 Subject: [PATCH 149/268] Rubicon: Remove eids logic (#3111) --- adapters/rubicon/rubicon.go | 82 +--- adapters/rubicon/rubicon_test.go | 91 ----- ...-special-uid-with-other-stype-present.json | 372 ----------------- ...-special-uid-with-ppuid-stype-present.json | 372 ----------------- .../exemplary/user-buyeruid-present.json | 373 ------------------ 5 files changed, 4 insertions(+), 1286 deletions(-) delete mode 100644 adapters/rubicon/rubicontest/exemplary/user-buyeruid-not-present-but-special-uid-with-other-stype-present.json delete mode 100644 adapters/rubicon/rubicontest/exemplary/user-buyeruid-not-present-but-special-uid-with-ppuid-stype-present.json delete mode 100644 adapters/rubicon/rubicontest/exemplary/user-buyeruid-present.json diff --git a/adapters/rubicon/rubicon.go b/adapters/rubicon/rubicon.go index a7ab9ad8f59..635f6e14b42 100644 --- a/adapters/rubicon/rubicon.go +++ b/adapters/rubicon/rubicon.go @@ -98,11 +98,10 @@ type rubiconDataExt struct { } type rubiconUserExt struct { - Eids []openrtb2.EID `json:"eids,omitempty"` - RP rubiconUserExtRP `json:"rp"` - LiverampIdl string `json:"liveramp_idl,omitempty"` - Data json.RawMessage `json:"data,omitempty"` - Consent string `json:"consent,omitempty"` + Eids []openrtb2.EID `json:"eids,omitempty"` + RP rubiconUserExtRP `json:"rp"` + Data json.RawMessage `json:"data,omitempty"` + Consent string `json:"consent,omitempty"` } type rubiconSiteExtRP struct { @@ -340,19 +339,6 @@ func (a *RubiconAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ada if userBuyerUID == "" { userBuyerUID = extractUserBuyerUID(userExtRP.Eids) } - - mappedRubiconUidsParam, errors := getSegments(userExtRP.Eids) - if len(errors) > 0 { - errs = append(errs, errors...) - continue - } - - if err := updateUserExtWithSegments(&userExtRP, mappedRubiconUidsParam); err != nil { - errs = append(errs, err) - continue - } - - userExtRP.LiverampIdl = mappedRubiconUidsParam.liverampIdl } if userCopy.Consent != "" { @@ -941,66 +927,6 @@ func extractUserBuyerUID(eids []openrtb2.EID) string { return "" } -func getSegments(eids []openrtb2.EID) (mappedRubiconUidsParam, []error) { - rubiconUidsParam := mappedRubiconUidsParam{ - segments: make([]string, 0), - } - errs := make([]error, 0) - - for _, eid := range eids { - switch eid.Source { - case "liveintent.com": - uids := eid.UIDs - if len(uids) > 0 { - if eid.Ext != nil { - var eidExt rubiconUserExtEidExt - if err := json.Unmarshal(eid.Ext, &eidExt); err != nil { - errs = append(errs, &errortypes.BadInput{ - Message: err.Error(), - }) - continue - } - rubiconUidsParam.segments = eidExt.Segments - } - } - case "liveramp.com": - uids := eid.UIDs - if len(uids) > 0 { - uidId := uids[0].ID - if uidId != "" && rubiconUidsParam.liverampIdl == "" { - rubiconUidsParam.liverampIdl = uidId - } - } - } - } - - return rubiconUidsParam, errs -} - -func updateUserExtWithSegments(userExtRP *rubiconUserExt, rubiconUidsParam mappedRubiconUidsParam) error { - if len(rubiconUidsParam.segments) > 0 { - - if rubiconUidsParam.segments != nil { - userExtRPTarget := make(map[string]interface{}) - - if userExtRP.RP.Target != nil { - if err := json.Unmarshal(userExtRP.RP.Target, &userExtRPTarget); err != nil { - return &errortypes.BadInput{Message: err.Error()} - } - } - - userExtRPTarget["LIseg"] = rubiconUidsParam.segments - - if target, err := json.Marshal(&userExtRPTarget); err != nil { - return &errortypes.BadInput{Message: err.Error()} - } else { - userExtRP.RP.Target = target - } - } - } - return nil -} - func isVideo(imp openrtb2.Imp) bool { video := imp.Video if video != nil { diff --git a/adapters/rubicon/rubicon_test.go b/adapters/rubicon/rubicon_test.go index 6347415547b..893cceb8cf7 100644 --- a/adapters/rubicon/rubicon_test.go +++ b/adapters/rubicon/rubicon_test.go @@ -644,97 +644,6 @@ func TestOpenRTBRequestWithBadvOverflowed(t *testing.T) { assert.Equal(t, badvOverflowed[:50], badvRequest, "Unexpected dfp_ad_unit_code: %s") } -func TestOpenRTBRequestWithSpecificExtUserEids(t *testing.T) { - bidder := new(RubiconAdapter) - - request := &openrtb2.BidRequest{ - ID: "test-request-id", - Imp: []openrtb2.Imp{{ - ID: "test-imp-id", - Banner: &openrtb2.Banner{ - Format: []openrtb2.Format{ - {W: 300, H: 250}, - }, - }, - Ext: json.RawMessage(`{"bidder": { - "zoneId": 8394, - "siteId": 283282, - "accountId": 7891 - }}`), - }}, - App: &openrtb2.App{ - ID: "com.test", - Name: "testApp", - }, - User: &openrtb2.User{ - Ext: json.RawMessage(`{"eids": [ - { - "source": "pubcid", - "uids": [{ - "id": "2402fc76-7b39-4f0e-bfc2-060ef7693648" - }] - }, - { - "source": "adserver.org", - "uids": [{ - "id": "3d50a262-bd8e-4be3-90b8-246291523907", - "ext": { - "rtiPartner": "TDID" - } - }] - }, - { - "source": "liveintent.com", - "uids": [{ - "id": "T7JiRRvsRAmh88" - }], - "ext": { - "segments": ["999","888"] - } - }, - { - "source": "liveramp.com", - "uids": [{ - "id": "LIVERAMPID" - }], - "ext": { - "segments": ["111","222"] - } - } - ]}`), - }, - } - - reqs, _ := bidder.MakeRequests(request, &adapters.ExtraRequestInfo{}) - - rubiconReq := &openrtb2.BidRequest{} - if err := json.Unmarshal(reqs[0].Body, rubiconReq); err != nil { - t.Fatalf("Unexpected error while decoding request: %s", err) - } - - assert.NotNil(t, rubiconReq.User.Ext, "User.Ext object should not be nil.") - - var userExt rubiconUserExt - if err := json.Unmarshal(rubiconReq.User.Ext, &userExt); err != nil { - t.Fatal("Error unmarshalling request.user.ext object.") - } - - assert.NotNil(t, userExt.Eids) - assert.Equal(t, 4, len(userExt.Eids), "Eids values are not as expected!") - - // liveramp.com - assert.Equal(t, "LIVERAMPID", userExt.LiverampIdl, "Liveramp_idl value is not as expected!") - - userExtRPTarget := make(map[string]interface{}) - if err := json.Unmarshal(userExt.RP.Target, &userExtRPTarget); err != nil { - t.Fatal("Error unmarshalling request.user.ext.rp.target object.") - } - - assert.Contains(t, userExtRPTarget, "LIseg", "request.user.ext.rp.target value is not as expected!") - assert.Contains(t, userExtRPTarget["LIseg"], "888", "No segment with 888 as expected!") - assert.Contains(t, userExtRPTarget["LIseg"], "999", "No segment with 999 as expected!") -} - func TestOpenRTBRequestWithVideoImpEvenIfImpHasBannerButAllRequiredVideoFields(t *testing.T) { bidder := new(RubiconAdapter) diff --git a/adapters/rubicon/rubicontest/exemplary/user-buyeruid-not-present-but-special-uid-with-other-stype-present.json b/adapters/rubicon/rubicontest/exemplary/user-buyeruid-not-present-but-special-uid-with-other-stype-present.json deleted file mode 100644 index dea75ac513e..00000000000 --- a/adapters/rubicon/rubicontest/exemplary/user-buyeruid-not-present-but-special-uid-with-other-stype-present.json +++ /dev/null @@ -1,372 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "device": { - "ip": "123.123.123.123", - "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" - }, - "site": { - "page": "somePage", - "ref": "someRef", - "search": "someSearch" - }, - "user": { - "yob": 2000, - "geo": { - "country": "USA", - "lat": 47.627500, - "lon": -122.346200 - }, - "gender": "f", - "data": [ - { - "ext": { - "segtax": 4 - }, - "segment": [ - { - "id": "idToCopy" - } - ] - }, - { - "ext": { - "segtax": "someValue" - }, - "segment": [ - { - "id": "shouldNotBeCopied" - } - ] - }, - { - "ext": { - "segtax": "4" - }, - "segment": [ - { - "id": "shouldNotBeCopied2" - } - ] - }, - { - "ext": { - "segtax": 4 - }, - "segment": [ - { - "id": "idToCopy2" - } - ] - }, - { - "ext": { - "segtax": [ - 4 - ] - }, - "segment": [ - { - "id": "shouldNotBeCopied3" - } - ] - } - ], - "keywords": "someKeywords", - "ext": { - "rp": { - "target": { - "someKey": "someValue" - } - }, - "data": { - "dataKey1": "dataValue1", - "dataKey2": [ - "dataValue2", - "dataValue3" - ], - "dataKey3": true - }, - "eids": [ - { - "source": "rubiconproject.com", - "uids": [ - { - "id": "uidId", - "ext": { - "stype": "other" - } - } - ] - } - ] - } - }, - "imp": [ - { - "id": "test-imp-id", - "instl": 1, - "video": { - "placement": 3, - "mimes": [ - "video/mp4" - ], - "protocols": [ - 2, - 5 - ], - "w": 1024, - "h": 576 - }, - "ext": { - "data": { - "adserver": { - "name": "gam", - "adslot": "someAdSlot" - }, - "dataAttr1": "dataVal1", - "dataAttr2": "dataVal2" - }, - "bidder": { - "video": { - }, - "accountId": 1001, - "siteId": 113932, - "zoneId": 535510 - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "uri?tk_xint=pbs-test-tracker", - "body": { - "id": "test-request-id", - "device": { - "ext": { - "rp": { - "pixelratio": 0 - } - }, - "ip": "123.123.123.123", - "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" - }, - "site": { - "page": "somePage", - "ref": "someRef", - "search": "someSearch", - "ext": { - "rp": { - "site_id": 113932 - } - }, - "publisher": { - "ext": { - "rp": { - "account_id": 1001 - } - } - } - }, - "user": { - "buyeruid": "uidId", - "data": [ - { - "ext": { - "segtax": 4 - }, - "segment": [ - { - "id": "idToCopy" - } - ] - }, - { - "ext": { - "segtax": "someValue" - }, - "segment": [ - { - "id": "shouldNotBeCopied" - } - ] - }, - { - "ext": { - "segtax": "4" - }, - "segment": [ - { - "id": "shouldNotBeCopied2" - } - ] - }, - { - "ext": { - "segtax": 4 - }, - "segment": [ - { - "id": "idToCopy2" - } - ] - }, - { - "ext": { - "segtax": [ - 4 - ] - }, - "segment": [ - { - "id": "shouldNotBeCopied3" - } - ] - } - ], - "ext": { - "rp": { - "target": { - "someKey": "someValue", - "dataKey1": [ - "dataValue1" - ], - "dataKey2": [ - "dataValue2", - "dataValue3" - ], - "dataKey3": [ - "true" - ], - "iab": [ - "idToCopy", - "idToCopy2" - ] - } - }, - "eids": [ - { - "source": "rubiconproject.com", - "uids": [ - { - "id": "uidId", - "ext": { - "stype": "other" - } - } - ] - } - ] - }, - "keywords": "someKeywords" - }, - "imp": [ - { - "id": "test-imp-id", - "instl": 1, - "secure": 1, - "video": { - "placement": 3, - "ext": { - "rp": { - "size_id": 203 - } - }, - "mimes": [ - "video/mp4" - ], - "protocols": [ - 2, - 5 - ], - "w": 1024, - "h": 576 - }, - "ext": { - "rp": { - "target": { - "dataAttr1": [ - "dataVal1" - ], - "dataAttr2": [ - "dataVal2" - ], - "page": [ - "somePage" - ], - "ref": [ - "someRef" - ], - "search": [ - "someSearch" - ], - "dfp_ad_unit_code": "someAdSlot" - }, - "track": { - "mint": "", - "mint_version": "" - }, - "zone_id": 535510 - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "bid": [ - { - "id": "test_bid_id", - "impid": "test-imp-id", - "price": 0.27543, - "adm": "some-test-ad", - "cid": "test_cid", - "crid": "test_crid", - "dealid": "test_dealid", - "ext": { - "prebid": { - "type": "video" - } - } - } - ], - "seat": "adman" - } - ], - "cur": "USD" - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "test_bid_id", - "impid": "test-imp-id", - "price": 0.27543, - "adm": "some-test-ad", - "cid": "test_cid", - "crid": "test_crid", - "dealid": "test_dealid", - "ext": { - "prebid": { - "type": "video" - } - } - }, - "type": "video" - } - ] - } - ] -} diff --git a/adapters/rubicon/rubicontest/exemplary/user-buyeruid-not-present-but-special-uid-with-ppuid-stype-present.json b/adapters/rubicon/rubicontest/exemplary/user-buyeruid-not-present-but-special-uid-with-ppuid-stype-present.json deleted file mode 100644 index c2b129ebdba..00000000000 --- a/adapters/rubicon/rubicontest/exemplary/user-buyeruid-not-present-but-special-uid-with-ppuid-stype-present.json +++ /dev/null @@ -1,372 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "device": { - "ip": "123.123.123.123", - "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" - }, - "site": { - "page": "somePage", - "ref": "someRef", - "search": "someSearch" - }, - "user": { - "yob": 2000, - "geo": { - "country": "USA", - "lat": 47.627500, - "lon": -122.346200 - }, - "gender": "f", - "data": [ - { - "ext": { - "segtax": 4 - }, - "segment": [ - { - "id": "idToCopy" - } - ] - }, - { - "ext": { - "segtax": "someValue" - }, - "segment": [ - { - "id": "shouldNotBeCopied" - } - ] - }, - { - "ext": { - "segtax": "4" - }, - "segment": [ - { - "id": "shouldNotBeCopied2" - } - ] - }, - { - "ext": { - "segtax": 4 - }, - "segment": [ - { - "id": "idToCopy2" - } - ] - }, - { - "ext": { - "segtax": [ - 4 - ] - }, - "segment": [ - { - "id": "shouldNotBeCopied3" - } - ] - } - ], - "keywords": "someKeywords", - "ext": { - "rp": { - "target": { - "someKey": "someValue" - } - }, - "data": { - "dataKey1": "dataValue1", - "dataKey2": [ - "dataValue2", - "dataValue3" - ], - "dataKey3": true - }, - "eids": [ - { - "source": "rubiconproject.com", - "uids": [ - { - "id": "uidId", - "ext": { - "stype": "ppuid" - } - } - ] - } - ] - } - }, - "imp": [ - { - "id": "test-imp-id", - "instl": 1, - "video": { - "placement": 3, - "mimes": [ - "video/mp4" - ], - "protocols": [ - 2, - 5 - ], - "w": 1024, - "h": 576 - }, - "ext": { - "data": { - "adserver": { - "name": "gam", - "adslot": "someAdSlot" - }, - "dataAttr1": "dataVal1", - "dataAttr2": "dataVal2" - }, - "bidder": { - "video": { - }, - "accountId": 1001, - "siteId": 113932, - "zoneId": 535510 - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "uri?tk_xint=pbs-test-tracker", - "body": { - "id": "test-request-id", - "device": { - "ext": { - "rp": { - "pixelratio": 0 - } - }, - "ip": "123.123.123.123", - "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" - }, - "site": { - "page": "somePage", - "ref": "someRef", - "search": "someSearch", - "ext": { - "rp": { - "site_id": 113932 - } - }, - "publisher": { - "ext": { - "rp": { - "account_id": 1001 - } - } - } - }, - "user": { - "buyeruid": "uidId", - "data": [ - { - "ext": { - "segtax": 4 - }, - "segment": [ - { - "id": "idToCopy" - } - ] - }, - { - "ext": { - "segtax": "someValue" - }, - "segment": [ - { - "id": "shouldNotBeCopied" - } - ] - }, - { - "ext": { - "segtax": "4" - }, - "segment": [ - { - "id": "shouldNotBeCopied2" - } - ] - }, - { - "ext": { - "segtax": 4 - }, - "segment": [ - { - "id": "idToCopy2" - } - ] - }, - { - "ext": { - "segtax": [ - 4 - ] - }, - "segment": [ - { - "id": "shouldNotBeCopied3" - } - ] - } - ], - "ext": { - "rp": { - "target": { - "someKey": "someValue", - "dataKey1": [ - "dataValue1" - ], - "dataKey2": [ - "dataValue2", - "dataValue3" - ], - "dataKey3": [ - "true" - ], - "iab": [ - "idToCopy", - "idToCopy2" - ] - } - }, - "eids": [ - { - "source": "rubiconproject.com", - "uids": [ - { - "id": "uidId", - "ext": { - "stype": "ppuid" - } - } - ] - } - ] - }, - "keywords": "someKeywords" - }, - "imp": [ - { - "id": "test-imp-id", - "instl": 1, - "secure": 1, - "video": { - "placement": 3, - "ext": { - "rp": { - "size_id": 203 - } - }, - "mimes": [ - "video/mp4" - ], - "protocols": [ - 2, - 5 - ], - "w": 1024, - "h": 576 - }, - "ext": { - "rp": { - "target": { - "dataAttr1": [ - "dataVal1" - ], - "dataAttr2": [ - "dataVal2" - ], - "page": [ - "somePage" - ], - "ref": [ - "someRef" - ], - "search": [ - "someSearch" - ], - "dfp_ad_unit_code": "someAdSlot" - }, - "track": { - "mint": "", - "mint_version": "" - }, - "zone_id": 535510 - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "bid": [ - { - "id": "test_bid_id", - "impid": "test-imp-id", - "price": 0.27543, - "adm": "some-test-ad", - "cid": "test_cid", - "crid": "test_crid", - "dealid": "test_dealid", - "ext": { - "prebid": { - "type": "video" - } - } - } - ], - "seat": "adman" - } - ], - "cur": "USD" - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "test_bid_id", - "impid": "test-imp-id", - "price": 0.27543, - "adm": "some-test-ad", - "cid": "test_cid", - "crid": "test_crid", - "dealid": "test_dealid", - "ext": { - "prebid": { - "type": "video" - } - } - }, - "type": "video" - } - ] - } - ] -} diff --git a/adapters/rubicon/rubicontest/exemplary/user-buyeruid-present.json b/adapters/rubicon/rubicontest/exemplary/user-buyeruid-present.json deleted file mode 100644 index 458e19ee5a3..00000000000 --- a/adapters/rubicon/rubicontest/exemplary/user-buyeruid-present.json +++ /dev/null @@ -1,373 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "device": { - "ip": "123.123.123.123", - "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" - }, - "site": { - "page": "somePage", - "ref": "someRef", - "search": "someSearch" - }, - "user": { - "buyeruid": "buyeruid", - "yob": 2000, - "geo": { - "country": "USA", - "lat": 47.627500, - "lon": -122.346200 - }, - "gender": "f", - "data": [ - { - "ext": { - "segtax": 4 - }, - "segment": [ - { - "id": "idToCopy" - } - ] - }, - { - "ext": { - "segtax": "someValue" - }, - "segment": [ - { - "id": "shouldNotBeCopied" - } - ] - }, - { - "ext": { - "segtax": "4" - }, - "segment": [ - { - "id": "shouldNotBeCopied2" - } - ] - }, - { - "ext": { - "segtax": 4 - }, - "segment": [ - { - "id": "idToCopy2" - } - ] - }, - { - "ext": { - "segtax": [ - 4 - ] - }, - "segment": [ - { - "id": "shouldNotBeCopied3" - } - ] - } - ], - "keywords": "someKeywords", - "ext": { - "rp": { - "target": { - "someKey": "someValue" - } - }, - "data": { - "dataKey1": "dataValue1", - "dataKey2": [ - "dataValue2", - "dataValue3" - ], - "dataKey3": true - }, - "eids": [ - { - "source": "rubiconproject.com", - "uids": [ - { - "id": "uidId", - "ext": { - "stype": "ppuid" - } - } - ] - } - ] - } - }, - "imp": [ - { - "id": "test-imp-id", - "instl": 1, - "video": { - "placement": 3, - "mimes": [ - "video/mp4" - ], - "protocols": [ - 2, - 5 - ], - "w": 1024, - "h": 576 - }, - "ext": { - "data": { - "adserver": { - "name": "gam", - "adslot": "someAdSlot" - }, - "dataAttr1": "dataVal1", - "dataAttr2": "dataVal2" - }, - "bidder": { - "video": { - }, - "accountId": 1001, - "siteId": 113932, - "zoneId": 535510 - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "uri?tk_xint=pbs-test-tracker", - "body": { - "id": "test-request-id", - "device": { - "ext": { - "rp": { - "pixelratio": 0 - } - }, - "ip": "123.123.123.123", - "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" - }, - "site": { - "page": "somePage", - "ref": "someRef", - "search": "someSearch", - "ext": { - "rp": { - "site_id": 113932 - } - }, - "publisher": { - "ext": { - "rp": { - "account_id": 1001 - } - } - } - }, - "user": { - "buyeruid": "buyeruid", - "data": [ - { - "ext": { - "segtax": 4 - }, - "segment": [ - { - "id": "idToCopy" - } - ] - }, - { - "ext": { - "segtax": "someValue" - }, - "segment": [ - { - "id": "shouldNotBeCopied" - } - ] - }, - { - "ext": { - "segtax": "4" - }, - "segment": [ - { - "id": "shouldNotBeCopied2" - } - ] - }, - { - "ext": { - "segtax": 4 - }, - "segment": [ - { - "id": "idToCopy2" - } - ] - }, - { - "ext": { - "segtax": [ - 4 - ] - }, - "segment": [ - { - "id": "shouldNotBeCopied3" - } - ] - } - ], - "ext": { - "rp": { - "target": { - "someKey": "someValue", - "dataKey1": [ - "dataValue1" - ], - "dataKey2": [ - "dataValue2", - "dataValue3" - ], - "dataKey3": [ - "true" - ], - "iab": [ - "idToCopy", - "idToCopy2" - ] - } - }, - "eids": [ - { - "source": "rubiconproject.com", - "uids": [ - { - "id": "uidId", - "ext": { - "stype": "ppuid" - } - } - ] - } - ] - }, - "keywords": "someKeywords" - }, - "imp": [ - { - "id": "test-imp-id", - "instl": 1, - "secure": 1, - "video": { - "placement": 3, - "ext": { - "rp": { - "size_id": 203 - } - }, - "mimes": [ - "video/mp4" - ], - "protocols": [ - 2, - 5 - ], - "w": 1024, - "h": 576 - }, - "ext": { - "rp": { - "target": { - "dataAttr1": [ - "dataVal1" - ], - "dataAttr2": [ - "dataVal2" - ], - "page": [ - "somePage" - ], - "ref": [ - "someRef" - ], - "search": [ - "someSearch" - ], - "dfp_ad_unit_code": "someAdSlot" - }, - "track": { - "mint": "", - "mint_version": "" - }, - "zone_id": 535510 - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "bid": [ - { - "id": "test_bid_id", - "impid": "test-imp-id", - "price": 0.27543, - "adm": "some-test-ad", - "cid": "test_cid", - "crid": "test_crid", - "dealid": "test_dealid", - "ext": { - "prebid": { - "type": "video" - } - } - } - ], - "seat": "adman" - } - ], - "cur": "USD" - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "test_bid_id", - "impid": "test-imp-id", - "price": 0.27543, - "adm": "some-test-ad", - "cid": "test_cid", - "crid": "test_crid", - "dealid": "test_dealid", - "ext": { - "prebid": { - "type": "video" - } - } - }, - "type": "video" - } - ] - } - ] -} From 061aa844459befc5d8950f0e7d8ab7c86af95fe2 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Fri, 29 Sep 2023 16:13:59 +0530 Subject: [PATCH 150/268] Adapter alias - syncer changes (#3082) co-authored by @onkarvhanumante --- config/bidderinfo.go | 9 ++++-- config/bidderinfo_test.go | 63 ++++++++++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 16 deletions(-) diff --git a/config/bidderinfo.go b/config/bidderinfo.go index 0027e4d21d0..3b3f86d4ec9 100644 --- a/config/bidderinfo.go +++ b/config/bidderinfo.go @@ -321,8 +321,13 @@ func processBidderAliases(aliasNillableFieldsByBidder map[string]aliasNillableFi if aliasBidderInfo.PlatformID == "" { aliasBidderInfo.PlatformID = parentBidderInfo.PlatformID } - if aliasBidderInfo.Syncer == nil { - aliasBidderInfo.Syncer = parentBidderInfo.Syncer + if aliasBidderInfo.Syncer == nil && parentBidderInfo.Syncer != nil { + syncerKey := aliasBidderInfo.AliasOf + if parentBidderInfo.Syncer.Key != "" { + syncerKey = parentBidderInfo.Syncer.Key + } + syncer := Syncer{Key: syncerKey} + aliasBidderInfo.Syncer = &syncer } if aliasBidderInfo.UserSyncURL == "" { aliasBidderInfo.UserSyncURL = parentBidderInfo.UserSyncURL diff --git a/config/bidderinfo_test.go b/config/bidderinfo_test.go index 438ed5af776..0900421a574 100644 --- a/config/bidderinfo_test.go +++ b/config/bidderinfo_test.go @@ -262,12 +262,6 @@ func TestProcessBidderInfo(t *testing.T) { PlatformID: "123", Syncer: &Syncer{ Key: "foo", - IFrame: &SyncerEndpoint{ - URL: "https://foo.com/sync?mode=iframe&r={{.RedirectURL}}", - RedirectURL: "https://redirect/setuid/iframe", - ExternalURL: "https://iframe.host", - UserMacro: "UID", - }, }, UserSyncURL: "user-url", XAPI: AdapterXAPI{ @@ -293,7 +287,7 @@ func TestProcessBidderInfo(t *testing.T) { } func TestProcessAliasBidderInfo(t *testing.T) { - parentBidderInfo := BidderInfo{ + parentWithSyncerKey := BidderInfo{ AppSecret: "app-secret", Capabilities: &CapabilitiesInfo{ App: &PlatformInfo{ @@ -389,8 +383,29 @@ func TestProcessAliasBidderInfo(t *testing.T) { Tracker: "alias-tracker", }, } - bidderB := parentBidderInfo + bidderB := parentWithSyncerKey bidderB.AliasOf = "bidderA" + bidderB.Syncer = &Syncer{ + Key: bidderB.Syncer.Key, + } + + parentWithoutSyncerKey := BidderInfo{ + Syncer: &Syncer{ + IFrame: &SyncerEndpoint{ + URL: "https://foo.com/sync?mode=iframe&r={{.RedirectURL}}", + RedirectURL: "https://redirect/setuid/iframe", + ExternalURL: "https://iframe.host", + UserMacro: "UID", + }, + }, + } + + bidderC := parentWithoutSyncerKey + bidderC.AliasOf = "bidderA" + bidderC.Syncer = &Syncer{ + Key: "bidderA", + } + testCases := []struct { description string aliasInfos map[string]aliasNillableFields @@ -399,7 +414,7 @@ func TestProcessAliasBidderInfo(t *testing.T) { expectedErr error }{ { - description: "inherit all parent info in alias bidder", + description: "inherit all parent info in alias bidder, use parent syncer key as syncer alias key", aliasInfos: map[string]aliasNillableFields{ "bidderB": { Disabled: nil, @@ -409,14 +424,34 @@ func TestProcessAliasBidderInfo(t *testing.T) { }, }, bidderInfos: BidderInfos{ - "bidderA": parentBidderInfo, + "bidderA": parentWithSyncerKey, "bidderB": BidderInfo{ AliasOf: "bidderA", // all other fields should be inherited from parent bidder }, }, expectedErr: nil, - expectedBidderInfos: BidderInfos{"bidderA": parentBidderInfo, "bidderB": bidderB}, + expectedBidderInfos: BidderInfos{"bidderA": parentWithSyncerKey, "bidderB": bidderB}, + }, + { + description: "inherit all parent info in alias bidder, use parent name as syncer alias key", + aliasInfos: map[string]aliasNillableFields{ + "bidderC": { + Disabled: nil, + ModifyingVastXmlAllowed: nil, + Experiment: nil, + XAPI: nil, + }, + }, + bidderInfos: BidderInfos{ + "bidderA": parentWithoutSyncerKey, + "bidderC": BidderInfo{ + AliasOf: "bidderA", + // all other fields should be inherited from parent bidder + }, + }, + expectedErr: nil, + expectedBidderInfos: BidderInfos{"bidderA": parentWithoutSyncerKey, "bidderC": bidderC}, }, { description: "all bidder info specified for alias, do not inherit from parent bidder", @@ -429,11 +464,11 @@ func TestProcessAliasBidderInfo(t *testing.T) { }, }, bidderInfos: BidderInfos{ - "bidderA": parentBidderInfo, + "bidderA": parentWithSyncerKey, "bidderB": aliasBidderInfo, }, expectedErr: nil, - expectedBidderInfos: BidderInfos{"bidderA": parentBidderInfo, "bidderB": aliasBidderInfo}, + expectedBidderInfos: BidderInfos{"bidderA": parentWithSyncerKey, "bidderB": aliasBidderInfo}, }, { description: "invalid alias", @@ -461,7 +496,7 @@ func TestProcessAliasBidderInfo(t *testing.T) { if test.expectedErr != nil { assert.Equal(t, test.expectedErr, err) } else { - assert.Equal(t, test.expectedBidderInfos, bidderInfos) + assert.Equal(t, test.expectedBidderInfos, bidderInfos, test.description) } } } From 1a5f12c5bc104981ef16be65c88572cfef2517c0 Mon Sep 17 00:00:00 2001 From: Brian Sardo <1168933+bsardo@users.noreply.github.com> Date: Fri, 29 Sep 2023 11:29:43 -0400 Subject: [PATCH 151/268] Remove Config Backwards Compatibility: Host GDPR Options (#3153) --- config/config.go | 98 ------ config/config_test.go | 766 ------------------------------------------ 2 files changed, 864 deletions(-) diff --git a/config/config.go b/config/config.go index b083719e956..a8d276a15c2 100644 --- a/config/config.go +++ b/config/config.go @@ -6,7 +6,6 @@ import ( "fmt" "net/url" "reflect" - "strconv" "strings" "time" @@ -409,7 +408,6 @@ func (t *TCF2) PurposeOneTreatmentAccessAllowed() bool { // Making a purpose struct so purpose specific details can be added later. type TCF2Purpose struct { - Enabled bool `mapstructure:"enabled"` // Deprecated: Use enforce_purpose instead EnforceAlgo string `mapstructure:"enforce_algo"` // Integer representation of enforcement algo for performance improvement on compares EnforceAlgoID TCF2EnforcementAlgo @@ -1117,24 +1115,9 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { v.AutomaticEnv() v.ReadInConfig() - // Migrate config settings to maintain compatibility with old configs - migrateConfigPurposeOneTreatment(v) - migrateConfigSpecialFeature1(v) - migrateConfigTCF2PurposeFlags(v) - // These defaults must be set after the migrate functions because those functions look for the presence of these // config fields and there isn't a way to detect presence of a config field using the viper package if a default // is set. Viper IsSet and Get functions consider default values. - v.SetDefault("gdpr.tcf2.purpose1.enabled", true) - v.SetDefault("gdpr.tcf2.purpose2.enabled", true) - v.SetDefault("gdpr.tcf2.purpose3.enabled", true) - v.SetDefault("gdpr.tcf2.purpose4.enabled", true) - v.SetDefault("gdpr.tcf2.purpose5.enabled", true) - v.SetDefault("gdpr.tcf2.purpose6.enabled", true) - v.SetDefault("gdpr.tcf2.purpose7.enabled", true) - v.SetDefault("gdpr.tcf2.purpose8.enabled", true) - v.SetDefault("gdpr.tcf2.purpose9.enabled", true) - v.SetDefault("gdpr.tcf2.purpose10.enabled", true) v.SetDefault("gdpr.tcf2.purpose1.enforce_algo", TCF2EnforceAlgoFull) v.SetDefault("gdpr.tcf2.purpose2.enforce_algo", TCF2EnforceAlgoFull) v.SetDefault("gdpr.tcf2.purpose3.enforce_algo", TCF2EnforceAlgoFull) @@ -1180,87 +1163,6 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { } } -func migrateConfigPurposeOneTreatment(v *viper.Viper) { - if oldConfig, ok := v.Get("gdpr.tcf2.purpose_one_treatement").(map[string]interface{}); ok { - if v.IsSet("gdpr.tcf2.purpose_one_treatment") { - glog.Warning("using gdpr.tcf2.purpose_one_treatment and ignoring deprecated gdpr.tcf2.purpose_one_treatement") - } else { - glog.Warning("gdpr.tcf2.purpose_one_treatement.enabled should be changed to gdpr.tcf2.purpose_one_treatment.enabled") - glog.Warning("gdpr.tcf2.purpose_one_treatement.access_allowed should be changed to gdpr.tcf2.purpose_one_treatment.access_allowed") - v.Set("gdpr.tcf2.purpose_one_treatment", oldConfig) - } - } -} - -func migrateConfigSpecialFeature1(v *viper.Viper) { - if oldConfig, ok := v.Get("gdpr.tcf2.special_purpose1").(map[string]interface{}); ok { - if v.IsSet("gdpr.tcf2.special_feature1") { - glog.Warning("using gdpr.tcf2.special_feature1 and ignoring deprecated gdpr.tcf2.special_purpose1") - } else { - glog.Warning("gdpr.tcf2.special_purpose1.enabled is deprecated and should be changed to gdpr.tcf2.special_feature1.enforce") - glog.Warning("gdpr.tcf2.special_purpose1.vendor_exceptions is deprecated and should be changed to gdpr.tcf2.special_feature1.vendor_exceptions") - v.Set("gdpr.tcf2.special_feature1.enforce", oldConfig["enabled"]) - v.Set("gdpr.tcf2.special_feature1.vendor_exceptions", oldConfig["vendor_exceptions"]) - } - } -} - -func migrateConfigTCF2PurposeFlags(v *viper.Viper) { - migrateConfigTCF2EnforcePurposeFlags(v) - migrateConfigTCF2PurposeEnabledFlags(v) -} - -func migrateConfigTCF2EnforcePurposeFlags(v *viper.Viper) { - for i := 1; i <= 10; i++ { - algoField := fmt.Sprintf("gdpr.tcf2.purpose%d.enforce_algo", i) - purposeField := fmt.Sprintf("gdpr.tcf2.purpose%d.enforce_purpose", i) - - if !v.IsSet(purposeField) { - continue - } - if _, ok := v.Get(purposeField).(string); !ok { - continue - } - if v.IsSet(algoField) { - glog.Warningf("using %s and ignoring deprecated %s string type", algoField, purposeField) - } else { - v.Set(algoField, TCF2EnforceAlgoFull) - - glog.Warningf("setting %s to \"%s\" based on deprecated %s string type \"%s\"", algoField, TCF2EnforceAlgoFull, purposeField, v.GetString(purposeField)) - } - - oldPurposeFieldValue := v.GetString(purposeField) - newPurposeFieldValue := "false" - if oldPurposeFieldValue == TCF2EnforceAlgoFull { - newPurposeFieldValue = "true" - } - - glog.Warningf("converting %s from string \"%s\" to bool \"%s\"; string type is deprecated", purposeField, oldPurposeFieldValue, newPurposeFieldValue) - v.Set(purposeField, newPurposeFieldValue) - } -} - -func migrateConfigTCF2PurposeEnabledFlags(v *viper.Viper) { - for i := 1; i <= 10; i++ { - oldField := fmt.Sprintf("gdpr.tcf2.purpose%d.enabled", i) - newField := fmt.Sprintf("gdpr.tcf2.purpose%d.enforce_purpose", i) - - if v.IsSet(oldField) { - oldConfig := v.GetBool(oldField) - if v.IsSet(newField) { - glog.Warningf("using %s and ignoring deprecated %s", newField, oldField) - } else { - glog.Warningf("%s is deprecated and should be changed to %s", oldField, newField) - v.Set(newField, oldConfig) - } - } - - if v.IsSet(newField) { - v.Set(oldField, strconv.FormatBool(v.GetBool(newField))) - } - } -} - func isConfigInfoPresent(v *viper.Viper, prefix string, fields []string) bool { prefix = prefix + "." for _, field := range fields { diff --git a/config/config_test.go b/config/config_test.go index 9fc85715c6a..97be28eb6e3 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -208,7 +208,6 @@ func TestDefaults(t *testing.T) { expectedTCF2 := TCF2{ Enabled: true, Purpose1: TCF2Purpose{ - Enabled: true, EnforceAlgo: TCF2EnforceAlgoFull, EnforceAlgoID: TCF2FullEnforcement, EnforcePurpose: true, @@ -217,7 +216,6 @@ func TestDefaults(t *testing.T) { VendorExceptionMap: map[openrtb_ext.BidderName]struct{}{}, }, Purpose2: TCF2Purpose{ - Enabled: true, EnforceAlgo: TCF2EnforceAlgoFull, EnforceAlgoID: TCF2FullEnforcement, EnforcePurpose: true, @@ -226,7 +224,6 @@ func TestDefaults(t *testing.T) { VendorExceptionMap: map[openrtb_ext.BidderName]struct{}{}, }, Purpose3: TCF2Purpose{ - Enabled: true, EnforceAlgo: TCF2EnforceAlgoFull, EnforceAlgoID: TCF2FullEnforcement, EnforcePurpose: true, @@ -235,7 +232,6 @@ func TestDefaults(t *testing.T) { VendorExceptionMap: map[openrtb_ext.BidderName]struct{}{}, }, Purpose4: TCF2Purpose{ - Enabled: true, EnforceAlgo: TCF2EnforceAlgoFull, EnforceAlgoID: TCF2FullEnforcement, EnforcePurpose: true, @@ -244,7 +240,6 @@ func TestDefaults(t *testing.T) { VendorExceptionMap: map[openrtb_ext.BidderName]struct{}{}, }, Purpose5: TCF2Purpose{ - Enabled: true, EnforceAlgo: TCF2EnforceAlgoFull, EnforceAlgoID: TCF2FullEnforcement, EnforcePurpose: true, @@ -253,7 +248,6 @@ func TestDefaults(t *testing.T) { VendorExceptionMap: map[openrtb_ext.BidderName]struct{}{}, }, Purpose6: TCF2Purpose{ - Enabled: true, EnforceAlgo: TCF2EnforceAlgoFull, EnforceAlgoID: TCF2FullEnforcement, EnforcePurpose: true, @@ -262,7 +256,6 @@ func TestDefaults(t *testing.T) { VendorExceptionMap: map[openrtb_ext.BidderName]struct{}{}, }, Purpose7: TCF2Purpose{ - Enabled: true, EnforceAlgo: TCF2EnforceAlgoFull, EnforceAlgoID: TCF2FullEnforcement, EnforcePurpose: true, @@ -271,7 +264,6 @@ func TestDefaults(t *testing.T) { VendorExceptionMap: map[openrtb_ext.BidderName]struct{}{}, }, Purpose8: TCF2Purpose{ - Enabled: true, EnforceAlgo: TCF2EnforceAlgoFull, EnforceAlgoID: TCF2FullEnforcement, EnforcePurpose: true, @@ -280,7 +272,6 @@ func TestDefaults(t *testing.T) { VendorExceptionMap: map[openrtb_ext.BidderName]struct{}{}, }, Purpose9: TCF2Purpose{ - Enabled: true, EnforceAlgo: TCF2EnforceAlgoFull, EnforceAlgoID: TCF2FullEnforcement, EnforcePurpose: true, @@ -289,7 +280,6 @@ func TestDefaults(t *testing.T) { VendorExceptionMap: map[openrtb_ext.BidderName]struct{}{}, }, Purpose10: TCF2Purpose{ - Enabled: true, EnforceAlgo: TCF2EnforceAlgoFull, EnforceAlgoID: TCF2FullEnforcement, EnforcePurpose: true, @@ -334,7 +324,6 @@ gdpr: enforce_vendors: false vendor_exceptions: ["foo1a", "foo1b"] purpose2: - enabled: false enforce_algo: "full" enforce_purpose: false enforce_vendors: false @@ -608,7 +597,6 @@ func TestFullConfig(t *testing.T) { expectedTCF2 := TCF2{ Enabled: true, Purpose1: TCF2Purpose{ - Enabled: true, // true by default EnforceAlgo: TCF2EnforceAlgoFull, EnforceAlgoID: TCF2FullEnforcement, EnforcePurpose: true, @@ -617,7 +605,6 @@ func TestFullConfig(t *testing.T) { VendorExceptionMap: map[openrtb_ext.BidderName]struct{}{openrtb_ext.BidderName("foo1a"): {}, openrtb_ext.BidderName("foo1b"): {}}, }, Purpose2: TCF2Purpose{ - Enabled: false, EnforceAlgo: TCF2EnforceAlgoFull, EnforceAlgoID: TCF2FullEnforcement, EnforcePurpose: false, @@ -626,7 +613,6 @@ func TestFullConfig(t *testing.T) { VendorExceptionMap: map[openrtb_ext.BidderName]struct{}{openrtb_ext.BidderName("foo2"): {}}, }, Purpose3: TCF2Purpose{ - Enabled: true, // true by default EnforceAlgo: TCF2EnforceAlgoBasic, EnforceAlgoID: TCF2BasicEnforcement, EnforcePurpose: true, @@ -635,7 +621,6 @@ func TestFullConfig(t *testing.T) { VendorExceptionMap: map[openrtb_ext.BidderName]struct{}{openrtb_ext.BidderName("foo3"): {}}, }, Purpose4: TCF2Purpose{ - Enabled: true, // true by default EnforceAlgo: TCF2EnforceAlgoFull, EnforceAlgoID: TCF2FullEnforcement, EnforcePurpose: true, @@ -644,7 +629,6 @@ func TestFullConfig(t *testing.T) { VendorExceptionMap: map[openrtb_ext.BidderName]struct{}{openrtb_ext.BidderName("foo4"): {}}, }, Purpose5: TCF2Purpose{ - Enabled: true, // true by default EnforceAlgo: TCF2EnforceAlgoFull, EnforceAlgoID: TCF2FullEnforcement, EnforcePurpose: true, @@ -653,7 +637,6 @@ func TestFullConfig(t *testing.T) { VendorExceptionMap: map[openrtb_ext.BidderName]struct{}{openrtb_ext.BidderName("foo5"): {}}, }, Purpose6: TCF2Purpose{ - Enabled: true, // true by default EnforceAlgo: TCF2EnforceAlgoFull, EnforceAlgoID: TCF2FullEnforcement, EnforcePurpose: true, @@ -662,7 +645,6 @@ func TestFullConfig(t *testing.T) { VendorExceptionMap: map[openrtb_ext.BidderName]struct{}{openrtb_ext.BidderName("foo6"): {}}, }, Purpose7: TCF2Purpose{ - Enabled: true, // true by default EnforceAlgo: TCF2EnforceAlgoFull, EnforceAlgoID: TCF2FullEnforcement, EnforcePurpose: true, @@ -671,7 +653,6 @@ func TestFullConfig(t *testing.T) { VendorExceptionMap: map[openrtb_ext.BidderName]struct{}{openrtb_ext.BidderName("foo7"): {}}, }, Purpose8: TCF2Purpose{ - Enabled: true, // true by default EnforceAlgo: TCF2EnforceAlgoFull, EnforceAlgoID: TCF2FullEnforcement, EnforcePurpose: true, @@ -680,7 +661,6 @@ func TestFullConfig(t *testing.T) { VendorExceptionMap: map[openrtb_ext.BidderName]struct{}{openrtb_ext.BidderName("foo8"): {}}, }, Purpose9: TCF2Purpose{ - Enabled: true, // true by default EnforceAlgo: TCF2EnforceAlgoFull, EnforceAlgoID: TCF2FullEnforcement, EnforcePurpose: true, @@ -689,7 +669,6 @@ func TestFullConfig(t *testing.T) { VendorExceptionMap: map[openrtb_ext.BidderName]struct{}{openrtb_ext.BidderName("foo9"): {}}, }, Purpose10: TCF2Purpose{ - Enabled: true, // true by default EnforceAlgo: TCF2EnforceAlgoFull, EnforceAlgoID: TCF2FullEnforcement, EnforcePurpose: true, @@ -943,751 +922,6 @@ func TestBidderInfoFromEnv(t *testing.T) { assert.Equal(t, "2.6", cfg.BidderInfos["bidder1"].OpenRTB.Version) } -func TestMigrateConfigPurposeOneTreatment(t *testing.T) { - oldPurposeOneTreatmentConfig := []byte(` - gdpr: - tcf2: - purpose_one_treatement: - enabled: true - access_allowed: true - `) - newPurposeOneTreatmentConfig := []byte(` - gdpr: - tcf2: - purpose_one_treatment: - enabled: true - access_allowed: true - `) - oldAndNewPurposeOneTreatmentConfig := []byte(` - gdpr: - tcf2: - purpose_one_treatement: - enabled: false - access_allowed: true - purpose_one_treatment: - enabled: true - access_allowed: false - `) - - tests := []struct { - description string - config []byte - wantPurpose1TreatmentEnabled bool - wantPurpose1TreatmentAccessAllowed bool - }{ - { - description: "New config and old config not set", - config: []byte{}, - }, - { - description: "New config not set, old config set", - config: oldPurposeOneTreatmentConfig, - wantPurpose1TreatmentEnabled: true, - wantPurpose1TreatmentAccessAllowed: true, - }, - { - description: "New config set, old config not set", - config: newPurposeOneTreatmentConfig, - wantPurpose1TreatmentEnabled: true, - wantPurpose1TreatmentAccessAllowed: true, - }, - { - description: "New config and old config set", - config: oldAndNewPurposeOneTreatmentConfig, - wantPurpose1TreatmentEnabled: true, - wantPurpose1TreatmentAccessAllowed: false, - }, - } - - for _, tt := range tests { - v := viper.New() - v.SetConfigType("yaml") - v.ReadConfig(bytes.NewBuffer(tt.config)) - - migrateConfigPurposeOneTreatment(v) - - if len(tt.config) > 0 { - assert.Equal(t, tt.wantPurpose1TreatmentEnabled, v.Get("gdpr.tcf2.purpose_one_treatment.enabled").(bool), tt.description) - assert.Equal(t, tt.wantPurpose1TreatmentAccessAllowed, v.Get("gdpr.tcf2.purpose_one_treatment.access_allowed").(bool), tt.description) - } else { - assert.Nil(t, v.Get("gdpr.tcf2.purpose_one_treatment.enabled"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose_one_treatment.access_allowed"), tt.description) - } - } -} - -func TestMigrateConfigSpecialFeature1(t *testing.T) { - oldSpecialFeature1Config := []byte(` - gdpr: - tcf2: - special_purpose1: - enabled: true - vendor_exceptions: ["appnexus"] - `) - newSpecialFeature1Config := []byte(` - gdpr: - tcf2: - special_feature1: - enforce: true - vendor_exceptions: ["appnexus"] - `) - oldAndNewSpecialFeature1Config := []byte(` - gdpr: - tcf2: - special_purpose1: - enabled: false - vendor_exceptions: ["appnexus"] - special_feature1: - enforce: true - vendor_exceptions: ["rubicon"] - `) - - tests := []struct { - description string - config []byte - wantSpecialFeature1Enforce bool - wantSpecialFeature1VendorExceptions []string - }{ - { - description: "New config and old config not set", - config: []byte{}, - }, - { - description: "New config not set, old config set", - config: oldSpecialFeature1Config, - wantSpecialFeature1Enforce: true, - wantSpecialFeature1VendorExceptions: []string{"appnexus"}, - }, - { - description: "New config set, old config not set", - config: newSpecialFeature1Config, - wantSpecialFeature1Enforce: true, - wantSpecialFeature1VendorExceptions: []string{"appnexus"}, - }, - { - description: "New config and old config set", - config: oldAndNewSpecialFeature1Config, - wantSpecialFeature1Enforce: true, - wantSpecialFeature1VendorExceptions: []string{"rubicon"}, - }, - } - - for _, tt := range tests { - v := viper.New() - v.SetConfigType("yaml") - v.ReadConfig(bytes.NewBuffer(tt.config)) - - migrateConfigSpecialFeature1(v) - - if len(tt.config) > 0 { - assert.Equal(t, tt.wantSpecialFeature1Enforce, v.Get("gdpr.tcf2.special_feature1.enforce").(bool), tt.description) - assert.Equal(t, tt.wantSpecialFeature1VendorExceptions, v.GetStringSlice("gdpr.tcf2.special_feature1.vendor_exceptions"), tt.description) - } else { - assert.Nil(t, v.Get("gdpr.tcf2.special_feature1.enforce"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.special_feature1.vendor_exceptions"), tt.description) - } - - var c Configuration - err := v.Unmarshal(&c) - assert.NoError(t, err, tt.description) - assert.Equal(t, tt.wantSpecialFeature1Enforce, c.GDPR.TCF2.SpecialFeature1.Enforce, tt.description) - - // convert expected vendor exceptions to type BidderName - expectedVendorExceptions := make([]openrtb_ext.BidderName, 0, 0) - for _, ve := range tt.wantSpecialFeature1VendorExceptions { - expectedVendorExceptions = append(expectedVendorExceptions, openrtb_ext.BidderName(ve)) - } - assert.ElementsMatch(t, expectedVendorExceptions, c.GDPR.TCF2.SpecialFeature1.VendorExceptions, tt.description) - } -} - -func TestMigrateConfigTCF2PurposeEnabledFlags(t *testing.T) { - trueStr := "true" - falseStr := "false" - - tests := []struct { - description string - config []byte - wantPurpose1EnforcePurpose string - wantPurpose2EnforcePurpose string - wantPurpose3EnforcePurpose string - wantPurpose4EnforcePurpose string - wantPurpose5EnforcePurpose string - wantPurpose6EnforcePurpose string - wantPurpose7EnforcePurpose string - wantPurpose8EnforcePurpose string - wantPurpose9EnforcePurpose string - wantPurpose10EnforcePurpose string - wantPurpose1Enabled string - wantPurpose2Enabled string - wantPurpose3Enabled string - wantPurpose4Enabled string - wantPurpose5Enabled string - wantPurpose6Enabled string - wantPurpose7Enabled string - wantPurpose8Enabled string - wantPurpose9Enabled string - wantPurpose10Enabled string - }{ - { - description: "New config and old config flags not set", - config: []byte{}, - }, - { - description: "New config not set, old config set - use old flags", - config: []byte(` - gdpr: - tcf2: - purpose1: - enabled: false - purpose2: - enabled: true - purpose3: - enabled: false - purpose4: - enabled: true - purpose5: - enabled: false - purpose6: - enabled: true - purpose7: - enabled: false - purpose8: - enabled: true - purpose9: - enabled: false - purpose10: - enabled: true - `), - wantPurpose1EnforcePurpose: falseStr, - wantPurpose2EnforcePurpose: trueStr, - wantPurpose3EnforcePurpose: falseStr, - wantPurpose4EnforcePurpose: trueStr, - wantPurpose5EnforcePurpose: falseStr, - wantPurpose6EnforcePurpose: trueStr, - wantPurpose7EnforcePurpose: falseStr, - wantPurpose8EnforcePurpose: trueStr, - wantPurpose9EnforcePurpose: falseStr, - wantPurpose10EnforcePurpose: trueStr, - wantPurpose1Enabled: falseStr, - wantPurpose2Enabled: trueStr, - wantPurpose3Enabled: falseStr, - wantPurpose4Enabled: trueStr, - wantPurpose5Enabled: falseStr, - wantPurpose6Enabled: trueStr, - wantPurpose7Enabled: falseStr, - wantPurpose8Enabled: trueStr, - wantPurpose9Enabled: falseStr, - wantPurpose10Enabled: trueStr, - }, - { - description: "New config flags set, old config flags not set - use new flags", - config: []byte(` - gdpr: - tcf2: - purpose1: - enforce_purpose: true - purpose2: - enforce_purpose: false - purpose3: - enforce_purpose: true - purpose4: - enforce_purpose: false - purpose5: - enforce_purpose: true - purpose6: - enforce_purpose: false - purpose7: - enforce_purpose: true - purpose8: - enforce_purpose: false - purpose9: - enforce_purpose: true - purpose10: - enforce_purpose: false - `), - wantPurpose1EnforcePurpose: trueStr, - wantPurpose2EnforcePurpose: falseStr, - wantPurpose3EnforcePurpose: trueStr, - wantPurpose4EnforcePurpose: falseStr, - wantPurpose5EnforcePurpose: trueStr, - wantPurpose6EnforcePurpose: falseStr, - wantPurpose7EnforcePurpose: trueStr, - wantPurpose8EnforcePurpose: falseStr, - wantPurpose9EnforcePurpose: trueStr, - wantPurpose10EnforcePurpose: falseStr, - wantPurpose1Enabled: trueStr, - wantPurpose2Enabled: falseStr, - wantPurpose3Enabled: trueStr, - wantPurpose4Enabled: falseStr, - wantPurpose5Enabled: trueStr, - wantPurpose6Enabled: falseStr, - wantPurpose7Enabled: trueStr, - wantPurpose8Enabled: falseStr, - wantPurpose9Enabled: trueStr, - wantPurpose10Enabled: falseStr, - }, - { - description: "New config flags and old config flags set - use new flags", - config: []byte(` - gdpr: - tcf2: - purpose1: - enabled: false - enforce_purpose: true - purpose2: - enabled: false - enforce_purpose: true - purpose3: - enabled: false - enforce_purpose: true - purpose4: - enabled: false - enforce_purpose: true - purpose5: - enabled: false - enforce_purpose: true - purpose6: - enabled: false - enforce_purpose: true - purpose7: - enabled: false - enforce_purpose: true - purpose8: - enabled: false - enforce_purpose: true - purpose9: - enabled: false - enforce_purpose: true - purpose10: - enabled: false - enforce_purpose: true - `), - wantPurpose1EnforcePurpose: trueStr, - wantPurpose2EnforcePurpose: trueStr, - wantPurpose3EnforcePurpose: trueStr, - wantPurpose4EnforcePurpose: trueStr, - wantPurpose5EnforcePurpose: trueStr, - wantPurpose6EnforcePurpose: trueStr, - wantPurpose7EnforcePurpose: trueStr, - wantPurpose8EnforcePurpose: trueStr, - wantPurpose9EnforcePurpose: trueStr, - wantPurpose10EnforcePurpose: trueStr, - wantPurpose1Enabled: trueStr, - wantPurpose2Enabled: trueStr, - wantPurpose3Enabled: trueStr, - wantPurpose4Enabled: trueStr, - wantPurpose5Enabled: trueStr, - wantPurpose6Enabled: trueStr, - wantPurpose7Enabled: trueStr, - wantPurpose8Enabled: trueStr, - wantPurpose9Enabled: trueStr, - wantPurpose10Enabled: trueStr, - }, - } - - for _, tt := range tests { - v := viper.New() - v.SetConfigType("yaml") - v.ReadConfig(bytes.NewBuffer(tt.config)) - - migrateConfigTCF2PurposeEnabledFlags(v) - - if len(tt.config) > 0 { - assert.Equal(t, tt.wantPurpose1EnforcePurpose, v.GetString("gdpr.tcf2.purpose1.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose2EnforcePurpose, v.GetString("gdpr.tcf2.purpose2.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose3EnforcePurpose, v.GetString("gdpr.tcf2.purpose3.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose4EnforcePurpose, v.GetString("gdpr.tcf2.purpose4.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose5EnforcePurpose, v.GetString("gdpr.tcf2.purpose5.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose6EnforcePurpose, v.GetString("gdpr.tcf2.purpose6.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose7EnforcePurpose, v.GetString("gdpr.tcf2.purpose7.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose8EnforcePurpose, v.GetString("gdpr.tcf2.purpose8.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose9EnforcePurpose, v.GetString("gdpr.tcf2.purpose9.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose10EnforcePurpose, v.GetString("gdpr.tcf2.purpose10.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose1Enabled, v.GetString("gdpr.tcf2.purpose1.enabled"), tt.description) - assert.Equal(t, tt.wantPurpose2Enabled, v.GetString("gdpr.tcf2.purpose2.enabled"), tt.description) - assert.Equal(t, tt.wantPurpose3Enabled, v.GetString("gdpr.tcf2.purpose3.enabled"), tt.description) - assert.Equal(t, tt.wantPurpose4Enabled, v.GetString("gdpr.tcf2.purpose4.enabled"), tt.description) - assert.Equal(t, tt.wantPurpose5Enabled, v.GetString("gdpr.tcf2.purpose5.enabled"), tt.description) - assert.Equal(t, tt.wantPurpose6Enabled, v.GetString("gdpr.tcf2.purpose6.enabled"), tt.description) - assert.Equal(t, tt.wantPurpose7Enabled, v.GetString("gdpr.tcf2.purpose7.enabled"), tt.description) - assert.Equal(t, tt.wantPurpose8Enabled, v.GetString("gdpr.tcf2.purpose8.enabled"), tt.description) - assert.Equal(t, tt.wantPurpose9Enabled, v.GetString("gdpr.tcf2.purpose9.enabled"), tt.description) - assert.Equal(t, tt.wantPurpose10Enabled, v.GetString("gdpr.tcf2.purpose10.enabled"), tt.description) - } else { - assert.Nil(t, v.Get("gdpr.tcf2.purpose1.enforce_purpose"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose2.enforce_purpose"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose3.enforce_purpose"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose4.enforce_purpose"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose5.enforce_purpose"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose6.enforce_purpose"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose7.enforce_purpose"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose8.enforce_purpose"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose9.enforce_purpose"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose10.enforce_purpose"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose1.enabled"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose2.enabled"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose3.enabled"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose4.enabled"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose5.enabled"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose6.enabled"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose7.enabled"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose8.enabled"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose9.enabled"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose10.enabled"), tt.description) - } - } -} - -func TestMigrateConfigTCF2PurposeFlags(t *testing.T) { - tests := []struct { - description string - config []byte - wantPurpose1EnforceAlgo string - wantPurpose1EnforcePurpose bool - wantPurpose1Enabled bool - }{ - { - description: "enforce_purpose does not set enforce_algo but sets enabled", - config: []byte(` - gdpr: - tcf2: - purpose1: - enforce_algo: "off" - enforce_purpose: "full" - enabled: false - purpose2: - enforce_purpose: "full" - enabled: false - purpose3: - enabled: false - `), - wantPurpose1EnforceAlgo: "off", - wantPurpose1EnforcePurpose: true, - wantPurpose1Enabled: true, - }, - { - description: "enforce_purpose sets enforce_algo and enabled", - config: []byte(` - gdpr: - tcf2: - purpose1: - enforce_purpose: "full" - enabled: false - `), - wantPurpose1EnforceAlgo: "full", - wantPurpose1EnforcePurpose: true, - wantPurpose1Enabled: true, - }, - { - description: "enforce_purpose does not set enforce_algo or enabled", - config: []byte(` - gdpr: - tcf2: - purpose1: - enabled: false - `), - wantPurpose1EnforceAlgo: "", - wantPurpose1EnforcePurpose: false, - wantPurpose1Enabled: false, - }, - } - - for _, tt := range tests { - v := viper.New() - v.SetConfigType("yaml") - v.ReadConfig(bytes.NewBuffer(tt.config)) - - migrateConfigTCF2PurposeFlags(v) - - assert.Equal(t, tt.wantPurpose1EnforceAlgo, v.GetString("gdpr.tcf2.purpose1.enforce_algo"), tt.description) - assert.Equal(t, tt.wantPurpose1EnforcePurpose, v.GetBool("gdpr.tcf2.purpose1.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose1Enabled, v.GetBool("gdpr.tcf2.purpose1.enabled"), tt.description) - } - -} - -func TestMigrateConfigTCF2EnforcePurposeFlags(t *testing.T) { - trueStr := "true" - falseStr := "false" - - tests := []struct { - description string - config []byte - wantEnforceAlgosSet bool - wantPurpose1EnforceAlgo string - wantPurpose2EnforceAlgo string - wantPurpose3EnforceAlgo string - wantPurpose4EnforceAlgo string - wantPurpose5EnforceAlgo string - wantPurpose6EnforceAlgo string - wantPurpose7EnforceAlgo string - wantPurpose8EnforceAlgo string - wantPurpose9EnforceAlgo string - wantPurpose10EnforceAlgo string - wantEnforcePurposesSet bool - wantPurpose1EnforcePurpose string - wantPurpose2EnforcePurpose string - wantPurpose3EnforcePurpose string - wantPurpose4EnforcePurpose string - wantPurpose5EnforcePurpose string - wantPurpose6EnforcePurpose string - wantPurpose7EnforcePurpose string - wantPurpose8EnforcePurpose string - wantPurpose9EnforcePurpose string - wantPurpose10EnforcePurpose string - }{ - { - description: "enforce_algo and enforce_purpose are not set", - config: []byte{}, - wantEnforceAlgosSet: false, - wantEnforcePurposesSet: false, - }, - { - description: "enforce_algo not set; set it based on enforce_purpose string value", - config: []byte(` - gdpr: - tcf2: - purpose1: - enforce_purpose: "full" - purpose2: - enforce_purpose: "no" - purpose3: - enforce_purpose: "full" - purpose4: - enforce_purpose: "no" - purpose5: - enforce_purpose: "full" - purpose6: - enforce_purpose: "no" - purpose7: - enforce_purpose: "full" - purpose8: - enforce_purpose: "no" - purpose9: - enforce_purpose: "full" - purpose10: - enforce_purpose: "no" - `), - wantEnforceAlgosSet: true, - wantPurpose1EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose2EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose3EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose4EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose5EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose6EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose7EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose8EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose9EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose10EnforceAlgo: TCF2EnforceAlgoFull, - wantEnforcePurposesSet: true, - wantPurpose1EnforcePurpose: trueStr, - wantPurpose2EnforcePurpose: falseStr, - wantPurpose3EnforcePurpose: trueStr, - wantPurpose4EnforcePurpose: falseStr, - wantPurpose5EnforcePurpose: trueStr, - wantPurpose6EnforcePurpose: falseStr, - wantPurpose7EnforcePurpose: trueStr, - wantPurpose8EnforcePurpose: falseStr, - wantPurpose9EnforcePurpose: trueStr, - wantPurpose10EnforcePurpose: falseStr, - }, - { - description: "enforce_algo not set; don't set it based on enforce_purpose bool value", - config: []byte(` - gdpr: - tcf2: - purpose1: - enforce_purpose: true - purpose2: - enforce_purpose: false - purpose3: - enforce_purpose: true - purpose4: - enforce_purpose: false - purpose5: - enforce_purpose: true - purpose6: - enforce_purpose: false - purpose7: - enforce_purpose: true - purpose8: - enforce_purpose: false - purpose9: - enforce_purpose: true - purpose10: - enforce_purpose: false - `), - wantEnforceAlgosSet: false, - wantEnforcePurposesSet: true, - wantPurpose1EnforcePurpose: trueStr, - wantPurpose2EnforcePurpose: falseStr, - wantPurpose3EnforcePurpose: trueStr, - wantPurpose4EnforcePurpose: falseStr, - wantPurpose5EnforcePurpose: trueStr, - wantPurpose6EnforcePurpose: falseStr, - wantPurpose7EnforcePurpose: trueStr, - wantPurpose8EnforcePurpose: falseStr, - wantPurpose9EnforcePurpose: trueStr, - wantPurpose10EnforcePurpose: falseStr, - }, - { - description: "enforce_algo is set and enforce_purpose is not; enforce_algo is unchanged", - config: []byte(` - gdpr: - tcf2: - purpose1: - enforce_algo: "full" - purpose2: - enforce_algo: "full" - purpose3: - enforce_algo: "full" - purpose4: - enforce_algo: "full" - purpose5: - enforce_algo: "full" - purpose6: - enforce_algo: "full" - purpose7: - enforce_algo: "full" - purpose8: - enforce_algo: "full" - purpose9: - enforce_algo: "full" - purpose10: - enforce_algo: "full" - `), - wantEnforceAlgosSet: true, - wantPurpose1EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose2EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose3EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose4EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose5EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose6EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose7EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose8EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose9EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose10EnforceAlgo: TCF2EnforceAlgoFull, - wantEnforcePurposesSet: false, - }, - { - description: "enforce_algo and enforce_purpose are set; enforce_algo is unchanged", - config: []byte(` - gdpr: - tcf2: - purpose1: - enforce_algo: "full" - enforce_purpose: "no" - purpose2: - enforce_algo: "full" - enforce_purpose: "no" - purpose3: - enforce_algo: "full" - enforce_purpose: "no" - purpose4: - enforce_algo: "full" - enforce_purpose: "no" - purpose5: - enforce_algo: "full" - enforce_purpose: "no" - purpose6: - enforce_algo: "full" - enforce_purpose: "no" - purpose7: - enforce_algo: "full" - enforce_purpose: "no" - purpose8: - enforce_algo: "full" - enforce_purpose: "no" - purpose9: - enforce_algo: "full" - enforce_purpose: "no" - purpose10: - enforce_algo: "full" - enforce_purpose: "no" - `), - wantEnforceAlgosSet: true, - wantPurpose1EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose2EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose3EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose4EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose5EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose6EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose7EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose8EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose9EnforceAlgo: TCF2EnforceAlgoFull, - wantPurpose10EnforceAlgo: TCF2EnforceAlgoFull, - wantEnforcePurposesSet: true, - wantPurpose1EnforcePurpose: falseStr, - wantPurpose2EnforcePurpose: falseStr, - wantPurpose3EnforcePurpose: falseStr, - wantPurpose4EnforcePurpose: falseStr, - wantPurpose5EnforcePurpose: falseStr, - wantPurpose6EnforcePurpose: falseStr, - wantPurpose7EnforcePurpose: falseStr, - wantPurpose8EnforcePurpose: falseStr, - wantPurpose9EnforcePurpose: falseStr, - wantPurpose10EnforcePurpose: falseStr, - }, - } - - for _, tt := range tests { - v := viper.New() - v.SetConfigType("yaml") - v.ReadConfig(bytes.NewBuffer(tt.config)) - - migrateConfigTCF2EnforcePurposeFlags(v) - - if tt.wantEnforceAlgosSet { - assert.Equal(t, tt.wantPurpose1EnforceAlgo, v.GetString("gdpr.tcf2.purpose1.enforce_algo"), tt.description) - assert.Equal(t, tt.wantPurpose2EnforceAlgo, v.GetString("gdpr.tcf2.purpose2.enforce_algo"), tt.description) - assert.Equal(t, tt.wantPurpose3EnforceAlgo, v.GetString("gdpr.tcf2.purpose3.enforce_algo"), tt.description) - assert.Equal(t, tt.wantPurpose4EnforceAlgo, v.GetString("gdpr.tcf2.purpose4.enforce_algo"), tt.description) - assert.Equal(t, tt.wantPurpose5EnforceAlgo, v.GetString("gdpr.tcf2.purpose5.enforce_algo"), tt.description) - assert.Equal(t, tt.wantPurpose6EnforceAlgo, v.GetString("gdpr.tcf2.purpose6.enforce_algo"), tt.description) - assert.Equal(t, tt.wantPurpose7EnforceAlgo, v.GetString("gdpr.tcf2.purpose7.enforce_algo"), tt.description) - assert.Equal(t, tt.wantPurpose8EnforceAlgo, v.GetString("gdpr.tcf2.purpose8.enforce_algo"), tt.description) - assert.Equal(t, tt.wantPurpose9EnforceAlgo, v.GetString("gdpr.tcf2.purpose9.enforce_algo"), tt.description) - assert.Equal(t, tt.wantPurpose10EnforceAlgo, v.GetString("gdpr.tcf2.purpose10.enforce_algo"), tt.description) - } else { - assert.Nil(t, v.Get("gdpr.tcf2.purpose1.enforce_algo"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose2.enforce_algo"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose3.enforce_algo"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose4.enforce_algo"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose5.enforce_algo"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose6.enforce_algo"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose7.enforce_algo"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose8.enforce_algo"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose9.enforce_algo"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose10.enforce_algo"), tt.description) - } - - if tt.wantEnforcePurposesSet { - assert.Equal(t, tt.wantPurpose1EnforcePurpose, v.GetString("gdpr.tcf2.purpose1.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose2EnforcePurpose, v.GetString("gdpr.tcf2.purpose2.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose3EnforcePurpose, v.GetString("gdpr.tcf2.purpose3.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose4EnforcePurpose, v.GetString("gdpr.tcf2.purpose4.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose5EnforcePurpose, v.GetString("gdpr.tcf2.purpose5.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose6EnforcePurpose, v.GetString("gdpr.tcf2.purpose6.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose7EnforcePurpose, v.GetString("gdpr.tcf2.purpose7.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose8EnforcePurpose, v.GetString("gdpr.tcf2.purpose8.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose9EnforcePurpose, v.GetString("gdpr.tcf2.purpose9.enforce_purpose"), tt.description) - assert.Equal(t, tt.wantPurpose10EnforcePurpose, v.GetString("gdpr.tcf2.purpose10.enforce_purpose"), tt.description) - } else { - assert.Nil(t, v.Get("gdpr.tcf2.purpose1.enforce_purpose"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose2.enforce_purpose"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose3.enforce_purpose"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose4.enforce_purpose"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose5.enforce_purpose"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose6.enforce_purpose"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose7.enforce_purpose"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose8.enforce_purpose"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose9.enforce_purpose"), tt.description) - assert.Nil(t, v.Get("gdpr.tcf2.purpose10.enforce_purpose"), tt.description) - } - } -} - func TestIsConfigInfoPresent(t *testing.T) { configPrefix1Field2Only := []byte(` prefix1: From 5cc92ae811966b22b485aaa5a8040a454ccfbd66 Mon Sep 17 00:00:00 2001 From: Brian Sardo <1168933+bsardo@users.noreply.github.com> Date: Fri, 29 Sep 2023 11:57:59 -0400 Subject: [PATCH 152/268] Remove Config Backwards Compatibility: Account GDPR Purpose (#3154) --- account/account.go | 104 +--------- account/account_test.go | 284 +------------------------- metrics/config/metrics.go | 8 - metrics/go_metrics.go | 54 +---- metrics/go_metrics_test.go | 88 -------- metrics/metrics.go | 1 - metrics/metrics_mock.go | 4 - metrics/prometheus/prometheus.go | 74 +------ metrics/prometheus/prometheus_test.go | 85 -------- 9 files changed, 18 insertions(+), 684 deletions(-) diff --git a/account/account.go b/account/account.go index 36b6da51c38..7b5f9435a11 100644 --- a/account/account.go +++ b/account/account.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "github.com/buger/jsonparser" "github.com/prebid/go-gdpr/consentconstants" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" @@ -12,7 +11,6 @@ import ( "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/stored_requests" "github.com/prebid/prebid-server/util/iputil" - jsonpatch "gopkg.in/evanphx/json-patch.v4" ) // GetAccount looks up the config.Account object referenced by the given accountID, with access rules applied @@ -50,23 +48,10 @@ func GetAccount(ctx context.Context, cfg *config.Configuration, fetcher stored_r // accountID resolved to a valid account, merge with AccountDefaults for a complete config account = &config.Account{} err := json.Unmarshal(accountJSON, account) - - // this logic exists for backwards compatibility. If the initial unmarshal fails above, we attempt to - // resolve it by converting the GDPR enforce purpose fields and then attempting an unmarshal again before - // declaring a malformed account error. - // unmarshal fetched account to determine if it is well-formed - var deprecatedPurposeFields []string if _, ok := err.(*json.UnmarshalTypeError); ok { - // attempt to convert deprecated GDPR enforce purpose fields to resolve issue - accountJSON, err, deprecatedPurposeFields = ConvertGDPREnforcePurposeFields(accountJSON) - // unmarshal again to check if unmarshal error still exists after GDPR field conversion - err = json.Unmarshal(accountJSON, account) - - if _, ok := err.(*json.UnmarshalTypeError); ok { - return nil, []error{&errortypes.MalformedAcct{ - Message: fmt.Sprintf("The prebid-server account config for account id \"%s\" is malformed. Please reach out to the prebid server host.", accountID), - }} - } + return nil, []error{&errortypes.MalformedAcct{ + Message: fmt.Sprintf("The prebid-server account config for account id \"%s\" is malformed. Please reach out to the prebid server host.", accountID), + }} } usingGDPRChannelEnabled := useGDPRChannelEnabled(account) usingCCPAChannelEnabled := useCCPAChannelEnabled(account) @@ -77,10 +62,7 @@ func GetAccount(ctx context.Context, cfg *config.Configuration, fetcher stored_r if usingCCPAChannelEnabled { me.RecordAccountCCPAChannelEnabledWarning(accountID) } - for _, purposeName := range deprecatedPurposeFields { - me.RecordAccountGDPRPurposeWarning(accountID, purposeName) - } - if len(deprecatedPurposeFields) > 0 || usingGDPRChannelEnabled || usingCCPAChannelEnabled { + if usingGDPRChannelEnabled || usingCCPAChannelEnabled { me.RecordAccountUpgradeStatus(accountID) } @@ -176,84 +158,6 @@ func setDerivedConfig(account *config.Account) { } } -// PatchAccount represents the GDPR portion of a publisher account configuration that can be mutated -// for backwards compatibility reasons -type PatchAccount struct { - GDPR map[string]*PatchAccountGDPRPurpose `json:"gdpr"` -} - -// PatchAccountGDPRPurpose represents account-specific GDPR purpose configuration data that can be mutated -// for backwards compatibility reasons -type PatchAccountGDPRPurpose struct { - EnforceAlgo string `json:"enforce_algo,omitempty"` - EnforcePurpose *bool `json:"enforce_purpose,omitempty"` -} - -// ConvertGDPREnforcePurposeFields is responsible for ensuring account GDPR config backwards compatibility -// given the recent type change of gdpr.purpose{1-10}.enforce_purpose from a string to a bool. This function -// iterates over each GDPR purpose config and sets enforce_purpose and enforce_algo to the appropriate -// bool and string values respectively if enforce_purpose is a string and enforce_algo is not set -func ConvertGDPREnforcePurposeFields(config []byte) (newConfig []byte, err error, deprecatedPurposeFields []string) { - gdprJSON, _, _, err := jsonparser.Get(config, "gdpr") - if err != nil && err == jsonparser.KeyPathNotFoundError { - return config, nil, deprecatedPurposeFields - } - if err != nil { - return nil, err, deprecatedPurposeFields - } - - newAccount := PatchAccount{ - GDPR: map[string]*PatchAccountGDPRPurpose{}, - } - - for i := 1; i <= 10; i++ { - purposeName := fmt.Sprintf("purpose%d", i) - - enforcePurpose, purposeDataType, _, err := jsonparser.Get(gdprJSON, purposeName, "enforce_purpose") - if err != nil && err == jsonparser.KeyPathNotFoundError { - continue - } - if err != nil { - return nil, err, deprecatedPurposeFields - } - if purposeDataType != jsonparser.String { - continue - } else { - deprecatedPurposeFields = append(deprecatedPurposeFields, purposeName) - } - - _, _, _, err = jsonparser.Get(gdprJSON, purposeName, "enforce_algo") - if err != nil && err != jsonparser.KeyPathNotFoundError { - return nil, err, deprecatedPurposeFields - } - if err == nil { - continue - } - - newEnforcePurpose := false - if string(enforcePurpose) == "full" { - newEnforcePurpose = true - } - - newAccount.GDPR[purposeName] = &PatchAccountGDPRPurpose{ - EnforceAlgo: "full", - EnforcePurpose: &newEnforcePurpose, - } - } - - patchConfig, err := json.Marshal(newAccount) - if err != nil { - return nil, err, deprecatedPurposeFields - } - - newConfig, err = jsonpatch.MergePatch(config, patchConfig) - if err != nil { - return nil, err, deprecatedPurposeFields - } - - return newConfig, nil, deprecatedPurposeFields -} - func useGDPRChannelEnabled(account *config.Account) bool { return account.GDPR.ChannelEnabled.IsSet() && !account.GDPR.IntegrationEnabled.IsSet() } diff --git a/account/account_test.go b/account/account_test.go index b527dee149f..d5223f76119 100644 --- a/account/account_test.go +++ b/account/account_test.go @@ -6,7 +6,6 @@ import ( "fmt" "testing" - "github.com/buger/jsonparser" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/metrics" @@ -18,23 +17,12 @@ import ( ) var mockAccountData = map[string]json.RawMessage{ - "valid_acct": json.RawMessage(`{"disabled":false}`), - "invalid_acct_ipv6_ipv4": json.RawMessage(`{"disabled":false, "privacy": {"ipv6": {"anon_keep_bits": -32}, "ipv4": {"anon_keep_bits": -16}}}`), - "disabled_acct": json.RawMessage(`{"disabled":true}`), - "malformed_acct": json.RawMessage(`{"disabled":"invalid type"}`), - "gdpr_channel_enabled_acct": json.RawMessage(`{"disabled":false,"gdpr":{"channel_enabled":{"amp":true}}}`), - "ccpa_channel_enabled_acct": json.RawMessage(`{"disabled":false,"ccpa":{"channel_enabled":{"amp":true}}}`), - "gdpr_channel_enabled_deprecated_purpose_acct": json.RawMessage(`{"disabled":false,"gdpr":{"purpose1":{"enforce_purpose":"full"}, "channel_enabled":{"amp":true}}}`), - "gdpr_deprecated_purpose1": json.RawMessage(`{"disabled":false,"gdpr":{"purpose1":{"enforce_purpose":"full"}}}`), - "gdpr_deprecated_purpose2": json.RawMessage(`{"disabled":false,"gdpr":{"purpose2":{"enforce_purpose":"full"}}}`), - "gdpr_deprecated_purpose3": json.RawMessage(`{"disabled":false,"gdpr":{"purpose3":{"enforce_purpose":"full"}}}`), - "gdpr_deprecated_purpose4": json.RawMessage(`{"disabled":false,"gdpr":{"purpose4":{"enforce_purpose":"full"}}}`), - "gdpr_deprecated_purpose5": json.RawMessage(`{"disabled":false,"gdpr":{"purpose5":{"enforce_purpose":"full"}}}`), - "gdpr_deprecated_purpose6": json.RawMessage(`{"disabled":false,"gdpr":{"purpose6":{"enforce_purpose":"full"}}}`), - "gdpr_deprecated_purpose7": json.RawMessage(`{"disabled":false,"gdpr":{"purpose7":{"enforce_purpose":"full"}}}`), - "gdpr_deprecated_purpose8": json.RawMessage(`{"disabled":false,"gdpr":{"purpose8":{"enforce_purpose":"full"}}}`), - "gdpr_deprecated_purpose9": json.RawMessage(`{"disabled":false,"gdpr":{"purpose9":{"enforce_purpose":"full"}}}`), - "gdpr_deprecated_purpose10": json.RawMessage(`{"disabled":false,"gdpr":{"purpose10":{"enforce_purpose":"full"}}}`), + "valid_acct": json.RawMessage(`{"disabled":false}`), + "invalid_acct_ipv6_ipv4": json.RawMessage(`{"disabled":false, "privacy": {"ipv6": {"anon_keep_bits": -32}, "ipv4": {"anon_keep_bits": -16}}}`), + "disabled_acct": json.RawMessage(`{"disabled":true}`), + "malformed_acct": json.RawMessage(`{"disabled":"invalid type"}`), + "gdpr_channel_enabled_acct": json.RawMessage(`{"disabled":false,"gdpr":{"channel_enabled":{"amp":true}}}`), + "ccpa_channel_enabled_acct": json.RawMessage(`{"disabled":false,"ccpa":{"channel_enabled":{"amp":true}}}`), } type mockAccountFetcher struct { @@ -89,12 +77,6 @@ func TestGetAccount(t *testing.T) { {accountID: "disabled_acct", required: false, disabled: true, err: &errortypes.BlacklistedAcct{}}, {accountID: "disabled_acct", required: true, disabled: true, err: &errortypes.BlacklistedAcct{}}, - // pubID given and matches a host account with Disabled: false and GDPR purpose data to convert - {accountID: "gdpr_deprecated_purpose1", required: false, disabled: false, err: nil}, - {accountID: "gdpr_deprecated_purpose1", required: true, disabled: false, err: nil}, - {accountID: "gdpr_deprecated_purpose1", required: false, disabled: true, err: nil}, - {accountID: "gdpr_deprecated_purpose1", required: true, disabled: true, err: nil}, - // pubID given and matches a host account that has a malformed config {accountID: "malformed_acct", required: false, disabled: false, err: &errortypes.MalformedAcct{}}, {accountID: "malformed_acct", required: true, disabled: false, err: &errortypes.MalformedAcct{}}, @@ -120,7 +102,6 @@ func TestGetAccount(t *testing.T) { assert.NoError(t, cfg.MarshalAccountDefaults()) metrics := &metrics.MetricsEngineMock{} - metrics.Mock.On("RecordAccountGDPRPurposeWarning", mock.Anything, mock.Anything).Return() metrics.Mock.On("RecordAccountUpgradeStatus", mock.Anything, mock.Anything).Return() account, errors := GetAccount(context.Background(), cfg, fetcher, test.accountID, metrics) @@ -238,160 +219,6 @@ func TestSetDerivedConfig(t *testing.T) { } } -func TestConvertGDPREnforcePurposeFields(t *testing.T) { - enforcePurposeNo := `{"enforce_purpose":"no"}` - enforcePurposeNoMapped := `{"enforce_algo":"full", "enforce_purpose":false}` - enforcePurposeFull := `{"enforce_purpose":"full"}` - enforcePurposeFullMapped := `{"enforce_algo":"full", "enforce_purpose":true}` - - tests := []struct { - description string - giveConfig []byte - wantConfig []byte - wantErr error - wantPurposeFields []string - }{ - { - description: "config is nil", - giveConfig: nil, - wantConfig: nil, - wantErr: nil, - wantPurposeFields: nil, - }, - { - description: "config is empty - no gdpr key", - giveConfig: []byte(``), - wantConfig: []byte(``), - wantErr: nil, - wantPurposeFields: nil, - }, - { - description: "gdpr present but empty", - giveConfig: []byte(`{"gdpr": {}}`), - wantConfig: []byte(`{"gdpr": {}}`), - wantErr: nil, - wantPurposeFields: nil, - }, - { - description: "gdpr present but invalid", - giveConfig: []byte(`{"gdpr": {`), - wantConfig: nil, - wantErr: jsonparser.MalformedJsonError, - wantPurposeFields: nil, - }, - { - description: "gdpr.purpose1 present but empty", - giveConfig: []byte(`{"gdpr":{"purpose1":{}}}`), - wantConfig: []byte(`{"gdpr":{"purpose1":{}}}`), - wantErr: nil, - wantPurposeFields: nil, - }, - { - description: "gdpr.purpose1.enforce_purpose is set to bool", - giveConfig: []byte(`{"gdpr":{"purpose1":{"enforce_purpose":true}}}`), - wantConfig: []byte(`{"gdpr":{"purpose1":{"enforce_purpose":true}}}`), - wantErr: nil, - wantPurposeFields: nil, - }, - { - description: "gdpr.purpose1.enforce_purpose is set to string full", - giveConfig: []byte(`{"gdpr":{"purpose1":{"enforce_purpose":"full"}}}`), - wantConfig: []byte(`{"gdpr":{"purpose1":{"enforce_algo":"full", "enforce_purpose":true}}}`), - wantErr: nil, - wantPurposeFields: []string{"purpose1"}, - }, - { - description: "gdpr.purpose1.enforce_purpose is set to string no", - giveConfig: []byte(`{"gdpr":{"purpose1":{"enforce_purpose":"no"}}}`), - wantConfig: []byte(`{"gdpr":{"purpose1":{"enforce_algo":"full", "enforce_purpose":false}}}`), - wantErr: nil, - wantPurposeFields: []string{"purpose1"}, - }, - { - description: "gdpr.purpose1.enforce_purpose is set to string no and other fields are untouched during conversion", - giveConfig: []byte(`{"gdpr":{"purpose1":{"enforce_purpose":"no", "enforce_vendors":true}}}`), - wantConfig: []byte(`{"gdpr":{"purpose1":{"enforce_algo":"full", "enforce_purpose":false, "enforce_vendors":true}}}`), - wantErr: nil, - wantPurposeFields: []string{"purpose1"}, - }, - { - description: "gdpr.purpose1.enforce_purpose is set but invalid", - giveConfig: []byte(`{"gdpr":{"purpose1":{"enforce_purpose":}}}`), - wantConfig: nil, - wantErr: jsonparser.MalformedJsonError, - wantPurposeFields: nil, - }, - { - description: "gdpr.purpose1.enforce_algo is set", - giveConfig: []byte(`{"gdpr":{"purpose1":{"enforce_algo":"full"}}}`), - wantConfig: []byte(`{"gdpr":{"purpose1":{"enforce_algo":"full"}}}`), - wantErr: nil, - wantPurposeFields: nil, - }, - { - description: "gdpr.purpose1.enforce_purpose is set to string and enforce_algo is set", - giveConfig: []byte(`{"gdpr":{"purpose1":{"enforce_algo":"full", "enforce_purpose":"full"}}}`), - wantConfig: []byte(`{"gdpr":{"purpose1":{"enforce_algo":"full", "enforce_purpose":"full"}}}`), - wantErr: nil, - wantPurposeFields: []string{"purpose1"}, - }, - { - description: "gdpr.purpose1.enforce_purpose is set to string and enforce_algo is set but invalid", - giveConfig: []byte(`{"gdpr":{"purpose1":{"enforce_algo":, "enforce_purpose":"full"}}}`), - wantConfig: nil, - wantErr: jsonparser.MalformedJsonError, - wantPurposeFields: []string{"purpose1"}, - }, - { - description: "gdpr.purpose{1-10}.enforce_purpose are set to strings no and full alternating", - giveConfig: []byte(`{"gdpr":{` + - `"purpose1":` + enforcePurposeNo + - `,"purpose2":` + enforcePurposeFull + - `,"purpose3":` + enforcePurposeNo + - `,"purpose4":` + enforcePurposeFull + - `,"purpose5":` + enforcePurposeNo + - `,"purpose6":` + enforcePurposeFull + - `,"purpose7":` + enforcePurposeNo + - `,"purpose8":` + enforcePurposeFull + - `,"purpose9":` + enforcePurposeNo + - `,"purpose10":` + enforcePurposeFull + - `}}`), - wantConfig: []byte(`{"gdpr":{` + - `"purpose1":` + enforcePurposeNoMapped + - `,"purpose2":` + enforcePurposeFullMapped + - `,"purpose3":` + enforcePurposeNoMapped + - `,"purpose4":` + enforcePurposeFullMapped + - `,"purpose5":` + enforcePurposeNoMapped + - `,"purpose6":` + enforcePurposeFullMapped + - `,"purpose7":` + enforcePurposeNoMapped + - `,"purpose8":` + enforcePurposeFullMapped + - `,"purpose9":` + enforcePurposeNoMapped + - `,"purpose10":` + enforcePurposeFullMapped + - `}}`), - wantErr: nil, - wantPurposeFields: []string{"purpose1", "purpose2", "purpose3", "purpose4", "purpose5", "purpose6", "purpose7", "purpose8", "purpose9", "purpose10"}, - }, - } - - for _, tt := range tests { - metricsMock := &metrics.MetricsEngineMock{} - metricsMock.Mock.On("RecordAccountGDPRPurposeWarning", mock.Anything, mock.Anything).Return() - metricsMock.Mock.On("RecordAccountUpgradeStatus", mock.Anything, mock.Anything).Return() - - newConfig, err, deprecatedPurposeFields := ConvertGDPREnforcePurposeFields(tt.giveConfig) - if tt.wantErr != nil { - assert.Error(t, err, tt.description) - } - - if len(tt.wantConfig) == 0 { - assert.Equal(t, tt.wantConfig, newConfig, tt.description) - } else { - assert.JSONEq(t, string(tt.wantConfig), string(newConfig), tt.description) - } - assert.Equal(t, tt.wantPurposeFields, deprecatedPurposeFields, tt.description) - } -} - func TestGdprCcpaChannelEnabledMetrics(t *testing.T) { cfg := &config.Configuration{} fetcher := &mockAccountFetcher{} @@ -442,89 +269,6 @@ func TestGdprCcpaChannelEnabledMetrics(t *testing.T) { } } -func TestGdprPurposeWarningMetrics(t *testing.T) { - cfg := &config.Configuration{} - fetcher := &mockAccountFetcher{} - assert.NoError(t, cfg.MarshalAccountDefaults()) - - testCases := []struct { - name string - givenMetric string - givenAccountID string - givenConfig []byte - expectedMetricCount int - }{ - { - name: "Purpose1MetricCalled", - givenAccountID: "gdpr_deprecated_purpose1", - expectedMetricCount: 1, - }, - { - name: "Purpose2MetricCalled", - givenAccountID: "gdpr_deprecated_purpose2", - expectedMetricCount: 1, - }, - { - name: "Purpose3MetricCalled", - givenAccountID: "gdpr_deprecated_purpose3", - expectedMetricCount: 1, - }, - { - name: "Purpose4MetricCalled", - givenAccountID: "gdpr_deprecated_purpose4", - expectedMetricCount: 1, - }, - { - name: "Purpose5MetricCalled", - givenAccountID: "gdpr_deprecated_purpose5", - expectedMetricCount: 1, - }, - { - name: "Purpose6MetricCalled", - givenAccountID: "gdpr_deprecated_purpose6", - expectedMetricCount: 1, - }, - { - name: "Purpose7MetricCalled", - givenAccountID: "gdpr_deprecated_purpose7", - expectedMetricCount: 1, - }, - { - name: "Purpose8MetricCalled", - givenAccountID: "gdpr_deprecated_purpose8", - expectedMetricCount: 1, - }, - { - name: "Purpose9MetricCalled", - givenAccountID: "gdpr_deprecated_purpose9", - expectedMetricCount: 1, - }, - { - name: "Purpose10MetricCalled", - givenAccountID: "gdpr_deprecated_purpose10", - expectedMetricCount: 1, - }, - { - name: "PurposeMetricNotCalled", - givenAccountID: "valid_acct", - expectedMetricCount: 0, - }, - } - - for _, test := range testCases { - t.Run(test.name, func(t *testing.T) { - metrics := &metrics.MetricsEngineMock{} - metrics.Mock.On("RecordAccountGDPRPurposeWarning", mock.Anything, mock.Anything).Return() - metrics.Mock.On("RecordAccountUpgradeStatus", mock.Anything, mock.Anything).Return() - - _, _ = GetAccount(context.Background(), cfg, fetcher, test.givenAccountID, metrics) - - metrics.AssertNumberOfCalls(t, "RecordAccountGDPRPurposeWarning", test.expectedMetricCount) - }) - - } -} - func TestAccountUpgradeStatusGetAccount(t *testing.T) { cfg := &config.Configuration{} fetcher := &mockAccountFetcher{} @@ -536,24 +280,12 @@ func TestAccountUpgradeStatusGetAccount(t *testing.T) { givenMetrics []string expectedMetricCount int }{ - { - name: "MultipleDeprecatedConfigs", - givenAccountIDs: []string{"gdpr_channel_enabled_deprecated_purpose_acct"}, - givenMetrics: []string{"RecordAccountGDPRChannelEnabledWarning", "RecordAccountGDPRPurposeWarning"}, - expectedMetricCount: 1, - }, { name: "ZeroDeprecatedConfigs", givenAccountIDs: []string{"valid_acct"}, givenMetrics: []string{}, expectedMetricCount: 0, }, - { - name: "OneDeprecatedConfigPurpose", - givenAccountIDs: []string{"gdpr_deprecated_purpose1"}, - givenMetrics: []string{"RecordAccountGDPRPurposeWarning"}, - expectedMetricCount: 1, - }, { name: "OneDeprecatedConfigGDPRChannelEnabled", givenAccountIDs: []string{"gdpr_channel_enabled_acct"}, @@ -568,8 +300,8 @@ func TestAccountUpgradeStatusGetAccount(t *testing.T) { }, { name: "MultipleAccountsWithDeprecatedConfigs", - givenAccountIDs: []string{"gdpr_channel_enabled_acct", "gdpr_deprecated_purpose1"}, - givenMetrics: []string{"RecordAccountGDPRChannelEnabledWarning", "RecordAccountGDPRPurposeWarning"}, + givenAccountIDs: []string{"gdpr_channel_enabled_acct", "ccpa_channel_enabled_acct"}, + givenMetrics: []string{"RecordAccountGDPRChannelEnabledWarning", "RecordAccountCCPAChannelEnabledWarning"}, expectedMetricCount: 2, }, } diff --git a/metrics/config/metrics.go b/metrics/config/metrics.go index bf173253e56..757cde336b2 100644 --- a/metrics/config/metrics.go +++ b/metrics/config/metrics.go @@ -322,11 +322,6 @@ func (me *MultiMetricsEngine) RecordBidValidationSecureMarkupWarn(adapter openrt } } -func (me *MultiMetricsEngine) RecordAccountGDPRPurposeWarning(account string, purposeName string) { - for _, thisME := range *me { - thisME.RecordAccountGDPRPurposeWarning(account, purposeName) - } -} func (me *MultiMetricsEngine) RecordAccountGDPRChannelEnabledWarning(account string) { for _, thisME := range *me { thisME.RecordAccountGDPRChannelEnabledWarning(account) @@ -536,9 +531,6 @@ func (me *NilMetricsEngine) RecordBidValidationSecureMarkupError(adapter openrtb func (me *NilMetricsEngine) RecordBidValidationSecureMarkupWarn(adapter openrtb_ext.BidderName, account string) { } -func (me *NilMetricsEngine) RecordAccountGDPRPurposeWarning(account string, purposeName string) { -} - func (me *NilMetricsEngine) RecordAccountGDPRChannelEnabledWarning(account string) { } diff --git a/metrics/go_metrics.go b/metrics/go_metrics.go index 382dc64c090..37080b05456 100644 --- a/metrics/go_metrics.go +++ b/metrics/go_metrics.go @@ -127,19 +127,9 @@ type accountMetrics struct { bidValidationSecureMarkupWarnMeter metrics.Meter // Account Deprciation Metrics - accountDeprecationWarningsPurpose1Meter metrics.Meter - accountDeprecationWarningsPurpose2Meter metrics.Meter - accountDeprecationWarningsPurpose3Meter metrics.Meter - accountDeprecationWarningsPurpose4Meter metrics.Meter - accountDeprecationWarningsPurpose5Meter metrics.Meter - accountDeprecationWarningsPurpose6Meter metrics.Meter - accountDeprecationWarningsPurpose7Meter metrics.Meter - accountDeprecationWarningsPurpose8Meter metrics.Meter - accountDeprecationWarningsPurpose9Meter metrics.Meter - accountDeprecationWarningsPurpose10Meter metrics.Meter - channelEnabledGDPRMeter metrics.Meter - channelEnabledCCPAMeter metrics.Meter - accountDeprecationSummaryMeter metrics.Meter + channelEnabledGDPRMeter metrics.Meter + channelEnabledCCPAMeter metrics.Meter + accountDeprecationSummaryMeter metrics.Meter } type ModuleMetrics struct { @@ -576,16 +566,6 @@ func (me *Metrics) getAccountMetrics(id string) *accountMetrics { am.bidValidationSecureMarkupMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.response.validation.secure.err", id), me.MetricsRegistry) am.bidValidationSecureMarkupWarnMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.response.validation.secure.warn", id), me.MetricsRegistry) - am.accountDeprecationWarningsPurpose1Meter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.config.gdpr.purpose1.warn", id), me.MetricsRegistry) - am.accountDeprecationWarningsPurpose2Meter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.config.gdpr.purpose2.warn", id), me.MetricsRegistry) - am.accountDeprecationWarningsPurpose3Meter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.config.gdpr.purpose3.warn", id), me.MetricsRegistry) - am.accountDeprecationWarningsPurpose4Meter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.config.gdpr.purpose4.warn", id), me.MetricsRegistry) - am.accountDeprecationWarningsPurpose5Meter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.config.gdpr.purpose5.warn", id), me.MetricsRegistry) - am.accountDeprecationWarningsPurpose6Meter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.config.gdpr.purpose6.warn", id), me.MetricsRegistry) - am.accountDeprecationWarningsPurpose7Meter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.config.gdpr.purpose7.warn", id), me.MetricsRegistry) - am.accountDeprecationWarningsPurpose8Meter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.config.gdpr.purpose8.warn", id), me.MetricsRegistry) - am.accountDeprecationWarningsPurpose9Meter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.config.gdpr.purpose9.warn", id), me.MetricsRegistry) - am.accountDeprecationWarningsPurpose10Meter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.config.gdpr.purpose10.warn", id), me.MetricsRegistry) am.channelEnabledCCPAMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.config.ccpa.channel_enabled.warn", id), me.MetricsRegistry) am.channelEnabledGDPRMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.config.gdpr.channel_enabled.warn", id), me.MetricsRegistry) am.accountDeprecationSummaryMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.config.summary", id), me.MetricsRegistry) @@ -635,34 +615,6 @@ func (me *Metrics) RecordDebugRequest(debugEnabled bool, pubID string) { } } -func (me *Metrics) RecordAccountGDPRPurposeWarning(account string, purposeName string) { - if account != PublisherUnknown { - am := me.getAccountMetrics(account) - switch purposeName { - case "purpose1": - am.accountDeprecationWarningsPurpose1Meter.Mark(1) - case "purpose2": - am.accountDeprecationWarningsPurpose2Meter.Mark(1) - case "purpose3": - am.accountDeprecationWarningsPurpose3Meter.Mark(1) - case "purpose4": - am.accountDeprecationWarningsPurpose4Meter.Mark(1) - case "purpose5": - am.accountDeprecationWarningsPurpose5Meter.Mark(1) - case "purpose6": - am.accountDeprecationWarningsPurpose6Meter.Mark(1) - case "purpose7": - am.accountDeprecationWarningsPurpose7Meter.Mark(1) - case "purpose8": - am.accountDeprecationWarningsPurpose8Meter.Mark(1) - case "purpose9": - am.accountDeprecationWarningsPurpose9Meter.Mark(1) - case "purpose10": - am.accountDeprecationWarningsPurpose10Meter.Mark(1) - } - } -} - func (me *Metrics) RecordAccountGDPRChannelEnabledWarning(account string) { if account != PublisherUnknown { am := me.getAccountMetrics(account) diff --git a/metrics/go_metrics_test.go b/metrics/go_metrics_test.go index 515691fe503..3564f9fa2a5 100644 --- a/metrics/go_metrics_test.go +++ b/metrics/go_metrics_test.go @@ -1066,94 +1066,6 @@ func TestRecordModuleAccountMetrics(t *testing.T) { } } -func TestRecordAccountGDPRPurposeWarningMetrics(t *testing.T) { - testCases := []struct { - name string - givenPurposeName string - expectedP1MetricCount int64 - expectedP2MetricCount int64 - expectedP3MetricCount int64 - expectedP4MetricCount int64 - expectedP5MetricCount int64 - expectedP6MetricCount int64 - expectedP7MetricCount int64 - expectedP8MetricCount int64 - expectedP9MetricCount int64 - expectedP10MetricCount int64 - }{ - { - name: "Purpose1MetricIncremented", - givenPurposeName: "purpose1", - expectedP1MetricCount: 1, - }, - { - name: "Purpose2MetricIncremented", - givenPurposeName: "purpose2", - expectedP2MetricCount: 1, - }, - { - name: "Purpose3MetricIncremented", - givenPurposeName: "purpose3", - expectedP3MetricCount: 1, - }, - { - name: "Purpose4MetricIncremented", - givenPurposeName: "purpose4", - expectedP4MetricCount: 1, - }, - { - name: "Purpose5MetricIncremented", - givenPurposeName: "purpose5", - expectedP5MetricCount: 1, - }, - { - name: "Purpose6MetricIncremented", - givenPurposeName: "purpose6", - expectedP6MetricCount: 1, - }, - { - name: "Purpose7MetricIncremented", - givenPurposeName: "purpose7", - expectedP7MetricCount: 1, - }, - { - name: "Purpose8MetricIncremented", - givenPurposeName: "purpose8", - expectedP8MetricCount: 1, - }, - { - name: "Purpose9MetricIncremented", - givenPurposeName: "purpose9", - expectedP9MetricCount: 1, - }, - { - name: "Purpose10MetricIncremented", - givenPurposeName: "purpose10", - expectedP10MetricCount: 1, - }, - } - for _, test := range testCases { - t.Run(test.name, func(t *testing.T) { - registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus}, config.DisabledMetrics{}, nil, nil) - - m.RecordAccountGDPRPurposeWarning("acct-id", test.givenPurposeName) - am := m.getAccountMetrics("acct-id") - - assert.Equal(t, test.expectedP1MetricCount, am.accountDeprecationWarningsPurpose1Meter.Count()) - assert.Equal(t, test.expectedP2MetricCount, am.accountDeprecationWarningsPurpose2Meter.Count()) - assert.Equal(t, test.expectedP3MetricCount, am.accountDeprecationWarningsPurpose3Meter.Count()) - assert.Equal(t, test.expectedP4MetricCount, am.accountDeprecationWarningsPurpose4Meter.Count()) - assert.Equal(t, test.expectedP5MetricCount, am.accountDeprecationWarningsPurpose5Meter.Count()) - assert.Equal(t, test.expectedP6MetricCount, am.accountDeprecationWarningsPurpose6Meter.Count()) - assert.Equal(t, test.expectedP7MetricCount, am.accountDeprecationWarningsPurpose7Meter.Count()) - assert.Equal(t, test.expectedP8MetricCount, am.accountDeprecationWarningsPurpose8Meter.Count()) - assert.Equal(t, test.expectedP9MetricCount, am.accountDeprecationWarningsPurpose9Meter.Count()) - assert.Equal(t, test.expectedP10MetricCount, am.accountDeprecationWarningsPurpose10Meter.Count()) - }) - } -} - func TestRecordAccountGDPRChannelEnabledWarningMetrics(t *testing.T) { testCases := []struct { name string diff --git a/metrics/metrics.go b/metrics/metrics.go index a73019bed5e..7315fa72712 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -470,7 +470,6 @@ type MetricsEngine interface { RecordModuleSuccessRejected(labels ModuleLabels) RecordModuleExecutionError(labels ModuleLabels) RecordModuleTimeout(labels ModuleLabels) - RecordAccountGDPRPurposeWarning(account string, purposeName string) RecordAccountGDPRChannelEnabledWarning(account string) RecordAccountCCPAChannelEnabledWarning(account string) RecordAccountUpgradeStatus(account string) diff --git a/metrics/metrics_mock.go b/metrics/metrics_mock.go index a518b98d404..f6ecf57e37f 100644 --- a/metrics/metrics_mock.go +++ b/metrics/metrics_mock.go @@ -222,10 +222,6 @@ func (me *MetricsEngineMock) RecordModuleTimeout(labels ModuleLabels) { me.Called(labels) } -func (me *MetricsEngineMock) RecordAccountGDPRPurposeWarning(account string, purposeName string) { - me.Called(account, purposeName) -} - func (me *MetricsEngineMock) RecordAccountGDPRChannelEnabledWarning(account string) { me.Called(account) } diff --git a/metrics/prometheus/prometheus.go b/metrics/prometheus/prometheus.go index c57ba2214f6..363e5527fbc 100644 --- a/metrics/prometheus/prometheus.go +++ b/metrics/prometheus/prometheus.go @@ -89,19 +89,9 @@ type Metrics struct { accountBidResponseSecureMarkupWarn *prometheus.CounterVec // Account Deprecation Metrics - accountDeprecationWarningsPurpose1 prometheus.Counter - accountDeprecationWarningsPurpose2 prometheus.Counter - accountDeprecationWarningsPurpose3 prometheus.Counter - accountDeprecationWarningsPurpose4 prometheus.Counter - accountDeprecationWarningsPurpose5 prometheus.Counter - accountDeprecationWarningsPurpose6 prometheus.Counter - accountDeprecationWarningsPurpose7 prometheus.Counter - accountDeprecationWarningsPurpose8 prometheus.Counter - accountDeprecationWarningsPurpose9 prometheus.Counter - accountDeprecationWarningsPurpose10 prometheus.Counter - channelEnabledGDPR prometheus.Counter - channelEnabledCCPA prometheus.Counter - accountDeprecationSummary prometheus.Counter + channelEnabledGDPR prometheus.Counter + channelEnabledCCPA prometheus.Counter + accountDeprecationSummary prometheus.Counter // Module Metrics as a map where the key is the module name moduleDuration map[string]*prometheus.HistogramVec @@ -512,37 +502,6 @@ func NewMetrics(cfg config.PrometheusMetrics, disabledMetrics config.DisabledMet "Count of AdsCert request, and if they were successfully sent.", []string{successLabel}) - metrics.accountDeprecationWarningsPurpose1 = newCounterWithoutLabels(cfg, reg, - "account_config_gdpr_tcf2_purpose1_warn", - "Count of requests referencing an account whose config specifies a deprecated gdpr.tcf2.purpose1 field") - metrics.accountDeprecationWarningsPurpose2 = newCounterWithoutLabels(cfg, reg, - "account_config_gdpr_tcf2_purpose2_warn", - "Count of requests referencing an account whose config specifies a deprecated gdpr.tcf2.purpose2 field") - metrics.accountDeprecationWarningsPurpose3 = newCounterWithoutLabels(cfg, reg, - "account_config_gdpr_tcf2_purpose3_warn", - "Count of requests referencing an account whose config specifies a deprecated gdpr.tcf2.purpose3 field") - metrics.accountDeprecationWarningsPurpose4 = newCounterWithoutLabels(cfg, reg, - "account_config_gdpr_tcf2_purpose4_warn", - "Count of requests referencing an account whose config specifies a deprecated gdpr.tcf2.purpose4 field") - metrics.accountDeprecationWarningsPurpose5 = newCounterWithoutLabels(cfg, reg, - "account_config_gdpr_tcf2_purpose5_warn", - "Count of requests referencing an account whose config specifies a deprecated gdpr.tcf2.purpose5 field") - metrics.accountDeprecationWarningsPurpose6 = newCounterWithoutLabels(cfg, reg, - "account_config_gdpr_tcf2_purpose6_warn", - "Count of requests referencing an account whose config specifies a deprecated gdpr.tcf2.purpose6 field") - metrics.accountDeprecationWarningsPurpose7 = newCounterWithoutLabels(cfg, reg, - "account_config_gdpr_tcf2_purpose7_warn", - "Count of requests referencing an account whose config specifies a deprecated gdpr.tcf2.purpose7 field") - metrics.accountDeprecationWarningsPurpose8 = newCounterWithoutLabels(cfg, reg, - "account_config_gdpr_tcf2_purpose8_warn", - "Count of requests referencing an account whose config specifies a deprecated gdpr.tcf2.purpose8 field") - metrics.accountDeprecationWarningsPurpose9 = newCounterWithoutLabels(cfg, reg, - "account_config_gdpr_tcf2_purpose9_warn", - "Count of requests referencing an account whose config specifies a deprecated gdpr.tcf2.purpose9 field") - metrics.accountDeprecationWarningsPurpose10 = newCounterWithoutLabels(cfg, reg, - "account_config_gdpr_tcf2_purpose10_warn", - "Count of requests referencing an account whose config specifies a deprecated gdpr.tcf2.purpose10 field") - metrics.channelEnabledCCPA = newCounterWithoutLabels(cfg, reg, "account_config_ccpa_channel_enabled_warn", "Count of requests referencing an account whose config specifies a depreceated ccpa.channel_enabled field") @@ -734,33 +693,6 @@ func (m *Metrics) RecordDebugRequest(debugEnabled bool, pubID string) { } } -func (m *Metrics) RecordAccountGDPRPurposeWarning(account string, purposeName string) { - if account != metrics.PublisherUnknown { - switch purposeName { - case "purpose1": - m.accountDeprecationWarningsPurpose1.Inc() - case "purpose2": - m.accountDeprecationWarningsPurpose2.Inc() - case "purpose3": - m.accountDeprecationWarningsPurpose3.Inc() - case "purpose4": - m.accountDeprecationWarningsPurpose4.Inc() - case "purpose5": - m.accountDeprecationWarningsPurpose5.Inc() - case "purpose6": - m.accountDeprecationWarningsPurpose6.Inc() - case "purpose7": - m.accountDeprecationWarningsPurpose7.Inc() - case "purpose8": - m.accountDeprecationWarningsPurpose8.Inc() - case "purpose9": - m.accountDeprecationWarningsPurpose9.Inc() - case "purpose10": - m.accountDeprecationWarningsPurpose10.Inc() - } - } -} - func (m *Metrics) RecordAccountGDPRChannelEnabledWarning(account string) { if account != metrics.PublisherUnknown { m.channelEnabledGDPR.Inc() diff --git a/metrics/prometheus/prometheus_test.go b/metrics/prometheus/prometheus_test.go index 32f7848ccff..90d331fe5ae 100644 --- a/metrics/prometheus/prometheus_test.go +++ b/metrics/prometheus/prometheus_test.go @@ -1977,91 +1977,6 @@ func TestRecordModuleMetrics(t *testing.T) { } } -func TestRecordAccountGDPRPurposeWarningMetrics(t *testing.T) { - testCases := []struct { - name string - givenPurposeName string - expectedP1MetricCount float64 - expectedP2MetricCount float64 - expectedP3MetricCount float64 - expectedP4MetricCount float64 - expectedP5MetricCount float64 - expectedP6MetricCount float64 - expectedP7MetricCount float64 - expectedP8MetricCount float64 - expectedP9MetricCount float64 - expectedP10MetricCount float64 - }{ - { - name: "Purpose1MetricIncremented", - givenPurposeName: "purpose1", - expectedP1MetricCount: 1, - }, - { - name: "Purpose2MetricIncremented", - givenPurposeName: "purpose2", - expectedP2MetricCount: 1, - }, - { - name: "Purpose3MetricIncremented", - givenPurposeName: "purpose3", - expectedP3MetricCount: 1, - }, - { - name: "Purpose4MetricIncremented", - givenPurposeName: "purpose4", - expectedP4MetricCount: 1, - }, - { - name: "Purpose5MetricIncremented", - givenPurposeName: "purpose5", - expectedP5MetricCount: 1, - }, - { - name: "Purpose6MetricIncremented", - givenPurposeName: "purpose6", - expectedP6MetricCount: 1, - }, - { - name: "Purpose7MetricIncremented", - givenPurposeName: "purpose7", - expectedP7MetricCount: 1, - }, - { - name: "Purpose8MetricIncremented", - givenPurposeName: "purpose8", - expectedP8MetricCount: 1, - }, - { - name: "Purpose9MetricIncremented", - givenPurposeName: "purpose9", - expectedP9MetricCount: 1, - }, - { - name: "Purpose10MetricIncremented", - givenPurposeName: "purpose10", - expectedP10MetricCount: 1, - }, - } - for _, test := range testCases { - t.Run(test.name, func(t *testing.T) { - m := createMetricsForTesting() - m.RecordAccountGDPRPurposeWarning("acct-id", test.givenPurposeName) - - assertCounterValue(t, "", "Account Deprecation Warnings", m.accountDeprecationWarningsPurpose1, test.expectedP1MetricCount) - assertCounterValue(t, "", "Account Deprecation Warnings", m.accountDeprecationWarningsPurpose2, test.expectedP2MetricCount) - assertCounterValue(t, "", "Account Deprecation Warnings", m.accountDeprecationWarningsPurpose3, test.expectedP3MetricCount) - assertCounterValue(t, "", "Account Deprecation Warnings", m.accountDeprecationWarningsPurpose4, test.expectedP4MetricCount) - assertCounterValue(t, "", "Account Deprecation Warnings", m.accountDeprecationWarningsPurpose5, test.expectedP5MetricCount) - assertCounterValue(t, "", "Account Deprecation Warnings", m.accountDeprecationWarningsPurpose6, test.expectedP6MetricCount) - assertCounterValue(t, "", "Account Deprecation Warnings", m.accountDeprecationWarningsPurpose7, test.expectedP7MetricCount) - assertCounterValue(t, "", "Account Deprecation Warnings", m.accountDeprecationWarningsPurpose8, test.expectedP8MetricCount) - assertCounterValue(t, "", "Account Deprecation Warnings", m.accountDeprecationWarningsPurpose9, test.expectedP9MetricCount) - assertCounterValue(t, "", "Account Deprecation Warnings", m.accountDeprecationWarningsPurpose10, test.expectedP10MetricCount) - }) - } -} - func TestRecordAccountGDPRChannelEnabledWarningMetrics(t *testing.T) { testCases := []struct { name string From 13607862cf00ca1a721067772315368eada972ce Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Mon, 2 Oct 2023 16:38:57 -0400 Subject: [PATCH 153/268] Remove Deprecated Config: Account Blacklist (#3156) --- account/account.go | 11 +-- account/account_test.go | 22 ++--- config/config.go | 10 -- endpoints/cookie_sync.go | 2 +- endpoints/cookie_sync_test.go | 4 +- endpoints/events/account_test.go | 78 ++++++---------- endpoints/events/event.go | 2 +- endpoints/events/event_test.go | 12 +-- endpoints/openrtb2/amp_auction.go | 4 +- endpoints/openrtb2/amp_auction_test.go | 15 +-- endpoints/openrtb2/auction.go | 4 +- endpoints/openrtb2/auction_benchmark_test.go | 10 +- endpoints/openrtb2/auction_test.go | 4 +- .../required-blacklisted-acct.json | 91 ------------------- .../with-account/required-disabled-acct.json} | 8 +- .../blacklisted-site-publisher.json | 90 ------------------ endpoints/openrtb2/test_utils.go | 19 +--- endpoints/openrtb2/video_auction.go | 21 ++--- endpoints/openrtb2/video_auction_test.go | 40 +------- endpoints/setuid_test.go | 24 ----- errortypes/code.go | 2 +- errortypes/errortypes.go | 15 ++- 22 files changed, 81 insertions(+), 407 deletions(-) delete mode 100644 endpoints/openrtb2/sample-requests/account-required/with-account/required-blacklisted-acct.json rename endpoints/openrtb2/sample-requests/{blacklisted/blacklisted-app-publisher.json => account-required/with-account/required-disabled-acct.json} (86%) delete mode 100644 endpoints/openrtb2/sample-requests/blacklisted/blacklisted-site-publisher.json diff --git a/account/account.go b/account/account.go index 7b5f9435a11..70527d0f6ee 100644 --- a/account/account.go +++ b/account/account.go @@ -4,7 +4,9 @@ import ( "context" "encoding/json" "fmt" + "github.com/prebid/go-gdpr/consentconstants" + "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/metrics" @@ -15,17 +17,12 @@ import ( // GetAccount looks up the config.Account object referenced by the given accountID, with access rules applied func GetAccount(ctx context.Context, cfg *config.Configuration, fetcher stored_requests.AccountFetcher, accountID string, me metrics.MetricsEngine) (account *config.Account, errs []error) { - // Check BlacklistedAcctMap until we have deprecated it - if _, found := cfg.BlacklistedAcctMap[accountID]; found { - return nil, []error{&errortypes.BlacklistedAcct{ - Message: fmt.Sprintf("Prebid-server has disabled Account ID: %s, please reach out to the prebid server host.", accountID), - }} - } if cfg.AccountRequired && accountID == metrics.PublisherUnknown { return nil, []error{&errortypes.AcctRequired{ Message: fmt.Sprintf("Prebid-server has been configured to discard requests without a valid Account ID. Please reach out to the prebid server host."), }} } + if accountJSON, accErrs := fetcher.FetchAccount(ctx, cfg.AccountDefaultsJSON(), accountID); len(accErrs) > 0 || accountJSON == nil { // accountID does not reference a valid account for _, e := range accErrs { @@ -79,7 +76,7 @@ func GetAccount(ctx context.Context, cfg *config.Configuration, fetcher stored_r setDerivedConfig(account) } if account.Disabled { - errs = append(errs, &errortypes.BlacklistedAcct{ + errs = append(errs, &errortypes.AccountDisabled{ Message: fmt.Sprintf("Prebid-server has disabled Account ID: %s, please reach out to the prebid server host.", accountID), }) return nil, errs diff --git a/account/account_test.go b/account/account_test.go index d5223f76119..da0457f8d47 100644 --- a/account/account_test.go +++ b/account/account_test.go @@ -48,19 +48,16 @@ func TestGetAccount(t *testing.T) { // expected error, or nil if account should be found err error }{ - // Blacklisted account is always rejected even in permissive setup - {accountID: "bad_acct", required: false, disabled: false, err: &errortypes.BlacklistedAcct{}}, - // empty pubID {accountID: unknown, required: false, disabled: false, err: nil}, {accountID: unknown, required: true, disabled: false, err: &errortypes.AcctRequired{}}, - {accountID: unknown, required: false, disabled: true, err: &errortypes.BlacklistedAcct{}}, + {accountID: unknown, required: false, disabled: true, err: &errortypes.AccountDisabled{}}, {accountID: unknown, required: true, disabled: true, err: &errortypes.AcctRequired{}}, // pubID given but is not a valid host account (does not exist) {accountID: "doesnt_exist_acct", required: false, disabled: false, err: nil}, {accountID: "doesnt_exist_acct", required: true, disabled: false, err: nil}, - {accountID: "doesnt_exist_acct", required: false, disabled: true, err: &errortypes.BlacklistedAcct{}}, + {accountID: "doesnt_exist_acct", required: false, disabled: true, err: &errortypes.AccountDisabled{}}, {accountID: "doesnt_exist_acct", required: true, disabled: true, err: &errortypes.AcctRequired{}}, // pubID given and matches a valid host account with Disabled: false @@ -72,10 +69,10 @@ func TestGetAccount(t *testing.T) { {accountID: "invalid_acct_ipv6_ipv4", required: true, disabled: false, err: nil, checkDefaultIP: true}, // pubID given and matches a host account explicitly disabled (Disabled: true on account json) - {accountID: "disabled_acct", required: false, disabled: false, err: &errortypes.BlacklistedAcct{}}, - {accountID: "disabled_acct", required: true, disabled: false, err: &errortypes.BlacklistedAcct{}}, - {accountID: "disabled_acct", required: false, disabled: true, err: &errortypes.BlacklistedAcct{}}, - {accountID: "disabled_acct", required: true, disabled: true, err: &errortypes.BlacklistedAcct{}}, + {accountID: "disabled_acct", required: false, disabled: false, err: &errortypes.AccountDisabled{}}, + {accountID: "disabled_acct", required: true, disabled: false, err: &errortypes.AccountDisabled{}}, + {accountID: "disabled_acct", required: false, disabled: true, err: &errortypes.AccountDisabled{}}, + {accountID: "disabled_acct", required: true, disabled: true, err: &errortypes.AccountDisabled{}}, // pubID given and matches a host account that has a malformed config {accountID: "malformed_acct", required: false, disabled: false, err: &errortypes.MalformedAcct{}}, @@ -86,7 +83,7 @@ func TestGetAccount(t *testing.T) { // account not provided (does not exist) {accountID: "", required: false, disabled: false, err: nil}, {accountID: "", required: true, disabled: false, err: nil}, - {accountID: "", required: false, disabled: true, err: &errortypes.BlacklistedAcct{}}, + {accountID: "", required: false, disabled: true, err: &errortypes.AccountDisabled{}}, {accountID: "", required: true, disabled: true, err: &errortypes.AcctRequired{}}, } @@ -94,9 +91,8 @@ func TestGetAccount(t *testing.T) { description := fmt.Sprintf(`ID=%s/required=%t/disabled=%t`, test.accountID, test.required, test.disabled) t.Run(description, func(t *testing.T) { cfg := &config.Configuration{ - BlacklistedAcctMap: map[string]bool{"bad_acct": true}, - AccountRequired: test.required, - AccountDefaults: config.Account{Disabled: test.disabled}, + AccountRequired: test.required, + AccountDefaults: config.Account{Disabled: test.disabled}, } fetcher := &mockAccountFetcher{} assert.NoError(t, cfg.MarshalAccountDefaults()) diff --git a/config/config.go b/config/config.go index a8d276a15c2..cf3591dd564 100644 --- a/config/config.go +++ b/config/config.go @@ -67,9 +67,6 @@ type Configuration struct { // Array of blacklisted apps that is used to create the hash table BlacklistedAppMap so App.ID's can be instantly accessed. BlacklistedApps []string `mapstructure:"blacklisted_apps,flow"` BlacklistedAppMap map[string]bool - // Array of blacklisted accounts that is used to create the hash table BlacklistedAcctMap so Account.ID's can be instantly accessed. - BlacklistedAccts []string `mapstructure:"blacklisted_accts,flow"` - BlacklistedAcctMap map[string]bool // Is publisher/account ID required to be submitted in the OpenRTB2 request AccountRequired bool `mapstructure:"account_required"` // AccountDefaults defines default settings for valid accounts that are partially defined @@ -757,13 +754,6 @@ func New(v *viper.Viper, bidderInfos BidderInfos, normalizeBidderName func(strin c.BlacklistedAppMap[c.BlacklistedApps[i]] = true } - // To look for a request's account id in O(1) time, we fill this hash table located in the - // the BlacklistedAccts field of the Configuration struct defined in this file - c.BlacklistedAcctMap = make(map[string]bool) - for i := 0; i < len(c.BlacklistedAccts); i++ { - c.BlacklistedAcctMap[c.BlacklistedAccts[i]] = true - } - // Migrate combo stored request config to separate stored_reqs and amp stored_reqs configs. resolvedStoredRequestsConfig(&c) diff --git a/endpoints/cookie_sync.go b/endpoints/cookie_sync.go index 250d5fd07d3..bbee3847014 100644 --- a/endpoints/cookie_sync.go +++ b/endpoints/cookie_sync.go @@ -367,7 +367,7 @@ func combineErrors(errs []error) error { for _, err := range errs { // preserve knowledge of special account errors switch errortypes.ReadCode(err) { - case errortypes.BlacklistedAcctErrorCode: + case errortypes.AccountDisabledErrorCode: return errCookieSyncAccountBlocked case errortypes.AcctRequiredErrorCode: return errCookieSyncAccountInvalid diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go index 29fe74b273c..80de2b5ff50 100644 --- a/endpoints/cookie_sync_test.go +++ b/endpoints/cookie_sync_test.go @@ -1938,7 +1938,7 @@ func TestCombineErrors(t *testing.T) { }, { description: "Special Case: blocked (rejected via block list)", - givenErrorList: []error{&errortypes.BlacklistedAcct{}}, + givenErrorList: []error{&errortypes.AccountDisabled{}}, expectedError: errCookieSyncAccountBlocked, }, { @@ -1953,7 +1953,7 @@ func TestCombineErrors(t *testing.T) { }, { description: "Special Case: multiple special cases, first one wins", - givenErrorList: []error{&errortypes.BlacklistedAcct{}, &errortypes.AcctRequired{}, &errortypes.MalformedAcct{}}, + givenErrorList: []error{&errortypes.AccountDisabled{}, &errortypes.AcctRequired{}, &errortypes.MalformedAcct{}}, expectedError: errCookieSyncAccountBlocked, }, } diff --git a/endpoints/events/account_test.go b/endpoints/events/account_test.go index 7efb8af782b..8477b43b49b 100644 --- a/endpoints/events/account_test.go +++ b/endpoints/events/account_test.go @@ -2,7 +2,6 @@ package events import ( "errors" - "fmt" "io" "net/http" "net/http/httptest" @@ -15,19 +14,18 @@ import ( "github.com/prebid/prebid-server/metrics" "github.com/prebid/prebid-server/stored_requests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestHandleAccountServiceErrors(t *testing.T) { tests := map[string]struct { - fetcher *mockAccountsFetcher - cfg *config.Configuration - accountID string - want struct { - code int - response string - } + fetcher *mockAccountsFetcher + cfg *config.Configuration + accountID string + wantCode int + wantResponse string }{ - "badRequest": { + "bad-request": { fetcher: &mockAccountsFetcher{ Fail: true, Error: errors.New("some error"), @@ -40,16 +38,11 @@ func TestHandleAccountServiceErrors(t *testing.T) { TimeoutMS: int64(2000), AllowUnknownBidder: false, }, }, - accountID: "testacc", - want: struct { - code int - response string - }{ - code: 400, - response: "Invalid request: some error\nInvalid request: Prebid-server could not verify the Account ID. Please reach out to the prebid server host.\n", - }, + accountID: "testacc", + wantCode: 400, + wantResponse: "Invalid request: some error\nInvalid request: Prebid-server could not verify the Account ID. Please reach out to the prebid server host.\n", }, - "malformedAccountConfig": { + "malformed-account-config": { fetcher: &mockAccountsFetcher{ Fail: true, Error: &errortypes.MalformedAcct{}, @@ -60,34 +53,25 @@ func TestHandleAccountServiceErrors(t *testing.T) { TimeoutMS: int64(2000), AllowUnknownBidder: false, }, }, - accountID: "malformed_acct", - want: struct { - code int - response string - }{ - code: 500, - response: "Invalid request: The prebid-server account config for account id \"malformed_acct\" is malformed. Please reach out to the prebid server host.\n", - }, + accountID: "malformed_acct", + wantCode: 500, + wantResponse: "Invalid request: The prebid-server account config for account id \"malformed_acct\" is malformed. Please reach out to the prebid server host.\n", }, - "serviceUnavailable": { + "service-unavailable": { fetcher: &mockAccountsFetcher{ Fail: false, }, cfg: &config.Configuration{ - BlacklistedAcctMap: map[string]bool{"testacc": true}, - MaxRequestSize: maxSize, + AccountDefaults: config.Account{}, + AccountRequired: true, + MaxRequestSize: maxSize, VTrack: config.VTrack{ TimeoutMS: int64(2000), AllowUnknownBidder: false, }, }, - accountID: "testacc", - want: struct { - code int - response string - }{ - code: 503, - response: "Invalid request: Prebid-server has disabled Account ID: testacc, please reach out to the prebid server host.\n", - }, + accountID: "disabled_acct", + wantCode: 503, + wantResponse: "Invalid request: Prebid-server has disabled Account ID: disabled_acct, please reach out to the prebid server host.\n", }, "timeout": { fetcher: &mockAccountsFetcher{ @@ -106,19 +90,13 @@ func TestHandleAccountServiceErrors(t *testing.T) { AllowUnknownBidder: false, }, }, - accountID: "testacc", - want: struct { - code int - response string - }{ - code: 504, - response: "Invalid request: context deadline exceeded\nInvalid request: Prebid-server could not verify the Account ID. Please reach out to the prebid server host.\n", - }, + accountID: "testacc", + wantCode: 504, + wantResponse: "Invalid request: context deadline exceeded\nInvalid request: Prebid-server could not verify the Account ID. Please reach out to the prebid server host.\n", }, } for name, test := range tests { - handlers := []struct { name string h httprouter.Handle @@ -137,13 +115,11 @@ func TestHandleAccountServiceErrors(t *testing.T) { // execute handler.h(recorder, handler.r, nil) d, err := io.ReadAll(recorder.Result().Body) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) // validate - assert.Equal(t, test.want.code, recorder.Result().StatusCode, fmt.Sprintf("Expected %d", test.want.code)) - assert.Equal(t, test.want.response, string(d)) + assert.Equal(t, test.wantCode, recorder.Result().StatusCode) + assert.Equal(t, test.wantResponse, string(d)) }) } } diff --git a/endpoints/events/event.go b/endpoints/events/event.go index e8084f1b273..7f923eda09d 100644 --- a/endpoints/events/event.go +++ b/endpoints/events/event.go @@ -206,7 +206,7 @@ func HandleAccountServiceErrors(errs []error) (status int, messages []string) { errCode := errortypes.ReadCode(er) - if errCode == errortypes.BlacklistedAppErrorCode || errCode == errortypes.BlacklistedAcctErrorCode { + if errCode == errortypes.BlacklistedAppErrorCode || errCode == errortypes.AccountDisabledErrorCode { status = http.StatusServiceUnavailable } if errCode == errortypes.MalformedAcctErrorCode { diff --git a/endpoints/events/event_test.go b/endpoints/events/event_test.go index 95711ba1328..7f129634221 100644 --- a/endpoints/events/event_test.go +++ b/endpoints/events/event_test.go @@ -20,7 +20,6 @@ import ( "github.com/stretchr/testify/assert" ) -// Mock Analytics Module type eventsMockAnalyticsModule struct { Fail bool Error error @@ -31,35 +30,30 @@ func (e *eventsMockAnalyticsModule) LogAuctionObject(ao *analytics.AuctionObject if e.Fail { panic(e.Error) } - return } func (e *eventsMockAnalyticsModule) LogVideoObject(vo *analytics.VideoObject) { if e.Fail { panic(e.Error) } - return } func (e *eventsMockAnalyticsModule) LogCookieSyncObject(cso *analytics.CookieSyncObject) { if e.Fail { panic(e.Error) } - return } func (e *eventsMockAnalyticsModule) LogSetUIDObject(so *analytics.SetUIDObject) { if e.Fail { panic(e.Error) } - return } func (e *eventsMockAnalyticsModule) LogAmpObject(ao *analytics.AmpObject) { if e.Fail { panic(e.Error) } - return } func (e *eventsMockAnalyticsModule) LogNotificationEventObject(ne *analytics.NotificationEvent) { @@ -67,15 +61,13 @@ func (e *eventsMockAnalyticsModule) LogNotificationEventObject(ne *analytics.Not panic(e.Error) } e.Invoked = true - - return } -// Mock Account fetcher var mockAccountData = map[string]json.RawMessage{ "events_enabled": json.RawMessage(`{"events": {"enabled":true}}`), "events_disabled": json.RawMessage(`{"events": {"enabled":false}}`), "malformed_acct": json.RawMessage(`{"events": {"enabled":"invalid type"}}`), + "disabled_acct": json.RawMessage(`{"disabled": true}`), } type mockAccountsFetcher struct { @@ -102,7 +94,7 @@ func (maf mockAccountsFetcher) FetchAccount(ctx context.Context, defaultAccountJ return nil, []error{maf.Error} } - return nil, []error{stored_requests.NotFoundError{accountID, "Account"}} + return nil, []error{stored_requests.NotFoundError{ID: accountID, DataType: "Account"}} } // Tests diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index 2879610d8e4..aa80d0756c3 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -77,7 +77,7 @@ func NewAmpEndpoint( return nil, errors.New("NewAmpEndpoint requires non-nil arguments.") } - defRequest := defReqJSON != nil && len(defReqJSON) > 0 + defRequest := len(defReqJSON) > 0 ipValidator := iputil.PublicNetworkIPValidator{ IPv4PrivateNetworks: cfg.RequestValidation.IPv4PrivateNetworksParsed, @@ -208,7 +208,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h metricsStatus := metrics.RequestStatusBadInput for _, er := range errL { errCode := errortypes.ReadCode(er) - if errCode == errortypes.BlacklistedAppErrorCode || errCode == errortypes.BlacklistedAcctErrorCode { + if errCode == errortypes.BlacklistedAppErrorCode || errCode == errortypes.AccountDisabledErrorCode { httpStatus = http.StatusServiceUnavailable metricsStatus = metrics.RequestStatusBlacklisted break diff --git a/endpoints/openrtb2/amp_auction_test.go b/endpoints/openrtb2/amp_auction_test.go index 87033f71b64..89d9c472925 100644 --- a/endpoints/openrtb2/amp_auction_test.go +++ b/endpoints/openrtb2/amp_auction_test.go @@ -98,8 +98,6 @@ func TestGoodAmpRequests(t *testing.T) { if test.Config != nil { cfg.BlacklistedApps = test.Config.BlacklistedApps cfg.BlacklistedAppMap = test.Config.getBlacklistedAppMap() - cfg.BlacklistedAccts = test.Config.BlacklistedAccounts - cfg.BlacklistedAcctMap = test.Config.getBlackListedAccountMap() cfg.AccountRequired = test.Config.AccountRequired } @@ -121,7 +119,7 @@ func TestGoodAmpRequests(t *testing.T) { // Assertions if assert.Equal(t, test.ExpectedReturnCode, recorder.Code, "Expected status %d. Got %d. Amp test file: %s", http.StatusOK, recorder.Code, filename) { if test.ExpectedReturnCode == http.StatusOK { - assert.JSONEq(t, string(test.ExpectedAmpResponse), string(recorder.Body.Bytes()), "Not the expected response. Test file: %s", filename) + assert.JSONEq(t, string(test.ExpectedAmpResponse), recorder.Body.String(), "Not the expected response. Test file: %s", filename) } else { assert.Equal(t, test.ExpectedErrorMessage, recorder.Body.String(), filename) } @@ -148,11 +146,6 @@ func TestAccountErrors(t *testing.T) { storedReqID: "1", filename: "account-malformed/malformed-acct.json", }, - { - description: "Blocked account", - storedReqID: "1", - filename: "blacklisted/blacklisted-site-publisher.json", - }, } for _, tt := range tests { @@ -169,9 +162,7 @@ func TestAccountErrors(t *testing.T) { test.endpointType = AMP_ENDPOINT cfg := &config.Configuration{ - BlacklistedAccts: []string{"bad_acct"}, - BlacklistedAcctMap: map[string]bool{"bad_acct": true}, - MaxRequestSize: maxSize, + MaxRequestSize: maxSize, } cfg.MarshalAccountDefaults() @@ -2328,7 +2319,7 @@ func TestSendAmpResponse_LogsErrors(t *testing.T) { account := &config.Account{DebugAllow: true} reqWrapper := openrtb_ext.RequestWrapper{BidRequest: test.request} - labels, ao = sendAmpResponse(test.writer, test.hookExecutor, &exchange.AuctionResponse{BidResponse: test.response}, &reqWrapper, account, labels, ao, nil) + _, ao = sendAmpResponse(test.writer, test.hookExecutor, &exchange.AuctionResponse{BidResponse: test.response}, &reqWrapper, account, labels, ao, nil) assert.Equal(t, ao.Errors, test.expectedErrors, "Invalid errors.") assert.Equal(t, test.expectedStatus, ao.Status, "Invalid HTTP response status.") diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 810741982ef..b625c0ff54c 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -101,7 +101,7 @@ func NewEndpoint( return nil, errors.New("NewEndpoint requires non-nil arguments.") } - defRequest := defReqJSON != nil && len(defReqJSON) > 0 + defRequest := len(defReqJSON) > 0 ipValidator := iputil.PublicNetworkIPValidator{ IPv4PrivateNetworks: cfg.RequestValidation.IPv4PrivateNetworksParsed, @@ -2349,7 +2349,7 @@ func writeError(errs []error, w http.ResponseWriter, labels *metrics.Labels) boo metricsStatus := metrics.RequestStatusBadInput for _, err := range errs { erVal := errortypes.ReadCode(err) - if erVal == errortypes.BlacklistedAppErrorCode || erVal == errortypes.BlacklistedAcctErrorCode { + if erVal == errortypes.BlacklistedAppErrorCode || erVal == errortypes.AccountDisabledErrorCode { httpStatus = http.StatusServiceUnavailable metricsStatus = metrics.RequestStatusBlacklisted break diff --git a/endpoints/openrtb2/auction_benchmark_test.go b/endpoints/openrtb2/auction_benchmark_test.go index a3c19ee0b10..ee74548ea47 100644 --- a/endpoints/openrtb2/auction_benchmark_test.go +++ b/endpoints/openrtb2/auction_benchmark_test.go @@ -147,12 +147,10 @@ func BenchmarkValidWholeExemplary(b *testing.B) { test.endpointType = OPENRTB_ENDPOINT cfg := &config.Configuration{ - MaxRequestSize: maxSize, - BlacklistedApps: test.Config.BlacklistedApps, - BlacklistedAppMap: test.Config.getBlacklistedAppMap(), - BlacklistedAccts: test.Config.BlacklistedAccounts, - BlacklistedAcctMap: test.Config.getBlackListedAccountMap(), - AccountRequired: test.Config.AccountRequired, + MaxRequestSize: maxSize, + BlacklistedApps: test.Config.BlacklistedApps, + BlacklistedAppMap: test.Config.getBlacklistedAppMap(), + AccountRequired: test.Config.AccountRequired, } auctionEndpointHandler, _, mockBidServers, mockCurrencyRatesServer, err := buildTestEndpoint(test, cfg) diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index c071d6b0950..b5631c93d3d 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -160,8 +160,6 @@ func runJsonBasedTest(t *testing.T, filename, desc string) { if test.Config != nil { cfg.BlacklistedApps = test.Config.BlacklistedApps cfg.BlacklistedAppMap = test.Config.getBlacklistedAppMap() - cfg.BlacklistedAccts = test.Config.BlacklistedAccounts - cfg.BlacklistedAcctMap = test.Config.getBlackListedAccountMap() cfg.AccountRequired = test.Config.AccountRequired } cfg.MarshalAccountDefaults() @@ -5803,7 +5801,7 @@ func TestSendAuctionResponse_LogsErrors(t *testing.T) { ao := analytics.AuctionObject{} account := &config.Account{DebugAllow: true} - labels, ao = sendAuctionResponse(writer, test.hookExecutor, test.response, test.request, account, labels, ao) + _, ao = sendAuctionResponse(writer, test.hookExecutor, test.response, test.request, account, labels, ao) assert.Equal(t, ao.Errors, test.expectedErrors, "Invalid errors.") assert.Equal(t, test.expectedStatus, ao.Status, "Invalid HTTP response status.") diff --git a/endpoints/openrtb2/sample-requests/account-required/with-account/required-blacklisted-acct.json b/endpoints/openrtb2/sample-requests/account-required/with-account/required-blacklisted-acct.json deleted file mode 100644 index 894a92fdb27..00000000000 --- a/endpoints/openrtb2/sample-requests/account-required/with-account/required-blacklisted-acct.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "description": "Account is required but request comes with a blacklisted account id", - "config": { - "accountRequired": true, - "blacklistedAccts": ["bad_acct"] - }, - "mockBidRequest": { - "id": "some-request-id", - "user": { - "ext": { - "consent": "gdpr-consent-string", - "prebid": { - "buyeruids": { - "appnexus": "override-appnexus-id-in-cookie" - } - } - } - }, - "app": { - "id": "cool_app", - "publisher": { - "id": "bad_acct" - } - }, - "regs": { - "ext": { - "gdpr": 1 - } - }, - "imp": [ - { - "id": "some-impression-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "ext": { - "appnexus": { - "placementId": 12883451 - }, - "districtm": { - "placementId": 105 - }, - "rubicon": { - "accountId": 1001, - "siteId": 113932, - "zoneId": 535510 - } - } - } - ], - "tmax": 500, - "ext": { - "prebid": { - "aliases": { - "districtm": "appnexus" - }, - "bidadjustmentfactors": { - "appnexus": 1.01, - "districtm": 0.98, - "rubicon": 0.99 - }, - "cache": { - "bids": {} - }, - "targeting": { - "includewinners": false, - "pricegranularity": { - "precision": 2, - "ranges": [ - { - "max": 20, - "increment": 0.10 - } - ] - } - } - } - } - }, - "expectedReturnCode": 503, - "expectedErrorMessage": "Invalid request: Prebid-server has disabled Account ID: bad_acct, please reach out to the prebid server host.\n" -} diff --git a/endpoints/openrtb2/sample-requests/blacklisted/blacklisted-app-publisher.json b/endpoints/openrtb2/sample-requests/account-required/with-account/required-disabled-acct.json similarity index 86% rename from endpoints/openrtb2/sample-requests/blacklisted/blacklisted-app-publisher.json rename to endpoints/openrtb2/sample-requests/account-required/with-account/required-disabled-acct.json index ef7a93b8bad..31a0021b7c1 100644 --- a/endpoints/openrtb2/sample-requests/blacklisted/blacklisted-app-publisher.json +++ b/endpoints/openrtb2/sample-requests/account-required/with-account/required-disabled-acct.json @@ -1,7 +1,7 @@ { - "description": "This is a perfectly valid request except that it comes with a blacklisted app publisher account", + "description": "Account is required but request comes with a disabled account id", "config": { - "blacklistedAccts": ["bad_acct"] + "accountRequired": true }, "mockBidRequest": { "id": "some-request-id", @@ -18,7 +18,7 @@ "app": { "id": "cool_app", "publisher": { - "id": "bad_acct" + "id": "disabled_acct" } }, "regs": { @@ -86,5 +86,5 @@ } }, "expectedReturnCode": 503, - "expectedErrorMessage": "Invalid request: Prebid-server has disabled Account ID: bad_acct, please reach out to the prebid server host.\n" + "expectedErrorMessage": "Invalid request: Prebid-server has disabled Account ID: disabled_acct, please reach out to the prebid server host.\n" } diff --git a/endpoints/openrtb2/sample-requests/blacklisted/blacklisted-site-publisher.json b/endpoints/openrtb2/sample-requests/blacklisted/blacklisted-site-publisher.json deleted file mode 100644 index cdec20d22ba..00000000000 --- a/endpoints/openrtb2/sample-requests/blacklisted/blacklisted-site-publisher.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "description": "This is a perfectly valid request except that it comes with a blacklisted site publisher account", - "config": { - "blacklistedAccts": ["bad_acct"] - }, - "mockBidRequest": { - "id": "some-request-id", - "user": { - "ext": { - "consent": "gdpr-consent-string", - "prebid": { - "buyeruids": { - "appnexus": "override-appnexus-id-in-cookie" - } - } - } - }, - "site": { - "id": "cool_site", - "publisher": { - "id": "bad_acct" - } - }, - "regs": { - "ext": { - "gdpr": 1 - } - }, - "imp": [ - { - "id": "some-impression-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "ext": { - "appnexus": { - "placementId": 12883451 - }, - "districtm": { - "placementId": 105 - }, - "rubicon": { - "accountId": 1001, - "siteId": 113932, - "zoneId": 535510 - } - } - } - ], - "tmax": 500, - "ext": { - "prebid": { - "aliases": { - "districtm": "appnexus" - }, - "bidadjustmentfactors": { - "appnexus": 1.01, - "districtm": 0.98, - "rubicon": 0.99 - }, - "cache": { - "bids": {} - }, - "targeting": { - "includewinners": false, - "pricegranularity": { - "precision": 2, - "ranges": [ - { - "max": 20, - "increment": 0.10 - } - ] - } - } - } - } - }, - "expectedReturnCode": 503, - "expectedErrorMessage": "Invalid request: Prebid-server has disabled Account ID: bad_acct, please reach out to the prebid server host.\n" -} diff --git a/endpoints/openrtb2/test_utils.go b/endpoints/openrtb2/test_utils.go index 3d249dc8d59..2d22f1e4ebe 100644 --- a/endpoints/openrtb2/test_utils.go +++ b/endpoints/openrtb2/test_utils.go @@ -84,7 +84,6 @@ type testCase struct { type testConfigValues struct { AccountRequired bool `json:"accountRequired"` AliasJSON string `json:"aliases"` - BlacklistedAccounts []string `json:"blacklistedAccts"` BlacklistedApps []string `json:"blacklistedApps"` DisabledAdapters []string `json:"disabledAdapters"` CurrencyRates map[string]map[string]float64 `json:"currencyRates"` @@ -932,7 +931,6 @@ func (s mockCurrencyRatesClient) handle(w http.ResponseWriter, req *http.Request return } w.Write(currencyServerJsonResponse) - return } // mockBidderHandler carries mock bidder server information that will be read from JSON test files @@ -994,7 +992,6 @@ func (b mockBidderHandler) bid(w http.ResponseWriter, req *http.Request) { return } w.Write(serverJsonResponse) - return } // mockAdapter is a mock impression-splitting adapter @@ -1154,18 +1151,6 @@ func (tc *testConfigValues) getBlacklistedAppMap() map[string]bool { return blacklistedAppMap } -func (tc *testConfigValues) getBlackListedAccountMap() map[string]bool { - var blacklistedAccountMap map[string]bool - - if len(tc.BlacklistedAccounts) > 0 { - blacklistedAccountMap = make(map[string]bool, len(tc.BlacklistedAccounts)) - for _, account := range tc.BlacklistedAccounts { - blacklistedAccountMap[account] = true - } - } - return blacklistedAccountMap -} - // exchangeTestWrapper is a wrapper that asserts the openrtb2 bid request just before the HoldAuction call type exchangeTestWrapper struct { ex exchange.Exchange @@ -1278,10 +1263,10 @@ func buildTestEndpoint(test testCase, cfg *config.Configuration) (httprouter.Han storedResponseFetcher = empty_fetcher.EmptyFetcher{} } - var accountFetcher stored_requests.AccountFetcher - accountFetcher = &mockAccountFetcher{ + accountFetcher := &mockAccountFetcher{ data: map[string]json.RawMessage{ "malformed_acct": json.RawMessage(`{"disabled":"invalid type"}`), + "disabled_acct": json.RawMessage(`{"disabled":true}`), }, } diff --git a/endpoints/openrtb2/video_auction.go b/endpoints/openrtb2/video_auction.go index a2a519fa8df..7b2a7a5295a 100644 --- a/endpoints/openrtb2/video_auction.go +++ b/endpoints/openrtb2/video_auction.go @@ -244,7 +244,7 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re for _, podEr := range podErrors { resPodErr = append(resPodErr, strings.Join(podEr.ErrMsgs, ", ")) } - err := errors.New(fmt.Sprintf("all pods are incorrect: %s", strings.Join(resPodErr, "; "))) + err := fmt.Errorf("all pods are incorrect: %s", strings.Join(resPodErr, "; ")) errL = append(errL, err) handleError(&labels, w, errL, &vo, &debugLog) return @@ -403,7 +403,7 @@ func handleError(labels *metrics.Labels, w http.ResponseWriter, errL []error, vo var status int = http.StatusInternalServerError for _, er := range errL { erVal := errortypes.ReadCode(er) - if erVal == errortypes.BlacklistedAppErrorCode || erVal == errortypes.BlacklistedAcctErrorCode { + if erVal == errortypes.BlacklistedAppErrorCode || erVal == errortypes.AccountDisabledErrorCode { status = http.StatusServiceUnavailable labels.RequestStatus = metrics.RequestStatusBlacklisted break @@ -555,7 +555,7 @@ func buildVideoResponse(bidresponse *openrtb2.BidResponse, podErrors []PodError) if adPod == nil { adPod = &openrtb_ext.AdPod{ PodId: podId, - Targeting: make([]openrtb_ext.VideoTargeting, 0, 0), + Targeting: make([]openrtb_ext.VideoTargeting, 0), } adPods = append(adPods, adPod) } @@ -620,22 +620,15 @@ func getVideoStoredRequestId(request []byte) (string, error) { func mergeData(videoRequest *openrtb_ext.BidRequestVideo, bidRequest *openrtb2.BidRequest) error { if videoRequest.Site != nil { bidRequest.Site = videoRequest.Site - if &videoRequest.Content != nil { - bidRequest.Site.Content = &videoRequest.Content - } + bidRequest.Site.Content = &videoRequest.Content } if videoRequest.App != nil { bidRequest.App = videoRequest.App - if &videoRequest.Content != nil { - bidRequest.App.Content = &videoRequest.Content - } - } - - if &videoRequest.Device != nil { - bidRequest.Device = &videoRequest.Device + bidRequest.App.Content = &videoRequest.Content } + bidRequest.Device = &videoRequest.Device bidRequest.User = videoRequest.User if len(videoRequest.BCat) != 0 { @@ -768,7 +761,7 @@ func (deps *endpointDeps) validateVideoRequest(req *openrtb_ext.BidRequestVideo) err := errors.New("request missing required field: PodConfig.Pods") errL = append(errL, err) } - podErrors := make([]PodError, 0, 0) + podErrors := make([]PodError, 0) podIdsSet := make(map[int]bool) for ind, pod := range req.PodConfig.Pods { podErr := PodError{} diff --git a/endpoints/openrtb2/video_auction_test.go b/endpoints/openrtb2/video_auction_test.go index da4522ebe0c..f3135ff48db 100644 --- a/endpoints/openrtb2/video_auction_test.go +++ b/endpoints/openrtb2/video_auction_test.go @@ -292,7 +292,7 @@ func TestVideoEndpointNoPods(t *testing.T) { deps := mockDeps(t, ex) deps.VideoAuctionEndpoint(recorder, req, nil) - errorMessage := string(recorder.Body.Bytes()) + errorMessage := recorder.Body.String() assert.Equal(t, recorder.Code, 500, "Should catch error in request") assert.Equal(t, "Critical error while running the video endpoint: request missing required field: PodConfig.DurationRangeSec request missing required field: PodConfig.Pods", errorMessage, "Incorrect request validation message") @@ -739,7 +739,7 @@ func TestVideoBuildVideoResponsePodErrors(t *testing.T) { func TestVideoBuildVideoResponseNoBids(t *testing.T) { openRtbBidResp := openrtb2.BidResponse{} - podErrors := make([]PodError, 0, 0) + podErrors := make([]PodError, 0) openRtbBidResp.SeatBid = make([]openrtb2.SeatBid, 0) bidRespVideo, err := buildVideoResponse(&openRtbBidResp, podErrors) assert.NoError(t, err, "Error should be nil") @@ -808,7 +808,7 @@ func TestHandleError(t *testing.T) { { description: "Blocked account - return 503 with blocked metrics status", giveErrors: []error{ - &errortypes.BlacklistedAcct{}, + &errortypes.AccountDisabled{}, }, wantCode: 503, wantMetricsStatus: metrics.RequestStatusBlacklisted, @@ -1275,40 +1275,6 @@ func mockDeps(t *testing.T, ex *mockExchangeVideo) *endpointDeps { } } -func mockDepsInvalidPrivacy(t *testing.T, ex *mockExchangeVideo) *endpointDeps { - return &endpointDeps{ - fakeUUIDGenerator{}, - ex, - mockBidderParamValidator{}, - &mockVideoStoredReqFetcher{}, - &mockVideoStoredReqFetcher{}, - &mockAccountFetcher{data: mockVideoAccountData}, - &config.Configuration{MaxRequestSize: maxSize, - AccountDefaults: config.Account{ - Privacy: config.AccountPrivacy{ - AllowActivities: &config.AllowActivities{ - TransmitPreciseGeo: config.Activity{Rules: []config.ActivityRule{ - {Condition: config.ActivityCondition{ComponentName: []string{"bidderA.BidderB.bidderC"}}}, - }}, - }, - }, - }, - }, - &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), - map[string]string{}, - false, - []byte{}, - openrtb_ext.BuildBidderMap(), - ex.cache, - regexp.MustCompile(`[<>]`), - hardcodedResponseIPValidator{response: true}, - empty_fetcher.EmptyFetcher{}, - hooks.EmptyPlanBuilder{}, - nil, - } -} - func mockDepsAppendBidderNames(t *testing.T, ex *mockExchangeAppendBidderNames) *endpointDeps { deps := &endpointDeps{ fakeUUIDGenerator{}, diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go index 897538c35e5..18099193045 100644 --- a/endpoints/setuid_test.go +++ b/endpoints/setuid_test.go @@ -1244,27 +1244,6 @@ func TestSetUIDEndpointMetrics(t *testing.T) { a.On("LogSetUIDObject", &expected).Once() }, }, - { - description: "Blocked account", - uri: "/setuid?bidder=pubmatic&uid=123&account=blocked_acct", - cookies: []*usersync.Cookie{}, - syncersBidderNameToKey: map[string]string{"pubmatic": "pubmatic"}, - gdprAllowsHostCookies: true, - expectedResponseCode: 400, - expectedMetrics: func(m *metrics.MetricsEngineMock) { - m.On("RecordSetUid", metrics.SetUidAccountBlocked).Once() - }, - expectedAnalytics: func(a *MockAnalytics) { - expected := analytics.SetUIDObject{ - Status: 400, - Bidder: "pubmatic", - UID: "", - Errors: []error{errCookieSyncAccountBlocked}, - Success: false, - } - a.On("LogSetUIDObject", &expected).Once() - }, - }, { description: "Invalid account", uri: "/setuid?bidder=pubmatic&uid=123&account=unknown", @@ -1549,9 +1528,6 @@ func makeRequest(uri string, existingSyncs map[string]string) *http.Request { func doRequest(req *http.Request, analytics analytics.PBSAnalyticsModule, metrics metrics.MetricsEngine, syncersBidderNameToKey map[string]string, gdprAllowsHostCookies, gdprReturnsError, gdprReturnsMalformedError, cfgAccountRequired bool, maxCookieSize int, priorityGroups [][]string) *httptest.ResponseRecorder { cfg := config.Configuration{ AccountRequired: cfgAccountRequired, - BlacklistedAcctMap: map[string]bool{ - "blocked_acct": true, - }, AccountDefaults: config.Account{}, UserSync: config.UserSync{ PriorityGroups: priorityGroups, diff --git a/errortypes/code.go b/errortypes/code.go index ef8287f2d7d..5cbf3f860b4 100644 --- a/errortypes/code.go +++ b/errortypes/code.go @@ -9,7 +9,7 @@ const ( BadServerResponseErrorCode FailedToRequestBidsErrorCode BidderTemporarilyDisabledErrorCode - BlacklistedAcctErrorCode + AccountDisabledErrorCode AcctRequiredErrorCode NoConversionRateErrorCode MalformedAcctErrorCode diff --git a/errortypes/errortypes.go b/errortypes/errortypes.go index 01a5cca4af7..18b70634c48 100644 --- a/errortypes/errortypes.go +++ b/errortypes/errortypes.go @@ -79,23 +79,20 @@ func (err *BlacklistedApp) Severity() Severity { return SeverityFatal } -// BlacklistedAcct should be used when a request account ID matches an entry in the BlacklistedAccts -// environment variable array -// -// These errors will be written to http.ResponseWriter before canceling execution -type BlacklistedAcct struct { +// AccountDisabled should be used when a request an account is specifically disabled in account config. +type AccountDisabled struct { Message string } -func (err *BlacklistedAcct) Error() string { +func (err *AccountDisabled) Error() string { return err.Message } -func (err *BlacklistedAcct) Code() int { - return BlacklistedAcctErrorCode +func (err *AccountDisabled) Code() int { + return AccountDisabledErrorCode } -func (err *BlacklistedAcct) Severity() Severity { +func (err *AccountDisabled) Severity() Severity { return SeverityFatal } From a2e387f36d48a846bedc6020d772239bba314372 Mon Sep 17 00:00:00 2001 From: Brian Sardo <1168933+bsardo@users.noreply.github.com> Date: Tue, 3 Oct 2023 12:26:50 -0400 Subject: [PATCH 154/268] Remove Config Backwards Compatibility: Account GDPR/CCPA Integration Enabled (#3155) --- account/account.go | 20 --- account/account_test.go | 103 ------------- config/account.go | 18 +-- config/account_test.go | 203 ++++++++------------------ metrics/config/metrics.go | 25 ---- metrics/go_metrics.go | 30 ---- metrics/go_metrics_test.go | 75 ---------- metrics/metrics.go | 3 - metrics/metrics_mock.go | 12 -- metrics/prometheus/prometheus.go | 34 ----- metrics/prometheus/prometheus_test.go | 67 --------- 11 files changed, 64 insertions(+), 526 deletions(-) diff --git a/account/account.go b/account/account.go index 70527d0f6ee..b4d0c334d6b 100644 --- a/account/account.go +++ b/account/account.go @@ -50,18 +50,6 @@ func GetAccount(ctx context.Context, cfg *config.Configuration, fetcher stored_r Message: fmt.Sprintf("The prebid-server account config for account id \"%s\" is malformed. Please reach out to the prebid server host.", accountID), }} } - usingGDPRChannelEnabled := useGDPRChannelEnabled(account) - usingCCPAChannelEnabled := useCCPAChannelEnabled(account) - - if usingGDPRChannelEnabled { - me.RecordAccountGDPRChannelEnabledWarning(accountID) - } - if usingCCPAChannelEnabled { - me.RecordAccountCCPAChannelEnabledWarning(accountID) - } - if usingGDPRChannelEnabled || usingCCPAChannelEnabled { - me.RecordAccountUpgradeStatus(accountID) - } if err != nil { errs = append(errs, err) @@ -154,11 +142,3 @@ func setDerivedConfig(account *config.Account) { } } } - -func useGDPRChannelEnabled(account *config.Account) bool { - return account.GDPR.ChannelEnabled.IsSet() && !account.GDPR.IntegrationEnabled.IsSet() -} - -func useCCPAChannelEnabled(account *config.Account) bool { - return account.CCPA.ChannelEnabled.IsSet() && !account.CCPA.IntegrationEnabled.IsSet() -} diff --git a/account/account_test.go b/account/account_test.go index da0457f8d47..7a242f21188 100644 --- a/account/account_test.go +++ b/account/account_test.go @@ -214,106 +214,3 @@ func TestSetDerivedConfig(t *testing.T) { assert.Equal(t, account.GDPR.Purpose1.EnforceAlgoID, tt.wantEnforceAlgoID, tt.description) } } - -func TestGdprCcpaChannelEnabledMetrics(t *testing.T) { - cfg := &config.Configuration{} - fetcher := &mockAccountFetcher{} - assert.NoError(t, cfg.MarshalAccountDefaults()) - - testCases := []struct { - name string - givenAccountID string - givenMetric string - expectedMetricCount int - }{ - { - name: "ChannelEnabledGDPR", - givenAccountID: "gdpr_channel_enabled_acct", - givenMetric: "RecordAccountGDPRChannelEnabledWarning", - expectedMetricCount: 1, - }, - { - name: "ChannelEnabledCCPA", - givenAccountID: "ccpa_channel_enabled_acct", - givenMetric: "RecordAccountCCPAChannelEnabledWarning", - expectedMetricCount: 1, - }, - { - name: "NotChannelEnabledCCPA", - givenAccountID: "valid_acct", - givenMetric: "RecordAccountCCPAChannelEnabledWarning", - expectedMetricCount: 0, - }, - { - name: "NotChannelEnabledGDPR", - givenAccountID: "valid_acct", - givenMetric: "RecordAccountGDPRChannelEnabledWarning", - expectedMetricCount: 0, - }, - } - - for _, test := range testCases { - t.Run(test.name, func(t *testing.T) { - metrics := &metrics.MetricsEngineMock{} - metrics.Mock.On(test.givenMetric, mock.Anything, mock.Anything).Return() - metrics.Mock.On("RecordAccountUpgradeStatus", mock.Anything, mock.Anything).Return() - - _, _ = GetAccount(context.Background(), cfg, fetcher, test.givenAccountID, metrics) - - metrics.AssertNumberOfCalls(t, test.givenMetric, test.expectedMetricCount) - }) - } -} - -func TestAccountUpgradeStatusGetAccount(t *testing.T) { - cfg := &config.Configuration{} - fetcher := &mockAccountFetcher{} - assert.NoError(t, cfg.MarshalAccountDefaults()) - - testCases := []struct { - name string - givenAccountIDs []string - givenMetrics []string - expectedMetricCount int - }{ - { - name: "ZeroDeprecatedConfigs", - givenAccountIDs: []string{"valid_acct"}, - givenMetrics: []string{}, - expectedMetricCount: 0, - }, - { - name: "OneDeprecatedConfigGDPRChannelEnabled", - givenAccountIDs: []string{"gdpr_channel_enabled_acct"}, - givenMetrics: []string{"RecordAccountGDPRChannelEnabledWarning"}, - expectedMetricCount: 1, - }, - { - name: "OneDeprecatedConfigCCPAChannelEnabled", - givenAccountIDs: []string{"ccpa_channel_enabled_acct"}, - givenMetrics: []string{"RecordAccountCCPAChannelEnabledWarning"}, - expectedMetricCount: 1, - }, - { - name: "MultipleAccountsWithDeprecatedConfigs", - givenAccountIDs: []string{"gdpr_channel_enabled_acct", "ccpa_channel_enabled_acct"}, - givenMetrics: []string{"RecordAccountGDPRChannelEnabledWarning", "RecordAccountCCPAChannelEnabledWarning"}, - expectedMetricCount: 2, - }, - } - - for _, test := range testCases { - t.Run(test.name, func(t *testing.T) { - metrics := &metrics.MetricsEngineMock{} - for _, metric := range test.givenMetrics { - metrics.Mock.On(metric, mock.Anything, mock.Anything).Return() - } - metrics.Mock.On("RecordAccountUpgradeStatus", mock.Anything, mock.Anything).Return() - - for _, accountID := range test.givenAccountIDs { - _, _ = GetAccount(context.Background(), cfg, fetcher, accountID, metrics) - } - metrics.AssertNumberOfCalls(t, "RecordAccountUpgradeStatus", test.expectedMetricCount) - }) - } -} diff --git a/config/account.go b/config/account.go index d57fdb90773..92af6c8a97f 100644 --- a/config/account.go +++ b/config/account.go @@ -53,9 +53,8 @@ type CookieSync struct { // AccountCCPA represents account-specific CCPA configuration type AccountCCPA struct { - Enabled *bool `mapstructure:"enabled" json:"enabled,omitempty"` - IntegrationEnabled AccountChannel `mapstructure:"integration_enabled" json:"integration_enabled"` - ChannelEnabled AccountChannel `mapstructure:"channel_enabled" json:"channel_enabled"` + Enabled *bool `mapstructure:"enabled" json:"enabled,omitempty"` + ChannelEnabled AccountChannel `mapstructure:"channel_enabled" json:"channel_enabled"` } type AccountPriceFloors struct { @@ -94,17 +93,14 @@ func (pf *AccountPriceFloors) IsAdjustForBidAdjustmentEnabled() bool { func (a *AccountCCPA) EnabledForChannelType(channelType ChannelType) *bool { if channelEnabled := a.ChannelEnabled.GetByChannelType(channelType); channelEnabled != nil { return channelEnabled - } else if integrationEnabled := a.IntegrationEnabled.GetByChannelType(channelType); integrationEnabled != nil { - return integrationEnabled } return a.Enabled } // AccountGDPR represents account-specific GDPR configuration type AccountGDPR struct { - Enabled *bool `mapstructure:"enabled" json:"enabled,omitempty"` - IntegrationEnabled AccountChannel `mapstructure:"integration_enabled" json:"integration_enabled"` - ChannelEnabled AccountChannel `mapstructure:"channel_enabled" json:"channel_enabled"` + Enabled *bool `mapstructure:"enabled" json:"enabled,omitempty"` + ChannelEnabled AccountChannel `mapstructure:"channel_enabled" json:"channel_enabled"` // Array of basic enforcement vendors that is used to create the hash table so vendor names can be instantly accessed BasicEnforcementVendors []string `mapstructure:"basic_enforcement_vendors" json:"basic_enforcement_vendors"` BasicEnforcementVendorsMap map[string]struct{} @@ -129,8 +125,6 @@ type AccountGDPR struct { func (a *AccountGDPR) EnabledForChannelType(channelType ChannelType) *bool { if channelEnabled := a.ChannelEnabled.GetByChannelType(channelType); channelEnabled != nil { return channelEnabled - } else if integrationEnabled := a.IntegrationEnabled.GetByChannelType(channelType); integrationEnabled != nil { - return integrationEnabled } return a.Enabled } @@ -298,10 +292,6 @@ func (m AccountModules) ModuleConfig(id string) (json.RawMessage, error) { return m[vendor][module], nil } -func (a *AccountChannel) IsSet() bool { - return a.AMP != nil || a.App != nil || a.Video != nil || a.Web != nil || a.DOOH != nil -} - type AccountPrivacy struct { AllowActivities *AllowActivities `mapstructure:"allowactivities" json:"allowactivities"` IPv6Config IPv6 `mapstructure:"ipv6" json:"ipv6"` diff --git a/config/account_test.go b/config/account_test.go index 58f2a52e645..d0c8507deef 100644 --- a/config/account_test.go +++ b/config/account_test.go @@ -14,68 +14,46 @@ func TestAccountGDPREnabledForChannelType(t *testing.T) { trueValue, falseValue := true, false tests := []struct { - description string - giveChannelType ChannelType - giveGDPREnabled *bool - giveWebGDPREnabled *bool - giveWebGDPREnabledForIntegration *bool - wantEnabled *bool + description string + giveChannelType ChannelType + giveGDPREnabled *bool + giveWebGDPREnabled *bool + wantEnabled *bool }{ { - description: "GDPR Web channel enabled, general GDPR disabled", - giveChannelType: ChannelWeb, - giveGDPREnabled: &falseValue, - giveWebGDPREnabled: &trueValue, - giveWebGDPREnabledForIntegration: nil, - wantEnabled: &trueValue, + description: "GDPR Web channel enabled, general GDPR disabled", + giveChannelType: ChannelWeb, + giveGDPREnabled: &falseValue, + giveWebGDPREnabled: &trueValue, + wantEnabled: &trueValue, }, { - description: "GDPR Web channel disabled, general GDPR enabled", - giveChannelType: ChannelWeb, - giveGDPREnabled: &trueValue, - giveWebGDPREnabled: &falseValue, - giveWebGDPREnabledForIntegration: nil, - wantEnabled: &falseValue, + description: "GDPR Web channel disabled, general GDPR enabled", + giveChannelType: ChannelWeb, + giveGDPREnabled: &trueValue, + giveWebGDPREnabled: &falseValue, + wantEnabled: &falseValue, }, { - description: "GDPR Web channel unspecified, general GDPR disabled", - giveChannelType: ChannelWeb, - giveGDPREnabled: &falseValue, - giveWebGDPREnabled: nil, - giveWebGDPREnabledForIntegration: nil, - wantEnabled: &falseValue, + description: "GDPR Web channel unspecified, general GDPR disabled", + giveChannelType: ChannelWeb, + giveGDPREnabled: &falseValue, + giveWebGDPREnabled: nil, + wantEnabled: &falseValue, }, { - description: "GDPR Web channel unspecified, general GDPR enabled", - giveChannelType: ChannelWeb, - giveGDPREnabled: &trueValue, - giveWebGDPREnabled: nil, - giveWebGDPREnabledForIntegration: nil, - wantEnabled: &trueValue, + description: "GDPR Web channel unspecified, general GDPR enabled", + giveChannelType: ChannelWeb, + giveGDPREnabled: &trueValue, + giveWebGDPREnabled: nil, + wantEnabled: &trueValue, }, { - description: "GDPR Web channel unspecified, general GDPR unspecified", - giveChannelType: ChannelWeb, - giveGDPREnabled: nil, - giveWebGDPREnabled: nil, - giveWebGDPREnabledForIntegration: nil, - wantEnabled: nil, - }, - { - description: "Inegration Enabled is set, and channel enabled isn't", - giveChannelType: ChannelWeb, - giveGDPREnabled: &falseValue, - giveWebGDPREnabled: nil, - giveWebGDPREnabledForIntegration: &trueValue, - wantEnabled: &trueValue, - }, - { - description: "Inegration Enabled is set, and channel enabled is set, channel should have precedence", - giveChannelType: ChannelWeb, - giveGDPREnabled: &falseValue, - giveWebGDPREnabled: &trueValue, - giveWebGDPREnabledForIntegration: &falseValue, - wantEnabled: &trueValue, + description: "GDPR Web channel unspecified, general GDPR unspecified", + giveChannelType: ChannelWeb, + giveGDPREnabled: nil, + giveWebGDPREnabled: nil, + wantEnabled: nil, }, } @@ -86,9 +64,6 @@ func TestAccountGDPREnabledForChannelType(t *testing.T) { ChannelEnabled: AccountChannel{ Web: tt.giveWebGDPREnabled, }, - IntegrationEnabled: AccountChannel{ - Web: tt.giveWebGDPREnabledForIntegration, - }, }, } @@ -107,68 +82,46 @@ func TestAccountCCPAEnabledForChannelType(t *testing.T) { trueValue, falseValue := true, false tests := []struct { - description string - giveChannelType ChannelType - giveCCPAEnabled *bool - giveWebCCPAEnabled *bool - giveWebCCPAEnabledForIntegration *bool - wantEnabled *bool + description string + giveChannelType ChannelType + giveCCPAEnabled *bool + giveWebCCPAEnabled *bool + wantEnabled *bool }{ { - description: "CCPA Web channel enabled, general CCPA disabled", - giveChannelType: ChannelWeb, - giveCCPAEnabled: &falseValue, - giveWebCCPAEnabled: &trueValue, - giveWebCCPAEnabledForIntegration: nil, - wantEnabled: &trueValue, - }, - { - description: "CCPA Web channel disabled, general CCPA enabled", - giveChannelType: ChannelWeb, - giveCCPAEnabled: &trueValue, - giveWebCCPAEnabled: &falseValue, - giveWebCCPAEnabledForIntegration: nil, - wantEnabled: &falseValue, + description: "CCPA Web channel enabled, general CCPA disabled", + giveChannelType: ChannelWeb, + giveCCPAEnabled: &falseValue, + giveWebCCPAEnabled: &trueValue, + wantEnabled: &trueValue, }, { - description: "CCPA Web channel unspecified, general CCPA disabled", - giveChannelType: ChannelWeb, - giveCCPAEnabled: &falseValue, - giveWebCCPAEnabled: nil, - giveWebCCPAEnabledForIntegration: nil, - wantEnabled: &falseValue, + description: "CCPA Web channel disabled, general CCPA enabled", + giveChannelType: ChannelWeb, + giveCCPAEnabled: &trueValue, + giveWebCCPAEnabled: &falseValue, + wantEnabled: &falseValue, }, { - description: "CCPA Web channel unspecified, general CCPA enabled", - giveChannelType: ChannelWeb, - giveCCPAEnabled: &trueValue, - giveWebCCPAEnabled: nil, - giveWebCCPAEnabledForIntegration: nil, - wantEnabled: &trueValue, + description: "CCPA Web channel unspecified, general CCPA disabled", + giveChannelType: ChannelWeb, + giveCCPAEnabled: &falseValue, + giveWebCCPAEnabled: nil, + wantEnabled: &falseValue, }, { - description: "CCPA Web channel unspecified, general CCPA unspecified", - giveChannelType: ChannelWeb, - giveCCPAEnabled: nil, - giveWebCCPAEnabled: nil, - giveWebCCPAEnabledForIntegration: nil, - wantEnabled: nil, + description: "CCPA Web channel unspecified, general CCPA enabled", + giveChannelType: ChannelWeb, + giveCCPAEnabled: &trueValue, + giveWebCCPAEnabled: nil, + wantEnabled: &trueValue, }, { - description: "Inegration Enabled is set, and channel enabled isn't", - giveChannelType: ChannelWeb, - giveCCPAEnabled: &falseValue, - giveWebCCPAEnabled: nil, - giveWebCCPAEnabledForIntegration: &trueValue, - wantEnabled: &trueValue, - }, - { - description: "Inegration Enabled is set, and channel enabled is set, channel should have precedence", - giveChannelType: ChannelWeb, - giveCCPAEnabled: &falseValue, - giveWebCCPAEnabled: &trueValue, - giveWebCCPAEnabledForIntegration: &falseValue, - wantEnabled: &trueValue, + description: "CCPA Web channel unspecified, general CCPA unspecified", + giveChannelType: ChannelWeb, + giveCCPAEnabled: nil, + giveWebCCPAEnabled: nil, + wantEnabled: nil, }, } @@ -179,9 +132,6 @@ func TestAccountCCPAEnabledForChannelType(t *testing.T) { ChannelEnabled: AccountChannel{ Web: tt.giveWebCCPAEnabled, }, - IntegrationEnabled: AccountChannel{ - Web: tt.giveWebCCPAEnabledForIntegration, - }, }, } @@ -844,39 +794,6 @@ func TestModulesGetConfig(t *testing.T) { } } -func TestAccountChannelIsSet(t *testing.T) { - trueBool := true - falseBool := false - - testCases := []struct { - name string - givenAccountChannel *AccountChannel - expected bool - }{ - { - name: "AccountChannelSetAllFields", - givenAccountChannel: &AccountChannel{AMP: &trueBool, App: &falseBool, Video: &falseBool, Web: &falseBool, DOOH: &falseBool}, - expected: true, - }, - { - name: "AccountChannelNotSet", - givenAccountChannel: &AccountChannel{}, - expected: false, - }, - { - name: "AccountChannelSetAmpOnly", - givenAccountChannel: &AccountChannel{AMP: &trueBool}, - expected: true, - }, - } - - for _, test := range testCases { - t.Run(test.name, func(t *testing.T) { - assert.Equal(t, test.expected, test.givenAccountChannel.IsSet()) - }) - } -} - func TestAccountPriceFloorsValidate(t *testing.T) { tests := []struct { diff --git a/metrics/config/metrics.go b/metrics/config/metrics.go index 757cde336b2..d5cb00344ec 100644 --- a/metrics/config/metrics.go +++ b/metrics/config/metrics.go @@ -322,22 +322,6 @@ func (me *MultiMetricsEngine) RecordBidValidationSecureMarkupWarn(adapter openrt } } -func (me *MultiMetricsEngine) RecordAccountGDPRChannelEnabledWarning(account string) { - for _, thisME := range *me { - thisME.RecordAccountGDPRChannelEnabledWarning(account) - } -} -func (me *MultiMetricsEngine) RecordAccountCCPAChannelEnabledWarning(account string) { - for _, thisME := range *me { - thisME.RecordAccountCCPAChannelEnabledWarning(account) - } -} -func (me *MultiMetricsEngine) RecordAccountUpgradeStatus(account string) { - for _, thisME := range *me { - thisME.RecordAccountUpgradeStatus(account) - } -} - func (me *MultiMetricsEngine) RecordModuleCalled(labels metrics.ModuleLabels, duration time.Duration) { for _, thisME := range *me { thisME.RecordModuleCalled(labels, duration) @@ -531,15 +515,6 @@ func (me *NilMetricsEngine) RecordBidValidationSecureMarkupError(adapter openrtb func (me *NilMetricsEngine) RecordBidValidationSecureMarkupWarn(adapter openrtb_ext.BidderName, account string) { } -func (me *NilMetricsEngine) RecordAccountGDPRChannelEnabledWarning(account string) { -} - -func (me *NilMetricsEngine) RecordAccountCCPAChannelEnabledWarning(account string) { -} - -func (me *NilMetricsEngine) RecordAccountUpgradeStatus(account string) { -} - func (me *NilMetricsEngine) RecordModuleCalled(labels metrics.ModuleLabels, duration time.Duration) { } diff --git a/metrics/go_metrics.go b/metrics/go_metrics.go index 37080b05456..0d60a7009d9 100644 --- a/metrics/go_metrics.go +++ b/metrics/go_metrics.go @@ -125,11 +125,6 @@ type accountMetrics struct { bidValidationCreativeSizeWarnMeter metrics.Meter bidValidationSecureMarkupMeter metrics.Meter bidValidationSecureMarkupWarnMeter metrics.Meter - - // Account Deprciation Metrics - channelEnabledGDPRMeter metrics.Meter - channelEnabledCCPAMeter metrics.Meter - accountDeprecationSummaryMeter metrics.Meter } type ModuleMetrics struct { @@ -566,10 +561,6 @@ func (me *Metrics) getAccountMetrics(id string) *accountMetrics { am.bidValidationSecureMarkupMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.response.validation.secure.err", id), me.MetricsRegistry) am.bidValidationSecureMarkupWarnMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.response.validation.secure.warn", id), me.MetricsRegistry) - am.channelEnabledCCPAMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.config.ccpa.channel_enabled.warn", id), me.MetricsRegistry) - am.channelEnabledGDPRMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.config.gdpr.channel_enabled.warn", id), me.MetricsRegistry) - am.accountDeprecationSummaryMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.config.summary", id), me.MetricsRegistry) - if !me.MetricsDisabled.AccountModulesMetrics { for _, mod := range me.modules { am.moduleMetrics[mod] = makeBlankModuleMetrics() @@ -615,27 +606,6 @@ func (me *Metrics) RecordDebugRequest(debugEnabled bool, pubID string) { } } -func (me *Metrics) RecordAccountGDPRChannelEnabledWarning(account string) { - if account != PublisherUnknown { - am := me.getAccountMetrics(account) - am.channelEnabledGDPRMeter.Mark(1) - } -} - -func (me *Metrics) RecordAccountCCPAChannelEnabledWarning(account string) { - if account != PublisherUnknown { - am := me.getAccountMetrics(account) - am.channelEnabledCCPAMeter.Mark(1) - } -} - -func (me *Metrics) RecordAccountUpgradeStatus(account string) { - if account != PublisherUnknown { - am := me.getAccountMetrics(account) - am.accountDeprecationSummaryMeter.Mark(1) - } -} - func (me *Metrics) RecordStoredResponse(pubId string) { me.StoredResponsesMeter.Mark(1) if pubId != PublisherUnknown && !me.MetricsDisabled.AccountStoredResponses { diff --git a/metrics/go_metrics_test.go b/metrics/go_metrics_test.go index 3564f9fa2a5..8acd1923a85 100644 --- a/metrics/go_metrics_test.go +++ b/metrics/go_metrics_test.go @@ -1066,81 +1066,6 @@ func TestRecordModuleAccountMetrics(t *testing.T) { } } -func TestRecordAccountGDPRChannelEnabledWarningMetrics(t *testing.T) { - testCases := []struct { - name string - givenPubID string - expectedMetricCount int64 - }{ - { - name: "GdprChannelMetricIncremented", - givenPubID: "acct-id", - expectedMetricCount: 1, - }, - } - for _, test := range testCases { - t.Run(test.name, func(t *testing.T) { - registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus}, config.DisabledMetrics{}, nil, nil) - - m.RecordAccountGDPRChannelEnabledWarning(test.givenPubID) - am := m.getAccountMetrics(test.givenPubID) - - assert.Equal(t, test.expectedMetricCount, am.channelEnabledGDPRMeter.Count()) - }) - } -} - -func TestRecordAccountCCPAChannelEnabledWarningMetrics(t *testing.T) { - testCases := []struct { - name string - givenPubID string - expectedMetricCount int64 - }{ - { - name: "CcpaChannelMetricIncremented", - givenPubID: "acct-id", - expectedMetricCount: 1, - }, - } - for _, test := range testCases { - t.Run(test.name, func(t *testing.T) { - registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus}, config.DisabledMetrics{}, nil, nil) - - m.RecordAccountCCPAChannelEnabledWarning(test.givenPubID) - am := m.getAccountMetrics(test.givenPubID) - - assert.Equal(t, test.expectedMetricCount, am.channelEnabledCCPAMeter.Count()) - }) - } -} - -func TestRecordAccountUpgradeStatusMetrics(t *testing.T) { - testCases := []struct { - name string - givenPubID string - expectedMetricCount int64 - }{ - { - name: "AccountDeprecationMeterIncremented", - givenPubID: "acct-id", - expectedMetricCount: 1, - }, - } - for _, test := range testCases { - t.Run(test.name, func(t *testing.T) { - registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus}, config.DisabledMetrics{}, nil, nil) - - m.RecordAccountUpgradeStatus(test.givenPubID) - am := m.getAccountMetrics(test.givenPubID) - - assert.Equal(t, test.expectedMetricCount, am.accountDeprecationSummaryMeter.Count()) - }) - } -} - func TestRecordOverheadTime(t *testing.T) { testCases := []struct { name string diff --git a/metrics/metrics.go b/metrics/metrics.go index 7315fa72712..99e64af0835 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -470,7 +470,4 @@ type MetricsEngine interface { RecordModuleSuccessRejected(labels ModuleLabels) RecordModuleExecutionError(labels ModuleLabels) RecordModuleTimeout(labels ModuleLabels) - RecordAccountGDPRChannelEnabledWarning(account string) - RecordAccountCCPAChannelEnabledWarning(account string) - RecordAccountUpgradeStatus(account string) } diff --git a/metrics/metrics_mock.go b/metrics/metrics_mock.go index f6ecf57e37f..eb092f0d972 100644 --- a/metrics/metrics_mock.go +++ b/metrics/metrics_mock.go @@ -221,15 +221,3 @@ func (me *MetricsEngineMock) RecordModuleExecutionError(labels ModuleLabels) { func (me *MetricsEngineMock) RecordModuleTimeout(labels ModuleLabels) { me.Called(labels) } - -func (me *MetricsEngineMock) RecordAccountGDPRChannelEnabledWarning(account string) { - me.Called(account) -} - -func (me *MetricsEngineMock) RecordAccountCCPAChannelEnabledWarning(account string) { - me.Called(account) -} - -func (me *MetricsEngineMock) RecordAccountUpgradeStatus(account string) { - me.Called(account) -} diff --git a/metrics/prometheus/prometheus.go b/metrics/prometheus/prometheus.go index 363e5527fbc..30fb6c5f774 100644 --- a/metrics/prometheus/prometheus.go +++ b/metrics/prometheus/prometheus.go @@ -88,11 +88,6 @@ type Metrics struct { accountBidResponseSecureMarkupError *prometheus.CounterVec accountBidResponseSecureMarkupWarn *prometheus.CounterVec - // Account Deprecation Metrics - channelEnabledGDPR prometheus.Counter - channelEnabledCCPA prometheus.Counter - accountDeprecationSummary prometheus.Counter - // Module Metrics as a map where the key is the module name moduleDuration map[string]*prometheus.HistogramVec moduleCalls map[string]*prometheus.CounterVec @@ -502,17 +497,6 @@ func NewMetrics(cfg config.PrometheusMetrics, disabledMetrics config.DisabledMet "Count of AdsCert request, and if they were successfully sent.", []string{successLabel}) - metrics.channelEnabledCCPA = newCounterWithoutLabels(cfg, reg, - "account_config_ccpa_channel_enabled_warn", - "Count of requests referencing an account whose config specifies a depreceated ccpa.channel_enabled field") - metrics.channelEnabledGDPR = newCounterWithoutLabels(cfg, reg, - "account_config_gdpr_channel_enabled_warn", - "Count of requests referencing an account whose config specifies a depreceated gdpr.channel_enabled field") - - metrics.accountDeprecationSummary = newCounterWithoutLabels(cfg, reg, - "account_config_summary", - "Count of deprecated account config fields encountered across all accounts") - createModulesMetrics(cfg, reg, &metrics, moduleStageNames, standardTimeBuckets) metrics.Gatherer = reg @@ -693,24 +677,6 @@ func (m *Metrics) RecordDebugRequest(debugEnabled bool, pubID string) { } } -func (m *Metrics) RecordAccountGDPRChannelEnabledWarning(account string) { - if account != metrics.PublisherUnknown { - m.channelEnabledGDPR.Inc() - } -} - -func (m *Metrics) RecordAccountCCPAChannelEnabledWarning(account string) { - if account != metrics.PublisherUnknown { - m.channelEnabledCCPA.Inc() - } -} - -func (m *Metrics) RecordAccountUpgradeStatus(account string) { - if account != metrics.PublisherUnknown { - m.accountDeprecationSummary.Inc() - } -} - func (m *Metrics) RecordStoredResponse(pubId string) { m.storedResponses.Inc() if !m.metricsDisabled.AccountStoredResponses && pubId != metrics.PublisherUnknown { diff --git a/metrics/prometheus/prometheus_test.go b/metrics/prometheus/prometheus_test.go index 90d331fe5ae..e57ae5e198a 100644 --- a/metrics/prometheus/prometheus_test.go +++ b/metrics/prometheus/prometheus_test.go @@ -1976,70 +1976,3 @@ func TestRecordModuleMetrics(t *testing.T) { } } } - -func TestRecordAccountGDPRChannelEnabledWarningMetrics(t *testing.T) { - testCases := []struct { - name string - givenPubID string - expectedMetricCount float64 - }{ - { - name: "GdprChannelMetricIncremented", - givenPubID: "acct-id", - expectedMetricCount: 1, - }, - } - for _, test := range testCases { - t.Run(test.name, func(t *testing.T) { - m := createMetricsForTesting() - m.RecordAccountGDPRChannelEnabledWarning(test.givenPubID) - - assertCounterValue(t, "", "GDPR Channel Enabled Deprecation Warnings", m.channelEnabledGDPR, test.expectedMetricCount) - }) - } -} - -func TestRecordAccountCCPAChannelEnabledWarningMetrics(t *testing.T) { - testCases := []struct { - name string - givenPubID string - expectedMetricCount float64 - }{ - { - name: "CcpaChannelMetricIncremented", - givenPubID: "acct-id", - expectedMetricCount: 1, - }, - } - for _, test := range testCases { - t.Run(test.name, func(t *testing.T) { - m := createMetricsForTesting() - m.RecordAccountCCPAChannelEnabledWarning(test.givenPubID) - - assertCounterValue(t, "", "CCPA Channel Enabled Deprecation Warnings", m.channelEnabledCCPA, test.expectedMetricCount) - }) - } -} - -func TestRecordAccountUpgradeStatusMetrics(t *testing.T) { - testCases := []struct { - name string - givenPubID string - expectedMetricCount float64 - }{ - { - name: "AccountDeprecationMeterIncremented", - givenPubID: "acct-id", - expectedMetricCount: 1, - }, - } - for _, test := range testCases { - t.Run(test.name, func(t *testing.T) { - m := createMetricsForTesting() - m.RecordAccountUpgradeStatus(test.givenPubID) - - assertCounterValue(t, "", "Account Depreciation Summary Meter should be incremented", m.accountDeprecationSummary, test.expectedMetricCount) - }) - - } -} From 781dc7beb873df33be13183ac1fe74465c7fc50d Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Wed, 4 Oct 2023 12:25:14 -0400 Subject: [PATCH 155/268] Remove Config Backwards Compatibility: User Sync URL (#3163) --- config/bidderinfo.go | 53 --------------------- config/bidderinfo_test.go | 97 ++++++--------------------------------- config/config_test.go | 1 - 3 files changed, 15 insertions(+), 136 deletions(-) diff --git a/config/bidderinfo.go b/config/bidderinfo.go index 3b3f86d4ec9..f1f437c5c93 100644 --- a/config/bidderinfo.go +++ b/config/bidderinfo.go @@ -9,10 +9,8 @@ import ( "strings" "text/template" - "github.com/golang/glog" "github.com/prebid/prebid-server/macros" "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/sliceutil" validator "github.com/asaskevich/govalidator" "gopkg.in/yaml.v3" @@ -38,9 +36,6 @@ type BidderInfo struct { Experiment BidderInfoExperiment `yaml:"experiment" mapstructure:"experiment"` - // needed for backwards compatibility - UserSyncURL string `yaml:"usersync_url" mapstructure:"usersync_url"` - // needed for Rubicon XAPI AdapterXAPI `yaml:"xapi" mapstructure:"xapi"` @@ -329,9 +324,6 @@ func processBidderAliases(aliasNillableFieldsByBidder map[string]aliasNillableFi syncer := Syncer{Key: syncerKey} aliasBidderInfo.Syncer = &syncer } - if aliasBidderInfo.UserSyncURL == "" { - aliasBidderInfo.UserSyncURL = parentBidderInfo.UserSyncURL - } if alias.Disabled == nil { aliasBidderInfo.Disabled = parentBidderInfo.Disabled } @@ -614,51 +606,6 @@ func applyBidderInfoConfigOverrides(configBidderInfos BidderInfos, fsBidderInfos bidderInfo.EndpointCompression = fsBidderCfg.EndpointCompression } - // validate and try to apply the legacy usersync_url configuration in attempt to provide - // an easier upgrade path. be warned, this will break if the bidder adds a second syncer - // type and will eventually be removed after we've given hosts enough time to upgrade to - // the new config. - if bidderInfo.UserSyncURL != "" { - if fsBidderCfg.Syncer == nil { - return nil, fmt.Errorf("adapters.%s.usersync_url cannot be applied, bidder does not define a user sync", strings.ToLower(bidderName)) - } - - endpointsCount := 0 - if bidderInfo.Syncer.IFrame != nil { - bidderInfo.Syncer.IFrame.URL = bidderInfo.UserSyncURL - endpointsCount++ - } - if bidderInfo.Syncer.Redirect != nil { - bidderInfo.Syncer.Redirect.URL = bidderInfo.UserSyncURL - endpointsCount++ - } - - // use Supports as a hint if there are no good defaults provided - if endpointsCount == 0 { - if sliceutil.ContainsStringIgnoreCase(bidderInfo.Syncer.Supports, "iframe") { - bidderInfo.Syncer.IFrame = &SyncerEndpoint{URL: bidderInfo.UserSyncURL} - endpointsCount++ - } - if sliceutil.ContainsStringIgnoreCase(bidderInfo.Syncer.Supports, "redirect") { - bidderInfo.Syncer.Redirect = &SyncerEndpoint{URL: bidderInfo.UserSyncURL} - endpointsCount++ - } - } - - if endpointsCount == 0 { - return nil, fmt.Errorf("adapters.%s.usersync_url cannot be applied, bidder does not define user sync endpoints and does not define supported endpoints", strings.ToLower(bidderName)) - } - - // if the bidder defines both an iframe and redirect endpoint, we can't be sure which config value to - // override, and it wouldn't be both. this is a fatal configuration error. - if endpointsCount > 1 { - return nil, fmt.Errorf("adapters.%s.usersync_url cannot be applied, bidder defines multiple user sync endpoints or supports multiple endpoints", strings.ToLower(bidderName)) - } - - // provide a warning that this compatibility layer is temporary - glog.Warningf("adapters.%s.usersync_url is deprecated and will be removed in a future version, please update to the latest user sync config values", strings.ToLower(bidderName)) - } - fsBidderInfos[string(normalizedBidderName)] = bidderInfo } else { return nil, fmt.Errorf("error finding configuration for bidder %s: unknown bidder", bidderName) diff --git a/config/bidderinfo_test.go b/config/bidderinfo_test.go index 0900421a574..7b134314609 100644 --- a/config/bidderinfo_test.go +++ b/config/bidderinfo_test.go @@ -9,6 +9,7 @@ import ( "github.com/prebid/prebid-server/openrtb_ext" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const testInfoFilesPathValid = "./test/bidder-info-valid" @@ -50,7 +51,6 @@ disabled: false extra_info: extra-info app_secret: app-secret platform_id: 123 -usersync_url: user-url userSync: key: foo default: iframe @@ -217,7 +217,6 @@ func TestProcessBidderInfo(t *testing.T) { UserMacro: "UID", }, }, - UserSyncURL: "user-url", XAPI: AdapterXAPI{ Username: "uname", Password: "pwd", @@ -263,7 +262,6 @@ func TestProcessBidderInfo(t *testing.T) { Syncer: &Syncer{ Key: "foo", }, - UserSyncURL: "user-url", XAPI: AdapterXAPI{ Username: "uname", Password: "pwd", @@ -273,6 +271,7 @@ func TestProcessBidderInfo(t *testing.T) { }, }, } + for _, test := range testCases { reader := StubInfoReader{test.bidderInfos} bidderInfos, err := processBidderInfos(reader, mockNormalizeBidderName) @@ -281,9 +280,7 @@ func TestProcessBidderInfo(t *testing.T) { } else { assert.Equal(t, test.expectedBidderInfos, bidderInfos, "incorrect bidder infos for test case: %s", test.description) } - } - } func TestProcessAliasBidderInfo(t *testing.T) { @@ -328,7 +325,6 @@ func TestProcessAliasBidderInfo(t *testing.T) { UserMacro: "UID", }, }, - UserSyncURL: "user-url", XAPI: AdapterXAPI{ Username: "uname", Password: "pwd", @@ -376,7 +372,6 @@ func TestProcessAliasBidderInfo(t *testing.T) { UserMacro: "alias-UID", }, }, - UserSyncURL: "alias-user-url", XAPI: AdapterXAPI{ Username: "alias-uname", Password: "alias-pwd", @@ -1493,78 +1488,15 @@ func TestSyncerEndpointOverride(t *testing.T) { } func TestApplyBidderInfoConfigSyncerOverrides(t *testing.T) { - var testCases = []struct { - description string - givenFsBidderInfos BidderInfos - givenConfigBidderInfos BidderInfos - expectedError string - expectedBidderInfos BidderInfos - }{ - { - description: "Syncer Override", - givenFsBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "original"}}}, - givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, - expectedBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, - }, - { - description: "UserSyncURL Override IFrame", - givenFsBidderInfos: BidderInfos{"a": {Syncer: &Syncer{IFrame: &SyncerEndpoint{URL: "original"}}}}, - givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}}, - expectedBidderInfos: BidderInfos{"a": {UserSyncURL: "override", Syncer: &Syncer{IFrame: &SyncerEndpoint{URL: "override"}}}}, - }, - { - description: "UserSyncURL Supports IFrame", - givenFsBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Supports: []string{"iframe"}}}}, - givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}}, - expectedBidderInfos: BidderInfos{"a": {UserSyncURL: "override", Syncer: &Syncer{Supports: []string{"iframe"}, IFrame: &SyncerEndpoint{URL: "override"}}}}, - }, - { - description: "UserSyncURL Override Redirect", - givenFsBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Supports: []string{"redirect"}}}}, - givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}}, - expectedBidderInfos: BidderInfos{"a": {UserSyncURL: "override", Syncer: &Syncer{Supports: []string{"redirect"}, Redirect: &SyncerEndpoint{URL: "override"}}}}, - }, - { - description: "UserSyncURL Supports Redirect", - givenFsBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Redirect: &SyncerEndpoint{URL: "original"}}}}, - givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}}, - expectedBidderInfos: BidderInfos{"a": {UserSyncURL: "override", Syncer: &Syncer{Redirect: &SyncerEndpoint{URL: "override"}}}}, - }, - { - description: "UserSyncURL Override Syncer Not Defined", - givenFsBidderInfos: BidderInfos{"a": {}}, - givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}}, - expectedError: "adapters.a.usersync_url cannot be applied, bidder does not define a user sync", - }, - { - description: "UserSyncURL Override Syncer Endpoints Not Defined", - givenFsBidderInfos: BidderInfos{"a": {Syncer: &Syncer{}}}, - givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}}, - expectedError: "adapters.a.usersync_url cannot be applied, bidder does not define user sync endpoints and does not define supported endpoints", - }, - { - description: "UserSyncURL Override Ambiguous", - givenFsBidderInfos: BidderInfos{"a": {Syncer: &Syncer{IFrame: &SyncerEndpoint{URL: "originalIFrame"}, Redirect: &SyncerEndpoint{URL: "originalRedirect"}}}}, - givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}}, - expectedError: "adapters.a.usersync_url cannot be applied, bidder defines multiple user sync endpoints or supports multiple endpoints", - }, - { - description: "UserSyncURL Supports Ambiguous", - givenFsBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Supports: []string{"iframe", "redirect"}}}}, - givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}}, - expectedError: "adapters.a.usersync_url cannot be applied, bidder defines multiple user sync endpoints or supports multiple endpoints", - }, - } + var ( + givenFileSystem = BidderInfos{"a": {Syncer: &Syncer{Key: "original"}}} + givenConfig = BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}} + expected = BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}} + ) - for _, test := range testCases { - bidderInfos, resultErr := applyBidderInfoConfigOverrides(test.givenConfigBidderInfos, test.givenFsBidderInfos, mockNormalizeBidderName) - if test.expectedError == "" { - assert.NoError(t, resultErr, test.description+":err") - assert.Equal(t, test.expectedBidderInfos, bidderInfos, test.description+":result") - } else { - assert.EqualError(t, resultErr, test.expectedError, test.description+":err") - } - } + result, resultErr := applyBidderInfoConfigOverrides(givenConfig, givenFileSystem, mockNormalizeBidderName) + assert.NoError(t, resultErr) + assert.Equal(t, expected, result) } func TestApplyBidderInfoConfigOverrides(t *testing.T) { @@ -1754,10 +1686,12 @@ func TestApplyBidderInfoConfigOverridesInvalid(t *testing.T) { func TestReadFullYamlBidderConfig(t *testing.T) { bidder := "bidderA" bidderInf := BidderInfo{} + err := yaml.Unmarshal([]byte(fullBidderYAMLConfig), &bidderInf) - actualBidderInfo, err := applyBidderInfoConfigOverrides(BidderInfos{bidder: bidderInf}, BidderInfos{bidder: {Syncer: &Syncer{Supports: []string{"iframe"}}}}, mockNormalizeBidderName) + require.NoError(t, err) - assert.NoError(t, err, "Error wasn't expected") + actualBidderInfo, err := applyBidderInfoConfigOverrides(BidderInfos{bidder: bidderInf}, BidderInfos{bidder: {Syncer: &Syncer{Supports: []string{"iframe"}}}}, mockNormalizeBidderName) + require.NoError(t, err) expectedBidderInfo := BidderInfos{ bidder: { @@ -1794,11 +1728,10 @@ func TestReadFullYamlBidderConfig(t *testing.T) { ExtraAdapterInfo: "extra-info", AppSecret: "app-secret", PlatformID: "123", - UserSyncURL: "user-url", Syncer: &Syncer{ Key: "foo", IFrame: &SyncerEndpoint{ - URL: "user-url", + URL: "https://foo.com/sync?mode=iframe&r={{.RedirectURL}}", RedirectURL: "https://redirect/setuid/iframe", ExternalURL: "https://iframe.host", UserMacro: "UID", diff --git a/config/config_test.go b/config/config_test.go index 97be28eb6e3..21d1681c1e7 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -32,7 +32,6 @@ var bidderInfos = BidderInfos{ MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}, }, }, - UserSyncURL: "http://bidder2.com/usersync", }, } From 134e9aa739da331754cfe4694f5fe8b767a1adb3 Mon Sep 17 00:00:00 2001 From: Veronika Solovei Date: Wed, 4 Oct 2023 16:33:06 -0700 Subject: [PATCH 156/268] Analytics activities (#3024) --- .../{config/config.go => build/build.go} | 47 ++++--- .../config_test.go => build/build_test.go} | 116 +++++++++++++++--- analytics/core.go | 4 +- analytics/filesystem/file_module.go | 2 +- analytics/pubstack/pubstack_module.go | 4 +- analytics/pubstack/pubstack_module_test.go | 14 +-- analytics/runner.go | 14 +++ endpoints/cookie_sync.go | 6 +- endpoints/cookie_sync_test.go | 44 +++---- endpoints/events/event.go | 9 +- endpoints/events/event_test.go | 9 +- endpoints/openrtb2/amp_auction.go | 12 +- endpoints/openrtb2/amp_auction_test.go | 37 +++--- endpoints/openrtb2/auction.go | 15 +-- endpoints/openrtb2/auction_benchmark_test.go | 4 +- endpoints/openrtb2/auction_test.go | 66 +++++----- endpoints/openrtb2/test_utils.go | 6 +- endpoints/openrtb2/video_auction.go | 10 +- endpoints/openrtb2/video_auction_test.go | 18 +-- endpoints/setuid.go | 4 +- endpoints/setuid_test.go | 34 ++--- router/router.go | 16 +-- 22 files changed, 307 insertions(+), 184 deletions(-) rename analytics/{config/config.go => build/build.go} (55%) rename analytics/{config/config_test.go => build/build_test.go} (50%) create mode 100644 analytics/runner.go diff --git a/analytics/config/config.go b/analytics/build/build.go similarity index 55% rename from analytics/config/config.go rename to analytics/build/build.go index 557fec361dc..6fb48705981 100644 --- a/analytics/config/config.go +++ b/analytics/build/build.go @@ -1,4 +1,4 @@ -package config +package build import ( "github.com/benbjohnson/clock" @@ -8,14 +8,15 @@ import ( "github.com/prebid/prebid-server/analytics/filesystem" "github.com/prebid/prebid-server/analytics/pubstack" "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/privacy" ) // Modules that need to be logged to need to be initialized here -func NewPBSAnalytics(analytics *config.Analytics) analytics.PBSAnalyticsModule { +func New(analytics *config.Analytics) analytics.Runner { modules := make(enabledAnalytics, 0) if len(analytics.File.Filename) > 0 { if mod, err := filesystem.NewFileLogger(analytics.File.Filename); err == nil { - modules = append(modules, mod) + modules["filelogger"] = mod } else { glog.Fatalf("Could not initialize FileLogger for file %v :%v", analytics.File.Filename, err) } @@ -32,7 +33,7 @@ func NewPBSAnalytics(analytics *config.Analytics) analytics.PBSAnalyticsModule { analytics.Pubstack.Buffers.Timeout, clock.New()) if err == nil { - modules = append(modules, pubstackModule) + modules["pubstack"] = pubstackModule } else { glog.Errorf("Could not initialize PubstackModule: %v", err) } @@ -41,17 +42,23 @@ func NewPBSAnalytics(analytics *config.Analytics) analytics.PBSAnalyticsModule { } // Collection of all the correctly configured analytics modules - implements the PBSAnalyticsModule interface -type enabledAnalytics []analytics.PBSAnalyticsModule +type enabledAnalytics map[string]analytics.Module -func (ea enabledAnalytics) LogAuctionObject(ao *analytics.AuctionObject) { - for _, module := range ea { - module.LogAuctionObject(ao) +func (ea enabledAnalytics) LogAuctionObject(ao *analytics.AuctionObject, ac privacy.ActivityControl) { + for name, module := range ea { + component := privacy.Component{Type: privacy.ComponentTypeAnalytics, Name: name} + if ac.Allow(privacy.ActivityReportAnalytics, component, privacy.ActivityRequest{}) { + module.LogAuctionObject(ao) + } } } -func (ea enabledAnalytics) LogVideoObject(vo *analytics.VideoObject) { - for _, module := range ea { - module.LogVideoObject(vo) +func (ea enabledAnalytics) LogVideoObject(vo *analytics.VideoObject, ac privacy.ActivityControl) { + for name, module := range ea { + component := privacy.Component{Type: privacy.ComponentTypeAnalytics, Name: name} + if ac.Allow(privacy.ActivityReportAnalytics, component, privacy.ActivityRequest{}) { + module.LogVideoObject(vo) + } } } @@ -67,14 +74,20 @@ func (ea enabledAnalytics) LogSetUIDObject(so *analytics.SetUIDObject) { } } -func (ea enabledAnalytics) LogAmpObject(ao *analytics.AmpObject) { - for _, module := range ea { - module.LogAmpObject(ao) +func (ea enabledAnalytics) LogAmpObject(ao *analytics.AmpObject, ac privacy.ActivityControl) { + for name, module := range ea { + component := privacy.Component{Type: privacy.ComponentTypeAnalytics, Name: name} + if ac.Allow(privacy.ActivityReportAnalytics, component, privacy.ActivityRequest{}) { + module.LogAmpObject(ao) + } } } -func (ea enabledAnalytics) LogNotificationEventObject(ne *analytics.NotificationEvent) { - for _, module := range ea { - module.LogNotificationEventObject(ne) +func (ea enabledAnalytics) LogNotificationEventObject(ne *analytics.NotificationEvent, ac privacy.ActivityControl) { + for name, module := range ea { + component := privacy.Component{Type: privacy.ComponentTypeAnalytics, Name: name} + if ac.Allow(privacy.ActivityReportAnalytics, component, privacy.ActivityRequest{}) { + module.LogNotificationEventObject(ne) + } } } diff --git a/analytics/config/config_test.go b/analytics/build/build_test.go similarity index 50% rename from analytics/config/config_test.go rename to analytics/build/build_test.go index c0ad9c26a16..dbd129a7afd 100644 --- a/analytics/config/config_test.go +++ b/analytics/build/build_test.go @@ -1,15 +1,16 @@ -package config +package build import ( + "github.com/prebid/prebid-server/analytics" "net/http" "os" "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/stretchr/testify/assert" - - "github.com/prebid/prebid-server/analytics" "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/privacy" + "github.com/prebid/prebid-server/util/ptrutil" + "github.com/stretchr/testify/assert" ) const TEST_DIR string = "testFiles" @@ -21,7 +22,7 @@ func TestSampleModule(t *testing.T) { Status: http.StatusOK, Errors: nil, Response: &openrtb2.BidResponse{}, - }) + }, privacy.ActivityControl{}) if count != 1 { t.Errorf("PBSAnalyticsModule failed at LogAuctionObject") } @@ -42,17 +43,17 @@ func TestSampleModule(t *testing.T) { t.Errorf("PBSAnalyticsModule failed at LogCookieSyncObject") } - am.LogAmpObject(&analytics.AmpObject{}) + am.LogAmpObject(&analytics.AmpObject{}, privacy.ActivityControl{}) if count != 4 { t.Errorf("PBSAnalyticsModule failed at LogAmpObject") } - am.LogVideoObject(&analytics.VideoObject{}) + am.LogVideoObject(&analytics.VideoObject{}, privacy.ActivityControl{}) if count != 5 { t.Errorf("PBSAnalyticsModule failed at LogVideoObject") } - am.LogNotificationEventObject(&analytics.NotificationEvent{}) + am.LogNotificationEventObject(&analytics.NotificationEvent{}, privacy.ActivityControl{}) if count != 6 { t.Errorf("PBSAnalyticsModule failed at LogNotificationEventObject") } @@ -74,14 +75,14 @@ func (m *sampleModule) LogAmpObject(ao *analytics.AmpObject) { *m.count++ } func (m *sampleModule) LogNotificationEventObject(ne *analytics.NotificationEvent) { *m.count++ } -func initAnalytics(count *int) analytics.PBSAnalyticsModule { +func initAnalytics(count *int) analytics.Runner { modules := make(enabledAnalytics, 0) - modules = append(modules, &sampleModule{count}) + modules["sampleModule"] = &sampleModule{count} return &modules } func TestNewPBSAnalytics(t *testing.T) { - pbsAnalytics := NewPBSAnalytics(&config.Analytics{}) + pbsAnalytics := New(&config.Analytics{}) instance := pbsAnalytics.(enabledAnalytics) assert.Equal(t, len(instance), 0) @@ -94,7 +95,7 @@ func TestNewPBSAnalytics_FileLogger(t *testing.T) { } } defer os.RemoveAll(TEST_DIR) - mod := NewPBSAnalytics(&config.Analytics{File: config.FileLogs{Filename: TEST_DIR + "/test"}}) + mod := New(&config.Analytics{File: config.FileLogs{Filename: TEST_DIR + "/test"}}) switch modType := mod.(type) { case enabledAnalytics: if len(enabledAnalytics(modType)) != 1 { @@ -104,7 +105,7 @@ func TestNewPBSAnalytics_FileLogger(t *testing.T) { t.Fatalf("Failed to initialize analytics module") } - pbsAnalytics := NewPBSAnalytics(&config.Analytics{File: config.FileLogs{Filename: TEST_DIR + "/test"}}) + pbsAnalytics := New(&config.Analytics{File: config.FileLogs{Filename: TEST_DIR + "/test"}}) instance := pbsAnalytics.(enabledAnalytics) assert.Equal(t, len(instance), 1) @@ -112,7 +113,7 @@ func TestNewPBSAnalytics_FileLogger(t *testing.T) { func TestNewPBSAnalytics_Pubstack(t *testing.T) { - pbsAnalyticsWithoutError := NewPBSAnalytics(&config.Analytics{ + pbsAnalyticsWithoutError := New(&config.Analytics{ Pubstack: config.Pubstack{ Enabled: true, ScopeId: "scopeId", @@ -129,7 +130,7 @@ func TestNewPBSAnalytics_Pubstack(t *testing.T) { assert.Equal(t, len(instanceWithoutError), 1) - pbsAnalyticsWithError := NewPBSAnalytics(&config.Analytics{ + pbsAnalyticsWithError := New(&config.Analytics{ Pubstack: config.Pubstack{ Enabled: true, }, @@ -137,3 +138,88 @@ func TestNewPBSAnalytics_Pubstack(t *testing.T) { instanceWithError := pbsAnalyticsWithError.(enabledAnalytics) assert.Equal(t, len(instanceWithError), 0) } + +func TestSampleModuleActivitiesAllowed(t *testing.T) { + var count int + am := initAnalytics(&count) + + acAllowed := privacy.NewActivityControl(getDefaultActivityConfig("sampleModule", true)) + + ao := &analytics.AuctionObject{ + Status: http.StatusOK, + Errors: nil, + Response: &openrtb2.BidResponse{}, + } + + am.LogAuctionObject(ao, acAllowed) + if count != 1 { + t.Errorf("PBSAnalyticsModule failed at LogAuctionObject") + } + + am.LogAmpObject(&analytics.AmpObject{}, acAllowed) + if count != 2 { + t.Errorf("PBSAnalyticsModule failed at LogAmpObject") + } + + am.LogVideoObject(&analytics.VideoObject{}, acAllowed) + if count != 3 { + t.Errorf("PBSAnalyticsModule failed at LogVideoObject") + } + + am.LogNotificationEventObject(&analytics.NotificationEvent{}, acAllowed) + if count != 4 { + t.Errorf("PBSAnalyticsModule failed at LogNotificationEventObject") + } +} + +func TestSampleModuleActivitiesDenied(t *testing.T) { + var count int + am := initAnalytics(&count) + + acDenied := privacy.NewActivityControl(getDefaultActivityConfig("sampleModule", false)) + + ao := &analytics.AuctionObject{ + Status: http.StatusOK, + Errors: nil, + Response: &openrtb2.BidResponse{}, + } + + am.LogAuctionObject(ao, acDenied) + if count != 0 { + t.Errorf("PBSAnalyticsModule failed at LogAuctionObject") + } + + am.LogAmpObject(&analytics.AmpObject{}, acDenied) + if count != 0 { + t.Errorf("PBSAnalyticsModule failed at LogAmpObject") + } + + am.LogVideoObject(&analytics.VideoObject{}, acDenied) + if count != 0 { + t.Errorf("PBSAnalyticsModule failed at LogVideoObject") + } + + am.LogNotificationEventObject(&analytics.NotificationEvent{}, acDenied) + if count != 0 { + t.Errorf("PBSAnalyticsModule failed at LogNotificationEventObject") + } +} + +func getDefaultActivityConfig(componentName string, allow bool) *config.AccountPrivacy { + return &config.AccountPrivacy{ + AllowActivities: &config.AllowActivities{ + ReportAnalytics: config.Activity{ + Default: ptrutil.ToPtr(true), + Rules: []config.ActivityRule{ + { + Allow: allow, + Condition: config.ActivityCondition{ + ComponentName: []string{componentName}, + ComponentType: []string{"analytics"}, + }, + }, + }, + }, + }, + } +} diff --git a/analytics/core.go b/analytics/core.go index eca93741bd2..0279ae83868 100644 --- a/analytics/core.go +++ b/analytics/core.go @@ -9,10 +9,10 @@ import ( "github.com/prebid/prebid-server/openrtb_ext" ) -// PBSAnalyticsModule must be implemented by analytics modules to extract the required information and logging +// Module must be implemented by analytics modules to extract the required information and logging // activities. Do not use marshal the parameter objects directly as they can change over time. Use a separate // model for each analytics module and transform as appropriate. -type PBSAnalyticsModule interface { +type Module interface { LogAuctionObject(*AuctionObject) LogVideoObject(*VideoObject) LogCookieSyncObject(*CookieSyncObject) diff --git a/analytics/filesystem/file_module.go b/analytics/filesystem/file_module.go index 9a357529c3a..f055e4470b1 100644 --- a/analytics/filesystem/file_module.go +++ b/analytics/filesystem/file_module.go @@ -86,7 +86,7 @@ func (f *FileLogger) LogNotificationEventObject(ne *analytics.NotificationEvent) } // Method to initialize the analytic module -func NewFileLogger(filename string) (analytics.PBSAnalyticsModule, error) { +func NewFileLogger(filename string) (analytics.Module, error) { options := glog.LogOptions{ File: filename, Flag: glog.LstdFlags, diff --git a/analytics/pubstack/pubstack_module.go b/analytics/pubstack/pubstack_module.go index 987c935f884..f2d8726d356 100644 --- a/analytics/pubstack/pubstack_module.go +++ b/analytics/pubstack/pubstack_module.go @@ -50,7 +50,7 @@ type PubstackModule struct { clock clock.Clock } -func NewModule(client *http.Client, scope, endpoint, configRefreshDelay string, maxEventCount int, maxByteSize, maxTime string, clock clock.Clock) (analytics.PBSAnalyticsModule, error) { +func NewModule(client *http.Client, scope, endpoint, configRefreshDelay string, maxEventCount int, maxByteSize, maxTime string, clock clock.Clock) (analytics.Module, error) { configUpdateTask, err := NewConfigUpdateHttpTask( client, scope, @@ -63,7 +63,7 @@ func NewModule(client *http.Client, scope, endpoint, configRefreshDelay string, return NewModuleWithConfigTask(client, scope, endpoint, maxEventCount, maxByteSize, maxTime, configUpdateTask, clock) } -func NewModuleWithConfigTask(client *http.Client, scope, endpoint string, maxEventCount int, maxByteSize, maxTime string, configTask ConfigUpdateTask, clock clock.Clock) (analytics.PBSAnalyticsModule, error) { +func NewModuleWithConfigTask(client *http.Client, scope, endpoint string, maxEventCount int, maxByteSize, maxTime string, configTask ConfigUpdateTask, clock clock.Clock) (analytics.Module, error) { glog.Infof("[pubstack] Initializing module scope=%s endpoint=%s\n", scope, endpoint) // parse args diff --git a/analytics/pubstack/pubstack_module_test.go b/analytics/pubstack/pubstack_module_test.go index 504a1cfe17e..23e110df9c1 100644 --- a/analytics/pubstack/pubstack_module_test.go +++ b/analytics/pubstack/pubstack_module_test.go @@ -50,47 +50,47 @@ func TestNewModuleSuccess(t *testing.T) { tests := []struct { description string feature string - logObject func(analytics.PBSAnalyticsModule) + logObject func(analytics.Module) }{ { description: "auction events are only published when logging an auction object with auction feature on", feature: auction, - logObject: func(module analytics.PBSAnalyticsModule) { + logObject: func(module analytics.Module) { module.LogAuctionObject(&analytics.AuctionObject{Status: http.StatusOK}) }, }, { description: "AMP events are only published when logging an AMP object with AMP feature on", feature: amp, - logObject: func(module analytics.PBSAnalyticsModule) { + logObject: func(module analytics.Module) { module.LogAmpObject(&analytics.AmpObject{Status: http.StatusOK}) }, }, { description: "video events are only published when logging a video object with video feature on", feature: video, - logObject: func(module analytics.PBSAnalyticsModule) { + logObject: func(module analytics.Module) { module.LogVideoObject(&analytics.VideoObject{Status: http.StatusOK}) }, }, { description: "cookie events are only published when logging a cookie object with cookie feature on", feature: cookieSync, - logObject: func(module analytics.PBSAnalyticsModule) { + logObject: func(module analytics.Module) { module.LogCookieSyncObject(&analytics.CookieSyncObject{Status: http.StatusOK}) }, }, { description: "setUID events are only published when logging a setUID object with setUID feature on", feature: setUID, - logObject: func(module analytics.PBSAnalyticsModule) { + logObject: func(module analytics.Module) { module.LogSetUIDObject(&analytics.SetUIDObject{Status: http.StatusOK}) }, }, { description: "Ignore excluded fields from marshal", feature: auction, - logObject: func(module analytics.PBSAnalyticsModule) { + logObject: func(module analytics.Module) { module.LogAuctionObject(&analytics.AuctionObject{ RequestWrapper: &openrtb_ext.RequestWrapper{}, SeatNonBid: []openrtb_ext.SeatNonBid{ diff --git a/analytics/runner.go b/analytics/runner.go new file mode 100644 index 00000000000..08f67561f8a --- /dev/null +++ b/analytics/runner.go @@ -0,0 +1,14 @@ +package analytics + +import ( + "github.com/prebid/prebid-server/privacy" +) + +type Runner interface { + LogAuctionObject(*AuctionObject, privacy.ActivityControl) + LogVideoObject(*VideoObject, privacy.ActivityControl) + LogCookieSyncObject(*CookieSyncObject) + LogSetUIDObject(*SetUIDObject) + LogAmpObject(*AmpObject, privacy.ActivityControl) + LogNotificationEventObject(*NotificationEvent, privacy.ActivityControl) +} diff --git a/endpoints/cookie_sync.go b/endpoints/cookie_sync.go index bbee3847014..24530efa56a 100644 --- a/endpoints/cookie_sync.go +++ b/endpoints/cookie_sync.go @@ -50,7 +50,7 @@ func NewCookieSyncEndpoint( gdprPermsBuilder gdpr.PermissionsBuilder, tcf2CfgBuilder gdpr.TCF2ConfigBuilder, metrics metrics.MetricsEngine, - pbsAnalytics analytics.PBSAnalyticsModule, + analyticsRunner analytics.Runner, accountsFetcher stored_requests.AccountFetcher, bidders map[string]openrtb_ext.BidderName) HTTPRouterHandler { @@ -70,7 +70,7 @@ func NewCookieSyncEndpoint( bidderHashSet: bidderHashSet, }, metrics: metrics, - pbsAnalytics: pbsAnalytics, + pbsAnalytics: analyticsRunner, accountsFetcher: accountsFetcher, } } @@ -80,7 +80,7 @@ type cookieSyncEndpoint struct { config *config.Configuration privacyConfig usersyncPrivacyConfig metrics metrics.MetricsEngine - pbsAnalytics analytics.PBSAnalyticsModule + pbsAnalytics analytics.Runner accountsFetcher stored_requests.AccountFetcher } diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go index 80de2b5ff50..45f7a75da0c 100644 --- a/endpoints/cookie_sync_test.go +++ b/endpoints/cookie_sync_test.go @@ -42,7 +42,7 @@ func TestNewCookieSyncEndpoint(t *testing.T) { configGDPR = config.GDPR{HostVendorID: 42} configCCPAEnforce = true metrics = metrics.MetricsEngineMock{} - analytics = MockAnalytics{} + analytics = MockAnalyticsRunner{} fetcher = FakeAccountsFetcher{} bidders = map[string]openrtb_ext.BidderName{"bidderA": openrtb_ext.BidderName("bidderA"), "bidderB": openrtb_ext.BidderName("bidderB")} ) @@ -114,7 +114,7 @@ func TestCookieSyncHandle(t *testing.T) { expectedStatusCode int expectedBody string setMetricsExpectations func(*metrics.MetricsEngineMock) - setAnalyticsExpectations func(*MockAnalytics) + setAnalyticsExpectations func(*MockAnalyticsRunner) }{ { description: "Request With Cookie", @@ -133,7 +133,7 @@ func TestCookieSyncHandle(t *testing.T) { m.On("RecordCookieSync", metrics.CookieSyncOK).Once() m.On("RecordSyncerRequest", "aSyncer", metrics.SyncerCookieSyncOK).Once() }, - setAnalyticsExpectations: func(a *MockAnalytics) { + setAnalyticsExpectations: func(a *MockAnalyticsRunner) { expected := analytics.CookieSyncObject{ Status: 200, Errors: nil, @@ -165,7 +165,7 @@ func TestCookieSyncHandle(t *testing.T) { m.On("RecordCookieSync", metrics.CookieSyncOK).Once() m.On("RecordSyncerRequest", "aSyncer", metrics.SyncerCookieSyncOK).Once() }, - setAnalyticsExpectations: func(a *MockAnalytics) { + setAnalyticsExpectations: func(a *MockAnalyticsRunner) { expected := analytics.CookieSyncObject{ Status: 200, Errors: nil, @@ -194,7 +194,7 @@ func TestCookieSyncHandle(t *testing.T) { setMetricsExpectations: func(m *metrics.MetricsEngineMock) { m.On("RecordCookieSync", metrics.CookieSyncBadRequest).Once() }, - setAnalyticsExpectations: func(a *MockAnalytics) { + setAnalyticsExpectations: func(a *MockAnalyticsRunner) { expected := analytics.CookieSyncObject{ Status: 400, Errors: []error{errors.New("JSON parsing failed: invalid character 'm' looking for beginning of value")}, @@ -217,7 +217,7 @@ func TestCookieSyncHandle(t *testing.T) { setMetricsExpectations: func(m *metrics.MetricsEngineMock) { m.On("RecordCookieSync", metrics.CookieSyncOptOut).Once() }, - setAnalyticsExpectations: func(a *MockAnalytics) { + setAnalyticsExpectations: func(a *MockAnalyticsRunner) { expected := analytics.CookieSyncObject{ Status: 401, Errors: []error{errors.New("User has opted out")}, @@ -240,7 +240,7 @@ func TestCookieSyncHandle(t *testing.T) { setMetricsExpectations: func(m *metrics.MetricsEngineMock) { m.On("RecordCookieSync", metrics.CookieSyncGDPRHostCookieBlocked).Once() }, - setAnalyticsExpectations: func(a *MockAnalytics) { + setAnalyticsExpectations: func(a *MockAnalyticsRunner) { expected := analytics.CookieSyncObject{ Status: 200, Errors: nil, @@ -255,7 +255,7 @@ func TestCookieSyncHandle(t *testing.T) { mockMetrics := metrics.MetricsEngineMock{} test.setMetricsExpectations(&mockMetrics) - mockAnalytics := MockAnalytics{} + mockAnalytics := MockAnalyticsRunner{} test.setAnalyticsExpectations(&mockAnalytics) fakeAccountFetcher := FakeAccountsFetcher{} @@ -1248,7 +1248,7 @@ func TestSetCooperativeSync(t *testing.T) { func TestWriteParseRequestErrorMetrics(t *testing.T) { err := errors.New("anyError") - mockAnalytics := MockAnalytics{} + mockAnalytics := MockAnalyticsRunner{} mockAnalytics.On("LogCookieSyncObject", mock.Anything) writer := httptest.NewRecorder() @@ -1471,7 +1471,7 @@ func TestParseBidderFilter(t *testing.T) { func TestCookieSyncHandleError(t *testing.T) { err := errors.New("anyError") - mockAnalytics := MockAnalytics{} + mockAnalytics := MockAnalyticsRunner{} mockAnalytics.On("LogCookieSyncObject", mock.Anything) writer := httptest.NewRecorder() @@ -1664,7 +1664,7 @@ func TestCookieSyncHandleResponse(t *testing.T) { } for _, test := range testCases { - mockAnalytics := MockAnalytics{} + mockAnalytics := MockAnalyticsRunner{} mockAnalytics.On("LogCookieSyncObject", &test.expectedAnalytics).Once() cookie := usersync.NewCookie() @@ -1996,32 +1996,32 @@ func (m *MockSyncer) GetSync(syncTypes []usersync.SyncType, privacyMacros macros return args.Get(0).(usersync.Sync), args.Error(1) } -type MockAnalytics struct { +type MockAnalyticsRunner struct { mock.Mock } -func (m *MockAnalytics) LogAuctionObject(obj *analytics.AuctionObject) { - m.Called(obj) +func (m *MockAnalyticsRunner) LogAuctionObject(obj *analytics.AuctionObject, ac privacy.ActivityControl) { + m.Called(obj, ac) } -func (m *MockAnalytics) LogVideoObject(obj *analytics.VideoObject) { - m.Called(obj) +func (m *MockAnalyticsRunner) LogVideoObject(obj *analytics.VideoObject, ac privacy.ActivityControl) { + m.Called(obj, ac) } -func (m *MockAnalytics) LogCookieSyncObject(obj *analytics.CookieSyncObject) { +func (m *MockAnalyticsRunner) LogCookieSyncObject(obj *analytics.CookieSyncObject) { m.Called(obj) } -func (m *MockAnalytics) LogSetUIDObject(obj *analytics.SetUIDObject) { +func (m *MockAnalyticsRunner) LogSetUIDObject(obj *analytics.SetUIDObject) { m.Called(obj) } -func (m *MockAnalytics) LogAmpObject(obj *analytics.AmpObject) { - m.Called(obj) +func (m *MockAnalyticsRunner) LogAmpObject(obj *analytics.AmpObject, ac privacy.ActivityControl) { + m.Called(obj, ac) } -func (m *MockAnalytics) LogNotificationEventObject(obj *analytics.NotificationEvent) { - m.Called(obj) +func (m *MockAnalyticsRunner) LogNotificationEventObject(obj *analytics.NotificationEvent, ac privacy.ActivityControl) { + m.Called(obj, ac) } type MockGDPRPerms struct { diff --git a/endpoints/events/event.go b/endpoints/events/event.go index 7f923eda09d..d5cf89b2ef5 100644 --- a/endpoints/events/event.go +++ b/endpoints/events/event.go @@ -16,6 +16,7 @@ import ( "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/metrics" + "github.com/prebid/prebid-server/privacy" "github.com/prebid/prebid-server/stored_requests" "github.com/prebid/prebid-server/util/httputil" ) @@ -40,13 +41,13 @@ const integrationParamMaxLength = 64 type eventEndpoint struct { Accounts stored_requests.AccountFetcher - Analytics analytics.PBSAnalyticsModule + Analytics analytics.Runner Cfg *config.Configuration TrackingPixel *httputil.Pixel MetricsEngine metrics.MetricsEngine } -func NewEventEndpoint(cfg *config.Configuration, accounts stored_requests.AccountFetcher, analytics analytics.PBSAnalyticsModule, me metrics.MetricsEngine) httprouter.Handle { +func NewEventEndpoint(cfg *config.Configuration, accounts stored_requests.AccountFetcher, analytics analytics.Runner, me metrics.MetricsEngine) httprouter.Handle { ee := &eventEndpoint{ Accounts: accounts, Analytics: analytics, @@ -114,11 +115,13 @@ func (e *eventEndpoint) Handle(w http.ResponseWriter, r *http.Request, _ httprou return } + activities := privacy.NewActivityControl(&account.Privacy) + // handle notification event e.Analytics.LogNotificationEventObject(&analytics.NotificationEvent{ Request: eventRequest, Account: account, - }) + }, activities) // Add tracking pixel if format == image if eventRequest.Format == analytics.Image { diff --git a/endpoints/events/event_test.go b/endpoints/events/event_test.go index 7f129634221..d721187b6ff 100644 --- a/endpoints/events/event_test.go +++ b/endpoints/events/event_test.go @@ -16,6 +16,7 @@ import ( "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/metrics" + "github.com/prebid/prebid-server/privacy" "github.com/prebid/prebid-server/stored_requests" "github.com/stretchr/testify/assert" ) @@ -26,13 +27,13 @@ type eventsMockAnalyticsModule struct { Invoked bool } -func (e *eventsMockAnalyticsModule) LogAuctionObject(ao *analytics.AuctionObject) { +func (e *eventsMockAnalyticsModule) LogAuctionObject(ao *analytics.AuctionObject, _ privacy.ActivityControl) { if e.Fail { panic(e.Error) } } -func (e *eventsMockAnalyticsModule) LogVideoObject(vo *analytics.VideoObject) { +func (e *eventsMockAnalyticsModule) LogVideoObject(vo *analytics.VideoObject, _ privacy.ActivityControl) { if e.Fail { panic(e.Error) } @@ -50,13 +51,13 @@ func (e *eventsMockAnalyticsModule) LogSetUIDObject(so *analytics.SetUIDObject) } } -func (e *eventsMockAnalyticsModule) LogAmpObject(ao *analytics.AmpObject) { +func (e *eventsMockAnalyticsModule) LogAmpObject(ao *analytics.AmpObject, _ privacy.ActivityControl) { if e.Fail { panic(e.Error) } } -func (e *eventsMockAnalyticsModule) LogNotificationEventObject(ne *analytics.NotificationEvent) { +func (e *eventsMockAnalyticsModule) LogNotificationEventObject(ne *analytics.NotificationEvent, _ privacy.ActivityControl) { if e.Fail { panic(e.Error) } diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index aa80d0756c3..76762d8b9ea 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -11,8 +11,6 @@ import ( "strings" "time" - "github.com/prebid/prebid-server/privacy" - "github.com/buger/jsonparser" "github.com/golang/glog" "github.com/julienschmidt/httprouter" @@ -33,6 +31,7 @@ import ( "github.com/prebid/prebid-server/hooks" "github.com/prebid/prebid-server/metrics" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/privacy" "github.com/prebid/prebid-server/stored_requests" "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" "github.com/prebid/prebid-server/stored_responses" @@ -64,7 +63,7 @@ func NewAmpEndpoint( accounts stored_requests.AccountFetcher, cfg *config.Configuration, metricsEngine metrics.MetricsEngine, - pbsAnalytics analytics.PBSAnalyticsModule, + analyticsRunner analytics.Runner, disabledBidders map[string]string, defReqJSON []byte, bidderMap map[string]openrtb_ext.BidderName, @@ -93,7 +92,7 @@ func NewAmpEndpoint( accounts, cfg, metricsEngine, - pbsAnalytics, + analyticsRunner, disabledBidders, defRequest, defReqJSON, @@ -134,11 +133,12 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h CookieFlag: metrics.CookieFlagUnknown, RequestStatus: metrics.RequestStatusOK, } + activityControl := privacy.ActivityControl{} defer func() { deps.metricsEngine.RecordRequest(labels) deps.metricsEngine.RecordRequestTime(labels, time.Since(start)) - deps.analytics.LogAmpObject(&ao) + deps.analytics.LogAmpObject(&ao, activityControl) }() // Add AMP headers @@ -230,7 +230,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h tcf2Config := gdpr.NewTCF2Config(deps.cfg.GDPR.TCF2, account.GDPR) - activityControl := privacy.NewActivityControl(&account.Privacy) + activityControl = privacy.NewActivityControl(&account.Privacy) secGPC := r.Header.Get("Sec-GPC") diff --git a/endpoints/openrtb2/amp_auction_test.go b/endpoints/openrtb2/amp_auction_test.go index 89d9c472925..3c0feb4f7ab 100644 --- a/endpoints/openrtb2/amp_auction_test.go +++ b/endpoints/openrtb2/amp_auction_test.go @@ -20,7 +20,7 @@ import ( "github.com/prebid/prebid-server/amp" "github.com/prebid/prebid-server/analytics" - analyticsConf "github.com/prebid/prebid-server/analytics/config" + analyticsBuild "github.com/prebid/prebid-server/analytics/build" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/exchange" @@ -30,6 +30,7 @@ import ( "github.com/prebid/prebid-server/metrics" metricsConfig "github.com/prebid/prebid-server/metrics/config" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/privacy" "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" ) @@ -201,7 +202,7 @@ func TestAMPPageInfo(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -305,7 +306,7 @@ func TestGDPRConsent(t *testing.T) { GDPR: config.GDPR{Enabled: true}, }, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -729,7 +730,7 @@ func TestCCPAConsent(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -843,7 +844,7 @@ func TestConsentWarnings(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -942,7 +943,7 @@ func TestNewAndLegacyConsentBothProvided(t *testing.T) { GDPR: config.GDPR{Enabled: true}, }, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -997,7 +998,7 @@ func TestAMPSiteExt(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), nil, nil, openrtb_ext.BuildBidderMap(), @@ -1040,7 +1041,7 @@ func TestAmpBadRequests(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -1074,7 +1075,7 @@ func TestAmpDebug(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -1210,7 +1211,7 @@ func TestQueryParamOverrides(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -1368,7 +1369,7 @@ func (s formatOverrideSpec) execute(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -1631,25 +1632,25 @@ type mockLogger struct { auctionObject *analytics.AuctionObject } -func newMockLogger(ao *analytics.AmpObject, aucObj *analytics.AuctionObject) analytics.PBSAnalyticsModule { +func newMockLogger(ao *analytics.AmpObject, aucObj *analytics.AuctionObject) analytics.Runner { return &mockLogger{ ampObject: ao, auctionObject: aucObj, } } -func (logger mockLogger) LogAuctionObject(ao *analytics.AuctionObject) { +func (logger mockLogger) LogAuctionObject(ao *analytics.AuctionObject, _ privacy.ActivityControl) { *logger.auctionObject = *ao } -func (logger mockLogger) LogVideoObject(vo *analytics.VideoObject) { +func (logger mockLogger) LogVideoObject(vo *analytics.VideoObject, _ privacy.ActivityControl) { } func (logger mockLogger) LogCookieSyncObject(cookieObject *analytics.CookieSyncObject) { } func (logger mockLogger) LogSetUIDObject(uuidObj *analytics.SetUIDObject) { } -func (logger mockLogger) LogNotificationEventObject(uuidObj *analytics.NotificationEvent) { +func (logger mockLogger) LogNotificationEventObject(uuidObj *analytics.NotificationEvent, _ privacy.ActivityControl) { } -func (logger mockLogger) LogAmpObject(ao *analytics.AmpObject) { +func (logger mockLogger) LogAmpObject(ao *analytics.AmpObject, _ privacy.ActivityControl) { *logger.ampObject = *ao } @@ -1962,7 +1963,7 @@ func TestAmpAuctionResponseHeaders(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -1998,7 +1999,7 @@ func TestRequestWithTargeting(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), nil, nil, openrtb_ext.BuildBidderMap(), diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index b625c0ff54c..4fce4c15786 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -14,8 +14,6 @@ import ( "strings" "time" - "github.com/prebid/prebid-server/privacy" - "github.com/buger/jsonparser" "github.com/gofrs/uuid" "github.com/golang/glog" @@ -30,6 +28,7 @@ import ( "github.com/prebid/prebid-server/bidadjustment" "github.com/prebid/prebid-server/hooks" "github.com/prebid/prebid-server/ortb" + "github.com/prebid/prebid-server/privacy" "golang.org/x/net/publicsuffix" jsonpatch "gopkg.in/evanphx/json-patch.v4" @@ -89,7 +88,7 @@ func NewEndpoint( accounts stored_requests.AccountFetcher, cfg *config.Configuration, metricsEngine metrics.MetricsEngine, - pbsAnalytics analytics.PBSAnalyticsModule, + analyticsRunner analytics.Runner, disabledBidders map[string]string, defReqJSON []byte, bidderMap map[string]openrtb_ext.BidderName, @@ -117,7 +116,7 @@ func NewEndpoint( accounts, cfg, metricsEngine, - pbsAnalytics, + analyticsRunner, disabledBidders, defRequest, defReqJSON, @@ -139,7 +138,7 @@ type endpointDeps struct { accounts stored_requests.AccountFetcher cfg *config.Configuration metricsEngine metrics.MetricsEngine - analytics analytics.PBSAnalyticsModule + analytics analytics.Runner disabledBidders map[string]string defaultRequest bool defReqJSON []byte @@ -176,10 +175,12 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http CookieFlag: metrics.CookieFlagUnknown, RequestStatus: metrics.RequestStatusOK, } + + activityControl := privacy.ActivityControl{} defer func() { deps.metricsEngine.RecordRequest(labels) deps.metricsEngine.RecordRequestTime(labels, time.Since(start)) - deps.analytics.LogAuctionObject(&ao) + deps.analytics.LogAuctionObject(&ao, activityControl) }() w.Header().Set("X-Prebid", version.BuildXPrebidHeader(version.Ver)) @@ -197,7 +198,7 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http tcf2Config := gdpr.NewTCF2Config(deps.cfg.GDPR.TCF2, account.GDPR) - activityControl := privacy.NewActivityControl(&account.Privacy) + activityControl = privacy.NewActivityControl(&account.Privacy) ctx := context.Background() diff --git a/endpoints/openrtb2/auction_benchmark_test.go b/endpoints/openrtb2/auction_benchmark_test.go index ee74548ea47..f3e82dca099 100644 --- a/endpoints/openrtb2/auction_benchmark_test.go +++ b/endpoints/openrtb2/auction_benchmark_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - analyticsConf "github.com/prebid/prebid-server/analytics/config" + analyticsBuild "github.com/prebid/prebid-server/analytics/build" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/currency" "github.com/prebid/prebid-server/exchange" @@ -105,7 +105,7 @@ func BenchmarkOpenrtbEndpoint(b *testing.B) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, nilMetrics, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, nil, diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index b5631c93d3d..55bf68ff730 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -23,7 +23,7 @@ import ( nativeRequests "github.com/prebid/openrtb/v19/native1/request" "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/analytics" - analyticsConf "github.com/prebid/prebid-server/analytics/config" + analyticsBuild "github.com/prebid/prebid-server/analytics/build" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/exchange" @@ -447,7 +447,7 @@ func TestExplicitUserId(t *testing.T) { empty_fetcher.EmptyFetcher{}, cfg, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -505,7 +505,7 @@ func doBadAliasRequest(t *testing.T, filename string, expectMsg string) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), disabledBidders, aliasJSON, bidderMap, @@ -560,7 +560,7 @@ func TestNilExchange(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), map[string]string{}, + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, @@ -585,7 +585,7 @@ func TestNilValidator(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -611,7 +611,7 @@ func TestExchangeError(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -738,7 +738,7 @@ func TestImplicitIPsEndToEnd(t *testing.T) { empty_fetcher.EmptyFetcher{}, cfg, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -938,7 +938,7 @@ func TestImplicitDNTEndToEnd(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -1175,7 +1175,7 @@ func TestStoredRequests(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -1624,7 +1624,7 @@ func TestValidateRequest(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -2403,7 +2403,7 @@ func TestSetIntegrationType(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -2469,7 +2469,7 @@ func TestStoredRequestGenerateUuid(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -2573,7 +2573,7 @@ func TestOversizedRequest(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(len(reqBody) - 1)}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -2612,7 +2612,7 @@ func TestRequestSizeEdgeCase(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(len(reqBody))}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -2649,7 +2649,7 @@ func TestNoEncoding(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -2734,7 +2734,7 @@ func TestContentType(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -2951,7 +2951,7 @@ func TestValidateImpExt(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(8096)}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{"disabledbidder": "The bidder 'disabledbidder' has been disabled."}, false, []byte{}, @@ -3006,7 +3006,7 @@ func TestCurrencyTrunc(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -3054,7 +3054,7 @@ func TestCCPAInvalid(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -3106,7 +3106,7 @@ func TestNoSaleInvalid(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -3161,7 +3161,7 @@ func TestValidateSourceTID(t *testing.T) { empty_fetcher.EmptyFetcher{}, cfg, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -3206,7 +3206,7 @@ func TestSChainInvalid(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -3774,7 +3774,7 @@ func TestEidPermissionsInvalid(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -4028,7 +4028,7 @@ func TestIOS14EndToEnd(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -4091,7 +4091,7 @@ func TestAuctionWarnings(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -4137,7 +4137,7 @@ func TestParseRequestParseImpInfoError(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(len(reqBody))}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -4217,7 +4217,7 @@ func TestParseGzipedRequest(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(50), Compression: config.Compression{Request: config.CompressionInfo{GZIP: false}}}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -4716,7 +4716,7 @@ func TestAuctionResponseHeaders(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -4817,7 +4817,7 @@ func TestParseRequestMergeBidderParams(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(len(test.givenRequestBody))}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -4920,7 +4920,7 @@ func TestParseRequestStoredResponses(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(len(test.givenRequestBody))}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -5018,7 +5018,7 @@ func TestParseRequestStoredBidResponses(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(len(test.givenRequestBody))}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -5054,7 +5054,7 @@ func TestValidateStoredResp(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -5867,7 +5867,7 @@ func TestParseRequestMultiBid(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(len(test.givenRequestBody))}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, diff --git a/endpoints/openrtb2/test_utils.go b/endpoints/openrtb2/test_utils.go index 2d22f1e4ebe..365f480eb4c 100644 --- a/endpoints/openrtb2/test_utils.go +++ b/endpoints/openrtb2/test_utils.go @@ -20,7 +20,7 @@ import ( "github.com/prebid/openrtb/v19/openrtb3" "github.com/prebid/prebid-server/adapters" "github.com/prebid/prebid-server/analytics" - analyticsConf "github.com/prebid/prebid-server/analytics/config" + analyticsBuild "github.com/prebid/prebid-server/analytics/build" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/currency" "github.com/prebid/prebid-server/errortypes" @@ -1275,7 +1275,7 @@ func buildTestEndpoint(test testCase, cfg *config.Configuration) (httprouter.Han planBuilder = hooks.EmptyPlanBuilder{} } - var endpointBuilder func(uuidutil.UUIDGenerator, exchange.Exchange, openrtb_ext.BidderParamValidator, stored_requests.Fetcher, stored_requests.AccountFetcher, *config.Configuration, metrics.MetricsEngine, analytics.PBSAnalyticsModule, map[string]string, []byte, map[string]openrtb_ext.BidderName, stored_requests.Fetcher, hooks.ExecutionPlanBuilder, *exchange.TmaxAdjustmentsPreprocessed) (httprouter.Handle, error) + var endpointBuilder func(uuidutil.UUIDGenerator, exchange.Exchange, openrtb_ext.BidderParamValidator, stored_requests.Fetcher, stored_requests.AccountFetcher, *config.Configuration, metrics.MetricsEngine, analytics.Runner, map[string]string, []byte, map[string]openrtb_ext.BidderName, stored_requests.Fetcher, hooks.ExecutionPlanBuilder, *exchange.TmaxAdjustmentsPreprocessed) (httprouter.Handle, error) switch test.endpointType { case AMP_ENDPOINT: @@ -1292,7 +1292,7 @@ func buildTestEndpoint(test testCase, cfg *config.Configuration) (httprouter.Han accountFetcher, cfg, met, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), disabledBidders, []byte(test.Config.AliasJSON), bidderMap, diff --git a/endpoints/openrtb2/video_auction.go b/endpoints/openrtb2/video_auction.go index 7b2a7a5295a..fc6d2a91a62 100644 --- a/endpoints/openrtb2/video_auction.go +++ b/endpoints/openrtb2/video_auction.go @@ -52,7 +52,7 @@ func NewVideoEndpoint( accounts stored_requests.AccountFetcher, cfg *config.Configuration, met metrics.MetricsEngine, - pbsAnalytics analytics.PBSAnalyticsModule, + analyticsRunner analytics.Runner, disabledBidders map[string]string, defReqJSON []byte, bidderMap map[string]openrtb_ext.BidderName, @@ -82,7 +82,7 @@ func NewVideoEndpoint( accounts, cfg, met, - pbsAnalytics, + analyticsRunner, disabledBidders, defRequest, defReqJSON, @@ -149,6 +149,8 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re } debugLog.DebugEnabledOrOverridden = debugLog.Enabled || debugLog.DebugOverride + activityControl := privacy.ActivityControl{} + defer func() { if len(debugLog.CacheKey) > 0 && vo.VideoResponse == nil { err := debugLog.PutDebugLogError(deps.cache, deps.cfg.CacheURL.ExpectedTimeMillis, vo.Errors) @@ -158,7 +160,7 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re } deps.metricsEngine.RecordRequest(labels) deps.metricsEngine.RecordRequestTime(labels, time.Since(start)) - deps.analytics.LogVideoObject(&vo) + deps.analytics.LogVideoObject(&vo, activityControl) }() w.Header().Set("X-Prebid", version.BuildXPrebidHeader(version.Ver)) @@ -303,7 +305,7 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re return } - activityControl := privacy.NewActivityControl(&account.Privacy) + activityControl = privacy.NewActivityControl(&account.Privacy) secGPC := r.Header.Get("Sec-GPC") auctionRequest := &exchange.AuctionRequest{ diff --git a/endpoints/openrtb2/video_auction_test.go b/endpoints/openrtb2/video_auction_test.go index f3135ff48db..181a68929ed 100644 --- a/endpoints/openrtb2/video_auction_test.go +++ b/endpoints/openrtb2/video_auction_test.go @@ -12,7 +12,7 @@ import ( "testing" "github.com/prebid/prebid-server/analytics" - analyticsConf "github.com/prebid/prebid-server/analytics/config" + analyticsBuild "github.com/prebid/prebid-server/analytics/build" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/exchange" @@ -21,6 +21,7 @@ import ( metricsConfig "github.com/prebid/prebid-server/metrics/config" "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/prebid_cache_client" + "github.com/prebid/prebid-server/privacy" "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" "github.com/prebid/prebid-server/util/ptrutil" @@ -1235,11 +1236,11 @@ type mockAnalyticsModule struct { videoObjects []*analytics.VideoObject } -func (m *mockAnalyticsModule) LogAuctionObject(ao *analytics.AuctionObject) { +func (m *mockAnalyticsModule) LogAuctionObject(ao *analytics.AuctionObject, _ privacy.ActivityControl) { m.auctionObjects = append(m.auctionObjects, ao) } -func (m *mockAnalyticsModule) LogVideoObject(vo *analytics.VideoObject) { +func (m *mockAnalyticsModule) LogVideoObject(vo *analytics.VideoObject, _ privacy.ActivityControl) { m.videoObjects = append(m.videoObjects, vo) } @@ -1247,9 +1248,10 @@ func (m *mockAnalyticsModule) LogCookieSyncObject(cso *analytics.CookieSyncObjec func (m *mockAnalyticsModule) LogSetUIDObject(so *analytics.SetUIDObject) {} -func (m *mockAnalyticsModule) LogAmpObject(ao *analytics.AmpObject) {} +func (m *mockAnalyticsModule) LogAmpObject(ao *analytics.AmpObject, _ privacy.ActivityControl) {} -func (m *mockAnalyticsModule) LogNotificationEventObject(ne *analytics.NotificationEvent) {} +func (m *mockAnalyticsModule) LogNotificationEventObject(ne *analytics.NotificationEvent, _ privacy.ActivityControl) { +} func mockDeps(t *testing.T, ex *mockExchangeVideo) *endpointDeps { return &endpointDeps{ @@ -1261,7 +1263,7 @@ func mockDeps(t *testing.T, ex *mockExchangeVideo) *endpointDeps { &mockAccountFetcher{data: mockVideoAccountData}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -1285,7 +1287,7 @@ func mockDepsAppendBidderNames(t *testing.T, ex *mockExchangeAppendBidderNames) empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -1311,7 +1313,7 @@ func mockDepsNoBids(t *testing.T, ex *mockExchangeVideoNoBids) *endpointDeps { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, diff --git a/endpoints/setuid.go b/endpoints/setuid.go index 520a133b51e..1bf3b575273 100644 --- a/endpoints/setuid.go +++ b/endpoints/setuid.go @@ -36,7 +36,7 @@ const ( const uidCookieName = "uids" -func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]usersync.Syncer, gdprPermsBuilder gdpr.PermissionsBuilder, tcf2CfgBuilder gdpr.TCF2ConfigBuilder, pbsanalytics analytics.PBSAnalyticsModule, accountsFetcher stored_requests.AccountFetcher, metricsEngine metrics.MetricsEngine) httprouter.Handle { +func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]usersync.Syncer, gdprPermsBuilder gdpr.PermissionsBuilder, tcf2CfgBuilder gdpr.TCF2ConfigBuilder, analyticsRunner analytics.Runner, accountsFetcher stored_requests.AccountFetcher, metricsEngine metrics.MetricsEngine) httprouter.Handle { encoder := usersync.Base64Encoder{} decoder := usersync.Base64Decoder{} @@ -46,7 +46,7 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use Errors: make([]error, 0), } - defer pbsanalytics.LogSetUIDObject(&so) + defer analyticsRunner.LogSetUIDObject(&so) cookie := usersync.ReadCookie(r, decoder, &cfg.HostCookie) if !cookie.AllowSyncs() { diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go index 18099193045..3636f7fbbdc 100644 --- a/endpoints/setuid_test.go +++ b/endpoints/setuid_test.go @@ -13,6 +13,7 @@ import ( "time" "github.com/prebid/prebid-server/analytics" + analyticsBuild "github.com/prebid/prebid-server/analytics/build" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/gdpr" @@ -22,7 +23,6 @@ import ( "github.com/prebid/prebid-server/usersync" "github.com/stretchr/testify/assert" - analyticsConf "github.com/prebid/prebid-server/analytics/config" metricsConf "github.com/prebid/prebid-server/metrics/config" ) @@ -328,7 +328,7 @@ func TestSetUIDEndpoint(t *testing.T) { }, } - analytics := analyticsConf.NewPBSAnalytics(&config.Analytics{}) + analytics := analyticsBuild.New(&config.Analytics{}) metrics := &metricsConf.NilMetricsEngine{} for _, test := range testCases { @@ -362,7 +362,7 @@ func TestSetUIDEndpoint(t *testing.T) { func TestSetUIDPriorityEjection(t *testing.T) { decoder := usersync.Base64Decoder{} - analytics := analyticsConf.NewPBSAnalytics(&config.Analytics{}) + analytics := analyticsBuild.New(&config.Analytics{}) syncersByBidder := map[string]string{ "pubmatic": "pubmatic", "syncer1": "syncer1", @@ -1093,7 +1093,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { cfgAccountRequired bool expectedResponseCode int expectedMetrics func(*metrics.MetricsEngineMock) - expectedAnalytics func(*MockAnalytics) + expectedAnalytics func(*MockAnalyticsRunner) }{ { description: "Success - Sync", @@ -1106,7 +1106,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { m.On("RecordSetUid", metrics.SetUidOK).Once() m.On("RecordSyncerSet", "pubmatic", metrics.SyncerSetUidOK).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 200, Bidder: "pubmatic", @@ -1128,7 +1128,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { m.On("RecordSetUid", metrics.SetUidOK).Once() m.On("RecordSyncerSet", "pubmatic", metrics.SyncerSetUidCleared).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 200, Bidder: "pubmatic", @@ -1149,7 +1149,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { expectedMetrics: func(m *metrics.MetricsEngineMock) { m.On("RecordSetUid", metrics.SetUidOptOut).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 401, Bidder: "", @@ -1170,7 +1170,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { expectedMetrics: func(m *metrics.MetricsEngineMock) { m.On("RecordSetUid", metrics.SetUidSyncerUnknown).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 400, Bidder: "", @@ -1191,7 +1191,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { expectedMetrics: func(m *metrics.MetricsEngineMock) { m.On("RecordSetUid", metrics.SetUidBadRequest).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 400, Bidder: "pubmatic", @@ -1212,7 +1212,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { expectedMetrics: func(m *metrics.MetricsEngineMock) { m.On("RecordSetUid", metrics.SetUidBadRequest).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 400, Bidder: "pubmatic", @@ -1233,7 +1233,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { expectedMetrics: func(m *metrics.MetricsEngineMock) { m.On("RecordSetUid", metrics.SetUidGDPRHostCookieBlocked).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 451, Bidder: "pubmatic", @@ -1255,7 +1255,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { expectedMetrics: func(m *metrics.MetricsEngineMock) { m.On("RecordSetUid", metrics.SetUidAccountInvalid).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 400, Bidder: "pubmatic", @@ -1277,7 +1277,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { expectedMetrics: func(m *metrics.MetricsEngineMock) { m.On("RecordSetUid", metrics.SetUidAccountConfigMalformed).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 400, Bidder: "pubmatic", @@ -1299,7 +1299,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { expectedMetrics: func(m *metrics.MetricsEngineMock) { m.On("RecordSetUid", metrics.SetUidBadRequest).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 400, Bidder: "pubmatic", @@ -1313,7 +1313,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { } for _, test := range testCases { - analyticsEngine := &MockAnalytics{} + analyticsEngine := &MockAnalyticsRunner{} test.expectedAnalytics(analyticsEngine) metricsEngine := &metrics.MetricsEngineMock{} @@ -1337,7 +1337,7 @@ func TestOptedOut(t *testing.T) { cookie.SetOptOut(true) addCookie(request, cookie) syncersBidderNameToKey := map[string]string{"pubmatic": "pubmatic"} - analytics := analyticsConf.NewPBSAnalytics(&config.Analytics{}) + analytics := analyticsBuild.New(&config.Analytics{}) metrics := &metricsConf.NilMetricsEngine{} response := doRequest(request, analytics, metrics, syncersBidderNameToKey, true, false, false, false, 0, nil) @@ -1525,7 +1525,7 @@ func makeRequest(uri string, existingSyncs map[string]string) *http.Request { return request } -func doRequest(req *http.Request, analytics analytics.PBSAnalyticsModule, metrics metrics.MetricsEngine, syncersBidderNameToKey map[string]string, gdprAllowsHostCookies, gdprReturnsError, gdprReturnsMalformedError, cfgAccountRequired bool, maxCookieSize int, priorityGroups [][]string) *httptest.ResponseRecorder { +func doRequest(req *http.Request, analytics analytics.Runner, metrics metrics.MetricsEngine, syncersBidderNameToKey map[string]string, gdprAllowsHostCookies, gdprReturnsError, gdprReturnsMalformedError, cfgAccountRequired bool, maxCookieSize int, priorityGroups [][]string) *httptest.ResponseRecorder { cfg := config.Configuration{ AccountRequired: cfgAccountRequired, AccountDefaults: config.Account{}, diff --git a/router/router.go b/router/router.go index f2b1f7e7447..29bd8382e78 100644 --- a/router/router.go +++ b/router/router.go @@ -10,7 +10,7 @@ import ( "strings" "time" - analyticsConf "github.com/prebid/prebid-server/analytics/config" + analyticsBuild "github.com/prebid/prebid-server/analytics/build" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/currency" "github.com/prebid/prebid-server/endpoints" @@ -191,7 +191,7 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R // todo(zachbadgett): better shutdown r.Shutdown = shutdown - pbsAnalytics := analyticsConf.NewPBSAnalytics(&cfg.Analytics) + analyticsRunner := analyticsBuild.New(&cfg.Analytics) paramsValidator, err := openrtb_ext.NewBidderParamsValidator(schemaDirectory) if err != nil { @@ -228,17 +228,17 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R macroReplacer := macros.NewStringIndexBasedReplacer() theExchange := exchange.NewExchange(adapters, cacheClient, cfg, syncersByBidder, r.MetricsEngine, cfg.BidderInfos, gdprPermsBuilder, rateConvertor, categoriesFetcher, adsCertSigner, macroReplacer) var uuidGenerator uuidutil.UUIDRandomGenerator - openrtbEndpoint, err := openrtb2.NewEndpoint(uuidGenerator, theExchange, paramsValidator, fetcher, accounts, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBidders, storedRespFetcher, planBuilder, tmaxAdjustments) + openrtbEndpoint, err := openrtb2.NewEndpoint(uuidGenerator, theExchange, paramsValidator, fetcher, accounts, cfg, r.MetricsEngine, analyticsRunner, disabledBidders, defReqJSON, activeBidders, storedRespFetcher, planBuilder, tmaxAdjustments) if err != nil { glog.Fatalf("Failed to create the openrtb2 endpoint handler. %v", err) } - ampEndpoint, err := openrtb2.NewAmpEndpoint(uuidGenerator, theExchange, paramsValidator, ampFetcher, accounts, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBidders, storedRespFetcher, planBuilder, tmaxAdjustments) + ampEndpoint, err := openrtb2.NewAmpEndpoint(uuidGenerator, theExchange, paramsValidator, ampFetcher, accounts, cfg, r.MetricsEngine, analyticsRunner, disabledBidders, defReqJSON, activeBidders, storedRespFetcher, planBuilder, tmaxAdjustments) if err != nil { glog.Fatalf("Failed to create the amp endpoint handler. %v", err) } - videoEndpoint, err := openrtb2.NewVideoEndpoint(uuidGenerator, theExchange, paramsValidator, fetcher, videoFetcher, accounts, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBidders, cacheClient, tmaxAdjustments) + videoEndpoint, err := openrtb2.NewVideoEndpoint(uuidGenerator, theExchange, paramsValidator, fetcher, videoFetcher, accounts, cfg, r.MetricsEngine, analyticsRunner, disabledBidders, defReqJSON, activeBidders, cacheClient, tmaxAdjustments) if err != nil { glog.Fatalf("Failed to create the video endpoint handler. %v", err) } @@ -254,7 +254,7 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R r.GET("/info/bidders", infoEndpoints.NewBiddersEndpoint(cfg.BidderInfos, defaultAliases)) r.GET("/info/bidders/:bidderName", infoEndpoints.NewBiddersDetailEndpoint(cfg.BidderInfos, defaultAliases)) r.GET("/bidders/params", NewJsonDirectoryServer(schemaDirectory, paramsValidator, defaultAliases)) - r.POST("/cookie_sync", endpoints.NewCookieSyncEndpoint(syncersByBidder, cfg, gdprPermsBuilder, tcf2CfgBuilder, r.MetricsEngine, pbsAnalytics, accounts, activeBidders).Handle) + r.POST("/cookie_sync", endpoints.NewCookieSyncEndpoint(syncersByBidder, cfg, gdprPermsBuilder, tcf2CfgBuilder, r.MetricsEngine, analyticsRunner, accounts, activeBidders).Handle) r.GET("/status", endpoints.NewStatusEndpoint(cfg.StatusResponse)) r.GET("/", serveIndex) r.Handler("GET", "/version", endpoints.NewVersionEndpoint(version.Ver, version.Rev)) @@ -267,7 +267,7 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R } // event endpoint - eventEndpoint := events.NewEventEndpoint(cfg, accounts, pbsAnalytics, r.MetricsEngine) + eventEndpoint := events.NewEventEndpoint(cfg, accounts, analyticsRunner, r.MetricsEngine) r.GET("/event", eventEndpoint) userSyncDeps := &pbs.UserSyncDeps{ @@ -277,7 +277,7 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R PriorityGroups: cfg.UserSync.PriorityGroups, } - r.GET("/setuid", endpoints.NewSetUIDEndpoint(cfg, syncersByBidder, gdprPermsBuilder, tcf2CfgBuilder, pbsAnalytics, accounts, r.MetricsEngine)) + r.GET("/setuid", endpoints.NewSetUIDEndpoint(cfg, syncersByBidder, gdprPermsBuilder, tcf2CfgBuilder, analyticsRunner, accounts, r.MetricsEngine)) r.GET("/getuids", endpoints.NewGetUIDsEndpoint(cfg.HostCookie)) r.POST("/optout", userSyncDeps.OptOut) r.GET("/optout", userSyncDeps.OptOut) From 324a9735e5e32210d2f1650321540e7544c4e777 Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 5 Oct 2023 02:01:14 -0400 Subject: [PATCH 157/268] update lunamedia contact info (#3137) --- static/bidder-info/lunamedia.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/bidder-info/lunamedia.yaml b/static/bidder-info/lunamedia.yaml index ef34143eb40..4064a566040 100644 --- a/static/bidder-info/lunamedia.yaml +++ b/static/bidder-info/lunamedia.yaml @@ -1,6 +1,6 @@ endpoint: "http://rtb.lunamedia.live/?pid={{.PublisherID}}" maintainer: - email: "josh@lunamedia.io" + email: "cs@lunamedia.io" capabilities: site: mediaTypes: From 8cdfe486d33a3cd33ad5ae544ebd706e64806b5b Mon Sep 17 00:00:00 2001 From: Ashish Garg Date: Thu, 5 Oct 2023 16:58:10 +0530 Subject: [PATCH 158/268] enable adapter alias feature (#3179) --- exchange/adapter_util.go | 4 ---- exchange/adapter_util_test.go | 7 ------- 2 files changed, 11 deletions(-) diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index 2337f7f6bbb..1890635cb3d 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -33,10 +33,6 @@ func buildBidders(infos config.BidderInfos, builders map[openrtb_ext.BidderName] var errs []error for bidder, info := range infos { - if len(info.AliasOf) > 0 { - errs = append(errs, fmt.Errorf("This feature is currently under development")) - continue - } bidderName, bidderNameFound := openrtb_ext.NormalizeBidderName(bidder) if !bidderNameFound { errs = append(errs, fmt.Errorf("%v: unknown bidder", bidder)) diff --git a/exchange/adapter_util_test.go b/exchange/adapter_util_test.go index 611498fea0c..08d751cdadf 100644 --- a/exchange/adapter_util_test.go +++ b/exchange/adapter_util_test.go @@ -68,13 +68,6 @@ func TestBuildAdapters(t *testing.T) { errors.New("unknown: unknown bidder"), }, }, - { - description: "Alias feature disabled", - bidderInfos: map[string]config.BidderInfo{"appNexus": {AliasOf: "rubicon"}}, - expectedErrors: []error{ - errors.New("This feature is currently under development"), - }, - }, } cfg := &config.Configuration{} From 23bc394e8218bb3f6c860c37bd13c56ea50d3df1 Mon Sep 17 00:00:00 2001 From: fkoch-sc Date: Mon, 9 Oct 2023 08:48:29 +0200 Subject: [PATCH 159/268] New Adapter: smartx (#3109) Co-authored-by: Andreas Schubert Co-authored-by: schubert-sc <144821265+schubert-sc@users.noreply.github.com> --- adapters/smartx/params_test.go | 58 ++++++++ adapters/smartx/smartx.go | 90 +++++++++++++ adapters/smartx/smartx_test.go | 24 ++++ .../smartx/smartxtest/exemplary/01-video.json | 77 +++++++++++ .../smartxtest/exemplary/02-consent.json | 124 ++++++++++++++++++ .../smartxtest/exemplary/03-device.json | 121 +++++++++++++++++ .../02-internal-server-error.json | 45 +++++++ .../03-missing-bidder-in-response.json | 47 +++++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_smartx.go | 10 ++ static/bidder-info/smartx.yaml | 12 ++ static/bidder-params/smartx.json | 37 ++++++ 13 files changed, 649 insertions(+) create mode 100644 adapters/smartx/params_test.go create mode 100644 adapters/smartx/smartx.go create mode 100644 adapters/smartx/smartx_test.go create mode 100644 adapters/smartx/smartxtest/exemplary/01-video.json create mode 100644 adapters/smartx/smartxtest/exemplary/02-consent.json create mode 100644 adapters/smartx/smartxtest/exemplary/03-device.json create mode 100644 adapters/smartx/smartxtest/supplemental/02-internal-server-error.json create mode 100644 adapters/smartx/smartxtest/supplemental/03-missing-bidder-in-response.json create mode 100644 openrtb_ext/imp_smartx.go create mode 100644 static/bidder-info/smartx.yaml create mode 100644 static/bidder-params/smartx.json diff --git a/adapters/smartx/params_test.go b/adapters/smartx/params_test.go new file mode 100644 index 00000000000..fd28f4ead9b --- /dev/null +++ b/adapters/smartx/params_test.go @@ -0,0 +1,58 @@ +package smartx + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/openrtb_ext" +) + +var validParams = []string{ + `{"tagId":"Nu68JuOWAvrbzoyrOR9a7A", "publisherId":"11986", "siteId":"22860"}`, + `{"tagId":"Nu68JuOWAvrbzoyrOR9a7A", "publisherId":"11986", "appId":"22860"}`, +} + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderSmartx, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected smartx params: %s", validParam) + } + } +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `[]`, + `{}`, + `{"anyparam": "anyvalue"}`, + `{"tagId":"Nu68JuOWAvrbzoyrOR9a7A"}`, + `{"publisherId":"11986"}`, + `{"siteId":"22860"}`, + `{"appId":"22860"}`, + `{"tagId":"Nu68JuOWAvrbzoyrOR9a7A", "publisherId":"11986"}`, + `{"tagId":"Nu68JuOWAvrbzoyrOR9a7A", "siteId":"22860"}`, + `{"tagId":"Nu68JuOWAvrbzoyrOR9a7A", "appId":"22860"}`, + `{"publisherId":"11986", "appId":"22860"}`, + `{"publisherId":"11986", "appId":"22860"}`, +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderSmartHub, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} diff --git a/adapters/smartx/smartx.go b/adapters/smartx/smartx.go new file mode 100644 index 00000000000..6fbc94968ca --- /dev/null +++ b/adapters/smartx/smartx.go @@ -0,0 +1,90 @@ +package smartx + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +type adapter struct { + endpointURL string +} + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + return &adapter{ + endpointURL: config.Endpoint, + }, nil +} + +func (a *adapter) MakeRequests(openRTBRequest *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) (requestsToBidder []*adapters.RequestData, errs []error) { + openRTBRequestJSON, err := json.Marshal(openRTBRequest) + if err != nil { + errs = append(errs, fmt.Errorf("marshal bidRequest: %w", err)) + return nil, errs + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("x-openrtb-version", "2.5") + + if openRTBRequest.Device != nil { + if openRTBRequest.Device.UA != "" { + headers.Set("User-Agent", openRTBRequest.Device.UA) + } + + if openRTBRequest.Device.IP != "" { + headers.Set("Forwarded", "for="+openRTBRequest.Device.IP) + headers.Set("X-Forwarded-For", openRTBRequest.Device.IP) + } + } + + return append(requestsToBidder, &adapters.RequestData{ + Method: http.MethodPost, + Uri: a.endpointURL, + Body: openRTBRequestJSON, + Headers: headers, + }), nil +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} + } + + var response openrtb2.BidResponse + if err := json.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + if len(response.SeatBid) == 0 { + return nil, []error{errors.New("no bidders found in JSON response")} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + if response.Cur != "" { + bidResponse.Currency = response.Cur + } + + var errs []error + + for _, seatBid := range response.SeatBid { + for i := range seatBid.Bid { + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: openrtb_ext.BidTypeVideo, + }) + } + } + + return bidResponse, errs +} diff --git a/adapters/smartx/smartx_test.go b/adapters/smartx/smartx_test.go new file mode 100644 index 00000000000..ba6f6ba7762 --- /dev/null +++ b/adapters/smartx/smartx_test.go @@ -0,0 +1,24 @@ +package smartx + +import ( + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +const testsDir = "smartxtest" +const testsBidderEndpoint = "https://bid.smartclip.net/bid/1005" + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder( + openrtb_ext.BidderRise, + config.Adapter{Endpoint: testsBidderEndpoint}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 115, DataCenter: "2"}) + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, testsDir, bidder) +} diff --git a/adapters/smartx/smartxtest/exemplary/01-video.json b/adapters/smartx/smartxtest/exemplary/01-video.json new file mode 100644 index 00000000000..c4d3f9c5b31 --- /dev/null +++ b/adapters/smartx/smartxtest/exemplary/01-video.json @@ -0,0 +1,77 @@ +{ + "mockBidRequest":{ + "id":"test-request-id-video", + "imp":[ + { + "id":"test-imp-id", + "video":{ + "mimes":[ + "video/mp4" + ] + } + } + ] + }, + "httpCalls":[ + { + "expectedRequest":{ + "uri":"https://bid.smartclip.net/bid/1005", + "body":{ + "id":"test-request-id-video", + "imp":[ + { + "id":"test-imp-id", + "video":{ + "mimes":[ + "video/mp4" + ] + } + } + ] + } + }, + "mockResponse":{ + "status":200, + "body":{ + "id":"test-request-id-video", + "seatbid":[ + { + "seat":"smartadserver", + "bid":[ + { + "id":"8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid":"test-imp-id-video", + "price":0.500000, + "adm":"some-test-ad", + "crid":"crid_10", + "h":576, + "w":1024, + "mtype":2 + } + ] + } + ], + "cur":"EUR" + } + } + } + ], + "expectedBidResponses":[ + { + "bids":[{ + "bid":{ + "id":"8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid":"test-imp-id-video", + "price":0.500000, + "adm":"some-test-ad", + "crid":"crid_10", + "h":576, + "w":1024, + "mtype":2 + }, + "currency":"EUR", + "type": "video" + }] + } + ] +} \ No newline at end of file diff --git a/adapters/smartx/smartxtest/exemplary/02-consent.json b/adapters/smartx/smartxtest/exemplary/02-consent.json new file mode 100644 index 00000000000..bc0e5604f4e --- /dev/null +++ b/adapters/smartx/smartxtest/exemplary/02-consent.json @@ -0,0 +1,124 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "prebid": { + "bidder": { + "smartx": { + "publisherId": "11986", + "tagId": "Nu68JuOWAvrbzoyrOR9a7A", + "siteId": "22860" + } + } + } + } + } + ], + "user": { + "ext": { + "consent": "COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bid.smartclip.net/bid/1005", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "prebid": { + "bidder": { + "smartx": { + "publisherId": "11986", + "tagId": "Nu68JuOWAvrbzoyrOR9a7A", + "siteId": "22860" + } + } + } + } + } + ], + "user": { + "ext": { + "consent": "COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "https://advertiser.example.com" + ], + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": { + "ix": {} + } + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": [ + "https://advertiser.example.com" + ], + "cid": "958", + "crid": "29681110", + "w": 300, + "h": 250, + "ext": { + "ix": {} + } + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/smartx/smartxtest/exemplary/03-device.json b/adapters/smartx/smartxtest/exemplary/03-device.json new file mode 100644 index 00000000000..f45cc76c99a --- /dev/null +++ b/adapters/smartx/smartxtest/exemplary/03-device.json @@ -0,0 +1,121 @@ +{ + "mockBidRequest": { + "id": "test-request-id-video", + "device": { + "ua": "Mozilla/5.0 (Linux; Android 12; SAMSUNG SM-G780G) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/17.0 Chrome/96.0.4664.104 Mobile Safari/537.36", + "geo": { + "lat": 48.1663, + "lon": 11.5683, + "type": 2, + "country": "DEU", + "region": "BY", + "city": "Munich", + "zip": "81249", + "ipservice": 3 + }, + "dnt": 0, + "lmt": 0, + "ip": "0.0.0.0", + "devicetype": 4, + "make": "Samsung", + "model": "SM-G780G", + "os": "Android", + "language": "en" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bid.smartclip.net/bid/1005", + "body": { + "id": "test-request-id-video", + "device": { + "ua": "Mozilla/5.0 (Linux; Android 12; SAMSUNG SM-G780G) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/17.0 Chrome/96.0.4664.104 Mobile Safari/537.36", + "geo": { + "lat": 48.1663, + "lon": 11.5683, + "type": 2, + "country": "DEU", + "region": "BY", + "city": "Munich", + "zip": "81249", + "ipservice": 3 + }, + "dnt": 0, + "lmt": 0, + "ip": "0.0.0.0", + "devicetype": 4, + "make": "Samsung", + "model": "SM-G780G", + "os": "Android", + "language": "en" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id-video", + "seatbid": [ + { + "seat": "smartadserver", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id-video", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 576, + "w": 1024, + "mtype": 2 + } + ] + } + ], + "cur": "EUR" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id-video", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 576, + "w": 1024, + "mtype": 2 + }, + "currency": "EUR", + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/smartx/smartxtest/supplemental/02-internal-server-error.json b/adapters/smartx/smartxtest/supplemental/02-internal-server-error.json new file mode 100644 index 00000000000..d44ef7f77e1 --- /dev/null +++ b/adapters/smartx/smartxtest/supplemental/02-internal-server-error.json @@ -0,0 +1,45 @@ +{ + "mockBidRequest": { + "id": "test-internal-server-error-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bid.smartclip.net/bid/1005", + "body": { + "id": "test-internal-server-error-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + } + } + ] + } + }, + "mockResponse": { + "status": 400, + "body": {} + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/smartx/smartxtest/supplemental/03-missing-bidder-in-response.json b/adapters/smartx/smartxtest/supplemental/03-missing-bidder-in-response.json new file mode 100644 index 00000000000..71875f12809 --- /dev/null +++ b/adapters/smartx/smartxtest/supplemental/03-missing-bidder-in-response.json @@ -0,0 +1,47 @@ +{ + "mockBidRequest": { + "id": "test-missing-bidder-in-response-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bid.smartclip.net/bid/1005", + "body": { + "id": "test-missing-bidder-in-response-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + } + } + ] + } + }, + "mockResponse": { + "body": { + "seatbid": [] + }, + "status": 200 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "no bidders found in JSON response", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index c5b4b1134cc..95cb1626085 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -148,6 +148,7 @@ import ( "github.com/prebid/prebid-server/adapters/smartadserver" "github.com/prebid/prebid-server/adapters/smarthub" "github.com/prebid/prebid-server/adapters/smartrtb" + "github.com/prebid/prebid-server/adapters/smartx" "github.com/prebid/prebid-server/adapters/smartyads" "github.com/prebid/prebid-server/adapters/smilewanted" "github.com/prebid/prebid-server/adapters/sonobi" @@ -348,6 +349,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderSmartAdserver: smartadserver.Builder, openrtb_ext.BidderSmartHub: smarthub.Builder, openrtb_ext.BidderSmartRTB: smartrtb.Builder, + openrtb_ext.BidderSmartx: smartx.Builder, openrtb_ext.BidderSmartyAds: smartyads.Builder, openrtb_ext.BidderSmileWanted: smilewanted.Builder, openrtb_ext.BidderSonobi: sonobi.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 67f43ec62dd..475d56a7ba8 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -178,6 +178,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderSmartAdserver, BidderSmartHub, BidderSmartRTB, + BidderSmartx, BidderSmartyAds, BidderSmileWanted, BidderSonobi, @@ -466,6 +467,7 @@ const ( BidderSmartAdserver BidderName = "smartadserver" BidderSmartHub BidderName = "smarthub" BidderSmartRTB BidderName = "smartrtb" + BidderSmartx BidderName = "smartx" BidderSmartyAds BidderName = "smartyads" BidderSmileWanted BidderName = "smilewanted" BidderSonobi BidderName = "sonobi" diff --git a/openrtb_ext/imp_smartx.go b/openrtb_ext/imp_smartx.go new file mode 100644 index 00000000000..9a2975b01de --- /dev/null +++ b/openrtb_ext/imp_smartx.go @@ -0,0 +1,10 @@ +package openrtb_ext + +type ExtImpSmartclip struct { + TagID string `json:"tagId"` + PublisherID string `json:"publisherId"` + SiteID string `json:"siteId"` + AppID string `json:"appId"` + BundleID string `json:"bundleId"` + StoreURL string `json:"storeUrl"` +} diff --git a/static/bidder-info/smartx.yaml b/static/bidder-info/smartx.yaml new file mode 100644 index 00000000000..9a387ecfbd2 --- /dev/null +++ b/static/bidder-info/smartx.yaml @@ -0,0 +1,12 @@ +endpoint: "https://bid.smartclip.net/bid/1005" +maintainer: + email: "bidding@smartclip.tv" +gvlVendorID: 115 +modifyingVastXmlAllowed: false +capabilities: + site: + mediaTypes: + - video + app: + mediaTypes: + - video diff --git a/static/bidder-params/smartx.json b/static/bidder-params/smartx.json new file mode 100644 index 00000000000..3bd97456770 --- /dev/null +++ b/static/bidder-params/smartx.json @@ -0,0 +1,37 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "smartclip.tv Adapter Params", + "description": "A schema which validates params accepted by the smartclip.tv adapter", + "type": "object", + "properties": { + "tagId": { + "type": "string", + "description": "Ad tag ID" + }, + "publisherId": { + "type": "string", + "description": "Publisher ID" + }, + "siteId": { + "type": "string", + "description": "Site ID" + }, + "appId": { + "type": "string", + "description": "App ID" + }, + "bundleId": { + "type": "string", + "description": "Bundle ID" + }, + "storeUrl": { + "type": "string", + "description": "AppStore URL" + } + }, + "oneOf": [ + { "required": ["siteId"] }, + { "required": ["appId"] } + ], + "required": ["tagId", "publisherId"] +} \ No newline at end of file From 1944dbb8592872a712532abaf7a331b2a862b2ac Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Mon, 9 Oct 2023 15:46:46 -0400 Subject: [PATCH 160/268] Adapter Name Case Insensitive: EID Permissions (#3187) --- endpoints/openrtb2/amp_auction.go | 1 + endpoints/openrtb2/auction.go | 40 ++--- endpoints/openrtb2/auction_test.go | 65 ++++++-- ...idpermissions-insensitive-bidder-name.json | 109 ------------- endpoints/openrtb2/video_auction.go | 3 +- endpoints/openrtb2/video_auction_test.go | 4 + .../eidpermissions-allowed-alias.json | 12 +- ...dpermissions-allowed-case-insensitive.json | 144 ++++++++++++++++++ .../exchangetest/eidpermissions-allowed.json | 12 +- .../exchangetest/eidpermissions-denied.json | 6 +- exchange/utils.go | 3 +- exchange/utils_test.go | 8 + 12 files changed, 262 insertions(+), 145 deletions(-) delete mode 100644 endpoints/openrtb2/sample-requests/valid-whole/exemplary/eidpermissions-insensitive-bidder-name.json create mode 100644 exchange/exchangetest/eidpermissions-allowed-case-insensitive.json diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index 76762d8b9ea..2fde59c25e4 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -103,6 +103,7 @@ func NewAmpEndpoint( storedRespFetcher, hookExecutionPlanBuilder, tmaxAdjustments, + openrtb_ext.NormalizeBidderName, }).AmpAuction), nil } diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 4fce4c15786..3a929c43abe 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -126,9 +126,12 @@ func NewEndpoint( ipValidator, storedRespFetcher, hookExecutionPlanBuilder, - tmaxAdjustments}).Auction), nil + tmaxAdjustments, + openrtb_ext.NormalizeBidderName}).Auction), nil } +type normalizeBidderName func(name string) (openrtb_ext.BidderName, bool) + type endpointDeps struct { uuidGenerator uuidutil.UUIDGenerator ex exchange.Exchange @@ -149,6 +152,7 @@ type endpointDeps struct { storedRespFetcher stored_requests.Fetcher hookExecutionPlanBuilder hooks.ExecutionPlanBuilder tmaxAdjustments *exchange.TmaxAdjustmentsPreprocessed + normalizeBidderName normalizeBidderName } func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { @@ -765,7 +769,7 @@ func (deps *endpointDeps) validateRequest(req *openrtb_ext.RequestWrapper, isAmp } } - var aliases map[string]string + var requestAliases map[string]string reqExt, err := req.GetRequestExt() if err != nil { return []error{fmt.Errorf("request.ext is invalid: %v", err)} @@ -777,17 +781,17 @@ func (deps *endpointDeps) validateRequest(req *openrtb_ext.RequestWrapper, isAmp } if reqPrebid != nil { - aliases = reqPrebid.Aliases + requestAliases = reqPrebid.Aliases - if err := deps.validateAliases(aliases); err != nil { + if err := deps.validateAliases(requestAliases); err != nil { return []error{err} } - if err := deps.validateAliasesGVLIDs(reqPrebid.AliasGVLIDs, aliases); err != nil { + if err := deps.validateAliasesGVLIDs(reqPrebid.AliasGVLIDs, requestAliases); err != nil { return []error{err} } - if err := deps.validateBidAdjustmentFactors(reqPrebid.BidAdjustmentFactors, aliases); err != nil { + if err := deps.validateBidAdjustmentFactors(reqPrebid.BidAdjustmentFactors, requestAliases); err != nil { return []error{err} } @@ -795,7 +799,7 @@ func (deps *endpointDeps) validateRequest(req *openrtb_ext.RequestWrapper, isAmp return []error{err} } - if err := deps.validateEidPermissions(reqPrebid.Data, aliases); err != nil { + if err := deps.validateEidPermissions(reqPrebid.Data, requestAliases); err != nil { return []error{err} } @@ -844,7 +848,7 @@ func (deps *endpointDeps) validateRequest(req *openrtb_ext.RequestWrapper, isAmp } } - if errs := deps.validateUser(req, aliases, gpp); errs != nil { + if errs := deps.validateUser(req, requestAliases, gpp); errs != nil { if len(errs) > 0 { errL = append(errL, errs...) } @@ -871,7 +875,7 @@ func (deps *endpointDeps) validateRequest(req *openrtb_ext.RequestWrapper, isAmp if errortypes.ContainsFatalError([]error{err}) { return errL } - } else if _, err := ccpaPolicy.Parse(exchange.GetValidBidders(aliases)); err != nil { + } else if _, err := ccpaPolicy.Parse(exchange.GetValidBidders(requestAliases)); err != nil { if _, invalidConsent := err.(*errortypes.Warning); invalidConsent { errL = append(errL, &errortypes.Warning{ Message: fmt.Sprintf("CCPA consent is invalid and will be ignored. (%v)", err), @@ -894,7 +898,7 @@ func (deps *endpointDeps) validateRequest(req *openrtb_ext.RequestWrapper, isAmp } impIDs[imp.ID] = i - errs := deps.validateImp(imp, aliases, i, hasStoredResponses, storedBidResp) + errs := deps.validateImp(imp, requestAliases, i, hasStoredResponses, storedBidResp) if len(errs) > 0 { errL = append(errL, errs...) } @@ -986,7 +990,7 @@ func validateSChains(sChains []*openrtb_ext.ExtRequestPrebidSChain) error { return err } -func (deps *endpointDeps) validateEidPermissions(prebid *openrtb_ext.ExtRequestPrebidData, aliases map[string]string) error { +func (deps *endpointDeps) validateEidPermissions(prebid *openrtb_ext.ExtRequestPrebidData, requestAliases map[string]string) error { if prebid == nil { return nil } @@ -1006,7 +1010,7 @@ func (deps *endpointDeps) validateEidPermissions(prebid *openrtb_ext.ExtRequestP return fmt.Errorf(`request.ext.prebid.data.eidpermissions[%d] missing or empty required field: "bidders"`, i) } - if err := validateBidders(eid.Bidders, deps.bidderMap, aliases); err != nil { + if err := deps.validateBidders(eid.Bidders, deps.bidderMap, requestAliases); err != nil { return fmt.Errorf(`request.ext.prebid.data.eidpermissions[%d] contains %v`, i, err) } } @@ -1014,20 +1018,16 @@ func (deps *endpointDeps) validateEidPermissions(prebid *openrtb_ext.ExtRequestP return nil } -func validateBidders(bidders []string, knownBidders map[string]openrtb_ext.BidderName, knownAliases map[string]string) error { +func (deps *endpointDeps) validateBidders(bidders []string, knownBidders map[string]openrtb_ext.BidderName, knownRequestAliases map[string]string) error { for _, bidder := range bidders { if bidder == "*" { if len(bidders) > 1 { return errors.New(`bidder wildcard "*" mixed with specific bidders`) } } else { - bidderName := bidder - normalizedCoreBidder, ok := openrtb_ext.NormalizeBidderName(bidderName) - if ok { - bidderName = normalizedCoreBidder.String() - } - _, isCoreBidder := knownBidders[bidderName] - _, isAlias := knownAliases[bidder] + bidderNormalized, _ := deps.normalizeBidderName(bidder) + _, isCoreBidder := knownBidders[bidderNormalized.String()] + _, isAlias := knownRequestAliases[bidder] if !isCoreBidder && !isAlias { return fmt.Errorf(`unrecognized bidder "%v"`, bidder) } diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index 55bf68ff730..8204a80e3db 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -1186,6 +1186,7 @@ func TestStoredRequests(t *testing.T) { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } testStoreVideoAttr := []bool{true, true, false, false, false} @@ -1635,6 +1636,7 @@ func TestValidateRequest(t *testing.T) { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } testCases := []struct { @@ -2414,6 +2416,7 @@ func TestSetIntegrationType(t *testing.T) { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } testCases := []struct { @@ -2480,6 +2483,7 @@ func TestStoredRequestGenerateUuid(t *testing.T) { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } req := &openrtb2.BidRequest{} @@ -2584,6 +2588,7 @@ func TestOversizedRequest(t *testing.T) { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } req := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(reqBody)) @@ -2623,6 +2628,7 @@ func TestRequestSizeEdgeCase(t *testing.T) { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } req := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(reqBody)) @@ -2962,6 +2968,7 @@ func TestValidateImpExt(t *testing.T) { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } for _, group := range testGroups { @@ -3017,6 +3024,7 @@ func TestCurrencyTrunc(t *testing.T) { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } ui := int64(1) @@ -3065,6 +3073,7 @@ func TestCCPAInvalid(t *testing.T) { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } ui := int64(1) @@ -3117,6 +3126,7 @@ func TestNoSaleInvalid(t *testing.T) { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } ui := int64(1) @@ -3172,6 +3182,7 @@ func TestValidateSourceTID(t *testing.T) { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } ui := int64(1) @@ -3217,6 +3228,7 @@ func TestSChainInvalid(t *testing.T) { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } ui := int64(1) @@ -3785,6 +3797,7 @@ func TestEidPermissionsInvalid(t *testing.T) { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } ui := int64(1) @@ -3853,6 +3866,13 @@ func TestValidateEidPermissions(t *testing.T) { }}}}, expectedError: nil, }, + { + description: "Valid - One - Case Insensitive", + request: &openrtb_ext.ExtRequest{Prebid: openrtb_ext.ExtRequestPrebid{Data: &openrtb_ext.ExtRequestPrebidData{EidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ + {Source: "sourceA", Bidders: []string{"A"}}, + }}}}, + expectedError: nil, + }, { description: "Valid - Many", request: &openrtb_ext.ExtRequest{Prebid: openrtb_ext.ExtRequestPrebid{Data: &openrtb_ext.ExtRequestPrebidData{EidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ @@ -3901,9 +3921,16 @@ func TestValidateEidPermissions(t *testing.T) { }}}}, expectedError: errors.New(`request.ext.prebid.data.eidpermissions[1] contains unrecognized bidder "z"`), }, + { + description: "Valid - Alias Case Sensitive", + request: &openrtb_ext.ExtRequest{Prebid: openrtb_ext.ExtRequestPrebid{Data: &openrtb_ext.ExtRequestPrebidData{EidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ + {Source: "sourceA", Bidders: []string{"B"}}, + }}}}, + expectedError: errors.New(`request.ext.prebid.data.eidpermissions[0] contains unrecognized bidder "B"`), + }, } - endpoint := &endpointDeps{bidderMap: knownBidders} + endpoint := &endpointDeps{bidderMap: knownBidders, normalizeBidderName: fakeNormalizeBidderName} for _, test := range testCases { result := endpoint.validateEidPermissions(test.request.Prebid.Data, knownAliases) assert.Equal(t, test.expectedError, result, test.description) @@ -3939,6 +3966,13 @@ func TestValidateBidders(t *testing.T) { knownAliases: map[string]string{"c": "c"}, expectedError: nil, }, + { + description: "Valid - One Core Bidder - Case Insensitive", + bidders: []string{"A"}, + knownBidders: map[string]openrtb_ext.BidderName{"a": openrtb_ext.BidderName("a")}, + knownAliases: map[string]string{"c": "c"}, + expectedError: nil, + }, { description: "Valid - Many Core Bidders", bidders: []string{"a", "b"}, @@ -3953,6 +3987,13 @@ func TestValidateBidders(t *testing.T) { knownAliases: map[string]string{"c": "c"}, expectedError: nil, }, + { + description: "Valid - One Alias Bidder - Case Sensitive", + bidders: []string{"C"}, + knownBidders: map[string]openrtb_ext.BidderName{"a": openrtb_ext.BidderName("a")}, + knownAliases: map[string]string{"c": "c"}, + expectedError: errors.New(`unrecognized bidder "C"`), + }, { description: "Valid - Many Alias Bidders", bidders: []string{"c", "d"}, @@ -3974,13 +4015,6 @@ func TestValidateBidders(t *testing.T) { knownAliases: map[string]string{"c": "c"}, expectedError: errors.New(`unrecognized bidder "z"`), }, - { - description: "Invalid - Unknown Bidder Case Sensitive", - bidders: []string{"A"}, - knownBidders: map[string]openrtb_ext.BidderName{"a": openrtb_ext.BidderName("a")}, - knownAliases: map[string]string{"c": "c"}, - expectedError: errors.New(`unrecognized bidder "A"`), - }, { description: "Invalid - Unknown Bidder With Known Bidders", bidders: []string{"a", "c", "z"}, @@ -4011,8 +4045,9 @@ func TestValidateBidders(t *testing.T) { }, } + endpoint := &endpointDeps{normalizeBidderName: fakeNormalizeBidderName} for _, test := range testCases { - result := validateBidders(test.bidders, test.knownBidders, test.knownAliases) + result := endpoint.validateBidders(test.bidders, test.knownBidders, test.knownAliases) assert.Equal(t, test.expectedError, result, test.description) } } @@ -4102,6 +4137,7 @@ func TestAuctionWarnings(t *testing.T) { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } for _, test := range testCases { t.Run(test.name, func(t *testing.T) { @@ -4148,6 +4184,7 @@ func TestParseRequestParseImpInfoError(t *testing.T) { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } hookExecutor := hookexecution.NewHookExecutor(deps.hookExecutionPlanBuilder, hookexecution.EndpointAuction, deps.metricsEngine) @@ -4228,6 +4265,7 @@ func TestParseGzipedRequest(t *testing.T) { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } hookExecutor := hookexecution.NewHookExecutor(deps.hookExecutionPlanBuilder, hookexecution.EndpointAuction, deps.metricsEngine) @@ -4828,6 +4866,7 @@ func TestParseRequestMergeBidderParams(t *testing.T) { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } hookExecutor := hookexecution.NewHookExecutor(deps.hookExecutionPlanBuilder, hookexecution.EndpointAuction, deps.metricsEngine) @@ -4931,6 +4970,7 @@ func TestParseRequestStoredResponses(t *testing.T) { &mockStoredResponseFetcher{mockStoredResponses}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } hookExecutor := hookexecution.NewHookExecutor(deps.hookExecutionPlanBuilder, hookexecution.EndpointAuction, deps.metricsEngine) @@ -5029,6 +5069,7 @@ func TestParseRequestStoredBidResponses(t *testing.T) { &mockStoredResponseFetcher{mockStoredBidResponses}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } hookExecutor := hookexecution.NewHookExecutor(deps.hookExecutionPlanBuilder, hookexecution.EndpointAuction, deps.metricsEngine) @@ -5065,6 +5106,7 @@ func TestValidateStoredResp(t *testing.T) { &mockStoredResponseFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } testCases := []struct { @@ -5878,6 +5920,7 @@ func TestParseRequestMultiBid(t *testing.T) { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } hookExecutor := hookexecution.NewHookExecutor(deps.hookExecutionPlanBuilder, hookexecution.EndpointAuction, deps.metricsEngine) @@ -6043,3 +6086,7 @@ func TestValidateAliases(t *testing.T) { }) } } + +func fakeNormalizeBidderName(name string) (openrtb_ext.BidderName, bool) { + return openrtb_ext.BidderName(strings.ToLower(name)), true +} diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/eidpermissions-insensitive-bidder-name.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/eidpermissions-insensitive-bidder-name.json deleted file mode 100644 index b06b2593e26..00000000000 --- a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/eidpermissions-insensitive-bidder-name.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "description": "This demonstrates ext.prebid.data.eidpermissions.bidders with case insensitive bidder names", - "config": { - "mockBidders": [ - { - "bidderName": "appnexus", - "currency": "USD", - "price": 1.00 - }, - { - "bidderName": "rubicon", - "currency": "USD", - "price": 1.00 - } - ] - }, - "mockBidRequest": { - "id": "some-request-id", - "site": { - "page": "prebid.org" - }, - "user": { - "ext": { - "consent": "gdpr-consent-string" - } - }, - "regs": { - "ext": { - "gdpr": 1, - "us_privacy": "1NYN" - } - }, - "imp": [ - { - "id": "some-impression-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "ext": { - "APPNEXUS": { - "placementId": 12883451 - } - } - } - ], - "tmax": 500, - "ext": { - "prebid": { - "data": { - "eidpermissions": [ - { - "source": "source1", - "bidders": [ - "APPNEXUS" - ] - } - ] - }, - "cache": { - "bids": {} - }, - "channel": { - "name": "video", - "version": "1.0" - }, - "targeting": { - "includewinners": false, - "pricegranularity": { - "precision": 2, - "ranges": [ - { - "max": 20, - "increment": 0.10 - } - ] - } - } - } - } - }, - "expectedBidResponse": { - "id": "some-request-id", - "seatbid": [ - { - "bid": [ - { - "id": "appnexus-bid", - "impid": "some-impression-id", - "price": 1 - } - ], - "seat": "APPNEXUS" - } - ], - "bidid": "test bid id", - "cur": "USD", - "nbr": 0 - }, - "expectedReturnCode": 200 -} \ No newline at end of file diff --git a/endpoints/openrtb2/video_auction.go b/endpoints/openrtb2/video_auction.go index fc6d2a91a62..8faf15543d3 100644 --- a/endpoints/openrtb2/video_auction.go +++ b/endpoints/openrtb2/video_auction.go @@ -92,7 +92,8 @@ func NewVideoEndpoint( ipValidator, empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, - tmaxAdjustments}).VideoAuctionEndpoint), nil + tmaxAdjustments, + openrtb_ext.NormalizeBidderName}).VideoAuctionEndpoint), nil } /* diff --git a/endpoints/openrtb2/video_auction_test.go b/endpoints/openrtb2/video_auction_test.go index 181a68929ed..19af821f205 100644 --- a/endpoints/openrtb2/video_auction_test.go +++ b/endpoints/openrtb2/video_auction_test.go @@ -1227,6 +1227,7 @@ func mockDepsWithMetrics(t *testing.T, ex *mockExchangeVideo) (*endpointDeps, *m empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } return deps, metrics, mockModule } @@ -1274,6 +1275,7 @@ func mockDeps(t *testing.T, ex *mockExchangeVideo) *endpointDeps { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } } @@ -1298,6 +1300,7 @@ func mockDepsAppendBidderNames(t *testing.T, ex *mockExchangeAppendBidderNames) empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } return deps @@ -1324,6 +1327,7 @@ func mockDepsNoBids(t *testing.T, ex *mockExchangeVideoNoBids) *endpointDeps { empty_fetcher.EmptyFetcher{}, hooks.EmptyPlanBuilder{}, nil, + openrtb_ext.NormalizeBidderName, } return edep diff --git a/exchange/exchangetest/eidpermissions-allowed-alias.json b/exchange/exchangetest/eidpermissions-allowed-alias.json index f10bdcf86c0..de3c0e1dca6 100644 --- a/exchange/exchangetest/eidpermissions-allowed-alias.json +++ b/exchange/exchangetest/eidpermissions-allowed-alias.json @@ -10,7 +10,11 @@ "eids": [ { "source": "source1", - "id": "anyId" + "uids": [ + { + "id": "id1" + } + ] } ] } @@ -66,7 +70,11 @@ "eids": [ { "source": "source1", - "id": "anyId" + "uids": [ + { + "id": "id1" + } + ] } ] } diff --git a/exchange/exchangetest/eidpermissions-allowed-case-insensitive.json b/exchange/exchangetest/eidpermissions-allowed-case-insensitive.json new file mode 100644 index 00000000000..86797501495 --- /dev/null +++ b/exchange/exchangetest/eidpermissions-allowed-case-insensitive.json @@ -0,0 +1,144 @@ +{ + "incomingRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "user": { + "ext": { + "eids": [ + { + "source": "source1", + "uids": [ + { + "id": "id1" + } + ] + } + ] + } + }, + "ext": { + "prebid": { + "data": { + "eidpermissions": [ + { + "source": "source1", + "bidders": [ + "APPNEXUS" + ] + } + ] + } + } + }, + "imp": [ + { + "id": "my-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "prebid": { + "bidder": { + "appnexus": { + "placementId": 1 + } + } + } + } + } + ] + } + }, + "outgoingRequests": { + "appnexus": { + "expectRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "user": { + "ext": { + "eids": [ + { + "source": "source1", + "uids": [ + { + "id": "id1" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "my-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "placementId": 1 + } + } + } + ] + } + }, + "mockResponse": { + "pbsSeatBids": [ + { + "pbsBids": [ + { + "ortbBid": { + "id": "apn-bid", + "impid": "my-imp-id", + "price": 0.3, + "w": 200, + "h": 250, + "crid": "creative-1" + }, + "bidType": "video" + } + ], + "seat": "appnexus" + } + ] + } + } + }, + "response": { + "bids": { + "id": "some-request-id", + "seatbid": [ + { + "seat": "appnexus", + "bid": [ + { + "id": "apn-bid", + "impid": "my-imp-id", + "price": 0.3, + "w": 200, + "h": 250, + "crid": "creative-1", + "ext": { + "origbidcpm": 0.3, + "prebid": { + "type": "video" + } + } + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/exchange/exchangetest/eidpermissions-allowed.json b/exchange/exchangetest/eidpermissions-allowed.json index 6b27212cbcf..9daee27a9b6 100644 --- a/exchange/exchangetest/eidpermissions-allowed.json +++ b/exchange/exchangetest/eidpermissions-allowed.json @@ -10,7 +10,11 @@ "eids": [ { "source": "source1", - "id": "anyId" + "uids": [ + { + "id": "id1" + } + ] } ] } @@ -63,7 +67,11 @@ "eids": [ { "source": "source1", - "id": "anyId" + "uids": [ + { + "id": "id1" + } + ] } ] } diff --git a/exchange/exchangetest/eidpermissions-denied.json b/exchange/exchangetest/eidpermissions-denied.json index df112905235..04eb51bb600 100644 --- a/exchange/exchangetest/eidpermissions-denied.json +++ b/exchange/exchangetest/eidpermissions-denied.json @@ -10,7 +10,11 @@ "eids": [ { "source": "source1", - "id": "anyId" + "uids": [ + { + "id": "id1" + } + ] } ] } diff --git a/exchange/utils.go b/exchange/utils.go index 0a38e487632..0d9c90cda99 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "math/rand" + "strings" "github.com/buger/jsonparser" "github.com/prebid/go-gdpr/vendorconsent" @@ -710,7 +711,7 @@ func removeUnpermissionedEids(request *openrtb2.BidRequest, bidder string, reque allowed := false if rule, hasRule := eidRules[eid.Source]; hasRule { for _, ruleBidder := range rule { - if ruleBidder == "*" || ruleBidder == bidder { + if ruleBidder == "*" || strings.EqualFold(ruleBidder, bidder) { allowed = true break } diff --git a/exchange/utils_test.go b/exchange/utils_test.go index ee6dad1ad96..0dbf5b38e5c 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -2768,6 +2768,14 @@ func TestRemoveUnpermissionedEids(t *testing.T) { }, expectedUserExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}]}`), }, + { + description: "Allowed By Specific Bidder - Case Insensitive", + userExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}]}`), + eidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ + {Source: "source1", Bidders: []string{"BIDDERA"}}, + }, + expectedUserExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}]}`), + }, { description: "Allowed By All Bidders", userExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}]}`), From e76b4b392ba8cd52893dac12d30913f6a71174db Mon Sep 17 00:00:00 2001 From: Emanuele Simonelli <136568337+EmanueleSimonelli@users.noreply.github.com> Date: Tue, 10 Oct 2023 09:15:31 +0200 Subject: [PATCH 161/268] OneTag: ORTB 2.6 initial support (#3128) Co-authored by @EmanueleSimonelli --- static/bidder-info/onetag.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/static/bidder-info/onetag.yaml b/static/bidder-info/onetag.yaml index 3677921ee5c..bc52faffe1b 100644 --- a/static/bidder-info/onetag.yaml +++ b/static/bidder-info/onetag.yaml @@ -1,4 +1,6 @@ endpoint: "https://prebid-server.onetag-sys.com/prebid-server/{{.PublisherID}}" +openrtb: + version: 2.6 maintainer: email: devops@onetag.com gvlVendorID: 241 From c8f3b2df7a1ef96cee637d04009fad90cff9b36c Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Tue, 10 Oct 2023 13:24:43 -0400 Subject: [PATCH 162/268] Adapter Name Case Insensitive: SetUID Endpoint (#3186) --- endpoints/setuid.go | 11 +++++-- endpoints/setuid_test.go | 63 ++++++++++++++++++++++++++-------------- 2 files changed, 50 insertions(+), 24 deletions(-) diff --git a/endpoints/setuid.go b/endpoints/setuid.go index 1bf3b575273..7af70d002b5 100644 --- a/endpoints/setuid.go +++ b/endpoints/setuid.go @@ -18,6 +18,7 @@ import ( "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/gdpr" "github.com/prebid/prebid-server/metrics" + "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/privacy" gppPrivacy "github.com/prebid/prebid-server/privacy/gpp" "github.com/prebid/prebid-server/stored_requests" @@ -329,7 +330,13 @@ func getSyncer(query url.Values, syncersByBidder map[string]usersync.Syncer) (us return nil, "", errors.New(`"bidder" query param is required`) } - syncer, syncerExists := syncersByBidder[bidder] + // case insensitive comparison + bidderNormalized, bidderFound := openrtb_ext.NormalizeBidderName(bidder) + if !bidderFound { + return nil, "", errors.New("The bidder name provided is not supported by Prebid Server") + } + + syncer, syncerExists := syncersByBidder[bidderNormalized.String()] if !syncerExists { return nil, "", errors.New("The bidder name provided is not supported by Prebid Server") } @@ -340,7 +347,7 @@ func getSyncer(query url.Values, syncersByBidder map[string]usersync.Syncer) (us func isSyncerPriority(bidderNameFromSyncerQuery string, priorityGroups [][]string) bool { for _, group := range priorityGroups { for _, bidder := range group { - if bidderNameFromSyncerQuery == bidder { + if strings.EqualFold(bidderNameFromSyncerQuery, bidder) { return true } } diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go index 3636f7fbbdc..387de6bd05f 100644 --- a/endpoints/setuid_test.go +++ b/endpoints/setuid_test.go @@ -50,6 +50,16 @@ func TestSetUIDEndpoint(t *testing.T) { expectedHeaders: map[string]string{"Content-Type": "text/html", "Content-Length": "0"}, description: "Set uid for valid bidder", }, + { + uri: "/setuid?bidder=PUBMATIC&uid=123", + syncersBidderNameToKey: map[string]string{"pubmatic": "pubmatic"}, + existingSyncs: nil, + gdprAllowsHostCookies: true, + expectedSyncs: map[string]string{"pubmatic": "123"}, + expectedStatusCode: http.StatusOK, + expectedHeaders: map[string]string{"Content-Type": "text/html", "Content-Length": "0"}, + description: "Set uid for valid bidder case insensitive", + }, { uri: "/setuid?bidder=appnexus&uid=123", syncersBidderNameToKey: map[string]string{"appnexus": "adnxs"}, @@ -1458,35 +1468,44 @@ func TestIsSyncerPriority(t *testing.T) { expected bool }{ { - name: "bidder-name-is-priority", - givenBidderNameFromSyncerQuery: "priorityBidder", - givenPriorityGroups: [][]string{ - {"priorityBidder"}, - {"2", "3"}, - }, - expected: true, + name: "priority-tier-1", + givenBidderNameFromSyncerQuery: "a", + givenPriorityGroups: [][]string{{"a"}}, + expected: true, }, { - name: "bidder-name-is-not-priority", - givenBidderNameFromSyncerQuery: "notPriorityBidderName", - givenPriorityGroups: [][]string{ - {"1"}, - {"2", "3"}, - }, - expected: false, + name: "priority-tier-other", + givenBidderNameFromSyncerQuery: "c", + givenPriorityGroups: [][]string{{"a"}, {"b", "c"}}, + expected: true, }, { - name: "no-bidder-name-given", + name: "priority-case-insensitive", + givenBidderNameFromSyncerQuery: "A", + givenPriorityGroups: [][]string{{"a"}}, + expected: true, + }, + { + name: "not-priority-empty", + givenBidderNameFromSyncerQuery: "a", + givenPriorityGroups: [][]string{}, + expected: false, + }, + { + name: "not-priority-not-defined", + givenBidderNameFromSyncerQuery: "a", + givenPriorityGroups: [][]string{{"b"}}, + expected: false, + }, + { + name: "no-bidder", givenBidderNameFromSyncerQuery: "", - givenPriorityGroups: [][]string{ - {"1"}, - {"2", "3"}, - }, - expected: false, + givenPriorityGroups: [][]string{{"b"}}, + expected: false, }, { - name: "no-priority-groups-given", - givenBidderNameFromSyncerQuery: "bidderName", + name: "no-priority-groups", + givenBidderNameFromSyncerQuery: "a", givenPriorityGroups: [][]string{}, expected: false, }, From 81c78ff026e3e0024f0affaaa5adaf4dbe8dec8b Mon Sep 17 00:00:00 2001 From: Nilesh Chate <97721111+pm-nilesh-chate@users.noreply.github.com> Date: Wed, 11 Oct 2023 16:11:45 +0530 Subject: [PATCH 163/268] pubmatic: add fledge support (#3174) --- adapters/pubmatic/pubmatic.go | 25 +++ .../pubmatictest/exemplary/fledge.json | 166 ++++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 adapters/pubmatic/pubmatictest/exemplary/fledge.json diff --git a/adapters/pubmatic/pubmatic.go b/adapters/pubmatic/pubmatic.go index 04bd00cb179..bd406d68631 100644 --- a/adapters/pubmatic/pubmatic.go +++ b/adapters/pubmatic/pubmatic.go @@ -19,6 +19,8 @@ import ( const MAX_IMPRESSIONS_PUBMATIC = 30 +const ae = "ae" + type PubmaticAdapter struct { URI string } @@ -42,6 +44,7 @@ type pubmaticBidExtVideo struct { type ExtImpBidderPubmatic struct { adapters.ExtImpBidder Data json.RawMessage `json:"data,omitempty"` + AE int `json:"ae,omitempty"` } type ExtAdServer struct { @@ -60,6 +63,10 @@ type extRequestAdServer struct { openrtb_ext.ExtRequest } +type respExt struct { + FledgeAuctionConfigs map[string]json.RawMessage `json:"fledge_auction_configs,omitempty"` +} + const ( dctrKeyName = "key_val" pmZoneIDKeyName = "pmZoneId" @@ -304,6 +311,10 @@ func parseImpressionObject(imp *openrtb2.Imp, extractWrapperExtFromImp, extractP populateFirstPartyDataImpAttributes(bidderExt.Data, extMap) } + if bidderExt.AE != 0 { + extMap[ae] = bidderExt.AE + } + imp.Ext = nil if len(extMap) > 0 { ext, err := json.Marshal(extMap) @@ -465,6 +476,20 @@ func (a *PubmaticAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externa if bidResp.Cur != "" { bidResponse.Currency = bidResp.Cur } + + if bidResp.Ext != nil { + var bidRespExt respExt + if err := json.Unmarshal(bidResp.Ext, &bidRespExt); err == nil && bidRespExt.FledgeAuctionConfigs != nil { + bidResponse.FledgeAuctionConfigs = make([]*openrtb_ext.FledgeAuctionConfig, 0, len(bidRespExt.FledgeAuctionConfigs)) + for impId, config := range bidRespExt.FledgeAuctionConfigs { + fledgeAuctionConfig := &openrtb_ext.FledgeAuctionConfig{ + ImpId: impId, + Config: config, + } + bidResponse.FledgeAuctionConfigs = append(bidResponse.FledgeAuctionConfigs, fledgeAuctionConfig) + } + } + } return bidResponse, errs } diff --git a/adapters/pubmatic/pubmatictest/exemplary/fledge.json b/adapters/pubmatic/pubmatictest/exemplary/fledge.json new file mode 100644 index 00000000000..793f0984624 --- /dev/null +++ b/adapters/pubmatic/pubmatictest/exemplary/fledge.json @@ -0,0 +1,166 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "ae": 1, + "bidder": { + "publisherId": "999", + "adSlot": "AdTag_Div1@300x250" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://hbopenbid.pubmatic.com/translator?source=prebid-server", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ], + "h": 250, + "w": 300 + }, + "tagid": "AdTag_Div1", + "ext": { + "ae": 1 + } + } + ], + "ext": {"prebid":{}} + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "pubmatic", + "bid": [ + { + "id": "9d8e77c2-ee0f-4781-af59-5359493b11af", + "impid": "test-imp-id", + "price": 1.1, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "ext": {} + } + ] + } + ], + "cur": "USD", + "ext": { + "fledge_auction_configs": { + "test-imp-id": { + "seller": "PUBMATIC_SELLER_CONSTANT_STRING", + "sellerTimeout": 123, + "decisionLogicUrl": "PUBMATIC_URL_CONSTANT_STRING", + "interestGroupBuyers": [ + "somedomain1.com", + "somedomain2.com", + "somedomain3.com", + "somedomain4.com" + ], + "perBuyerSignals": { + "somedomain1.com": { + "multiplier": 1, + "win_reporting_id": "1234" + }, + "somedomain2.com": { + "multiplier": 2, + "win_reporting_id": "2345" + }, + "somedomain3.com": { + "multiplier": 3, + "win_reporting_id": "3456" + }, + "somedomain4.com": { + "multiplier": 4, + "win_reporting_id": "4567" + } + } + } + } + } + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "9d8e77c2-ee0f-4781-af59-5359493b11af", + "impid": "test-imp-id", + "price": 1.1, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 728, + "h": 90, + "ext": {} + }, + "type": "banner" + } + ], + "fledgeauctionconfigs": [ + { + "impid": "test-imp-id", + "config": { + "seller": "PUBMATIC_SELLER_CONSTANT_STRING", + "sellerTimeout": 123, + "decisionLogicUrl": "PUBMATIC_URL_CONSTANT_STRING", + "interestGroupBuyers": [ + "somedomain1.com", + "somedomain2.com", + "somedomain3.com", + "somedomain4.com" + ], + "perBuyerSignals": { + "somedomain1.com": { + "multiplier": 1, + "win_reporting_id": "1234" + }, + "somedomain2.com": { + "multiplier": 2, + "win_reporting_id": "2345" + }, + "somedomain3.com": { + "multiplier": 3, + "win_reporting_id": "3456" + }, + "somedomain4.com": { + "multiplier": 4, + "win_reporting_id": "4567" + } + } + } + } + ] + } + ] +} \ No newline at end of file From 3c7d8528cad8cd4d1f598b50197e345ddb0bec24 Mon Sep 17 00:00:00 2001 From: Edge226Ads <144908224+Edge226Ads@users.noreply.github.com> Date: Mon, 16 Oct 2023 11:44:17 +0300 Subject: [PATCH 164/268] New Adapter: Edge226 (#3105) --- adapters/edge226/edge226.go | 145 ++++++++++++++++++ adapters/edge226/edge226_test.go | 20 +++ .../edge226test/exemplary/endpointId.json | 125 +++++++++++++++ .../edge226test/exemplary/simple-banner.json | 125 +++++++++++++++ .../edge226test/exemplary/simple-native.json | 109 +++++++++++++ .../edge226test/exemplary/simple-video.json | 120 +++++++++++++++ .../exemplary/simple-web-banner.json | 125 +++++++++++++++ .../supplemental/bad_media_type.json | 82 ++++++++++ .../supplemental/bad_response.json | 84 ++++++++++ .../edge226test/supplemental/status-204.json | 79 ++++++++++ .../supplemental/status-not-200.json | 84 ++++++++++ adapters/edge226/params_test.go | 47 ++++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_edge226.go | 6 + static/bidder-info/edge226.yaml | 16 ++ static/bidder-params/edge226.json | 23 +++ 17 files changed, 1194 insertions(+) create mode 100644 adapters/edge226/edge226.go create mode 100644 adapters/edge226/edge226_test.go create mode 100644 adapters/edge226/edge226test/exemplary/endpointId.json create mode 100644 adapters/edge226/edge226test/exemplary/simple-banner.json create mode 100644 adapters/edge226/edge226test/exemplary/simple-native.json create mode 100644 adapters/edge226/edge226test/exemplary/simple-video.json create mode 100644 adapters/edge226/edge226test/exemplary/simple-web-banner.json create mode 100644 adapters/edge226/edge226test/supplemental/bad_media_type.json create mode 100644 adapters/edge226/edge226test/supplemental/bad_response.json create mode 100644 adapters/edge226/edge226test/supplemental/status-204.json create mode 100644 adapters/edge226/edge226test/supplemental/status-not-200.json create mode 100644 adapters/edge226/params_test.go create mode 100644 openrtb_ext/imp_edge226.go create mode 100644 static/bidder-info/edge226.yaml create mode 100644 static/bidder-params/edge226.json diff --git a/adapters/edge226/edge226.go b/adapters/edge226/edge226.go new file mode 100644 index 00000000000..a124cb47eca --- /dev/null +++ b/adapters/edge226/edge226.go @@ -0,0 +1,145 @@ +package edge226 + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +type adapter struct { + endpoint string +} + +type reqBodyExt struct { + Edge226BidderExt reqBodyExtBidder `json:"bidder"` +} + +type reqBodyExtBidder struct { + Type string `json:"type"` + PlacementID string `json:"placementId,omitempty"` + EndpointID string `json:"endpointId,omitempty"` +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var err error + var adapterRequests []*adapters.RequestData + + reqCopy := *request + for _, imp := range request.Imp { + reqCopy.Imp = []openrtb2.Imp{imp} + + var bidderExt adapters.ExtImpBidder + var edge226Ext openrtb_ext.ImpExtEdge226 + + if err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { + return nil, []error{err} + } + if err = json.Unmarshal(bidderExt.Bidder, &edge226Ext); err != nil { + return nil, []error{err} + } + + temp := reqBodyExt{Edge226BidderExt: reqBodyExtBidder{}} + + if edge226Ext.PlacementID != "" { + temp.Edge226BidderExt.PlacementID = edge226Ext.PlacementID + temp.Edge226BidderExt.Type = "publisher" + } else if edge226Ext.EndpointID != "" { + temp.Edge226BidderExt.EndpointID = edge226Ext.EndpointID + temp.Edge226BidderExt.Type = "network" + } + + finalyImpExt, err := json.Marshal(temp) + if err != nil { + return nil, []error{err} + } + + reqCopy.Imp[0].Ext = finalyImpExt + + adapterReq, err := a.makeRequest(&reqCopy) + if err != nil { + return nil, []error{err} + } + + if adapterReq != nil { + adapterRequests = append(adapterRequests, adapterReq) + } + } + return adapterRequests, nil +} + +func (a *adapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, error) { + reqJSON, err := json.Marshal(request) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + return &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: reqJSON, + Headers: headers, + }, err +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} + } + + var response openrtb2.BidResponse + if err := json.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + bidResponse.Currency = response.Cur + for _, seatBid := range response.SeatBid { + for i := range seatBid.Bid { + bidType, err := getBidMediaType(&seatBid.Bid[i]) + if err != nil { + return nil, []error{err} + } + + b := &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + } + return bidResponse, nil +} + +func getBidMediaType(bid *openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupAudio: + return openrtb_ext.BidTypeAudio, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + return "", fmt.Errorf("Unable to fetch mediaType in multi-format: %s", bid.ImpID) + } +} diff --git a/adapters/edge226/edge226_test.go b/adapters/edge226/edge226_test.go new file mode 100644 index 00000000000..c5e40ce726d --- /dev/null +++ b/adapters/edge226/edge226_test.go @@ -0,0 +1,20 @@ +package edge226 + +import ( + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderEdge226, config.Adapter{ + Endpoint: "http://test.com/pserver"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "edge226test", bidder) +} diff --git a/adapters/edge226/edge226test/exemplary/endpointId.json b/adapters/edge226/edge226test/exemplary/endpointId.json new file mode 100644 index 00000000000..741c1f8cb9b --- /dev/null +++ b/adapters/edge226/edge226test/exemplary/endpointId.json @@ -0,0 +1,125 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://test.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test", + "type": "network" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "mtype": 1 + } + ], + "seat": "edge226" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/edge226/edge226test/exemplary/simple-banner.json b/adapters/edge226/edge226test/exemplary/simple-banner.json new file mode 100644 index 00000000000..741c1f8cb9b --- /dev/null +++ b/adapters/edge226/edge226test/exemplary/simple-banner.json @@ -0,0 +1,125 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://test.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test", + "type": "network" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "mtype": 1 + } + ], + "seat": "edge226" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/edge226/edge226test/exemplary/simple-native.json b/adapters/edge226/edge226test/exemplary/simple-native.json new file mode 100644 index 00000000000..581864cdb41 --- /dev/null +++ b/adapters/edge226/edge226test/exemplary/simple-native.json @@ -0,0 +1,109 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://test.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "mtype": 4 + } + ], + "seat": "edge226" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/edge226/edge226test/exemplary/simple-video.json b/adapters/edge226/edge226test/exemplary/simple-video.json new file mode 100644 index 00000000000..c14a1bd988e --- /dev/null +++ b/adapters/edge226/edge226test/exemplary/simple-video.json @@ -0,0 +1,120 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://test.com/pserver", + "body": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "00:01:00", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 2 + } + ], + "seat": "edge226" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "00:01:00", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/edge226/edge226test/exemplary/simple-web-banner.json b/adapters/edge226/edge226test/exemplary/simple-web-banner.json new file mode 100644 index 00000000000..6cc7295003c --- /dev/null +++ b/adapters/edge226/edge226test/exemplary/simple-web-banner.json @@ -0,0 +1,125 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "site": { + "id": "1", + "domain": "test.com" + }, + "device": { + "ip": "123.123.123.123", + "ua": "Ubuntu" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://test.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "site": { + "id": "1", + "domain": "test.com" + }, + "device": { + "ip": "123.123.123.123", + "ua": "Ubuntu" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 468, + "h": 60, + "mtype": 1 + } + ], + "seat": "edge226" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 468, + "h": 60, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/edge226/edge226test/supplemental/bad_media_type.json b/adapters/edge226/edge226test/supplemental/bad_media_type.json new file mode 100644 index 00000000000..75b13412ad6 --- /dev/null +++ b/adapters/edge226/edge226test/supplemental/bad_media_type.json @@ -0,0 +1,82 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://test.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "ext": {} + } + ], + "seat": "edge226" + } + ], + "cur": "USD" + } + } + }], + "expectedMakeBidsErrors": [ + { + "value": "Unable to fetch mediaType in multi-format: test-imp-id", + "comparison": "literal" + } + ] +} diff --git a/adapters/edge226/edge226test/supplemental/bad_response.json b/adapters/edge226/edge226test/supplemental/bad_response.json new file mode 100644 index 00000000000..1e5664bafec --- /dev/null +++ b/adapters/edge226/edge226test/supplemental/bad_response.json @@ -0,0 +1,84 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://test.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + } + }, + "mockResponse": { + "status": 200, + "body": "" + } + }], + "expectedMakeBidsErrors": [ + { + "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "comparison": "literal" + } + ] +} diff --git a/adapters/edge226/edge226test/supplemental/status-204.json b/adapters/edge226/edge226test/supplemental/status-204.json new file mode 100644 index 00000000000..da929ce61cb --- /dev/null +++ b/adapters/edge226/edge226test/supplemental/status-204.json @@ -0,0 +1,79 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://test.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + } + }, + "mockResponse": { + "status": 204, + "body": {} + } + }], + "expectedBidResponses": [] +} diff --git a/adapters/edge226/edge226test/supplemental/status-not-200.json b/adapters/edge226/edge226test/supplemental/status-not-200.json new file mode 100644 index 00000000000..cf1847c2cac --- /dev/null +++ b/adapters/edge226/edge226test/supplemental/status-not-200.json @@ -0,0 +1,84 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://test.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + } + }, + "mockResponse": { + "status": 404, + "body": {} + } + }], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 404. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/edge226/params_test.go b/adapters/edge226/params_test.go new file mode 100644 index 00000000000..3191bc62136 --- /dev/null +++ b/adapters/edge226/params_test.go @@ -0,0 +1,47 @@ +package edge226 + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range validParams { + if err := validator.Validate(openrtb_ext.BidderEdge226, json.RawMessage(p)); err != nil { + t.Errorf("Schema rejected valid params: %s", p) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderEdge226, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} + +var validParams = []string{ + `{"placementId": "test"}`, + `{"placementId": "1"}`, + `{"endpointId": "test"}`, + `{"endpointId": "1"}`, +} + +var invalidParams = []string{ + `{"placementId": 42}`, + `{"endpointId": 42}`, + `{"placementId": "1", "endpointId": "1"}`, +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 95cb1626085..5d06ba9ba43 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -74,6 +74,7 @@ import ( "github.com/prebid/prebid-server/adapters/dianomi" "github.com/prebid/prebid-server/adapters/dmx" evolution "github.com/prebid/prebid-server/adapters/e_volution" + "github.com/prebid/prebid-server/adapters/edge226" "github.com/prebid/prebid-server/adapters/emtv" "github.com/prebid/prebid-server/adapters/eplanning" "github.com/prebid/prebid-server/adapters/epom" @@ -263,6 +264,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderDecenterAds: decenterads.Builder, openrtb_ext.BidderDeepintent: deepintent.Builder, openrtb_ext.BidderDianomi: dianomi.Builder, + openrtb_ext.BidderEdge226: edge226.Builder, openrtb_ext.BidderDmx: dmx.Builder, openrtb_ext.BidderEmtv: emtv.Builder, openrtb_ext.BidderEmxDigital: cadentaperturemx.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 475d56a7ba8..fd5ae176ab1 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -92,6 +92,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderDecenterAds, BidderDeepintent, BidderDianomi, + BidderEdge226, BidderDmx, BidderEmtv, BidderEmxDigital, @@ -381,6 +382,7 @@ const ( BidderDecenterAds BidderName = "decenterads" BidderDeepintent BidderName = "deepintent" BidderDianomi BidderName = "dianomi" + BidderEdge226 BidderName = "edge226" BidderDmx BidderName = "dmx" BidderEmtv BidderName = "emtv" BidderEmxDigital BidderName = "emx_digital" diff --git a/openrtb_ext/imp_edge226.go b/openrtb_ext/imp_edge226.go new file mode 100644 index 00000000000..44f3490ee42 --- /dev/null +++ b/openrtb_ext/imp_edge226.go @@ -0,0 +1,6 @@ +package openrtb_ext + +type ImpExtEdge226 struct { + PlacementID string `json:"placementId"` + EndpointID string `json:"endpointId"` +} diff --git a/static/bidder-info/edge226.yaml b/static/bidder-info/edge226.yaml new file mode 100644 index 00000000000..c4fbdefc29b --- /dev/null +++ b/static/bidder-info/edge226.yaml @@ -0,0 +1,16 @@ +endpoint: "http://ssp.dauup.com/pserver" +maintainer: + email: "audit@edge226.com" +gvlVendorID: 1202 +capabilities: + site: + mediaTypes: + - banner + - video + - native + + app: + mediaTypes: + - banner + - video + - native diff --git a/static/bidder-params/edge226.json b/static/bidder-params/edge226.json new file mode 100644 index 00000000000..95b0fbdabb8 --- /dev/null +++ b/static/bidder-params/edge226.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Edge226 Adapter Params", + "description": "A schema which validates params accepted by the Edge226 adapter", + "type": "object", + + "properties": { + "placementId": { + "type": "string", + "minLength": 1, + "description": "Placement ID" + }, + "endpointId": { + "type": "string", + "minLength": 1, + "description": "Endpoint ID" + } + }, + "oneOf": [ + { "required": ["placementId"] }, + { "required": ["endpointId"] } + ] + } \ No newline at end of file From 6f4bb597a93a34d2cd08ef99c811fb316c3b511b Mon Sep 17 00:00:00 2001 From: Maxime Liege <56251840+github-maxime-liege@users.noreply.github.com> Date: Mon, 16 Oct 2023 10:46:35 +0200 Subject: [PATCH 165/268] New Adapter: Teads (#3112) --- adapters/teads/models.go | 40 ++++ adapters/teads/teads.go | 202 ++++++++++++++++++ adapters/teads/teads_test.go | 27 +++ .../exemplary/simple-banner-with-format.json | 168 +++++++++++++++ .../teadstest/exemplary/simple-banner.json | 158 ++++++++++++++ .../teadstest/exemplary/simple-video.json | 184 ++++++++++++++++ .../supplemental/bid-id-does-not-match.json | 152 +++++++++++++ .../supplemental/currency-empty-string.json | 185 ++++++++++++++++ .../supplemental/no-impression-response.json | 184 ++++++++++++++++ .../teadstest/supplemental/no-impression.json | 12 ++ .../supplemental/no-placementId.json | 28 +++ .../supplemental/renderer-name-empty.json | 143 +++++++++++++ .../supplemental/renderer-version-empty.json | 143 +++++++++++++ .../teadstest/supplemental/status-400.json | 65 ++++++ .../teadstest/supplemental/status-500.json | 65 ++++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_teads.go | 5 + static/bidder-info/teads.yaml | 9 + static/bidder-params/teads.json | 15 ++ 20 files changed, 1789 insertions(+) create mode 100644 adapters/teads/models.go create mode 100644 adapters/teads/teads.go create mode 100644 adapters/teads/teads_test.go create mode 100644 adapters/teads/teadstest/exemplary/simple-banner-with-format.json create mode 100644 adapters/teads/teadstest/exemplary/simple-banner.json create mode 100644 adapters/teads/teadstest/exemplary/simple-video.json create mode 100644 adapters/teads/teadstest/supplemental/bid-id-does-not-match.json create mode 100644 adapters/teads/teadstest/supplemental/currency-empty-string.json create mode 100644 adapters/teads/teadstest/supplemental/no-impression-response.json create mode 100644 adapters/teads/teadstest/supplemental/no-impression.json create mode 100644 adapters/teads/teadstest/supplemental/no-placementId.json create mode 100644 adapters/teads/teadstest/supplemental/renderer-name-empty.json create mode 100644 adapters/teads/teadstest/supplemental/renderer-version-empty.json create mode 100644 adapters/teads/teadstest/supplemental/status-400.json create mode 100644 adapters/teads/teadstest/supplemental/status-500.json create mode 100644 openrtb_ext/imp_teads.go create mode 100644 static/bidder-info/teads.yaml create mode 100644 static/bidder-params/teads.json diff --git a/adapters/teads/models.go b/adapters/teads/models.go new file mode 100644 index 00000000000..5b63c163197 --- /dev/null +++ b/adapters/teads/models.go @@ -0,0 +1,40 @@ +package teads + +import ( + "encoding/json" + "text/template" +) + +type adapter struct { + endpointTemplate *template.Template +} + +type defaultBidderImpExtension struct { + Bidder bidder `json:"bidder"` +} + +type bidder struct { + PlacementId int `json:"placementId"` +} + +type teadsImpExtension struct { + KV teadsKV `json:"kv"` +} + +type teadsKV struct { + PlacementId int `json:"placementId"` +} + +type teadsBidExt struct { + Prebid teadsPrebidExt `json:"prebid"` +} + +type teadsPrebidExt struct { + Meta teadsPrebidMeta `json:"meta"` +} + +type teadsPrebidMeta struct { + RendererName string `json:"rendererName"` + RendererVersion string `json:"rendererVersion"` + RendererData json.RawMessage `json:"rendererData"` +} diff --git a/adapters/teads/teads.go b/adapters/teads/teads.go new file mode 100644 index 00000000000..9c2bb57fc57 --- /dev/null +++ b/adapters/teads/teads.go @@ -0,0 +1,202 @@ +package teads + +import ( + "encoding/json" + "fmt" + "net/http" + "net/url" + "strconv" + "text/template" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/macros" + "github.com/prebid/prebid-server/openrtb_ext" +) + +// Builder builds a new instance of the Teads adapter for the given bidder with the given config. +func Builder(_ openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + template, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) + } + + bidder := &adapter{ + endpointTemplate: template, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + if len(request.Imp) == 0 { + return nil, []error{&errortypes.BadInput{ + Message: "No impression in the bid request", + }} + } + + endpointURL, err := a.buildEndpointURL() + if endpointURL == "" { + return nil, []error{err} + } + + if err := updateImpObject(request.Imp); err != nil { + return nil, []error{err} + } + + reqJSON, err := json.Marshal(request) + if err != nil { + return nil, []error{&errortypes.BadInput{ + Message: "Error parsing BidRequest object", + }} + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + return []*adapters.RequestData{{ + Method: "POST", + Uri: endpointURL, + Body: reqJSON, + Headers: headers, + }}, []error{} +} + +func updateImpObject(imps []openrtb2.Imp) error { + for i := range imps { + imp := &imps[i] + + if imp.Banner != nil { + if len(imp.Banner.Format) != 0 { + bannerCopy := *imp.Banner + bannerCopy.H = &imp.Banner.Format[0].H + bannerCopy.W = &imp.Banner.Format[0].W + imp.Banner = &bannerCopy + } + } + + var defaultImpExt defaultBidderImpExtension + if err := json.Unmarshal(imp.Ext, &defaultImpExt); err != nil { + return &errortypes.BadInput{ + Message: "Error parsing Imp.Ext object", + } + } + if defaultImpExt.Bidder.PlacementId == 0 { + return &errortypes.BadInput{ + Message: "placementId should not be 0.", + } + } + imp.TagID = strconv.Itoa(defaultImpExt.Bidder.PlacementId) + teadsImpExt := &teadsImpExtension{ + KV: teadsKV{ + PlacementId: defaultImpExt.Bidder.PlacementId, + }, + } + if extJson, err := json.Marshal(teadsImpExt); err != nil { + return &errortypes.BadInput{ + Message: "Error stringify Imp.Ext object", + } + } else { + imp.Ext = extJson + } + } + return nil +} + +// Builds enpoint url based on adapter-specific pub settings from imp.ext +func (a *adapter) buildEndpointURL() (string, error) { + endpointParams := macros.EndpointTemplateParams{} + host, err := macros.ResolveMacros(a.endpointTemplate, endpointParams) + + if err != nil { + return "", &errortypes.BadInput{ + Message: "Unable to parse endpoint url template: " + err.Error(), + } + } + + thisURI, err := url.Parse(host) + if err != nil { + return "", &errortypes.BadInput{ + Message: "Malformed URL: " + err.Error(), + } + } + + return thisURI.String(), nil +} + +func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, _ *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(response) { + return nil, nil + } + + err := adapters.CheckResponseStatusCodeForErrors(response) + if err != nil { + return nil, []error{err} + } + + var bidResp openrtb2.BidResponse + if err := json.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{err} + } + + bidderResponse := adapters.NewBidderResponseWithBidsCapacity(len(bidResp.SeatBid)) + + for _, sb := range bidResp.SeatBid { + for i := 0; i < len(sb.Bid); i++ { + bid := sb.Bid[i] + + bidExtTeads, err := getTeadsRendererFromBidExt(bid.Ext) + if err != nil { + return nil, err + } + bidType, err := getMediaTypeForImp(bid.ImpID, internalRequest.Imp) + if err != nil { + return nil, err + } + bidderResponse.Bids = append(bidderResponse.Bids, &adapters.TypedBid{ + Bid: &bid, + BidMeta: &openrtb_ext.ExtBidPrebidMeta{ + RendererName: bidExtTeads.Prebid.Meta.RendererName, + RendererVersion: bidExtTeads.Prebid.Meta.RendererVersion, + }, + BidType: bidType, + }) + } + } + if bidResp.Cur != "" { + bidderResponse.Currency = bidResp.Cur + } + return bidderResponse, nil +} + +func getTeadsRendererFromBidExt(ext json.RawMessage) (*teadsBidExt, []error) { + var bidExtTeads teadsBidExt + if err := json.Unmarshal(ext, &bidExtTeads); err != nil { + return nil, []error{err} + } + if bidExtTeads.Prebid.Meta.RendererName == "" { + return nil, []error{&errortypes.BadInput{ + Message: "RendererName should not be empty if present", + }} + } + if bidExtTeads.Prebid.Meta.RendererVersion == "" { + return nil, []error{&errortypes.BadInput{ + Message: "RendererVersion should not be empty if present", + }} + } + return &bidExtTeads, nil +} + +func getMediaTypeForImp(impID string, imps []openrtb2.Imp) (openrtb_ext.BidType, []error) { + for _, imp := range imps { + if imp.ID == impID { + if imp.Video != nil { + return openrtb_ext.BidTypeVideo, nil + } + return openrtb_ext.BidTypeBanner, nil + } + } + return openrtb_ext.BidType(""), []error{&errortypes.BadInput{ + Message: "Imp ids were not equals", + }} +} diff --git a/adapters/teads/teads_test.go b/adapters/teads/teads_test.go new file mode 100644 index 00000000000..791ce7aed6f --- /dev/null +++ b/adapters/teads/teads_test.go @@ -0,0 +1,27 @@ +package teads + +import ( + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderTeads, config.Adapter{ + Endpoint: "https://a.teads.tv/prebid-server/bid-request"}, config.Server{ExternalUrl: "https://a.teads.tv/prebid-server/bid-request", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "teadstest", bidder) +} + +func TestEndpointTemplateMalformed(t *testing.T) { + _, buildErr := Builder(openrtb_ext.BidderTeads, config.Adapter{ + Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "https://a.teads.tv/prebid-server/bid-request", GvlID: 1, DataCenter: "2"}) + + assert.Error(t, buildErr) +} diff --git a/adapters/teads/teadstest/exemplary/simple-banner-with-format.json b/adapters/teads/teadstest/exemplary/simple-banner-with-format.json new file mode 100644 index 00000000000..b2677e6faba --- /dev/null +++ b/adapters/teads/teadstest/exemplary/simple-banner-with-format.json @@ -0,0 +1,168 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": 125 + } + } + } + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "teads", + "version": "5.0.25", + "data": { + "resize": true, + "sdkEngineVersion": "189" + } + } + ] + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://a.teads.tv/prebid-server/bid-request", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "tagid": "125", + "banner": { + "w": 300, + "h": 250, + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "kv": { + "placementId": 125 + } + } + } + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "teads", + "version": "5.0.25", + "data": { + "resize": true, + "sdkEngineVersion": "189" + } + } + ] + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "39312703-e970-4914-ae56-8e7d7d1fd16b", + "tagid": "125", + "seatbid": [ + { + "seat": "teads", + "bid": [ + { + "id": "695ac187-fb3f-4d1f-8d5d-099c5e4c4d28", + "impid": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "price": 33, + "nurl": "https://localhost:8080/prebid-server/win-notice?data=base64&clearingPrice=${AUCTION_PRICE}", + "adm": "{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"ads\":[{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"type\":\"VastXml\",\"content\":\"Teads Technology\",\"scenario_id\":971105412,\"dsp_campaign_id\":\"1\",\"dsp_creative_id\":\"1\",\"insertion_id\":1,\"placement_id\":2,\"portfolio_item_id\":971104812}],\"wigoEnabled\":false,\"placementMetadata\":{\"2\":{\"adCallTrackingUrl\":\"https://localhost:18281/track?action=adCall&pid=2&pageId=2&auctid=39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6&vid=708ca808-ec55-4d97-ab81-9c4777e16058&hb_provider=prebid-server&hb_ad_unit_code=742d38c4-7994-4c2b-ac82-18d3a64ba3c7&env=thirdparty-inapp>c=1&gdpr_apply=false&gac=1&gap=1&ca=false&bsg=uncat&bsias=uncat&pfid=971104812&gid=1&brid=0&cid=1&rpm_reason=3&ut=1&p=5fwoPMJCquIB-txdmwQS0l79-hhHVnlTzyR9mmnBMtZRceP6-q31KzCfLpS8WTNaw_sXr-hkOFBxaxa-jyLblbVc&cts=1685971107773&cs=267268361555465193905\",\"auctionId\":\"39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6\"}},\"viewerId\":\"708ca808-ec55-4d97-ab81-9c4777e16058\"}", + "adid": "1", + "adomain": [ + "teads.com" + ], + "cid": "1", + "crid": "1", + "cat": [ + "IAB1-6", + "IAB10-5" + ], + "ext": { + "prebid": { + "meta": { + "rendererName": "teads", + "rendererVersion": "5.0.25", + "rendererData": { + "resize": true, + "sdkEngineVersion": "189" + } + } + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "695ac187-fb3f-4d1f-8d5d-099c5e4c4d28", + "impid": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "price": 33, + "nurl": "https://localhost:8080/prebid-server/win-notice?data=base64&clearingPrice=${AUCTION_PRICE}", + "adm": "{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"ads\":[{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"type\":\"VastXml\",\"content\":\"Teads Technology\",\"scenario_id\":971105412,\"dsp_campaign_id\":\"1\",\"dsp_creative_id\":\"1\",\"insertion_id\":1,\"placement_id\":2,\"portfolio_item_id\":971104812}],\"wigoEnabled\":false,\"placementMetadata\":{\"2\":{\"adCallTrackingUrl\":\"https://localhost:18281/track?action=adCall&pid=2&pageId=2&auctid=39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6&vid=708ca808-ec55-4d97-ab81-9c4777e16058&hb_provider=prebid-server&hb_ad_unit_code=742d38c4-7994-4c2b-ac82-18d3a64ba3c7&env=thirdparty-inapp>c=1&gdpr_apply=false&gac=1&gap=1&ca=false&bsg=uncat&bsias=uncat&pfid=971104812&gid=1&brid=0&cid=1&rpm_reason=3&ut=1&p=5fwoPMJCquIB-txdmwQS0l79-hhHVnlTzyR9mmnBMtZRceP6-q31KzCfLpS8WTNaw_sXr-hkOFBxaxa-jyLblbVc&cts=1685971107773&cs=267268361555465193905\",\"auctionId\":\"39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6\"}},\"viewerId\":\"708ca808-ec55-4d97-ab81-9c4777e16058\"}", + "adid": "1", + "adomain": [ + "teads.com" + ], + "cid": "1", + "crid": "1", + "cat": [ + "IAB1-6", + "IAB10-5" + ], + "ext": { + "prebid": { + "meta": { + "rendererName": "teads", + "rendererVersion": "5.0.25", + "rendererData": { + "resize": true, + "sdkEngineVersion": "189" + } + } + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/teads/teadstest/exemplary/simple-banner.json b/adapters/teads/teadstest/exemplary/simple-banner.json new file mode 100644 index 00000000000..2d9be7c7368 --- /dev/null +++ b/adapters/teads/teadstest/exemplary/simple-banner.json @@ -0,0 +1,158 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "placementId": 125 + } + } + } + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "teads", + "version": "5.0.25", + "data": { + "resize": true, + "sdkEngineVersion": "189" + } + } + ] + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://a.teads.tv/prebid-server/bid-request", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "tagid": "125", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "kv": { + "placementId": 125 + } + } + } + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "teads", + "version": "5.0.25", + "data": { + "resize": true, + "sdkEngineVersion": "189" + } + } + ] + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "39312703-e970-4914-ae56-8e7d7d1fd16b", + "tagid": "125", + "seatbid": [ + { + "seat": "teads", + "bid": [ + { + "id": "695ac187-fb3f-4d1f-8d5d-099c5e4c4d28", + "impid": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "price": 33, + "nurl": "https://localhost:8080/prebid-server/win-notice?data=base64&clearingPrice=${AUCTION_PRICE}", + "adm": "{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"ads\":[{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"type\":\"VastXml\",\"content\":\"Teads Technology\",\"scenario_id\":971105412,\"dsp_campaign_id\":\"1\",\"dsp_creative_id\":\"1\",\"insertion_id\":1,\"placement_id\":2,\"portfolio_item_id\":971104812}],\"wigoEnabled\":false,\"placementMetadata\":{\"2\":{\"adCallTrackingUrl\":\"https://localhost:18281/track?action=adCall&pid=2&pageId=2&auctid=39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6&vid=708ca808-ec55-4d97-ab81-9c4777e16058&hb_provider=prebid-server&hb_ad_unit_code=742d38c4-7994-4c2b-ac82-18d3a64ba3c7&env=thirdparty-inapp>c=1&gdpr_apply=false&gac=1&gap=1&ca=false&bsg=uncat&bsias=uncat&pfid=971104812&gid=1&brid=0&cid=1&rpm_reason=3&ut=1&p=5fwoPMJCquIB-txdmwQS0l79-hhHVnlTzyR9mmnBMtZRceP6-q31KzCfLpS8WTNaw_sXr-hkOFBxaxa-jyLblbVc&cts=1685971107773&cs=267268361555465193905\",\"auctionId\":\"39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6\"}},\"viewerId\":\"708ca808-ec55-4d97-ab81-9c4777e16058\"}", + "adid": "1", + "adomain": [ + "teads.com" + ], + "cid": "1", + "crid": "1", + "cat": [ + "IAB1-6", + "IAB10-5" + ], + "ext": { + "prebid": { + "meta": { + "rendererName": "teads", + "rendererVersion": "5.0.25", + "rendererData": { + "resize": true, + "sdkEngineVersion": "189" + } + } + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "695ac187-fb3f-4d1f-8d5d-099c5e4c4d28", + "impid": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "price": 33, + "nurl": "https://localhost:8080/prebid-server/win-notice?data=base64&clearingPrice=${AUCTION_PRICE}", + "adm": "{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"ads\":[{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"type\":\"VastXml\",\"content\":\"Teads Technology\",\"scenario_id\":971105412,\"dsp_campaign_id\":\"1\",\"dsp_creative_id\":\"1\",\"insertion_id\":1,\"placement_id\":2,\"portfolio_item_id\":971104812}],\"wigoEnabled\":false,\"placementMetadata\":{\"2\":{\"adCallTrackingUrl\":\"https://localhost:18281/track?action=adCall&pid=2&pageId=2&auctid=39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6&vid=708ca808-ec55-4d97-ab81-9c4777e16058&hb_provider=prebid-server&hb_ad_unit_code=742d38c4-7994-4c2b-ac82-18d3a64ba3c7&env=thirdparty-inapp>c=1&gdpr_apply=false&gac=1&gap=1&ca=false&bsg=uncat&bsias=uncat&pfid=971104812&gid=1&brid=0&cid=1&rpm_reason=3&ut=1&p=5fwoPMJCquIB-txdmwQS0l79-hhHVnlTzyR9mmnBMtZRceP6-q31KzCfLpS8WTNaw_sXr-hkOFBxaxa-jyLblbVc&cts=1685971107773&cs=267268361555465193905\",\"auctionId\":\"39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6\"}},\"viewerId\":\"708ca808-ec55-4d97-ab81-9c4777e16058\"}", + "adid": "1", + "adomain": [ + "teads.com" + ], + "cid": "1", + "crid": "1", + "cat": [ + "IAB1-6", + "IAB10-5" + ], + "ext": { + "prebid": { + "meta": { + "rendererName": "teads", + "rendererVersion": "5.0.25", + "rendererData": { + "resize": true, + "sdkEngineVersion": "189" + } + } + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/teads/teadstest/exemplary/simple-video.json b/adapters/teads/teadstest/exemplary/simple-video.json new file mode 100644 index 00000000000..814569a47e1 --- /dev/null +++ b/adapters/teads/teadstest/exemplary/simple-video.json @@ -0,0 +1,184 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "placementId": 125 + } + } + } + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "teads", + "version": "5.0.25", + "data": { + "resize": true, + "sdkEngineVersion": "189" + } + } + ] + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://a.teads.tv/prebid-server/bid-request", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "tagid": "125", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560 + }, + "ext": { + "kv": { + "placementId": 125 + } + } + } + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "teads", + "version": "5.0.25", + "data": { + "resize": true, + "sdkEngineVersion": "189" + } + } + ] + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "39312703-e970-4914-ae56-8e7d7d1fd16b", + "tagid": "125", + "seatbid": [ + { + "seat": "teads", + "bid": [ + { + "id": "695ac187-fb3f-4d1f-8d5d-099c5e4c4d28", + "impid": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "price": 33, + "nurl": "https://localhost:8080/prebid-server/win-notice?data=base64&clearingPrice=${AUCTION_PRICE}", + "adm": "{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"ads\":[{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"type\":\"VastXml\",\"content\":\"Teads Technology\",\"scenario_id\":971105412,\"dsp_campaign_id\":\"1\",\"dsp_creative_id\":\"1\",\"insertion_id\":1,\"placement_id\":2,\"portfolio_item_id\":971104812}],\"wigoEnabled\":false,\"placementMetadata\":{\"2\":{\"adCallTrackingUrl\":\"https://localhost:18281/track?action=adCall&pid=2&pageId=2&auctid=39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6&vid=708ca808-ec55-4d97-ab81-9c4777e16058&hb_provider=prebid-server&hb_ad_unit_code=742d38c4-7994-4c2b-ac82-18d3a64ba3c7&env=thirdparty-inapp>c=1&gdpr_apply=false&gac=1&gap=1&ca=false&bsg=uncat&bsias=uncat&pfid=971104812&gid=1&brid=0&cid=1&rpm_reason=3&ut=1&p=5fwoPMJCquIB-txdmwQS0l79-hhHVnlTzyR9mmnBMtZRceP6-q31KzCfLpS8WTNaw_sXr-hkOFBxaxa-jyLblbVc&cts=1685971107773&cs=267268361555465193905\",\"auctionId\":\"39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6\"}},\"viewerId\":\"708ca808-ec55-4d97-ab81-9c4777e16058\"}", + "adid": "1", + "adomain": [ + "teads.com" + ], + "cid": "1", + "crid": "1", + "cat": [ + "IAB1-6", + "IAB10-5" + ], + "ext": { + "prebid": { + "meta": { + "rendererName": "teads", + "rendererVersion": "5.0.25", + "rendererData": { + "resize": true, + "sdkEngineVersion": "189" + } + } + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "695ac187-fb3f-4d1f-8d5d-099c5e4c4d28", + "impid": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "price": 33, + "nurl": "https://localhost:8080/prebid-server/win-notice?data=base64&clearingPrice=${AUCTION_PRICE}", + "adm": "{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"ads\":[{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"type\":\"VastXml\",\"content\":\"Teads Technology\",\"scenario_id\":971105412,\"dsp_campaign_id\":\"1\",\"dsp_creative_id\":\"1\",\"insertion_id\":1,\"placement_id\":2,\"portfolio_item_id\":971104812}],\"wigoEnabled\":false,\"placementMetadata\":{\"2\":{\"adCallTrackingUrl\":\"https://localhost:18281/track?action=adCall&pid=2&pageId=2&auctid=39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6&vid=708ca808-ec55-4d97-ab81-9c4777e16058&hb_provider=prebid-server&hb_ad_unit_code=742d38c4-7994-4c2b-ac82-18d3a64ba3c7&env=thirdparty-inapp>c=1&gdpr_apply=false&gac=1&gap=1&ca=false&bsg=uncat&bsias=uncat&pfid=971104812&gid=1&brid=0&cid=1&rpm_reason=3&ut=1&p=5fwoPMJCquIB-txdmwQS0l79-hhHVnlTzyR9mmnBMtZRceP6-q31KzCfLpS8WTNaw_sXr-hkOFBxaxa-jyLblbVc&cts=1685971107773&cs=267268361555465193905\",\"auctionId\":\"39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6\"}},\"viewerId\":\"708ca808-ec55-4d97-ab81-9c4777e16058\"}", + "adid": "1", + "adomain": [ + "teads.com" + ], + "cid": "1", + "crid": "1", + "cat": [ + "IAB1-6", + "IAB10-5" + ], + "ext": { + "prebid": { + "meta": { + "rendererName": "teads", + "rendererVersion": "5.0.25", + "rendererData": { + "resize": true, + "sdkEngineVersion": "189" + } + } + } + } + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/teads/teadstest/supplemental/bid-id-does-not-match.json b/adapters/teads/teadstest/supplemental/bid-id-does-not-match.json new file mode 100644 index 00000000000..384e72fb537 --- /dev/null +++ b/adapters/teads/teadstest/supplemental/bid-id-does-not-match.json @@ -0,0 +1,152 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "placementId": 125 + } + } + } + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "teads", + "version": "5.0.25", + "data": { + "resize": true, + "sdkEngineVersion": "189" + } + } + ] + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://a.teads.tv/prebid-server/bid-request", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "tagid": "125", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560 + }, + "ext": { + "kv": { + "placementId": 125 + } + } + } + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "teads", + "version": "5.0.25", + "data": { + "resize": true, + "sdkEngineVersion": "189" + } + } + ] + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "39312703-e970-4914-ae56-8e7d7d1fd16b", + "cur": "EUR", + "tagid": "125", + "seatbid": [ + { + "seat": "teads", + "bid": [ + { + "id": "695ac187-fb3f-4d1f-8d5d-099c5e4c4d28", + "impid": "does-not-match", + "price": 33, + "nurl": "https://localhost:8080/prebid-server/win-notice?data=base64&clearingPrice=${AUCTION_PRICE}", + "adm": "{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"ads\":[{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"type\":\"VastXml\",\"content\":\"Teads Technology\",\"scenario_id\":971105412,\"dsp_campaign_id\":\"1\",\"dsp_creative_id\":\"1\",\"insertion_id\":1,\"placement_id\":2,\"portfolio_item_id\":971104812}],\"wigoEnabled\":false,\"placementMetadata\":{\"2\":{\"adCallTrackingUrl\":\"https://localhost:18281/track?action=adCall&pid=2&pageId=2&auctid=39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6&vid=708ca808-ec55-4d97-ab81-9c4777e16058&hb_provider=prebid-server&hb_ad_unit_code=742d38c4-7994-4c2b-ac82-18d3a64ba3c7&env=thirdparty-inapp>c=1&gdpr_apply=false&gac=1&gap=1&ca=false&bsg=uncat&bsias=uncat&pfid=971104812&gid=1&brid=0&cid=1&rpm_reason=3&ut=1&p=5fwoPMJCquIB-txdmwQS0l79-hhHVnlTzyR9mmnBMtZRceP6-q31KzCfLpS8WTNaw_sXr-hkOFBxaxa-jyLblbVc&cts=1685971107773&cs=267268361555465193905\",\"auctionId\":\"39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6\"}},\"viewerId\":\"708ca808-ec55-4d97-ab81-9c4777e16058\"}", + "adid": "1", + "adomain": [ + "teads.com" + ], + "cid": "1", + "crid": "1", + "cat": [ + "IAB1-6", + "IAB10-5" + ], + "ext": { + "prebid": { + "meta": { + "rendererName": "teads", + "rendererVersion": "5.0.25", + "rendererData": { + "resize": true, + "sdkEngineVersion": "189" + } + } + } + } + } + ] + } + ] + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Imp ids were not equals", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/teads/teadstest/supplemental/currency-empty-string.json b/adapters/teads/teadstest/supplemental/currency-empty-string.json new file mode 100644 index 00000000000..5f0d700b14b --- /dev/null +++ b/adapters/teads/teadstest/supplemental/currency-empty-string.json @@ -0,0 +1,185 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "placementId": 125 + } + } + } + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "teads", + "version": "5.0.25", + "data": { + "resize": true, + "sdkEngineVersion": "189" + } + } + ] + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://a.teads.tv/prebid-server/bid-request", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "tagid": "125", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560 + }, + "ext": { + "kv": { + "placementId": 125 + } + } + } + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "teads", + "version": "5.0.25", + "data": { + "resize": true, + "sdkEngineVersion": "189" + } + } + ] + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "39312703-e970-4914-ae56-8e7d7d1fd16b", + "cur": "EUR", + "tagid": "125", + "seatbid": [ + { + "seat": "teads", + "bid": [ + { + "id": "695ac187-fb3f-4d1f-8d5d-099c5e4c4d28", + "impid": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "price": 33, + "nurl": "https://localhost:8080/prebid-server/win-notice?data=base64&clearingPrice=${AUCTION_PRICE}", + "adm": "{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"ads\":[{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"type\":\"VastXml\",\"content\":\"Teads Technology\",\"scenario_id\":971105412,\"dsp_campaign_id\":\"1\",\"dsp_creative_id\":\"1\",\"insertion_id\":1,\"placement_id\":2,\"portfolio_item_id\":971104812}],\"wigoEnabled\":false,\"placementMetadata\":{\"2\":{\"adCallTrackingUrl\":\"https://localhost:18281/track?action=adCall&pid=2&pageId=2&auctid=39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6&vid=708ca808-ec55-4d97-ab81-9c4777e16058&hb_provider=prebid-server&hb_ad_unit_code=742d38c4-7994-4c2b-ac82-18d3a64ba3c7&env=thirdparty-inapp>c=1&gdpr_apply=false&gac=1&gap=1&ca=false&bsg=uncat&bsias=uncat&pfid=971104812&gid=1&brid=0&cid=1&rpm_reason=3&ut=1&p=5fwoPMJCquIB-txdmwQS0l79-hhHVnlTzyR9mmnBMtZRceP6-q31KzCfLpS8WTNaw_sXr-hkOFBxaxa-jyLblbVc&cts=1685971107773&cs=267268361555465193905\",\"auctionId\":\"39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6\"}},\"viewerId\":\"708ca808-ec55-4d97-ab81-9c4777e16058\"}", + "adid": "1", + "adomain": [ + "teads.com" + ], + "cid": "1", + "crid": "1", + "cat": [ + "IAB1-6", + "IAB10-5" + ], + "ext": { + "prebid": { + "meta": { + "rendererName": "teads", + "rendererVersion": "5.0.25", + "rendererData": { + "resize": true, + "sdkEngineVersion": "189" + } + } + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "695ac187-fb3f-4d1f-8d5d-099c5e4c4d28", + "impid": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "price": 33, + "nurl": "https://localhost:8080/prebid-server/win-notice?data=base64&clearingPrice=${AUCTION_PRICE}", + "adm": "{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"ads\":[{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"type\":\"VastXml\",\"content\":\"Teads Technology\",\"scenario_id\":971105412,\"dsp_campaign_id\":\"1\",\"dsp_creative_id\":\"1\",\"insertion_id\":1,\"placement_id\":2,\"portfolio_item_id\":971104812}],\"wigoEnabled\":false,\"placementMetadata\":{\"2\":{\"adCallTrackingUrl\":\"https://localhost:18281/track?action=adCall&pid=2&pageId=2&auctid=39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6&vid=708ca808-ec55-4d97-ab81-9c4777e16058&hb_provider=prebid-server&hb_ad_unit_code=742d38c4-7994-4c2b-ac82-18d3a64ba3c7&env=thirdparty-inapp>c=1&gdpr_apply=false&gac=1&gap=1&ca=false&bsg=uncat&bsias=uncat&pfid=971104812&gid=1&brid=0&cid=1&rpm_reason=3&ut=1&p=5fwoPMJCquIB-txdmwQS0l79-hhHVnlTzyR9mmnBMtZRceP6-q31KzCfLpS8WTNaw_sXr-hkOFBxaxa-jyLblbVc&cts=1685971107773&cs=267268361555465193905\",\"auctionId\":\"39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6\"}},\"viewerId\":\"708ca808-ec55-4d97-ab81-9c4777e16058\"}", + "adid": "1", + "adomain": [ + "teads.com" + ], + "cid": "1", + "crid": "1", + "cat": [ + "IAB1-6", + "IAB10-5" + ], + "ext": { + "prebid": { + "meta": { + "rendererName": "teads", + "rendererVersion": "5.0.25", + "rendererData": { + "resize": true, + "sdkEngineVersion": "189" + } + } + } + } + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/teads/teadstest/supplemental/no-impression-response.json b/adapters/teads/teadstest/supplemental/no-impression-response.json new file mode 100644 index 00000000000..814569a47e1 --- /dev/null +++ b/adapters/teads/teadstest/supplemental/no-impression-response.json @@ -0,0 +1,184 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "placementId": 125 + } + } + } + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "teads", + "version": "5.0.25", + "data": { + "resize": true, + "sdkEngineVersion": "189" + } + } + ] + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://a.teads.tv/prebid-server/bid-request", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "tagid": "125", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 940, + "h": 560 + }, + "ext": { + "kv": { + "placementId": 125 + } + } + } + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "teads", + "version": "5.0.25", + "data": { + "resize": true, + "sdkEngineVersion": "189" + } + } + ] + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "39312703-e970-4914-ae56-8e7d7d1fd16b", + "tagid": "125", + "seatbid": [ + { + "seat": "teads", + "bid": [ + { + "id": "695ac187-fb3f-4d1f-8d5d-099c5e4c4d28", + "impid": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "price": 33, + "nurl": "https://localhost:8080/prebid-server/win-notice?data=base64&clearingPrice=${AUCTION_PRICE}", + "adm": "{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"ads\":[{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"type\":\"VastXml\",\"content\":\"Teads Technology\",\"scenario_id\":971105412,\"dsp_campaign_id\":\"1\",\"dsp_creative_id\":\"1\",\"insertion_id\":1,\"placement_id\":2,\"portfolio_item_id\":971104812}],\"wigoEnabled\":false,\"placementMetadata\":{\"2\":{\"adCallTrackingUrl\":\"https://localhost:18281/track?action=adCall&pid=2&pageId=2&auctid=39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6&vid=708ca808-ec55-4d97-ab81-9c4777e16058&hb_provider=prebid-server&hb_ad_unit_code=742d38c4-7994-4c2b-ac82-18d3a64ba3c7&env=thirdparty-inapp>c=1&gdpr_apply=false&gac=1&gap=1&ca=false&bsg=uncat&bsias=uncat&pfid=971104812&gid=1&brid=0&cid=1&rpm_reason=3&ut=1&p=5fwoPMJCquIB-txdmwQS0l79-hhHVnlTzyR9mmnBMtZRceP6-q31KzCfLpS8WTNaw_sXr-hkOFBxaxa-jyLblbVc&cts=1685971107773&cs=267268361555465193905\",\"auctionId\":\"39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6\"}},\"viewerId\":\"708ca808-ec55-4d97-ab81-9c4777e16058\"}", + "adid": "1", + "adomain": [ + "teads.com" + ], + "cid": "1", + "crid": "1", + "cat": [ + "IAB1-6", + "IAB10-5" + ], + "ext": { + "prebid": { + "meta": { + "rendererName": "teads", + "rendererVersion": "5.0.25", + "rendererData": { + "resize": true, + "sdkEngineVersion": "189" + } + } + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "695ac187-fb3f-4d1f-8d5d-099c5e4c4d28", + "impid": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "price": 33, + "nurl": "https://localhost:8080/prebid-server/win-notice?data=base64&clearingPrice=${AUCTION_PRICE}", + "adm": "{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"ads\":[{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"type\":\"VastXml\",\"content\":\"Teads Technology\",\"scenario_id\":971105412,\"dsp_campaign_id\":\"1\",\"dsp_creative_id\":\"1\",\"insertion_id\":1,\"placement_id\":2,\"portfolio_item_id\":971104812}],\"wigoEnabled\":false,\"placementMetadata\":{\"2\":{\"adCallTrackingUrl\":\"https://localhost:18281/track?action=adCall&pid=2&pageId=2&auctid=39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6&vid=708ca808-ec55-4d97-ab81-9c4777e16058&hb_provider=prebid-server&hb_ad_unit_code=742d38c4-7994-4c2b-ac82-18d3a64ba3c7&env=thirdparty-inapp>c=1&gdpr_apply=false&gac=1&gap=1&ca=false&bsg=uncat&bsias=uncat&pfid=971104812&gid=1&brid=0&cid=1&rpm_reason=3&ut=1&p=5fwoPMJCquIB-txdmwQS0l79-hhHVnlTzyR9mmnBMtZRceP6-q31KzCfLpS8WTNaw_sXr-hkOFBxaxa-jyLblbVc&cts=1685971107773&cs=267268361555465193905\",\"auctionId\":\"39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6\"}},\"viewerId\":\"708ca808-ec55-4d97-ab81-9c4777e16058\"}", + "adid": "1", + "adomain": [ + "teads.com" + ], + "cid": "1", + "crid": "1", + "cat": [ + "IAB1-6", + "IAB10-5" + ], + "ext": { + "prebid": { + "meta": { + "rendererName": "teads", + "rendererVersion": "5.0.25", + "rendererData": { + "resize": true, + "sdkEngineVersion": "189" + } + } + } + } + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/teads/teadstest/supplemental/no-impression.json b/adapters/teads/teadstest/supplemental/no-impression.json new file mode 100644 index 00000000000..7b1cdceb9e1 --- /dev/null +++ b/adapters/teads/teadstest/supplemental/no-impression.json @@ -0,0 +1,12 @@ +{ + "mockBidRequest": { + "id": "test-request-id" + }, + + "expectedMakeRequestsErrors": [ + { + "value": "No impression in the bid request", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/teads/teadstest/supplemental/no-placementId.json b/adapters/teads/teadstest/supplemental/no-placementId.json new file mode 100644 index 00000000000..e343bc82a34 --- /dev/null +++ b/adapters/teads/teadstest/supplemental/no-placementId.json @@ -0,0 +1,28 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id-1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": {} + } + } + ] + }, + + "expectedMakeRequestsErrors": [ + { + "value": "placementId should not be 0.", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/teads/teadstest/supplemental/renderer-name-empty.json b/adapters/teads/teadstest/supplemental/renderer-name-empty.json new file mode 100644 index 00000000000..da4ee9a5094 --- /dev/null +++ b/adapters/teads/teadstest/supplemental/renderer-name-empty.json @@ -0,0 +1,143 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3 + ], + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "placementId": 125 + } + } + } + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "", + "version": "5.0.25", + "data": { + "resize": true, + "sdkEngineVersion": "189" + } + } + ] + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://a.teads.tv/prebid-server/bid-request", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "tagid": "125", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3 + ], + "w": 940, + "h": 560 + }, + "ext": { + "kv": { + "placementId": 125 + } + } + } + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "", + "version": "5.0.25", + "data": { + "resize": true, + "sdkEngineVersion": "189" + } + } + ] + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "39312703-e970-4914-ae56-8e7d7d1fd16b", + "tagid": "125", + "seatbid": [ + { + "seat": "teads", + "bid": [ + { + "id": "695ac187-fb3f-4d1f-8d5d-099c5e4c4d28", + "impid": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "price": 33, + "nurl": "https://localhost:8080/prebid-server/win-notice?data=base64&clearingPrice=${AUCTION_PRICE}", + "adm": "{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"ads\":[{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"type\":\"VastXml\",\"content\":\"Teads Technology\",\"scenario_id\":971105412,\"dsp_campaign_id\":\"1\",\"dsp_creative_id\":\"1\",\"insertion_id\":1,\"placement_id\":2,\"portfolio_item_id\":971104812}],\"wigoEnabled\":false,\"placementMetadata\":{\"2\":{\"adCallTrackingUrl\":\"https://localhost:18281/track?action=adCall&pid=2&pageId=2&auctid=39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6&vid=708ca808-ec55-4d97-ab81-9c4777e16058&hb_provider=prebid-server&hb_ad_unit_code=742d38c4-7994-4c2b-ac82-18d3a64ba3c7&env=thirdparty-inapp>c=1&gdpr_apply=false&gac=1&gap=1&ca=false&bsg=uncat&bsias=uncat&pfid=971104812&gid=1&brid=0&cid=1&rpm_reason=3&ut=1&p=5fwoPMJCquIB-txdmwQS0l79-hhHVnlTzyR9mmnBMtZRceP6-q31KzCfLpS8WTNaw_sXr-hkOFBxaxa-jyLblbVc&cts=1685971107773&cs=267268361555465193905\",\"auctionId\":\"39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6\"}},\"viewerId\":\"708ca808-ec55-4d97-ab81-9c4777e16058\"}", + "adid": "1", + "adomain": [ + "teads.com" + ], + "cid": "1", + "crid": "1", + "cat": [ + "IAB1-6", + "IAB10-5" + ], + "ext": { + "prebid": { + "meta": { + "rendererName": "", + "rendererVersion": "5.0.25", + "rendererData": { + "resize": true, + "sdkEngineVersion": "189" + } + } + } + } + } + ] + } + ] + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "RendererName should not be empty if present", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/teads/teadstest/supplemental/renderer-version-empty.json b/adapters/teads/teadstest/supplemental/renderer-version-empty.json new file mode 100644 index 00000000000..e9e7b278dcb --- /dev/null +++ b/adapters/teads/teadstest/supplemental/renderer-version-empty.json @@ -0,0 +1,143 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3 + ], + "w": 940, + "h": 560 + }, + "ext": { + "bidder": { + "placementId": 125 + } + } + } + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "teads", + "version": "", + "data": { + "resize": true, + "sdkEngineVersion": "189" + } + } + ] + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://a.teads.tv/prebid-server/bid-request", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "tagid": "125", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 15, + "maxduration": 30, + "protocols": [ + 2, + 3 + ], + "w": 940, + "h": 560 + }, + "ext": { + "kv": { + "placementId": 125 + } + } + } + ], + "ext": { + "prebid": { + "sdk": { + "renderers": [ + { + "name": "teads", + "version": "", + "data": { + "resize": true, + "sdkEngineVersion": "189" + } + } + ] + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "39312703-e970-4914-ae56-8e7d7d1fd16b", + "tagid": "125", + "seatbid": [ + { + "seat": "teads", + "bid": [ + { + "id": "695ac187-fb3f-4d1f-8d5d-099c5e4c4d28", + "impid": "b6321d41-3840-4cb3-baad-b6fc5b0c8553", + "price": 33, + "nurl": "https://localhost:8080/prebid-server/win-notice?data=base64&clearingPrice=${AUCTION_PRICE}", + "adm": "{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"ads\":[{\"settings\":{\"values\":{\"animations\":{\"expand\":0,\"collapse\":0.5},\"placementId\":2,\"adType\":\"video\",\"placementFormat\":\"inread\",\"allowedPlayer\":\"any\",\"pageId\":2},\"components\":{\"closeButton\":{\"display\":false,\"countdown\":0},\"credits\":{\"display\":false},\"soundButton\":{\"display\":true,\"countdown\":0,\"type\":\"equalizer\"},\"label\":{\"display\":false},\"slider\":{\"closeButtonDisplay\":false}},\"behaviors\":{\"smartPosition\":{\"top\":false,\"corner\":false,\"mustBypassWhitelist\":true},\"slider\":{\"enable\":false},\"friendly\":false,\"playerClick\":\"fullscreen\",\"soundStart\":{\"type\":\"mute\"},\"soundMute\":\"threshold\",\"soundOver\":\"over\",\"launch\":\"auto\",\"videoStart\":\"threshold\",\"videoPause\":\"threshold\",\"secure\":false}},\"type\":\"VastXml\",\"content\":\"Teads Technology\",\"scenario_id\":971105412,\"dsp_campaign_id\":\"1\",\"dsp_creative_id\":\"1\",\"insertion_id\":1,\"placement_id\":2,\"portfolio_item_id\":971104812}],\"wigoEnabled\":false,\"placementMetadata\":{\"2\":{\"adCallTrackingUrl\":\"https://localhost:18281/track?action=adCall&pid=2&pageId=2&auctid=39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6&vid=708ca808-ec55-4d97-ab81-9c4777e16058&hb_provider=prebid-server&hb_ad_unit_code=742d38c4-7994-4c2b-ac82-18d3a64ba3c7&env=thirdparty-inapp>c=1&gdpr_apply=false&gac=1&gap=1&ca=false&bsg=uncat&bsias=uncat&pfid=971104812&gid=1&brid=0&cid=1&rpm_reason=3&ut=1&p=5fwoPMJCquIB-txdmwQS0l79-hhHVnlTzyR9mmnBMtZRceP6-q31KzCfLpS8WTNaw_sXr-hkOFBxaxa-jyLblbVc&cts=1685971107773&cs=267268361555465193905\",\"auctionId\":\"39312703-e970-4914-ae56-8e7d7d1fd16b__b6321d41-3840-4cb3-baad-b6fc5b0c8553__c0f2e6ba-63d0-4e20-ab41-fe0822eb65a6\"}},\"viewerId\":\"708ca808-ec55-4d97-ab81-9c4777e16058\"}", + "adid": "1", + "adomain": [ + "teads.com" + ], + "cid": "1", + "crid": "1", + "cat": [ + "IAB1-6", + "IAB10-5" + ], + "ext": { + "prebid": { + "meta": { + "rendererName": "teads", + "rendererVersion": "", + "rendererData": { + "resize": true, + "sdkEngineVersion": "189" + } + } + } + } + } + ] + } + ] + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "RendererVersion should not be empty if present", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/teads/teadstest/supplemental/status-400.json b/adapters/teads/teadstest/supplemental/status-400.json new file mode 100644 index 00000000000..cd9fafff0a1 --- /dev/null +++ b/adapters/teads/teadstest/supplemental/status-400.json @@ -0,0 +1,65 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": 1 + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://a.teads.tv/prebid-server/bid-request", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "kv": { + "placementId": 1 + } + } + } + ] + } + }, + "mockResponse": { + "status": 400, + "body": {} + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/teads/teadstest/supplemental/status-500.json b/adapters/teads/teadstest/supplemental/status-500.json new file mode 100644 index 00000000000..337d4754006 --- /dev/null +++ b/adapters/teads/teadstest/supplemental/status-500.json @@ -0,0 +1,65 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": 1 + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://a.teads.tv/prebid-server/bid-request", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "kv": { + "placementId": 1 + } + } + } + ] + } + }, + "mockResponse": { + "status": 500, + "body": {} + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 5d06ba9ba43..d8ab16c1d61 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -159,6 +159,7 @@ import ( "github.com/prebid/prebid-server/adapters/suntContent" "github.com/prebid/prebid-server/adapters/taboola" "github.com/prebid/prebid-server/adapters/tappx" + "github.com/prebid/prebid-server/adapters/teads" "github.com/prebid/prebid-server/adapters/telaria" "github.com/prebid/prebid-server/adapters/tpmn" "github.com/prebid/prebid-server/adapters/trafficgate" @@ -363,6 +364,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderSynacormedia: imds.Builder, openrtb_ext.BidderTaboola: taboola.Builder, openrtb_ext.BidderTappx: tappx.Builder, + openrtb_ext.BidderTeads: teads.Builder, openrtb_ext.BidderTelaria: telaria.Builder, openrtb_ext.BidderTpmn: tpmn.Builder, openrtb_ext.BidderTrafficGate: trafficgate.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index fd5ae176ab1..635f17cd58f 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -191,6 +191,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderSynacormedia, BidderTaboola, BidderTappx, + BidderTeads, BidderTelaria, BidderTpmn, BidderTrafficGate, @@ -481,6 +482,7 @@ const ( BidderSynacormedia BidderName = "synacormedia" BidderTaboola BidderName = "taboola" BidderTappx BidderName = "tappx" + BidderTeads BidderName = "teads" BidderTelaria BidderName = "telaria" BidderTpmn BidderName = "tpmn" BidderTrafficGate BidderName = "trafficgate" diff --git a/openrtb_ext/imp_teads.go b/openrtb_ext/imp_teads.go new file mode 100644 index 00000000000..50d11ae9192 --- /dev/null +++ b/openrtb_ext/imp_teads.go @@ -0,0 +1,5 @@ +package openrtb_ext + +type ExtImpTeads struct { + PlacementID string `json:"placementId"` +} diff --git a/static/bidder-info/teads.yaml b/static/bidder-info/teads.yaml new file mode 100644 index 00000000000..5dc428ddf7b --- /dev/null +++ b/static/bidder-info/teads.yaml @@ -0,0 +1,9 @@ +endpoint: "https://a.teads.tv/prebid-server/bid-request" +maintainer: + email: "support-sdk@teads.com" +gvlVendorID: 132 +capabilities: + app: + mediaTypes: + - banner + - video \ No newline at end of file diff --git a/static/bidder-params/teads.json b/static/bidder-params/teads.json new file mode 100644 index 00000000000..2b3f47d8bc2 --- /dev/null +++ b/static/bidder-params/teads.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Teads Adapter Params", + "description": "A schema which validates params accepted by the Teads adapter", + + "type": "object", + "properties": { + "placementId": { + "type": "integer", + "description": "The placement id.", + "minimum": 1 + } + }, + "required": ["placementId"] + } \ No newline at end of file From dff9b3b581e66dce0ed32a3d3d3cdf83771cb984 Mon Sep 17 00:00:00 2001 From: vrtcal-dev <50931150+vrtcal-dev@users.noreply.github.com> Date: Mon, 16 Oct 2023 05:59:02 -0500 Subject: [PATCH 166/268] Updated User Sync Support and GPP Support Flag (#3181) Co-authored-by: Ubuntu --- static/bidder-info/vrtcal.yaml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/static/bidder-info/vrtcal.yaml b/static/bidder-info/vrtcal.yaml index 2aeb292a7ed..1ce005cd223 100644 --- a/static/bidder-info/vrtcal.yaml +++ b/static/bidder-info/vrtcal.yaml @@ -14,7 +14,11 @@ capabilities: - video - native userSync: - # vrtcal supports user syncing, but requires configuration by the host. contact this - # bidder directly at the email address in this file to ask about enabling user sync. - supports: - - redirect + iframe: + url: "https://usync.vrtcal.com/i?ssp=1804&synctype=iframe&us_privacy={{.USPrivacy}}&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&surl={{.RedirectURL}}" + userMacro: "$$VRTCALUSER$$" + redirect: + url: "https://usync.vrtcal.com/i?ssp=1804&synctype=redirect&us_privacy={{.USPrivacy}}&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&surl={{.RedirectURL}}" + userMacro: "$$VRTCALUSER$$" +openrtb: + gpp-supported: true From 987e640abf1bd069f7da0825c6622b30ea2d5c9e Mon Sep 17 00:00:00 2001 From: Ashish Garg Date: Mon, 16 Oct 2023 16:40:50 +0530 Subject: [PATCH 167/268] make event endpoint case insensitive (#3199) --- endpoints/events/event.go | 8 +++++++- endpoints/events/event_test.go | 13 +++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/endpoints/events/event.go b/endpoints/events/event.go index d5cf89b2ef5..ffcb4e006e1 100644 --- a/endpoints/events/event.go +++ b/endpoints/events/event.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "github.com/prebid/prebid-server/openrtb_ext" "net/http" "net/url" "strconv" @@ -188,7 +189,12 @@ func ParseEventRequest(r *http.Request) (*analytics.EventRequest, []error) { } // Bidder - event.Bidder = r.URL.Query().Get(BidderParameter) + bidderName := r.URL.Query().Get(BidderParameter) + if normalisedBidderName, ok := openrtb_ext.NormalizeBidderName(bidderName); ok { + bidderName = normalisedBidderName.String() + } + + event.Bidder = bidderName return event, errs } diff --git a/endpoints/events/event_test.go b/endpoints/events/event_test.go index d721187b6ff..5fc115786fe 100644 --- a/endpoints/events/event_test.go +++ b/endpoints/events/event_test.go @@ -651,6 +651,19 @@ func TestShouldParseEventCorrectly(t *testing.T) { Analytics: analytics.Enabled, }, }, + "case insensitive bidder name": { + req: httptest.NewRequest("GET", "/event?t=win&b=bidId&f=b&ts=1000&x=1&a=accountId&bidder=RubiCon&int=intType", strings.NewReader("")), + expected: &analytics.EventRequest{ + Type: analytics.Win, + BidID: "bidId", + Timestamp: 1000, + Bidder: "rubicon", + AccountID: "", + Format: analytics.Blank, + Analytics: analytics.Enabled, + Integration: "intType", + }, + }, } for name, test := range tests { From 05e06bb1b22f9a957813ec77fdbbe29947d5aa25 Mon Sep 17 00:00:00 2001 From: lm-ved <105272141+lm-ved@users.noreply.github.com> Date: Mon, 16 Oct 2023 16:43:38 +0530 Subject: [PATCH 168/268] New Adapter: LemmaDigital (#3157) Co-authored-by: Tushar Pathare --- adapters/lemmadigital/lemmadigital.go | 114 ++++++++++++++ adapters/lemmadigital/lemmadigital_test.go | 20 +++ .../lemmadigitaltest/exemplary/banner.json | 110 +++++++++++++ .../lemmadigitaltest/exemplary/multi-imp.json | 144 ++++++++++++++++++ .../lemmadigitaltest/exemplary/video.json | 89 +++++++++++ .../supplemental/empty-imps.json | 18 +++ .../supplemental/empty-seatbid-array.json | 101 ++++++++++++ .../invalid-ld-ext-bidder-object.json | 48 ++++++ .../supplemental/invalid-ld-ext-object.json | 42 +++++ .../supplemental/invalid-response.json | 62 ++++++++ .../supplemental/status-code-bad-request.json | 62 ++++++++ .../supplemental/status-code-no-content.json | 59 +++++++ .../supplemental/status-code-other-error.json | 62 ++++++++ adapters/lemmadigital/params_test.go | 59 +++++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_lemmadigital.go | 6 + static/bidder-info/lemmadigital.yaml | 14 ++ static/bidder-params/lemmadigital.json | 19 +++ 19 files changed, 1033 insertions(+) create mode 100644 adapters/lemmadigital/lemmadigital.go create mode 100644 adapters/lemmadigital/lemmadigital_test.go create mode 100644 adapters/lemmadigital/lemmadigitaltest/exemplary/banner.json create mode 100644 adapters/lemmadigital/lemmadigitaltest/exemplary/multi-imp.json create mode 100644 adapters/lemmadigital/lemmadigitaltest/exemplary/video.json create mode 100644 adapters/lemmadigital/lemmadigitaltest/supplemental/empty-imps.json create mode 100644 adapters/lemmadigital/lemmadigitaltest/supplemental/empty-seatbid-array.json create mode 100644 adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-ld-ext-bidder-object.json create mode 100644 adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-ld-ext-object.json create mode 100644 adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-response.json create mode 100644 adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-bad-request.json create mode 100644 adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-no-content.json create mode 100644 adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-other-error.json create mode 100644 adapters/lemmadigital/params_test.go create mode 100644 openrtb_ext/imp_lemmadigital.go create mode 100644 static/bidder-info/lemmadigital.yaml create mode 100644 static/bidder-params/lemmadigital.json diff --git a/adapters/lemmadigital/lemmadigital.go b/adapters/lemmadigital/lemmadigital.go new file mode 100644 index 00000000000..3b77de52984 --- /dev/null +++ b/adapters/lemmadigital/lemmadigital.go @@ -0,0 +1,114 @@ +package lemmadigital + +import ( + "encoding/json" + "errors" + "fmt" + "strconv" + "text/template" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/macros" + "github.com/prebid/prebid-server/openrtb_ext" +) + +type adapter struct { + endpoint *template.Template +} + +// Builder builds a new instance of the Lemmadigital adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + template, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) + } + + bidder := &adapter{ + endpoint: template, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + if len(request.Imp) == 0 { + return nil, []error{errors.New("Impression array should not be empty")} + } + + var bidderExt adapters.ExtImpBidder + if err := json.Unmarshal(request.Imp[0].Ext, &bidderExt); err != nil { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Invalid imp.ext for impression index %d. Error Infomation: %s", 0, err.Error()), + }} + } + + var impExt openrtb_ext.ImpExtLemmaDigital + if err := json.Unmarshal(bidderExt.Bidder, &impExt); err != nil { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Invalid imp.ext.bidder for impression index %d. Error Infomation: %s", 0, err.Error()), + }} + } + + endpoint, err := a.buildEndpointURL(impExt) + if err != nil { + return nil, []error{err} + } + + requestJSON, err := json.Marshal(request) + if err != nil { + return nil, []error{err} + } + + requestData := &adapters.RequestData{ + Method: "POST", + Uri: endpoint, + Body: requestJSON, + } + + return []*adapters.RequestData{requestData}, nil +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} + } + + var response openrtb2.BidResponse + if err := json.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidType := openrtb_ext.BidTypeBanner + if nil != request.Imp[0].Video { + bidType = openrtb_ext.BidTypeVideo + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + if len(response.Cur) > 0 { + bidResponse.Currency = response.Cur + } + for _, seatBid := range response.SeatBid { + for i := range seatBid.Bid { + b := &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + break + } + + return bidResponse, nil +} + +func (a *adapter) buildEndpointURL(params openrtb_ext.ImpExtLemmaDigital) (string, error) { + endpointParams := macros.EndpointTemplateParams{PublisherID: strconv.Itoa(params.PublisherId), + AdUnit: strconv.Itoa(params.AdId)} + return macros.ResolveMacros(a.endpoint, endpointParams) +} diff --git a/adapters/lemmadigital/lemmadigital_test.go b/adapters/lemmadigital/lemmadigital_test.go new file mode 100644 index 00000000000..0372fa81d6b --- /dev/null +++ b/adapters/lemmadigital/lemmadigital_test.go @@ -0,0 +1,20 @@ +package lemmadigital + +import ( + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderLemmadigital, config.Adapter{ + Endpoint: "https://sg.ads.lemmatechnologies.com/lemma/servad?pid={{.PublisherID}}&aid={{.AdUnit}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "lemmadigitaltest", bidder) +} diff --git a/adapters/lemmadigital/lemmadigitaltest/exemplary/banner.json b/adapters/lemmadigital/lemmadigitaltest/exemplary/banner.json new file mode 100644 index 00000000000..a478380e394 --- /dev/null +++ b/adapters/lemmadigital/lemmadigitaltest/exemplary/banner.json @@ -0,0 +1,110 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 1920, + "h": 1080 + }], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "aid": 1, + "pid": 1 + } + }, + "bidfloor": 0.1 + }], + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36" + }, + "site": { + "id": "siteID", + "publisher": { + "id": "1" + } + } + }, + + "httpCalls": [{ + "expectedRequest": { + "uri": "https://sg.ads.lemmatechnologies.com/lemma/servad?pid=1&aid=1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 1920, + "h": 1080 + }], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "aid": 1, + "pid": 1 + } + }, + "bidfloor": 0.1 + }], + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36" + }, + "site": { + "id": "siteID", + "publisher": { + "id": "1" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "seat": "1", + "bid": [{ + "id": "1239875642389471056", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "1", + "adm": "some-test-ad", + "adomain": ["lemmadigital.com"], + "crid": "1", + "h": 1080, + "w": 1920, + "dealid": "test_deal" + }] + }], + "bidid": "1239875642389471056", + "cur": "USD" + } + } + }], + + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "1239875642389471056", + "impid": "test-imp-id", + "price": 0.5, + "adid": "1", + "adm": "some-test-ad", + "adomain": ["lemmadigital.com"], + "crid": "1", + "w": 1920, + "h": 1080, + "dealid": "test_deal" + }, + "type": "banner" + }] + }] +} \ No newline at end of file diff --git a/adapters/lemmadigital/lemmadigitaltest/exemplary/multi-imp.json b/adapters/lemmadigital/lemmadigitaltest/exemplary/multi-imp.json new file mode 100644 index 00000000000..e051b54ff95 --- /dev/null +++ b/adapters/lemmadigital/lemmadigitaltest/exemplary/multi-imp.json @@ -0,0 +1,144 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 1920, + "h": 1080 + }], + "h": 1080, + "w": 1920 + }, + "ext": { + "bidder": { + "aid": 1, + "pid": 1 + } + }, + "bidfloor": 0.1 + }, { + "id": "test-imp-id-2", + "banner": { + "format": [{ + "w": 1080, + "h": 1920 + }], + "h": 1920, + "w": 1080 + }, + "ext": { + "bidder": { + "aid": 1, + "pid": 1 + } + }, + "bidfloor": 0.12 + }], + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36" + }, + "site": { + "id": "siteID", + "publisher": { + "id": "1" + } + } + }, + + "httpCalls": [{ + "expectedRequest": { + "uri": "https://sg.ads.lemmatechnologies.com/lemma/servad?pid=1&aid=1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 1920, + "h": 1080 + }], + "h": 1080, + "w": 1920 + }, + "ext": { + "bidder": { + "aid": 1, + "pid": 1 + } + }, + "bidfloor": 0.1 + }, { + "id": "test-imp-id-2", + "banner": { + "format": [{ + "w": 1080, + "h": 1920 + }], + "h": 1920, + "w": 1080 + }, + "ext": { + "bidder": { + "aid": 1, + "pid": 1 + } + }, + "bidfloor": 0.12 + }], + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36" + }, + "site": { + "id": "siteID", + "publisher": { + "id": "1" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "seat": "1", + "bid": [{ + "id": "1239875642389471056", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "1", + "adm": "some-test-ad", + "adomain": ["lemmadigital.com"], + "crid": "1", + "h": 1080, + "w": 1920, + "dealid": "test_deal" + }] + }], + "bidid": "1239875642389471056", + "cur": "USD" + } + } + }], + + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "1239875642389471056", + "impid": "test-imp-id", + "price": 0.5, + "adid": "1", + "adm": "some-test-ad", + "adomain": ["lemmadigital.com"], + "crid": "1", + "w": 1920, + "h": 1080, + "dealid": "test_deal" + }, + "type": "banner" + }] + }] +} \ No newline at end of file diff --git a/adapters/lemmadigital/lemmadigitaltest/exemplary/video.json b/adapters/lemmadigital/lemmadigitaltest/exemplary/video.json new file mode 100644 index 00000000000..63bab75b674 --- /dev/null +++ b/adapters/lemmadigital/lemmadigitaltest/exemplary/video.json @@ -0,0 +1,89 @@ +{ + "mockBidRequest": { + "id": "test-request-id-video", + "imp": [{ + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "protocols": [1], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "aid": 1, + "pid": 1 + } + } + }], + "site": { + "publisher": { + "id": "1" + } + } + }, + + "httpCalls": [{ + "expectedRequest": { + "uri": "https://sg.ads.lemmatechnologies.com/lemma/servad?pid=1&aid=1", + "body": { + "id": "test-request-id-video", + "imp": [{ + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "protocols": [1], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "aid": 1, + "pid": 1 + } + } + }], + "site": { + "publisher": { + "id": "1" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id-video", + "seatbid": [{ + "seat": "1", + "bid": [{ + "id": "1239875642389471056", + "impid": "test-imp-id-video", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_video", + "h": 1080, + "w": 1920 + }] + }], + "cur": "USD" + } + } + }], + + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "1239875642389471056", + "impid": "test-imp-id-video", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_video", + "w": 1920, + "h": 1080 + }, + "type": "video" + }] + }] +} \ No newline at end of file diff --git a/adapters/lemmadigital/lemmadigitaltest/supplemental/empty-imps.json b/adapters/lemmadigital/lemmadigitaltest/supplemental/empty-imps.json new file mode 100644 index 00000000000..e13cdcb480a --- /dev/null +++ b/adapters/lemmadigital/lemmadigitaltest/supplemental/empty-imps.json @@ -0,0 +1,18 @@ +{ + "mockBidRequest": { + "id": "test-request-id-video", + "imp": [], + "site": { + "publisher": { + "id": "1" + } + } + }, + + "httpCalls": [], + "expectedBidResponses": [], + "expectedMakeRequestsErrors": [{ + "value": "Impression array should not be empty", + "comparison": "literal" + }] +} \ No newline at end of file diff --git a/adapters/lemmadigital/lemmadigitaltest/supplemental/empty-seatbid-array.json b/adapters/lemmadigital/lemmadigitaltest/supplemental/empty-seatbid-array.json new file mode 100644 index 00000000000..c88e0fa7861 --- /dev/null +++ b/adapters/lemmadigital/lemmadigitaltest/supplemental/empty-seatbid-array.json @@ -0,0 +1,101 @@ +{ + "mockBidRequest": { + "app": { + "bundle": "com.ld.test", + "cat": [ + "IAB-1" + ], + "domain": "ld.com", + "id": "1", + "name": "LD Test", + "publisher": { + "id": "1" + } + }, + "device": { + "dnt": 0, + "ip": "0.0.0.0", + "language": "en", + "ua": "user-agent" + }, + "id": "test-request-id-video", + "imp": [{ + "ext": { + "bidder": { + "aid": 1, + "pid": 1 + } + }, + "id": "test-imp-id-video", + "video": { + "h": 1080, + "mimes": [ + "video/mp4" + ], + "protocols": [ + 1 + ], + "w": 1920 + } + }], + "tmax": 1000 + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://sg.ads.lemmatechnologies.com/lemma/servad?pid=1&aid=1", + "body": { + "app": { + "bundle": "com.ld.test", + "cat": [ + "IAB-1" + ], + "domain": "ld.com", + "id": "1", + "name": "LD Test", + "publisher": { + "id": "1" + } + }, + "device": { + "dnt": 0, + "ip": "0.0.0.0", + "language": "en", + "ua": "user-agent" + }, + "id": "test-request-id-video", + "imp": [{ + "ext": { + "bidder": { + "aid": 1, + "pid": 1 + } + }, + "id": "test-imp-id-video", + "video": { + "h": 1080, + "mimes": [ + "video/mp4" + ], + "protocols": [ + 1 + ], + "w": 1920 + } + }], + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-1", + "seatbid": [], + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [] +}] +} \ No newline at end of file diff --git a/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-ld-ext-bidder-object.json b/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-ld-ext-bidder-object.json new file mode 100644 index 00000000000..ba46d76b598 --- /dev/null +++ b/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-ld-ext-bidder-object.json @@ -0,0 +1,48 @@ +{ + "expectedMakeRequestsErrors": [{ + "value": "Invalid imp.ext.bidder for impression index 0. Error Infomation: json: cannot unmarshal string into Go struct field ImpExtLemmaDigital.pid of type int", + "comparison": "literal" + }], + "mockBidRequest": { + "app": { + "bundle": "com.ld.test", + "cat": [ + "IAB-1" + ], + "domain": "ld.com", + "id": "1", + "name": "LD Test", + "publisher": { + "id": "1" + } + }, + "device": { + "dnt": 0, + "ip": "0.0.0.0", + "language": "en", + "ua": "user-agent" + }, + "id": "test-request-id-video", + "imp": [{ + "id": "test-imp-id-video", + "video": { + "h": 1080, + "mimes": [ + "video/mp4" + ], + "protocols": [ + 1 + ], + "w": 1920 + }, + "ext": { + "bidder": { + "aid": 1, + "pid": "1" + } + } + }], + "tmax": 1000 + }, + "httpCalls": [] + } \ No newline at end of file diff --git a/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-ld-ext-object.json b/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-ld-ext-object.json new file mode 100644 index 00000000000..4d3d795c185 --- /dev/null +++ b/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-ld-ext-object.json @@ -0,0 +1,42 @@ +{ + "expectedMakeRequestsErrors": [{ + "value": "Invalid imp.ext for impression index 0. Error Infomation: unexpected end of JSON input", + "comparison": "literal" + }], + "mockBidRequest": { + "app": { + "bundle": "com.ld.test", + "cat": [ + "IAB-1" + ], + "domain": "ld.com", + "id": "1", + "name": "LD Test", + "publisher": { + "id": "1" + } + }, + "device": { + "dnt": 0, + "ip": "0.0.0.0", + "language": "en", + "ua": "user-agent" + }, + "id": "test-request-id-video", + "imp": [{ + "id": "test-imp-id-video", + "video": { + "h": 1080, + "mimes": [ + "video/mp4" + ], + "protocols": [ + 1 + ], + "w": 1920 + } + }], + "tmax": 1000 + }, + "httpCalls": [] +} \ No newline at end of file diff --git a/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-response.json b/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-response.json new file mode 100644 index 00000000000..036d35fb345 --- /dev/null +++ b/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-response.json @@ -0,0 +1,62 @@ +{ + "mockBidRequest": { + "id": "test-request-id-video", + "imp": [{ + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "protocols": [1], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "aid": 1, + "pid": 1 + } + } + }], + "site": { + "publisher": { + "id": "1" + } + } + }, + + "httpCalls": [{ + "expectedRequest": { + "uri": "https://sg.ads.lemmatechnologies.com/lemma/servad?pid=1&aid=1", + "body": { + "id": "test-request-id-video", + "imp": [{ + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "protocols": [1], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "aid": 1, + "pid": 1 + } + } + }], + "site": { + "publisher": { + "id": "1" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": "" + } + }], + "expectedMakeBidsErrors": [{ + "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "comparison": "literal" + }] +} \ No newline at end of file diff --git a/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-bad-request.json b/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-bad-request.json new file mode 100644 index 00000000000..37ebea4b7be --- /dev/null +++ b/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-bad-request.json @@ -0,0 +1,62 @@ +{ + "mockBidRequest": { + "id": "test-request-id-video", + "imp": [{ + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "protocols": [1], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "aid": 1, + "pid": 1 + } + } + }], + "site": { + "publisher": { + "id": "1" + } + } + }, + + "httpCalls": [{ + "expectedRequest": { + "uri": "https://sg.ads.lemmatechnologies.com/lemma/servad?pid=1&aid=1", + "body": { + "id": "test-request-id-video", + "imp": [{ + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "protocols": [1], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "aid": 1, + "pid": 1 + } + } + }], + "site": { + "publisher": { + "id": "1" + } + } + } + }, + "mockResponse": { + "status": 400 + } + }], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [{ + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + }] +} \ No newline at end of file diff --git a/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-no-content.json b/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-no-content.json new file mode 100644 index 00000000000..7c4813df43a --- /dev/null +++ b/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-no-content.json @@ -0,0 +1,59 @@ +{ + "mockBidRequest": { + "id": "test-request-id-video", + "imp": [{ + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "protocols": [1], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "aid": 1, + "pid": 1 + } + } + }], + "site": { + "publisher": { + "id": "1" + } + } + }, + + "httpCalls": [{ + "expectedRequest": { + "uri": "https://sg.ads.lemmatechnologies.com/lemma/servad?pid=1&aid=1", + "body": { + "id": "test-request-id-video", + "imp": [{ + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "protocols": [1], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "aid": 1, + "pid": 1 + } + } + }], + "site": { + "publisher": { + "id": "1" + } + } + } + }, + "mockResponse": { + "status": 204 + } + }], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [] +} \ No newline at end of file diff --git a/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-other-error.json b/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-other-error.json new file mode 100644 index 00000000000..047dc4efd83 --- /dev/null +++ b/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-other-error.json @@ -0,0 +1,62 @@ +{ + "mockBidRequest": { + "id": "test-request-id-video", + "imp": [{ + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "protocols": [1], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "aid": 1, + "pid": 1 + } + } + }], + "site": { + "publisher": { + "id": "1" + } + } + }, + + "httpCalls": [{ + "expectedRequest": { + "uri": "https://sg.ads.lemmatechnologies.com/lemma/servad?pid=1&aid=1", + "body": { + "id": "test-request-id-video", + "imp": [{ + "id": "test-imp-id-video", + "video": { + "mimes": ["video/mp4"], + "protocols": [1], + "w": 1920, + "h": 1080 + }, + "ext": { + "bidder": { + "aid": 1, + "pid": 1 + } + } + }], + "site": { + "publisher": { + "id": "1" + } + } + } + }, + "mockResponse": { + "status": 503 + } + }], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [{ + "value": "Unexpected status code: 503. Run with request.debug = 1 for more info", + "comparison": "literal" + }] +} \ No newline at end of file diff --git a/adapters/lemmadigital/params_test.go b/adapters/lemmadigital/params_test.go new file mode 100644 index 00000000000..57bc7d83e79 --- /dev/null +++ b/adapters/lemmadigital/params_test.go @@ -0,0 +1,59 @@ +package lemmadigital + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/openrtb_ext" +) + +// Tests for static/bidder-params/lemmadigital.json + +// Tests whether the schema supports the intended params. +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schema. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderLemmadigital, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected params: %s \n Error: %s", validParam, err) + } + } +} + +// Tests whether the schema rejects unsupported imp.ext fields. +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schema. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderLemmadigital, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed invalid/unexpected params: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{"pid":1, "aid": 1}`, + `{"pid":2147483647, "aid": 2147483647}`, +} + +var invalidParams = []string{ + ``, + `null`, + `false`, + `0`, + `0.0`, + `[]`, + `{}`, + `{"pid":1}`, + `{"aid":1}`, + `{"pid":"1","aid":1}`, + `{"pid":1.0,"aid":"1"}`, + `{"pid":"1","aid":"1"}`, + `{"pid":false,"aid":true}`, +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index d8ab16c1d61..25630fed414 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -103,6 +103,7 @@ import ( "github.com/prebid/prebid-server/adapters/kidoz" "github.com/prebid/prebid-server/adapters/kiviads" "github.com/prebid/prebid-server/adapters/krushmedia" + "github.com/prebid/prebid-server/adapters/lemmadigital" "github.com/prebid/prebid-server/adapters/liftoff" "github.com/prebid/prebid-server/adapters/limelightDigital" lmkiviads "github.com/prebid/prebid-server/adapters/lm_kiviads" @@ -304,6 +305,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderKiviads: kiviads.Builder, openrtb_ext.BidderLmKiviads: lmkiviads.Builder, openrtb_ext.BidderKrushmedia: krushmedia.Builder, + openrtb_ext.BidderLemmadigital: lemmadigital.Builder, openrtb_ext.BidderLiftoff: liftoff.Builder, openrtb_ext.BidderLimelightDigital: limelightDigital.Builder, openrtb_ext.BidderLockerDome: lockerdome.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 635f17cd58f..744c7fad3fe 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -131,6 +131,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderKiviads, BidderLmKiviads, BidderKrushmedia, + BidderLemmadigital, BidderLiftoff, BidderLimelightDigital, BidderLockerDome, @@ -422,6 +423,7 @@ const ( BidderKiviads BidderName = "kiviads" BidderLmKiviads BidderName = "lm_kiviads" BidderKrushmedia BidderName = "krushmedia" + BidderLemmadigital BidderName = "lemmadigital" BidderLiftoff BidderName = "liftoff" BidderLimelightDigital BidderName = "limelightDigital" BidderLockerDome BidderName = "lockerdome" diff --git a/openrtb_ext/imp_lemmadigital.go b/openrtb_ext/imp_lemmadigital.go new file mode 100644 index 00000000000..c691dd173d9 --- /dev/null +++ b/openrtb_ext/imp_lemmadigital.go @@ -0,0 +1,6 @@ +package openrtb_ext + +type ImpExtLemmaDigital struct { + PublisherId int `json:"pid"` + AdId int `json:"aid"` +} diff --git a/static/bidder-info/lemmadigital.yaml b/static/bidder-info/lemmadigital.yaml new file mode 100644 index 00000000000..535c91ffa77 --- /dev/null +++ b/static/bidder-info/lemmadigital.yaml @@ -0,0 +1,14 @@ +endpoint: "https://sg.ads.lemmatechnologies.com/lemma/servad?pid={{.PublisherID}}&aid={{.AdUnit}}" +maintainer: + email: support@lemmatechnologies.com +endpointCompression: gzip +modifyingVastXmlAllowed: true +capabilities: + app: + mediaTypes: + - banner + - video + site: + mediaTypes: + - banner + - video \ No newline at end of file diff --git a/static/bidder-params/lemmadigital.json b/static/bidder-params/lemmadigital.json new file mode 100644 index 00000000000..be4a89edd7a --- /dev/null +++ b/static/bidder-params/lemmadigital.json @@ -0,0 +1,19 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Lemma Adapter Params", + "description": "A schema which validates params accepted by the Lemma adapter", + "type": "object", + + "properties": { + "pid": { + "type": "integer", + "description": "Publisher ID" + }, + "aid": { + "type": "integer", + "description": "Ad ID" + } + }, + + "required": ["pid", "aid"] +} \ No newline at end of file From 2dbf6719898e4a2f041db672d4b25f09310b20e0 Mon Sep 17 00:00:00 2001 From: Irakli Gotsiridze Date: Mon, 16 Oct 2023 15:06:51 +0300 Subject: [PATCH 169/268] minduration non-required (#3185) --- adapters/sovrn/sovrn.go | 1 - .../sovrn/sovrntest/video/simple-video.json | 2 - .../videosupplemental/no-minduration.json | 49 ------------------- 3 files changed, 52 deletions(-) delete mode 100644 adapters/sovrn/sovrntest/videosupplemental/no-minduration.json diff --git a/adapters/sovrn/sovrn.go b/adapters/sovrn/sovrn.go index 405e5ebf763..15b07800b78 100644 --- a/adapters/sovrn/sovrn.go +++ b/adapters/sovrn/sovrn.go @@ -97,7 +97,6 @@ func (s *SovrnAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapt video := imp.Video if video != nil { if video.MIMEs == nil || - video.MinDuration == 0 || video.MaxDuration == 0 || video.Protocols == nil { errs = append(errs, &errortypes.BadInput{ diff --git a/adapters/sovrn/sovrntest/video/simple-video.json b/adapters/sovrn/sovrntest/video/simple-video.json index 9cfeef5e11d..fae6778a015 100644 --- a/adapters/sovrn/sovrntest/video/simple-video.json +++ b/adapters/sovrn/sovrntest/video/simple-video.json @@ -10,7 +10,6 @@ "video/3gpp", "video/x-ms-wmv" ], - "minduration": 5, "maxduration": 30, "protocols": [ 4, @@ -79,7 +78,6 @@ "video/3gpp", "video/x-ms-wmv" ], - "minduration": 5, "maxduration": 30, "protocols": [ 4, diff --git a/adapters/sovrn/sovrntest/videosupplemental/no-minduration.json b/adapters/sovrn/sovrntest/videosupplemental/no-minduration.json deleted file mode 100644 index 88703ddadc4..00000000000 --- a/adapters/sovrn/sovrntest/videosupplemental/no-minduration.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "video": { - "mimes": [ - "video/mp4", - "video/3gpp", - "video/x-ms-wmv" - ], - "maxduration": 30, - "protocols": [ - 4, - 5, - 6, - 8 - ] - }, - "ext": { - "bidder": { - "tagid": "123456" - } - } - } - ], - "device": { - "ua": "test-user-agent", - "ip": "123.123.123.123", - "language": "en", - "dnt": 0 - }, - "site": { - "domain": "www.publisher.com", - "page": "http://www.publisher.com/awesome/site" - }, - "user": { - "buyeruid": "test_reader_id" - } - }, - "expectedMakeRequestsErrors": [ - { - "value": "Missing required video parameter", - "comparison": "literal" - } - ], - "httpCalls": [] -} From c45ab815c19a7e915331c13f9ffa08bd89371ac5 Mon Sep 17 00:00:00 2001 From: Arne Schulz Date: Mon, 16 Oct 2023 14:08:57 +0200 Subject: [PATCH 170/268] add supportCORS to orbidder user sync config (#3193) --- static/bidder-info/orbidder.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/static/bidder-info/orbidder.yaml b/static/bidder-info/orbidder.yaml index 74348c75d7f..c42fb91de44 100644 --- a/static/bidder-info/orbidder.yaml +++ b/static/bidder-info/orbidder.yaml @@ -11,6 +11,7 @@ capabilities: - banner - native userSync: + supportCors: true redirect: url: "https://orbidder.otto.de/pbs-usersync?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&redirect={{.RedirectURL}}" userMacro: "[ODN_ID]" \ No newline at end of file From 9d216fb8a04bff546bf403899135d4047050262d Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Mon, 16 Oct 2023 18:41:46 +0530 Subject: [PATCH 171/268] Adapter Name Case Insensitive: /vtrack endpoint (#3196) authored by @onkarvhanumante --- endpoints/events/vtrack.go | 41 ++++--- endpoints/events/vtrack_test.go | 209 ++++++++++++++++++++++++-------- 2 files changed, 182 insertions(+), 68 deletions(-) diff --git a/endpoints/events/vtrack.go b/endpoints/events/vtrack.go index d320fdc6989..e0bf3fd4be8 100644 --- a/endpoints/events/vtrack.go +++ b/endpoints/events/vtrack.go @@ -16,6 +16,7 @@ import ( "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/metrics" + "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/prebid_cache_client" "github.com/prebid/prebid-server/stored_requests" ) @@ -27,12 +28,15 @@ const ( ImpressionOpenTag = "" ) +type normalizeBidderName func(name string) (openrtb_ext.BidderName, bool) + type vtrackEndpoint struct { - Cfg *config.Configuration - Accounts stored_requests.AccountFetcher - BidderInfos config.BidderInfos - Cache prebid_cache_client.Client - MetricsEngine metrics.MetricsEngine + Cfg *config.Configuration + Accounts stored_requests.AccountFetcher + BidderInfos config.BidderInfos + Cache prebid_cache_client.Client + MetricsEngine metrics.MetricsEngine + normalizeBidderName normalizeBidderName } type BidCacheRequest struct { @@ -49,11 +53,12 @@ type CacheObject struct { func NewVTrackEndpoint(cfg *config.Configuration, accounts stored_requests.AccountFetcher, cache prebid_cache_client.Client, bidderInfos config.BidderInfos, me metrics.MetricsEngine) httprouter.Handle { vte := &vtrackEndpoint{ - Cfg: cfg, - Accounts: accounts, - BidderInfos: bidderInfos, - Cache: cache, - MetricsEngine: me, + Cfg: cfg, + Accounts: accounts, + BidderInfos: bidderInfos, + Cache: cache, + MetricsEngine: me, + normalizeBidderName: openrtb_ext.NormalizeBidderName, } return vte.Handle @@ -203,7 +208,7 @@ func ParseVTrackRequest(httpRequest *http.Request, maxRequestSize int64) (req *B // handleVTrackRequest handles a VTrack request func (v *vtrackEndpoint) handleVTrackRequest(ctx context.Context, req *BidCacheRequest, account *config.Account, integration string) (*BidCacheResponse, []error) { - biddersAllowingVastUpdate := getBiddersAllowingVastUpdate(req, &v.BidderInfos, v.Cfg.VTrack.AllowUnknownBidder) + biddersAllowingVastUpdate := getBiddersAllowingVastUpdate(req, &v.BidderInfos, v.Cfg.VTrack.AllowUnknownBidder, v.normalizeBidderName) // cache data r, errs := v.cachePutObjects(ctx, req, biddersAllowingVastUpdate, account.ID, integration) @@ -251,11 +256,11 @@ func (v *vtrackEndpoint) cachePutObjects(ctx context.Context, req *BidCacheReque } // getBiddersAllowingVastUpdate returns a list of bidders that allow VAST XML modification -func getBiddersAllowingVastUpdate(req *BidCacheRequest, bidderInfos *config.BidderInfos, allowUnknownBidder bool) map[string]struct{} { +func getBiddersAllowingVastUpdate(req *BidCacheRequest, bidderInfos *config.BidderInfos, allowUnknownBidder bool, normalizeBidderName normalizeBidderName) map[string]struct{} { bl := map[string]struct{}{} for _, bcr := range req.Puts { - if _, ok := bl[bcr.Bidder]; isAllowVastForBidder(bcr.Bidder, bidderInfos, allowUnknownBidder) && !ok { + if _, ok := bl[bcr.Bidder]; isAllowVastForBidder(bcr.Bidder, bidderInfos, allowUnknownBidder, normalizeBidderName) && !ok { bl[bcr.Bidder] = struct{}{} } } @@ -264,12 +269,14 @@ func getBiddersAllowingVastUpdate(req *BidCacheRequest, bidderInfos *config.Bidd } // isAllowVastForBidder checks if a bidder is active and allowed to modify vast xml data -func isAllowVastForBidder(bidder string, bidderInfos *config.BidderInfos, allowUnknownBidder bool) bool { +func isAllowVastForBidder(bidder string, bidderInfos *config.BidderInfos, allowUnknownBidder bool, normalizeBidderName normalizeBidderName) bool { //if bidder is active and isModifyingVastXmlAllowed is true // check if bidder is configured - if b, ok := (*bidderInfos)[bidder]; bidderInfos != nil && ok { - // check if bidder is enabled - return b.IsEnabled() && b.ModifyingVastXmlAllowed + if normalizedBidder, ok := normalizeBidderName(bidder); ok { + if b, ok := (*bidderInfos)[normalizedBidder.String()]; bidderInfos != nil && ok { + // check if bidder is enabled + return b.IsEnabled() && b.ModifyingVastXmlAllowed + } } return allowUnknownBidder diff --git a/endpoints/events/vtrack_test.go b/endpoints/events/vtrack_test.go index 2c40c9b41de..1e36a9e627f 100644 --- a/endpoints/events/vtrack_test.go +++ b/endpoints/events/vtrack_test.go @@ -13,6 +13,7 @@ import ( "testing" "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/prebid_cache_client" "github.com/prebid/prebid-server/stored_requests" "github.com/stretchr/testify/assert" @@ -28,15 +29,17 @@ const ( // Mock pbs cache client type vtrackMockCacheClient struct { - Fail bool - Error error - Uuids []string + Fail bool + Error error + Uuids []string + Values []prebid_cache_client.Cacheable } func (m *vtrackMockCacheClient) PutJson(ctx context.Context, values []prebid_cache_client.Cacheable) ([]string, []error) { if m.Fail { return []string{}, []error{m.Error} } + m.Values = values return m.Uuids, []error{} } func (m *vtrackMockCacheClient) GetExtCacheData() (scheme string, host string, path string) { @@ -64,10 +67,11 @@ func TestShouldRespondWithBadRequestWhenAccountParameterIsMissing(t *testing.T) recorder := httptest.NewRecorder() e := vtrackEndpoint{ - Cfg: cfg, - BidderInfos: nil, - Cache: mockCacheClient, - Accounts: mockAccountsFetcher, + Cfg: cfg, + BidderInfos: nil, + Cache: mockCacheClient, + Accounts: mockAccountsFetcher, + normalizeBidderName: openrtb_ext.NormalizeBidderName, } // execute @@ -105,10 +109,11 @@ func TestShouldRespondWithBadRequestWhenRequestBodyIsEmpty(t *testing.T) { recorder := httptest.NewRecorder() e := vtrackEndpoint{ - Cfg: cfg, - BidderInfos: nil, - Cache: mockCacheClient, - Accounts: mockAccountsFetcher, + Cfg: cfg, + BidderInfos: nil, + Cache: mockCacheClient, + Accounts: mockAccountsFetcher, + normalizeBidderName: openrtb_ext.NormalizeBidderName, } // execute @@ -146,10 +151,11 @@ func TestShouldRespondWithBadRequestWhenRequestBodyIsInvalid(t *testing.T) { recorder := httptest.NewRecorder() e := vtrackEndpoint{ - Cfg: cfg, - BidderInfos: nil, - Cache: mockCacheClient, - Accounts: mockAccountsFetcher, + Cfg: cfg, + BidderInfos: nil, + Cache: mockCacheClient, + Accounts: mockAccountsFetcher, + normalizeBidderName: openrtb_ext.NormalizeBidderName, } // execute @@ -190,10 +196,11 @@ func TestShouldRespondWithBadRequestWhenBidIdIsMissing(t *testing.T) { recorder := httptest.NewRecorder() e := vtrackEndpoint{ - Cfg: cfg, - BidderInfos: nil, - Cache: mockCacheClient, - Accounts: mockAccountsFetcher, + Cfg: cfg, + BidderInfos: nil, + Cache: mockCacheClient, + Accounts: mockAccountsFetcher, + normalizeBidderName: openrtb_ext.NormalizeBidderName, } // execute @@ -242,10 +249,11 @@ func TestShouldRespondWithBadRequestWhenBidderIsMissing(t *testing.T) { recorder := httptest.NewRecorder() e := vtrackEndpoint{ - Cfg: cfg, - BidderInfos: nil, - Cache: mockCacheClient, - Accounts: mockAccountsFetcher, + Cfg: cfg, + BidderInfos: nil, + Cache: mockCacheClient, + Accounts: mockAccountsFetcher, + normalizeBidderName: openrtb_ext.NormalizeBidderName, } // execute @@ -291,10 +299,11 @@ func TestShouldRespondWithInternalServerErrorWhenPbsCacheClientFails(t *testing. recorder := httptest.NewRecorder() e := vtrackEndpoint{ - Cfg: cfg, - BidderInfos: nil, - Cache: mockCacheClient, - Accounts: mockAccountsFetcher, + Cfg: cfg, + BidderInfos: nil, + Cache: mockCacheClient, + Accounts: mockAccountsFetcher, + normalizeBidderName: openrtb_ext.NormalizeBidderName, } // execute @@ -340,10 +349,11 @@ func TestShouldTolerateAccountNotFound(t *testing.T) { recorder := httptest.NewRecorder() e := vtrackEndpoint{ - Cfg: cfg, - BidderInfos: nil, - Cache: mockCacheClient, - Accounts: mockAccountsFetcher, + Cfg: cfg, + BidderInfos: nil, + Cache: mockCacheClient, + Accounts: mockAccountsFetcher, + normalizeBidderName: openrtb_ext.NormalizeBidderName, } // execute @@ -397,10 +407,11 @@ func TestShouldSendToCacheExpectedPutsAndUpdatableBiddersWhenBidderVastNotAllowe recorder := httptest.NewRecorder() e := vtrackEndpoint{ - Cfg: cfg, - BidderInfos: bidderInfos, - Cache: mockCacheClient, - Accounts: mockAccountsFetcher, + Cfg: cfg, + BidderInfos: bidderInfos, + Cache: mockCacheClient, + Accounts: mockAccountsFetcher, + normalizeBidderName: openrtb_ext.NormalizeBidderName, } // execute @@ -459,11 +470,15 @@ func TestShouldSendToCacheExpectedPutsAndUpdatableBiddersWhenBidderVastAllowed(t recorder := httptest.NewRecorder() + var mockNormalizeBidderName normalizeBidderName = func(name string) (openrtb_ext.BidderName, bool) { + return openrtb_ext.BidderName(name), true + } e := vtrackEndpoint{ - Cfg: cfg, - BidderInfos: bidderInfos, - Cache: mockCacheClient, - Accounts: mockAccountsFetcher, + Cfg: cfg, + BidderInfos: bidderInfos, + Cache: mockCacheClient, + Accounts: mockAccountsFetcher, + normalizeBidderName: mockNormalizeBidderName, } // execute @@ -478,6 +493,95 @@ func TestShouldSendToCacheExpectedPutsAndUpdatableBiddersWhenBidderVastAllowed(t assert.Equal(t, 200, recorder.Result().StatusCode, "Expected 200 when account is not found and request is valid") assert.Equal(t, "{\"responses\":[{\"uuid\":\"uuid1\"},{\"uuid\":\"uuid2\"}]}", string(d), "Expected 200 when account is found and request is valid") assert.Equal(t, "application/json", recorder.Header().Get("Content-Type")) + assert.Len(t, mockCacheClient.Values, 2) + assert.Contains(t, string(mockCacheClient.Values[0].Data), "bidder=bidder") + assert.Contains(t, string(mockCacheClient.Values[1].Data), "bidder=updatable_bidder") +} + +func TestShouldSendToCacheExpectedPutsAndUpdatableCaseSensitiveBiddersWhenBidderVastAllowed(t *testing.T) { + // mock pbs cache client + mockCacheClient := &vtrackMockCacheClient{ + Fail: false, + Uuids: []string{"uuid1", "uuid2"}, + } + + // mock AccountsFetcher + mockAccountsFetcher := &mockAccountsFetcher{ + Fail: false, + } + + // config + cfg := &config.Configuration{ + MaxRequestSize: maxSize, VTrack: config.VTrack{ + TimeoutMS: int64(2000), AllowUnknownBidder: false, + }, + AccountDefaults: config.Account{}, + } + cfg.MarshalAccountDefaults() + + // bidder info + bidderInfos := make(config.BidderInfos) + bidderInfos["appnexus"] = config.BidderInfo{ + Disabled: false, + ModifyingVastXmlAllowed: true, + } + + d, err := getVTrackRequestData(true, true) + assert.NoError(t, err) + + cacheReq := &BidCacheRequest{ + Puts: []prebid_cache_client.Cacheable{ + { + Type: prebid_cache_client.TypeXML, + BidID: "bidId1", + Bidder: "APPNEXUS", // case sensitive name + Data: d, + TTLSeconds: 3600, + Timestamp: 1000, + }, + { + Type: prebid_cache_client.TypeXML, + BidID: "bidId2", + Bidder: "ApPnExUs", // case sensitive name + Data: d, + TTLSeconds: 3600, + Timestamp: 1000, + }, + }, + } + buf := &bytes.Buffer{} + enc := json.NewEncoder(buf) + enc.SetEscapeHTML(false) + err = enc.Encode(cacheReq) + assert.NoError(t, err) + data := buf.String() + + req := httptest.NewRequest("POST", "/vtrack?a=events_enabled", strings.NewReader(data)) + + recorder := httptest.NewRecorder() + e := vtrackEndpoint{ + Cfg: cfg, + BidderInfos: bidderInfos, + Cache: mockCacheClient, + Accounts: mockAccountsFetcher, + normalizeBidderName: openrtb_ext.NormalizeBidderName, + } + + // execute + e.Handle(recorder, req, nil) + + d, err = io.ReadAll(recorder.Result().Body) + if err != nil { + t.Fatal(err) + } + + // validate + assert.Equal(t, 200, recorder.Result().StatusCode, "Expected 200 when account is not found and request is valid") + assert.Equal(t, "{\"responses\":[{\"uuid\":\"uuid1\"},{\"uuid\":\"uuid2\"}]}", string(d), "Expected 200 when account is found and request is valid") + assert.Equal(t, "application/json", recorder.Header().Get("Content-Type")) + assert.Len(t, mockCacheClient.Values, 2) + assert.Contains(t, string(mockCacheClient.Values[0].Data), "bidder=APPNEXUS") + assert.Contains(t, string(mockCacheClient.Values[1].Data), "bidder=ApPnExUs") } func TestShouldSendToCacheExpectedPutsAndUpdatableUnknownBiddersWhenUnknownBidderIsAllowed(t *testing.T) { @@ -515,10 +619,11 @@ func TestShouldSendToCacheExpectedPutsAndUpdatableUnknownBiddersWhenUnknownBidde recorder := httptest.NewRecorder() e := vtrackEndpoint{ - Cfg: cfg, - BidderInfos: bidderInfos, - Cache: mockCacheClient, - Accounts: mockAccountsFetcher, + Cfg: cfg, + BidderInfos: bidderInfos, + Cache: mockCacheClient, + Accounts: mockAccountsFetcher, + normalizeBidderName: openrtb_ext.NormalizeBidderName, } // execute @@ -571,10 +676,11 @@ func TestShouldReturnBadRequestWhenRequestExceedsMaxRequestSize(t *testing.T) { recorder := httptest.NewRecorder() e := vtrackEndpoint{ - Cfg: cfg, - BidderInfos: bidderInfos, - Cache: mockCacheClient, - Accounts: mockAccountsFetcher, + Cfg: cfg, + BidderInfos: bidderInfos, + Cache: mockCacheClient, + Accounts: mockAccountsFetcher, + normalizeBidderName: openrtb_ext.NormalizeBidderName, } // execute @@ -615,10 +721,11 @@ func TestShouldRespondWithInternalErrorPbsCacheIsNotConfigured(t *testing.T) { recorder := httptest.NewRecorder() e := vtrackEndpoint{ - Cfg: cfg, - BidderInfos: nil, - Cache: nil, - Accounts: mockAccountsFetcher, + Cfg: cfg, + BidderInfos: nil, + Cache: nil, + Accounts: mockAccountsFetcher, + normalizeBidderName: openrtb_ext.NormalizeBidderName, } // execute From 5b44d36066dccaa378ac6dba031964ea48a576cf Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Mon, 16 Oct 2023 18:42:52 +0530 Subject: [PATCH 172/268] Prometheus metrics: bidder name should be in lowercase (#3198) co-authored by @onkarvhanumante --- metrics/prometheus/preload.go | 2 +- metrics/prometheus/prometheus.go | 33 +++++++----- metrics/prometheus/prometheus_test.go | 73 +++++++++++++++------------ metrics/prometheus/type_conversion.go | 9 ++++ 4 files changed, 71 insertions(+), 46 deletions(-) diff --git a/metrics/prometheus/preload.go b/metrics/prometheus/preload.go index 59f70cfb9fb..db40feabbd8 100644 --- a/metrics/prometheus/preload.go +++ b/metrics/prometheus/preload.go @@ -9,7 +9,7 @@ import ( func preloadLabelValues(m *Metrics, syncerKeys []string, moduleStageNames map[string][]string) { var ( adapterErrorValues = enumAsString(metrics.AdapterErrors()) - adapterValues = enumAsString(openrtb_ext.CoreBidderNames()) + adapterValues = enumAsLowerCaseString(openrtb_ext.CoreBidderNames()) bidTypeValues = []string{markupDeliveryAdm, markupDeliveryNurl} boolValues = boolValuesAsString() cacheResultValues = enumAsString(metrics.CacheResults()) diff --git a/metrics/prometheus/prometheus.go b/metrics/prometheus/prometheus.go index 30fb6c5f774..bd63997f0d2 100644 --- a/metrics/prometheus/prometheus.go +++ b/metrics/prometheus/prometheus.go @@ -3,6 +3,7 @@ package prometheusmetrics import ( "fmt" "strconv" + "strings" "time" "github.com/prebid/prebid-server/config" @@ -762,15 +763,16 @@ func (m *Metrics) RecordStoredDataError(labels metrics.StoredDataLabels) { } func (m *Metrics) RecordAdapterRequest(labels metrics.AdapterLabels) { + lowerCasedAdapter := strings.ToLower(string(labels.Adapter)) m.adapterRequests.With(prometheus.Labels{ - adapterLabel: string(labels.Adapter), + adapterLabel: lowerCasedAdapter, cookieLabel: string(labels.CookieFlag), hasBidsLabel: strconv.FormatBool(labels.AdapterBids == metrics.AdapterBidPresent), }).Inc() for err := range labels.AdapterErrors { m.adapterErrors.With(prometheus.Labels{ - adapterLabel: string(labels.Adapter), + adapterLabel: lowerCasedAdapter, adapterErrorLabel: string(err), }).Inc() } @@ -779,22 +781,23 @@ func (m *Metrics) RecordAdapterRequest(labels metrics.AdapterLabels) { // Keeps track of created and reused connections to adapter bidders and the time from the // connection request, to the connection creation, or reuse from the pool across all engines func (m *Metrics) RecordAdapterConnections(adapterName openrtb_ext.BidderName, connWasReused bool, connWaitTime time.Duration) { + lowerCasedAdapterName := strings.ToLower(string(adapterName)) if m.metricsDisabled.AdapterConnectionMetrics { return } if connWasReused { m.adapterReusedConnections.With(prometheus.Labels{ - adapterLabel: string(adapterName), + adapterLabel: lowerCasedAdapterName, }).Inc() } else { m.adapterCreatedConnections.With(prometheus.Labels{ - adapterLabel: string(adapterName), + adapterLabel: lowerCasedAdapterName, }).Inc() } m.adapterConnectionWaitTime.With(prometheus.Labels{ - adapterLabel: string(adapterName), + adapterLabel: lowerCasedAdapterName, }).Observe(connWaitTime.Seconds()) } @@ -812,7 +815,7 @@ func (m *Metrics) RecordBidderServerResponseTime(bidderServerResponseTime time.D func (m *Metrics) RecordAdapterPanic(labels metrics.AdapterLabels) { m.adapterPanics.With(prometheus.Labels{ - adapterLabel: string(labels.Adapter), + adapterLabel: strings.ToLower(string(labels.Adapter)), }).Inc() } @@ -823,14 +826,14 @@ func (m *Metrics) RecordAdapterBidReceived(labels metrics.AdapterLabels, bidType } m.adapterBids.With(prometheus.Labels{ - adapterLabel: string(labels.Adapter), + adapterLabel: strings.ToLower(string(labels.Adapter)), markupDeliveryLabel: markupDelivery, }).Inc() } func (m *Metrics) RecordAdapterPrice(labels metrics.AdapterLabels, cpm float64) { m.adapterPrices.With(prometheus.Labels{ - adapterLabel: string(labels.Adapter), + adapterLabel: strings.ToLower(string(labels.Adapter)), }).Observe(cpm) } @@ -843,7 +846,7 @@ func (m *Metrics) RecordOverheadTime(overhead metrics.OverheadType, duration tim func (m *Metrics) RecordAdapterTime(labels metrics.AdapterLabels, length time.Duration) { if len(labels.AdapterErrors) == 0 { m.adapterRequestsTimer.With(prometheus.Labels{ - adapterLabel: string(labels.Adapter), + adapterLabel: strings.ToLower(string(labels.Adapter)), }).Observe(length.Seconds()) } } @@ -955,7 +958,7 @@ func (m *Metrics) RecordAdapterGDPRRequestBlocked(adapterName openrtb_ext.Bidder } m.adapterGDPRBlockedRequests.With(prometheus.Labels{ - adapterLabel: string(adapterName), + adapterLabel: strings.ToLower(string(adapterName)), }).Inc() } @@ -975,8 +978,9 @@ func (m *Metrics) RecordAdsCertSignTime(adsCertSignTime time.Duration) { } func (m *Metrics) RecordBidValidationCreativeSizeError(adapter openrtb_ext.BidderName, account string) { + lowerCasedAdapter := strings.ToLower(string(adapter)) m.adapterBidResponseValidationSizeError.With(prometheus.Labels{ - adapterLabel: string(adapter), successLabel: successLabel, + adapterLabel: lowerCasedAdapter, successLabel: successLabel, }).Inc() if !m.metricsDisabled.AccountAdapterDetails && account != metrics.PublisherUnknown { @@ -987,8 +991,9 @@ func (m *Metrics) RecordBidValidationCreativeSizeError(adapter openrtb_ext.Bidde } func (m *Metrics) RecordBidValidationCreativeSizeWarn(adapter openrtb_ext.BidderName, account string) { + lowerCasedAdapter := strings.ToLower(string(adapter)) m.adapterBidResponseValidationSizeWarn.With(prometheus.Labels{ - adapterLabel: string(adapter), successLabel: successLabel, + adapterLabel: lowerCasedAdapter, successLabel: successLabel, }).Inc() if !m.metricsDisabled.AccountAdapterDetails && account != metrics.PublisherUnknown { @@ -1000,7 +1005,7 @@ func (m *Metrics) RecordBidValidationCreativeSizeWarn(adapter openrtb_ext.Bidder func (m *Metrics) RecordBidValidationSecureMarkupError(adapter openrtb_ext.BidderName, account string) { m.adapterBidResponseSecureMarkupError.With(prometheus.Labels{ - adapterLabel: string(adapter), successLabel: successLabel, + adapterLabel: strings.ToLower(string(adapter)), successLabel: successLabel, }).Inc() if !m.metricsDisabled.AccountAdapterDetails && account != metrics.PublisherUnknown { @@ -1012,7 +1017,7 @@ func (m *Metrics) RecordBidValidationSecureMarkupError(adapter openrtb_ext.Bidde func (m *Metrics) RecordBidValidationSecureMarkupWarn(adapter openrtb_ext.BidderName, account string) { m.adapterBidResponseSecureMarkupWarn.With(prometheus.Labels{ - adapterLabel: string(adapter), successLabel: successLabel, + adapterLabel: strings.ToLower(string(adapter)), successLabel: successLabel, }).Inc() if !m.metricsDisabled.AccountAdapterDetails && account != metrics.PublisherUnknown { diff --git a/metrics/prometheus/prometheus_test.go b/metrics/prometheus/prometheus_test.go index e57ae5e198a..bea0087c6ea 100644 --- a/metrics/prometheus/prometheus_test.go +++ b/metrics/prometheus/prometheus_test.go @@ -226,18 +226,19 @@ func TestBidValidationCreativeSizeMetric(t *testing.T) { expectedAccountCount: 0, }, } - + adapterName := openrtb_ext.BidderName("AnyName") + lowerCasedAdapterName := "anyname" for _, test := range testCases { m := createMetricsForTesting() m.metricsDisabled.AccountAdapterDetails = test.givenAccountAdapterMetricsDisabled - m.RecordBidValidationCreativeSizeError(adapterLabel, "acct-id") - m.RecordBidValidationCreativeSizeWarn(adapterLabel, "acct-id") + m.RecordBidValidationCreativeSizeError(adapterName, "acct-id") + m.RecordBidValidationCreativeSizeWarn(adapterName, "acct-id") assertCounterVecValue(t, "", "account bid validation", m.accountBidResponseValidationSizeError, test.expectedAccountCount, prometheus.Labels{accountLabel: "acct-id", successLabel: successLabel}) - assertCounterVecValue(t, "", "adapter bid validation", m.adapterBidResponseValidationSizeError, test.expectedAdapterCount, prometheus.Labels{adapterLabel: adapterLabel, successLabel: successLabel}) + assertCounterVecValue(t, "", "adapter bid validation", m.adapterBidResponseValidationSizeError, test.expectedAdapterCount, prometheus.Labels{adapterLabel: lowerCasedAdapterName, successLabel: successLabel}) assertCounterVecValue(t, "", "account bid validation", m.accountBidResponseValidationSizeWarn, test.expectedAccountCount, prometheus.Labels{accountLabel: "acct-id", successLabel: successLabel}) - assertCounterVecValue(t, "", "adapter bid validation", m.adapterBidResponseValidationSizeWarn, test.expectedAdapterCount, prometheus.Labels{adapterLabel: adapterLabel, successLabel: successLabel}) + assertCounterVecValue(t, "", "adapter bid validation", m.adapterBidResponseValidationSizeWarn, test.expectedAdapterCount, prometheus.Labels{adapterLabel: lowerCasedAdapterName, successLabel: successLabel}) } } @@ -263,17 +264,19 @@ func TestBidValidationSecureMarkupMetric(t *testing.T) { }, } + adapterName := openrtb_ext.BidderName("AnyName") + lowerCasedAdapterName := "anyname" for _, test := range testCases { m := createMetricsForTesting() m.metricsDisabled.AccountAdapterDetails = test.givenAccountAdapterMetricsDisabled - m.RecordBidValidationSecureMarkupError(adapterLabel, "acct-id") - m.RecordBidValidationSecureMarkupWarn(adapterLabel, "acct-id") + m.RecordBidValidationSecureMarkupError(adapterName, "acct-id") + m.RecordBidValidationSecureMarkupWarn(adapterName, "acct-id") assertCounterVecValue(t, "", "Account Secure Markup Error", m.accountBidResponseSecureMarkupError, test.expectedAccountCount, prometheus.Labels{accountLabel: "acct-id", successLabel: successLabel}) - assertCounterVecValue(t, "", "Adapter Secure Markup Error", m.adapterBidResponseSecureMarkupError, test.expectedAdapterCount, prometheus.Labels{adapterLabel: adapterLabel, successLabel: successLabel}) + assertCounterVecValue(t, "", "Adapter Secure Markup Error", m.adapterBidResponseSecureMarkupError, test.expectedAdapterCount, prometheus.Labels{adapterLabel: lowerCasedAdapterName, successLabel: successLabel}) assertCounterVecValue(t, "", "Account Secure Markup Warn", m.accountBidResponseSecureMarkupWarn, test.expectedAccountCount, prometheus.Labels{accountLabel: "acct-id", successLabel: successLabel}) - assertCounterVecValue(t, "", "Adapter Secure Markup Warn", m.adapterBidResponseSecureMarkupWarn, test.expectedAdapterCount, prometheus.Labels{adapterLabel: adapterLabel, successLabel: successLabel}) + assertCounterVecValue(t, "", "Adapter Secure Markup Warn", m.adapterBidResponseSecureMarkupWarn, test.expectedAdapterCount, prometheus.Labels{adapterLabel: lowerCasedAdapterName, successLabel: successLabel}) } } @@ -768,10 +771,11 @@ func TestRecordStoredDataError(t *testing.T) { } func TestAdapterBidReceivedMetric(t *testing.T) { - adapterName := "anyName" + adapterName := openrtb_ext.BidderName("anyName") + lowerCasedAdapterName := "anyname" performTest := func(m *Metrics, hasAdm bool) { labels := metrics.AdapterLabels{ - Adapter: openrtb_ext.BidderName(adapterName), + Adapter: adapterName, } bidType := openrtb_ext.BidTypeBanner m.RecordAdapterBidReceived(labels, bidType, hasAdm) @@ -809,13 +813,13 @@ func TestAdapterBidReceivedMetric(t *testing.T) { assertCounterVecValue(t, test.description, "adapterBids[adm]", m.adapterBids, test.expectedAdmCount, prometheus.Labels{ - adapterLabel: adapterName, + adapterLabel: lowerCasedAdapterName, markupDeliveryLabel: markupDeliveryAdm, }) assertCounterVecValue(t, test.description, "adapterBids[nurl]", m.adapterBids, test.expectedNurlCount, prometheus.Labels{ - adapterLabel: adapterName, + adapterLabel: lowerCasedAdapterName, markupDeliveryLabel: markupDeliveryNurl, }) } @@ -824,6 +828,7 @@ func TestAdapterBidReceivedMetric(t *testing.T) { func TestRecordAdapterPriceMetric(t *testing.T) { m := createMetricsForTesting() adapterName := "anyName" + lowerCasedAdapterName := "anyname" cpm := float64(42) m.RecordAdapterPrice(metrics.AdapterLabels{ @@ -832,12 +837,13 @@ func TestRecordAdapterPriceMetric(t *testing.T) { expectedCount := uint64(1) expectedSum := cpm - result := getHistogramFromHistogramVec(m.adapterPrices, adapterLabel, adapterName) + result := getHistogramFromHistogramVec(m.adapterPrices, adapterLabel, lowerCasedAdapterName) assertHistogram(t, "adapterPrices", result, expectedCount, expectedSum) } func TestAdapterRequestMetrics(t *testing.T) { adapterName := "anyName" + lowerCasedAdapterName := "anyname" performTest := func(m *Metrics, cookieFlag metrics.CookieFlag, adapterBids metrics.AdapterBid) { labels := metrics.AdapterLabels{ Adapter: openrtb_ext.BidderName(adapterName), @@ -937,7 +943,7 @@ func TestAdapterRequestMetrics(t *testing.T) { processMetrics(m.adapterRequests, func(m dto.Metric) { isMetricForAdapter := false for _, label := range m.GetLabel() { - if label.GetName() == adapterLabel && label.GetValue() == adapterName { + if label.GetName() == adapterLabel && label.GetValue() == lowerCasedAdapterName { isMetricForAdapter = true } } @@ -974,6 +980,7 @@ func TestAdapterRequestMetrics(t *testing.T) { func TestAdapterRequestErrorMetrics(t *testing.T) { adapterName := "anyName" + lowerCasedAdapterName := "anyname" performTest := func(m *Metrics, adapterErrors map[metrics.AdapterError]struct{}) { labels := metrics.AdapterLabels{ Adapter: openrtb_ext.BidderName(adapterName), @@ -1030,7 +1037,7 @@ func TestAdapterRequestErrorMetrics(t *testing.T) { processMetrics(m.adapterErrors, func(m dto.Metric) { isMetricForAdapter := false for _, label := range m.GetLabel() { - if label.GetName() == adapterLabel && label.GetValue() == adapterName { + if label.GetName() == adapterLabel && label.GetValue() == lowerCasedAdapterName { isMetricForAdapter = true } } @@ -1052,6 +1059,7 @@ func TestAdapterRequestErrorMetrics(t *testing.T) { func TestAdapterTimeMetric(t *testing.T) { adapterName := "anyName" + lowerCasedAdapterName := "anyname" performTest := func(m *Metrics, timeInMs float64, adapterErrors map[metrics.AdapterError]struct{}) { m.RecordAdapterTime(metrics.AdapterLabels{ Adapter: openrtb_ext.BidderName(adapterName), @@ -1090,24 +1098,24 @@ func TestAdapterTimeMetric(t *testing.T) { test.testCase(m) - result := getHistogramFromHistogramVec(m.adapterRequestsTimer, adapterLabel, adapterName) + result := getHistogramFromHistogramVec(m.adapterRequestsTimer, adapterLabel, lowerCasedAdapterName) assertHistogram(t, test.description, result, test.expectedCount, test.expectedSum) } } func TestAdapterPanicMetric(t *testing.T) { m := createMetricsForTesting() - adapterName := "anyName" - + adapterName := openrtb_ext.BidderName("anyName") + lowerCasedAdapterName := "anyname" m.RecordAdapterPanic(metrics.AdapterLabels{ - Adapter: openrtb_ext.BidderName(adapterName), + Adapter: adapterName, }) expectedCount := float64(1) assertCounterVecValue(t, "", "adapterPanics", m.adapterPanics, expectedCount, prometheus.Labels{ - adapterLabel: adapterName, + adapterLabel: lowerCasedAdapterName, }) } @@ -1509,6 +1517,8 @@ func TestRecordBidderServerResponseTime(t *testing.T) { } func TestRecordAdapterConnections(t *testing.T) { + adapterName := openrtb_ext.BidderName("Adapter") + lowerCasedAdapterName := "adapter" type testIn struct { adapterName openrtb_ext.BidderName @@ -1531,7 +1541,7 @@ func TestRecordAdapterConnections(t *testing.T) { { description: "[1] Successful, new connection created, was idle, has connection wait", in: testIn{ - adapterName: openrtb_ext.BidderAppnexus, + adapterName: adapterName, connWasReused: false, connWait: time.Second * 5, }, @@ -1545,7 +1555,7 @@ func TestRecordAdapterConnections(t *testing.T) { { description: "[2] Successful, new connection created, not idle, has connection wait", in: testIn{ - adapterName: openrtb_ext.BidderAppnexus, + adapterName: adapterName, connWasReused: false, connWait: time.Second * 4, }, @@ -1559,7 +1569,7 @@ func TestRecordAdapterConnections(t *testing.T) { { description: "[3] Successful, was reused, was idle, no connection wait", in: testIn{ - adapterName: openrtb_ext.BidderAppnexus, + adapterName: adapterName, connWasReused: true, }, out: testOut{ @@ -1572,7 +1582,7 @@ func TestRecordAdapterConnections(t *testing.T) { { description: "[4] Successful, was reused, not idle, has connection wait", in: testIn{ - adapterName: openrtb_ext.BidderAppnexus, + adapterName: adapterName, connWasReused: true, connWait: time.Second * 5, }, @@ -1602,7 +1612,7 @@ func TestRecordAdapterConnections(t *testing.T) { "adapter_connection_reused", m.adapterReusedConnections, float64(test.out.expectedConnReusedCount), - prometheus.Labels{adapterLabel: string(test.in.adapterName)}) + prometheus.Labels{adapterLabel: lowerCasedAdapterName}) // Assert number of new created connections assertCounterVecValue(t, @@ -1610,10 +1620,10 @@ func TestRecordAdapterConnections(t *testing.T) { "adapter_connection_created", m.adapterCreatedConnections, float64(test.out.expectedConnCreatedCount), - prometheus.Labels{adapterLabel: string(test.in.adapterName)}) + prometheus.Labels{adapterLabel: lowerCasedAdapterName}) // Assert connection wait time - histogram := getHistogramFromHistogramVec(m.adapterConnectionWaitTime, adapterLabel, string(test.in.adapterName)) + histogram := getHistogramFromHistogramVec(m.adapterConnectionWaitTime, adapterLabel, lowerCasedAdapterName) assert.Equal(t, test.out.expectedConnWaitCount, histogram.GetSampleCount(), assertDesciptions[2]) assert.Equal(t, test.out.expectedConnWaitTime, histogram.GetSampleSum(), assertDesciptions[3]) } @@ -1781,8 +1791,9 @@ func assertHistogram(t *testing.T, name string, histogram dto.Histogram, expecte func TestRecordAdapterGDPRRequestBlocked(t *testing.T) { m := createMetricsForTesting() - - m.RecordAdapterGDPRRequestBlocked(openrtb_ext.BidderAppnexus) + adapterName := openrtb_ext.BidderName("AnyName") + lowerCasedAdapterName := "anyname" + m.RecordAdapterGDPRRequestBlocked(adapterName) assertCounterVecValue(t, "Increment adapter GDPR request blocked counter", @@ -1790,7 +1801,7 @@ func TestRecordAdapterGDPRRequestBlocked(t *testing.T) { m.adapterGDPRBlockedRequests, 1, prometheus.Labels{ - adapterLabel: string(openrtb_ext.BidderAppnexus), + adapterLabel: lowerCasedAdapterName, }) } diff --git a/metrics/prometheus/type_conversion.go b/metrics/prometheus/type_conversion.go index 0ae5366b3f7..9bf2ec94a08 100644 --- a/metrics/prometheus/type_conversion.go +++ b/metrics/prometheus/type_conversion.go @@ -2,6 +2,7 @@ package prometheusmetrics import ( "strconv" + "strings" ) func enumAsString[T ~string](values []T) []string { @@ -12,6 +13,14 @@ func enumAsString[T ~string](values []T) []string { return valuesAsString } +func enumAsLowerCaseString[T ~string](values []T) []string { + valuesAsString := make([]string, len(values)) + for i, v := range values { + valuesAsString[i] = strings.ToLower(string(v)) + } + return valuesAsString +} + func boolValuesAsString() []string { return []string{ strconv.FormatBool(true), From 6c6aa9ac75bc99deef78fa5870307cf1e04dd22c Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Mon, 16 Oct 2023 18:43:30 +0530 Subject: [PATCH 173/268] InfluxDB metrics : bidder name should be in lowercase (#3209) co-authored by @onkarvhanumante --- metrics/config/metrics_test.go | 14 +- metrics/go_metrics.go | 87 +++++---- metrics/go_metrics_test.go | 253 ++++++++++++++++++++------ metrics/metrics.go | 1 + metrics/prometheus/prometheus_test.go | 2 +- 5 files changed, 259 insertions(+), 98 deletions(-) diff --git a/metrics/config/metrics_test.go b/metrics/config/metrics_test.go index f77dcf005d8..1eae1a25545 100644 --- a/metrics/config/metrics_test.go +++ b/metrics/config/metrics_test.go @@ -2,6 +2,7 @@ package config import ( "fmt" + "strings" "testing" "time" @@ -168,13 +169,14 @@ func TestMultiMetricsEngine(t *testing.T) { VerifyMetrics(t, "Request", goEngine.RequestStatuses[metrics.ReqTypeORTB2Web][metrics.RequestStatusOK].Count(), 5) VerifyMetrics(t, "ImpMeter", goEngine.ImpMeter.Count(), 8) VerifyMetrics(t, "NoCookieMeter", goEngine.NoCookieMeter.Count(), 0) - VerifyMetrics(t, "AdapterMetrics.Pubmatic.GotBidsMeter", goEngine.AdapterMetrics[openrtb_ext.BidderPubmatic].GotBidsMeter.Count(), 5) - VerifyMetrics(t, "AdapterMetrics.Pubmatic.NoBidMeter", goEngine.AdapterMetrics[openrtb_ext.BidderPubmatic].NoBidMeter.Count(), 0) + + VerifyMetrics(t, "AdapterMetrics.pubmatic.GotBidsMeter", goEngine.AdapterMetrics[strings.ToLower(string(openrtb_ext.BidderPubmatic))].GotBidsMeter.Count(), 5) + VerifyMetrics(t, "AdapterMetrics.pubmatic.NoBidMeter", goEngine.AdapterMetrics[strings.ToLower(string(openrtb_ext.BidderPubmatic))].NoBidMeter.Count(), 0) for _, err := range metrics.AdapterErrors() { - VerifyMetrics(t, "AdapterMetrics.Pubmatic.Request.ErrorMeter."+string(err), goEngine.AdapterMetrics[openrtb_ext.BidderPubmatic].ErrorMeters[err].Count(), 0) + VerifyMetrics(t, "AdapterMetrics.pubmatic.Request.ErrorMeter."+string(err), goEngine.AdapterMetrics[strings.ToLower(string(openrtb_ext.BidderPubmatic))].ErrorMeters[err].Count(), 0) } - VerifyMetrics(t, "AdapterMetrics.AppNexus.GotBidsMeter", goEngine.AdapterMetrics[openrtb_ext.BidderAppnexus].GotBidsMeter.Count(), 0) - VerifyMetrics(t, "AdapterMetrics.AppNexus.NoBidMeter", goEngine.AdapterMetrics[openrtb_ext.BidderAppnexus].NoBidMeter.Count(), 5) + VerifyMetrics(t, "AdapterMetrics.appnexus.GotBidsMeter", goEngine.AdapterMetrics[strings.ToLower(string(openrtb_ext.BidderAppnexus))].GotBidsMeter.Count(), 0) + VerifyMetrics(t, "AdapterMetrics.appnexus.NoBidMeter", goEngine.AdapterMetrics[strings.ToLower(string(openrtb_ext.BidderAppnexus))].NoBidMeter.Count(), 5) VerifyMetrics(t, "RecordRequestQueueTime.Video.Rejected", goEngine.RequestsQueueTimer[metrics.ReqTypeVideo][false].Count(), 1) VerifyMetrics(t, "RecordRequestQueueTime.Video.Accepted", goEngine.RequestsQueueTimer[metrics.ReqTypeVideo][true].Count(), 0) @@ -186,7 +188,7 @@ func TestMultiMetricsEngine(t *testing.T) { VerifyMetrics(t, "StoredImpCache.Hit", goEngine.StoredImpCacheMeter[metrics.CacheHit].Count(), 5) VerifyMetrics(t, "AccountCache.Hit", goEngine.AccountCacheMeter[metrics.CacheHit].Count(), 6) - VerifyMetrics(t, "AdapterMetrics.AppNexus.GDPRRequestBlocked", goEngine.AdapterMetrics[openrtb_ext.BidderAppnexus].GDPRRequestBlocked.Count(), 1) + VerifyMetrics(t, "AdapterMetrics.appNexus.GDPRRequestBlocked", goEngine.AdapterMetrics[strings.ToLower(string(openrtb_ext.BidderAppnexus))].GDPRRequestBlocked.Count(), 1) // verify that each module has its own metric recorded for module, stages := range modulesStages { diff --git a/metrics/go_metrics.go b/metrics/go_metrics.go index 0d60a7009d9..13cc022c9c8 100644 --- a/metrics/go_metrics.go +++ b/metrics/go_metrics.go @@ -2,6 +2,7 @@ package metrics import ( "fmt" + "strings" "sync" "time" @@ -62,12 +63,13 @@ type Metrics struct { PrivacyLMTRequest metrics.Meter PrivacyTCFRequestVersion map[TCFVersionValue]metrics.Meter - AdapterMetrics map[openrtb_ext.BidderName]*AdapterMetrics + AdapterMetrics map[string]*AdapterMetrics // Don't export accountMetrics because we need helper functions here to insure its properly populated dynamically accountMetrics map[string]*accountMetrics accountMetricsRWMutex sync.RWMutex - exchanges []openrtb_ext.BidderName + // adapter name exchanges + exchanges []string modules []string // Will hold boolean values to help us disable metric collection if needed MetricsDisabled config.DisabledMetrics @@ -117,7 +119,7 @@ type accountMetrics struct { bidsReceivedMeter metrics.Meter priceHistogram metrics.Histogram // store account by adapter metrics. Type is map[PBSBidder.BidderCode] - adapterMetrics map[openrtb_ext.BidderName]*AdapterMetrics + adapterMetrics map[string]*AdapterMetrics moduleMetrics map[string]*ModuleMetrics storedResponsesMeter metrics.Meter @@ -145,7 +147,7 @@ type ModuleMetrics struct { // rather than loading metrics that never get filled. // This will also eventually let us configure metrics, such as setting a limited set of metrics // for a production instance, and then expanding again when we need more debugging. -func NewBlankMetrics(registry metrics.Registry, exchanges []openrtb_ext.BidderName, disabledMetrics config.DisabledMetrics, moduleStageNames map[string][]string) *Metrics { +func NewBlankMetrics(registry metrics.Registry, exchanges []string, disabledMetrics config.DisabledMetrics, moduleStageNames map[string][]string) *Metrics { blankMeter := &metrics.NilMeter{} blankTimer := &metrics.NilTimer{} @@ -193,7 +195,7 @@ func NewBlankMetrics(registry metrics.Registry, exchanges []openrtb_ext.BidderNa PrivacyLMTRequest: blankMeter, PrivacyTCFRequestVersion: make(map[TCFVersionValue]metrics.Meter, len(TCFVersions())), - AdapterMetrics: make(map[openrtb_ext.BidderName]*AdapterMetrics, len(exchanges)), + AdapterMetrics: make(map[string]*AdapterMetrics, len(exchanges)), accountMetrics: make(map[string]*accountMetrics), MetricsDisabled: disabledMetrics, @@ -272,7 +274,11 @@ func getModuleNames(moduleStageNames map[string][]string) []string { // mode metrics. The code would allways try to record the metrics, but effectively noop if we are // using a blank meter/timer. func NewMetrics(registry metrics.Registry, exchanges []openrtb_ext.BidderName, disableAccountMetrics config.DisabledMetrics, syncerKeys []string, moduleStageNames map[string][]string) *Metrics { - newMetrics := NewBlankMetrics(registry, exchanges, disableAccountMetrics, moduleStageNames) + lowerCaseExchanges := []string{} + for _, exchange := range exchanges { + lowerCaseExchanges = append(lowerCaseExchanges, strings.ToLower(string(exchange))) + } + newMetrics := NewBlankMetrics(registry, lowerCaseExchanges, disableAccountMetrics, moduleStageNames) newMetrics.ConnectionCounter = metrics.GetOrRegisterCounter("active_connections", registry) newMetrics.TMaxTimeoutCounter = metrics.GetOrRegisterCounter("tmax_timeout", registry) newMetrics.ConnectionAcceptErrorMeter = metrics.GetOrRegisterMeter("connection_accept_errors", registry) @@ -331,7 +337,7 @@ func NewMetrics(registry metrics.Registry, exchanges []openrtb_ext.BidderName, d } } - for _, a := range exchanges { + for _, a := range lowerCaseExchanges { registerAdapterMetrics(registry, "adapter", string(a), newMetrics.AdapterMetrics[a]) } @@ -546,7 +552,7 @@ func (me *Metrics) getAccountMetrics(id string) *accountMetrics { am.debugRequestMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.debug_requests", id), me.MetricsRegistry) am.bidsReceivedMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.bids_received", id), me.MetricsRegistry) am.priceHistogram = metrics.GetOrRegisterHistogram(fmt.Sprintf("account.%s.prices", id), me.MetricsRegistry, metrics.NewExpDecaySample(1028, 0.015)) - am.adapterMetrics = make(map[openrtb_ext.BidderName]*AdapterMetrics, len(me.exchanges)) + am.adapterMetrics = make(map[string]*AdapterMetrics, len(me.exchanges)) am.moduleMetrics = make(map[string]*ModuleMetrics) am.storedResponsesMeter = metrics.GetOrRegisterMeter(fmt.Sprintf("account.%s.stored_responses", id), me.MetricsRegistry) if !me.MetricsDisabled.AccountAdapterDetails { @@ -670,9 +676,11 @@ func (me *Metrics) RecordStoredDataError(labels StoredDataLabels) { // RecordAdapterPanic implements a part of the MetricsEngine interface func (me *Metrics) RecordAdapterPanic(labels AdapterLabels) { - am, ok := me.AdapterMetrics[labels.Adapter] + adapterStr := string(labels.Adapter) + lowerCaseAdapterName := strings.ToLower(adapterStr) + am, ok := me.AdapterMetrics[lowerCaseAdapterName] if !ok { - glog.Errorf("Trying to run adapter metrics on %s: adapter metrics not found", string(labels.Adapter)) + glog.Errorf("Trying to run adapter metrics on %s: adapter metrics not found", adapterStr) return } am.PanicMeter.Mark(1) @@ -680,13 +688,15 @@ func (me *Metrics) RecordAdapterPanic(labels AdapterLabels) { // RecordAdapterRequest implements a part of the MetricsEngine interface func (me *Metrics) RecordAdapterRequest(labels AdapterLabels) { - am, ok := me.AdapterMetrics[labels.Adapter] + adapterStr := string(labels.Adapter) + lowerCaseAdapter := strings.ToLower(adapterStr) + am, ok := me.AdapterMetrics[lowerCaseAdapter] if !ok { - glog.Errorf("Trying to run adapter metrics on %s: adapter metrics not found", string(labels.Adapter)) + glog.Errorf("Trying to run adapter metrics on %s: adapter metrics not found", adapterStr) return } - aam, ok := me.getAccountMetrics(labels.PubID).adapterMetrics[labels.Adapter] + aam, ok := me.getAccountMetrics(labels.PubID).adapterMetrics[lowerCaseAdapter] switch labels.AdapterBids { case AdapterBidNone: am.NoBidMeter.Mark(1) @@ -719,8 +729,8 @@ func (me *Metrics) RecordAdapterConnections(adapterName openrtb_ext.BidderName, if me.MetricsDisabled.AdapterConnectionMetrics { return } - - am, ok := me.AdapterMetrics[adapterName] + lowerCaseAdapterName := strings.ToLower(string(adapterName)) + am, ok := me.AdapterMetrics[lowerCaseAdapterName] if !ok { glog.Errorf("Trying to log adapter connection metrics for %s: adapter not found", string(adapterName)) return @@ -749,16 +759,18 @@ func (me *Metrics) RecordBidderServerResponseTime(bidderServerResponseTime time. // RecordAdapterBidReceived implements a part of the MetricsEngine interface. // This tracks how many bids from each Bidder use `adm` vs. `nurl. func (me *Metrics) RecordAdapterBidReceived(labels AdapterLabels, bidType openrtb_ext.BidType, hasAdm bool) { - am, ok := me.AdapterMetrics[labels.Adapter] + adapterStr := string(labels.Adapter) + lowerCaseAdapterName := strings.ToLower(adapterStr) + am, ok := me.AdapterMetrics[lowerCaseAdapterName] if !ok { - glog.Errorf("Trying to run adapter bid metrics on %s: adapter metrics not found", string(labels.Adapter)) + glog.Errorf("Trying to run adapter bid metrics on %s: adapter metrics not found", adapterStr) return } // Adapter metrics am.BidsReceivedMeter.Mark(1) // Account-Adapter metrics - if aam, ok := me.getAccountMetrics(labels.PubID).adapterMetrics[labels.Adapter]; ok { + if aam, ok := me.getAccountMetrics(labels.PubID).adapterMetrics[lowerCaseAdapterName]; ok { aam.BidsReceivedMeter.Mark(1) } @@ -775,22 +787,26 @@ func (me *Metrics) RecordAdapterBidReceived(labels AdapterLabels, bidType openrt // RecordAdapterPrice implements a part of the MetricsEngine interface. Generates a histogram of winning bid prices func (me *Metrics) RecordAdapterPrice(labels AdapterLabels, cpm float64) { - am, ok := me.AdapterMetrics[labels.Adapter] + adapterStr := string(labels.Adapter) + lowercaseAdapter := strings.ToLower(adapterStr) + am, ok := me.AdapterMetrics[lowercaseAdapter] if !ok { - glog.Errorf("Trying to run adapter price metrics on %s: adapter metrics not found", string(labels.Adapter)) + glog.Errorf("Trying to run adapter price metrics on %s: adapter metrics not found", adapterStr) return } // Adapter metrics am.PriceHistogram.Update(int64(cpm)) // Account-Adapter metrics - if aam, ok := me.getAccountMetrics(labels.PubID).adapterMetrics[labels.Adapter]; ok { + if aam, ok := me.getAccountMetrics(labels.PubID).adapterMetrics[lowercaseAdapter]; ok { aam.PriceHistogram.Update(int64(cpm)) } } // RecordAdapterTime implements a part of the MetricsEngine interface. Records the adapter response time func (me *Metrics) RecordAdapterTime(labels AdapterLabels, length time.Duration) { - am, ok := me.AdapterMetrics[labels.Adapter] + adapterStr := string(labels.Adapter) + lowercaseAdapter := strings.ToLower(adapterStr) + am, ok := me.AdapterMetrics[lowercaseAdapter] if !ok { glog.Errorf("Trying to run adapter latency metrics on %s: adapter metrics not found", string(labels.Adapter)) return @@ -798,7 +814,7 @@ func (me *Metrics) RecordAdapterTime(labels AdapterLabels, length time.Duration) // Adapter metrics am.RequestTimer.Update(length) // Account-Adapter metrics - if aam, ok := me.getAccountMetrics(labels.PubID).adapterMetrics[labels.Adapter]; ok { + if aam, ok := me.getAccountMetrics(labels.PubID).adapterMetrics[lowercaseAdapter]; ok { aam.RequestTimer.Update(length) } } @@ -911,13 +927,14 @@ func (me *Metrics) RecordRequestPrivacy(privacy PrivacyLabels) { } func (me *Metrics) RecordAdapterGDPRRequestBlocked(adapterName openrtb_ext.BidderName) { + adapterStr := string(adapterName) if me.MetricsDisabled.AdapterGDPRRequestBlocked { return } - am, ok := me.AdapterMetrics[adapterName] + am, ok := me.AdapterMetrics[strings.ToLower(adapterStr)] if !ok { - glog.Errorf("Trying to log adapter GDPR request blocked metric for %s: adapter not found", string(adapterName)) + glog.Errorf("Trying to log adapter GDPR request blocked metric for %s: adapter not found", adapterStr) return } @@ -937,9 +954,10 @@ func (me *Metrics) RecordAdsCertSignTime(adsCertSignTime time.Duration) { } func (me *Metrics) RecordBidValidationCreativeSizeError(adapter openrtb_ext.BidderName, pubID string) { - am, ok := me.AdapterMetrics[adapter] + adapterStr := string(adapter) + am, ok := me.AdapterMetrics[strings.ToLower(adapterStr)] if !ok { - glog.Errorf("Trying to run adapter metrics on %s: adapter metrics not found", string(adapter)) + glog.Errorf("Trying to run adapter metrics on %s: adapter metrics not found", adapterStr) return } am.BidValidationCreativeSizeErrorMeter.Mark(1) @@ -951,9 +969,10 @@ func (me *Metrics) RecordBidValidationCreativeSizeError(adapter openrtb_ext.Bidd } func (me *Metrics) RecordBidValidationCreativeSizeWarn(adapter openrtb_ext.BidderName, pubID string) { - am, ok := me.AdapterMetrics[adapter] + adapterStr := string(adapter) + am, ok := me.AdapterMetrics[strings.ToLower(adapterStr)] if !ok { - glog.Errorf("Trying to run adapter metrics on %s: adapter metrics not found", string(adapter)) + glog.Errorf("Trying to run adapter metrics on %s: adapter metrics not found", adapterStr) return } am.BidValidationCreativeSizeWarnMeter.Mark(1) @@ -965,9 +984,10 @@ func (me *Metrics) RecordBidValidationCreativeSizeWarn(adapter openrtb_ext.Bidde } func (me *Metrics) RecordBidValidationSecureMarkupError(adapter openrtb_ext.BidderName, pubID string) { - am, ok := me.AdapterMetrics[adapter] + adapterStr := string(adapter) + am, ok := me.AdapterMetrics[strings.ToLower(adapterStr)] if !ok { - glog.Errorf("Trying to run adapter metrics on %s: adapter metrics not found", string(adapter)) + glog.Errorf("Trying to run adapter metrics on %s: adapter metrics not found", adapterStr) return } am.BidValidationSecureMarkupErrorMeter.Mark(1) @@ -979,9 +999,10 @@ func (me *Metrics) RecordBidValidationSecureMarkupError(adapter openrtb_ext.Bidd } func (me *Metrics) RecordBidValidationSecureMarkupWarn(adapter openrtb_ext.BidderName, pubID string) { - am, ok := me.AdapterMetrics[adapter] + adapterStr := string(adapter) + am, ok := me.AdapterMetrics[strings.ToLower(adapterStr)] if !ok { - glog.Errorf("Trying to run adapter metrics on %s: adapter metrics not found", string(adapter)) + glog.Errorf("Trying to run adapter metrics on %s: adapter metrics not found", adapterStr) return } am.BidValidationSecureMarkupWarnMeter.Mark(1) diff --git a/metrics/go_metrics_test.go b/metrics/go_metrics_test.go index 8acd1923a85..08ee65f52ac 100644 --- a/metrics/go_metrics_test.go +++ b/metrics/go_metrics_test.go @@ -15,15 +15,15 @@ func TestNewMetrics(t *testing.T) { registry := metrics.NewRegistry() syncerKeys := []string{"foo"} moduleStageNames := map[string][]string{"foobar": {"entry", "raw"}, "another_module": {"raw", "auction"}} - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus, openrtb_ext.BidderRubicon}, config.DisabledMetrics{}, syncerKeys, moduleStageNames) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Adapter1"), openrtb_ext.BidderName("Adapter2")}, config.DisabledMetrics{}, syncerKeys, moduleStageNames) ensureContains(t, registry, "app_requests", m.AppRequestMeter) ensureContains(t, registry, "debug_requests", m.DebugRequestMeter) ensureContains(t, registry, "no_cookie_requests", m.NoCookieMeter) ensureContains(t, registry, "request_time", m.RequestTimer) ensureContains(t, registry, "amp_no_cookie_requests", m.AmpNoCookieMeter) - ensureContainsAdapterMetrics(t, registry, "adapter.appnexus", m.AdapterMetrics["appnexus"]) - ensureContainsAdapterMetrics(t, registry, "adapter.rubicon", m.AdapterMetrics["rubicon"]) + ensureContainsAdapterMetrics(t, registry, "adapter.adapter1", m.AdapterMetrics["adapter1"]) + ensureContainsAdapterMetrics(t, registry, "adapter.adapter2", m.AdapterMetrics["adapter2"]) ensureContains(t, registry, "cookie_sync_requests", m.CookieSyncMeter) ensureContains(t, registry, "cookie_sync_requests.ok", m.CookieSyncStatusMeter[CookieSyncOK]) ensureContains(t, registry, "cookie_sync_requests.bad_request", m.CookieSyncStatusMeter[CookieSyncBadRequest]) @@ -95,19 +95,21 @@ func TestNewMetrics(t *testing.T) { func TestRecordBidType(t *testing.T) { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus}, config.DisabledMetrics{}, nil, nil) + adapterName := "FOO" + lowerCaseAdapterName := "foo" + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapterName)}, config.DisabledMetrics{}, nil, nil) m.RecordAdapterBidReceived(AdapterLabels{ - Adapter: openrtb_ext.BidderAppnexus, + Adapter: openrtb_ext.BidderName(adapterName), }, openrtb_ext.BidTypeBanner, true) - VerifyMetrics(t, "Appnexus Banner Adm Bids", m.AdapterMetrics[openrtb_ext.BidderAppnexus].MarkupMetrics[openrtb_ext.BidTypeBanner].AdmMeter.Count(), 1) - VerifyMetrics(t, "Appnexus Banner Nurl Bids", m.AdapterMetrics[openrtb_ext.BidderAppnexus].MarkupMetrics[openrtb_ext.BidTypeBanner].NurlMeter.Count(), 0) + VerifyMetrics(t, "foo Banner Adm Bids", m.AdapterMetrics[lowerCaseAdapterName].MarkupMetrics[openrtb_ext.BidTypeBanner].AdmMeter.Count(), 1) + VerifyMetrics(t, "foo Banner Nurl Bids", m.AdapterMetrics[lowerCaseAdapterName].MarkupMetrics[openrtb_ext.BidTypeBanner].NurlMeter.Count(), 0) m.RecordAdapterBidReceived(AdapterLabels{ - Adapter: openrtb_ext.BidderAppnexus, + Adapter: openrtb_ext.BidderName(adapterName), }, openrtb_ext.BidTypeVideo, false) - VerifyMetrics(t, "Appnexus Video Adm Bids", m.AdapterMetrics[openrtb_ext.BidderAppnexus].MarkupMetrics[openrtb_ext.BidTypeVideo].AdmMeter.Count(), 0) - VerifyMetrics(t, "Appnexus Video Nurl Bids", m.AdapterMetrics[openrtb_ext.BidderAppnexus].MarkupMetrics[openrtb_ext.BidTypeVideo].NurlMeter.Count(), 1) + VerifyMetrics(t, "foo Video Adm Bids", m.AdapterMetrics[lowerCaseAdapterName].MarkupMetrics[openrtb_ext.BidTypeVideo].AdmMeter.Count(), 0) + VerifyMetrics(t, "foo Video Nurl Bids", m.AdapterMetrics[lowerCaseAdapterName].MarkupMetrics[openrtb_ext.BidTypeVideo].NurlMeter.Count(), 1) } func ensureContains(t *testing.T, registry metrics.Registry, name string, metric interface{}) { @@ -198,17 +200,19 @@ func TestRecordBidTypeDisabledConfig(t *testing.T) { PubID: "acct-id", }, } - + adapter := "AnyName" + lowerCaseAdapter := "anyname" for _, test := range testCases { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus}, test.DisabledMetrics, nil, nil) + + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, test.DisabledMetrics, nil, nil) m.RecordAdapterBidReceived(AdapterLabels{ - Adapter: openrtb_ext.BidderAppnexus, + Adapter: openrtb_ext.BidderName(adapter), PubID: test.PubID, }, test.BidType, test.hasAdm) - assert.Equal(t, test.ExpectedAdmMeterCount, m.AdapterMetrics[openrtb_ext.BidderAppnexus].MarkupMetrics[test.BidType].AdmMeter.Count(), "Appnexus Banner Adm Bids") - assert.Equal(t, test.ExpectedNurlMeterCount, m.AdapterMetrics[openrtb_ext.BidderAppnexus].MarkupMetrics[test.BidType].NurlMeter.Count(), "Appnexus Banner Nurl Bids") + assert.Equal(t, test.ExpectedAdmMeterCount, m.AdapterMetrics[lowerCaseAdapter].MarkupMetrics[test.BidType].AdmMeter.Count(), "AnyName Banner Adm Bids") + assert.Equal(t, test.ExpectedNurlMeterCount, m.AdapterMetrics[lowerCaseAdapter].MarkupMetrics[test.BidType].NurlMeter.Count(), "AnyName Banner Nurl Bids") if test.DisabledMetrics.AccountAdapterDetails { assert.Len(t, m.accountMetrics[test.PubID].adapterMetrics, 0, "Test failed. Account metrics that contain adapter information are disabled, therefore we expect no entries in m.accountMetrics[accountId].adapterMetrics, we have %d \n", len(m.accountMetrics[test.PubID].adapterMetrics)) @@ -272,9 +276,10 @@ func TestRecordDebugRequest(t *testing.T) { expectedDebugCount: 0, }, } + adapter := "AnyName" for _, test := range testCases { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus}, test.givenDisabledMetrics, nil, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, test.givenDisabledMetrics, nil, nil) m.RecordDebugRequest(test.givenDebugEnabledFlag, test.givenPubID) am := m.getAccountMetrics(test.givenPubID) @@ -311,16 +316,18 @@ func TestRecordBidValidationCreativeSize(t *testing.T) { expectedAccountCount: 0, }, } + adapter := "AnyName" + lowerCaseAdapter := "anyname" for _, test := range testCases { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus}, test.givenDisabledMetrics, nil, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, test.givenDisabledMetrics, nil, nil) - m.RecordBidValidationCreativeSizeError(openrtb_ext.BidderAppnexus, test.givenPubID) - m.RecordBidValidationCreativeSizeWarn(openrtb_ext.BidderAppnexus, test.givenPubID) + m.RecordBidValidationCreativeSizeError(openrtb_ext.BidderName(adapter), test.givenPubID) + m.RecordBidValidationCreativeSizeWarn(openrtb_ext.BidderName(adapter), test.givenPubID) am := m.getAccountMetrics(test.givenPubID) - assert.Equal(t, test.expectedAdapterCount, m.AdapterMetrics[openrtb_ext.BidderAppnexus].BidValidationCreativeSizeErrorMeter.Count()) - assert.Equal(t, test.expectedAdapterCount, m.AdapterMetrics[openrtb_ext.BidderAppnexus].BidValidationCreativeSizeWarnMeter.Count()) + assert.Equal(t, test.expectedAdapterCount, m.AdapterMetrics[lowerCaseAdapter].BidValidationCreativeSizeErrorMeter.Count()) + assert.Equal(t, test.expectedAdapterCount, m.AdapterMetrics[lowerCaseAdapter].BidValidationCreativeSizeWarnMeter.Count()) assert.Equal(t, test.expectedAccountCount, am.bidValidationCreativeSizeMeter.Count()) assert.Equal(t, test.expectedAccountCount, am.bidValidationCreativeSizeWarnMeter.Count()) } @@ -353,16 +360,18 @@ func TestRecordBidValidationSecureMarkup(t *testing.T) { expectedAccountCount: 0, }, } + adapter := "AnyName" + lowerCaseAdapter := "anyname" for _, test := range testCases { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus}, test.givenDisabledMetrics, nil, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, test.givenDisabledMetrics, nil, nil) - m.RecordBidValidationSecureMarkupError(openrtb_ext.BidderAppnexus, test.givenPubID) - m.RecordBidValidationSecureMarkupWarn(openrtb_ext.BidderAppnexus, test.givenPubID) + m.RecordBidValidationSecureMarkupError(openrtb_ext.BidderName(adapter), test.givenPubID) + m.RecordBidValidationSecureMarkupWarn(openrtb_ext.BidderName(adapter), test.givenPubID) am := m.getAccountMetrics(test.givenPubID) - assert.Equal(t, test.expectedAdapterCount, m.AdapterMetrics[openrtb_ext.BidderAppnexus].BidValidationSecureMarkupErrorMeter.Count()) - assert.Equal(t, test.expectedAdapterCount, m.AdapterMetrics[openrtb_ext.BidderAppnexus].BidValidationSecureMarkupWarnMeter.Count()) + assert.Equal(t, test.expectedAdapterCount, m.AdapterMetrics[lowerCaseAdapter].BidValidationSecureMarkupErrorMeter.Count()) + assert.Equal(t, test.expectedAdapterCount, m.AdapterMetrics[lowerCaseAdapter].BidValidationSecureMarkupWarnMeter.Count()) assert.Equal(t, test.expectedAccountCount, am.bidValidationSecureMarkupMeter.Count()) assert.Equal(t, test.expectedAccountCount, am.bidValidationSecureMarkupWarnMeter.Count()) } @@ -385,9 +394,10 @@ func TestRecordDNSTime(t *testing.T) { outExpDuration: time.Duration(0), }, } + adapter := "AnyName" for _, test := range testCases { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) m.RecordDNSTime(test.inDnsLookupDuration) @@ -412,9 +422,10 @@ func TestRecordTLSHandshakeTime(t *testing.T) { expectedDuration: time.Duration(0), }, } + adapter := "AnyName" for _, test := range testCases { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) m.RecordTLSHandshakeTime(test.tLSHandshakeDuration) @@ -442,9 +453,10 @@ func TestRecordBidderServerResponseTime(t *testing.T) { expectedSum: 1000, }, } + adapter := "AnyName" for _, test := range testCases { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) m.RecordBidderServerResponseTime(test.time) @@ -467,7 +479,8 @@ func TestRecordAdapterConnections(t *testing.T) { expectedConnCreatedCount int64 expectedConnWaitTime time.Duration } - + adapter := "AnyName" + lowerCaseAdapterName := "anyname" testCases := []struct { description string in testIn @@ -476,7 +489,7 @@ func TestRecordAdapterConnections(t *testing.T) { { description: "Successful, new connection created, has connection wait", in: testIn{ - adapterName: openrtb_ext.BidderAppnexus, + adapterName: openrtb_ext.BidderName(adapter), connWasReused: false, connWait: time.Second * 5, connMetricsDisabled: false, @@ -490,7 +503,7 @@ func TestRecordAdapterConnections(t *testing.T) { { description: "Successful, new connection created, has connection wait", in: testIn{ - adapterName: openrtb_ext.BidderAppnexus, + adapterName: openrtb_ext.BidderName(adapter), connWasReused: false, connWait: time.Second * 4, connMetricsDisabled: false, @@ -503,7 +516,7 @@ func TestRecordAdapterConnections(t *testing.T) { { description: "Successful, was reused, no connection wait", in: testIn{ - adapterName: openrtb_ext.BidderAppnexus, + adapterName: openrtb_ext.BidderName(adapter), connWasReused: true, connMetricsDisabled: false, }, @@ -515,7 +528,7 @@ func TestRecordAdapterConnections(t *testing.T) { { description: "Successful, was reused, has connection wait", in: testIn{ - adapterName: openrtb_ext.BidderAppnexus, + adapterName: openrtb_ext.BidderName(adapter), connWasReused: true, connWait: time.Second * 5, connMetricsDisabled: false, @@ -538,7 +551,7 @@ func TestRecordAdapterConnections(t *testing.T) { { description: "Adapter connection metrics are disabled, nothing gets updated", in: testIn{ - adapterName: openrtb_ext.BidderAppnexus, + adapterName: openrtb_ext.BidderName(adapter), connWasReused: false, connWait: time.Second * 5, connMetricsDisabled: true, @@ -549,19 +562,18 @@ func TestRecordAdapterConnections(t *testing.T) { for i, test := range testCases { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus}, config.DisabledMetrics{AdapterConnectionMetrics: test.in.connMetricsDisabled}, nil, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, config.DisabledMetrics{AdapterConnectionMetrics: test.in.connMetricsDisabled}, nil, nil) m.RecordAdapterConnections(test.in.adapterName, test.in.connWasReused, test.in.connWait) - - assert.Equal(t, test.out.expectedConnReusedCount, m.AdapterMetrics[openrtb_ext.BidderAppnexus].ConnReused.Count(), "Test [%d] incorrect number of reused connections to adapter", i) - assert.Equal(t, test.out.expectedConnCreatedCount, m.AdapterMetrics[openrtb_ext.BidderAppnexus].ConnCreated.Count(), "Test [%d] incorrect number of new connections to adapter created", i) - assert.Equal(t, test.out.expectedConnWaitTime.Nanoseconds(), m.AdapterMetrics[openrtb_ext.BidderAppnexus].ConnWaitTime.Sum(), "Test [%d] incorrect wait time in connection to adapter", i) + assert.Equal(t, test.out.expectedConnReusedCount, m.AdapterMetrics[lowerCaseAdapterName].ConnReused.Count(), "Test [%d] incorrect number of reused connections to adapter", i) + assert.Equal(t, test.out.expectedConnCreatedCount, m.AdapterMetrics[lowerCaseAdapterName].ConnCreated.Count(), "Test [%d] incorrect number of new connections to adapter created", i) + assert.Equal(t, test.out.expectedConnWaitTime.Nanoseconds(), m.AdapterMetrics[lowerCaseAdapterName].ConnWaitTime.Sum(), "Test [%d] incorrect wait time in connection to adapter", i) } } func TestNewMetricsWithDisabledConfig(t *testing.T) { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus, openrtb_ext.BidderRubicon}, config.DisabledMetrics{AccountAdapterDetails: true, AccountModulesMetrics: true}, nil, map[string][]string{"foobar": {"entry", "raw"}}) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Foo"), openrtb_ext.BidderName("bar")}, config.DisabledMetrics{AccountAdapterDetails: true, AccountModulesMetrics: true}, nil, map[string][]string{"foobar": {"entry", "raw"}}) assert.True(t, m.MetricsDisabled.AccountAdapterDetails, "Accound adapter metrics should be disabled") assert.True(t, m.MetricsDisabled.AccountModulesMetrics, "Accound modules metrics should be disabled") @@ -569,7 +581,7 @@ func TestNewMetricsWithDisabledConfig(t *testing.T) { func TestRecordPrebidCacheRequestTimeWithSuccess(t *testing.T) { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Foo")}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) m.RecordPrebidCacheRequestTime(true, 42) @@ -579,7 +591,7 @@ func TestRecordPrebidCacheRequestTimeWithSuccess(t *testing.T) { func TestRecordPrebidCacheRequestTimeWithNotSuccess(t *testing.T) { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Foo")}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) m.RecordPrebidCacheRequestTime(false, 42) @@ -647,7 +659,7 @@ func TestRecordStoredDataFetchTime(t *testing.T) { for _, tt := range tests { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus, openrtb_ext.BidderRubicon}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Foo"), openrtb_ext.BidderName("Bar")}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) m.RecordStoredDataFetchTime(StoredDataLabels{ DataType: tt.dataType, DataFetchType: tt.fetchType, @@ -721,7 +733,7 @@ func TestRecordStoredDataError(t *testing.T) { for _, tt := range tests { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus, openrtb_ext.BidderRubicon}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Foo"), openrtb_ext.BidderName("Bar")}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) m.RecordStoredDataError(StoredDataLabels{ DataType: tt.dataType, Error: tt.errorType, @@ -734,7 +746,7 @@ func TestRecordStoredDataError(t *testing.T) { func TestRecordRequestPrivacy(t *testing.T) { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus, openrtb_ext.BidderRubicon}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Foo"), openrtb_ext.BidderName("Bar")}, config.DisabledMetrics{AccountAdapterDetails: true}, nil, nil) // CCPA m.RecordRequestPrivacy(PrivacyLabels{ @@ -780,6 +792,8 @@ func TestRecordRequestPrivacy(t *testing.T) { func TestRecordAdapterGDPRRequestBlocked(t *testing.T) { var fakeBidder openrtb_ext.BidderName = "fooAdvertising" + adapter := "AnyName" + lowerCaseAdapterName := "anyname" tests := []struct { description string @@ -790,7 +804,7 @@ func TestRecordAdapterGDPRRequestBlocked(t *testing.T) { { description: "", metricsDisabled: false, - adapterName: openrtb_ext.BidderAppnexus, + adapterName: openrtb_ext.BidderName(adapter), expectedCount: 1, }, { @@ -802,24 +816,23 @@ func TestRecordAdapterGDPRRequestBlocked(t *testing.T) { { description: "", metricsDisabled: true, - adapterName: openrtb_ext.BidderAppnexus, + adapterName: openrtb_ext.BidderName(adapter), expectedCount: 0, }, } - for _, tt := range tests { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus}, config.DisabledMetrics{AdapterGDPRRequestBlocked: tt.metricsDisabled}, nil, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, config.DisabledMetrics{AdapterGDPRRequestBlocked: tt.metricsDisabled}, nil, nil) m.RecordAdapterGDPRRequestBlocked(tt.adapterName) - assert.Equal(t, tt.expectedCount, m.AdapterMetrics[openrtb_ext.BidderAppnexus].GDPRRequestBlocked.Count(), tt.description) + assert.Equal(t, tt.expectedCount, m.AdapterMetrics[lowerCaseAdapterName].GDPRRequestBlocked.Count(), tt.description) } } func TestRecordCookieSync(t *testing.T) { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus, openrtb_ext.BidderRubicon}, config.DisabledMetrics{}, nil, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Foo"), openrtb_ext.BidderName("Bar")}, config.DisabledMetrics{}, nil, nil) // Known m.RecordCookieSync(CookieSyncBadRequest) @@ -837,7 +850,7 @@ func TestRecordCookieSync(t *testing.T) { func TestRecordSyncerRequest(t *testing.T) { registry := metrics.NewRegistry() syncerKeys := []string{"foo"} - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus, openrtb_ext.BidderRubicon}, config.DisabledMetrics{}, syncerKeys, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Adapter1"), openrtb_ext.BidderName("Adapter2")}, config.DisabledMetrics{}, syncerKeys, nil) // Known m.RecordSyncerRequest("foo", SyncerCookieSyncOK) @@ -856,7 +869,7 @@ func TestRecordSyncerRequest(t *testing.T) { func TestRecordSetUid(t *testing.T) { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus, openrtb_ext.BidderRubicon}, config.DisabledMetrics{}, nil, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Foo"), openrtb_ext.BidderName("Bar")}, config.DisabledMetrics{}, nil, nil) // Known m.RecordSetUid(SetUidOptOut) @@ -875,7 +888,7 @@ func TestRecordSetUid(t *testing.T) { func TestRecordSyncerSet(t *testing.T) { registry := metrics.NewRegistry() syncerKeys := []string{"foo"} - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus, openrtb_ext.BidderRubicon}, config.DisabledMetrics{}, syncerKeys, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("Adapter1"), openrtb_ext.BidderName("Adapter2")}, config.DisabledMetrics{}, syncerKeys, nil) // Known m.RecordSyncerSet("foo", SyncerSetUidCleared) @@ -929,7 +942,7 @@ func TestStoredResponses(t *testing.T) { } for _, test := range testCases { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus}, config.DisabledMetrics{AccountStoredResponses: test.accountStoredResponsesMetricsDisabled}, nil, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("AnyName")}, config.DisabledMetrics{AccountStoredResponses: test.accountStoredResponsesMetricsDisabled}, nil, nil) m.RecordStoredResponse(test.givenPubID) am := m.getAccountMetrics(test.givenPubID) @@ -963,7 +976,7 @@ func TestRecordAdsCertSignTime(t *testing.T) { } for _, test := range testCases { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus}, config.DisabledMetrics{}, nil, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("AnyName")}, config.DisabledMetrics{}, nil, nil) m.RecordAdsCertSignTime(test.inAdsCertSignDuration) @@ -994,7 +1007,7 @@ func TestRecordAdsCertReqMetric(t *testing.T) { for _, test := range testCases { registry := metrics.NewRegistry() - m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderAppnexus}, config.DisabledMetrics{}, nil, nil) + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName("AnyName")}, config.DisabledMetrics{}, nil, nil) m.RecordAdsCertReq(test.requestSuccess) @@ -1131,3 +1144,127 @@ func VerifyMetrics(t *testing.T, name string, expected int64, actual int64) { t.Errorf("Error in metric %s: expected %d, got %d.", name, expected, actual) } } + +func TestRecordAdapterPanic(t *testing.T) { + registry := metrics.NewRegistry() + adapter := "AnyName" + lowerCaseAdapterName := "anyname" + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, config.DisabledMetrics{AccountAdapterDetails: true, AccountModulesMetrics: true}, nil, map[string][]string{"foobar": {"entry", "raw"}}) + m.RecordAdapterPanic(AdapterLabels{Adapter: openrtb_ext.BidderName(adapter)}) + assert.Equal(t, m.AdapterMetrics[lowerCaseAdapterName].PanicMeter.Count(), int64(1)) +} + +func TestRecordAdapterPrice(t *testing.T) { + registry := metrics.NewRegistry() + syncerKeys := []string{"foo"} + adapter := "AnyName" + lowerCaseAdapterName := "anyname" + pubID := "pub1" + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter), openrtb_ext.BidderAppnexus}, config.DisabledMetrics{}, syncerKeys, nil) + m.RecordAdapterPrice(AdapterLabels{Adapter: openrtb_ext.BidderName(adapter), PubID: pubID}, 1000) + assert.Equal(t, m.AdapterMetrics[lowerCaseAdapterName].PriceHistogram.Max(), int64(1000)) + assert.Equal(t, m.getAccountMetrics(pubID).adapterMetrics[lowerCaseAdapterName].PriceHistogram.Max(), int64(1000)) +} + +func TestRecordAdapterTime(t *testing.T) { + registry := metrics.NewRegistry() + syncerKeys := []string{"foo"} + adapter := "AnyName" + lowerCaseAdapterName := "anyname" + pubID := "pub1" + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter), openrtb_ext.BidderAppnexus, openrtb_ext.BidderName("Adapter2")}, config.DisabledMetrics{}, syncerKeys, nil) + m.RecordAdapterTime(AdapterLabels{Adapter: openrtb_ext.BidderName(adapter), PubID: pubID}, 1000) + assert.Equal(t, m.AdapterMetrics[lowerCaseAdapterName].RequestTimer.Max(), int64(1000)) + assert.Equal(t, m.getAccountMetrics(pubID).adapterMetrics[lowerCaseAdapterName].RequestTimer.Max(), int64(1000)) +} + +func TestRecordAdapterRequest(t *testing.T) { + syncerKeys := []string{"foo"} + moduleStageNames := map[string][]string{"foobar": {"entry", "raw"}, "another_module": {"raw", "auction"}} + adapter := "AnyName" + lowerCaseAdapter := "anyname" + type errorCount struct { + badInput, badServer, timeout, failedToRequestBid, validation, tmaxTimeout, unknown int64 + } + type adapterBidsCount struct { + NoBid, GotBid int64 + } + tests := []struct { + description string + labels AdapterLabels + expectedNoCookieCount int64 + expectedAdapterBidsCount adapterBidsCount + expectedErrorCount errorCount + }{ + { + description: "no-bid", + labels: AdapterLabels{ + Adapter: openrtb_ext.BidderName(adapter), + AdapterBids: AdapterBidNone, + PubID: "acc-1", + }, + expectedAdapterBidsCount: adapterBidsCount{NoBid: 1}, + }, + { + description: "got-bid", + labels: AdapterLabels{ + Adapter: openrtb_ext.BidderName(adapter), + AdapterBids: AdapterBidPresent, + PubID: "acc-2", + }, + expectedAdapterBidsCount: adapterBidsCount{GotBid: 1}, + }, + { + description: "adapter-errors", + labels: AdapterLabels{ + Adapter: openrtb_ext.BidderName(adapter), + PubID: "acc-1", + AdapterErrors: map[AdapterError]struct{}{ + AdapterErrorBadInput: {}, + AdapterErrorBadServerResponse: {}, + AdapterErrorFailedToRequestBids: {}, + AdapterErrorTimeout: {}, + AdapterErrorValidation: {}, + AdapterErrorTmaxTimeout: {}, + AdapterErrorUnknown: {}, + }, + }, + expectedErrorCount: errorCount{ + badInput: 1, + badServer: 1, + timeout: 1, + failedToRequestBid: 1, + validation: 1, + tmaxTimeout: 1, + unknown: 1, + }, + }, + } + for _, test := range tests { + t.Run(test.description, func(t *testing.T) { + registry := metrics.NewRegistry() + m := NewMetrics(registry, []openrtb_ext.BidderName{openrtb_ext.BidderName(adapter)}, config.DisabledMetrics{}, syncerKeys, moduleStageNames) + m.RecordAdapterRequest(test.labels) + adapterMetric := m.AdapterMetrics[lowerCaseAdapter] + if assert.NotNil(t, adapterMetric) { + assert.Equal(t, test.expectedAdapterBidsCount, adapterBidsCount{ + NoBid: adapterMetric.NoBidMeter.Count(), + GotBid: adapterMetric.GotBidsMeter.Count(), + }) + } + assert.Equal(t, test.expectedNoCookieCount, adapterMetric.NoCookieMeter.Count()) + adapterErrMetric := adapterMetric.ErrorMeters + if assert.NotNil(t, adapterErrMetric) { + assert.Equal(t, test.expectedErrorCount, errorCount{ + badInput: adapterErrMetric[AdapterErrorBadInput].Count(), + badServer: adapterErrMetric[AdapterErrorBadServerResponse].Count(), + timeout: adapterErrMetric[AdapterErrorTimeout].Count(), + failedToRequestBid: adapterErrMetric[AdapterErrorFailedToRequestBids].Count(), + validation: adapterErrMetric[AdapterErrorValidation].Count(), + tmaxTimeout: adapterErrMetric[AdapterErrorTmaxTimeout].Count(), + unknown: adapterErrMetric[AdapterErrorUnknown].Count(), + }) + } + }) + } +} diff --git a/metrics/metrics.go b/metrics/metrics.go index 99e64af0835..0c3025bd296 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -282,6 +282,7 @@ func AdapterErrors() []AdapterError { AdapterErrorTimeout, AdapterErrorFailedToRequestBids, AdapterErrorValidation, + AdapterErrorTmaxTimeout, AdapterErrorUnknown, } } diff --git a/metrics/prometheus/prometheus_test.go b/metrics/prometheus/prometheus_test.go index bea0087c6ea..a2b0e84d2ea 100644 --- a/metrics/prometheus/prometheus_test.go +++ b/metrics/prometheus/prometheus_test.go @@ -64,7 +64,7 @@ func TestMetricCountGatekeeping(t *testing.T) { // Verify Per-Adapter Cardinality // - This assertion provides a warning for newly added adapter metrics. Threre are 40+ adapters which makes the // cost of new per-adapter metrics rather expensive. Thought should be given when adding new per-adapter metrics. - assert.True(t, perAdapterCardinalityCount <= 29, "Per-Adapter Cardinality count equals %d \n", perAdapterCardinalityCount) + assert.True(t, perAdapterCardinalityCount <= 30, "Per-Adapter Cardinality count equals %d \n", perAdapterCardinalityCount) } func TestConnectionMetrics(t *testing.T) { From eea6ffe5d71c9c629948e3bde0ebd4ef377c889c Mon Sep 17 00:00:00 2001 From: Ashish Garg Date: Tue, 17 Oct 2023 11:45:09 +0530 Subject: [PATCH 174/268] migrate adform alias to use new pattern (#3180) --- exchange/adapter_builders.go | 1 - openrtb_ext/bidders.go | 2 -- static/bidder-info/adform.yaml | 20 +------------------ static/bidder-params/adform.json | 33 -------------------------------- 4 files changed, 1 insertion(+), 55 deletions(-) delete mode 100644 static/bidder-params/adform.json diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 25630fed414..61af122ad1a 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -197,7 +197,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderAceex: aceex.Builder, openrtb_ext.BidderAcuityAds: acuityads.Builder, openrtb_ext.BidderAdf: adf.Builder, - openrtb_ext.BidderAdform: adf.Builder, openrtb_ext.BidderAdgeneration: adgeneration.Builder, openrtb_ext.BidderAdhese: adhese.Builder, openrtb_ext.BidderAdkernel: adkernel.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 744c7fad3fe..8c4a9ea0dc4 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -23,7 +23,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderAceex, BidderAcuityAds, BidderAdf, - BidderAdform, BidderAdgeneration, BidderAdhese, BidderAdkernel, @@ -315,7 +314,6 @@ const ( BidderAceex BidderName = "aceex" BidderAcuityAds BidderName = "acuityads" BidderAdf BidderName = "adf" - BidderAdform BidderName = "adform" BidderAdgeneration BidderName = "adgeneration" BidderAdhese BidderName = "adhese" BidderAdkernel BidderName = "adkernel" diff --git a/static/bidder-info/adform.yaml b/static/bidder-info/adform.yaml index 2310f346c25..4aa6e70f1d0 100644 --- a/static/bidder-info/adform.yaml +++ b/static/bidder-info/adform.yaml @@ -1,19 +1 @@ -endpoint: "https://adx.adform.net/adx/openrtb" -maintainer: - email: "scope.sspp@adform.com" -gvlVendorID: 50 -capabilities: - app: - mediaTypes: - - banner - - native - - video - site: - mediaTypes: - - banner - - native - - video -userSync: - redirect: - url: "https://cm.adform.net/cookie?redirect_url={{.RedirectURL}}" - userMacro: "$UID" +aliasOf: adf diff --git a/static/bidder-params/adform.json b/static/bidder-params/adform.json deleted file mode 100644 index e112f122e49..00000000000 --- a/static/bidder-params/adform.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Adform Adapter Params", - "description": "A schema which validates params accepted by the adf adapter", - "type": "object", - "properties": { - "mid": { - "type": ["integer", "string"], - "pattern": "^\\d+$", - "description": "An ID which identifies the placement selling the impression" - }, - "inv": { - "type": ["integer"], - "description": "An ID which identifies the Adform inventory source id" - }, - "mname": { - "type": ["string"], - "description": "A Name which identifies the placement selling the impression" - }, - "priceType": { - "type": ["string"], - "description": "gross or net. Default is net.", - "pattern": "gross|net" - } - }, - "anyOf":[ - { - "required": ["mid"] - }, { - "required": ["inv", "mname"] - } - ] -} From 293cadc2f365d39ca452ccddea938b69f7482feb Mon Sep 17 00:00:00 2001 From: Ashish Garg Date: Tue, 17 Oct 2023 11:52:09 +0530 Subject: [PATCH 175/268] migrate copper alias to use new pattern (#3182) --- exchange/adapter_builders.go | 1 - openrtb_ext/bidders.go | 2 -- static/bidder-info/copper6.yaml | 10 +--------- static/bidder-params/copper6.json | 26 -------------------------- 4 files changed, 1 insertion(+), 38 deletions(-) delete mode 100644 static/bidder-params/copper6.json diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 61af122ad1a..f758b3ee33b 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -257,7 +257,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderConnectAd: connectad.Builder, openrtb_ext.BidderConsumable: consumable.Builder, openrtb_ext.BidderConversant: conversant.Builder, - openrtb_ext.BidderCopper6: adtelligent.Builder, openrtb_ext.BidderCpmstar: cpmstar.Builder, openrtb_ext.BidderCriteo: criteo.Builder, openrtb_ext.BidderCWire: cwire.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 8c4a9ea0dc4..8b0262bca19 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -83,7 +83,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderConnectAd, BidderConsumable, BidderConversant, - BidderCopper6, BidderCpmstar, BidderCriteo, BidderCWire, @@ -374,7 +373,6 @@ const ( BidderConnectAd BidderName = "connectad" BidderConsumable BidderName = "consumable" BidderConversant BidderName = "conversant" - BidderCopper6 BidderName = "copper6" BidderCpmstar BidderName = "cpmstar" BidderCriteo BidderName = "criteo" BidderCWire BidderName = "cwire" diff --git a/static/bidder-info/copper6.yaml b/static/bidder-info/copper6.yaml index 213cbe3624d..b4e259ef08a 100644 --- a/static/bidder-info/copper6.yaml +++ b/static/bidder-info/copper6.yaml @@ -1,15 +1,7 @@ +aliasOf: adtelligent endpoint: "http://ghb.app.copper6.com/pbs/ortb" maintainer: email: "info@copper6.com" -capabilities: - app: - mediaTypes: - - banner - - video - site: - mediaTypes: - - banner - - video userSync: # Copper6 ssp supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. diff --git a/static/bidder-params/copper6.json b/static/bidder-params/copper6.json deleted file mode 100644 index fa4050f6c84..00000000000 --- a/static/bidder-params/copper6.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Copper6 Adapter Params", - "description": "A schema which validates params accepted by the Copper6 ssp adapter", - - "type": "object", - "properties": { - "placementId": { - "type": "integer", - "description": "An ID which identifies this placement of the impression" - }, - "siteId": { - "type": "integer", - "description": "An ID which identifies the site selling the impression" - }, - "aid": { - "type": "integer", - "description": "An ID which identifies the channel" - }, - "bidFloor": { - "type": "number", - "description": "BidFloor, US Dollars" - } - }, - "required": ["aid"] -} From 1384564fb934b487eba9f4e491268d7cdacbc4d5 Mon Sep 17 00:00:00 2001 From: Ashish Garg Date: Tue, 17 Oct 2023 12:00:53 +0530 Subject: [PATCH 176/268] update cookie sync endpoint to be case insensitive (#3103) --- endpoints/cookie_sync_test.go | 2 +- usersync/bidderfilter.go | 6 +- usersync/bidderfilter_test.go | 7 + usersync/chooser.go | 32 +++- usersync/chooser_test.go | 344 ++++++++++++++++++++++++---------- 5 files changed, 283 insertions(+), 108 deletions(-) diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go index 45f7a75da0c..af7819b94b9 100644 --- a/endpoints/cookie_sync_test.go +++ b/endpoints/cookie_sync_test.go @@ -87,7 +87,7 @@ func TestNewCookieSyncEndpoint(t *testing.T) { assert.IsType(t, &cookieSyncEndpoint{}, endpoint) assert.Equal(t, expected.config, result.config) - assert.Equal(t, expected.chooser, result.chooser) + assert.ObjectsAreEqualValues(expected.chooser, result.chooser) assert.Equal(t, expected.metrics, result.metrics) assert.Equal(t, expected.pbsAnalytics, result.pbsAnalytics) assert.Equal(t, expected.accountsFetcher, result.accountsFetcher) diff --git a/usersync/bidderfilter.go b/usersync/bidderfilter.go index 2d7d16ffe2b..2e4df476f26 100644 --- a/usersync/bidderfilter.go +++ b/usersync/bidderfilter.go @@ -1,5 +1,9 @@ package usersync +import ( + "strings" +) + // BidderFilter determines if a bidder has permission to perform a user sync activity. type BidderFilter interface { // Allowed returns true if the filter determines the bidder has permission and false if either @@ -40,7 +44,7 @@ func (f SpecificBidderFilter) Allowed(bidder string) bool { func NewSpecificBidderFilter(bidders []string, mode BidderFilterMode) BidderFilter { biddersLookup := make(map[string]struct{}, len(bidders)) for _, bidder := range bidders { - biddersLookup[bidder] = struct{}{} + biddersLookup[strings.ToLower(bidder)] = struct{}{} } return SpecificBidderFilter{biddersLookup: biddersLookup, mode: mode} diff --git a/usersync/bidderfilter_test.go b/usersync/bidderfilter_test.go index ddc757339a2..009c051bacc 100644 --- a/usersync/bidderfilter_test.go +++ b/usersync/bidderfilter_test.go @@ -1,6 +1,7 @@ package usersync import ( + "strings" "testing" "github.com/stretchr/testify/assert" @@ -69,6 +70,12 @@ func TestSpecificBidderFilter(t *testing.T) { mode: BidderFilterMode(-1), expected: false, }, + { + description: "Case Insensitive Include - One", + bidders: []string{strings.ToUpper(bidder)}, + mode: BidderFilterModeInclude, + expected: true, + }, } for _, test := range testCases { diff --git a/usersync/chooser.go b/usersync/chooser.go index 3f478049066..578c63717de 100644 --- a/usersync/chooser.go +++ b/usersync/chooser.go @@ -1,5 +1,10 @@ package usersync +import ( + "github.com/prebid/prebid-server/openrtb_ext" + "strings" +) + // Chooser determines which syncers are eligible for a given request. type Chooser interface { // Choose considers bidders to sync, filters the bidders, and returns the result of the @@ -15,9 +20,10 @@ func NewChooser(bidderSyncerLookup map[string]Syncer) Chooser { } return standardChooser{ - bidderSyncerLookup: bidderSyncerLookup, - biddersAvailable: bidders, - bidderChooser: standardBidderChooser{shuffler: randomShuffler{}}, + bidderSyncerLookup: bidderSyncerLookup, + biddersAvailable: bidders, + bidderChooser: standardBidderChooser{shuffler: randomShuffler{}}, + normalizeValidBidderName: openrtb_ext.NormalizeBidderName, } } @@ -100,9 +106,10 @@ type Privacy interface { // standardChooser implements the user syncer algorithm per official Prebid specification. type standardChooser struct { - bidderSyncerLookup map[string]Syncer - biddersAvailable []string - bidderChooser bidderChooser + bidderSyncerLookup map[string]Syncer + biddersAvailable []string + bidderChooser bidderChooser + normalizeValidBidderName func(name string) (openrtb_ext.BidderName, bool) } // Choose randomly selects user syncers which are permitted by the user's privacy settings and @@ -136,7 +143,12 @@ func (c standardChooser) Choose(request Request, cookie *Cookie) Result { } func (c standardChooser) evaluate(bidder string, syncersSeen map[string]struct{}, syncTypeFilter SyncTypeFilter, privacy Privacy, cookie *Cookie) (Syncer, BidderEvaluation) { - syncer, exists := c.bidderSyncerLookup[bidder] + bidderNormalized, exists := c.normalizeValidBidderName(bidder) + if !exists { + return nil, BidderEvaluation{Status: StatusUnknownBidder, Bidder: bidder} + } + + syncer, exists := c.bidderSyncerLookup[bidderNormalized.String()] if !exists { return nil, BidderEvaluation{Status: StatusUnknownBidder, Bidder: bidder} } @@ -147,7 +159,7 @@ func (c standardChooser) evaluate(bidder string, syncersSeen map[string]struct{} } syncersSeen[syncer.Key()] = struct{}{} - if !syncer.SupportsType(syncTypeFilter.ForBidder(bidder)) { + if !syncer.SupportsType(syncTypeFilter.ForBidder(strings.ToLower(bidder))) { return nil, BidderEvaluation{Status: StatusTypeNotSupported, Bidder: bidder, SyncerKey: syncer.Key()} } @@ -160,11 +172,11 @@ func (c standardChooser) evaluate(bidder string, syncersSeen map[string]struct{} return nil, BidderEvaluation{Status: StatusBlockedByPrivacy, Bidder: bidder, SyncerKey: syncer.Key()} } - if !privacy.GDPRAllowsBidderSync(bidder) { + if !privacy.GDPRAllowsBidderSync(bidderNormalized.String()) { return nil, BidderEvaluation{Status: StatusBlockedByGDPR, Bidder: bidder, SyncerKey: syncer.Key()} } - if !privacy.CCPAAllowsBidderSync(bidder) { + if !privacy.CCPAAllowsBidderSync(bidderNormalized.String()) { return nil, BidderEvaluation{Status: StatusBlockedByCCPA, Bidder: bidder, SyncerKey: syncer.Key()} } diff --git a/usersync/chooser_test.go b/usersync/chooser_test.go index 4f38002c988..6ab5a6b53e3 100644 --- a/usersync/chooser_test.go +++ b/usersync/chooser_test.go @@ -1,12 +1,13 @@ package usersync import ( + "github.com/prebid/prebid-server/openrtb_ext" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "testing" "time" "github.com/prebid/prebid-server/macros" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" ) func TestNewChooser(t *testing.T) { @@ -47,7 +48,10 @@ func TestChooserChoose(t *testing.T) { fakeSyncerA := fakeSyncer{key: "keyA", supportsIFrame: true} fakeSyncerB := fakeSyncer{key: "keyB", supportsIFrame: true} fakeSyncerC := fakeSyncer{key: "keyC", supportsIFrame: false} - bidderSyncerLookup := map[string]Syncer{"a": fakeSyncerA, "b": fakeSyncerB, "c": fakeSyncerC} + bidderSyncerLookup := map[string]Syncer{"a": fakeSyncerA, "b": fakeSyncerB, "c": fakeSyncerC, "appnexus": fakeSyncerA} + normalizedBidderNamesLookup := func(name string) (openrtb_ext.BidderName, bool) { + return openrtb_ext.BidderName(name), true + } syncerChoiceA := SyncerChoice{Bidder: "a", Syncer: fakeSyncerA} syncerChoiceB := SyncerChoice{Bidder: "b", Syncer: fakeSyncerB} syncTypeFilter := SyncTypeFilter{ @@ -61,16 +65,18 @@ func TestChooserChoose(t *testing.T) { givenRequest Request givenChosenBidders []string givenCookie Cookie + bidderNamesLookup func(name string) (openrtb_ext.BidderName, bool) expected Result }{ { description: "Cookie Opt Out", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + Privacy: &fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: 0, }, givenChosenBidders: []string{"a"}, givenCookie: Cookie{optOut: true}, + bidderNamesLookup: normalizedBidderNamesLookup, expected: Result{ Status: StatusBlockedByUserOptOut, BiddersEvaluated: nil, @@ -80,11 +86,12 @@ func TestChooserChoose(t *testing.T) { { description: "GDPR Host Cookie Not Allowed", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: false, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + Privacy: &fakePrivacy{gdprAllowsHostCookie: false, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: 0, }, givenChosenBidders: []string{"a"}, givenCookie: Cookie{}, + bidderNamesLookup: normalizedBidderNamesLookup, expected: Result{ Status: StatusBlockedByGDPR, BiddersEvaluated: nil, @@ -94,11 +101,12 @@ func TestChooserChoose(t *testing.T) { { description: "No Bidders", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + Privacy: &fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: 0, }, givenChosenBidders: []string{}, givenCookie: Cookie{}, + bidderNamesLookup: normalizedBidderNamesLookup, expected: Result{ Status: StatusOK, BiddersEvaluated: []BidderEvaluation{}, @@ -108,11 +116,12 @@ func TestChooserChoose(t *testing.T) { { description: "One Bidder - Sync", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + Privacy: &fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: 0, }, givenChosenBidders: []string{"a"}, givenCookie: Cookie{}, + bidderNamesLookup: normalizedBidderNamesLookup, expected: Result{ Status: StatusOK, BiddersEvaluated: []BidderEvaluation{{Bidder: "a", SyncerKey: "keyA", Status: StatusOK}}, @@ -122,11 +131,12 @@ func TestChooserChoose(t *testing.T) { { description: "One Bidder - No Sync", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + Privacy: &fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: 0, }, givenChosenBidders: []string{"c"}, givenCookie: Cookie{}, + bidderNamesLookup: normalizedBidderNamesLookup, expected: Result{ Status: StatusOK, BiddersEvaluated: []BidderEvaluation{{Bidder: "c", SyncerKey: "keyC", Status: StatusTypeNotSupported}}, @@ -136,11 +146,12 @@ func TestChooserChoose(t *testing.T) { { description: "Many Bidders - All Sync - Limit Disabled With 0", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + Privacy: &fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: 0, }, givenChosenBidders: []string{"a", "b"}, givenCookie: Cookie{}, + bidderNamesLookup: normalizedBidderNamesLookup, expected: Result{ Status: StatusOK, BiddersEvaluated: []BidderEvaluation{{Bidder: "a", SyncerKey: "keyA", Status: StatusOK}, {Bidder: "b", SyncerKey: "keyB", Status: StatusOK}}, @@ -150,11 +161,12 @@ func TestChooserChoose(t *testing.T) { { description: "Many Bidders - All Sync - Limit Disabled With Negative Value", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + Privacy: &fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: -1, }, givenChosenBidders: []string{"a", "b"}, givenCookie: Cookie{}, + bidderNamesLookup: normalizedBidderNamesLookup, expected: Result{ Status: StatusOK, BiddersEvaluated: []BidderEvaluation{{Bidder: "a", SyncerKey: "keyA", Status: StatusOK}, {Bidder: "b", SyncerKey: "keyB", Status: StatusOK}}, @@ -164,11 +176,12 @@ func TestChooserChoose(t *testing.T) { { description: "Many Bidders - Limited Sync", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + Privacy: &fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: 1, }, givenChosenBidders: []string{"a", "b"}, givenCookie: Cookie{}, + bidderNamesLookup: normalizedBidderNamesLookup, expected: Result{ Status: StatusOK, BiddersEvaluated: []BidderEvaluation{{Bidder: "a", SyncerKey: "keyA", Status: StatusOK}}, @@ -178,11 +191,12 @@ func TestChooserChoose(t *testing.T) { { description: "Many Bidders - Limited Sync - Disqualified Syncers Don't Count Towards Limit", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + Privacy: &fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: 1, }, givenChosenBidders: []string{"c", "a", "b"}, givenCookie: Cookie{}, + bidderNamesLookup: normalizedBidderNamesLookup, expected: Result{ Status: StatusOK, BiddersEvaluated: []BidderEvaluation{{Bidder: "c", SyncerKey: "keyC", Status: StatusTypeNotSupported}, {Bidder: "a", SyncerKey: "keyA", Status: StatusOK}}, @@ -192,17 +206,65 @@ func TestChooserChoose(t *testing.T) { { description: "Many Bidders - Some Sync, Some Don't", givenRequest: Request{ - Privacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + Privacy: &fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, Limit: 0, }, givenChosenBidders: []string{"a", "c"}, givenCookie: Cookie{}, + bidderNamesLookup: normalizedBidderNamesLookup, expected: Result{ Status: StatusOK, BiddersEvaluated: []BidderEvaluation{{Bidder: "a", SyncerKey: "keyA", Status: StatusOK}, {Bidder: "c", SyncerKey: "keyC", Status: StatusTypeNotSupported}}, SyncersChosen: []SyncerChoice{syncerChoiceA}, }, }, + { + description: "Unknown Bidder", + givenRequest: Request{ + Privacy: &fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + Limit: 0, + }, + givenChosenBidders: []string{"a"}, + givenCookie: Cookie{}, + bidderNamesLookup: func(name string) (openrtb_ext.BidderName, bool) { + return openrtb_ext.BidderName(name), false + }, + expected: Result{ + Status: StatusOK, + BiddersEvaluated: []BidderEvaluation{{Bidder: "a", Status: StatusUnknownBidder}}, + SyncersChosen: []SyncerChoice{}, + }, + }, + { + description: "Case insensitive bidder name", + givenRequest: Request{ + Privacy: &fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + Limit: 0, + }, + givenChosenBidders: []string{"AppNexus"}, + givenCookie: Cookie{}, + bidderNamesLookup: openrtb_ext.NormalizeBidderName, + expected: Result{ + Status: StatusOK, + BiddersEvaluated: []BidderEvaluation{{Bidder: "AppNexus", SyncerKey: "keyA", Status: StatusOK}}, + SyncersChosen: []SyncerChoice{{Bidder: "AppNexus", Syncer: fakeSyncerA}}, + }, + }, + { + description: "Duplicate bidder name", + givenRequest: Request{ + Privacy: &fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + Limit: 0, + }, + givenChosenBidders: []string{"AppNexus", "appNexus"}, + givenCookie: Cookie{}, + bidderNamesLookup: openrtb_ext.NormalizeBidderName, + expected: Result{ + Status: StatusOK, + BiddersEvaluated: []BidderEvaluation{{Bidder: "AppNexus", SyncerKey: "keyA", Status: StatusOK}, {Bidder: "appNexus", SyncerKey: "keyA", Status: StatusDuplicate}}, + SyncersChosen: []SyncerChoice{{Bidder: "AppNexus", Syncer: fakeSyncerA}}, + }, + }, } bidders := []string{"anyRequested"} @@ -219,9 +281,10 @@ func TestChooserChoose(t *testing.T) { Return(test.givenChosenBidders) chooser := standardChooser{ - bidderSyncerLookup: bidderSyncerLookup, - biddersAvailable: biddersAvailable, - bidderChooser: mockBidderChooser, + bidderSyncerLookup: bidderSyncerLookup, + biddersAvailable: biddersAvailable, + bidderChooser: mockBidderChooser, + normalizeValidBidderName: test.bidderNamesLookup, } result := chooser.Choose(test.givenRequest, &test.givenCookie) @@ -232,113 +295,199 @@ func TestChooserChoose(t *testing.T) { func TestChooserEvaluate(t *testing.T) { fakeSyncerA := fakeSyncer{key: "keyA", supportsIFrame: true} fakeSyncerB := fakeSyncer{key: "keyB", supportsIFrame: false} - bidderSyncerLookup := map[string]Syncer{"a": fakeSyncerA, "b": fakeSyncerB} + bidderSyncerLookup := map[string]Syncer{"a": fakeSyncerA, "b": fakeSyncerB, "appnexus": fakeSyncerA, "suntContent": fakeSyncerA} syncTypeFilter := SyncTypeFilter{ IFrame: NewUniformBidderFilter(BidderFilterModeInclude), Redirect: NewUniformBidderFilter(BidderFilterModeExclude)} - + normalizedBidderNamesLookup := func(name string) (openrtb_ext.BidderName, bool) { + return openrtb_ext.BidderName(name), true + } cookieNeedsSync := Cookie{} cookieAlreadyHasSyncForA := Cookie{uids: map[string]UIDEntry{"keyA": {Expires: time.Now().Add(time.Duration(24) * time.Hour)}}} cookieAlreadyHasSyncForB := Cookie{uids: map[string]UIDEntry{"keyB": {Expires: time.Now().Add(time.Duration(24) * time.Hour)}}} testCases := []struct { - description string - givenBidder string - givenSyncersSeen map[string]struct{} - givenPrivacy Privacy - givenCookie Cookie - expectedSyncer Syncer - expectedEvaluation BidderEvaluation + description string + givenBidder string + normalisedBidderName string + givenSyncersSeen map[string]struct{} + givenPrivacy fakePrivacy + givenCookie Cookie + givenSyncTypeFilter SyncTypeFilter + normalizedBidderNamesLookup func(name string) (openrtb_ext.BidderName, bool) + expectedSyncer Syncer + expectedEvaluation BidderEvaluation }{ { - description: "Valid", - givenBidder: "a", - givenSyncersSeen: map[string]struct{}{}, - givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, - givenCookie: cookieNeedsSync, - expectedSyncer: fakeSyncerA, - expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusOK}, + description: "Valid", + givenBidder: "a", + normalisedBidderName: "a", + givenSyncersSeen: map[string]struct{}{}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + givenCookie: cookieNeedsSync, + givenSyncTypeFilter: syncTypeFilter, + normalizedBidderNamesLookup: normalizedBidderNamesLookup, + expectedSyncer: fakeSyncerA, + expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusOK}, + }, + { + description: "Unknown Bidder", + givenBidder: "unknown", + normalisedBidderName: "", + givenSyncersSeen: map[string]struct{}{}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + givenCookie: cookieNeedsSync, + givenSyncTypeFilter: syncTypeFilter, + normalizedBidderNamesLookup: normalizedBidderNamesLookup, + expectedSyncer: nil, + expectedEvaluation: BidderEvaluation{Bidder: "unknown", Status: StatusUnknownBidder}, + }, + { + description: "Duplicate Syncer", + givenBidder: "a", + normalisedBidderName: "", + givenSyncersSeen: map[string]struct{}{"keyA": {}}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + givenCookie: cookieNeedsSync, + givenSyncTypeFilter: syncTypeFilter, + normalizedBidderNamesLookup: normalizedBidderNamesLookup, + expectedSyncer: nil, + expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusDuplicate}, + }, + { + description: "Incompatible Kind", + givenBidder: "b", + normalisedBidderName: "", + givenSyncersSeen: map[string]struct{}{}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + givenCookie: cookieNeedsSync, + givenSyncTypeFilter: syncTypeFilter, + normalizedBidderNamesLookup: normalizedBidderNamesLookup, + expectedSyncer: nil, + expectedEvaluation: BidderEvaluation{Bidder: "b", SyncerKey: "keyB", Status: StatusTypeNotSupported}, + }, + { + description: "Already Synced", + givenBidder: "a", + normalisedBidderName: "", + givenSyncersSeen: map[string]struct{}{}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + givenCookie: cookieAlreadyHasSyncForA, + givenSyncTypeFilter: syncTypeFilter, + normalizedBidderNamesLookup: normalizedBidderNamesLookup, + expectedSyncer: nil, + expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusAlreadySynced}, }, { - description: "Unknown Bidder", - givenBidder: "unknown", - givenSyncersSeen: map[string]struct{}{}, - givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, - givenCookie: cookieNeedsSync, - expectedSyncer: nil, - expectedEvaluation: BidderEvaluation{Bidder: "unknown", Status: StatusUnknownBidder}, + description: "Different Bidder Already Synced", + givenBidder: "a", + normalisedBidderName: "a", + givenSyncersSeen: map[string]struct{}{}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + givenCookie: cookieAlreadyHasSyncForB, + givenSyncTypeFilter: syncTypeFilter, + normalizedBidderNamesLookup: normalizedBidderNamesLookup, + expectedSyncer: fakeSyncerA, + expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusOK}, }, { - description: "Duplicate Syncer", - givenBidder: "a", - givenSyncersSeen: map[string]struct{}{"keyA": {}}, - givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, - givenCookie: cookieNeedsSync, - expectedSyncer: nil, - expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusDuplicate}, + description: "Blocked By GDPR", + givenBidder: "a", + normalisedBidderName: "a", + givenSyncersSeen: map[string]struct{}{}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: false, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + givenCookie: cookieNeedsSync, + givenSyncTypeFilter: syncTypeFilter, + normalizedBidderNamesLookup: normalizedBidderNamesLookup, + expectedSyncer: nil, + expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusBlockedByGDPR}, }, { - description: "Incompatible Kind", - givenBidder: "b", - givenSyncersSeen: map[string]struct{}{}, - givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, - givenCookie: cookieNeedsSync, - expectedSyncer: nil, - expectedEvaluation: BidderEvaluation{Bidder: "b", SyncerKey: "keyB", Status: StatusTypeNotSupported}, + description: "Blocked By CCPA", + givenBidder: "a", + normalisedBidderName: "a", + givenSyncersSeen: map[string]struct{}{}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: false, activityAllowUserSync: true}, + givenCookie: cookieNeedsSync, + givenSyncTypeFilter: syncTypeFilter, + normalizedBidderNamesLookup: normalizedBidderNamesLookup, + expectedSyncer: nil, + expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusBlockedByCCPA}, }, { - description: "Already Synced", - givenBidder: "a", - givenSyncersSeen: map[string]struct{}{}, - givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, - givenCookie: cookieAlreadyHasSyncForA, - expectedSyncer: nil, - expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusAlreadySynced}, + description: "Blocked By activity control", + givenBidder: "a", + normalisedBidderName: "", + givenSyncersSeen: map[string]struct{}{}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: false}, + givenCookie: cookieNeedsSync, + givenSyncTypeFilter: syncTypeFilter, + normalizedBidderNamesLookup: normalizedBidderNamesLookup, + expectedSyncer: nil, + expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusBlockedByPrivacy}, }, { - description: "Different Bidder Already Synced", - givenBidder: "a", - givenSyncersSeen: map[string]struct{}{}, - givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, - givenCookie: cookieAlreadyHasSyncForB, - expectedSyncer: fakeSyncerA, - expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusOK}, + description: "Case insensitive bidder name", + givenBidder: "AppNexus", + normalisedBidderName: "appnexus", + givenSyncersSeen: map[string]struct{}{}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + givenCookie: cookieNeedsSync, + givenSyncTypeFilter: syncTypeFilter, + normalizedBidderNamesLookup: openrtb_ext.NormalizeBidderName, + expectedSyncer: fakeSyncerA, + expectedEvaluation: BidderEvaluation{Bidder: "AppNexus", SyncerKey: "keyA", Status: StatusOK}, }, { - description: "Blocked By GDPR", - givenBidder: "a", - givenSyncersSeen: map[string]struct{}{}, - givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: false, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, - givenCookie: cookieNeedsSync, - expectedSyncer: nil, - expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusBlockedByGDPR}, + description: "Case insensitivity check for sync type filter", + givenBidder: "SuntContent", + normalisedBidderName: "suntContent", + givenSyncersSeen: map[string]struct{}{}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + givenCookie: cookieNeedsSync, + givenSyncTypeFilter: SyncTypeFilter{ + IFrame: NewSpecificBidderFilter([]string{"SuntContent"}, BidderFilterModeInclude), + Redirect: NewSpecificBidderFilter([]string{"SuntContent"}, BidderFilterModeExclude)}, + normalizedBidderNamesLookup: openrtb_ext.NormalizeBidderName, + expectedSyncer: fakeSyncerA, + expectedEvaluation: BidderEvaluation{Bidder: "SuntContent", SyncerKey: "keyA", Status: StatusOK}, }, { - description: "Blocked By CCPA", - givenBidder: "a", - givenSyncersSeen: map[string]struct{}{}, - givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: false, activityAllowUserSync: true}, - givenCookie: cookieNeedsSync, - expectedSyncer: nil, - expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusBlockedByCCPA}, + description: "Case Insensitivity Check For Blocked By GDPR", + givenBidder: "AppNexus", + normalisedBidderName: "appnexus", + givenSyncersSeen: map[string]struct{}{}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: false, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + givenCookie: cookieNeedsSync, + givenSyncTypeFilter: syncTypeFilter, + normalizedBidderNamesLookup: openrtb_ext.NormalizeBidderName, + expectedSyncer: nil, + expectedEvaluation: BidderEvaluation{Bidder: "AppNexus", SyncerKey: "keyA", Status: StatusBlockedByGDPR}, }, { - description: "Blocked By activity control", - givenBidder: "a", - givenSyncersSeen: map[string]struct{}{}, - givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: false}, - givenCookie: cookieNeedsSync, - expectedSyncer: nil, - expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusBlockedByPrivacy}, + description: "Case Insensitivity Check For Blocked By CCPA", + givenBidder: "AppNexus", + normalisedBidderName: "appnexus", + givenSyncersSeen: map[string]struct{}{}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: false, activityAllowUserSync: true}, + givenCookie: cookieNeedsSync, + givenSyncTypeFilter: syncTypeFilter, + normalizedBidderNamesLookup: openrtb_ext.NormalizeBidderName, + expectedSyncer: nil, + expectedEvaluation: BidderEvaluation{Bidder: "AppNexus", SyncerKey: "keyA", Status: StatusBlockedByCCPA}, }, } for _, test := range testCases { - chooser, _ := NewChooser(bidderSyncerLookup).(standardChooser) - sync, evaluation := chooser.evaluate(test.givenBidder, test.givenSyncersSeen, syncTypeFilter, test.givenPrivacy, &test.givenCookie) + t.Run(test.description, func(t *testing.T) { + chooser, _ := NewChooser(bidderSyncerLookup).(standardChooser) + chooser.normalizeValidBidderName = test.normalizedBidderNamesLookup + sync, evaluation := chooser.evaluate(test.givenBidder, test.givenSyncersSeen, test.givenSyncTypeFilter, &test.givenPrivacy, &test.givenCookie) - assert.Equal(t, test.expectedSyncer, sync, test.description+":syncer") - assert.Equal(t, test.expectedEvaluation, evaluation, test.description+":evaluation") + assert.Equal(t, test.normalisedBidderName, test.givenPrivacy.inputBidderName) + assert.Equal(t, test.expectedSyncer, sync, test.description+":syncer") + assert.Equal(t, test.expectedEvaluation, evaluation, test.description+":evaluation") + }) } } @@ -386,20 +535,23 @@ type fakePrivacy struct { gdprAllowsBidderSync bool ccpaAllowsBidderSync bool activityAllowUserSync bool + inputBidderName string } -func (p fakePrivacy) GDPRAllowsHostCookie() bool { +func (p *fakePrivacy) GDPRAllowsHostCookie() bool { return p.gdprAllowsHostCookie } -func (p fakePrivacy) GDPRAllowsBidderSync(bidder string) bool { +func (p *fakePrivacy) GDPRAllowsBidderSync(bidder string) bool { + p.inputBidderName = bidder return p.gdprAllowsBidderSync } -func (p fakePrivacy) CCPAAllowsBidderSync(bidder string) bool { +func (p *fakePrivacy) CCPAAllowsBidderSync(bidder string) bool { + p.inputBidderName = bidder return p.ccpaAllowsBidderSync } -func (p fakePrivacy) ActivityAllowsUserSync(bidder string) bool { +func (p *fakePrivacy) ActivityAllowsUserSync(bidder string) bool { return p.activityAllowUserSync } From b3e5d1d062507d071cd7833af2d91d2e118d4038 Mon Sep 17 00:00:00 2001 From: Sonali-More-Xandr <87759626+Sonali-More-Xandr@users.noreply.github.com> Date: Tue, 17 Oct 2023 20:42:02 +0530 Subject: [PATCH 177/268] Adapter Name Case Insensitive: user.ext.prebid.buyeruids (#3152) --- endpoints/openrtb2/amp_auction_test.go | 3 + endpoints/openrtb2/auction.go | 4 +- .../aliased-buyeruids-case-insensitive.json | 84 ++++++++++ .../buyeruids-camel-case.json | 77 ++++++++++ .../buyeruids-case-insensitive.json | 77 ++++++++++ .../buyeruid_case_insensitive.json | 144 ++++++++++++++++++ exchange/utils.go | 10 +- 7 files changed, 396 insertions(+), 3 deletions(-) create mode 100644 endpoints/openrtb2/sample-requests/amp/valid-supplementary/aliased-buyeruids-case-insensitive.json create mode 100644 endpoints/openrtb2/sample-requests/amp/valid-supplementary/buyeruids-camel-case.json create mode 100644 endpoints/openrtb2/sample-requests/amp/valid-supplementary/buyeruids-case-insensitive.json create mode 100644 exchange/exchangetest/buyeruid_case_insensitive.json diff --git a/endpoints/openrtb2/amp_auction_test.go b/endpoints/openrtb2/amp_auction_test.go index 3c0feb4f7ab..4315ec7926f 100644 --- a/endpoints/openrtb2/amp_auction_test.go +++ b/endpoints/openrtb2/amp_auction_test.go @@ -50,6 +50,9 @@ func TestGoodAmpRequests(t *testing.T) { "imp-with-stored-resp.json", "gdpr-no-consentstring.json", "gdpr.json", + "buyeruids-case-insensitive.json", + "buyeruids-camel-case.json", + "aliased-buyeruids-case-insensitive.json", }, }, { diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 3a929c43abe..fdb135497d0 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -1817,7 +1817,9 @@ func (deps *endpointDeps) validateUser(req *openrtb_ext.RequestWrapper, aliases return append(errL, errors.New(`request.user.ext.prebid requires a "buyeruids" property with at least one ID defined. If none exist, then request.user.ext.prebid should not be defined.`)) } for bidderName := range prebid.BuyerUIDs { - if _, ok := deps.bidderMap[bidderName]; !ok { + normalizedCoreBidder, _ := deps.normalizeBidderName(bidderName) + coreBidder := normalizedCoreBidder.String() + if _, ok := deps.bidderMap[coreBidder]; !ok { if _, ok := aliases[bidderName]; !ok { return append(errL, fmt.Errorf("request.user.ext.%s is neither a known bidder name nor an alias in request.ext.prebid.aliases", bidderName)) } diff --git a/endpoints/openrtb2/sample-requests/amp/valid-supplementary/aliased-buyeruids-case-insensitive.json b/endpoints/openrtb2/sample-requests/amp/valid-supplementary/aliased-buyeruids-case-insensitive.json new file mode 100644 index 00000000000..1d2462c98b8 --- /dev/null +++ b/endpoints/openrtb2/sample-requests/amp/valid-supplementary/aliased-buyeruids-case-insensitive.json @@ -0,0 +1,84 @@ +{ + "description": "Amp request where root.user.ext.prebid.buyeruids field makes use of alias defined in root.ext.prebid.aliases and request makes use of case sensitive bidder name", + "query": "tag_id=101", + "config": { + "mockBidders": [ + { + "bidderName": "appnexus", + "currency": "USD", + "price": 2 + } + ] + }, + "mockBidRequest": { + "id": "request-with-user-ext-obj", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "my-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "prebid": { + "bidder": { + "Appnexus": { + "placementId": 12883451 + } + } + } + } + } + ], + "user": { + "ext": { + "prebid": { + "buyeruids": { + "unknown": "123" + } + } + } + }, + "ext": { + "prebid": { + "aliases": { + "unknown": "Appnexus" + } + } + } + }, + "expectedAmpResponse": { + "targeting": { + "hb_bidder": "Appnexus", + "hb_bidder_Appnexus": "Appnexus", + "hb_cache_host": "www.pbcserver.com", + "hb_cache_host_Appnex": "www.pbcserver.com", + "hb_cache_id": "0", + "hb_cache_id_Appnexus": "0", + "hb_cache_path": "/pbcache/endpoint", + "hb_cache_path_Appnex": "/pbcache/endpoint", + "hb_pb": "2.00", + "hb_pb_Appnexus": "2.00" + }, + "ortb2": { + "ext": { + "warnings": { + "general": [ + { + "code": 10002, + "message": "debug turned off for account" + } + ] + } + } + } + }, + "expectedReturnCode": 200 +} \ No newline at end of file diff --git a/endpoints/openrtb2/sample-requests/amp/valid-supplementary/buyeruids-camel-case.json b/endpoints/openrtb2/sample-requests/amp/valid-supplementary/buyeruids-camel-case.json new file mode 100644 index 00000000000..4597fe7786a --- /dev/null +++ b/endpoints/openrtb2/sample-requests/amp/valid-supplementary/buyeruids-camel-case.json @@ -0,0 +1,77 @@ +{ + "description": "Amp request where root.user.ext.prebid.buyeruids field has camel case bidder name", + "query": "tag_id=101", + "config": { + "mockBidders": [ + { + "bidderName": "yahooAds", + "currency": "USD", + "price": 2 + } + ] + }, + "mockBidRequest": { + "id": "request-with-user-ext-obj", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "my-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "prebid": { + "bidder": { + "YahooAds": { + "placementId": 12883451 + } + } + } + } + } + ], + "user": { + "ext": { + "prebid": { + "buyeruids": { + "YahooAds": "123" + } + } + } + } + }, + "expectedAmpResponse": { + "targeting": { + "hb_bidder": "YahooAds", + "hb_bidder_YahooAds": "YahooAds", + "hb_cache_host": "www.pbcserver.com", + "hb_cache_host_YahooA": "www.pbcserver.com", + "hb_cache_id": "0", + "hb_cache_id_YahooAds": "0", + "hb_cache_path": "/pbcache/endpoint", + "hb_cache_path_YahooA": "/pbcache/endpoint", + "hb_pb": "2.00", + "hb_pb_YahooAds": "2.00" + }, + "ortb2": { + "ext": { + "warnings": { + "general": [ + { + "code": 10002, + "message": "debug turned off for account" + } + ] + } + } + } + }, + "expectedReturnCode": 200 +} \ No newline at end of file diff --git a/endpoints/openrtb2/sample-requests/amp/valid-supplementary/buyeruids-case-insensitive.json b/endpoints/openrtb2/sample-requests/amp/valid-supplementary/buyeruids-case-insensitive.json new file mode 100644 index 00000000000..976fcb3cf7f --- /dev/null +++ b/endpoints/openrtb2/sample-requests/amp/valid-supplementary/buyeruids-case-insensitive.json @@ -0,0 +1,77 @@ +{ + "description": "Amp request where root.user.ext.prebid.buyeruids field has case insensitive bidder name", + "query": "tag_id=101", + "config": { + "mockBidders": [ + { + "bidderName": "appnexus", + "currency": "USD", + "price": 2 + } + ] + }, + "mockBidRequest": { + "id": "request-with-user-ext-obj", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "my-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "prebid": { + "bidder": { + "Appnexus": { + "placementId": 12883451 + } + } + } + } + } + ], + "user": { + "ext": { + "prebid": { + "buyeruids": { + "Appnexus": "123" + } + } + } + } + }, + "expectedAmpResponse": { + "targeting": { + "hb_bidder": "Appnexus", + "hb_bidder_Appnexus": "Appnexus", + "hb_cache_host": "www.pbcserver.com", + "hb_cache_host_Appnex": "www.pbcserver.com", + "hb_cache_id": "0", + "hb_cache_id_Appnexus": "0", + "hb_cache_path": "/pbcache/endpoint", + "hb_cache_path_Appnex": "/pbcache/endpoint", + "hb_pb": "2.00", + "hb_pb_Appnexus": "2.00" + }, + "ortb2": { + "ext": { + "warnings": { + "general": [ + { + "code": 10002, + "message": "debug turned off for account" + } + ] + } + } + } + }, + "expectedReturnCode": 200 +} \ No newline at end of file diff --git a/exchange/exchangetest/buyeruid_case_insensitive.json b/exchange/exchangetest/buyeruid_case_insensitive.json new file mode 100644 index 00000000000..6999e8c9515 --- /dev/null +++ b/exchange/exchangetest/buyeruid_case_insensitive.json @@ -0,0 +1,144 @@ +{ + "incomingRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "user": { + "id": "userId", + "ext": { + "prebid": { + "buyeruids": { + "APPnexUS": "12345" + } + } + } + }, + "imp": [ + { + "id": "my-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "prebid": { + "bidder": { + "APPnexus": { + "placementId": 1 + }, + "appNEXUS": { + "placementId": 2 + }, + "amx": {} + } + } + } + } + ], + "ext": { + "prebid": { + "aliases": { + "APPnexus": "appnexus", + "appNEXUS": "appnexus" + } + } + } + } + }, + "outgoingRequests": { + "APPnexus": { + "expectRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "user": { + "id": "userId", + "buyeruid": "12345" + }, + "imp": [ + { + "id": "my-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "placementId": 1 + } + } + } + ] + } + } + }, + "appNEXUS": { + "expectRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "user": { + "id": "userId", + "buyeruid": "12345" + }, + "imp": [ + { + "id": "my-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "placementId": 2 + } + } + } + ] + } + } + }, + "amx": { + "expectRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "user": { + "id": "userId" + }, + "imp": [ + { + "id": "my-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + } + } + } + ] + } + } + } + }, + "response": { + "bids": { + "id": "some-request-id", + "ext": {} + } + } +} diff --git a/exchange/utils.go b/exchange/utils.go index 0d9c90cda99..7d5beb64fb0 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -327,6 +327,12 @@ func getAuctionBidderRequests(auctionRequest AuctionRequest, return nil, []error{err} } + lowerCaseExplicitBuyerUIDs := make(map[string]string) + for bidder, uid := range explicitBuyerUIDs { + lowerKey := strings.ToLower(bidder) + lowerCaseExplicitBuyerUIDs[lowerKey] = uid + } + var errs []error for bidder, imps := range impsByBidder { coreBidder := resolveBidder(bidder, aliases) @@ -361,7 +367,7 @@ func getAuctionBidderRequests(auctionRequest AuctionRequest, } syncerKey := bidderToSyncerKey[string(coreBidder)] - if hadSync := prepareUser(&reqCopy, bidder, syncerKey, explicitBuyerUIDs, auctionRequest.UserSyncs); !hadSync && req.BidRequest.App == nil { + if hadSync := prepareUser(&reqCopy, bidder, syncerKey, lowerCaseExplicitBuyerUIDs, auctionRequest.UserSyncs); !hadSync && req.BidRequest.App == nil { bidderRequest.BidderLabels.CookieFlag = metrics.CookieFlagNo } else { bidderRequest.BidderLabels.CookieFlag = metrics.CookieFlagYes @@ -642,7 +648,7 @@ func createSanitizedImpExt(impExt, impExtPrebid map[string]json.RawMessage) (map func prepareUser(req *openrtb2.BidRequest, givenBidder, syncerKey string, explicitBuyerUIDs map[string]string, usersyncs IdFetcher) bool { cookieId, hadCookie, _ := usersyncs.GetUID(syncerKey) - if id, ok := explicitBuyerUIDs[givenBidder]; ok { + if id, ok := explicitBuyerUIDs[strings.ToLower(givenBidder)]; ok { req.User = copyWithBuyerUID(req.User, id) } else if hadCookie { req.User = copyWithBuyerUID(req.User, cookieId) From f152b0d3bbfe624c39d2512d3146484bfc7a4e1e Mon Sep 17 00:00:00 2001 From: AlexBVolcy <74930484+AlexBVolcy@users.noreply.github.com> Date: Tue, 17 Oct 2023 08:24:37 -0700 Subject: [PATCH 178/268] Adapter Name Case Insensitive: Bid Adjustment Factors (#3210) --- endpoints/openrtb2/auction.go | 7 ++ ...actors-case-invalid-same-bidder-names.json | 81 ++++++++++++++++ ...ors-case-insensitive-different-casing.json | 97 +++++++++++++++++++ ... => bid-adj-factors-case-insensitive.json} | 0 exchange/bidder.go | 4 +- exchange/bidder_test.go | 14 +-- exchange/utils.go | 8 +- exchange/utils_test.go | 5 + 8 files changed, 205 insertions(+), 11 deletions(-) create mode 100644 endpoints/openrtb2/sample-requests/invalid-whole/bid-adj-factors-case-invalid-same-bidder-names.json create mode 100644 endpoints/openrtb2/sample-requests/valid-whole/exemplary/bid-adj-factors-case-insensitive-different-casing.json rename endpoints/openrtb2/sample-requests/valid-whole/exemplary/{bidder-adjustment-factors-case-insensitive.json => bid-adj-factors-case-insensitive.json} (100%) diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index fdb135497d0..0e1a23583a1 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -965,6 +965,7 @@ func validateAndFillSourceTID(req *openrtb_ext.RequestWrapper, generateRequestID } func (deps *endpointDeps) validateBidAdjustmentFactors(adjustmentFactors map[string]float64, aliases map[string]string) error { + uniqueBidders := make(map[string]struct{}) for bidderToAdjust, adjustmentFactor := range adjustmentFactors { if adjustmentFactor <= 0 { return fmt.Errorf("request.ext.prebid.bidadjustmentfactors.%s must be a positive number. Got %f", bidderToAdjust, adjustmentFactor) @@ -976,6 +977,12 @@ func (deps *endpointDeps) validateBidAdjustmentFactors(adjustmentFactors map[str bidderName = normalizedCoreBidder.String() } + if _, exists := uniqueBidders[bidderName]; exists { + return fmt.Errorf("cannot have multiple bidders that differ only in case style") + } else { + uniqueBidders[bidderName] = struct{}{} + } + if _, isBidder := deps.bidderMap[bidderName]; !isBidder { if _, isAlias := aliases[bidderToAdjust]; !isAlias { return fmt.Errorf("request.ext.prebid.bidadjustmentfactors.%s is not a known bidder or alias", bidderToAdjust) diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/bid-adj-factors-case-invalid-same-bidder-names.json b/endpoints/openrtb2/sample-requests/invalid-whole/bid-adj-factors-case-invalid-same-bidder-names.json new file mode 100644 index 00000000000..d484f129ba3 --- /dev/null +++ b/endpoints/openrtb2/sample-requests/invalid-whole/bid-adj-factors-case-invalid-same-bidder-names.json @@ -0,0 +1,81 @@ +{ + "description": "This demonstrates a request with bidadjustmentfactors that have multiple of the same bidder is invalid request", + "config": { + "mockBidders": [ + { + "bidderName": "appnexus", + "currency": "USD", + "price": 1.00 + } + ] + }, + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "ext": { + "consent": "gdpr-consent-string" + } + }, + "regs": { + "ext": { + "gdpr": 1, + "us_privacy": "1NYN" + } + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "Appnexus": { + "placementId": 12883451 + } + } + } + ], + "tmax": 500, + "ext": { + "prebid": { + "bidadjustmentfactors": { + "APPNEXUS": 1.01, + "Appnexus": 2.00 + }, + "cache": { + "bids": {} + }, + "channel": { + "name": "video", + "version": "1.0" + }, + "targeting": { + "includewinners": false, + "pricegranularity": { + "precision": 2, + "ranges": [ + { + "max": 20, + "increment": 0.10 + } + ] + } + } + } + } + }, + "expectedReturnCode": 400, + "expectedErrorMessage": "Invalid request: cannot have multiple bidders that differ only in case style" +} \ No newline at end of file diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/bid-adj-factors-case-insensitive-different-casing.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/bid-adj-factors-case-insensitive-different-casing.json new file mode 100644 index 00000000000..a231af657cd --- /dev/null +++ b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/bid-adj-factors-case-insensitive-different-casing.json @@ -0,0 +1,97 @@ +{ + "description": "This demonstrates bid adjustment factors with bidder names that have different casing in imp vs. in bidadjustmentfactors", + "config": { + "mockBidders": [ + { + "bidderName": "appnexus", + "currency": "USD", + "price": 1.00 + } + ] + }, + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "ext": { + "consent": "gdpr-consent-string" + } + }, + "regs": { + "ext": { + "gdpr": 1, + "us_privacy": "1NYN" + } + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "Appnexus": { + "placementId": 12883451 + } + } + } + ], + "tmax": 500, + "ext": { + "prebid": { + "bidadjustmentfactors": { + "APPNEXUS": 1.01 + }, + "cache": { + "bids": {} + }, + "channel": { + "name": "video", + "version": "1.0" + }, + "targeting": { + "includewinners": false, + "pricegranularity": { + "precision": 2, + "ranges": [ + { + "max": 20, + "increment": 0.10 + } + ] + } + } + } + } + }, + "expectedBidResponse": { + "id": "some-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "appnexus-bid", + "impid": "some-impression-id", + "price": 1.01 + } + ], + "seat": "Appnexus" + } + ], + "bidid": "test bid id", + "cur": "USD", + "nbr": 0 + }, + "expectedReturnCode": 200 +} \ No newline at end of file diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/bidder-adjustment-factors-case-insensitive.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/bid-adj-factors-case-insensitive.json similarity index 100% rename from endpoints/openrtb2/sample-requests/valid-whole/exemplary/bidder-adjustment-factors-case-insensitive.json rename to endpoints/openrtb2/sample-requests/valid-whole/exemplary/bid-adj-factors-case-insensitive.json diff --git a/exchange/bidder.go b/exchange/bidder.go index dfdb7cdf85f..40135787b25 100644 --- a/exchange/bidder.go +++ b/exchange/bidder.go @@ -348,9 +348,9 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest Bidde } adjustmentFactor := 1.0 - if givenAdjustment, ok := bidRequestOptions.bidAdjustments[bidderName.String()]; ok { + if givenAdjustment, ok := bidRequestOptions.bidAdjustments[(strings.ToLower(bidderName.String()))]; ok { adjustmentFactor = givenAdjustment - } else if givenAdjustment, ok := bidRequestOptions.bidAdjustments[bidderRequest.BidderName.String()]; ok { + } else if givenAdjustment, ok := bidRequestOptions.bidAdjustments[(strings.ToLower(bidderRequest.BidderName.String()))]; ok { adjustmentFactor = givenAdjustment } diff --git a/exchange/bidder_test.go b/exchange/bidder_test.go index 65f6b795247..09c811ba9c6 100644 --- a/exchange/bidder_test.go +++ b/exchange/bidder_test.go @@ -2672,7 +2672,7 @@ func TestExtraBidWithBidAdjustments(t *testing.T) { }, BidType: openrtb_ext.BidTypeBanner, DealPriority: 4, - Seat: "pubmatic", + Seat: "PUBMATIC", }, { Bid: &openrtb2.Bid{ @@ -2699,7 +2699,7 @@ func TestExtraBidWithBidAdjustments(t *testing.T) { BidType: openrtb_ext.BidTypeVideo, OriginalBidCPM: 7, OriginalBidCur: "USD", - BidMeta: &openrtb_ext.ExtBidPrebidMeta{AdapterCode: string(openrtb_ext.BidderPubmatic)}, + BidMeta: &openrtb_ext.ExtBidPrebidMeta{AdapterCode: "PUBMATIC"}, }}, Seat: "groupm", Currency: "USD", @@ -2715,9 +2715,9 @@ func TestExtraBidWithBidAdjustments(t *testing.T) { BidType: openrtb_ext.BidTypeBanner, OriginalBidCur: "USD", OriginalBidCPM: 3, - BidMeta: &openrtb_ext.ExtBidPrebidMeta{AdapterCode: string(openrtb_ext.BidderPubmatic)}, + BidMeta: &openrtb_ext.ExtBidPrebidMeta{AdapterCode: "PUBMATIC"}, }}, - Seat: string(openrtb_ext.BidderPubmatic), + Seat: "PUBMATIC", Currency: "USD", }, } @@ -2727,10 +2727,10 @@ func TestExtraBidWithBidAdjustments(t *testing.T) { bidderReq := BidderRequest{ BidRequest: &openrtb2.BidRequest{Imp: []openrtb2.Imp{{ID: "impId"}}}, - BidderName: openrtb_ext.BidderPubmatic, + BidderName: "PUBMATIC", } bidAdjustments := map[string]float64{ - string(openrtb_ext.BidderPubmatic): 2, + string(openrtb_ext.BidderPubmatic): 2, // All lowercase value in bid adjustments to simulate it being case insensitive "groupm": 3, } @@ -2745,7 +2745,7 @@ func TestExtraBidWithBidAdjustments(t *testing.T) { openrtb_ext.ExtAlternateBidderCodes{ Enabled: true, Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{ - string(openrtb_ext.BidderPubmatic): { + "PUBMATIC": { Enabled: true, AllowedBidderCodes: []string{"groupm"}, }, diff --git a/exchange/utils.go b/exchange/utils.go index 7d5beb64fb0..4fe9af12ff3 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -899,8 +899,12 @@ func parseRequestDebugValues(test int8, requestExtPrebid *openrtb_ext.ExtRequest } func getExtBidAdjustmentFactors(requestExtPrebid *openrtb_ext.ExtRequestPrebid) map[string]float64 { - if requestExtPrebid != nil { - return requestExtPrebid.BidAdjustmentFactors + if requestExtPrebid != nil && requestExtPrebid.BidAdjustmentFactors != nil { + caseInsensitiveMap := make(map[string]float64, len(requestExtPrebid.BidAdjustmentFactors)) + for bidder, bidAdjFactor := range requestExtPrebid.BidAdjustmentFactors { + caseInsensitiveMap[strings.ToLower(bidder)] = bidAdjFactor + } + return caseInsensitiveMap } return nil } diff --git a/exchange/utils_test.go b/exchange/utils_test.go index 0dbf5b38e5c..a1e71b30c23 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -1834,6 +1834,11 @@ func TestGetExtBidAdjustmentFactors(t *testing.T) { requestExtPrebid: &openrtb_ext.ExtRequestPrebid{BidAdjustmentFactors: map[string]float64{"bid-factor": 1.0}}, outBidAdjustmentFactors: map[string]float64{"bid-factor": 1.0}, }, + { + desc: "BidAdjustmentFactors contains uppercase bidders, expect case insensitve map returned", + requestExtPrebid: &openrtb_ext.ExtRequestPrebid{BidAdjustmentFactors: map[string]float64{"Bidder": 1.0, "APPNEXUS": 2.0}}, + outBidAdjustmentFactors: map[string]float64{"bidder": 1.0, "appnexus": 2.0}, + }, } for _, test := range testCases { actualBidAdjustmentFactors := getExtBidAdjustmentFactors(test.requestExtPrebid) From 17109ca1a600463f4ba18da6ab2bee43cf88c020 Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Tue, 17 Oct 2023 23:42:12 -0400 Subject: [PATCH 179/268] Welcome Back: yeahmobi (#3228) --- adapters/yeahmobi/params_test.go | 47 +++++ adapters/yeahmobi/yeahmobi.go | 189 ++++++++++++++++++ adapters/yeahmobi/yeahmobi_test.go | 28 +++ .../yeahmobitest/exemplary/no-bid.json | 51 +++++ .../yeahmobitest/exemplary/simple-banner.json | 81 ++++++++ .../exemplary/simple-native-1.1.json | 82 ++++++++ .../yeahmobitest/exemplary/simple-native.json | 82 ++++++++ .../yeahmobitest/exemplary/simple-video.json | 89 +++++++++ .../supplemental/bad_imp_ext.json | 21 ++ .../supplemental/bad_imp_ext_bidder.json | 23 +++ .../supplemental/bad_response.json | 55 +++++ .../yeahmobitest/supplemental/status_400.json | 55 +++++ .../yeahmobitest/supplemental/status_500.json | 55 +++++ exchange/adapter_builders.go | 2 + exchange/adapter_util.go | 1 - openrtb_ext/bidders.go | 2 + openrtb_ext/imp_yeahmobi.go | 7 + static/bidder-info/yeahmobi.yaml | 9 + static/bidder-params/yeahmobi.json | 21 ++ 19 files changed, 899 insertions(+), 1 deletion(-) create mode 100644 adapters/yeahmobi/params_test.go create mode 100644 adapters/yeahmobi/yeahmobi.go create mode 100644 adapters/yeahmobi/yeahmobi_test.go create mode 100644 adapters/yeahmobi/yeahmobitest/exemplary/no-bid.json create mode 100644 adapters/yeahmobi/yeahmobitest/exemplary/simple-banner.json create mode 100644 adapters/yeahmobi/yeahmobitest/exemplary/simple-native-1.1.json create mode 100644 adapters/yeahmobi/yeahmobitest/exemplary/simple-native.json create mode 100644 adapters/yeahmobi/yeahmobitest/exemplary/simple-video.json create mode 100644 adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext.json create mode 100644 adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext_bidder.json create mode 100644 adapters/yeahmobi/yeahmobitest/supplemental/bad_response.json create mode 100644 adapters/yeahmobi/yeahmobitest/supplemental/status_400.json create mode 100644 adapters/yeahmobi/yeahmobitest/supplemental/status_500.json create mode 100644 openrtb_ext/imp_yeahmobi.go create mode 100644 static/bidder-info/yeahmobi.yaml create mode 100644 static/bidder-params/yeahmobi.json diff --git a/adapters/yeahmobi/params_test.go b/adapters/yeahmobi/params_test.go new file mode 100644 index 00000000000..997bf93a53f --- /dev/null +++ b/adapters/yeahmobi/params_test.go @@ -0,0 +1,47 @@ +package yeahmobi + +import ( + "encoding/json" + "github.com/prebid/prebid-server/openrtb_ext" + "testing" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderYeahmobi, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected yeahmobi params: %s", validParam) + } + } +} + +// TestInvalidParams makes sure that the yeahmobi schema rejects all the imp.ext fields we don't support. +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderYeahmobi, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{"pubId": "11233", "zoneId": "sin"}`, + `{"pubId": "11244", "zoneId": "iad"}`, +} + +var invalidParams = []string{ + `{"pubId": "11233"}`, + `{"zoneId": "aaa"}`, + `{"pubId": 123, "zoneId": "sin"}`, + `{"pubId": "", "zoneId": "iad"}`, + `{"pubId": "11233", "zoneId": ""}`, +} diff --git a/adapters/yeahmobi/yeahmobi.go b/adapters/yeahmobi/yeahmobi.go new file mode 100644 index 00000000000..ede25387ce2 --- /dev/null +++ b/adapters/yeahmobi/yeahmobi.go @@ -0,0 +1,189 @@ +package yeahmobi + +import ( + "encoding/json" + "fmt" + "net/http" + "net/url" + "text/template" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/macros" + "github.com/prebid/prebid-server/openrtb_ext" +) + +type adapter struct { + EndpointTemplate *template.Template +} + +// Builder builds a new instance of the Yeahmobi adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + template, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) + } + + bidder := &adapter{ + EndpointTemplate: template, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var adapterRequests []*adapters.RequestData + + adapterRequest, errs := a.makeRequest(request) + if errs == nil { + adapterRequests = append(adapterRequests, adapterRequest) + } + + return adapterRequests, errs +} + +func (a *adapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, []error) { + var errs []error + + yeahmobiExt, errs := getYeahmobiExt(request) + + if yeahmobiExt == nil { + return nil, errs + } + endPoint, err := a.getEndpoint(yeahmobiExt) + if err != nil { + return nil, append(errs, err) + } + transform(request) + reqBody, err := json.Marshal(request) + + if err != nil { + return nil, append(errs, err) + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + + return &adapters.RequestData{ + Method: "POST", + Uri: endPoint, + Body: reqBody, + Headers: headers, + }, errs +} + +func transform(request *openrtb2.BidRequest) { + for i, imp := range request.Imp { + if imp.Native != nil { + var nativeRequest map[string]interface{} + nativeCopyRequest := make(map[string]interface{}) + err := json.Unmarshal([]byte(request.Imp[i].Native.Request), &nativeRequest) + //just ignore the bad native request + if err == nil { + _, exists := nativeRequest["native"] + if exists { + continue + } + + nativeCopyRequest["native"] = nativeRequest + nativeReqByte, err := json.Marshal(nativeCopyRequest) + //just ignore the bad native request + if err != nil { + continue + } + + nativeCopy := *request.Imp[i].Native + nativeCopy.Request = string(nativeReqByte) + request.Imp[i].Native = &nativeCopy + } + } + } +} + +func getYeahmobiExt(request *openrtb2.BidRequest) (*openrtb_ext.ExtImpYeahmobi, []error) { + var extImpYeahmobi openrtb_ext.ExtImpYeahmobi + var errs []error + + for _, imp := range request.Imp { + var extBidder adapters.ExtImpBidder + err := json.Unmarshal(imp.Ext, &extBidder) + if err != nil { + errs = append(errs, err) + continue + } + err = json.Unmarshal(extBidder.Bidder, &extImpYeahmobi) + if err != nil { + errs = append(errs, err) + continue + } + break + } + + return &extImpYeahmobi, errs + +} + +func (a *adapter) getEndpoint(ext *openrtb_ext.ExtImpYeahmobi) (string, error) { + return macros.ResolveMacros(a.EndpointTemplate, macros.EndpointTemplateParams{Host: "gw-" + url.QueryEscape(ext.ZoneId) + "-bid.yeahtargeter.com"}) +} + +// MakeBids make the bids for the bid response. +func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if response.StatusCode == http.StatusNoContent { + return nil, nil + } + + if response.StatusCode == http.StatusBadRequest { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Unexpected status code: %d.", response.StatusCode), + }} + } + + if response.StatusCode != http.StatusOK { + return nil, []error{&errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unexpected status code: %d.", response.StatusCode), + }} + } + + var bidResp openrtb2.BidResponse + + if err := json.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(1) + + for _, sb := range bidResp.SeatBid { + for i := range sb.Bid { + var mediaType = getBidType(sb.Bid[i].ImpID, internalRequest.Imp) + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &sb.Bid[i], + BidType: mediaType, + }) + } + } + return bidResponse, nil + +} + +func getBidType(impId string, imps []openrtb2.Imp) openrtb_ext.BidType { + bidType := openrtb_ext.BidTypeBanner + for _, imp := range imps { + if imp.ID == impId { + if imp.Banner != nil { + break + } + if imp.Video != nil { + bidType = openrtb_ext.BidTypeVideo + break + } + if imp.Native != nil { + bidType = openrtb_ext.BidTypeNative + break + } + + } + } + return bidType +} diff --git a/adapters/yeahmobi/yeahmobi_test.go b/adapters/yeahmobi/yeahmobi_test.go new file mode 100644 index 00000000000..0b1c39ef214 --- /dev/null +++ b/adapters/yeahmobi/yeahmobi_test.go @@ -0,0 +1,28 @@ +package yeahmobi + +import ( + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderYeahmobi, config.Adapter{ + Endpoint: "https://{{.Host}}/prebid/bid"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "yeahmobitest", bidder) +} + +func TestEndpointTemplateMalformed(t *testing.T) { + _, buildErr := Builder(openrtb_ext.BidderYeahmobi, config.Adapter{ + Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + assert.Error(t, buildErr) +} diff --git a/adapters/yeahmobi/yeahmobitest/exemplary/no-bid.json b/adapters/yeahmobi/yeahmobitest/exemplary/no-bid.json new file mode 100644 index 00000000000..723cc40e664 --- /dev/null +++ b/adapters/yeahmobi/yeahmobitest/exemplary/no-bid.json @@ -0,0 +1,51 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 50}] + }, + "ext": { + "bidder": { + "pubId": "fake-pub-id", + "zoneId": "sin" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://gw-sin-bid.yeahtargeter.com/prebid/bid", + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 300, "h": 50}] + }, + "ext": { + "bidder": { + "pubId": "fake-pub-id", + "zoneId": "sin" + } + } + } + ] + } + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + + "expectedBidResponses": [] + +} diff --git a/adapters/yeahmobi/yeahmobitest/exemplary/simple-banner.json b/adapters/yeahmobi/yeahmobitest/exemplary/simple-banner.json new file mode 100644 index 00000000000..7499a7874e7 --- /dev/null +++ b/adapters/yeahmobi/yeahmobitest/exemplary/simple-banner.json @@ -0,0 +1,81 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 50}] + }, + "ext": { + "bidder": { + "pubId": "fake-pub-id", + "zoneId": "sin" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://gw-sin-bid.yeahtargeter.com/prebid/bid", + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 300, "h": 50}] + }, + "ext": { + "bidder": { + "pubId": "fake-pub-id", + "zoneId": "sin" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "ttx", + "bid": [{ + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 1.2, + "adm": "some-ads", + "crid": "crid_testid" + }] + } + ], + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 1.2, + "adm": "some-ads", + "crid": "crid_testid" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/yeahmobi/yeahmobitest/exemplary/simple-native-1.1.json b/adapters/yeahmobi/yeahmobitest/exemplary/simple-native-1.1.json new file mode 100644 index 00000000000..7e93eb68246 --- /dev/null +++ b/adapters/yeahmobi/yeahmobitest/exemplary/simple-native-1.1.json @@ -0,0 +1,82 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "{\"native\":{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":2,\"required\":1,\"title\":{\"len\":90}},{\"id\":6,\"required\":1,\"img\":{\"type\":3,\"wmin\":128,\"hmin\":128,\"mimes\":[\"image/jpg\",\"image/jpeg\",\"image/png\"]}},{\"id\":7,\"required\":1,\"data\":{\"type\":2,\"len\":120}}]}}", + "ver": "1.2" + }, + "ext": { + "bidder": { + "pubId": "fake-pub-id", + "zoneId": "sin" + } + } + } + ] + }, + "httpcalls": [ + { + "expectedRequest": { + "uri": "https://gw-sin-bid.yeahtargeter.com/prebid/bid", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "{\"native\":{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":2,\"required\":1,\"title\":{\"len\":90}},{\"id\":6,\"required\":1,\"img\":{\"type\":3,\"wmin\":128,\"hmin\":128,\"mimes\":[\"image/jpg\",\"image/jpeg\",\"image/png\"]}},{\"id\":7,\"required\":1,\"data\":{\"type\":2,\"len\":120}}]}}", + "ver": "1.2" + }, + "ext": { + "bidder": { + "pubId": "fake-pub-id", + "zoneId": "sin" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "8400d766-58b3-47d4-80d7-6658b337d403", + "impid": "test-imp-id", + "price": 1.2, + "adm": "some ads", + "crid": "crid_testid" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8400d766-58b3-47d4-80d7-6658b337d403", + "impid": "test-imp-id", + "price": 1.2, + "adm": "some ads", + "crid": "crid_testid" + + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/yeahmobi/yeahmobitest/exemplary/simple-native.json b/adapters/yeahmobi/yeahmobitest/exemplary/simple-native.json new file mode 100644 index 00000000000..894e835bc07 --- /dev/null +++ b/adapters/yeahmobi/yeahmobitest/exemplary/simple-native.json @@ -0,0 +1,82 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":2,\"required\":1,\"title\":{\"len\":90}},{\"id\":6,\"required\":1,\"img\":{\"type\":3,\"wmin\":128,\"hmin\":128,\"mimes\":[\"image/jpg\",\"image/jpeg\",\"image/png\"]}},{\"id\":7,\"required\":1,\"data\":{\"type\":2,\"len\":120}}]}", + "ver": "1.2" + }, + "ext": { + "bidder": { + "pubId": "fake-pub-id", + "zoneId": "sin" + } + } + } + ] + }, + "httpcalls": [ + { + "expectedRequest": { + "uri": "https://gw-sin-bid.yeahtargeter.com/prebid/bid", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "{\"native\":{\"assets\":[{\"id\":2,\"required\":1,\"title\":{\"len\":90}},{\"id\":6,\"img\":{\"hmin\":128,\"mimes\":[\"image/jpg\",\"image/jpeg\",\"image/png\"],\"type\":3,\"wmin\":128},\"required\":1},{\"data\":{\"len\":120,\"type\":2},\"id\":7,\"required\":1}],\"context\":1,\"plcmtcnt\":1,\"plcmttype\":4,\"ver\":\"1.2\"}}", + "ver": "1.2" + }, + "ext": { + "bidder": { + "pubId": "fake-pub-id", + "zoneId": "sin" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "8400d766-58b3-47d4-80d7-6658b337d403", + "impid": "test-imp-id", + "price": 1.2, + "adm": "some ads", + "crid": "crid_testid" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8400d766-58b3-47d4-80d7-6658b337d403", + "impid": "test-imp-id", + "price": 1.2, + "adm": "some ads", + "crid": "crid_testid" + + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/yeahmobi/yeahmobitest/exemplary/simple-video.json b/adapters/yeahmobi/yeahmobitest/exemplary/simple-video.json new file mode 100644 index 00000000000..b040d31b5f6 --- /dev/null +++ b/adapters/yeahmobi/yeahmobitest/exemplary/simple-video.json @@ -0,0 +1,89 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 300, + "h": 250, + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "pubId": "fake-pub-id", + "zoneId": "sin" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://gw-sin-bid.yeahtargeter.com/prebid/bid", + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "video": { + "w": 300, + "h": 250, + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "pubId": "fake-pub-id", + "zoneId": "sin" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "ttx", + "bid": [{ + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 1.2, + "adm": "some-ads", + "crid": "crid_testid" + }] + } + ], + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 1.2, + "adm": "some-ads", + "crid": "crid_testid" + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext.json b/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext.json new file mode 100644 index 00000000000..444e1e7a8d8 --- /dev/null +++ b/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext.json @@ -0,0 +1,21 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 50}] + }, + "ext": "aaa" + } + ] + }, + + "expectedMakeRequestsErrors": [ + { + "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "comparison": "literal" + } + ] +} diff --git a/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext_bidder.json b/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext_bidder.json new file mode 100644 index 00000000000..89697d37141 --- /dev/null +++ b/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext_bidder.json @@ -0,0 +1,23 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 50}] + }, + "ext": { + "bidder": "aa" + } + } + ] + }, + + "expectedMakeRequestsErrors": [ + { + "value": "json: cannot unmarshal string into Go value of type openrtb_ext.ExtImpYeahmobi", + "comparison": "literal" + } + ] +} diff --git a/adapters/yeahmobi/yeahmobitest/supplemental/bad_response.json b/adapters/yeahmobi/yeahmobitest/supplemental/bad_response.json new file mode 100644 index 00000000000..0d77e5af93a --- /dev/null +++ b/adapters/yeahmobi/yeahmobitest/supplemental/bad_response.json @@ -0,0 +1,55 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 50}] + }, + "ext": { + "bidder": { + "pubId": "fake-pub-id", + "zoneId": "sin" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://gw-sin-bid.yeahtargeter.com/prebid/bid", + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 300, "h": 50}] + }, + "ext": { + "bidder": { + "pubId": "fake-pub-id", + "zoneId": "sin" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": "{\"id\":test-request-id" + } + } + ], + + "expectedMakeBidsErrors": [ + { + "comparison": "literal", + "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse" + } + ] +} diff --git a/adapters/yeahmobi/yeahmobitest/supplemental/status_400.json b/adapters/yeahmobi/yeahmobitest/supplemental/status_400.json new file mode 100644 index 00000000000..74bb869218c --- /dev/null +++ b/adapters/yeahmobi/yeahmobitest/supplemental/status_400.json @@ -0,0 +1,55 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 50}] + }, + "ext": { + "bidder": { + "pubId": "fake-pub-id", + "zoneId": "sin" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://gw-sin-bid.yeahtargeter.com/prebid/bid", + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 300, "h": 50}] + }, + "ext": { + "bidder": { + "pubId": "fake-pub-id", + "zoneId": "sin" + } + } + } + ] + } + }, + "mockResponse": { + "status": 400, + "body": {} + } + } + ], + + "expectedMakeBidsErrors": [ + { + "comparison": "literal", + "value": "Unexpected status code: 400." + } + ] +} diff --git a/adapters/yeahmobi/yeahmobitest/supplemental/status_500.json b/adapters/yeahmobi/yeahmobitest/supplemental/status_500.json new file mode 100644 index 00000000000..2d3264de897 --- /dev/null +++ b/adapters/yeahmobi/yeahmobitest/supplemental/status_500.json @@ -0,0 +1,55 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 300, "h": 50}] + }, + "ext": { + "bidder": { + "pubId": "fake-pub-id", + "zoneId": "sin" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://gw-sin-bid.yeahtargeter.com/prebid/bid", + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 300, "h": 50}] + }, + "ext": { + "bidder": { + "pubId": "fake-pub-id", + "zoneId": "sin" + } + } + } + ] + } + }, + "mockResponse": { + "status": 500, + "body": {} + } + } + ], + + "expectedMakeBidsErrors": [ + { + "comparison": "literal", + "value": "Unexpected status code: 500." + } + ] +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index f758b3ee33b..ea9e99cfb6c 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -179,6 +179,7 @@ import ( "github.com/prebid/prebid-server/adapters/vrtcal" "github.com/prebid/prebid-server/adapters/xeworks" "github.com/prebid/prebid-server/adapters/yahooAds" + "github.com/prebid/prebid-server/adapters/yeahmobi" "github.com/prebid/prebid-server/adapters/yieldlab" "github.com/prebid/prebid-server/adapters/yieldmo" "github.com/prebid/prebid-server/adapters/yieldone" @@ -389,6 +390,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderYahooAds: yahooAds.Builder, openrtb_ext.BidderYahooAdvertising: yahooAds.Builder, openrtb_ext.BidderYahooSSP: yahooAds.Builder, + openrtb_ext.BidderYeahmobi: yeahmobi.Builder, openrtb_ext.BidderYieldlab: yieldlab.Builder, openrtb_ext.BidderYieldmo: yieldmo.Builder, openrtb_ext.BidderYieldone: yieldone.Builder, diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index 1890635cb3d..a5a232bbd93 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -115,7 +115,6 @@ func GetDisabledBidderWarningMessages(infos config.BidderInfos) map[string]strin "verizonmedia": `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`, "brightroll": `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`, "engagebdr": `Bidder "engagebdr" is no longer available in Prebid Server. Please update your configuration.`, - "yeahmobi": `Bidder "yeahmobi" is no longer available in Prebid Server. Please update your configuration.`, "ninthdecimal": `Bidder "ninthdecimal" is no longer available in Prebid Server. Please update your configuration.`, "kubient": `Bidder "kubient" is no longer available in Prebid Server. Please update your configuration.`, "definemedia": `Bidder "definemedia" is no longer available in Prebid Server. Please update your configuration.`, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 8b0262bca19..1caa625c0d1 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -215,6 +215,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderYahooAds, BidderYahooAdvertising, BidderYahooSSP, + BidderYeahmobi, BidderYieldlab, BidderYieldmo, BidderYieldone, @@ -505,6 +506,7 @@ const ( BidderYahooAds BidderName = "yahooAds" BidderYahooAdvertising BidderName = "yahooAdvertising" BidderYahooSSP BidderName = "yahoossp" + BidderYeahmobi BidderName = "yeahmobi" BidderYieldlab BidderName = "yieldlab" BidderYieldmo BidderName = "yieldmo" BidderYieldone BidderName = "yieldone" diff --git a/openrtb_ext/imp_yeahmobi.go b/openrtb_ext/imp_yeahmobi.go new file mode 100644 index 00000000000..16948d807c4 --- /dev/null +++ b/openrtb_ext/imp_yeahmobi.go @@ -0,0 +1,7 @@ +package openrtb_ext + +// ExtImpYeahmobi defines the contract for bidrequest.imp[i].ext.prebid.bidder.yeahmobi +type ExtImpYeahmobi struct { + PubId string `json:"pubId"` + ZoneId string `json:"zoneId"` +} diff --git a/static/bidder-info/yeahmobi.yaml b/static/bidder-info/yeahmobi.yaml new file mode 100644 index 00000000000..975bf044c5b --- /dev/null +++ b/static/bidder-info/yeahmobi.yaml @@ -0,0 +1,9 @@ +endpoint: "https://{{.Host}}/prebid/bid" +maintainer: + email: "developer@yeahmobi.com" +capabilities: + app: + mediaTypes: + - banner + - video + - native diff --git a/static/bidder-params/yeahmobi.json b/static/bidder-params/yeahmobi.json new file mode 100644 index 00000000000..fe26fa7255a --- /dev/null +++ b/static/bidder-params/yeahmobi.json @@ -0,0 +1,21 @@ + +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Yeahmobi Adapter Params", + "description": "A schema which validates params accepted by the Yeahmobi adapter", + + "type": "object", + "properties": { + "pubId": { + "type": "string", + "description": "Publisher ID", + "minLength": 1 + }, + "zoneId": { + "type": "string", + "description": "Zone Id", + "minLength": 1 + } + }, + "required": ["pubId", "zoneId"] +} \ No newline at end of file From 11ef54d1989a624eb8c39e9b7183718fb82c67e0 Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Wed, 18 Oct 2023 01:57:26 -0400 Subject: [PATCH 180/268] Adapter Name Case Insensitive: First Party Data (#3211) --- exchange/exchange.go | 1 + exchange/utils.go | 54 +++-- exchange/utils_test.go | 151 ++++++++++--- firstpartydata/first_party_data.go | 24 +-- firstpartydata/first_party_data_test.go | 198 +++++++++--------- .../bidder-config-case-normalize.json | 28 +++ ...er-config-duplicated-case-insensitive.json | 63 ++++++ ...r-config-request-alias-case-sensitive.json | 28 +++ .../global-fpd-defined-app-content-data.json | 2 +- ...-correct-case-insensitive-integration.json | 88 ++++++++ .../resolvefpd/bidder-fpd-alias-matches.json | 25 +++ .../bidder-fpd-alias-not-matches.json | 21 ++ .../resolvefpd/bidder-fpd-case-normalize.json | 25 +++ .../tests/resolvefpd/bidder-fpd-only-app.json | 55 ++--- .../resolvefpd/bidder-fpd-only-site.json | 55 ++--- .../resolvefpd/bidder-fpd-only-user.json | 65 +++--- .../bidder-fpd-site-content-data-only.json | 75 +++---- ...bidder-fpd-app-content-data-user-data.json | 77 +++---- .../resolvefpd/global-and-bidder-fpd-app.json | 62 +++--- .../global-and-bidder-fpd-site-user.json | 66 +++--- .../global-and-bidder-fpd-site.json | 52 ++--- .../global-and-bidder-fpd-user.json | 30 +-- .../global-and-bidder-site-content-data.json | 90 ++++---- ...lobal-and-no-bidder-fpd-site-app-user.json | 102 ++++----- ...d-no-bidder-fpd-site-content-app-user.json | 92 ++++---- .../tests/resolvefpd/global-fpd-only-app.json | 98 ++++----- .../global-fpd-only-excludes-some.json | 138 ++++++++++++ .../global-fpd-only-include-all-explicit.json | 144 +++++++++++++ .../global-fpd-only-include-all-implicit.json | 141 +++++++++++++ .../resolvefpd/global-fpd-only-site.json | 102 ++++----- .../req-and-bidder-fpd-site-content.json | 102 ++++----- .../tests/resolvefpd/req-app-not-defined.json | 6 +- .../resolvefpd/req-site-not-defined.json | 6 +- .../resolvefpd/req-user-not-defined.json | 10 +- .../resolvefpd/site-page-empty-conflict.json | 6 +- openrtb_ext/bidders.go | 9 + 36 files changed, 1593 insertions(+), 698 deletions(-) create mode 100644 firstpartydata/tests/extractbidderconfigfpd/bidder-config-case-normalize.json create mode 100644 firstpartydata/tests/extractbidderconfigfpd/bidder-config-duplicated-case-insensitive.json create mode 100644 firstpartydata/tests/extractbidderconfigfpd/bidder-config-request-alias-case-sensitive.json create mode 100644 firstpartydata/tests/extractfpdforbidders/two-bidders-correct-case-insensitive-integration.json create mode 100644 firstpartydata/tests/resolvefpd/bidder-fpd-alias-matches.json create mode 100644 firstpartydata/tests/resolvefpd/bidder-fpd-alias-not-matches.json create mode 100644 firstpartydata/tests/resolvefpd/bidder-fpd-case-normalize.json create mode 100644 firstpartydata/tests/resolvefpd/global-fpd-only-excludes-some.json create mode 100644 firstpartydata/tests/resolvefpd/global-fpd-only-include-all-explicit.json create mode 100644 firstpartydata/tests/resolvefpd/global-fpd-only-include-all-implicit.json diff --git a/exchange/exchange.go b/exchange/exchange.go index 7544b4a7020..0810ad814ab 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -223,6 +223,7 @@ type BidderRequest struct { BidderCoreName openrtb_ext.BidderName BidderLabels metrics.AdapterLabels BidderStoredResponses map[string]json.RawMessage + IsRequestAlias bool ImpReplaceImpId map[string]bool } diff --git a/exchange/utils.go b/exchange/utils.go index 4fe9af12ff3..a67a87b9c97 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -214,9 +214,7 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, } - if auctionReq.FirstPartyData != nil && auctionReq.FirstPartyData[bidderRequest.BidderName] != nil { - applyFPD(auctionReq.FirstPartyData[bidderRequest.BidderName], bidderRequest.BidRequest) - } + applyFPD(auctionReq.FirstPartyData, bidderRequest) privacyEnforcement.TID = !auctionReq.Activities.Allow(privacy.ActivityTransmitTIDs, scopedName, privacy.NewRequestFromBidRequest(*req)) @@ -335,7 +333,7 @@ func getAuctionBidderRequests(auctionRequest AuctionRequest, var errs []error for bidder, imps := range impsByBidder { - coreBidder := resolveBidder(bidder, aliases) + coreBidder, isRequestAlias := resolveBidder(bidder, aliases) reqCopy := *req.BidRequest reqCopy.Imp = imps @@ -355,6 +353,7 @@ func getAuctionBidderRequests(auctionRequest AuctionRequest, bidderRequest := BidderRequest{ BidderName: openrtb_ext.BidderName(bidder), BidderCoreName: coreBidder, + IsRequestAlias: isRequestAlias, BidRequest: &reqCopy, BidderLabels: metrics.AdapterLabels{ Source: auctionRequest.LegacyLabels.Source, @@ -768,12 +767,14 @@ func setUserExtWithCopy(request *openrtb2.BidRequest, userExtJSON json.RawMessag } // resolveBidder returns the known BidderName associated with bidder, if bidder is an alias. If it's not an alias, the bidder is returned. -func resolveBidder(bidder string, aliases map[string]string) openrtb_ext.BidderName { +func resolveBidder(bidder string, requestAliases map[string]string) (openrtb_ext.BidderName, bool) { normalisedBidderName, _ := openrtb_ext.NormalizeBidderName(bidder) - if coreBidder, ok := aliases[bidder]; ok { - return openrtb_ext.BidderName(coreBidder) + + if coreBidder, ok := requestAliases[bidder]; ok { + return openrtb_ext.BidderName(coreBidder), true } - return normalisedBidderName + + return normalisedBidderName, false } // parseAliases parses the aliases from the BidRequest @@ -909,20 +910,36 @@ func getExtBidAdjustmentFactors(requestExtPrebid *openrtb_ext.ExtRequestPrebid) return nil } -func applyFPD(fpd *firstpartydata.ResolvedFirstPartyData, bidReq *openrtb2.BidRequest) { - if fpd.Site != nil { - bidReq.Site = fpd.Site +func applyFPD(fpd map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData, r BidderRequest) { + if fpd == nil { + return } - if fpd.App != nil { - bidReq.App = fpd.App + + bidder := r.BidderCoreName + if r.IsRequestAlias { + bidder = r.BidderName } - if fpd.User != nil { + + fpdToApply, exists := fpd[bidder] + if !exists || fpdToApply == nil { + return + } + + if fpdToApply.Site != nil { + r.BidRequest.Site = fpdToApply.Site + } + + if fpdToApply.App != nil { + r.BidRequest.App = fpdToApply.App + } + + if fpdToApply.User != nil { //BuyerUID is a value obtained between fpd extraction and fpd application. //BuyerUID needs to be set back to fpd before applying this fpd to final bidder request - if bidReq.User != nil && len(bidReq.User.BuyerUID) > 0 { - fpd.User.BuyerUID = bidReq.User.BuyerUID + if r.BidRequest.User != nil && len(r.BidRequest.User.BuyerUID) > 0 { + fpdToApply.User.BuyerUID = r.BidRequest.User.BuyerUID } - bidReq.User = fpd.User + r.BidRequest.User = fpdToApply.User } } @@ -934,13 +951,14 @@ func buildBidResponseRequest(req *openrtb2.BidRequest, bidderToBidderResponse := make(map[openrtb_ext.BidderName]BidderRequest) for bidderName, impResps := range bidderImpResponses { - resolvedBidder := resolveBidder(string(bidderName), aliases) + resolvedBidder, isRequestAlias := resolveBidder(string(bidderName), aliases) bidderToBidderResponse[bidderName] = BidderRequest{ BidRequest: req, BidderCoreName: resolvedBidder, BidderName: bidderName, BidderStoredResponses: impResps, ImpReplaceImpId: bidderImpReplaceImpID[string(resolvedBidder)], + IsRequestAlias: isRequestAlias, BidderLabels: metrics.AdapterLabels{Adapter: resolvedBidder}, } } diff --git a/exchange/utils_test.go b/exchange/utils_test.go index a1e71b30c23..1be1aaa8493 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -3242,60 +3242,145 @@ func TestCleanOpenRTBRequestsBidAdjustment(t *testing.T) { } func TestApplyFPD(t *testing.T) { - testCases := []struct { - description string - inputFpd firstpartydata.ResolvedFirstPartyData - inputRequest openrtb2.BidRequest - expectedRequest openrtb2.BidRequest + description string + inputFpd map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData + inputBidderName string + inputBidderCoreName string + inputBidderIsRequestAlias bool + inputRequest openrtb2.BidRequest + expectedRequest openrtb2.BidRequest }{ { - description: "req.Site defined; bidderFPD.Site not defined; expect request.Site remains the same", - inputFpd: firstpartydata.ResolvedFirstPartyData{Site: nil, App: nil, User: nil}, - inputRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}}, - expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}}, + description: "fpd-nil", + inputFpd: nil, + inputBidderName: "bidderFromRequest", + inputBidderCoreName: "bidderNormalized", + inputBidderIsRequestAlias: false, + inputRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}}, + expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}}, + }, + { + description: "fpd-bidderdata-nil", + inputFpd: map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData{ + "bidderNormalized": nil, + }, + inputBidderName: "bidderFromRequest", + inputBidderCoreName: "bidderNormalized", + inputBidderIsRequestAlias: false, + inputRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}}, + expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}}, + }, + { + description: "fpd-bidderdata-notdefined", + inputFpd: map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData{ + "differentBidder": {App: &openrtb2.App{ID: "AppId"}}, + }, + inputBidderName: "bidderFromRequest", + inputBidderCoreName: "bidderNormalized", + inputBidderIsRequestAlias: false, + inputRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}}, + expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}}, + }, + { + description: "fpd-bidderdata-alias", + inputFpd: map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData{ + "alias": {App: &openrtb2.App{ID: "AppId"}}, + }, + inputBidderName: "alias", + inputBidderCoreName: "bidder", + inputBidderIsRequestAlias: true, + inputRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}}, + expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}}, + }, + { + description: "req.Site defined; bidderFPD.Site not defined; expect request.Site remains the same", + inputFpd: map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData{ + "bidderNormalized": {Site: nil, App: nil, User: nil}, + }, + inputBidderName: "bidderFromRequest", + inputBidderCoreName: "bidderNormalized", + inputBidderIsRequestAlias: false, + inputRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}}, + expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}}, }, { description: "req.Site, req.App, req.User are not defined; bidderFPD.App, bidderFPD.Site and bidderFPD.User defined; " + "expect req.Site, req.App, req.User to be overriden by bidderFPD.App, bidderFPD.Site and bidderFPD.User", - inputFpd: firstpartydata.ResolvedFirstPartyData{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId"}}, - inputRequest: openrtb2.BidRequest{}, - expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId"}}, + inputFpd: map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData{ + "bidderNormalized": {Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId"}}, + }, + inputBidderName: "bidderFromRequest", + inputBidderCoreName: "bidderNormalized", + inputBidderIsRequestAlias: false, + inputRequest: openrtb2.BidRequest{}, + expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId"}}, }, { - description: "req.Site, defined; bidderFPD.App defined; expect request.App to be overriden by bidderFPD.App; expect req.Site remains the same", - inputFpd: firstpartydata.ResolvedFirstPartyData{App: &openrtb2.App{ID: "AppId"}}, - inputRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}}, - expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}}, + description: "req.Site, defined; bidderFPD.App defined; expect request.App to be overriden by bidderFPD.App; expect req.Site remains the same", + inputFpd: map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData{ + "bidderNormalized": {App: &openrtb2.App{ID: "AppId"}}, + }, + inputBidderName: "bidderFromRequest", + inputBidderCoreName: "bidderNormalized", + inputBidderIsRequestAlias: false, + inputRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}}, + expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}}, }, { - description: "req.Site, req.App defined; bidderFPD.App defined; expect request.App to be overriden by bidderFPD.App", - inputFpd: firstpartydata.ResolvedFirstPartyData{App: &openrtb2.App{ID: "AppId"}}, - inputRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "TestAppId"}}, - expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}}, + description: "req.Site, req.App defined; bidderFPD.App defined; expect request.App to be overriden by bidderFPD.App", + inputFpd: map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData{ + "bidderNormalized": {App: &openrtb2.App{ID: "AppId"}}, + }, + inputBidderName: "bidderFromRequest", + inputBidderCoreName: "bidderNormalized", + inputBidderIsRequestAlias: false, + inputRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "TestAppId"}}, + expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}}, }, { - description: "req.User is defined; bidderFPD.User defined; req.User has BuyerUID. Expect to see user.BuyerUID in result request", - inputFpd: firstpartydata.ResolvedFirstPartyData{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId"}}, - inputRequest: openrtb2.BidRequest{User: &openrtb2.User{ID: "UserIdIn", BuyerUID: "12345"}}, - expectedRequest: openrtb2.BidRequest{User: &openrtb2.User{ID: "UserId", BuyerUID: "12345"}, Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}}, + description: "req.User is defined; bidderFPD.User defined; req.User has BuyerUID. Expect to see user.BuyerUID in result request", + inputFpd: map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData{ + "bidderNormalized": {Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId"}}, + }, + inputBidderName: "bidderFromRequest", + inputBidderCoreName: "bidderNormalized", + inputBidderIsRequestAlias: false, + inputRequest: openrtb2.BidRequest{User: &openrtb2.User{ID: "UserIdIn", BuyerUID: "12345"}}, + expectedRequest: openrtb2.BidRequest{User: &openrtb2.User{ID: "UserId", BuyerUID: "12345"}, Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}}, }, { - description: "req.User is defined; bidderFPD.User defined; req.User has BuyerUID with zero length. Expect to see empty user.BuyerUID in result request", - inputFpd: firstpartydata.ResolvedFirstPartyData{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId"}}, - inputRequest: openrtb2.BidRequest{User: &openrtb2.User{ID: "UserIdIn", BuyerUID: ""}}, - expectedRequest: openrtb2.BidRequest{User: &openrtb2.User{ID: "UserId"}, Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}}, + description: "req.User is defined; bidderFPD.User defined; req.User has BuyerUID with zero length. Expect to see empty user.BuyerUID in result request", + inputFpd: map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData{ + "bidderNormalized": {Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId"}}, + }, + inputBidderName: "bidderFromRequest", + inputBidderCoreName: "bidderNormalized", + inputBidderIsRequestAlias: false, + inputRequest: openrtb2.BidRequest{User: &openrtb2.User{ID: "UserIdIn", BuyerUID: ""}}, + expectedRequest: openrtb2.BidRequest{User: &openrtb2.User{ID: "UserId"}, Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}}, }, { - description: "req.User is not defined; bidderFPD.User defined and has BuyerUID. Expect to see user.BuyerUID in result request", - inputFpd: firstpartydata.ResolvedFirstPartyData{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId", BuyerUID: "FPDBuyerUID"}}, - inputRequest: openrtb2.BidRequest{}, - expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId", BuyerUID: "FPDBuyerUID"}}, + description: "req.User is not defined; bidderFPD.User defined and has BuyerUID. Expect to see user.BuyerUID in result request", + inputFpd: map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData{ + "bidderNormalized": {Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId", BuyerUID: "FPDBuyerUID"}}, + }, + inputBidderName: "bidderFromRequest", + inputBidderCoreName: "bidderNormalized", + inputBidderIsRequestAlias: false, + inputRequest: openrtb2.BidRequest{}, + expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId", BuyerUID: "FPDBuyerUID"}}, }, } for _, testCase := range testCases { - applyFPD(&testCase.inputFpd, &testCase.inputRequest) + bidderRequest := BidderRequest{ + BidderName: openrtb_ext.BidderName(testCase.inputBidderName), + BidderCoreName: openrtb_ext.BidderName(testCase.inputBidderCoreName), + IsRequestAlias: testCase.inputBidderIsRequestAlias, + BidRequest: &testCase.inputRequest, + } + applyFPD(testCase.inputFpd, bidderRequest) assert.Equal(t, testCase.expectedRequest, testCase.inputRequest, fmt.Sprintf("incorrect request after applying fpd, testcase %s", testCase.description)) } } diff --git a/firstpartydata/first_party_data.go b/firstpartydata/first_party_data.go index 0fde931d445..b63feb1ec52 100644 --- a/firstpartydata/first_party_data.go +++ b/firstpartydata/first_party_data.go @@ -120,7 +120,9 @@ func ResolveFPD(bidRequest *openrtb2.BidRequest, fpdBidderConfigData map[openrtb } } else { // only bidders in global bidder list will receive global data and bidder specific data - for _, bidderName := range biddersWithGlobalFPD { + for _, bidder := range biddersWithGlobalFPD { + bidderName := openrtb_ext.NormalizeBidderNameOrUnchanged(bidder) + if _, present := allBiddersTable[string(bidderName)]; !present { allBiddersTable[string(bidderName)] = struct{}{} } @@ -462,12 +464,14 @@ func buildExtData(data []byte) []byte { // ExtractBidderConfigFPD extracts bidder specific configs from req.ext.prebid.bidderconfig func ExtractBidderConfigFPD(reqExt *openrtb_ext.RequestExt) (map[openrtb_ext.BidderName]*openrtb_ext.ORTB2, error) { fpd := make(map[openrtb_ext.BidderName]*openrtb_ext.ORTB2) + reqExtPrebid := reqExt.GetPrebid() if reqExtPrebid != nil { for _, bidderConfig := range reqExtPrebid.BidderConfigs { for _, bidder := range bidderConfig.Bidders { - if _, present := fpd[openrtb_ext.BidderName(bidder)]; present { - //if bidder has duplicated config - throw an error + bidderName := openrtb_ext.NormalizeBidderNameOrUnchanged(bidder) + + if _, duplicate := fpd[bidderName]; duplicate { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("multiple First Party Data bidder configs provided for bidder: %s", bidder), } @@ -476,18 +480,12 @@ func ExtractBidderConfigFPD(reqExt *openrtb_ext.RequestExt) (map[openrtb_ext.Bid fpdBidderData := &openrtb_ext.ORTB2{} if bidderConfig.Config != nil && bidderConfig.Config.ORTB2 != nil { - if bidderConfig.Config.ORTB2.Site != nil { - fpdBidderData.Site = bidderConfig.Config.ORTB2.Site - } - if bidderConfig.Config.ORTB2.App != nil { - fpdBidderData.App = bidderConfig.Config.ORTB2.App - } - if bidderConfig.Config.ORTB2.User != nil { - fpdBidderData.User = bidderConfig.Config.ORTB2.User - } + fpdBidderData.Site = bidderConfig.Config.ORTB2.Site + fpdBidderData.App = bidderConfig.Config.ORTB2.App + fpdBidderData.User = bidderConfig.Config.ORTB2.User } - fpd[openrtb_ext.BidderName(bidder)] = fpdBidderData + fpd[bidderName] = fpdBidderData } } reqExtPrebid.BidderConfigs = nil diff --git a/firstpartydata/first_party_data_test.go b/firstpartydata/first_party_data_test.go index 4c9cd7ad5e8..ffa05a31d17 100644 --- a/firstpartydata/first_party_data_test.go +++ b/firstpartydata/first_party_data_test.go @@ -3,6 +3,7 @@ package firstpartydata import ( "encoding/json" "os" + "path/filepath" "reflect" "testing" @@ -474,13 +475,13 @@ func TestExtractBidderConfigFPD(t *testing.T) { for _, test := range tests { t.Run(test.Name(), func(t *testing.T) { - filePath := testPath + "/" + test.Name() + path := filepath.Join(testPath, test.Name()) - fpdFile, err := loadFpdFile(filePath) - require.NoError(t, err, "Cannot Load Test") + testFile, err := loadTestFile[fpdFile](path) + require.NoError(t, err, "Load Test File") givenRequestExtPrebid := &openrtb_ext.ExtRequestPrebid{} - err = json.Unmarshal(fpdFile.InputRequestData, givenRequestExtPrebid) + err = json.Unmarshal(testFile.InputRequestData, givenRequestExtPrebid) require.NoError(t, err, "Cannot Load Test Conditions") testRequest := &openrtb_ext.RequestExt{} @@ -490,15 +491,17 @@ func TestExtractBidderConfigFPD(t *testing.T) { results, err := ExtractBidderConfigFPD(testRequest) // assert errors - if len(fpdFile.ValidationErrors) > 0 { - require.EqualError(t, err, fpdFile.ValidationErrors[0].Message, "Expected Error Not Received") + if len(testFile.ValidationErrors) > 0 { + require.EqualError(t, err, testFile.ValidationErrors[0].Message, "Expected Error Not Received") } else { require.NoError(t, err, "Error Not Expected") assert.Nil(t, testRequest.GetPrebid().BidderConfigs, "Bidder specific FPD config should be removed from request") } // assert fpd (with normalization for nicer looking tests) - for bidderName, expectedFPD := range fpdFile.BidderConfigFPD { + for bidderName, expectedFPD := range testFile.BidderConfigFPD { + require.Contains(t, results, bidderName) + if expectedFPD.App != nil { assert.JSONEq(t, string(expectedFPD.App), string(results[bidderName].App), "app is incorrect") } else { @@ -520,7 +523,6 @@ func TestExtractBidderConfigFPD(t *testing.T) { }) } } - func TestResolveFPD(t *testing.T) { testPath := "tests/resolvefpd" @@ -529,31 +531,27 @@ func TestResolveFPD(t *testing.T) { for _, test := range tests { t.Run(test.Name(), func(t *testing.T) { - filePath := testPath + "/" + test.Name() + path := filepath.Join(testPath, test.Name()) - fpdFile, err := loadFpdFile(filePath) - require.NoError(t, err, "Cannot Load Test") + testFile, err := loadTestFile[fpdFileForResolveFPD](path) + require.NoError(t, err, "Load Test File") request := &openrtb2.BidRequest{} - err = json.Unmarshal(fpdFile.InputRequestData, &request) + err = json.Unmarshal(testFile.InputRequestData, &request) require.NoError(t, err, "Cannot Load Request") originalRequest := &openrtb2.BidRequest{} - err = json.Unmarshal(fpdFile.InputRequestData, &originalRequest) + err = json.Unmarshal(testFile.InputRequestData, &originalRequest) require.NoError(t, err, "Cannot Load Request") - outputReq := &openrtb2.BidRequest{} - err = json.Unmarshal(fpdFile.OutputRequestData, &outputReq) - require.NoError(t, err, "Cannot Load Output Request") - reqExtFPD := make(map[string][]byte) - reqExtFPD["site"] = fpdFile.GlobalFPD["site"] - reqExtFPD["app"] = fpdFile.GlobalFPD["app"] - reqExtFPD["user"] = fpdFile.GlobalFPD["user"] + reqExtFPD["site"] = testFile.GlobalFPD["site"] + reqExtFPD["app"] = testFile.GlobalFPD["app"] + reqExtFPD["user"] = testFile.GlobalFPD["user"] reqFPD := make(map[string][]openrtb2.Data, 3) - reqFPDSiteContentData := fpdFile.GlobalFPD[siteContentDataKey] + reqFPDSiteContentData := testFile.GlobalFPD[siteContentDataKey] if len(reqFPDSiteContentData) > 0 { var siteConData []openrtb2.Data err = json.Unmarshal(reqFPDSiteContentData, &siteConData) @@ -563,7 +561,7 @@ func TestResolveFPD(t *testing.T) { reqFPD[siteContentDataKey] = siteConData } - reqFPDAppContentData := fpdFile.GlobalFPD[appContentDataKey] + reqFPDAppContentData := testFile.GlobalFPD[appContentDataKey] if len(reqFPDAppContentData) > 0 { var appConData []openrtb2.Data err = json.Unmarshal(reqFPDAppContentData, &appConData) @@ -573,7 +571,7 @@ func TestResolveFPD(t *testing.T) { reqFPD[appContentDataKey] = appConData } - reqFPDUserData := fpdFile.GlobalFPD[userDataKey] + reqFPDUserData := testFile.GlobalFPD[userDataKey] if len(reqFPDUserData) > 0 { var userData []openrtb2.Data err = json.Unmarshal(reqFPDUserData, &userData) @@ -582,88 +580,88 @@ func TestResolveFPD(t *testing.T) { } reqFPD[userDataKey] = userData } - if fpdFile.BidderConfigFPD == nil { - fpdFile.BidderConfigFPD = make(map[openrtb_ext.BidderName]*openrtb_ext.ORTB2) - fpdFile.BidderConfigFPD["appnexus"] = &openrtb_ext.ORTB2{} - } // run test - resultFPD, errL := ResolveFPD(request, fpdFile.BidderConfigFPD, reqExtFPD, reqFPD, []string{"appnexus"}) + resultFPD, errL := ResolveFPD(request, testFile.BidderConfigFPD, reqExtFPD, reqFPD, testFile.BiddersWithGlobalFPD) if len(errL) == 0 { assert.Equal(t, request, originalRequest, "Original request should not be modified") - bidderFPD := resultFPD["appnexus"] - - if outputReq.Site != nil && len(outputReq.Site.Ext) > 0 { - resSiteExt := bidderFPD.Site.Ext - expectedSiteExt := outputReq.Site.Ext - bidderFPD.Site.Ext = nil - outputReq.Site.Ext = nil - assert.JSONEq(t, string(expectedSiteExt), string(resSiteExt), "site.ext is incorrect") - - assert.Equal(t, outputReq.Site, bidderFPD.Site, "Site is incorrect") + expectedResultKeys := []string{} + for k := range testFile.OutputRequestData { + expectedResultKeys = append(expectedResultKeys, k.String()) } - if outputReq.App != nil && len(outputReq.App.Ext) > 0 { - resAppExt := bidderFPD.App.Ext - expectedAppExt := outputReq.App.Ext - bidderFPD.App.Ext = nil - outputReq.App.Ext = nil - - assert.JSONEq(t, string(expectedAppExt), string(resAppExt), "app.ext is incorrect") - - assert.Equal(t, outputReq.App, bidderFPD.App, "App is incorrect") + actualResultKeys := []string{} + for k := range resultFPD { + actualResultKeys = append(actualResultKeys, k.String()) } - if outputReq.User != nil && len(outputReq.User.Ext) > 0 { - resUserExt := bidderFPD.User.Ext - expectedUserExt := outputReq.User.Ext - bidderFPD.User.Ext = nil - outputReq.User.Ext = nil - assert.JSONEq(t, string(expectedUserExt), string(resUserExt), "user.ext is incorrect") - - assert.Equal(t, outputReq.User, bidderFPD.User, "User is incorrect") + require.ElementsMatch(t, expectedResultKeys, actualResultKeys) + + for k, outputReq := range testFile.OutputRequestData { + bidderFPD := resultFPD[k] + + if outputReq.Site != nil && len(outputReq.Site.Ext) > 0 { + resSiteExt := bidderFPD.Site.Ext + expectedSiteExt := outputReq.Site.Ext + bidderFPD.Site.Ext = nil + outputReq.Site.Ext = nil + assert.JSONEq(t, string(expectedSiteExt), string(resSiteExt), "site.ext is incorrect") + assert.Equal(t, outputReq.Site, bidderFPD.Site, "Site is incorrect") + } + if outputReq.App != nil && len(outputReq.App.Ext) > 0 { + resAppExt := bidderFPD.App.Ext + expectedAppExt := outputReq.App.Ext + bidderFPD.App.Ext = nil + outputReq.App.Ext = nil + assert.JSONEq(t, string(expectedAppExt), string(resAppExt), "app.ext is incorrect") + assert.Equal(t, outputReq.App, bidderFPD.App, "App is incorrect") + } + if outputReq.User != nil && len(outputReq.User.Ext) > 0 { + resUserExt := bidderFPD.User.Ext + expectedUserExt := outputReq.User.Ext + bidderFPD.User.Ext = nil + outputReq.User.Ext = nil + assert.JSONEq(t, string(expectedUserExt), string(resUserExt), "user.ext is incorrect") + assert.Equal(t, outputReq.User, bidderFPD.User, "User is incorrect") + } } } else { - assert.ElementsMatch(t, errL, fpdFile.ValidationErrors, "Incorrect first party data warning message") + assert.ElementsMatch(t, errL, testFile.ValidationErrors, "Incorrect first party data warning message") } }) } } - func TestExtractFPDForBidders(t *testing.T) { if specFiles, err := os.ReadDir("./tests/extractfpdforbidders"); err == nil { for _, specFile := range specFiles { - fileName := "./tests/extractfpdforbidders/" + specFile.Name() - - fpdFile, err := loadFpdFile(fileName) + path := filepath.Join("./tests/extractfpdforbidders/", specFile.Name()) - if err != nil { - t.Errorf("Unable to load file: %s", fileName) - } + testFile, err := loadTestFile[fpdFile](path) + require.NoError(t, err, "Load Test File") var expectedRequest openrtb2.BidRequest - err = json.Unmarshal(fpdFile.OutputRequestData, &expectedRequest) + err = json.Unmarshal(testFile.OutputRequestData, &expectedRequest) if err != nil { - t.Errorf("Unable to unmarshal input request: %s", fileName) + t.Errorf("Unable to unmarshal input request: %s", path) } resultRequest := &openrtb_ext.RequestWrapper{} resultRequest.BidRequest = &openrtb2.BidRequest{} - err = json.Unmarshal(fpdFile.InputRequestData, resultRequest.BidRequest) + err = json.Unmarshal(testFile.InputRequestData, resultRequest.BidRequest) assert.NoError(t, err, "Error should be nil") resultFPD, errL := ExtractFPDForBidders(resultRequest) - if len(fpdFile.ValidationErrors) > 0 { - assert.Equal(t, len(fpdFile.ValidationErrors), len(errL), "Incorrect number of errors was returned") - assert.ElementsMatch(t, errL, fpdFile.ValidationErrors, "Incorrect errors were returned") + if len(testFile.ValidationErrors) > 0 { + assert.Equal(t, len(testFile.ValidationErrors), len(errL), "Incorrect number of errors was returned") + assert.ElementsMatch(t, errL, testFile.ValidationErrors, "Incorrect errors were returned") //in case or error no further assertions needed continue } assert.Empty(t, errL, "Error should be empty") - assert.Equal(t, len(resultFPD), len(fpdFile.BiddersFPDResolved)) + assert.Equal(t, len(resultFPD), len(testFile.BiddersFPDResolved)) - for bidderName, expectedValue := range fpdFile.BiddersFPDResolved { + for bidderName, expectedValue := range testFile.BiddersFPDResolved { actualValue := resultFPD[bidderName] if expectedValue.Site != nil { if len(expectedValue.Site.Ext) > 0 { @@ -715,34 +713,10 @@ func TestExtractFPDForBidders(t *testing.T) { } assert.Equal(t, expectedRequest.User, resultRequest.BidRequest.User, "Incorrect user in request") } - } } } -func loadFpdFile(filename string) (fpdFile, error) { - var fileData fpdFile - fileContents, err := os.ReadFile(filename) - if err != nil { - return fileData, err - } - err = json.Unmarshal(fileContents, &fileData) - if err != nil { - return fileData, err - } - - return fileData, nil -} - -type fpdFile struct { - InputRequestData json.RawMessage `json:"inputRequestData,omitempty"` - OutputRequestData json.RawMessage `json:"outputRequestData,omitempty"` - BidderConfigFPD map[openrtb_ext.BidderName]*openrtb_ext.ORTB2 `json:"bidderConfigFPD,omitempty"` - BiddersFPDResolved map[openrtb_ext.BidderName]*ResolvedFirstPartyData `json:"biddersFPDResolved,omitempty"` - GlobalFPD map[string]json.RawMessage `json:"globalFPD,omitempty"` - ValidationErrors []*errortypes.BadInput `json:"validationErrors,omitempty"` -} - func TestResolveUser(t *testing.T) { testCases := []struct { description string @@ -1927,3 +1901,37 @@ var ( } `) ) + +func loadTestFile[T any](filename string) (T, error) { + var testFile T + + b, err := os.ReadFile(filename) + if err != nil { + return testFile, err + } + + err = json.Unmarshal(b, &testFile) + if err != nil { + return testFile, err + } + + return testFile, nil +} + +type fpdFile struct { + InputRequestData json.RawMessage `json:"inputRequestData,omitempty"` + OutputRequestData json.RawMessage `json:"outputRequestData,omitempty"` + BidderConfigFPD map[openrtb_ext.BidderName]*openrtb_ext.ORTB2 `json:"bidderConfigFPD,omitempty"` + BiddersFPDResolved map[openrtb_ext.BidderName]*ResolvedFirstPartyData `json:"biddersFPDResolved,omitempty"` + GlobalFPD map[string]json.RawMessage `json:"globalFPD,omitempty"` + ValidationErrors []*errortypes.BadInput `json:"validationErrors,omitempty"` +} + +type fpdFileForResolveFPD struct { + InputRequestData json.RawMessage `json:"inputRequestData,omitempty"` + OutputRequestData map[openrtb_ext.BidderName]openrtb2.BidRequest `json:"outputRequestData,omitempty"` + BiddersWithGlobalFPD []string `json:"biddersWithGlobalFPD,omitempty"` + BidderConfigFPD map[openrtb_ext.BidderName]*openrtb_ext.ORTB2 `json:"bidderConfigFPD,omitempty"` + GlobalFPD map[string]json.RawMessage `json:"globalFPD,omitempty"` + ValidationErrors []*errortypes.BadInput `json:"validationErrors,omitempty"` +} diff --git a/firstpartydata/tests/extractbidderconfigfpd/bidder-config-case-normalize.json b/firstpartydata/tests/extractbidderconfigfpd/bidder-config-case-normalize.json new file mode 100644 index 00000000000..934afe47de0 --- /dev/null +++ b/firstpartydata/tests/extractbidderconfigfpd/bidder-config-case-normalize.json @@ -0,0 +1,28 @@ +{ + "description": "Extracts bidder configs for a bidder, normalizing the case for a known bidder", + "inputRequestData": { + "data": {}, + "bidderconfig": [ + { + "bidders": [ + "APPNexus" + ], + "config": { + "ortb2": { + "site": { + "id": "apnSiteId" + } + } + } + } + ] + }, + "outputRequestData": {}, + "bidderConfigFPD": { + "appnexus": { + "site": { + "id": "apnSiteId" + } + } + } +} \ No newline at end of file diff --git a/firstpartydata/tests/extractbidderconfigfpd/bidder-config-duplicated-case-insensitive.json b/firstpartydata/tests/extractbidderconfigfpd/bidder-config-duplicated-case-insensitive.json new file mode 100644 index 00000000000..ed9904579d1 --- /dev/null +++ b/firstpartydata/tests/extractbidderconfigfpd/bidder-config-duplicated-case-insensitive.json @@ -0,0 +1,63 @@ +{ + "description": "Verifies error presence in case more than one bidder config specified for the same bidder, case insensitive", + "inputRequestData": { + "data": {}, + "bidderconfig": [ + { + "bidders": [ + "appnexus" + ], + "config": { + "ortb2": { + "site": { + "id": "apnSiteId", + "ext": { + "data": { + "sitefpddata": "sitefpddata", + "moreFpd": { + "fpd": 123 + }, + "morefpdData": "morefpddata" + } + } + } + } + } + }, + { + "bidders": [ + "APPNEXUS", + "telaria", + "testBidder2" + ], + "config": { + "ortb2": { + "user": { + "id": "telariaUserData", + "ext": { + "data": { + "userdata": "fpduserdata" + } + } + }, + "app": { + "id": "telariaAppData", + "ext": { + "data": { + "appdata": "fpdappdata" + } + } + } + } + } + } + ] + }, + "outputRequestData": {}, + "bidderConfigFPD": {}, + "validationErrors": [ + { + "Message": "multiple First Party Data bidder configs provided for bidder: APPNEXUS" + } + ] +} \ No newline at end of file diff --git a/firstpartydata/tests/extractbidderconfigfpd/bidder-config-request-alias-case-sensitive.json b/firstpartydata/tests/extractbidderconfigfpd/bidder-config-request-alias-case-sensitive.json new file mode 100644 index 00000000000..1becf730ada --- /dev/null +++ b/firstpartydata/tests/extractbidderconfigfpd/bidder-config-request-alias-case-sensitive.json @@ -0,0 +1,28 @@ +{ + "description": "Extracts bidder configs for a bidder, normalizing the case", + "inputRequestData": { + "data": {}, + "bidderconfig": [ + { + "bidders": [ + "requestAlias" + ], + "config": { + "ortb2": { + "site": { + "id": "aliasSiteId" + } + } + } + } + ] + }, + "outputRequestData": {}, + "bidderConfigFPD": { + "requestAlias": { + "site": { + "id": "aliasSiteId" + } + } + } +} \ No newline at end of file diff --git a/firstpartydata/tests/extractfpdforbidders/global-fpd-defined-app-content-data.json b/firstpartydata/tests/extractfpdforbidders/global-fpd-defined-app-content-data.json index 797846ee7a6..6e199f4eb0f 100644 --- a/firstpartydata/tests/extractfpdforbidders/global-fpd-defined-app-content-data.json +++ b/firstpartydata/tests/extractfpdforbidders/global-fpd-defined-app-content-data.json @@ -84,4 +84,4 @@ } }, "validationErrors": [] -} +} \ No newline at end of file diff --git a/firstpartydata/tests/extractfpdforbidders/two-bidders-correct-case-insensitive-integration.json b/firstpartydata/tests/extractfpdforbidders/two-bidders-correct-case-insensitive-integration.json new file mode 100644 index 00000000000..074c8ddef4e --- /dev/null +++ b/firstpartydata/tests/extractfpdforbidders/two-bidders-correct-case-insensitive-integration.json @@ -0,0 +1,88 @@ +{ + "description": "case insensitive known bidder, case sensitive request alias", + "inputRequestData": { + "id": "bid_id", + "site": { + "id": "reqSiteId", + "page": "http://www.foobar.com/1234.html", + "publisher": { + "id": "1" + } + }, + "user": { + "id": "reqUserId" + }, + "test": 1, + "ext": { + "prebid": { + "data": { + "bidders": [ + "APPNEXUS", + "requestAlias" + ] + }, + "bidderconfig": [ + { + "bidders": [ + "appnexus" + ], + "config": { + "ortb2": { + "site": { + "id": "apnSiteId" + }, + "user": { + "id": "apnUserId" + } + } + } + }, + { + "bidders": [ + "requestAlias" + ], + "config": { + "ortb2": { + "user": { + "keywords": "aliasUserKeywords" + } + } + } + } + ] + } + } + }, + "outputRequestData": { + "id": "bid_id", + "site": { + "id": "reqSiteId", + "page": "http://www.foobar.com/1234.html", + "publisher": { + "id": "1" + } + }, + "test": 1 + }, + "biddersFPDResolved": { + "appnexus": { + "site": { + "id": "apnSiteId", + "page": "http://www.foobar.com/1234.html", + "publisher": { + "id": "1" + } + }, + "user": { + "id": "apnUserId" + } + }, + "requestAlias": { + "user": { + "id": "reqUserId", + "keywords": "aliasUserKeywords" + } + } + }, + "validationErrors": [] +} diff --git a/firstpartydata/tests/resolvefpd/bidder-fpd-alias-matches.json b/firstpartydata/tests/resolvefpd/bidder-fpd-alias-matches.json new file mode 100644 index 00000000000..a9062d7ac4b --- /dev/null +++ b/firstpartydata/tests/resolvefpd/bidder-fpd-alias-matches.json @@ -0,0 +1,25 @@ +{ + "description": "Bidder FPD defined with a case sensitive request alias, positive test", + "inputRequestData": { + "app": { + "id": "reqUserID" + } + }, + "biddersWithGlobalFPD": [ + "requestAlias" + ], + "bidderConfigFPD": { + "requestAlias": { + "app": { + "id": "apnAppId" + } + } + }, + "outputRequestData": { + "requestAlias": { + "app": { + "id": "apnAppId" + } + } + } +} \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/bidder-fpd-alias-not-matches.json b/firstpartydata/tests/resolvefpd/bidder-fpd-alias-not-matches.json new file mode 100644 index 00000000000..ffc549c3cef --- /dev/null +++ b/firstpartydata/tests/resolvefpd/bidder-fpd-alias-not-matches.json @@ -0,0 +1,21 @@ +{ + "description": "Bidder FPD defined with a case sensitive request alias, negative test", + "inputRequestData": { + "app": { + "id": "reqUserID" + } + }, + "biddersWithGlobalFPD": [ + "requestAlias" + ], + "bidderConfigFPD": { + "REQUESTALIAS": { + "app": { + "id": "apnAppId" + } + } + }, + "outputRequestData": { + "requestAlias": {} + } +} \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/bidder-fpd-case-normalize.json b/firstpartydata/tests/resolvefpd/bidder-fpd-case-normalize.json new file mode 100644 index 00000000000..1f3e93b153c --- /dev/null +++ b/firstpartydata/tests/resolvefpd/bidder-fpd-case-normalize.json @@ -0,0 +1,25 @@ +{ + "description": "Bidder FPD defined with a case insensitive bidder", + "inputRequestData": { + "app": { + "id": "reqUserID" + } + }, + "biddersWithGlobalFPD": [ + "APPNEXUS" + ], + "bidderConfigFPD": { + "appnexus": { + "app": { + "id": "apnAppId" + } + } + }, + "outputRequestData": { + "appnexus": { + "app": { + "id": "apnAppId" + } + } + } +} \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/bidder-fpd-only-app.json b/firstpartydata/tests/resolvefpd/bidder-fpd-only-app.json index 812db7b10b5..7dc9adee182 100644 --- a/firstpartydata/tests/resolvefpd/bidder-fpd-only-app.json +++ b/firstpartydata/tests/resolvefpd/bidder-fpd-only-app.json @@ -1,30 +1,35 @@ { - "description": "Bidder FPD defined only for app", - "inputRequestData": { - "app": { - "id": "reqUserID" - } - }, - "bidderConfigFPD": { - "appnexus": { - "app": { - "id": "apnAppId", - "ext": { - "data": { - "other": "data" - } - } - } + "description": "Bidder FPD defined only for app", + "inputRequestData": { + "app": { + "id": "reqUserID" + } + }, + "biddersWithGlobalFPD": [ + "appnexus" + ], + "bidderConfigFPD": { + "appnexus": { + "app": { + "id": "apnAppId", + "ext": { + "data": { + "other": "data" + } } - }, - "outputRequestData": { - "app": { - "id": "apnAppId", - "ext": { - "data": { - "other": "data" - } - } + } + } + }, + "outputRequestData": { + "appnexus": { + "app": { + "id": "apnAppId", + "ext": { + "data": { + "other": "data" + } } + } } + } } \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/bidder-fpd-only-site.json b/firstpartydata/tests/resolvefpd/bidder-fpd-only-site.json index 5accfc3b3a0..8ee3b40175b 100644 --- a/firstpartydata/tests/resolvefpd/bidder-fpd-only-site.json +++ b/firstpartydata/tests/resolvefpd/bidder-fpd-only-site.json @@ -1,30 +1,35 @@ { - "description": "Bidder FPD defined only for site", - "inputRequestData": { - "site": { - "id": "reqUserID" - } - }, - "bidderConfigFPD": { - "appnexus": { - "site": { - "id": "apnSiteId", - "ext": { - "data": { - "other": "data" - } - } - } + "description": "Bidder FPD defined only for site", + "inputRequestData": { + "site": { + "id": "reqUserID" + } + }, + "biddersWithGlobalFPD": [ + "appnexus" + ], + "bidderConfigFPD": { + "appnexus": { + "site": { + "id": "apnSiteId", + "ext": { + "data": { + "other": "data" + } } - }, - "outputRequestData": { - "site": { - "id": "apnSiteId", - "ext": { - "data": { - "other": "data" - } - } + } + } + }, + "outputRequestData": { + "appnexus": { + "site": { + "id": "apnSiteId", + "ext": { + "data": { + "other": "data" + } } + } } + } } \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/bidder-fpd-only-user.json b/firstpartydata/tests/resolvefpd/bidder-fpd-only-user.json index 606cee7dbe6..204cf3c8d3f 100644 --- a/firstpartydata/tests/resolvefpd/bidder-fpd-only-user.json +++ b/firstpartydata/tests/resolvefpd/bidder-fpd-only-user.json @@ -1,35 +1,40 @@ { - "description": "Bidder FPD defined only for user", - "inputRequestData": { - "user": { - "id": "reqUserID", - "yob": 1982, - "gender": "M" - } - }, - "bidderConfigFPD": { - "appnexus": { - "user": { - "id": "apnUserId", - "yob": 1982, - "ext": { - "data": { - "other": "data" - } - } - } + "description": "Bidder FPD defined only for user", + "inputRequestData": { + "user": { + "id": "reqUserID", + "yob": 1982, + "gender": "M" + } + }, + "biddersWithGlobalFPD": [ + "appnexus" + ], + "bidderConfigFPD": { + "appnexus": { + "user": { + "id": "apnUserId", + "yob": 1982, + "ext": { + "data": { + "other": "data" + } } - }, - "outputRequestData": { - "user": { - "id": "apnUserId", - "yob": 1982, - "gender": "M", - "ext": { - "data": { - "other": "data" - } - } + } + } + }, + "outputRequestData": { + "appnexus": { + "user": { + "id": "apnUserId", + "yob": 1982, + "gender": "M", + "ext": { + "data": { + "other": "data" + } } + } } + } } \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/bidder-fpd-site-content-data-only.json b/firstpartydata/tests/resolvefpd/bidder-fpd-site-content-data-only.json index 541d51f42af..2008d46f265 100644 --- a/firstpartydata/tests/resolvefpd/bidder-fpd-site-content-data-only.json +++ b/firstpartydata/tests/resolvefpd/bidder-fpd-site-content-data-only.json @@ -28,6 +28,9 @@ "ifa": "123" } }, + "biddersWithGlobalFPD": [ + "appnexus" + ], "bidderConfigFPD": { "appnexus": { "site": { @@ -60,44 +63,46 @@ } }, "outputRequestData": { - "site": { - "id": "apnSiteId", - "name": "apnSiteName", - "domain": "apnSiteDomain", - "page": "http://www.foobar.com/1234.html", - "cat": [ - "books", - "novels" - ], - "search": "book search", - "publisher": { - "id": "1" - }, - "content": { - "episode": 7, - "title": "apnEpisodeName", - "series": "TvName", - "season": "season3", - "len": 600, - "data": [ - { - "id": "siteData3", - "name": "siteName3" + "appnexus": { + "site": { + "id": "apnSiteId", + "name": "apnSiteName", + "domain": "apnSiteDomain", + "page": "http://www.foobar.com/1234.html", + "cat": [ + "books", + "novels" + ], + "search": "book search", + "publisher": { + "id": "1" + }, + "content": { + "episode": 7, + "title": "apnEpisodeName", + "series": "TvName", + "season": "season3", + "len": 600, + "data": [ + { + "id": "siteData3", + "name": "siteName3" + } + ] + }, + "ext": { + "data": { + "other": "data", + "testSiteFpd": "testSite" } - ] - }, - "ext": { - "data": { - "other": "data", - "testSiteFpd": "testSite" } + }, + "device": { + "ua": "testDevice", + "ip": "123.145.167.10", + "devicetype": 1, + "ifa": "123" } - }, - "device": { - "ua": "testDevice", - "ip": "123.145.167.10", - "devicetype": 1, - "ifa": "123" } } } \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-app-content-data-user-data.json b/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-app-content-data-user-data.json index 16b5332e942..7be277eb5ff 100644 --- a/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-app-content-data-user-data.json +++ b/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-app-content-data-user-data.json @@ -14,6 +14,9 @@ "gender": "reqUserGender" } }, + "biddersWithGlobalFPD": [ + "appnexus" + ], "bidderConfigFPD": { "appnexus": { "app": { @@ -55,48 +58,50 @@ ] }, "outputRequestData": { - "app": { - "id": "apnAppId", - "page": "http://www.foobar.com/1234.html", - "publisher": { - "id": "1" + "appnexus": { + "app": { + "id": "apnAppId", + "page": "http://www.foobar.com/1234.html", + "publisher": { + "id": "1" + }, + "content": { + "data": [ + { + "id": "appData1", + "name": "appName1" + }, + { + "id": "appData2", + "name": "appName2" + } + ] + }, + "ext": { + "data": { + "morefpdData": "morefpddata", + "appFpd": 123 + } + } }, - "content": { + "user": { + "id": "reqUserID", + "yob": 1982, + "gender": "reqUserGender", "data": [ { - "id": "appData1", - "name": "appName1" + "id": "userData1", + "name": "userName1" }, { - "id": "appData2", - "name": "appName2" + "id": "userData2", + "name": "userName2" + } + ], + "ext": { + "data": { + "testUserFpd": "testuser" } - ] - }, - "ext": { - "data": { - "morefpdData": "morefpddata", - "appFpd": 123 - } - } - }, - "user": { - "id": "reqUserID", - "yob": 1982, - "gender": "reqUserGender", - "data": [ - { - "id": "userData1", - "name": "userName1" - }, - { - "id": "userData2", - "name": "userName2" - } - ], - "ext": { - "data": { - "testUserFpd": "testuser" } } } diff --git a/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-app.json b/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-app.json index 609ede597cf..fb27d1631c1 100644 --- a/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-app.json +++ b/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-app.json @@ -22,6 +22,9 @@ "ifa": "123" } }, + "biddersWithGlobalFPD": [ + "appnexus" + ], "bidderConfigFPD": { "appnexus": { "app": { @@ -44,36 +47,37 @@ } }, "outputRequestData": { - "app": { - "id": "apnAppId", - "page": "http://www.foobar.com/1234.html", - "publisher": { - "id": "1" - }, - "content": { - "episode": 6, - "title": "episodeName", - "series": "TvName", - "season": "season3", - "len": 900 - }, - "ext": { - "data": { - "moreFpd": { - "fpd": 123 - }, - "morefpdData": "morefpddata", - "appFpd": 123, - "appFpddata": "appFpddata" + "appnexus": { + "app": { + "id": "apnAppId", + "page": "http://www.foobar.com/1234.html", + "publisher": { + "id": "1" + }, + "content": { + "episode": 6, + "title": "episodeName", + "series": "TvName", + "season": "season3", + "len": 900 + }, + "ext": { + "data": { + "moreFpd": { + "fpd": 123 + }, + "morefpdData": "morefpddata", + "appFpd": 123, + "appFpddata": "appFpddata" + } } + }, + "device": { + "ua": "testDevice", + "ip": "123.145.167.10", + "devicetype": 1, + "ifa": "123" } - }, - "device": { - "ua": "testDevice", - "ip": "123.145.167.10", - "devicetype": 1, - "ifa": "123" } } -} - +} \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-site-user.json b/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-site-user.json index f66a8722308..9563fffebcc 100644 --- a/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-site-user.json +++ b/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-site-user.json @@ -19,6 +19,9 @@ "id": "apnUserId" } }, + "biddersWithGlobalFPD": [ + "appnexus" + ], "bidderConfigFPD": { "appnexus": { "site": { @@ -51,40 +54,41 @@ } }, "outputRequestData": { - "site": { - "id": "apnSiteId", - "page": "http://www.foobar.com/1234.html", - "publisher": { - "id": "1" - }, - "content": { - "episode": 6, - "title": "episodeName", - "series": "TvName", - "season": "season3", - "len": 900 - }, - "ext": { - "data": { - "morefpdData": "morefpddata", - "siteFpddata": "siteFpddata", - "moreFpd": { - "fpd": 123 + "appnexus": { + "site": { + "id": "apnSiteId", + "page": "http://www.foobar.com/1234.html", + "publisher": { + "id": "1" + }, + "content": { + "episode": 6, + "title": "episodeName", + "series": "TvName", + "season": "season3", + "len": 900 + }, + "ext": { + "data": { + "morefpdData": "morefpddata", + "siteFpddata": "siteFpddata", + "moreFpd": { + "fpd": 123 + } } } - } - }, - "user": { - "id": "apnUserId", - "ext": { - "data": { - "moreFpd": { - "fpd": 567 - }, - "testUserFpd": "testuser" + }, + "user": { + "id": "apnUserId", + "ext": { + "data": { + "moreFpd": { + "fpd": 567 + }, + "testUserFpd": "testuser" + } } } } } -} - +} \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-site.json b/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-site.json index be03f0cb9b0..4362362718a 100644 --- a/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-site.json +++ b/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-site.json @@ -16,6 +16,9 @@ } } }, + "biddersWithGlobalFPD": [ + "appnexus" + ], "bidderConfigFPD": { "appnexus": { "site": { @@ -40,31 +43,32 @@ } }, "outputRequestData": { - "site": { - "id": "apnSiteId", - "page": "http://www.foobar.com/1234.html", - "ref": "fpdRef", - "publisher": { - "id": "1" - }, - "content": { - "episode": 6, - "title": "episodeName", - "series": "TvName", - "season": "season3", - "len": 900 - }, - "ext": { - "data": { - "moreFpd": { - "fpd": 123 - }, - "morefpdData": "morefpddata", - "siteFpd": 123, - "siteFpddata": "siteFpddata" + "appnexus": { + "site": { + "id": "apnSiteId", + "page": "http://www.foobar.com/1234.html", + "ref": "fpdRef", + "publisher": { + "id": "1" + }, + "content": { + "episode": 6, + "title": "episodeName", + "series": "TvName", + "season": "season3", + "len": 900 + }, + "ext": { + "data": { + "moreFpd": { + "fpd": 123 + }, + "morefpdData": "morefpddata", + "siteFpd": 123, + "siteFpddata": "siteFpddata" + } } } } } -} - +} \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-user.json b/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-user.json index ef381d613e6..4d233e6c473 100644 --- a/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-user.json +++ b/firstpartydata/tests/resolvefpd/global-and-bidder-fpd-user.json @@ -7,6 +7,9 @@ "gender": "M" } }, + "biddersWithGlobalFPD": [ + "appnexus" + ], "bidderConfigFPD": { "appnexus": { "user": { @@ -30,21 +33,22 @@ } }, "outputRequestData": { - "user": { - "id": "apnUserId", - "yob": 1982, - "gender": "M", - "ext": { - "data": { - "testUserFpd": "testuser", - "morefpdData": "morefpddata", - "userFpddata": "siteFpddata", - "moreFpd": { - "fpd": 123 + "appnexus": { + "user": { + "id": "apnUserId", + "yob": 1982, + "gender": "M", + "ext": { + "data": { + "testUserFpd": "testuser", + "morefpdData": "morefpddata", + "userFpddata": "siteFpddata", + "moreFpd": { + "fpd": 123 + } } } } } } -} - +} \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/global-and-bidder-site-content-data.json b/firstpartydata/tests/resolvefpd/global-and-bidder-site-content-data.json index c0f4723d62a..a0a1c461292 100644 --- a/firstpartydata/tests/resolvefpd/global-and-bidder-site-content-data.json +++ b/firstpartydata/tests/resolvefpd/global-and-bidder-site-content-data.json @@ -20,6 +20,9 @@ "gender": "M" } }, + "biddersWithGlobalFPD": [ + "appnexus" + ], "bidderConfigFPD": { "appnexus": { "site": { @@ -62,52 +65,53 @@ ] }, "outputRequestData": { - "site": { - "id": "apnSiteId", - "page": "http://www.foobar.com/1234.html", - "ref": "fpdRef", - "publisher": { - "id": "1" - }, - "content": { - "data": [ - { - "id": "siteData1", - "name": "siteName1" - }, - { - "id": "siteData2", - "name": "siteName2" + "appnexus": { + "site": { + "id": "apnSiteId", + "page": "http://www.foobar.com/1234.html", + "ref": "fpdRef", + "publisher": { + "id": "1" + }, + "content": { + "data": [ + { + "id": "siteData1", + "name": "siteName1" + }, + { + "id": "siteData2", + "name": "siteName2" + } + ] + }, + "ext": { + "data": { + "moreFpd": { + "fpd": 123 + }, + "morefpdData": "morefpddata", + "siteFpd": 123, + "siteFpddata": "siteFpddata" } - ] - }, - "ext": { - "data": { - "moreFpd": { - "fpd": 123 - }, - "morefpdData": "morefpddata", - "siteFpd": 123, - "siteFpddata": "siteFpddata" } - } - }, - "device": { - "ua": "testDevice", - "ip": "123.145.167.10", - "devicetype": 1, - "ifa": "123" - }, - "user": { - "id": "reqUserID", - "yob": 1982, - "gender": "M", - "ext": { - "data": { - "testUserFpd": "testuser" + }, + "device": { + "ua": "testDevice", + "ip": "123.145.167.10", + "devicetype": 1, + "ifa": "123" + }, + "user": { + "id": "reqUserID", + "yob": 1982, + "gender": "M", + "ext": { + "data": { + "testUserFpd": "testuser" + } } } } } -} - +} \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/global-and-no-bidder-fpd-site-app-user.json b/firstpartydata/tests/resolvefpd/global-and-no-bidder-fpd-site-app-user.json index a705e8b2405..e8dace465e7 100644 --- a/firstpartydata/tests/resolvefpd/global-and-no-bidder-fpd-site-app-user.json +++ b/firstpartydata/tests/resolvefpd/global-and-no-bidder-fpd-site-app-user.json @@ -23,6 +23,9 @@ "gender": "M" } }, + "biddersWithGlobalFPD": [ + "appnexus" + ], "bidderConfigFPD": { "appnexus": { "site": { @@ -72,58 +75,59 @@ ] }, "outputRequestData": { - "site": { - "id": "apnSiteId", - "page": "http://www.foobar.com/1234.html", - "ref": "fpdRef", - "publisher": { - "id": "1" - }, - "content": { - "title": "episodeName8", - "series": "TvName", - "season": "season4", - "episode": 8, - "len": 900, - "data": [ - { - "id": "siteData1", - "name": "siteName1" - }, - { - "id": "siteData2", - "name": "siteName2" + "appnexus": { + "site": { + "id": "apnSiteId", + "page": "http://www.foobar.com/1234.html", + "ref": "fpdRef", + "publisher": { + "id": "1" + }, + "content": { + "title": "episodeName8", + "series": "TvName", + "season": "season4", + "episode": 8, + "len": 900, + "data": [ + { + "id": "siteData1", + "name": "siteName1" + }, + { + "id": "siteData2", + "name": "siteName2" + } + ] + }, + "ext": { + "testSiteExt": 123, + "data": { + "moreFpd": { + "fpd": 123 + }, + "morefpdData": "morefpddata", + "siteFpd": 123, + "siteFpddata": "siteFpddata" } - ] - }, - "ext": { - "testSiteExt": 123, - "data": { - "moreFpd": { - "fpd": 123 - }, - "morefpdData": "morefpddata", - "siteFpd": 123, - "siteFpddata": "siteFpddata" } - } - }, - "device": { - "ua": "testDevice", - "ip": "123.145.167.10", - "devicetype": 1, - "ifa": "123" - }, - "user": { - "id": "reqUserID", - "yob": 1982, - "gender": "M", - "ext": { - "data": { - "testUserFpd": "testuser" + }, + "device": { + "ua": "testDevice", + "ip": "123.145.167.10", + "devicetype": 1, + "ifa": "123" + }, + "user": { + "id": "reqUserID", + "yob": 1982, + "gender": "M", + "ext": { + "data": { + "testUserFpd": "testuser" + } } } } } -} - +} \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/global-and-no-bidder-fpd-site-content-app-user.json b/firstpartydata/tests/resolvefpd/global-and-no-bidder-fpd-site-content-app-user.json index ccfa030cd8d..10fa471744f 100644 --- a/firstpartydata/tests/resolvefpd/global-and-no-bidder-fpd-site-content-app-user.json +++ b/firstpartydata/tests/resolvefpd/global-and-no-bidder-fpd-site-content-app-user.json @@ -23,6 +23,9 @@ "gender": "M" } }, + "biddersWithGlobalFPD": [ + "appnexus" + ], "bidderConfigFPD": { "appnexus": { "site": { @@ -65,53 +68,54 @@ ] }, "outputRequestData": { - "site": { - "id": "apnSiteId", - "page": "http://www.foobar.com/1234.html", - "ref": "fpdRef", - "publisher": { - "id": "1" - }, - "content": { - "data": [ - { - "id": "siteData1", - "name": "siteName1" - }, - { - "id": "siteData2", - "name": "siteName2" + "appnexus": { + "site": { + "id": "apnSiteId", + "page": "http://www.foobar.com/1234.html", + "ref": "fpdRef", + "publisher": { + "id": "1" + }, + "content": { + "data": [ + { + "id": "siteData1", + "name": "siteName1" + }, + { + "id": "siteData2", + "name": "siteName2" + } + ] + }, + "ext": { + "testSiteExt": 123, + "data": { + "moreFpd": { + "fpd": 123 + }, + "morefpdData": "morefpddata", + "siteFpd": 123, + "siteFpddata": "siteFpddata" } - ] - }, - "ext": { - "testSiteExt": 123, - "data": { - "moreFpd": { - "fpd": 123 - }, - "morefpdData": "morefpddata", - "siteFpd": 123, - "siteFpddata": "siteFpddata" } - } - }, - "device": { - "ua": "testDevice", - "ip": "123.145.167.10", - "devicetype": 1, - "ifa": "123" - }, - "user": { - "id": "reqUserID", - "yob": 1982, - "gender": "M", - "ext": { - "data": { - "testUserFpd": "testuser" + }, + "device": { + "ua": "testDevice", + "ip": "123.145.167.10", + "devicetype": 1, + "ifa": "123" + }, + "user": { + "id": "reqUserID", + "yob": 1982, + "gender": "M", + "ext": { + "data": { + "testUserFpd": "testuser" + } } } } } -} - +} \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/global-fpd-only-app.json b/firstpartydata/tests/resolvefpd/global-fpd-only-app.json index e4d5e169986..55839983a5b 100644 --- a/firstpartydata/tests/resolvefpd/global-fpd-only-app.json +++ b/firstpartydata/tests/resolvefpd/global-fpd-only-app.json @@ -29,6 +29,9 @@ "gender": "M" } }, + "biddersWithGlobalFPD": [ + "appnexus" + ], "bidderConfigFPD": { "appnexus": { "app": { @@ -64,56 +67,57 @@ ] }, "outputRequestData": { - "app": { - "id": "apnAppId", - "publisher": { - "id": "1" - }, - "content": { - "episode": 6, - "title": "episodeName", - "series": "TvName", - "season": "season3", - "len": 900, - "data": [ - { - "id": "appData1", - "name": "appName1" - }, - { - "id": "appData2", - "name": "appName2" + "appnexus": { + "app": { + "id": "apnAppId", + "publisher": { + "id": "1" + }, + "content": { + "episode": 6, + "title": "episodeName", + "series": "TvName", + "season": "season3", + "len": 900, + "data": [ + { + "id": "appData1", + "name": "appName1" + }, + { + "id": "appData2", + "name": "appName2" + } + ] + }, + "ext": { + "testAppExt": 123, + "data": { + "moreFpd": { + "fpd": 123 + }, + "morefpdData": "morefpddata", + "appFpd": 123, + "appFpddata": "appFpddata" } - ] - }, - "ext": { - "testAppExt": 123, - "data": { - "moreFpd": { - "fpd": 123 - }, - "morefpdData": "morefpddata", - "appFpd": 123, - "appFpddata": "appFpddata" } - } - }, - "device": { - "ua": "testDevice", - "ip": "123.145.167.10", - "devicetype": 1, - "ifa": "123" - }, - "user": { - "id": "reqUserID", - "yob": 1982, - "gender": "M", - "ext": { - "data": { - "testUserFpd": "testuser" + }, + "device": { + "ua": "testDevice", + "ip": "123.145.167.10", + "devicetype": 1, + "ifa": "123" + }, + "user": { + "id": "reqUserID", + "yob": 1982, + "gender": "M", + "ext": { + "data": { + "testUserFpd": "testuser" + } } } } } -} - +} \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/global-fpd-only-excludes-some.json b/firstpartydata/tests/resolvefpd/global-fpd-only-excludes-some.json new file mode 100644 index 00000000000..b23a347cf9b --- /dev/null +++ b/firstpartydata/tests/resolvefpd/global-fpd-only-excludes-some.json @@ -0,0 +1,138 @@ +{ + "description": "Global and bidder FPD defined for site and user. Global FPD has site.content.data. Excludes rubicon since not listed in biddersWithGlobalFPD", + "inputRequestData": { + "site": { + "id": "reqSiteId", + "page": "http://www.foobar.com/1234.html", + "publisher": { + "id": "1" + }, + "content": { + "episode": 6, + "title": "episodeName", + "series": "TvName", + "season": "season3", + "len": 900 + }, + "ext": { + "testSiteExt": 123 + } + }, + "device": { + "ua": "testDevice", + "ip": "123.145.167.10", + "devicetype": 1, + "ifa": "123" + }, + "user": { + "id": "reqUserID", + "yob": 1982, + "gender": "M" + } + }, + "biddersWithGlobalFPD": [ + "appnexus" + ], + "bidderConfigFPD": { + "appnexus": { + "site": { + "id": "apnSiteId", + "page": "http://www.foobar.com/1234.html", + "ref": "fpdRef", + "ext": { + "data": { + "morefpdData": "morefpddata", + "siteFpddata": "siteFpddata", + "moreFpd": { + "fpd": 123 + } + } + } + } + }, + "rubicon": { + "site": { + "id": "rbcSiteId" + } + } + }, + "globalFPD": { + "site": { + "siteFpd": 123 + }, + "app": { + "appFpd": { + "testValue": true + } + }, + "user": { + "testUserFpd": "testuser" + }, + "siteContentData": [ + { + "id": "siteData1", + "name": "siteName1" + }, + { + "id": "siteData2", + "name": "siteName2" + } + ] + }, + "outputRequestData": { + "appnexus": { + "site": { + "id": "apnSiteId", + "page": "http://www.foobar.com/1234.html", + "ref": "fpdRef", + "publisher": { + "id": "1" + }, + "content": { + "episode": 6, + "title": "episodeName", + "series": "TvName", + "season": "season3", + "len": 900, + "data": [ + { + "id": "siteData1", + "name": "siteName1" + }, + { + "id": "siteData2", + "name": "siteName2" + } + ] + }, + "ext": { + "testSiteExt": 123, + "data": { + "moreFpd": { + "fpd": 123 + }, + "morefpdData": "morefpddata", + "siteFpd": 123, + "siteFpddata": "siteFpddata" + } + } + }, + "device": { + "ua": "testDevice", + "ip": "123.145.167.10", + "devicetype": 1, + "ifa": "123" + }, + "user": { + "id": "reqUserID", + "yob": 1982, + "gender": "M", + "ext": { + "data": { + "testUserFpd": "testuser" + } + } + } + } + } +} \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/global-fpd-only-include-all-explicit.json b/firstpartydata/tests/resolvefpd/global-fpd-only-include-all-explicit.json new file mode 100644 index 00000000000..f959ebcde4f --- /dev/null +++ b/firstpartydata/tests/resolvefpd/global-fpd-only-include-all-explicit.json @@ -0,0 +1,144 @@ +{ + "description": "Global and bidder FPD defined for site and user. Global FPD has site.content.data. Bidders mentioned explicitly in biddersWithGlobalFPD", + "inputRequestData": { + "site": { + "id": "reqSiteId", + "page": "http://www.foobar.com/1234.html", + "publisher": { + "id": "1" + }, + "content": { + "episode": 6, + "title": "episodeName", + "series": "TvName", + "season": "season3", + "len": 900 + }, + "ext": { + "testSiteExt": 123 + } + }, + "device": { + "ua": "testDevice", + "ip": "123.145.167.10", + "devicetype": 1, + "ifa": "123" + }, + "user": { + "id": "reqUserID", + "yob": 1982, + "gender": "M" + } + }, + "biddersWithGlobalFPD": [ + "appnexus", + "rubicon" + ], + "bidderConfigFPD": { + "appnexus": { + "site": { + "id": "apnSiteId", + "page": "http://www.foobar.com/1234.html", + "ref": "fpdRef", + "ext": { + "data": { + "morefpdData": "morefpddata", + "siteFpddata": "siteFpddata", + "moreFpd": { + "fpd": 123 + } + } + } + } + }, + "rubicon": { + "site": { + "id": "rbcSiteId" + } + } + }, + "globalFPD": { + "site": { + "siteFpd": 123 + }, + "app": { + "appFpd": { + "testValue": true + } + }, + "user": { + "testUserFpd": "testuser" + }, + "siteContentData": [ + { + "id": "siteData1", + "name": "siteName1" + }, + { + "id": "siteData2", + "name": "siteName2" + } + ] + }, + "outputRequestData": { + "appnexus": { + "site": { + "id": "apnSiteId", + "page": "http://www.foobar.com/1234.html", + "ref": "fpdRef", + "publisher": { + "id": "1" + }, + "content": { + "episode": 6, + "title": "episodeName", + "series": "TvName", + "season": "season3", + "len": 900, + "data": [ + { + "id": "siteData1", + "name": "siteName1" + }, + { + "id": "siteData2", + "name": "siteName2" + } + ] + }, + "ext": { + "testSiteExt": 123, + "data": { + "moreFpd": { + "fpd": 123 + }, + "morefpdData": "morefpddata", + "siteFpd": 123, + "siteFpddata": "siteFpddata" + } + } + }, + "device": { + "ua": "testDevice", + "ip": "123.145.167.10", + "devicetype": 1, + "ifa": "123" + }, + "user": { + "id": "reqUserID", + "yob": 1982, + "gender": "M", + "ext": { + "data": { + "testUserFpd": "testuser" + } + } + } + }, + "rubicon": { + "site": { + "id": "rbcSiteId" + } + } + } +} \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/global-fpd-only-include-all-implicit.json b/firstpartydata/tests/resolvefpd/global-fpd-only-include-all-implicit.json new file mode 100644 index 00000000000..7c1f0f10aff --- /dev/null +++ b/firstpartydata/tests/resolvefpd/global-fpd-only-include-all-implicit.json @@ -0,0 +1,141 @@ +{ + "description": "Global and bidder FPD defined for site and user. Global FPD has site.content.data. Bidders included implicitly with biddersWithGlobalFPD nil", + "inputRequestData": { + "site": { + "id": "reqSiteId", + "page": "http://www.foobar.com/1234.html", + "publisher": { + "id": "1" + }, + "content": { + "episode": 6, + "title": "episodeName", + "series": "TvName", + "season": "season3", + "len": 900 + }, + "ext": { + "testSiteExt": 123 + } + }, + "device": { + "ua": "testDevice", + "ip": "123.145.167.10", + "devicetype": 1, + "ifa": "123" + }, + "user": { + "id": "reqUserID", + "yob": 1982, + "gender": "M" + } + }, + "biddersWithGlobalFPD": null, + "bidderConfigFPD": { + "appnexus": { + "site": { + "id": "apnSiteId", + "page": "http://www.foobar.com/1234.html", + "ref": "fpdRef", + "ext": { + "data": { + "morefpdData": "morefpddata", + "siteFpddata": "siteFpddata", + "moreFpd": { + "fpd": 123 + } + } + } + } + }, + "rubicon": { + "site": { + "id": "rbcSiteId" + } + } + }, + "globalFPD": { + "site": { + "siteFpd": 123 + }, + "app": { + "appFpd": { + "testValue": true + } + }, + "user": { + "testUserFpd": "testuser" + }, + "siteContentData": [ + { + "id": "siteData1", + "name": "siteName1" + }, + { + "id": "siteData2", + "name": "siteName2" + } + ] + }, + "outputRequestData": { + "appnexus": { + "site": { + "id": "apnSiteId", + "page": "http://www.foobar.com/1234.html", + "ref": "fpdRef", + "publisher": { + "id": "1" + }, + "content": { + "episode": 6, + "title": "episodeName", + "series": "TvName", + "season": "season3", + "len": 900, + "data": [ + { + "id": "siteData1", + "name": "siteName1" + }, + { + "id": "siteData2", + "name": "siteName2" + } + ] + }, + "ext": { + "testSiteExt": 123, + "data": { + "moreFpd": { + "fpd": 123 + }, + "morefpdData": "morefpddata", + "siteFpd": 123, + "siteFpddata": "siteFpddata" + } + } + }, + "device": { + "ua": "testDevice", + "ip": "123.145.167.10", + "devicetype": 1, + "ifa": "123" + }, + "user": { + "id": "reqUserID", + "yob": 1982, + "gender": "M", + "ext": { + "data": { + "testUserFpd": "testuser" + } + } + } + }, + "rubicon": { + "site": { + "id": "rbcSiteId" + } + } + } +} \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/global-fpd-only-site.json b/firstpartydata/tests/resolvefpd/global-fpd-only-site.json index 49b8f4dcefb..3f7e91adc63 100644 --- a/firstpartydata/tests/resolvefpd/global-fpd-only-site.json +++ b/firstpartydata/tests/resolvefpd/global-fpd-only-site.json @@ -30,6 +30,9 @@ "gender": "M" } }, + "biddersWithGlobalFPD": [ + "appnexus" + ], "bidderConfigFPD": { "appnexus": { "site": { @@ -72,58 +75,59 @@ ] }, "outputRequestData": { - "site": { - "id": "apnSiteId", - "page": "http://www.foobar.com/1234.html", - "ref": "fpdRef", - "publisher": { - "id": "1" - }, - "content": { - "episode": 6, - "title": "episodeName", - "series": "TvName", - "season": "season3", - "len": 900, - "data": [ - { - "id": "siteData1", - "name": "siteName1" - }, - { - "id": "siteData2", - "name": "siteName2" + "appnexus": { + "site": { + "id": "apnSiteId", + "page": "http://www.foobar.com/1234.html", + "ref": "fpdRef", + "publisher": { + "id": "1" + }, + "content": { + "episode": 6, + "title": "episodeName", + "series": "TvName", + "season": "season3", + "len": 900, + "data": [ + { + "id": "siteData1", + "name": "siteName1" + }, + { + "id": "siteData2", + "name": "siteName2" + } + ] + }, + "ext": { + "testSiteExt": 123, + "data": { + "moreFpd": { + "fpd": 123 + }, + "morefpdData": "morefpddata", + "siteFpd": 123, + "siteFpddata": "siteFpddata" } - ] - }, - "ext": { - "testSiteExt": 123, - "data": { - "moreFpd": { - "fpd": 123 - }, - "morefpdData": "morefpddata", - "siteFpd": 123, - "siteFpddata": "siteFpddata" } - } - }, - "device": { - "ua": "testDevice", - "ip": "123.145.167.10", - "devicetype": 1, - "ifa": "123" - }, - "user": { - "id": "reqUserID", - "yob": 1982, - "gender": "M", - "ext": { - "data": { - "testUserFpd": "testuser" + }, + "device": { + "ua": "testDevice", + "ip": "123.145.167.10", + "devicetype": 1, + "ifa": "123" + }, + "user": { + "id": "reqUserID", + "yob": 1982, + "gender": "M", + "ext": { + "data": { + "testUserFpd": "testuser" + } } } } } -} - +} \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/req-and-bidder-fpd-site-content.json b/firstpartydata/tests/resolvefpd/req-and-bidder-fpd-site-content.json index 446e7151afa..da0d4357dd1 100644 --- a/firstpartydata/tests/resolvefpd/req-and-bidder-fpd-site-content.json +++ b/firstpartydata/tests/resolvefpd/req-and-bidder-fpd-site-content.json @@ -40,6 +40,9 @@ "gender": "M" } }, + "biddersWithGlobalFPD": [ + "appnexus" + ], "bidderConfigFPD": { "appnexus": { "site": { @@ -89,58 +92,59 @@ } }, "outputRequestData": { - "site": { - "id": "apnSiteId", - "page": "http://www.foobar.com/1234.html", - "ref": "fpdRef", - "publisher": { - "id": "1" - }, - "content": { - "episode": 8, - "title": "episodeName8", - "series": "TvName", - "season": "season4", - "len": 900, - "data": [ - { - "id": "siteData1", - "name": "siteName1" - }, - { - "id": "siteData2", - "name": "siteName2" + "appnexus": { + "site": { + "id": "apnSiteId", + "page": "http://www.foobar.com/1234.html", + "ref": "fpdRef", + "publisher": { + "id": "1" + }, + "content": { + "episode": 8, + "title": "episodeName8", + "series": "TvName", + "season": "season4", + "len": 900, + "data": [ + { + "id": "siteData1", + "name": "siteName1" + }, + { + "id": "siteData2", + "name": "siteName2" + } + ] + }, + "ext": { + "testSiteExt": 123, + "data": { + "moreFpd": { + "fpd": 123 + }, + "morefpdData": "morefpddata", + "siteFpd": 123, + "siteFpddata": "siteFpddata" } - ] - }, - "ext": { - "testSiteExt": 123, - "data": { - "moreFpd": { - "fpd": 123 - }, - "morefpdData": "morefpddata", - "siteFpd": 123, - "siteFpddata": "siteFpddata" } - } - }, - "device": { - "ua": "testDevice", - "ip": "123.145.167.10", - "devicetype": 1, - "ifa": "123" - }, - "user": { - "id": "reqUserID", - "yob": 1982, - "gender": "M", - "ext": { - "data": { - "testUserFpd": "testuser" + }, + "device": { + "ua": "testDevice", + "ip": "123.145.167.10", + "devicetype": 1, + "ifa": "123" + }, + "user": { + "id": "reqUserID", + "yob": 1982, + "gender": "M", + "ext": { + "data": { + "testUserFpd": "testuser" + } } } } } -} - +} \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/req-app-not-defined.json b/firstpartydata/tests/resolvefpd/req-app-not-defined.json index f24a4d27db1..6ab9e076f43 100644 --- a/firstpartydata/tests/resolvefpd/req-app-not-defined.json +++ b/firstpartydata/tests/resolvefpd/req-app-not-defined.json @@ -20,6 +20,9 @@ "gender": "M" } }, + "biddersWithGlobalFPD": [ + "appnexus" + ], "bidderConfigFPD": { "appnexus": { "app": { @@ -42,5 +45,4 @@ "Message": "incorrect First Party Data for bidder appnexus: App object is not defined in request, but defined in FPD config" } ] -} - +} \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/req-site-not-defined.json b/firstpartydata/tests/resolvefpd/req-site-not-defined.json index d078ad7804f..8e20a6e0e1d 100644 --- a/firstpartydata/tests/resolvefpd/req-site-not-defined.json +++ b/firstpartydata/tests/resolvefpd/req-site-not-defined.json @@ -7,6 +7,9 @@ "gender": "M" } }, + "biddersWithGlobalFPD": [ + "appnexus" + ], "bidderConfigFPD": { "appnexus": { "site": { @@ -29,5 +32,4 @@ "Message": "incorrect First Party Data for bidder appnexus: Site object is not defined in request, but defined in FPD config" } ] -} - +} \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/req-user-not-defined.json b/firstpartydata/tests/resolvefpd/req-user-not-defined.json index 76ae3f827ca..85c41c23969 100644 --- a/firstpartydata/tests/resolvefpd/req-user-not-defined.json +++ b/firstpartydata/tests/resolvefpd/req-user-not-defined.json @@ -5,6 +5,9 @@ "at": 1, "tmax": 5000 }, + "biddersWithGlobalFPD": [ + "appnexus" + ], "bidderConfigFPD": { "appnexus": { "user": { @@ -21,11 +24,12 @@ } } }, - "outputRequestData": {}, + "outputRequestData": { + "appnexus": {} + }, "validationErrors": [ { "Message": "incorrect First Party Data for bidder appnexus: User object is not defined in request, but defined in FPD config" } ] -} - +} \ No newline at end of file diff --git a/firstpartydata/tests/resolvefpd/site-page-empty-conflict.json b/firstpartydata/tests/resolvefpd/site-page-empty-conflict.json index 8da3dc69329..260385c49be 100644 --- a/firstpartydata/tests/resolvefpd/site-page-empty-conflict.json +++ b/firstpartydata/tests/resolvefpd/site-page-empty-conflict.json @@ -19,6 +19,9 @@ "gender": "M" } }, + "biddersWithGlobalFPD": [ + "appnexus" + ], "bidderConfigFPD": { "appnexus": { "site": { @@ -41,5 +44,4 @@ "Message": "incorrect First Party Data for bidder appnexus: Site object cannot set empty page if req.site.id is empty" } ] -} - +} \ No newline at end of file diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 1caa625c0d1..2258cad4214 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -563,6 +563,15 @@ func NormalizeBidderName(name string) (BidderName, bool) { return bidderName, exists } +// NormalizeBidderNameOrUnchanged returns the normalized name of known bidders, otherwise returns +// the name exactly as provided. +func NormalizeBidderNameOrUnchanged(name string) BidderName { + if normalized, exists := NormalizeBidderName(name); exists { + return normalized + } + return BidderName(name) +} + // The BidderParamValidator is used to enforce bidrequest.imp[i].ext.prebid.bidder.{anyBidder} values. // // This is treated differently from the other types because we rely on JSON-schemas to validate bidder params. From bde7bcf096b388186c183d3282b0c3bb75aeddaf Mon Sep 17 00:00:00 2001 From: guscarreon Date: Wed, 18 Oct 2023 02:19:04 -0400 Subject: [PATCH 181/268] Adapter Name Case Insensitive: ext.prebid.multibid (#3217) --- exchange/exchange.go | 8 +- exchange/exchange_test.go | 197 ++++++++ .../exchangetest/multi-bids-mixed-case.json | 449 ++++++++++++++++++ exchange/utils.go | 4 +- 4 files changed, 654 insertions(+), 4 deletions(-) create mode 100644 exchange/exchangetest/multi-bids-mixed-case.json diff --git a/exchange/exchange.go b/exchange/exchange.go index 0810ad814ab..a8c76a5ebb1 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -515,10 +515,14 @@ func buildMultiBidMap(prebid *openrtb_ext.ExtRequestPrebid) map[string]openrtb_e multiBidMap := make(map[string]openrtb_ext.ExtMultiBid) for _, multiBid := range prebid.MultiBid { if multiBid.Bidder != "" { - multiBidMap[multiBid.Bidder] = *multiBid + if bidderNormalized, bidderFound := openrtb_ext.NormalizeBidderName(multiBid.Bidder); bidderFound { + multiBidMap[string(bidderNormalized)] = *multiBid + } } else { for _, bidder := range multiBid.Bidders { - multiBidMap[bidder] = *multiBid + if bidderNormalized, bidderFound := openrtb_ext.NormalizeBidderName(bidder); bidderFound { + multiBidMap[string(bidderNormalized)] = *multiBid + } } } } diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go index 6e6e8afe76e..e57900cdfee 100644 --- a/exchange/exchange_test.go +++ b/exchange/exchange_test.go @@ -2259,8 +2259,13 @@ func TestTimeoutComputation(t *testing.T) { func TestExchangeJSON(t *testing.T) { if specFiles, err := os.ReadDir("./exchangetest"); err == nil { for _, specFile := range specFiles { + if !strings.HasSuffix(specFile.Name(), ".json") { + continue + } + fileName := "./exchangetest/" + specFile.Name() fileDisplayName := "exchange/exchangetest/" + specFile.Name() + t.Run(fileDisplayName, func(t *testing.T) { specData, err := loadFile(fileName) if assert.NoError(t, err, "Failed to load contents of file %s: %v", fileDisplayName, err) { @@ -5750,3 +5755,195 @@ func TestSetSeatNonBid(t *testing.T) { }) } } + +func TestBuildMultiBidMap(t *testing.T) { + type testCase struct { + desc string + inPrebid *openrtb_ext.ExtRequestPrebid + expected map[string]openrtb_ext.ExtMultiBid + } + testGroups := []struct { + groupDesc string + tests []testCase + }{ + { + groupDesc: "Nil or empty tests", + tests: []testCase{ + { + desc: "prebid nil, expect nil map", + inPrebid: nil, + expected: nil, + }, + { + desc: "prebid.MultiBid nil, expect nil map", + inPrebid: &openrtb_ext.ExtRequestPrebid{}, + expected: nil, + }, + { + desc: "not-nil prebid.MultiBid is empty, expect empty map", + inPrebid: &openrtb_ext.ExtRequestPrebid{ + MultiBid: []*openrtb_ext.ExtMultiBid{}, + }, + expected: map[string]openrtb_ext.ExtMultiBid{}, + }, + }, + }, + { + groupDesc: "prebid.MultiBid.Bidder tests", + tests: []testCase{ + { + desc: "Lowercase prebid.MultiBid.Bidder is found in the BidderName list, entry is mapped", + inPrebid: &openrtb_ext.ExtRequestPrebid{ + MultiBid: []*openrtb_ext.ExtMultiBid{ + {Bidder: "appnexus"}, + }, + }, + expected: map[string]openrtb_ext.ExtMultiBid{ + "appnexus": {Bidder: "appnexus"}, + }, + }, + { + desc: "Uppercase prebid.MultiBid.Bidder is found in the BidderName list, entry is mapped", + inPrebid: &openrtb_ext.ExtRequestPrebid{ + MultiBid: []*openrtb_ext.ExtMultiBid{ + {Bidder: "APPNEXUS"}, + }, + }, + expected: map[string]openrtb_ext.ExtMultiBid{ + "appnexus": {Bidder: "APPNEXUS"}, + }, + }, + { + desc: "Lowercase prebid.MultiBid.Bidder is not found in the BidderName list, expect empty map", + inPrebid: &openrtb_ext.ExtRequestPrebid{ + MultiBid: []*openrtb_ext.ExtMultiBid{ + {Bidder: "unknown"}, + }, + }, + expected: map[string]openrtb_ext.ExtMultiBid{}, + }, + { + desc: "Mixed-case prebid.MultiBid.Bidder is not found in the BidderName list, expect empty map", + inPrebid: &openrtb_ext.ExtRequestPrebid{ + MultiBid: []*openrtb_ext.ExtMultiBid{ + {Bidder: "UnknownBidder"}, + }, + }, + expected: map[string]openrtb_ext.ExtMultiBid{}, + }, + { + desc: "Different-cased prebid.MultiBid.Bidder entries that refer to the same adapter are found in the BidderName list are mapped once", + inPrebid: &openrtb_ext.ExtRequestPrebid{ + MultiBid: []*openrtb_ext.ExtMultiBid{ + {Bidder: "AppNexus"}, + {Bidder: "appnexus"}, + }, + }, + expected: map[string]openrtb_ext.ExtMultiBid{ + "appnexus": {Bidder: "appnexus"}, + }, + }, + }, + }, + { + groupDesc: "prebid.MultiBid.Bidders tests", + tests: []testCase{ + { + desc: "Lowercase prebid.MultiBid.Bidder is found in the BidderName list, entry is mapped", + inPrebid: &openrtb_ext.ExtRequestPrebid{ + MultiBid: []*openrtb_ext.ExtMultiBid{ + {Bidders: []string{"appnexus"}}, + }, + }, + expected: map[string]openrtb_ext.ExtMultiBid{ + "appnexus": { + Bidders: []string{"appnexus"}, + }, + }, + }, + { + desc: "Lowercase prebid.MultiBid.Bidder is not found in the BidderName list, expect empty map", + inPrebid: &openrtb_ext.ExtRequestPrebid{ + MultiBid: []*openrtb_ext.ExtMultiBid{ + {Bidders: []string{"unknown"}}, + }, + }, + expected: map[string]openrtb_ext.ExtMultiBid{}, + }, + { + desc: "Mixed-case prebid.MultiBid.Bidder is not found in the BidderName list, expect empty map", + inPrebid: &openrtb_ext.ExtRequestPrebid{ + MultiBid: []*openrtb_ext.ExtMultiBid{ + {Bidders: []string{"UnknownBidder"}}, + }, + }, + expected: map[string]openrtb_ext.ExtMultiBid{}, + }, + { + desc: "Different-cased prebid.MultiBid.Bidder entries that refer to the same adapter are found in the BidderName list are mapped once", + inPrebid: &openrtb_ext.ExtRequestPrebid{ + MultiBid: []*openrtb_ext.ExtMultiBid{ + {Bidders: []string{"AppNexus", "appnexus", "UnknownBidder"}}, + }, + }, + expected: map[string]openrtb_ext.ExtMultiBid{ + "appnexus": { + Bidders: []string{"AppNexus", "appnexus", "UnknownBidder"}, + }, + }, + }, + }, + }, + { + groupDesc: "prebid.MultiBid.Bidder and prebid.MultiBid.Bidders entries in tests", + tests: []testCase{ + { + desc: "prebid.MultiBid.Bidder found, ignore entries in prebid.MultiBid.Bidders, even if its unknown", + inPrebid: &openrtb_ext.ExtRequestPrebid{ + MultiBid: []*openrtb_ext.ExtMultiBid{ + { + Bidder: "UnknownBidder", + Bidders: []string{"appnexus", "rubicon", "pubmatic"}, + }, + }, + }, + expected: map[string]openrtb_ext.ExtMultiBid{}, + }, + { + desc: "prebid.MultiBid.Bidder found in one entry, prebid.MultiBid.Bidders in another. Add all to map", + inPrebid: &openrtb_ext.ExtRequestPrebid{ + MultiBid: []*openrtb_ext.ExtMultiBid{ + { + Bidder: "pubmatic", + Bidders: []string{"appnexus", "rubicon", "UnknownBidder"}, + }, + { + Bidders: []string{"UnknownBidder", "appnexus", "rubicon"}, + }, + }, + }, + expected: map[string]openrtb_ext.ExtMultiBid{ + "pubmatic": { + Bidder: "pubmatic", + Bidders: []string{"appnexus", "rubicon", "UnknownBidder"}, + }, + "appnexus": { + Bidders: []string{"UnknownBidder", "appnexus", "rubicon"}, + }, + "rubicon": { + Bidders: []string{"UnknownBidder", "appnexus", "rubicon"}, + }, + }, + }, + }, + }, + } + for _, group := range testGroups { + for _, tc := range group.tests { + t.Run(group.groupDesc+tc.desc, func(t *testing.T) { + multiBidMap := buildMultiBidMap(tc.inPrebid) + assert.Equal(t, tc.expected, multiBidMap, tc.desc) + }) + } + } +} diff --git a/exchange/exchangetest/multi-bids-mixed-case.json b/exchange/exchangetest/multi-bids-mixed-case.json new file mode 100644 index 00000000000..44630b3068c --- /dev/null +++ b/exchange/exchangetest/multi-bids-mixed-case.json @@ -0,0 +1,449 @@ +{ + "description": "incoming req.ext.prebid.multibid comes with a mixed case bidder name. Expect the same bidder name casing in the outgoing ext.prebid.multibid field", + "incomingRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "my-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "prebid": { + "bidder": { + "pubmatic": { + "publisherId": "5890" + }, + "appnexus": { + "placementId": 1 + } + } + } + } + }, + { + "id": "imp-id-2", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "prebid": { + "bidder": { + "pubmatic": { + "publisherId": "5890" + }, + "appnexus": { + "placementId": 1 + } + } + } + } + } + ], + "ext": { + "prebid": { + "targeting": { + "includewinners": true, + "includebidderkeys": true, + "pricegranularity": { + "precision": 2, + "ranges": [ + { + "min": 0, + "max": 20, + "increment": 0.1 + } + ] + } + }, + "multibid": [ + { + "bidder": "PUBmatic", + "maxbids": 2, + "targetbiddercodeprefix": "pubm" + }, + { + "bidders": [ + "appnexus", + "someBidder" + ], + "maxbids": 2 + } + ] + } + } + } + }, + "outgoingRequests": { + "pubmatic": { + "expectRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "my-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "5890" + } + } + }, + { + "id": "imp-id-2", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "5890" + } + } + } + ], + "ext": { + "prebid": { + "multibid": [ + { + "bidder": "PUBmatic", + "maxbids": 2, + "targetbiddercodeprefix": "pubm" + } + ] + } + } + } + }, + "mockResponse": { + "pbsSeatBids": [ + { + "pbsBids": [ + { + "ortbBid": { + "id": "winning-bid", + "impid": "my-imp-id", + "price": 0.71, + "w": 200, + "h": 250, + "crid": "creative-1" + }, + "bidType": "video", + "bidMeta": { + "adaptercode": "pubmatic" + } + }, + { + "ortbBid": { + "id": "losing-bid", + "impid": "my-imp-id", + "price": 0.21, + "w": 200, + "h": 250, + "crid": "creative-2" + }, + "bidType": "video", + "bidMeta": { + "adaptercode": "pubmatic" + } + }, + { + "ortbBid": { + "id": "other-bid", + "impid": "imp-id-2", + "price": 0.61, + "w": 300, + "h": 500, + "crid": "creative-3" + }, + "bidType": "video", + "bidMeta": { + "adaptercode": "pubmatic" + } + }, + { + "ortbBid": { + "id": "contending-bid", + "impid": "my-imp-id", + "price": 0.51, + "w": 200, + "h": 250, + "crid": "creative-4" + }, + "bidType": "video", + "bidMeta": { + "adaptercode": "pubmatic" + } + } + ], + "seat": "pubmatic" + } + ] + } + }, + "appnexus": { + "expectRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "my-imp-id", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "placementId": 1 + } + } + }, + { + "id": "imp-id-2", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "placementId": 1 + } + } + } + ], + "ext": { + "prebid": { + "multibid": [ + { + "bidders": [ + "appnexus" + ], + "maxbids": 2 + } + ] + } + } + } + }, + "mockResponse": { + "pbsSeatBids": [ + { + "pbsBids": [ + { + "ortbBid": { + "id": "apn-bid", + "impid": "my-imp-id", + "price": 0.3, + "w": 200, + "h": 500, + "crid": "creative-a-1" + }, + "bidType": "banner", + "bidMeta": { + "adaptercode": "appnexus" + } + }, + { + "ortbBid": { + "id": "apn-bid-2", + "impid": "my-imp-id", + "price": 0.3, + "w": 200, + "h": 500, + "crid": "creative-a-2" + }, + "bidType": "banner", + "bidMeta": { + "adaptercode": "appnexus" + } + } + ], + "seat": "appnexus" + } + ] + } + } + }, + "response": { + "bids": { + "id": "some-request-id", + "seatbid": [ + { + "seat": "pubmatic", + "bid": [ + { + "id": "winning-bid", + "impid": "my-imp-id", + "price": 0.71, + "w": 200, + "h": 250, + "crid": "creative-1", + "ext": { + "origbidcpm": 0.71, + "prebid": { + "meta": { + "adaptercode": "pubmatic" + }, + "type": "video", + "targeting": { + "hb_bidder": "pubmatic", + "hb_bidder_pubmatic": "pubmatic", + "hb_cache_host": "www.pbcserver.com", + "hb_cache_host_pubmat": "www.pbcserver.com", + "hb_cache_path": "/pbcache/endpoint", + "hb_cache_path_pubmat": "/pbcache/endpoint", + "hb_pb": "0.70", + "hb_pb_pubmatic": "0.70", + "hb_size": "200x250", + "hb_size_pubmatic": "200x250" + }, + "targetbiddercode": "pubmatic" + } + } + }, + { + "id": "losing-bid", + "impid": "my-imp-id", + "price": 0.21, + "w": 200, + "h": 250, + "crid": "creative-2", + "ext": { + "origbidcpm": 0.21, + "prebid": { + "meta": { + "adaptercode": "pubmatic" + }, + "type": "video" + } + } + }, + { + "id": "other-bid", + "impid": "imp-id-2", + "price": 0.61, + "w": 300, + "h": 500, + "crid": "creative-3", + "ext": { + "origbidcpm": 0.61, + "prebid": { + "meta": { + "adaptercode": "pubmatic" + }, + "type": "video", + "targeting": { + "hb_bidder": "pubmatic", + "hb_bidder_pubmatic": "pubmatic", + "hb_cache_host": "www.pbcserver.com", + "hb_cache_host_pubmat": "www.pbcserver.com", + "hb_cache_path": "/pbcache/endpoint", + "hb_cache_path_pubmat": "/pbcache/endpoint", + "hb_pb": "0.60", + "hb_pb_pubmatic": "0.60", + "hb_size": "300x500", + "hb_size_pubmatic": "300x500" + }, + "targetbiddercode": "pubmatic" + } + } + }, + { + "id": "contending-bid", + "impid": "my-imp-id", + "price": 0.51, + "w": 200, + "h": 250, + "crid": "creative-4", + "ext": { + "origbidcpm": 0.51, + "prebid": { + "meta": { + "adaptercode": "pubmatic" + }, + "type": "video", + "targeting": { + "hb_bidder_pubm2": "pubm2", + "hb_cache_host_pubm2": "www.pbcserver.com", + "hb_cache_path_pubm2": "/pbcache/endpoint", + "hb_pb_pubm2": "0.50", + "hb_size_pubm2": "200x250" + }, + "targetbiddercode": "pubm2" + } + } + } + ] + }, + { + "seat": "appnexus", + "bid": [ + { + "id": "apn-bid", + "impid": "my-imp-id", + "price": 0.3, + "w": 200, + "h": 500, + "crid": "creative-a-1", + "ext": { + "origbidcpm": 0.3, + "prebid": { + "meta": { + "adaptercode": "appnexus" + }, + "targetbiddercode": "appnexus", + "type": "banner", + "targeting": { + "hb_bidder_appnexus": "appnexus", + "hb_cache_host_appnex": "www.pbcserver.com", + "hb_cache_path_appnex": "/pbcache/endpoint", + "hb_pb_appnexus": "0.20", + "hb_size_appnexus": "200x500" + } + } + } + }, + { + "id": "apn-bid-2", + "impid": "my-imp-id", + "price": 0.3, + "w": 200, + "h": 500, + "crid": "creative-a-2", + "ext": { + "origbidcpm": 0.3, + "prebid": { + "meta": { + "adaptercode": "appnexus" + }, + "type": "banner" + } + } + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/exchange/utils.go b/exchange/utils.go index a67a87b9c97..70988fbf7b9 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -472,12 +472,12 @@ func buildRequestExtMultiBid(adapter string, reqMultiBid []*openrtb_ext.ExtMulti adapterMultiBid := make([]*openrtb_ext.ExtMultiBid, 0) for _, multiBid := range reqMultiBid { if multiBid.Bidder != "" { - if multiBid.Bidder == adapter || isBidderInExtAlternateBidderCodes(adapter, multiBid.Bidder, adapterABC) { + if strings.ToLower(multiBid.Bidder) == adapter || isBidderInExtAlternateBidderCodes(adapter, strings.ToLower(multiBid.Bidder), adapterABC) { adapterMultiBid = append(adapterMultiBid, multiBid) } } else { for _, bidder := range multiBid.Bidders { - if bidder == adapter || isBidderInExtAlternateBidderCodes(adapter, bidder, adapterABC) { + if strings.ToLower(bidder) == adapter || isBidderInExtAlternateBidderCodes(adapter, strings.ToLower(bidder), adapterABC) { adapterMultiBid = append(adapterMultiBid, &openrtb_ext.ExtMultiBid{ Bidders: []string{bidder}, MaxBids: multiBid.MaxBids, From f4425b6dbbf5e3f85adf9e377e5eec55afc9fc74 Mon Sep 17 00:00:00 2001 From: Ashish Garg Date: Wed, 18 Oct 2023 18:23:49 +0530 Subject: [PATCH 182/268] migrate janet alias to use new pattern (#3189) --- exchange/adapter_builders.go | 1 - openrtb_ext/bidders.go | 2 -- static/bidder-info/janet.yaml | 10 +--------- static/bidder-params/janet.json | 26 -------------------------- 4 files changed, 1 insertion(+), 38 deletions(-) delete mode 100644 static/bidder-params/janet.json diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index ea9e99cfb6c..573a0413520 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -296,7 +296,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderInvibes: invibes.Builder, openrtb_ext.BidderIQZone: iqzone.Builder, openrtb_ext.BidderIx: ix.Builder, - openrtb_ext.BidderJANet: adtelligent.Builder, openrtb_ext.BidderJixie: jixie.Builder, openrtb_ext.BidderKargo: kargo.Builder, openrtb_ext.BidderKayzen: kayzen.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 2258cad4214..bec6d3c1e1b 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -121,7 +121,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderInvibes, BidderIQZone, BidderIx, - BidderJANet, BidderJixie, BidderKargo, BidderKayzen, @@ -412,7 +411,6 @@ const ( BidderInvibes BidderName = "invibes" BidderIQZone BidderName = "iqzone" BidderIx BidderName = "ix" - BidderJANet BidderName = "janet" BidderJixie BidderName = "jixie" BidderKargo BidderName = "kargo" BidderKayzen BidderName = "kayzen" diff --git a/static/bidder-info/janet.yaml b/static/bidder-info/janet.yaml index 0a3abb53af4..97f44a2bd56 100644 --- a/static/bidder-info/janet.yaml +++ b/static/bidder-info/janet.yaml @@ -1,15 +1,7 @@ +aliasOf: adtelligent endpoint: "http://ghb.bidder.jmgads.com/pbs/ortb" maintainer: email: "info@thejmg.com" -capabilities: - app: - mediaTypes: - - banner - - video - site: - mediaTypes: - - banner - - video userSync: # JANet supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. diff --git a/static/bidder-params/janet.json b/static/bidder-params/janet.json deleted file mode 100644 index 38c2c2eb044..00000000000 --- a/static/bidder-params/janet.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "JANet Adapter Params", - "description": "A schema which validates params accepted by the JANet adapter", - - "type": "object", - "properties": { - "placementId": { - "type": "integer", - "description": "An ID which identifies this placement of the impression" - }, - "siteId": { - "type": "integer", - "description": "An ID which identifies the site selling the impression" - }, - "aid": { - "type": "integer", - "description": "An ID which identifies the channel" - }, - "bidFloor": { - "type": "number", - "description": "BidFloor, US Dollars" - } - }, - "required": ["aid"] -} From 83c7946ab769d9886b0967e1864c7d9535c1552a Mon Sep 17 00:00:00 2001 From: Ashish Garg Date: Wed, 18 Oct 2023 18:24:08 +0530 Subject: [PATCH 183/268] migrate janet alias to use new pattern (#3190) --- exchange/adapter_builders.go | 1 - openrtb_ext/bidders.go | 2 -- static/bidder-info/pgam.yaml | 10 +--------- static/bidder-params/pgam.json | 26 -------------------------- 4 files changed, 1 insertion(+), 38 deletions(-) delete mode 100644 static/bidder-params/pgam.json diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 573a0413520..8e97baf655f 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -330,7 +330,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderOutbrain: outbrain.Builder, openrtb_ext.BidderOwnAdx: ownadx.Builder, openrtb_ext.BidderPangle: pangle.Builder, - openrtb_ext.BidderPGAM: adtelligent.Builder, openrtb_ext.BidderPGAMSsp: pgamssp.Builder, openrtb_ext.BidderPubmatic: pubmatic.Builder, openrtb_ext.BidderPubnative: pubnative.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index bec6d3c1e1b..24f24c16278 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -155,7 +155,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderOutbrain, BidderOwnAdx, BidderPangle, - BidderPGAM, BidderPGAMSsp, BidderPubmatic, BidderPubnative, @@ -445,7 +444,6 @@ const ( BidderOutbrain BidderName = "outbrain" BidderOwnAdx BidderName = "ownadx" BidderPangle BidderName = "pangle" - BidderPGAM BidderName = "pgam" BidderPGAMSsp BidderName = "pgamssp" BidderPubmatic BidderName = "pubmatic" BidderPubnative BidderName = "pubnative" diff --git a/static/bidder-info/pgam.yaml b/static/bidder-info/pgam.yaml index 0c9b2f008b6..e0bf4388d4b 100644 --- a/static/bidder-info/pgam.yaml +++ b/static/bidder-info/pgam.yaml @@ -1,15 +1,7 @@ +aliasOf: adtelligent endpoint: "http://ghb.pgamssp.com/pbs/ortb" maintainer: email: "ppatel@pgammedia.com" -capabilities: - app: - mediaTypes: - - banner - - video - site: - mediaTypes: - - banner - - video userSync: # PGAM ssp supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. diff --git a/static/bidder-params/pgam.json b/static/bidder-params/pgam.json deleted file mode 100644 index c0a016a7d24..00000000000 --- a/static/bidder-params/pgam.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "PGAM Adapter Params", - "description": "A schema which validates params accepted by the PGAM ssp adapter", - - "type": "object", - "properties": { - "placementId": { - "type": "integer", - "description": "An ID which identifies this placement of the impression" - }, - "siteId": { - "type": "integer", - "description": "An ID which identifies the site selling the impression" - }, - "aid": { - "type": "integer", - "description": "An ID which identifies the channel" - }, - "bidFloor": { - "type": "number", - "description": "BidFloor, US Dollars" - } - }, - "required": ["aid"] -} From 32ddacacbcceec660d274f84b395840327af1247 Mon Sep 17 00:00:00 2001 From: Ashish Garg Date: Wed, 18 Oct 2023 18:38:40 +0530 Subject: [PATCH 184/268] migrate streamkey alias to use new pattern (#3191) --- exchange/adapter_builders.go | 1 - openrtb_ext/bidders.go | 2 -- static/bidder-info/streamkey.yaml | 1 + static/bidder-params/streamkey.json | 26 -------------------------- 4 files changed, 1 insertion(+), 29 deletions(-) delete mode 100644 static/bidder-params/streamkey.json diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 8e97baf655f..f28973ef8d9 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -357,7 +357,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderSonobi: sonobi.Builder, openrtb_ext.BidderSovrn: sovrn.Builder, openrtb_ext.BidderSspBC: sspBC.Builder, - openrtb_ext.BidderStreamkey: adtelligent.Builder, openrtb_ext.BidderSuntContent: suntContent.Builder, openrtb_ext.BidderStroeerCore: stroeerCore.Builder, openrtb_ext.BidderSynacormedia: imds.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 24f24c16278..bde67130350 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -182,7 +182,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderSonobi, BidderSovrn, BidderSspBC, - BidderStreamkey, BidderStroeerCore, BidderSuntContent, BidderSynacormedia, @@ -471,7 +470,6 @@ const ( BidderSonobi BidderName = "sonobi" BidderSovrn BidderName = "sovrn" BidderSspBC BidderName = "sspBC" - BidderStreamkey BidderName = "streamkey" BidderStroeerCore BidderName = "stroeerCore" BidderSuntContent BidderName = "suntContent" BidderSynacormedia BidderName = "synacormedia" diff --git a/static/bidder-info/streamkey.yaml b/static/bidder-info/streamkey.yaml index 9e5d05abaec..20510ceac69 100644 --- a/static/bidder-info/streamkey.yaml +++ b/static/bidder-info/streamkey.yaml @@ -1,3 +1,4 @@ +aliasOf: adtelligent endpoint: "http://ghb.hb.streamkey.net/pbs/ortb" maintainer: email: "contact@streamkey.tv" diff --git a/static/bidder-params/streamkey.json b/static/bidder-params/streamkey.json deleted file mode 100644 index ec8e5b1b643..00000000000 --- a/static/bidder-params/streamkey.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Streamkey Adapter Params", - "description": "A schema which validates params accepted by the Streamkey adapter", - - "type": "object", - "properties": { - "placementId": { - "type": "integer", - "description": "An ID which identifies this placement of the impression" - }, - "siteId": { - "type": "integer", - "description": "An ID which identifies the site selling the impression" - }, - "aid": { - "type": "integer", - "description": "An ID which identifies the channel" - }, - "bidFloor": { - "type": "number", - "description": "BidFloor, US Dollars" - } - }, - "required": ["aid"] -} From 9bfe196d3e868512dff813cd7a60721ac1b66f0e Mon Sep 17 00:00:00 2001 From: Ashish Garg Date: Wed, 18 Oct 2023 18:39:08 +0530 Subject: [PATCH 185/268] migrate viewdeos alias to use new pattern (#3192) --- exchange/adapter_builders.go | 1 - openrtb_ext/bidders.go | 2 -- static/bidder-info/viewdeos.yaml | 10 +--------- static/bidder-params/viewdeos.json | 26 -------------------------- 4 files changed, 1 insertion(+), 38 deletions(-) delete mode 100644 static/bidder-params/viewdeos.json diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index f28973ef8d9..a8b1b0ba361 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -377,7 +377,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderVideoByte: videobyte.Builder, openrtb_ext.BidderVideoHeroes: videoheroes.Builder, openrtb_ext.BidderVidoomy: vidoomy.Builder, - openrtb_ext.BidderViewdeos: adtelligent.Builder, openrtb_ext.BidderVisibleMeasures: visiblemeasures.Builder, openrtb_ext.BidderVisx: visx.Builder, openrtb_ext.BidderVox: vox.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index bde67130350..02e01c5336e 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -202,7 +202,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderVideoByte, BidderVideoHeroes, BidderVidoomy, - BidderViewdeos, BidderVisibleMeasures, BidderVisx, BidderVox, @@ -490,7 +489,6 @@ const ( BidderVideoByte BidderName = "videobyte" BidderVideoHeroes BidderName = "videoheroes" BidderVidoomy BidderName = "vidoomy" - BidderViewdeos BidderName = "viewdeos" BidderVisibleMeasures BidderName = "visiblemeasures" BidderVisx BidderName = "visx" BidderVox BidderName = "vox" diff --git a/static/bidder-info/viewdeos.yaml b/static/bidder-info/viewdeos.yaml index c5e1e8ef02c..8d14cb961d8 100644 --- a/static/bidder-info/viewdeos.yaml +++ b/static/bidder-info/viewdeos.yaml @@ -1,16 +1,8 @@ +aliasOf: adtelligent endpoint: "http://ghb.sync.viewdeos.com/pbs/ortb" maintainer: email: "contact@viewdeos.com" gvlVendorID: 924 -capabilities: - app: - mediaTypes: - - banner - - video - site: - mediaTypes: - - banner - - video userSync: # viewdeos supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. diff --git a/static/bidder-params/viewdeos.json b/static/bidder-params/viewdeos.json deleted file mode 100644 index 3e309e4b77a..00000000000 --- a/static/bidder-params/viewdeos.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Viewdeos Adapter Params", - "description": "A schema which validates params accepted by the Viewdeos adapter", - - "type": "object", - "properties": { - "placementId": { - "type": "integer", - "description": "An ID which identifies this placement of the impression" - }, - "siteId": { - "type": "integer", - "description": "An ID which identifies the site selling the impression" - }, - "aid": { - "type": "integer", - "description": "An ID which identifies the channel" - }, - "bidFloor": { - "type": "number", - "description": "BidFloor, US Dollars" - } - }, - "required": ["aid"] -} From 91881fe01ccac2eb44e517164e368b2e55e38116 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Wed, 18 Oct 2023 19:18:59 +0530 Subject: [PATCH 186/268] migrate limelight aliases to follow new pattern (#3183) co-authored by @onkarvhanumante --- exchange/adapter_builders.go | 6 ------ openrtb_ext/bidders.go | 12 ------------ static/bidder-info/adsyield.yaml | 16 +--------------- static/bidder-info/appstock.yaml | 16 +--------------- static/bidder-info/evtech.yaml | 16 +--------------- static/bidder-info/greedygame.yaml | 16 +--------------- static/bidder-info/iionads.yaml | 16 +--------------- static/bidder-info/xtrmqb.yaml | 16 +--------------- static/bidder-params/adsyield.json | 23 ----------------------- static/bidder-params/appstock.json | 23 ----------------------- static/bidder-params/evtech.json | 23 ----------------------- static/bidder-params/greedygame.json | 23 ----------------------- static/bidder-params/iionads.json | 23 ----------------------- static/bidder-params/xtrmqb.json | 23 ----------------------- 14 files changed, 6 insertions(+), 246 deletions(-) delete mode 100644 static/bidder-params/adsyield.json delete mode 100644 static/bidder-params/appstock.json delete mode 100644 static/bidder-params/evtech.json delete mode 100644 static/bidder-params/greedygame.json delete mode 100644 static/bidder-params/iionads.json delete mode 100644 static/bidder-params/xtrmqb.json diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index a8b1b0ba361..a65e051ebf3 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -213,7 +213,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderAdquery: adquery.Builder, openrtb_ext.BidderAdrino: adrino.Builder, openrtb_ext.BidderAdsinteractive: adsinteractive.Builder, - openrtb_ext.BidderAdsyield: limelightDigital.Builder, openrtb_ext.BidderAdtarget: adtarget.Builder, openrtb_ext.BidderAdtrgtme: adtrgtme.Builder, openrtb_ext.BidderAdtelligent: adtelligent.Builder, @@ -227,7 +226,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderAMX: amx.Builder, openrtb_ext.BidderApacdex: apacdex.Builder, openrtb_ext.BidderAppnexus: appnexus.Builder, - openrtb_ext.BidderAppstock: limelightDigital.Builder, openrtb_ext.BidderAppush: appush.Builder, openrtb_ext.BidderAudienceNetwork: audienceNetwork.Builder, openrtb_ext.BidderAutomatad: automatad.Builder, @@ -273,7 +271,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderEpom: epom.Builder, openrtb_ext.BidderEpsilon: conversant.Builder, openrtb_ext.BidderEVolution: evolution.Builder, - openrtb_ext.BidderEvtech: limelightDigital.Builder, openrtb_ext.BidderFlipp: flipp.Builder, openrtb_ext.BidderFreewheelSSP: freewheelssp.Builder, openrtb_ext.BidderFreewheelSSPOld: freewheelssp.Builder, @@ -282,11 +279,9 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderGamoshi: gamoshi.Builder, openrtb_ext.BidderGlobalsun: globalsun.Builder, openrtb_ext.BidderGothamads: gothamads.Builder, - openrtb_ext.BidderGreedygame: limelightDigital.Builder, openrtb_ext.BidderGrid: grid.Builder, openrtb_ext.BidderGumGum: gumgum.Builder, openrtb_ext.BidderHuaweiAds: huaweiads.Builder, - openrtb_ext.BidderIionads: limelightDigital.Builder, openrtb_ext.BidderImds: imds.Builder, openrtb_ext.BidderImpactify: impactify.Builder, openrtb_ext.BidderImprovedigital: improvedigital.Builder, @@ -382,7 +377,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderVox: vox.Builder, openrtb_ext.BidderVrtcal: vrtcal.Builder, openrtb_ext.BidderXeworks: xeworks.Builder, - openrtb_ext.BidderXtrmqb: limelightDigital.Builder, openrtb_ext.BidderYahooAds: yahooAds.Builder, openrtb_ext.BidderYahooAdvertising: yahooAds.Builder, openrtb_ext.BidderYahooSSP: yahooAds.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 02e01c5336e..b14eeb49b35 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -38,7 +38,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderAdquery, BidderAdrino, BidderAdsinteractive, - BidderAdsyield, BidderAdtarget, BidderAdtrgtme, BidderAdtelligent, @@ -52,7 +51,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderAMX, BidderApacdex, BidderAppnexus, - BidderAppstock, BidderAppush, BidderAudienceNetwork, BidderAutomatad, @@ -98,7 +96,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderEpom, BidderEpsilon, BidderEVolution, - BidderEvtech, BidderFlipp, BidderFreewheelSSP, BidderFreewheelSSPOld, @@ -107,11 +104,9 @@ var coreBidderNames []BidderName = []BidderName{ BidderGamoshi, BidderGlobalsun, BidderGothamads, - BidderGreedygame, BidderGrid, BidderGumGum, BidderHuaweiAds, - BidderIionads, BidderImds, BidderImpactify, BidderImprovedigital, @@ -207,7 +202,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderVox, BidderVrtcal, BidderXeworks, - BidderXtrmqb, BidderYahooAds, BidderYahooAdvertising, BidderYahooSSP, @@ -325,7 +319,6 @@ const ( BidderAdquery BidderName = "adquery" BidderAdrino BidderName = "adrino" BidderAdsinteractive BidderName = "adsinteractive" - BidderAdsyield BidderName = "adsyield" BidderAdtarget BidderName = "adtarget" BidderAdtrgtme BidderName = "adtrgtme" BidderAdtelligent BidderName = "adtelligent" @@ -339,7 +332,6 @@ const ( BidderAMX BidderName = "amx" BidderApacdex BidderName = "apacdex" BidderAppnexus BidderName = "appnexus" - BidderAppstock BidderName = "appstock" BidderAppush BidderName = "appush" BidderAudienceNetwork BidderName = "audienceNetwork" BidderAutomatad BidderName = "automatad" @@ -385,7 +377,6 @@ const ( BidderEpsilon BidderName = "epsilon" BidderEpom BidderName = "epom" BidderEVolution BidderName = "e_volution" - BidderEvtech BidderName = "evtech" BidderFlipp BidderName = "flipp" BidderFreewheelSSP BidderName = "freewheelssp" BidderFreewheelSSPOld BidderName = "freewheel-ssp" @@ -394,11 +385,9 @@ const ( BidderGamoshi BidderName = "gamoshi" BidderGlobalsun BidderName = "globalsun" BidderGothamads BidderName = "gothamads" - BidderGreedygame BidderName = "greedygame" BidderGrid BidderName = "grid" BidderGumGum BidderName = "gumgum" BidderHuaweiAds BidderName = "huaweiads" - BidderIionads BidderName = "iionads" BidderImds BidderName = "imds" BidderImpactify BidderName = "impactify" BidderImprovedigital BidderName = "improvedigital" @@ -494,7 +483,6 @@ const ( BidderVox BidderName = "vox" BidderVrtcal BidderName = "vrtcal" BidderXeworks BidderName = "xeworks" - BidderXtrmqb BidderName = "xtrmqb" BidderYahooAds BidderName = "yahooAds" BidderYahooAdvertising BidderName = "yahooAdvertising" BidderYahooSSP BidderName = "yahoossp" diff --git a/static/bidder-info/adsyield.yaml b/static/bidder-info/adsyield.yaml index dadd9cc3d13..2be1395b851 100644 --- a/static/bidder-info/adsyield.yaml +++ b/static/bidder-info/adsyield.yaml @@ -1,16 +1,2 @@ endpoint: "http://ads-pbs.open-adsyield.com/openrtb/{{.PublisherID}}?host={{.Host}}" -maintainer: - email: "engineering@project-limelight.com" -capabilities: - app: - mediaTypes: - - banner - - video - - audio - - native - site: - mediaTypes: - - banner - - video - - audio - - native +aliasOf: "limelightDigital" diff --git a/static/bidder-info/appstock.yaml b/static/bidder-info/appstock.yaml index 28f420e9e88..73b54aa7144 100644 --- a/static/bidder-info/appstock.yaml +++ b/static/bidder-info/appstock.yaml @@ -1,16 +1,2 @@ endpoint: "http://ads-pbs.pre.vr-tb.com/openrtb/{{.PublisherID}}?host={{.Host}}" -maintainer: - email: "engineering@project-limelight.com" -capabilities: - app: - mediaTypes: - - banner - - video - - audio - - native - site: - mediaTypes: - - banner - - video - - audio - - native +aliasOf: "limelightDigital" diff --git a/static/bidder-info/evtech.yaml b/static/bidder-info/evtech.yaml index 4277a5c46c8..59134e04523 100644 --- a/static/bidder-info/evtech.yaml +++ b/static/bidder-info/evtech.yaml @@ -1,19 +1,5 @@ endpoint: "http://ads-pbs.direct.e-volution.ai/openrtb/{{.PublisherID}}?host={{.Host}}" -maintainer: - email: "engineering@project-limelight.com" -capabilities: - app: - mediaTypes: - - banner - - video - - audio - - native - site: - mediaTypes: - - banner - - video - - audio - - native +aliasOf: "limelightDigital" userSync: iframe: url: https://tracker.direct.e-volution.ai/sync.html?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}} diff --git a/static/bidder-info/greedygame.yaml b/static/bidder-info/greedygame.yaml index 5e73e1fe950..330a7debd9d 100644 --- a/static/bidder-info/greedygame.yaml +++ b/static/bidder-info/greedygame.yaml @@ -1,16 +1,2 @@ endpoint: "http://ads-pbs.rtb-greedygame.com/openrtb/{{.PublisherID}}?host={{.Host}}" -maintainer: - email: "engineering@project-limelight.com" -capabilities: - app: - mediaTypes: - - banner - - video - - audio - - native - site: - mediaTypes: - - banner - - video - - audio - - native +aliasOf: "limelightDigital" diff --git a/static/bidder-info/iionads.yaml b/static/bidder-info/iionads.yaml index da2f494bb30..1dc154a358d 100644 --- a/static/bidder-info/iionads.yaml +++ b/static/bidder-info/iionads.yaml @@ -1,16 +1,2 @@ endpoint: "http://ads-pbs.iionads.com/openrtb/{{.PublisherID}}?host={{.Host}}" -maintainer: - email: "engineering@project-limelight.com" -capabilities: - app: - mediaTypes: - - banner - - video - - audio - - native - site: - mediaTypes: - - banner - - video - - audio - - native +aliasOf: "limelightDigital" \ No newline at end of file diff --git a/static/bidder-info/xtrmqb.yaml b/static/bidder-info/xtrmqb.yaml index c1f0da3fc1f..b7a068c3889 100644 --- a/static/bidder-info/xtrmqb.yaml +++ b/static/bidder-info/xtrmqb.yaml @@ -1,16 +1,2 @@ endpoint: "http://ads-pbs.ortb.tech/openrtb/{{.PublisherID}}?host={{.Host}}" -maintainer: - email: "engineering@project-limelight.com" -capabilities: - app: - mediaTypes: - - banner - - video - - audio - - native - site: - mediaTypes: - - banner - - video - - audio - - native +aliasOf: "limelightDigital" diff --git a/static/bidder-params/adsyield.json b/static/bidder-params/adsyield.json deleted file mode 100644 index c7c5308890f..00000000000 --- a/static/bidder-params/adsyield.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Adsyield Adapter Params", - "description": "A schema which validates params accepted by the Adsyield adapter", - "type": "object", - - "properties": { - "host": { - "type": "string", - "description": "Ad network's RTB host", - "format": "hostname", - "pattern": "^.+\\..+$" - }, - "publisherId": { - "type": ["integer", "string"], - "description": "Publisher ID", - "minimum": 1, - "pattern": "^[1-9][0-9]*$" - } - }, - - "required": ["host", "publisherId"] -} diff --git a/static/bidder-params/appstock.json b/static/bidder-params/appstock.json deleted file mode 100644 index eb2251e4e47..00000000000 --- a/static/bidder-params/appstock.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Appstock Adapter Params", - "description": "A schema which validates params accepted by the Appstock adapter", - "type": "object", - - "properties": { - "host": { - "type": "string", - "description": "Ad network's RTB host", - "format": "hostname", - "pattern": "^.+\\..+$" - }, - "publisherId": { - "type": ["integer", "string"], - "description": "Publisher ID", - "minimum": 1, - "pattern": "^[1-9][0-9]*$" - } - }, - - "required": ["host", "publisherId"] -} diff --git a/static/bidder-params/evtech.json b/static/bidder-params/evtech.json deleted file mode 100644 index 5e78b7de171..00000000000 --- a/static/bidder-params/evtech.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Evolution Technologies Adapter Params", - "description": "A schema which validates params accepted by the Evolution Technologies adapter", - "type": "object", - - "properties": { - "host": { - "type": "string", - "description": "Ad network's RTB host", - "format": "hostname", - "pattern": "^.+\\..+$" - }, - "publisherId": { - "type": ["integer", "string"], - "description": "Publisher ID", - "minimum": 1, - "pattern": "^[1-9][0-9]*$" - } - }, - - "required": ["host", "publisherId"] -} diff --git a/static/bidder-params/greedygame.json b/static/bidder-params/greedygame.json deleted file mode 100644 index 2057c147d44..00000000000 --- a/static/bidder-params/greedygame.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "GreedyGame Adapter Params", - "description": "A schema which validates params accepted by the GreedyGame adapter", - "type": "object", - - "properties": { - "host": { - "type": "string", - "description": "Ad network's RTB host", - "format": "hostname", - "pattern": "^.+\\..+$" - }, - "publisherId": { - "type": ["integer", "string"], - "description": "Publisher ID", - "minimum": 1, - "pattern": "^[1-9][0-9]*$" - } - }, - - "required": ["host", "publisherId"] -} diff --git a/static/bidder-params/iionads.json b/static/bidder-params/iionads.json deleted file mode 100644 index b9196445acc..00000000000 --- a/static/bidder-params/iionads.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Iion Adapter Params", - "description": "A schema which validates params accepted by the Iion adapter", - "type": "object", - - "properties": { - "host": { - "type": "string", - "description": "Ad network's RTB host", - "format": "hostname", - "pattern": "^.+\\..+$" - }, - "publisherId": { - "type": ["integer", "string"], - "description": "Publisher ID", - "minimum": 1, - "pattern": "^[1-9][0-9]*$" - } - }, - - "required": ["host", "publisherId"] -} diff --git a/static/bidder-params/xtrmqb.json b/static/bidder-params/xtrmqb.json deleted file mode 100644 index 59e711e9ad3..00000000000 --- a/static/bidder-params/xtrmqb.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "XTRM QB Adapter Params", - "description": "A schema which validates params accepted by the XTRM QB adapter", - "type": "object", - - "properties": { - "host": { - "type": "string", - "description": "Ad network's RTB host", - "format": "hostname", - "pattern": "^.+\\..+$" - }, - "publisherId": { - "type": ["integer", "string"], - "description": "Publisher ID", - "minimum": 1, - "pattern": "^[1-9][0-9]*$" - } - }, - - "required": ["host", "publisherId"] -} From ac7a0d40d11f12e950270857f2a2aca8178ae1fc Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Wed, 18 Oct 2023 19:19:58 +0530 Subject: [PATCH 187/268] migrate apacdex aliases to use new pattern (#3184) co-authored: @onkarvhanumante --- exchange/adapter_builders.go | 2 -- openrtb_ext/bidders.go | 4 --- static/bidder-info/quantumdex.yaml | 21 +-------------- static/bidder-info/valueimpression.yaml | 21 +-------------- static/bidder-params/quantumdex.json | 32 ----------------------- static/bidder-params/valueimpression.json | 32 ----------------------- 6 files changed, 2 insertions(+), 110 deletions(-) delete mode 100644 static/bidder-params/quantumdex.json delete mode 100644 static/bidder-params/valueimpression.json diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index a65e051ebf3..29e16bb2904 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -330,7 +330,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderPubnative: pubnative.Builder, openrtb_ext.BidderPulsepoint: pulsepoint.Builder, openrtb_ext.BidderPWBid: pwbid.Builder, - openrtb_ext.BidderQuantumdex: apacdex.Builder, openrtb_ext.BidderRevcontent: revcontent.Builder, openrtb_ext.BidderRichaudience: richaudience.Builder, openrtb_ext.BidderRise: rise.Builder, @@ -368,7 +367,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderUndertone: undertone.Builder, openrtb_ext.BidderUnicorn: unicorn.Builder, openrtb_ext.BidderUnruly: unruly.Builder, - openrtb_ext.BidderValueImpression: apacdex.Builder, openrtb_ext.BidderVideoByte: videobyte.Builder, openrtb_ext.BidderVideoHeroes: videoheroes.Builder, openrtb_ext.BidderVidoomy: vidoomy.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index b14eeb49b35..709c3aa3cdd 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -155,7 +155,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderPubnative, BidderPulsepoint, BidderPWBid, - BidderQuantumdex, BidderRevcontent, BidderRichaudience, BidderRise, @@ -193,7 +192,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderUndertone, BidderUnicorn, BidderUnruly, - BidderValueImpression, BidderVideoByte, BidderVideoHeroes, BidderVidoomy, @@ -436,7 +434,6 @@ const ( BidderPubnative BidderName = "pubnative" BidderPulsepoint BidderName = "pulsepoint" BidderPWBid BidderName = "pwbid" - BidderQuantumdex BidderName = "quantumdex" BidderRevcontent BidderName = "revcontent" BidderRichaudience BidderName = "richaudience" BidderRise BidderName = "rise" @@ -474,7 +471,6 @@ const ( BidderUndertone BidderName = "undertone" BidderUnicorn BidderName = "unicorn" BidderUnruly BidderName = "unruly" - BidderValueImpression BidderName = "valueimpression" BidderVideoByte BidderName = "videobyte" BidderVideoHeroes BidderName = "videoheroes" BidderVidoomy BidderName = "vidoomy" diff --git a/static/bidder-info/quantumdex.yaml b/static/bidder-info/quantumdex.yaml index 590737ac28b..32043ad62fb 100644 --- a/static/bidder-info/quantumdex.yaml +++ b/static/bidder-info/quantumdex.yaml @@ -1,20 +1 @@ -endpoint: "http://useast.quantumdex.io/auction/pbs" -maintainer: - email: "support@apacdex.com" -modifyingVastXmlAllowed: false -capabilities: - app: - mediaTypes: - - banner - - video - site: - mediaTypes: - - banner - - video -userSync: - iframe: - url: https://sync.quantumdex.io/usersync/pbs?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}} - userMacro: "[UID]" - redirect: - url: "https://sync.quantumdex.io/getuid?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}" - userMacro: "[UID]" +aliasOf: "apacdex" \ No newline at end of file diff --git a/static/bidder-info/valueimpression.yaml b/static/bidder-info/valueimpression.yaml index 9e6e583967c..32043ad62fb 100644 --- a/static/bidder-info/valueimpression.yaml +++ b/static/bidder-info/valueimpression.yaml @@ -1,20 +1 @@ -endpoint: "http://useast.quantumdex.io/auction/pbs" -maintainer: - email: "support@apacdex.com" -modifyingVastXmlAllowed: false -capabilities: - app: - mediaTypes: - - banner - - video - site: - mediaTypes: - - banner - - video -userSync: - iframe: - url: https://sync.quantumdex.io/usersync/pbs?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}} - userMacro: "[UID]" - redirect: - url: "https://sync.quantumdex.io/getuid?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}" - userMacro: "[UID]" \ No newline at end of file +aliasOf: "apacdex" \ No newline at end of file diff --git a/static/bidder-params/quantumdex.json b/static/bidder-params/quantumdex.json deleted file mode 100644 index 3ef9abe34c6..00000000000 --- a/static/bidder-params/quantumdex.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Quantumdex Adapter Params", - "description": "A schema which validates params accepted by the Quantumdex adapter", - "type": "object", - "properties": { - "placementId": { - "type": "string", - "description": "Placement ID provided by Quantumdex" - }, - "siteId": { - "type": "string", - "description": "Publisher site ID from Quantumdex" - }, - "floorPrice": { - "type": "number", - "description": "CPM bidfloor in USD" - } - }, - "oneOf": [ - { - "required": [ - "placementId" - ] - }, - { - "required": [ - "siteId" - ] - } - ] -} \ No newline at end of file diff --git a/static/bidder-params/valueimpression.json b/static/bidder-params/valueimpression.json deleted file mode 100644 index 793e940eb11..00000000000 --- a/static/bidder-params/valueimpression.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Valueimpression Adapter Params", - "description": "A schema which validates params accepted by the Valueimpression adapter", - "type": "object", - "properties": { - "placementId": { - "type": "string", - "description": "Placement ID provided by Valueimpression" - }, - "siteId": { - "type": "string", - "description": "Publisher site ID from Valueimpression" - }, - "floorPrice": { - "type": "number", - "description": "CPM bidfloor in USD" - } - }, - "oneOf": [ - { - "required": [ - "placementId" - ] - }, - { - "required": [ - "siteId" - ] - } - ] -} \ No newline at end of file From bc77035476d38200946f3f1b0ae9a6a76207eac3 Mon Sep 17 00:00:00 2001 From: Onkar Hanumante Date: Thu, 19 Oct 2023 04:55:44 +0530 Subject: [PATCH 188/268] Update release workflow to support major version release (#3235) --- .github/workflows/release.yml | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fd790699a14..f1d2b10c41c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,11 +6,12 @@ on: releaseType: type: choice options: + - major - minor - patch default: minor required: true - description: 'minor: v0.X.0, patch: v0.0.X' + description: 'major: vX.0.0, minor: v0.X.0, patch: v0.0.X' debug: type: boolean default: true @@ -78,11 +79,18 @@ jobs: nextTag='' releaseType=${{ inputs.releaseType }} - if [ $releaseType == "minor" ]; then - # increment minor version and reset patch version - nextTag=$(echo "${currentTag}" | awk -F. '{OFS="."; $2+=1; $3=0; print $0}') + if [ $releaseType == "major" ]; then + # PBS-GO skipped the v1.0.0 major release - https://github.com/prebid/prebid-server/issues/3068 + # If the current tag is v0.x.x, the script sets the next release tag to v2.0.0 + # Otherwise, the script increments the major version by 1 and sets the minor and patch versions to zero + # For example, v2.x.x will be incremented to v3.0.0 + major=$(echo "${currentTag}" | awk -F. '{gsub(/^v/, "", $1); if($1 == 0) $1=2; else $1+=1; print $1}') + nextTag="v${major}.0.0" + elif [ $releaseType == "minor" ]; then + # Increment minor version and reset patch version + nextTag=$(echo "${currentTag}" | awk -F. '{OFS="."; $2+=1; $3=0; print $0}') else - # increment patch version + # Increment patch version nextTag=$(echo "${currentTag}" | awk -F. '{OFS="."; $3+=1; print $0}') fi From 8131a14f69dbb585a3f0b699e794634589b823ee Mon Sep 17 00:00:00 2001 From: IQzoneIT Date: Thu, 19 Oct 2023 02:08:33 -0400 Subject: [PATCH 189/268] New Adapter: IQX (#3164) Co-authored-by: Dmytro Shyrokov --- adapters/iqx/iqx.go | 164 ++++++++++ adapters/iqx/iqxtest_test.go | 27 ++ .../iqx/iqzonextest/exemplary/banner.json | 283 ++++++++++++++++++ .../iqx/iqzonextest/exemplary/native.json | 164 ++++++++++ adapters/iqx/iqzonextest/exemplary/video.json | 204 +++++++++++++ .../supplemental/bad-response.json | 106 +++++++ .../supplemental/empty-mediatype.json | 190 ++++++++++++ .../supplemental/empty-seatbid-0-bid.json | 111 +++++++ .../supplemental/empty-seatbid.json | 111 +++++++ .../invalid-ext-bidder-object.json | 49 +++ .../supplemental/invalid-ext-object.json | 47 +++ .../supplemental/invalid-mediatype.json | 187 ++++++++++++ .../iqzonextest/supplemental/status-204.json | 100 +++++++ .../iqzonextest/supplemental/status-400.json | 106 +++++++ .../iqzonextest/supplemental/status-503.json | 105 +++++++ .../supplemental/unexpected-status.json | 106 +++++++ adapters/iqx/params_test.go | 53 ++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_iqx.go | 6 + static/bidder-info/iqx.yaml | 19 ++ static/bidder-params/iqx.json | 22 ++ 22 files changed, 2164 insertions(+) create mode 100644 adapters/iqx/iqx.go create mode 100644 adapters/iqx/iqxtest_test.go create mode 100644 adapters/iqx/iqzonextest/exemplary/banner.json create mode 100644 adapters/iqx/iqzonextest/exemplary/native.json create mode 100644 adapters/iqx/iqzonextest/exemplary/video.json create mode 100644 adapters/iqx/iqzonextest/supplemental/bad-response.json create mode 100644 adapters/iqx/iqzonextest/supplemental/empty-mediatype.json create mode 100644 adapters/iqx/iqzonextest/supplemental/empty-seatbid-0-bid.json create mode 100644 adapters/iqx/iqzonextest/supplemental/empty-seatbid.json create mode 100644 adapters/iqx/iqzonextest/supplemental/invalid-ext-bidder-object.json create mode 100644 adapters/iqx/iqzonextest/supplemental/invalid-ext-object.json create mode 100644 adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json create mode 100644 adapters/iqx/iqzonextest/supplemental/status-204.json create mode 100644 adapters/iqx/iqzonextest/supplemental/status-400.json create mode 100644 adapters/iqx/iqzonextest/supplemental/status-503.json create mode 100644 adapters/iqx/iqzonextest/supplemental/unexpected-status.json create mode 100644 adapters/iqx/params_test.go create mode 100644 openrtb_ext/imp_iqx.go create mode 100644 static/bidder-info/iqx.yaml create mode 100644 static/bidder-params/iqx.json diff --git a/adapters/iqx/iqx.go b/adapters/iqx/iqx.go new file mode 100644 index 00000000000..543d988bce5 --- /dev/null +++ b/adapters/iqx/iqx.go @@ -0,0 +1,164 @@ +package iqx + +import ( + "encoding/json" + "fmt" + "net/http" + "text/template" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/macros" + "github.com/prebid/prebid-server/openrtb_ext" +) + +type bidType struct { + Type string `json:"type"` +} + +type bidExt struct { + Prebid bidType `json:"prebid"` +} + +type adapter struct { + endpoint *template.Template +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + tmpl, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint URL template: %v", err) + } + + bidder := &adapter{ + endpoint: tmpl, + } + + return bidder, nil +} + +func (a *adapter) buildEndpointFromRequest(imp *openrtb2.Imp) (string, error) { + var impExt adapters.ExtImpBidder + if err := json.Unmarshal(imp.Ext, &impExt); err != nil { + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("Failed to deserialize bidder impression extension: %v", err), + } + } + + var iqzonexExt openrtb_ext.ExtIQX + if err := json.Unmarshal(impExt.Bidder, &iqzonexExt); err != nil { + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("Failed to deserialize IQZonex extension: %v", err), + } + } + + endpointParams := macros.EndpointTemplateParams{ + Host: iqzonexExt.Env, + SourceId: iqzonexExt.Pid, + } + + return macros.ResolveMacros(a.endpoint, endpointParams) +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var requests []*adapters.RequestData + var errs []error + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + + requestCopy := *request + for _, imp := range request.Imp { + requestCopy.Imp = []openrtb2.Imp{imp} + + endpoint, err := a.buildEndpointFromRequest(&imp) + if err != nil { + errs = append(errs, err) + continue + } + + requestJSON, err := json.Marshal(requestCopy) + if err != nil { + errs = append(errs, err) + continue + } + + request := &adapters.RequestData{ + Method: http.MethodPost, + Body: requestJSON, + Uri: endpoint, + Headers: headers, + } + + requests = append(requests, request) + } + + return requests, errs +} + +func (a *adapter) MakeBids(openRTBRequest *openrtb2.BidRequest, requestToBidder *adapters.RequestData, bidderRawResponse *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(bidderRawResponse) { + return nil, nil + } + + if bidderRawResponse.StatusCode == http.StatusServiceUnavailable { + return nil, []error{&errortypes.BadInput{ + Message: "Bidder IQZonex is unavailable. Please contact the bidder support.", + }} + } + + if err := adapters.CheckResponseStatusCodeForErrors(bidderRawResponse); err != nil { + return nil, []error{err} + } + + var bidResp openrtb2.BidResponse + if err := json.Unmarshal(bidderRawResponse.Body, &bidResp); err != nil { + return nil, []error{err} + } + + if len(bidResp.SeatBid) == 0 { + return nil, []error{&errortypes.BadServerResponse{ + Message: "Array SeatBid cannot be empty", + }} + } + + return prepareBidResponse(bidResp.SeatBid) +} + +func prepareBidResponse(seats []openrtb2.SeatBid) (*adapters.BidderResponse, []error) { + errs := []error{} + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(seats)) + + for _, seatBid := range seats { + for bidId, bid := range seatBid.Bid { + bidType, err := getMediaTypeForBid(bid) + if err != nil { + errs = append(errs, err) + continue + } + + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &seatBid.Bid[bidId], + BidType: bidType, + }) + } + } + + return bidResponse, errs +} + +func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + return "", fmt.Errorf("failed to parse bid mtype for impression id \"%s\"", bid.ImpID) + } +} diff --git a/adapters/iqx/iqxtest_test.go b/adapters/iqx/iqxtest_test.go new file mode 100644 index 00000000000..18eaf5fa5ba --- /dev/null +++ b/adapters/iqx/iqxtest_test.go @@ -0,0 +1,27 @@ +package iqx + +import ( + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder( + openrtb_ext.BidderIQX, + config.Adapter{ + Endpoint: "http://rtb.iqzone.com/?pid={{.SourceId}}&host={{.Host}}&pbs=1", + }, + config.Server{ + ExternalUrl: "http://hosturl.com", + GvlID: 1, + DataCenter: "2", + }, + ) + + assert.NoError(t, buildErr) + adapterstest.RunJSONBidderTest(t, "iqzonextest", bidder) +} diff --git a/adapters/iqx/iqzonextest/exemplary/banner.json b/adapters/iqx/iqzonextest/exemplary/banner.json new file mode 100644 index 00000000000..303de661a2d --- /dev/null +++ b/adapters/iqx/iqzonextest/exemplary/banner.json @@ -0,0 +1,283 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "1", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250, + "pos": 0 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + }, + { + "id": "2", + "secure": 1, + "bidfloor": 0.2, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250, + "pos": 4 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": ["IAB12"], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "1", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250, + "pos": 0 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": ["IAB12"], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "1", + "price": 1.2, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test2", + "adomain": ["test.com"], + "cat": ["IAB1"], + "cid": "cid", + "crid": "crid1", + "w": 300, + "h": 250, + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + }, + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "2", + "secure": 1, + "bidfloor": 0.2, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250, + "pos": 4 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": ["IAB12"], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "2", + "price": 2.4, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test3", + "adomain": ["test.com"], + "cat": ["IAB1"], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "id", + "impid": "1", + "price": 1.2, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test2", + "adomain": ["test.com"], + "cat": ["IAB1"], + "cid": "cid", + "crid": "crid1", + "w": 300, + "h": 250, + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + }, + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "id", + "impid": "2", + "price": 2.4, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test3", + "adomain": ["test.com"], + "cat": ["IAB1"], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/iqx/iqzonextest/exemplary/native.json b/adapters/iqx/iqzonextest/exemplary/native.json new file mode 100644 index 00000000000..f458d70e127 --- /dev/null +++ b/adapters/iqx/iqzonextest/exemplary/native.json @@ -0,0 +1,164 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "{}", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "mtype": 4, + "ext": { + "prebid": { + "type": "native" + } + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "{}", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "mtype": 4, + "ext": { + "prebid": { + "type": "native" + } + } + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/iqx/iqzonextest/exemplary/video.json b/adapters/iqx/iqzonextest/exemplary/video.json new file mode 100644 index 00000000000..21826ac0440 --- /dev/null +++ b/adapters/iqx/iqzonextest/exemplary/video.json @@ -0,0 +1,204 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "video": { + "mimes": [ + "video/mp4", + "video/ogg", + "video/webm" + ], + "minduration": 3, + "maxduration": 3000, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 480, + "h": 320, + "linearity": 1, + "playbackmethod": [ + 2 + ], + "pos": 0 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "video": { + "mimes": [ + "video/mp4", + "video/ogg", + "video/webm" + ], + "minduration": 3, + "maxduration": 3000, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 480, + "h": 320, + "linearity": 1, + "playbackmethod": [ + 2 + ], + "pos": 0 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "mtype": 2, + "ext": { + "prebid": { + "type": "video" + } + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "mtype": 2, + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/iqx/iqzonextest/supplemental/bad-response.json b/adapters/iqx/iqzonextest/supplemental/bad-response.json new file mode 100644 index 00000000000..3d9ff9ffcd3 --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/bad-response.json @@ -0,0 +1,106 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": "" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/iqx/iqzonextest/supplemental/empty-mediatype.json b/adapters/iqx/iqzonextest/supplemental/empty-mediatype.json new file mode 100644 index 00000000000..3f471c9c06e --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/empty-mediatype.json @@ -0,0 +1,190 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "1", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test1", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, { + "id": "id", + "impid": "2", + "price": 1.2, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test2", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "some": "value" + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "failed to parse bid mtype for impression id \"2\"", + "comparison": "literal" + } + ], + "expectedBidResponses": [ + { + "currency":"USD", + "bids":[ + { + "bid": { + "id": "id", + "impid": "1", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test1", + "adomain": ["test.com"], + "cat": ["IAB1"], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/iqx/iqzonextest/supplemental/empty-seatbid-0-bid.json b/adapters/iqx/iqzonextest/supplemental/empty-seatbid-0-bid.json new file mode 100644 index 00000000000..66b78f4bfbd --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/empty-seatbid-0-bid.json @@ -0,0 +1,111 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedMakeBidsErrors": [], + "expectedBidResponses": [{"currency":"USD","bids":[]}] +} diff --git a/adapters/iqx/iqzonextest/supplemental/empty-seatbid.json b/adapters/iqx/iqzonextest/supplemental/empty-seatbid.json new file mode 100644 index 00000000000..4df7e16f767 --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/empty-seatbid.json @@ -0,0 +1,111 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "a1580f2f-be6d-11eb-a150-d094662c1c35", + "bidid": "359da97d0384d8a14767029c18fd840d", + "seatbid": [], + "cur": "USD" + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Array SeatBid cannot be empty", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/iqx/iqzonextest/supplemental/invalid-ext-bidder-object.json b/adapters/iqx/iqzonextest/supplemental/invalid-ext-bidder-object.json new file mode 100644 index 00000000000..2f124a8cf3b --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/invalid-ext-bidder-object.json @@ -0,0 +1,49 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": [] + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [], + "expectedMakeRequestsErrors": [ + { + "value": "Failed to deserialize IQZonex extension: json: cannot unmarshal array into Go value of type openrtb_ext.ExtIQX", + "comparison": "literal" + } + ] +} diff --git a/adapters/iqx/iqzonextest/supplemental/invalid-ext-object.json b/adapters/iqx/iqzonextest/supplemental/invalid-ext-object.json new file mode 100644 index 00000000000..aa215eb3e34 --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/invalid-ext-object.json @@ -0,0 +1,47 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": "" + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [], + "expectedMakeRequestsErrors": [ + { + "value": "Failed to deserialize bidder impression extension: json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "comparison": "literal" + } + ] +} diff --git a/adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json b/adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json new file mode 100644 index 00000000000..f2ded0f0cb4 --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json @@ -0,0 +1,187 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "1", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test1", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + }, { + "id": "id", + "impid": "2", + "price": 1.2, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test2", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250 + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "failed to parse bid mtype for impression id \"2\"", + "comparison": "literal" + } + ], + "expectedBidResponses": [ + { + "currency":"USD", + "bids":[ + { + "bid": { + "id": "id", + "impid": "1", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test1", + "adomain": ["test.com"], + "cat": ["IAB1"], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "mtype": 1, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/iqx/iqzonextest/supplemental/status-204.json b/adapters/iqx/iqzonextest/supplemental/status-204.json new file mode 100644 index 00000000000..c850d34b527 --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/status-204.json @@ -0,0 +1,100 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/iqx/iqzonextest/supplemental/status-400.json b/adapters/iqx/iqzonextest/supplemental/status-400.json new file mode 100644 index 00000000000..7e3d17d3baf --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/status-400.json @@ -0,0 +1,106 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 400, + "body": "The Key has a different ad format" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/iqx/iqzonextest/supplemental/status-503.json b/adapters/iqx/iqzonextest/supplemental/status-503.json new file mode 100644 index 00000000000..1b6dd02af8c --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/status-503.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 503 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bidder IQZonex is unavailable. Please contact the bidder support.", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/iqx/iqzonextest/supplemental/unexpected-status.json b/adapters/iqx/iqzonextest/supplemental/unexpected-status.json new file mode 100644 index 00000000000..edfdf5fdd80 --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/unexpected-status.json @@ -0,0 +1,106 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 403, + "body": "Access is denied" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 403. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/iqx/params_test.go b/adapters/iqx/params_test.go new file mode 100644 index 00000000000..94bfb1d0926 --- /dev/null +++ b/adapters/iqx/params_test.go @@ -0,0 +1,53 @@ +package iqx + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/openrtb_ext" +) + +var validParams = []string{ + `{"env":"iqzonex-stage", "pid":"123456"}`, +} + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderIQX, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected iqzonex params: %s", validParam) + } + } +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `[]`, + `{}`, + `{"some": "param"}`, + `{"env":"iqzonex-stage"}`, + `{"pid":"1234"}`, + `{"othervalue":"Lorem ipsum"}`, + `{"env":"iqzonex-stage", pid:""}`, + `{"env":"", pid:"1234"}`, +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderIQX, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 29e16bb2904..d6b4400cd05 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -95,6 +95,7 @@ import ( "github.com/prebid/prebid-server/adapters/inmobi" "github.com/prebid/prebid-server/adapters/interactiveoffers" "github.com/prebid/prebid-server/adapters/invibes" + "github.com/prebid/prebid-server/adapters/iqx" "github.com/prebid/prebid-server/adapters/iqzone" "github.com/prebid/prebid-server/adapters/ix" "github.com/prebid/prebid-server/adapters/jixie" @@ -289,6 +290,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderInMobi: inmobi.Builder, openrtb_ext.BidderInteractiveoffers: interactiveoffers.Builder, openrtb_ext.BidderInvibes: invibes.Builder, + openrtb_ext.BidderIQX: iqx.Builder, openrtb_ext.BidderIQZone: iqzone.Builder, openrtb_ext.BidderIx: ix.Builder, openrtb_ext.BidderJixie: jixie.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 709c3aa3cdd..ae0f7b6c82a 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -114,6 +114,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderInMobi, BidderInteractiveoffers, BidderInvibes, + BidderIQX, BidderIQZone, BidderIx, BidderJixie, @@ -393,6 +394,7 @@ const ( BidderInMobi BidderName = "inmobi" BidderInteractiveoffers BidderName = "interactiveoffers" BidderInvibes BidderName = "invibes" + BidderIQX BidderName = "iqx" BidderIQZone BidderName = "iqzone" BidderIx BidderName = "ix" BidderJixie BidderName = "jixie" diff --git a/openrtb_ext/imp_iqx.go b/openrtb_ext/imp_iqx.go new file mode 100644 index 00000000000..0b0358b67e1 --- /dev/null +++ b/openrtb_ext/imp_iqx.go @@ -0,0 +1,6 @@ +package openrtb_ext + +type ExtIQX struct { + Env string `json:"env"` + Pid string `json:"pid"` +} diff --git a/static/bidder-info/iqx.yaml b/static/bidder-info/iqx.yaml new file mode 100644 index 00000000000..ab10ad96289 --- /dev/null +++ b/static/bidder-info/iqx.yaml @@ -0,0 +1,19 @@ +endpoint: "http://rtb.iqzone.com?pid={{.SourceId}}&host={{.Host}}&pbs=1" +maintainer: + email: "it@iqzone.com" +capabilities: + app: + mediaTypes: + - banner + - video + - native + site: + mediaTypes: + - banner + - video + - native +userSync: + # IQX supports user syncing, but requires configuration by the host. contact this + # bidder directly at the email address in this file to ask about enabling user sync. + supports: + - redirect \ No newline at end of file diff --git a/static/bidder-params/iqx.json b/static/bidder-params/iqx.json new file mode 100644 index 00000000000..447c92beeb8 --- /dev/null +++ b/static/bidder-params/iqx.json @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "IQX Adapter Params", + "description": "A schema which validates params accepted by the iqzonex adapter", + "type": "object", + "properties": { + "env": { + "type": "string", + "description": "IQX environment", + "minLength": 1 + }, + "pid": { + "type": "string", + "description": "Unique placement ID", + "minLength": 1 + } + }, + "required": [ + "env", + "pid" + ] +} From e8d93ccbc4a6c391176bbd6b1696d920b1aca840 Mon Sep 17 00:00:00 2001 From: Ahmet Faruk Karakus <65093478+ahmetfaruk59@users.noreply.github.com> Date: Thu, 19 Oct 2023 15:23:38 +0300 Subject: [PATCH 190/268] HuaweiAds: Fixing the fill rate issue (#3219) --- adapters/huaweiads/huaweiads.go | 12 +++++++++++- .../huaweiadstest/exemplary/nativeIncludeVideo.json | 2 ++ .../huaweiadstest/exemplary/nativeSingleImage.json | 2 ++ .../huaweiadstest/exemplary/nativeThreeImage.json | 2 ++ .../exemplary/nativeThreeImageIncludeIcon.json | 2 ++ .../supplemental/bad_response_not_native.json | 4 +++- 6 files changed, 22 insertions(+), 2 deletions(-) diff --git a/adapters/huaweiads/huaweiads.go b/adapters/huaweiads/huaweiads.go index 2b7c3c2548d..d156c2f750f 100644 --- a/adapters/huaweiads/huaweiads.go +++ b/adapters/huaweiads/huaweiads.go @@ -536,7 +536,8 @@ func getNativeFormat(adslot30 *adslot30, openRTBImp *openrtb2.Imp) error { // only compute the main image number, type = native1.ImageAssetTypeMain var numMainImage = 0 var numVideo = 0 - + var width int64 + var height int64 for _, asset := range nativePayload.Assets { // Only one of the {title,img,video,data} objects should be present in each object. if asset.Video != nil { @@ -547,10 +548,19 @@ func getNativeFormat(adslot30 *adslot30, openRTBImp *openrtb2.Imp) error { if asset.Img != nil { if asset.Img.Type == native1.ImageAssetTypeMain { numMainImage++ + if asset.Img.H != 0 && asset.Img.W != 0 { + width = asset.Img.W + height = asset.Img.H + } else if asset.Img.WMin != 0 && asset.Img.HMin != 0 { + width = asset.Img.WMin + height = asset.Img.HMin + } } continue } } + adslot30.W = width + adslot30.H = height var detailedCreativeTypeList = make([]string, 0, 2) if numVideo >= 1 { diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json index 24aad066b3d..673d6a39a99 100644 --- a/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json +++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json @@ -95,6 +95,8 @@ "detailedCreativeTypeList": [ "903" ], + "h": 200, + "w": 200, "test": 1 } ], diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json index 8e86675b4a6..d296010cc77 100644 --- a/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json +++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json @@ -93,6 +93,8 @@ "detailedCreativeTypeList": [ "901" ], + "h": 200, + "w": 200, "test": 1 } ], diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json index c29b2352d59..16313a5588a 100644 --- a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json +++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json @@ -92,6 +92,8 @@ "detailedCreativeTypeList": [ "904" ], + "h": 200, + "w": 200, "test": 1 } ], diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json index 5d3af50621a..6122af732c2 100644 --- a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json +++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json @@ -93,6 +93,8 @@ "detailedCreativeTypeList": [ "904" ], + "h": 200, + "w": 200, "test": 1 } ], diff --git a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json index 1466737008f..c38bc9f69b9 100644 --- a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json +++ b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json @@ -93,7 +93,9 @@ "test": 1, "detailedCreativeTypeList": [ "903" - ] + ], + "h": 200, + "w": 200 } ], "device": { From 34ddf1a1adc46d88023d15a4b7b684921fdcc3c4 Mon Sep 17 00:00:00 2001 From: kmdevops <126434358+kmdevops@users.noreply.github.com> Date: Thu, 19 Oct 2023 14:29:49 +0200 Subject: [PATCH 191/268] DXKulture adapter (#3176) co-authored: @kmdevops --- adapters/dxkulture/dxkulture.go | 170 ++++++++++++++++++ adapters/dxkulture/dxkulture_test.go | 17 ++ .../dxkulturetest/exemplary/banner.json | 144 +++++++++++++++ .../exemplary/empty-site-domain-ref.json | 142 +++++++++++++++ .../dxkulturetest/exemplary/ipv6.json | 142 +++++++++++++++ .../exemplary/video-test-request.json | 154 ++++++++++++++++ .../dxkulturetest/exemplary/video.json | 152 ++++++++++++++++ .../supplemental/invalid-imp-ext-bidder.json | 40 +++++ .../supplemental/invalid-imp-ext.json | 38 ++++ .../supplemental/invalid-response.json | 113 ++++++++++++ .../dxkulturetest/supplemental/no-mtype.json | 142 +++++++++++++++ .../supplemental/status-code-bad-request.json | 112 ++++++++++++ .../supplemental/status-code-no-content.json | 108 +++++++++++ .../supplemental/status-code-other-error.json | 112 ++++++++++++ adapters/dxkulture/params_test.go | 53 ++++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_dxkulture.go | 7 + static/bidder-info/dxkulture.yaml | 16 ++ static/bidder-params/dxkulture.json | 20 +++ 20 files changed, 1686 insertions(+) create mode 100644 adapters/dxkulture/dxkulture.go create mode 100644 adapters/dxkulture/dxkulture_test.go create mode 100644 adapters/dxkulture/dxkulturetest/exemplary/banner.json create mode 100644 adapters/dxkulture/dxkulturetest/exemplary/empty-site-domain-ref.json create mode 100644 adapters/dxkulture/dxkulturetest/exemplary/ipv6.json create mode 100644 adapters/dxkulture/dxkulturetest/exemplary/video-test-request.json create mode 100644 adapters/dxkulture/dxkulturetest/exemplary/video.json create mode 100644 adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext-bidder.json create mode 100644 adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext.json create mode 100644 adapters/dxkulture/dxkulturetest/supplemental/invalid-response.json create mode 100644 adapters/dxkulture/dxkulturetest/supplemental/no-mtype.json create mode 100644 adapters/dxkulture/dxkulturetest/supplemental/status-code-bad-request.json create mode 100644 adapters/dxkulture/dxkulturetest/supplemental/status-code-no-content.json create mode 100644 adapters/dxkulture/dxkulturetest/supplemental/status-code-other-error.json create mode 100644 adapters/dxkulture/params_test.go create mode 100644 openrtb_ext/imp_dxkulture.go create mode 100644 static/bidder-info/dxkulture.yaml create mode 100644 static/bidder-params/dxkulture.json diff --git a/adapters/dxkulture/dxkulture.go b/adapters/dxkulture/dxkulture.go new file mode 100644 index 00000000000..5347c71a303 --- /dev/null +++ b/adapters/dxkulture/dxkulture.go @@ -0,0 +1,170 @@ +package dxkulture + +import ( + "encoding/json" + "fmt" + "net/http" + "net/url" + + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/openrtb_ext" + + "github.com/prebid/openrtb/v19/openrtb2" +) + +var markupTypeToBidType = map[openrtb2.MarkupType]openrtb_ext.BidType{ + openrtb2.MarkupBanner: openrtb_ext.BidTypeBanner, + openrtb2.MarkupVideo: openrtb_ext.BidTypeVideo, +} + +type adapter struct { + endpoint string +} + +// Builder builds a new instance of the DXKulture adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + impressions := request.Imp + + adapterRequests := make([]*adapters.RequestData, 0, len(impressions)) + var errs []error + + for _, impression := range impressions { + impExt, err := parseExt(&impression) + if err != nil { + errs = append(errs, err) + continue + } + + request.Imp = []openrtb2.Imp{impression} + body, err := json.Marshal(request) + if err != nil { + errs = append(errs, err) + continue + } + + if request.Test == 1 { + impExt.PublisherId = "test" + } + + params := url.Values{} + params.Add("publisher_id", impExt.PublisherId) + params.Add("placement_id", impExt.PlacementId) + + adapterRequests = append(adapterRequests, &adapters.RequestData{ + Method: http.MethodPost, + Uri: a.endpoint + "?" + params.Encode(), + Body: body, + Headers: getHeaders(request), + }) + } + + request.Imp = impressions + return adapterRequests, errs +} + +func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(response) { + return nil, nil + } + if err := adapters.CheckResponseStatusCodeForErrors(response); err != nil { + return nil, []error{err} + } + + var ortbResponse openrtb2.BidResponse + err := json.Unmarshal(response.Body, &ortbResponse) + if err != nil { + return nil, []error{&errortypes.BadServerResponse{ + Message: "Bad Server Response", + }} + } + + var bidErrors []error + + bidderResponse := adapters.NewBidderResponseWithBidsCapacity(1) + for _, seatBid := range ortbResponse.SeatBid { + for i := range seatBid.Bid { + bid := seatBid.Bid[i] + bidType, err := getBidType(&bid) + if err != nil { + bidErrors = append(bidErrors, err) + continue + } + + bidderResponse.Bids = append(bidderResponse.Bids, &adapters.TypedBid{ + Bid: &bid, + BidType: bidType, + }) + } + } + + return bidderResponse, bidErrors +} + +func getBidType(bid *openrtb2.Bid) (openrtb_ext.BidType, error) { + if bidType, ok := markupTypeToBidType[bid.MType]; ok { + return bidType, nil + } + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unsupported MType %d", bid.MType), + } +} + +func parseExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpDXKulture, error) { + var bidderExt adapters.ExtImpBidder + + if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + return nil, &errortypes.BadInput{ + Message: fmt.Sprintf("Ignoring imp id=%s, error while decoding extImpBidder, err: %s", imp.ID, err), + } + } + + impExt := openrtb_ext.ExtImpDXKulture{} + err := json.Unmarshal(bidderExt.Bidder, &impExt) + if err != nil { + return nil, &errortypes.BadInput{ + Message: fmt.Sprintf("Ignoring imp id=%s, error while decoding impExt, err: %s", imp.ID, err), + } + } + + return &impExt, nil +} + +func getHeaders(request *openrtb2.BidRequest) http.Header { + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + headers.Add("X-Openrtb-Version", "2.5") + + if request.Site != nil { + if request.Site.Ref != "" { + headers.Set("Referer", request.Site.Ref) + } + if request.Site.Domain != "" { + headers.Add("Origin", request.Site.Domain) + } + } + + if request.Device != nil { + if len(request.Device.UA) > 0 { + headers.Add("User-Agent", request.Device.UA) + } + + if len(request.Device.IPv6) > 0 { + headers.Add("X-Forwarded-For", request.Device.IPv6) + } + + if len(request.Device.IP) > 0 { + headers.Add("X-Forwarded-For", request.Device.IP) + } + } + return headers +} diff --git a/adapters/dxkulture/dxkulture_test.go b/adapters/dxkulture/dxkulture_test.go new file mode 100644 index 00000000000..9b2da4f27ab --- /dev/null +++ b/adapters/dxkulture/dxkulture_test.go @@ -0,0 +1,17 @@ +package dxkulture + +import ( + "testing" + + "github.com/prebid/prebid-server/config" + + "github.com/prebid/prebid-server/adapters/adapterstest" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder("dxkulture", config.Adapter{Endpoint: "https://ads.kulture.media/pbs"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + adapterstest.RunJSONBidderTest(t, "dxkulturetest", bidder) +} diff --git a/adapters/dxkulture/dxkulturetest/exemplary/banner.json b/adapters/dxkulture/dxkulturetest/exemplary/banner.json new file mode 100644 index 00000000000..3b84881fc67 --- /dev/null +++ b/adapters/dxkulture/dxkulturetest/exemplary/banner.json @@ -0,0 +1,144 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "domain": "site.com", + "page": "http://site.com/page", + "ref": "http://site.com/ref" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "GET", + "headers": { + "Referer": [ + "http://site.com/ref" + ], + "Origin": [ + "site.com" + ], + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "User-Agent": [ + "user-agent" + ], + "X-Forwarded-For": [ + "1.2.3.4" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=pub123", + "body": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "domain": "site.com", + "page": "http://site.com/page", + "ref": "http://site.com/ref" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", + "crid": "16329", + "adomain": [ + "adomain.com" + ], + "price": 3, + "impid": "test-imp-id", + "adid": "2422", + "adm": "", + "mtype": 1 + } + ], + "seat": "dxkulture" + } + ], + "bidid": "test-request-id", + "id": "test-request-id" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", + "crid": "16329", + "adomain": [ + "adomain.com" + ], + "price": 3, + "impid": "test-imp-id", + "adid": "2422", + "adm": "", + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/dxkulture/dxkulturetest/exemplary/empty-site-domain-ref.json b/adapters/dxkulture/dxkulturetest/exemplary/empty-site-domain-ref.json new file mode 100644 index 00000000000..630467ce96b --- /dev/null +++ b/adapters/dxkulture/dxkulturetest/exemplary/empty-site-domain-ref.json @@ -0,0 +1,142 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "page": "http://site.com/page" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "GET", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "User-Agent": [ + "user-agent" + ], + "X-Forwarded-For": [ + "1.2.3.4" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=pub123", + "body": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "page": "http://site.com/page" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", + "crid": "16329", + "adomain": [ + "adomain.com" + ], + "price": 3, + "impid": "test-imp-id", + "adid": "2422", + "adm": "", + "mtype": 2 + } + ], + "seat": "dxkulture" + } + ], + "bidid": "test-request-id", + "id": "test-request-id" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", + "crid": "16329", + "adomain": [ + "adomain.com" + ], + "price": 3, + "impid": "test-imp-id", + "adid": "2422", + "adm": "", + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/dxkulture/dxkulturetest/exemplary/ipv6.json b/adapters/dxkulture/dxkulturetest/exemplary/ipv6.json new file mode 100644 index 00000000000..58f7e7fdf2c --- /dev/null +++ b/adapters/dxkulture/dxkulturetest/exemplary/ipv6.json @@ -0,0 +1,142 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ipv6": "2001:0000:130F:0000:0000:09C0:876A:130B" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "page": "http://site.com/page" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "GET", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "User-Agent": [ + "user-agent" + ], + "X-Forwarded-For": [ + "2001:0000:130F:0000:0000:09C0:876A:130B" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=pub123", + "body": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ipv6": "2001:0000:130F:0000:0000:09C0:876A:130B" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "page": "http://site.com/page" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", + "crid": "16329", + "adomain": [ + "adomain.com" + ], + "price": 3, + "impid": "test-imp-id", + "adid": "2422", + "adm": "", + "mtype": 2 + } + ], + "seat": "dxkulture" + } + ], + "bidid": "test-request-id", + "id": "test-request-id" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", + "crid": "16329", + "adomain": [ + "adomain.com" + ], + "price": 3, + "impid": "test-imp-id", + "adid": "2422", + "adm": "", + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/dxkulture/dxkulturetest/exemplary/video-test-request.json b/adapters/dxkulture/dxkulturetest/exemplary/video-test-request.json new file mode 100644 index 00000000000..6a0746ad258 --- /dev/null +++ b/adapters/dxkulture/dxkulturetest/exemplary/video-test-request.json @@ -0,0 +1,154 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "test": 1, + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "domain": "site.com", + "page": "http://site.com/page", + "ref": "http://site.com/ref" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "GET", + "headers": { + "Referer": [ + "http://site.com/ref" + ], + "Origin": [ + "site.com" + ], + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "User-Agent": [ + "user-agent" + ], + "X-Forwarded-For": [ + "1.2.3.4" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=test", + "body": { + "id": "test-request-id", + "test": 1, + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "domain": "site.com", + "page": "http://site.com/page", + "ref": "http://site.com/ref" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", + "crid": "16329", + "adomain": [ + "adomain.com" + ], + "price": 3, + "impid": "test-imp-id", + "adid": "2422", + "adm": "", + "mtype": 2 + } + ], + "seat": "dxkulture" + } + ], + "bidid": "test-request-id", + "id": "test-request-id" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", + "crid": "16329", + "adomain": [ + "adomain.com" + ], + "price": 3, + "impid": "test-imp-id", + "adid": "2422", + "adm": "", + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/dxkulture/dxkulturetest/exemplary/video.json b/adapters/dxkulture/dxkulturetest/exemplary/video.json new file mode 100644 index 00000000000..017dd5ea2bc --- /dev/null +++ b/adapters/dxkulture/dxkulturetest/exemplary/video.json @@ -0,0 +1,152 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "domain": "site.com", + "page": "http://site.com/page", + "ref": "http://site.com/ref" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "GET", + "headers": { + "Referer": [ + "http://site.com/ref" + ], + "Origin": [ + "site.com" + ], + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "User-Agent": [ + "user-agent" + ], + "X-Forwarded-For": [ + "1.2.3.4" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=pub123", + "body": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "domain": "site.com", + "page": "http://site.com/page", + "ref": "http://site.com/ref" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", + "crid": "16329", + "adomain": [ + "adomain.com" + ], + "price": 3, + "impid": "test-imp-id", + "adid": "2422", + "adm": "", + "mtype": 2 + } + ], + "seat": "dxkulture" + } + ], + "bidid": "test-request-id", + "id": "test-request-id" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", + "crid": "16329", + "adomain": [ + "adomain.com" + ], + "price": 3, + "impid": "test-imp-id", + "adid": "2422", + "adm": "", + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext-bidder.json b/adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext-bidder.json new file mode 100644 index 00000000000..ae30b327030 --- /dev/null +++ b/adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext-bidder.json @@ -0,0 +1,40 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": "not_json" + } + } + ], + "site": { + "domain": "site.com", + "page": "http://site.com/page", + "ref": "http://site.com/ref" + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "Ignoring imp id=test-imp-id, error while decoding impExt, err: json: cannot unmarshal string into Go value of type openrtb_ext.ExtImpDXKulture", + "comparison": "literal" + } + ] +} diff --git a/adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext.json b/adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext.json new file mode 100644 index 00000000000..2587dc216d2 --- /dev/null +++ b/adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext.json @@ -0,0 +1,38 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": "not_json" + } + ], + "site": { + "domain": "site.com", + "page": "http://site.com/page", + "ref": "http://site.com/ref" + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "Ignoring imp id=test-imp-id, error while decoding extImpBidder, err: json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "comparison": "literal" + } + ] +} diff --git a/adapters/dxkulture/dxkulturetest/supplemental/invalid-response.json b/adapters/dxkulture/dxkulturetest/supplemental/invalid-response.json new file mode 100644 index 00000000000..8fff1bb0375 --- /dev/null +++ b/adapters/dxkulture/dxkulturetest/supplemental/invalid-response.json @@ -0,0 +1,113 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "domain": "site.com", + "page": "http://site.com/page", + "ref": "http://site.com/ref" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "GET", + "headers": { + "Referer": [ + "http://site.com/ref" + ], + "Origin": [ + "site.com" + ], + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "User-Agent": [ + "user-agent" + ], + "X-Forwarded-For": [ + "1.2.3.4" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=pub123", + "body": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "domain": "site.com", + "page": "http://site.com/page", + "ref": "http://site.com/ref" + } + } + }, + "mockResponse": { + "status": 200, + "body": "body" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bad Server Response", + "comparison": "literal" + } + ] +} diff --git a/adapters/dxkulture/dxkulturetest/supplemental/no-mtype.json b/adapters/dxkulture/dxkulturetest/supplemental/no-mtype.json new file mode 100644 index 00000000000..a56200fad50 --- /dev/null +++ b/adapters/dxkulture/dxkulturetest/supplemental/no-mtype.json @@ -0,0 +1,142 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "domain": "site.com", + "page": "http://site.com/page", + "ref": "http://site.com/ref" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "GET", + "headers": { + "Referer": [ + "http://site.com/ref" + ], + "Origin": [ + "site.com" + ], + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "User-Agent": [ + "user-agent" + ], + "X-Forwarded-For": [ + "1.2.3.4" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=pub123", + "body": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "domain": "site.com", + "page": "http://site.com/page", + "ref": "http://site.com/ref" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "43271b2d-41c0-4093-8ba1-2105d9658e80", + "crid": "16329", + "adomain": [ + "adomain.com" + ], + "price": 3, + "impid": "test-imp-id", + "adid": "2422", + "adm": "" + } + ], + "seat": "dxkulture" + } + ], + "bidid": "test-request-id", + "id": "test-request-id" + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unsupported MType 0", + "comparison": "literal" + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [] + } + ] + +} diff --git a/adapters/dxkulture/dxkulturetest/supplemental/status-code-bad-request.json b/adapters/dxkulture/dxkulturetest/supplemental/status-code-bad-request.json new file mode 100644 index 00000000000..f0f2ce2c47b --- /dev/null +++ b/adapters/dxkulture/dxkulturetest/supplemental/status-code-bad-request.json @@ -0,0 +1,112 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "domain": "site.com", + "page": "http://site.com/page", + "ref": "http://site.com/ref" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "GET", + "headers": { + "Referer": [ + "http://site.com/ref" + ], + "Origin": [ + "site.com" + ], + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "User-Agent": [ + "user-agent" + ], + "X-Forwarded-For": [ + "1.2.3.4" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=pub123", + "body": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "domain": "site.com", + "page": "http://site.com/page", + "ref": "http://site.com/ref" + } + } + }, + "mockResponse": { + "status": 400 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/dxkulture/dxkulturetest/supplemental/status-code-no-content.json b/adapters/dxkulture/dxkulturetest/supplemental/status-code-no-content.json new file mode 100644 index 00000000000..43c53f3d64c --- /dev/null +++ b/adapters/dxkulture/dxkulturetest/supplemental/status-code-no-content.json @@ -0,0 +1,108 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "domain": "site.com", + "page": "http://site.com/page", + "ref": "http://site.com/ref" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "GET", + "headers": { + "Referer": [ + "http://site.com/ref" + ], + "Origin": [ + "site.com" + ], + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "User-Agent": [ + "user-agent" + ], + "X-Forwarded-For": [ + "1.2.3.4" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=pub123", + "body": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "domain": "site.com", + "page": "http://site.com/page", + "ref": "http://site.com/ref" + } + } + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [] +} diff --git a/adapters/dxkulture/dxkulturetest/supplemental/status-code-other-error.json b/adapters/dxkulture/dxkulturetest/supplemental/status-code-other-error.json new file mode 100644 index 00000000000..3e1b0b33c1e --- /dev/null +++ b/adapters/dxkulture/dxkulturetest/supplemental/status-code-other-error.json @@ -0,0 +1,112 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "domain": "site.com", + "page": "http://site.com/page", + "ref": "http://site.com/ref" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "GET", + "headers": { + "Referer": [ + "http://site.com/ref" + ], + "Origin": [ + "site.com" + ], + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "User-Agent": [ + "user-agent" + ], + "X-Forwarded-For": [ + "1.2.3.4" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=pub123", + "body": { + "id": "test-request-id", + "user": { + "buyeruid": "userId", + "yob": 1990 + }, + "device": { + "ua": "user-agent", + "ip": "1.2.3.4" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 1920, + "h": 1080, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": "pub123", + "placementId": "placement123" + } + } + } + ], + "site": { + "domain": "site.com", + "page": "http://site.com/page", + "ref": "http://site.com/ref" + } + } + }, + "mockResponse": { + "status": 505 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 505. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/dxkulture/params_test.go b/adapters/dxkulture/params_test.go new file mode 100644 index 00000000000..838d092df8f --- /dev/null +++ b/adapters/dxkulture/params_test.go @@ -0,0 +1,53 @@ +package dxkulture + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/openrtb_ext" +) + +// This file actually intends to test static/bidder-params/dxkulture.json +// +// These also validate the format of the external API: request.imp[i].ext.prebid.bidder.dxkulture + +// TestValidParams makes sure that the dxkulture schema accepts all imp.ext fields which we intend to support. +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderDXKulture, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected dxkulture params: %s", validParam) + } + } +} + +// TestInvalidParams makes sure that the dxkulture schema rejects all the imp.ext fields we don't support. +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderDXKulture, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{"publisherId": "pub", "placementId": "plac"}`, + `{"publisherId": "pub", "placementId": "plac", "a":1}`, +} + +var invalidParams = []string{ + `{"publisherId": "pub"}`, + `{"placementId": "plac"}`, + //malformed + `{"ub", "placementId": "plac"}`, + `{}`, +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index d6b4400cd05..6ab0dccfc7c 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -73,6 +73,7 @@ import ( "github.com/prebid/prebid-server/adapters/deepintent" "github.com/prebid/prebid-server/adapters/dianomi" "github.com/prebid/prebid-server/adapters/dmx" + "github.com/prebid/prebid-server/adapters/dxkulture" evolution "github.com/prebid/prebid-server/adapters/e_volution" "github.com/prebid/prebid-server/adapters/edge226" "github.com/prebid/prebid-server/adapters/emtv" @@ -266,6 +267,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderDianomi: dianomi.Builder, openrtb_ext.BidderEdge226: edge226.Builder, openrtb_ext.BidderDmx: dmx.Builder, + openrtb_ext.BidderDXKulture: dxkulture.Builder, openrtb_ext.BidderEmtv: emtv.Builder, openrtb_ext.BidderEmxDigital: cadentaperturemx.Builder, openrtb_ext.BidderEPlanning: eplanning.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index ae0f7b6c82a..22a915b769f 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -90,6 +90,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderDianomi, BidderEdge226, BidderDmx, + BidderDXKulture, BidderEmtv, BidderEmxDigital, BidderEPlanning, @@ -370,6 +371,7 @@ const ( BidderDianomi BidderName = "dianomi" BidderEdge226 BidderName = "edge226" BidderDmx BidderName = "dmx" + BidderDXKulture BidderName = "dxkulture" BidderEmtv BidderName = "emtv" BidderEmxDigital BidderName = "emx_digital" BidderEPlanning BidderName = "eplanning" diff --git a/openrtb_ext/imp_dxkulture.go b/openrtb_ext/imp_dxkulture.go new file mode 100644 index 00000000000..4b507c55248 --- /dev/null +++ b/openrtb_ext/imp_dxkulture.go @@ -0,0 +1,7 @@ +package openrtb_ext + +// ExtImpDXKulture defines the contract for bidrequest.imp[i].ext.prebid.bidder.dxkulture +type ExtImpDXKulture struct { + PublisherId string `json:"publisherId"` + PlacementId string `json:"placementId"` +} diff --git a/static/bidder-info/dxkulture.yaml b/static/bidder-info/dxkulture.yaml new file mode 100644 index 00000000000..1af72e9fc33 --- /dev/null +++ b/static/bidder-info/dxkulture.yaml @@ -0,0 +1,16 @@ +endpoint: "https://ads.kulture.media/pbs" +maintainer: + email: "devops@kulture.media" +capabilities: + app: + mediaTypes: + - banner + - video + site: + mediaTypes: + - banner + - video +userSync: + redirect: + url: "https://ads.kulture.media/usync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&cb={{.RedirectURL}}" + userMacro: "$UID" diff --git a/static/bidder-params/dxkulture.json b/static/bidder-params/dxkulture.json new file mode 100644 index 00000000000..858eefd22e4 --- /dev/null +++ b/static/bidder-params/dxkulture.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "DXKulture Adapter Params", + "description": "A schema which validates params accepted by the DXKulture adapter", + "type": "object", + "properties": { + "publisherId": { + "type": "string", + "description": "The publisher id" + }, + "placementId": { + "type": "string", + "description": "The placement id" + } + }, + "required": [ + "publisherId", + "placementId" + ] +} From 6f630fd80915492fba577be7868f1eaa8b0cf51a Mon Sep 17 00:00:00 2001 From: Brian Sardo <1168933+bsardo@users.noreply.github.com> Date: Thu, 19 Oct 2023 13:43:00 -0400 Subject: [PATCH 192/268] JSON Serialization: Change Libraries (#3225) --- account/account.go | 9 +- adservertargeting/adservertargeting_test.go | 7 +- adservertargeting/reqcache.go | 5 +- adservertargeting/respdataprocessor.go | 3 +- analytics/filesystem/file_module.go | 14 +- analytics/pubstack/helpers/json.go | 12 +- config/config.go | 3 +- currency/rate_converter.go | 4 +- currency/rates_test.go | 27 ++-- endpoints/cookie_sync.go | 3 +- endpoints/cookie_sync_test.go | 6 +- endpoints/currency_rates.go | 4 +- endpoints/events/vtrack.go | 7 +- endpoints/events/vtrack_test.go | 5 +- endpoints/info/bidders.go | 11 +- endpoints/info/bidders_detail.go | 5 +- endpoints/openrtb2/amp_auction.go | 11 +- endpoints/openrtb2/amp_auction_test.go | 61 ++++---- endpoints/openrtb2/auction.go | 33 ++-- endpoints/openrtb2/auction_test.go | 43 +++--- .../invalid-stored/bad_incoming_1.json | 2 +- .../invalid-stored/bad_incoming_imp.json | 2 +- .../invalid-stored/bad_stored_imp.json | 2 +- .../invalid-stored/bad_stored_req.json | 2 +- .../invalid-whole/interstital-bad-perc.json | 2 +- .../invalid-whole/invalid-source.json | 2 +- .../invalid-whole/malformed-bid-request.json | 2 +- .../invalid-whole/regs-ext-malformed.json | 2 +- .../invalid-whole/user-ext-consent-int.json | 2 +- .../user-gdpr-consent-invalid.json | 2 +- endpoints/openrtb2/test_utils.go | 15 +- endpoints/openrtb2/video_auction.go | 18 +-- endpoints/openrtb2/video_auction_test.go | 21 +-- endpoints/setuid_test.go | 4 +- endpoints/version.go | 3 +- errortypes/code.go | 2 + errortypes/errortypes.go | 34 +++++ exchange/auction.go | 10 +- exchange/auction_test.go | 10 +- exchange/bidder.go | 9 +- exchange/bidder_test.go | 7 +- exchange/events.go | 4 +- exchange/exchange.go | 17 ++- exchange/exchange_test.go | 69 ++++----- exchange/targeting_test.go | 5 +- exchange/utils.go | 39 ++--- exchange/utils_test.go | 53 +++---- firstpartydata/first_party_data.go | 7 +- firstpartydata/first_party_data_test.go | 133 +++++++++-------- floors/floors_test.go | 3 +- floors/rule_test.go | 2 +- gdpr/full_enforcement_test.go | 4 +- gdpr/vendorlist-fetching_test.go | 4 +- go.mod | 3 + go.sum | 3 + hooks/hookanalytics/analytics_test.go | 4 +- hooks/hookexecution/enricher.go | 5 +- hooks/hookexecution/enricher_test.go | 5 +- hooks/hookexecution/test_utils.go | 5 +- hooks/plan_test.go | 18 +-- modules/modules.go | 3 +- modules/modules_test.go | 2 +- modules/prebid/ortb2blocking/config.go | 5 +- modules/prebid/ortb2blocking/module_test.go | 2 +- openrtb_ext/convert_down_test.go | 99 ++++++------ openrtb_ext/convert_up_test.go | 12 +- openrtb_ext/deal_tier.go | 5 +- openrtb_ext/deal_tier_test.go | 21 +-- openrtb_ext/device_test.go | 25 ++-- openrtb_ext/imp_appnexus.go | 6 +- openrtb_ext/imp_appnexus_test.go | 6 +- openrtb_ext/request.go | 5 +- openrtb_ext/request_test.go | 3 +- openrtb_ext/request_wrapper.go | 141 ++++++++++-------- openrtb_ext/request_wrapper_test.go | 25 ++-- openrtb_ext/site_test.go | 18 +-- ortb/default_test.go | 9 +- prebid_cache_client/client_test.go | 3 +- privacy/scrubber.go | 9 +- router/router.go | 5 +- router/router_test.go | 3 +- schain/schainwriter.go | 5 +- schain/schainwriter_test.go | 3 +- .../backends/file_fetcher/fetcher.go | 3 +- .../backends/file_fetcher/fetcher_test.go | 7 +- .../backends/http_fetcher/fetcher.go | 10 +- .../backends/http_fetcher/fetcher_test.go | 7 +- stored_requests/events/api/api.go | 6 +- stored_requests/events/http/http.go | 3 +- stored_requests/events/http/http_test.go | 6 +- stored_responses/stored_responses.go | 3 +- usersync/cookie.go | 6 +- usersync/decoder.go | 8 +- usersync/encoder.go | 5 +- util/jsonutil/jsonutil.go | 113 +++++++++++++- util/jsonutil/jsonutil_test.go | 61 +++++++- util/jsonutil/stringInt_test.go | 11 +- version/xprebidheader_test.go | 6 +- 98 files changed, 862 insertions(+), 617 deletions(-) diff --git a/account/account.go b/account/account.go index b4d0c334d6b..1f5a3feee14 100644 --- a/account/account.go +++ b/account/account.go @@ -2,7 +2,6 @@ package account import ( "context" - "encoding/json" "fmt" "github.com/prebid/go-gdpr/consentconstants" @@ -13,6 +12,7 @@ import ( "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/stored_requests" "github.com/prebid/prebid-server/util/iputil" + "github.com/prebid/prebid-server/util/jsonutil" ) // GetAccount looks up the config.Account object referenced by the given accountID, with access rules applied @@ -44,17 +44,12 @@ func GetAccount(ctx context.Context, cfg *config.Configuration, fetcher stored_r } else { // accountID resolved to a valid account, merge with AccountDefaults for a complete config account = &config.Account{} - err := json.Unmarshal(accountJSON, account) - if _, ok := err.(*json.UnmarshalTypeError); ok { + if err := jsonutil.UnmarshalValid(accountJSON, account); err != nil { return nil, []error{&errortypes.MalformedAcct{ Message: fmt.Sprintf("The prebid-server account config for account id \"%s\" is malformed. Please reach out to the prebid server host.", accountID), }} } - if err != nil { - errs = append(errs, err) - return nil, errs - } // Fill in ID if needed, so it can be left out of account definition if len(account.ID) == 0 { account.ID = accountID diff --git a/adservertargeting/adservertargeting_test.go b/adservertargeting/adservertargeting_test.go index 4a651fdd2be..0da3635d9b7 100644 --- a/adservertargeting/adservertargeting_test.go +++ b/adservertargeting/adservertargeting_test.go @@ -8,6 +8,7 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/openrtb/v19/openrtb3" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/stretchr/testify/assert" ) @@ -42,7 +43,7 @@ func TestExtractAdServerTargeting(t *testing.T) { p := "https://www.test-url.com?ampkey=testAmpKey&data-override-height=400" u, _ := url.Parse(p) params := u.Query() - reqBytes, err := json.Marshal(r) + reqBytes, err := jsonutil.Marshal(r) assert.NoError(t, err, "unexpected req marshal error") res, warnings := collect(rw, reqBytes, params) @@ -248,7 +249,7 @@ func TestProcessAdServerTargetingFull(t *testing.T) { bidResponseExt := &openrtb_ext.ExtBidResponse{Warnings: make(map[openrtb_ext.BidderName][]openrtb_ext.ExtBidderMessage)} - reqBytes, err := json.Marshal(r) + reqBytes, err := jsonutil.Marshal(r) assert.NoError(t, err, "unexpected req marshal error") targetingKeyLen := 0 resResp := Apply(rw, reqBytes, resp, params, bidResponseExt, &targetingKeyLen) @@ -331,7 +332,7 @@ func TestProcessAdServerTargetingWarnings(t *testing.T) { bidResponseExt := &openrtb_ext.ExtBidResponse{Warnings: make(map[openrtb_ext.BidderName][]openrtb_ext.ExtBidderMessage)} - reqBytes, err := json.Marshal(r) + reqBytes, err := jsonutil.Marshal(r) assert.NoError(t, err, "unexpected req marshal error") resResp := Apply(rw, reqBytes, resp, params, bidResponseExt, nil) assert.Len(t, resResp.SeatBid, 2, "Incorrect response: seat bid number") diff --git a/adservertargeting/reqcache.go b/adservertargeting/reqcache.go index cb2edac9e4a..b8b147af84e 100644 --- a/adservertargeting/reqcache.go +++ b/adservertargeting/reqcache.go @@ -5,6 +5,7 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/util/jsonutil" ) type requestCache struct { @@ -24,7 +25,7 @@ func (reqImpCache *requestCache) GetImpsData() ([]json.RawMessage, error) { } var impsData []json.RawMessage - err = json.Unmarshal(imps, &impsData) + err = jsonutil.Unmarshal(imps, &impsData) if err != nil { return nil, err } @@ -48,7 +49,7 @@ func (bidsCache *bidsCache) GetBid(bidderName, bidId string, bid openrtb2.Bid) ( } _, bidExists := bidsCache.bids[bidderName][bidId] if !bidExists { - bidBytes, err := json.Marshal(bid) + bidBytes, err := jsonutil.Marshal(bid) if err != nil { return nil, err } diff --git a/adservertargeting/respdataprocessor.go b/adservertargeting/respdataprocessor.go index 94a391d08bb..649f802f6e2 100644 --- a/adservertargeting/respdataprocessor.go +++ b/adservertargeting/respdataprocessor.go @@ -8,6 +8,7 @@ import ( "github.com/pkg/errors" "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/jsonutil" jsonpatch "gopkg.in/evanphx/json-patch.v4" ) @@ -79,7 +80,7 @@ func buildBidExt(targetingData map[string]string, Targeting: targetingDataTruncated, }, } - bidExtTargeting, err := json.Marshal(bidExtTargetingData) + bidExtTargeting, err := jsonutil.Marshal(bidExtTargetingData) if err != nil { warnings = append(warnings, createWarning(err.Error())) return nil diff --git a/analytics/filesystem/file_module.go b/analytics/filesystem/file_module.go index f055e4470b1..24b7be6b599 100644 --- a/analytics/filesystem/file_module.go +++ b/analytics/filesystem/file_module.go @@ -2,12 +2,12 @@ package filesystem import ( "bytes" - "encoding/json" "fmt" "github.com/chasex/glog" "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/analytics" + "github.com/prebid/prebid-server/util/jsonutil" ) type RequestType string @@ -120,7 +120,7 @@ func jsonifyAuctionObject(ao *analytics.AuctionObject) string { } } - b, err := json.Marshal(&struct { + b, err := jsonutil.Marshal(&struct { Type RequestType `json:"type"` *logAuction }{ @@ -153,7 +153,7 @@ func jsonifyVideoObject(vo *analytics.VideoObject) string { } } - b, err := json.Marshal(&struct { + b, err := jsonutil.Marshal(&struct { Type RequestType `json:"type"` *logVideo }{ @@ -178,7 +178,7 @@ func jsonifyCookieSync(cso *analytics.CookieSyncObject) string { } } - b, err := json.Marshal(&struct { + b, err := jsonutil.Marshal(&struct { Type RequestType `json:"type"` *logUserSync }{ @@ -205,7 +205,7 @@ func jsonifySetUIDObject(so *analytics.SetUIDObject) string { } } - b, err := json.Marshal(&struct { + b, err := jsonutil.Marshal(&struct { Type RequestType `json:"type"` *logSetUID }{ @@ -239,7 +239,7 @@ func jsonifyAmpObject(ao *analytics.AmpObject) string { } } - b, err := json.Marshal(&struct { + b, err := jsonutil.Marshal(&struct { Type RequestType `json:"type"` *logAMP }{ @@ -263,7 +263,7 @@ func jsonifyNotificationEventObject(ne *analytics.NotificationEvent) string { } } - b, err := json.Marshal(&struct { + b, err := jsonutil.Marshal(&struct { Type RequestType `json:"type"` *logNotificationEvent }{ diff --git a/analytics/pubstack/helpers/json.go b/analytics/pubstack/helpers/json.go index 368c79e3f6a..f56a4c6194b 100644 --- a/analytics/pubstack/helpers/json.go +++ b/analytics/pubstack/helpers/json.go @@ -1,11 +1,11 @@ package helpers import ( - "encoding/json" "fmt" "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/analytics" + "github.com/prebid/prebid-server/util/jsonutil" ) func JsonifyAuctionObject(ao *analytics.AuctionObject, scope string) ([]byte, error) { @@ -26,7 +26,7 @@ func JsonifyAuctionObject(ao *analytics.AuctionObject, scope string) ([]byte, er } } - b, err := json.Marshal(&struct { + b, err := jsonutil.Marshal(&struct { Scope string `json:"scope"` *logAuction }{ @@ -59,7 +59,7 @@ func JsonifyVideoObject(vo *analytics.VideoObject, scope string) ([]byte, error) } } - b, err := json.Marshal(&struct { + b, err := jsonutil.Marshal(&struct { Scope string `json:"scope"` *logVideo }{ @@ -84,7 +84,7 @@ func JsonifyCookieSync(cso *analytics.CookieSyncObject, scope string) ([]byte, e } } - b, err := json.Marshal(&struct { + b, err := jsonutil.Marshal(&struct { Scope string `json:"scope"` *logUserSync }{ @@ -111,7 +111,7 @@ func JsonifySetUIDObject(so *analytics.SetUIDObject, scope string) ([]byte, erro } } - b, err := json.Marshal(&struct { + b, err := jsonutil.Marshal(&struct { Scope string `json:"scope"` *logSetUID }{ @@ -145,7 +145,7 @@ func JsonifyAmpObject(ao *analytics.AmpObject, scope string) ([]byte, error) { } } - b, err := json.Marshal(&struct { + b, err := jsonutil.Marshal(&struct { Scope string `json:"scope"` *logAMP }{ diff --git a/config/config.go b/config/config.go index cf3591dd564..4bd7f807002 100644 --- a/config/config.go +++ b/config/config.go @@ -14,6 +14,7 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/spf13/viper" ) @@ -775,7 +776,7 @@ func New(v *viper.Viper, bidderInfos BidderInfos, normalizeBidderName func(strin // MarshalAccountDefaults compiles AccountDefaults into the JSON format used for merge patch func (cfg *Configuration) MarshalAccountDefaults() error { var err error - if cfg.accountDefaultsJSON, err = json.Marshal(cfg.AccountDefaults); err != nil { + if cfg.accountDefaultsJSON, err = jsonutil.Marshal(cfg.AccountDefaults); err != nil { glog.Warningf("converting %+v to json: %v", cfg.AccountDefaults, err) } return err diff --git a/currency/rate_converter.go b/currency/rate_converter.go index f28807701ae..cda8d763048 100644 --- a/currency/rate_converter.go +++ b/currency/rate_converter.go @@ -1,7 +1,6 @@ package currency import ( - "encoding/json" "fmt" "io" "net/http" @@ -10,6 +9,7 @@ import ( "github.com/golang/glog" "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/util/timeutil" ) @@ -66,7 +66,7 @@ func (rc *RateConverter) fetch() (*Rates, error) { } updatedRates := &Rates{} - err = json.Unmarshal(bytesJSON, updatedRates) + err = jsonutil.UnmarshalValid(bytesJSON, updatedRates) if err != nil { return nil, err } diff --git a/currency/rates_test.go b/currency/rates_test.go index 23226dce8fb..86c25d14ac0 100644 --- a/currency/rates_test.go +++ b/currency/rates_test.go @@ -1,11 +1,12 @@ package currency import ( - "encoding/json" "errors" "testing" "github.com/stretchr/testify/assert" + + "github.com/prebid/prebid-server/util/jsonutil" ) func TestUnMarshallRates(t *testing.T) { @@ -22,7 +23,7 @@ func TestUnMarshallRates(t *testing.T) { ratesJSON: `malformed`, expectedRates: Rates{}, expectsError: true, - expectedError: errors.New("invalid character 'm' looking for beginning of value"), + expectedError: errors.New("expect { or n, but found m"), }, { desc: "Valid JSON field defining valid conversion object. Expect no error", @@ -50,7 +51,7 @@ func TestUnMarshallRates(t *testing.T) { expectedError: nil, }, { - desc: "Valid JSON field defines a conversions map with repeated entries, expect error", + desc: "Valid JSON field defines a conversions map with repeated entries, last one wins", ratesJSON: `{ "conversions":{ "USD":{ @@ -58,25 +59,31 @@ func TestUnMarshallRates(t *testing.T) { "MXN":20.00 }, "USD":{ - "GBP":0.7662523901 - }, + "GBP":0.4815162342 + } } }`, - expectedRates: Rates{}, - expectsError: true, - expectedError: errors.New("invalid character '}' looking for beginning of object key string"), + expectedRates: Rates{ + Conversions: map[string]map[string]float64{ + "USD": { + "GBP": 0.4815162342, + }, + }, + }, + expectsError: false, + expectedError: nil, }, } for _, tc := range testCases { // Execute: updatedRates := Rates{} - err := json.Unmarshal([]byte(tc.ratesJSON), &updatedRates) + err := jsonutil.UnmarshalValid([]byte(tc.ratesJSON), &updatedRates) // Verify: assert.Equal(t, err != nil, tc.expectsError, tc.desc) if tc.expectsError { - assert.Equal(t, err.Error(), tc.expectedError.Error(), tc.desc) + assert.Equal(t, tc.expectedError.Error(), err.Error(), tc.desc) } assert.Equal(t, tc.expectedRates, updatedRates, tc.desc) } diff --git a/endpoints/cookie_sync.go b/endpoints/cookie_sync.go index 24530efa56a..ff801de988f 100644 --- a/endpoints/cookie_sync.go +++ b/endpoints/cookie_sync.go @@ -27,6 +27,7 @@ import ( gppPrivacy "github.com/prebid/prebid-server/privacy/gpp" "github.com/prebid/prebid-server/stored_requests" "github.com/prebid/prebid-server/usersync" + "github.com/prebid/prebid-server/util/jsonutil" stringutil "github.com/prebid/prebid-server/util/stringutil" ) @@ -119,7 +120,7 @@ func (c *cookieSyncEndpoint) parseRequest(r *http.Request) (usersync.Request, ma } request := cookieSyncRequest{} - if err := json.Unmarshal(body, &request); err != nil { + if err := jsonutil.UnmarshalValid(body, &request); err != nil { return usersync.Request{}, macros.UserSyncPrivacy{}, fmt.Errorf("JSON parsing failed: %s", err.Error()) } diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go index af7819b94b9..1b02357dc5d 100644 --- a/endpoints/cookie_sync_test.go +++ b/endpoints/cookie_sync_test.go @@ -190,14 +190,14 @@ func TestCookieSyncHandle(t *testing.T) { SyncersChosen: []usersync.SyncerChoice{{Bidder: "a", Syncer: &syncer}}, }, expectedStatusCode: 400, - expectedBody: `JSON parsing failed: invalid character 'm' looking for beginning of value` + "\n", + expectedBody: `JSON parsing failed: expect { or n, but found m` + "\n", setMetricsExpectations: func(m *metrics.MetricsEngineMock) { m.On("RecordCookieSync", metrics.CookieSyncBadRequest).Once() }, setAnalyticsExpectations: func(a *MockAnalyticsRunner) { expected := analytics.CookieSyncObject{ Status: 400, - Errors: []error{errors.New("JSON parsing failed: invalid character 'm' looking for beginning of value")}, + Errors: []error{errors.New("JSON parsing failed: expect { or n, but found m")}, BidderStatus: []*analytics.CookieSyncBidder{}, } a.On("LogCookieSyncObject", &expected).Once() @@ -805,7 +805,7 @@ func TestCookieSyncParseRequest(t *testing.T) { givenBody: strings.NewReader(`malformed`), givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"}, givenCCPAEnabled: true, - expectedError: "JSON parsing failed: invalid character 'm' looking for beginning of value", + expectedError: "JSON parsing failed: expect { or n, but found m", }, { description: "Invalid Type Filter", diff --git a/endpoints/currency_rates.go b/endpoints/currency_rates.go index d35cb74cea4..49ae9963cd9 100644 --- a/endpoints/currency_rates.go +++ b/endpoints/currency_rates.go @@ -1,12 +1,12 @@ package endpoints import ( - "encoding/json" "net/http" "time" "github.com/golang/glog" "github.com/prebid/prebid-server/currency" + "github.com/prebid/prebid-server/util/jsonutil" ) // currencyRatesInfo holds currency rates information. @@ -60,7 +60,7 @@ func NewCurrencyRatesEndpoint(rateConverter rateConverter, fetchingInterval time currencyRateInfo := newCurrencyRatesInfo(rateConverter, fetchingInterval) return func(w http.ResponseWriter, _ *http.Request) { - jsonOutput, err := json.Marshal(currencyRateInfo) + jsonOutput, err := jsonutil.Marshal(currencyRateInfo) if err != nil { glog.Errorf("/currency/rates Critical error when trying to marshal currencyRateInfo: %v", err) w.WriteHeader(http.StatusInternalServerError) diff --git a/endpoints/events/vtrack.go b/endpoints/events/vtrack.go index e0bf3fd4be8..eeb409e24ae 100644 --- a/endpoints/events/vtrack.go +++ b/endpoints/events/vtrack.go @@ -19,6 +19,7 @@ import ( "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/prebid_cache_client" "github.com/prebid/prebid-server/stored_requests" + "github.com/prebid/prebid-server/util/jsonutil" ) const ( @@ -123,7 +124,7 @@ func (v *vtrackEndpoint) Handle(w http.ResponseWriter, r *http.Request, _ httpro } } - d, err := json.Marshal(*cachingResponse) + d, err := jsonutil.Marshal(*cachingResponse) if err != nil { w.WriteHeader(http.StatusInternalServerError) @@ -187,7 +188,7 @@ func ParseVTrackRequest(httpRequest *http.Request, maxRequestSize int64) (req *B return req, err } - if err := json.Unmarshal(requestJson, req); err != nil { + if err := jsonutil.UnmarshalValid(requestJson, req); err != nil { return req, err } @@ -319,7 +320,7 @@ func ModifyVastXmlString(externalUrl, vast, bidid, bidder, accountID string, tim // ModifyVastXmlJSON modifies BidCacheRequest element Vast XML data func ModifyVastXmlJSON(externalUrl string, data json.RawMessage, bidid, bidder, accountId string, timestamp int64, integrationType string) json.RawMessage { var vast string - if err := json.Unmarshal(data, &vast); err != nil { + if err := jsonutil.Unmarshal(data, &vast); err != nil { // failed to decode json, fall back to string vast = string(data) } diff --git a/endpoints/events/vtrack_test.go b/endpoints/events/vtrack_test.go index 1e36a9e627f..d950a443afe 100644 --- a/endpoints/events/vtrack_test.go +++ b/endpoints/events/vtrack_test.go @@ -16,6 +16,7 @@ import ( "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/prebid_cache_client" "github.com/prebid/prebid-server/stored_requests" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/stretchr/testify/assert" ) @@ -186,7 +187,7 @@ func TestShouldRespondWithBadRequestWhenBidIdIsMissing(t *testing.T) { }, } - reqData, err := json.Marshal(data) + reqData, err := jsonutil.Marshal(data) if err != nil { t.Fatal(err) } @@ -239,7 +240,7 @@ func TestShouldRespondWithBadRequestWhenBidderIsMissing(t *testing.T) { }, } - reqData, err := json.Marshal(data) + reqData, err := jsonutil.Marshal(data) if err != nil { t.Fatal(err) } diff --git a/endpoints/info/bidders.go b/endpoints/info/bidders.go index 9984abe216d..bd6d078b3ba 100644 --- a/endpoints/info/bidders.go +++ b/endpoints/info/bidders.go @@ -1,7 +1,6 @@ package info import ( - "encoding/json" "net/http" "sort" "strings" @@ -9,6 +8,7 @@ import ( "github.com/golang/glog" "github.com/julienschmidt/httprouter" "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/util/jsonutil" ) var invalidEnabledOnlyMsg = []byte(`Invalid value for 'enabledonly' query param, must be of boolean type`) @@ -103,7 +103,7 @@ func prepareBiddersResponseAll(bidders config.BidderInfos, aliases map[string]st } sort.Strings(bidderNames) - return json.Marshal(bidderNames) + return jsonutil.Marshal(bidderNames) } func prepareBiddersResponseAllBaseOnly(bidders config.BidderInfos) ([]byte, error) { @@ -116,7 +116,7 @@ func prepareBiddersResponseAllBaseOnly(bidders config.BidderInfos) ([]byte, erro } sort.Strings(bidderNames) - return json.Marshal(bidderNames) + return jsonutil.Marshal(bidderNames) } func prepareBiddersResponseEnabledOnly(bidders config.BidderInfos, aliases map[string]string) ([]byte, error) { @@ -135,8 +135,7 @@ func prepareBiddersResponseEnabledOnly(bidders config.BidderInfos, aliases map[s } sort.Strings(bidderNames) - - return json.Marshal(bidderNames) + return jsonutil.Marshal(bidderNames) } func prepareBiddersResponseEnabledOnlyBaseOnly(bidders config.BidderInfos) ([]byte, error) { @@ -149,7 +148,7 @@ func prepareBiddersResponseEnabledOnlyBaseOnly(bidders config.BidderInfos) ([]by } sort.Strings(bidderNames) - return json.Marshal(bidderNames) + return jsonutil.Marshal(bidderNames) } func writeBadRequest(w http.ResponseWriter, data []byte) { diff --git a/endpoints/info/bidders_detail.go b/endpoints/info/bidders_detail.go index d9dc776f50d..34d14efde1b 100644 --- a/endpoints/info/bidders_detail.go +++ b/endpoints/info/bidders_detail.go @@ -10,6 +10,7 @@ import ( "github.com/julienschmidt/httprouter" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/jsonutil" ) const ( @@ -101,7 +102,7 @@ func marshalDetailsResponse(details map[string]bidderDetail) (map[string][]byte, responses := map[string][]byte{} for bidder, detail := range details { - json, err := json.Marshal(detail) + json, err := jsonutil.Marshal(detail) if err != nil { return nil, fmt.Errorf("unable to marshal info for bidder %s: %v", bidder, err) } @@ -118,7 +119,7 @@ func marshalAllResponse(responses map[string][]byte) ([]byte, error) { responsesJSON[k] = json.RawMessage(v) } - json, err := json.Marshal(responsesJSON) + json, err := jsonutil.Marshal(responsesJSON) if err != nil { return nil, fmt.Errorf("unable to marshal info for bidder all: %v", err) } diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index 2fde59c25e4..76b0e83cf3d 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -37,6 +37,7 @@ import ( "github.com/prebid/prebid-server/stored_responses" "github.com/prebid/prebid-server/usersync" "github.com/prebid/prebid-server/util/iputil" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/version" ) @@ -341,7 +342,7 @@ func sendAmpResponse( // but this is a very unlikely corner case. Doing this so we can catch "hb_cache_id" // and "hb_cache_id_{deal}", which allows for deal support in AMP. bidExt := &openrtb_ext.ExtBid{} - err := json.Unmarshal(bid.Ext, bidExt) + err := jsonutil.Unmarshal(bid.Ext, bidExt) if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, "Critical error while unpacking AMP targets: %v", err) @@ -360,7 +361,7 @@ func sendAmpResponse( // Extract global targeting var extResponse openrtb_ext.ExtBidResponse - eRErr := json.Unmarshal(response.Ext, &extResponse) + eRErr := jsonutil.Unmarshal(response.Ext, &extResponse) if eRErr != nil { ao.Errors = append(ao.Errors, fmt.Errorf("AMP response: failed to unpack OpenRTB response.ext, debug info cannot be forwarded: %v", eRErr)) } @@ -409,7 +410,7 @@ func getExtBidResponse( } // Extract any errors var extResponse openrtb_ext.ExtBidResponse - eRErr := json.Unmarshal(response.Ext, &extResponse) + eRErr := jsonutil.Unmarshal(response.Ext, &extResponse) if eRErr != nil { ao.Errors = append(ao.Errors, fmt.Errorf("AMP response: failed to unpack OpenRTB response.ext, debug info cannot be forwarded: %v", eRErr)) } @@ -524,7 +525,7 @@ func (deps *endpointDeps) loadRequestJSONForAmp(httpRequest *http.Request) (req // The fetched config becomes the entire OpenRTB request requestJSON := storedRequests[ampParams.StoredRequestID] - if err := json.Unmarshal(requestJSON, req); err != nil { + if err := jsonutil.UnmarshalValid(requestJSON, req); err != nil { errs = []error{err} return } @@ -824,7 +825,7 @@ func setTrace(req *openrtb2.BidRequest, value string) error { return nil } - ext, err := json.Marshal(map[string]map[string]string{"prebid": {"trace": value}}) + ext, err := jsonutil.Marshal(map[string]map[string]string{"prebid": {"trace": value}}) if err != nil { return err } diff --git a/endpoints/openrtb2/amp_auction_test.go b/endpoints/openrtb2/amp_auction_test.go index 4315ec7926f..7de8995754a 100644 --- a/endpoints/openrtb2/amp_auction_test.go +++ b/endpoints/openrtb2/amp_auction_test.go @@ -32,6 +32,7 @@ import ( "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/privacy" "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/util/jsonutil" ) // TestGoodRequests makes sure that the auction runs properly-formatted stored bids correctly. @@ -77,7 +78,7 @@ func TestGoodAmpRequests(t *testing.T) { } test := testCase{} - if !assert.NoError(t, json.Unmarshal(fileJsonData, &test), "Failed to unmarshal data from file: %s. Error: %v", filename, err) { + if !assert.NoError(t, jsonutil.UnmarshalValid(fileJsonData, &test), "Failed to unmarshal data from file: %s. Error: %v", filename, err) { continue } @@ -130,7 +131,7 @@ func TestGoodAmpRequests(t *testing.T) { } if test.ExpectedValidatedBidReq != nil { // compare as json to ignore whitespace and ext field ordering - actualJson, err := json.Marshal(ex.actualValidatedBidReq) + actualJson, err := jsonutil.Marshal(ex.actualValidatedBidReq) if assert.NoError(t, err, "Error converting actual bid request to json. Test file: %s", filename) { assert.JSONEq(t, string(test.ExpectedValidatedBidReq), string(actualJson), "Not the expected validated request. Test file: %s", filename) } @@ -159,7 +160,7 @@ func TestAccountErrors(t *testing.T) { } test := testCase{} - if !assert.NoError(t, json.Unmarshal(fileJsonData, &test), "Failed to unmarshal data from file: %s. Error: %v", tt.filename, err) { + if !assert.NoError(t, jsonutil.UnmarshalValid(fileJsonData, &test), "Failed to unmarshal data from file: %s. Error: %v", tt.filename, err) { continue } test.StoredRequest = map[string]json.RawMessage{tt.storedReqID: test.BidRequest} @@ -325,7 +326,7 @@ func TestGDPRConsent(t *testing.T) { // Parse Response var response AmpResponse - if err := json.Unmarshal(responseRecorder.Body.Bytes(), &response); err != nil { + if err := jsonutil.UnmarshalValid(responseRecorder.Body.Bytes(), &response); err != nil { t.Fatalf("Error unmarshalling response: %s", err.Error()) } @@ -341,7 +342,7 @@ func TestGDPRConsent(t *testing.T) { return } var ue openrtb_ext.ExtUser - err = json.Unmarshal(result.User.Ext, &ue) + err = jsonutil.UnmarshalValid(result.User.Ext, &ue) if !assert.NoError(t, err, test.description+":deserialize") { return } @@ -356,7 +357,7 @@ func TestGDPRConsent(t *testing.T) { // Parse Resonse var responseLegacy AmpResponse - if err := json.Unmarshal(responseRecorderLegacy.Body.Bytes(), &responseLegacy); err != nil { + if err := jsonutil.UnmarshalValid(responseRecorderLegacy.Body.Bytes(), &responseLegacy); err != nil { t.Fatalf("Error unmarshalling response: %s", err.Error()) } @@ -372,7 +373,7 @@ func TestGDPRConsent(t *testing.T) { return } var ueLegacy openrtb_ext.ExtUser - err = json.Unmarshal(resultLegacy.User.Ext, &ueLegacy) + err = jsonutil.UnmarshalValid(resultLegacy.User.Ext, &ueLegacy) if !assert.NoError(t, err, test.description+":legacy:deserialize") { return } @@ -519,7 +520,7 @@ func TestOverrideWithParams(t *testing.T) { Site: &openrtb2.Site{Ext: json.RawMessage(`{"amp":1}`)}, User: &openrtb2.User{Ext: json.RawMessage(`malformed`)}, }, - errorMsgs: []string{"invalid character 'm' looking for beginning of value"}, + errorMsgs: []string{"expect { or n, but found m"}, expectFatalErrors: true, }, }, @@ -567,7 +568,7 @@ func TestOverrideWithParams(t *testing.T) { User: &openrtb2.User{Ext: json.RawMessage(`{"prebid":{malformed}}`)}, Site: &openrtb2.Site{Ext: json.RawMessage(`{"amp":1}`)}, }, - errorMsgs: []string{"invalid character 'm' looking for beginning of object key string"}, + errorMsgs: []string{"expect \" after {, but found m"}, expectFatalErrors: true, }, }, @@ -749,7 +750,7 @@ func TestCCPAConsent(t *testing.T) { // Parse Response var response AmpResponse - if err := json.Unmarshal(responseRecorder.Body.Bytes(), &response); err != nil { + if err := jsonutil.UnmarshalValid(responseRecorder.Body.Bytes(), &response); err != nil { t.Fatalf("Error unmarshalling response: %s", err.Error()) } @@ -765,7 +766,7 @@ func TestCCPAConsent(t *testing.T) { return } var re openrtb_ext.ExtRegs - err = json.Unmarshal(result.Regs.Ext, &re) + err = jsonutil.UnmarshalValid(result.Regs.Ext, &re) if !assert.NoError(t, err, test.description+":deserialize") { return } @@ -871,7 +872,7 @@ func TestConsentWarnings(t *testing.T) { // Parse Response var response AmpResponse - if err := json.Unmarshal(responseRecorder.Body.Bytes(), &response); err != nil { + if err := jsonutil.UnmarshalValid(responseRecorder.Body.Bytes(), &response); err != nil { t.Fatalf("Error unmarshalling response: %s", err.Error()) } @@ -962,7 +963,7 @@ func TestNewAndLegacyConsentBothProvided(t *testing.T) { // Parse Response var response AmpResponse - if err := json.Unmarshal(responseRecorder.Body.Bytes(), &response); err != nil { + if err := jsonutil.UnmarshalValid(responseRecorder.Body.Bytes(), &response); err != nil { t.Fatalf("Error unmarshalling response: %s", err.Error()) } @@ -978,7 +979,7 @@ func TestNewAndLegacyConsentBothProvided(t *testing.T) { return } var ue openrtb_ext.ExtUser - err = json.Unmarshal(result.User.Ext, &ue) + err = jsonutil.UnmarshalValid(result.User.Ext, &ue) if !assert.NoError(t, err, test.description+":deserialize") { return } @@ -1099,7 +1100,7 @@ func TestAmpDebug(t *testing.T) { } var response AmpResponse - if err := json.Unmarshal(recorder.Body.Bytes(), &response); err != nil { + if err := jsonutil.UnmarshalValid(recorder.Body.Bytes(), &response); err != nil { t.Fatalf("Error unmarshalling response: %s", err.Error()) } @@ -1134,7 +1135,7 @@ func TestInitAmpTargetingAndCache(t *testing.T) { { name: "malformed", request: &openrtb2.BidRequest{Ext: json.RawMessage("malformed")}, - expectedErrs: []string{"invalid character 'm' looking for beginning of value"}, + expectedErrs: []string{"expect { or n, but found m"}, }, { name: "nil", @@ -1240,12 +1241,12 @@ func TestQueryParamOverrides(t *testing.T) { } var response AmpResponse - if err := json.Unmarshal(recorder.Body.Bytes(), &response); err != nil { + if err := jsonutil.UnmarshalValid(recorder.Body.Bytes(), &response); err != nil { t.Fatalf("Error unmarshalling response: %s", err.Error()) } var resolvedRequest openrtb2.BidRequest - err := json.Unmarshal(response.ORTB2.Ext.Debug.ResolvedRequest, &resolvedRequest) + err := jsonutil.UnmarshalValid(response.ORTB2.Ext.Debug.ResolvedRequest, &resolvedRequest) assert.NoError(t, err, "resolved request should have a correct format") if resolvedRequest.TMax != timeout { t.Errorf("Expected TMax to equal timeout (%d), got: %d", timeout, resolvedRequest.TMax) @@ -1391,11 +1392,11 @@ func (s formatOverrideSpec) execute(t *testing.T) { t.Errorf("Request was: %s", string(requests["1"])) } var response AmpResponse - if err := json.Unmarshal(recorder.Body.Bytes(), &response); err != nil { + if err := jsonutil.UnmarshalValid(recorder.Body.Bytes(), &response); err != nil { t.Fatalf("Error unmarshalling response: %s", err.Error()) } var resolvedRequest openrtb2.BidRequest - err := json.Unmarshal(response.ORTB2.Ext.Debug.ResolvedRequest, &resolvedRequest) + err := jsonutil.UnmarshalValid(response.ORTB2.Ext.Debug.ResolvedRequest, &resolvedRequest) assert.NoError(t, err, "resolved request should have the correct format") formats := resolvedRequest.Imp[0].Banner.Format if len(formats) != len(s.expect) { @@ -1445,14 +1446,14 @@ func (m *mockAmpExchange) HoldAuction(ctx context.Context, auctionRequest *excha if len(auctionRequest.StoredAuctionResponses) > 0 { var seatBids []openrtb2.SeatBid - if err := json.Unmarshal(auctionRequest.StoredAuctionResponses[r.BidRequest.Imp[0].ID], &seatBids); err != nil { + if err := jsonutil.UnmarshalValid(auctionRequest.StoredAuctionResponses[r.BidRequest.Imp[0].ID], &seatBids); err != nil { return nil, err } response.SeatBid = seatBids } if r.BidRequest.Test == 1 { - resolvedRequest, err := json.Marshal(r.BidRequest) + resolvedRequest, err := jsonutil.Marshal(r.BidRequest) if err != nil { resolvedRequest = json.RawMessage("{}") } @@ -1511,7 +1512,7 @@ func getTestBidRequest(nilUser bool, userExt *openrtb_ext.ExtUser, nilRegs bool, var userExtData []byte if userExt != nil { var err error - userExtData, err = json.Marshal(userExt) + userExtData, err = jsonutil.Marshal(userExt) if err != nil { return nil, err } @@ -1528,7 +1529,7 @@ func getTestBidRequest(nilUser bool, userExt *openrtb_ext.ExtUser, nilRegs bool, var regsExtData []byte if regsExt != nil { var err error - regsExtData, err = json.Marshal(regsExt) + regsExtData, err = jsonutil.Marshal(regsExt) if err != nil { return nil, err } @@ -1540,7 +1541,7 @@ func getTestBidRequest(nilUser bool, userExt *openrtb_ext.ExtUser, nilRegs bool, Ext: regsExtData, } } - return json.Marshal(bidRequest) + return jsonutil.Marshal(bidRequest) } func TestSetEffectiveAmpPubID(t *testing.T) { @@ -2191,7 +2192,7 @@ func TestValidAmpResponseWhenRequestRejected(t *testing.T) { assert.NoError(t, err, "Failed to read test file.") test := testCase{} - assert.NoError(t, json.Unmarshal(fileData, &test), "Failed to parse test file.") + assert.NoError(t, jsonutil.UnmarshalValid(fileData, &test), "Failed to parse test file.") request := httptest.NewRequest("GET", fmt.Sprintf("/openrtb2/auction/amp?%s", test.Query), nil) recorder := httptest.NewRecorder() @@ -2211,8 +2212,8 @@ func TestValidAmpResponseWhenRequestRejected(t *testing.T) { var actualAmpResp AmpResponse var expectedAmpResp AmpResponse - assert.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &actualAmpResp), "Unable to unmarshal actual AmpResponse.") - assert.NoError(t, json.Unmarshal(test.ExpectedAmpResponse, &expectedAmpResp), "Unable to unmarshal expected AmpResponse.") + assert.NoError(t, jsonutil.UnmarshalValid(recorder.Body.Bytes(), &actualAmpResp), "Unable to unmarshal actual AmpResponse.") + assert.NoError(t, jsonutil.UnmarshalValid(test.ExpectedAmpResponse, &expectedAmpResp), "Unable to unmarshal expected AmpResponse.") // validate modules data separately, because it has dynamic data if expectedAmpResp.ORTB2.Ext.Prebid == nil { @@ -2248,7 +2249,7 @@ func TestSendAmpResponse_LogsErrors(t *testing.T) { { description: "Error logged when bid.ext unmarshal fails", expectedErrors: []error{ - errors.New("Critical error while unpacking AMP targets: unexpected end of JSON input"), + errors.New("Critical error while unpacking AMP targets: expect { or n, but found \""), }, expectedStatus: http.StatusInternalServerError, writer: httptest.NewRecorder(), @@ -2325,7 +2326,7 @@ func TestSendAmpResponse_LogsErrors(t *testing.T) { _, ao = sendAmpResponse(test.writer, test.hookExecutor, &exchange.AuctionResponse{BidResponse: test.response}, &reqWrapper, account, labels, ao, nil) - assert.Equal(t, ao.Errors, test.expectedErrors, "Invalid errors.") + assert.Equal(t, test.expectedErrors, ao.Errors, "Invalid errors.") assert.Equal(t, test.expectedStatus, ao.Status, "Invalid HTTP response status.") }) } diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 0e1a23583a1..2cad7a2463a 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -52,6 +52,7 @@ import ( "github.com/prebid/prebid-server/usersync" "github.com/prebid/prebid-server/util/httputil" "github.com/prebid/prebid-server/util/iputil" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/util/uuidutil" "github.com/prebid/prebid-server/version" ) @@ -308,11 +309,11 @@ func setSeatNonBidRaw(request *openrtb_ext.RequestWrapper, auctionResponse *exch // by HoldAuction response := auctionResponse.BidResponse respExt := &openrtb_ext.ExtBidResponse{} - if err := json.Unmarshal(response.Ext, &respExt); err != nil { + if err := jsonutil.Unmarshal(response.Ext, &respExt); err != nil { return err } if setSeatNonBid(respExt, request, auctionResponse) { - if respExtJson, err := json.Marshal(respExt); err == nil { + if respExtJson, err := jsonutil.Marshal(respExt); err == nil { response.Ext = respExtJson return nil } else { @@ -445,7 +446,7 @@ func (deps *endpointDeps) parseRequest(httpRequest *http.Request, labels *metric requestJson, rejectErr := hookExecutor.ExecuteEntrypointStage(httpRequest, requestJson) if rejectErr != nil { errs = []error{rejectErr} - if err = json.Unmarshal(requestJson, req.BidRequest); err != nil { + if err = jsonutil.UnmarshalValid(requestJson, req.BidRequest); err != nil { glog.Errorf("Failed to unmarshal BidRequest during entrypoint rejection: %s", err) } return @@ -493,7 +494,7 @@ func (deps *endpointDeps) parseRequest(httpRequest *http.Request, labels *metric requestJson, rejectErr = hookExecutor.ExecuteRawAuctionStage(requestJson) if rejectErr != nil { errs = []error{rejectErr} - if err = json.Unmarshal(requestJson, req.BidRequest); err != nil { + if err = jsonutil.UnmarshalValid(requestJson, req.BidRequest); err != nil { glog.Errorf("Failed to unmarshal BidRequest during raw auction stage rejection: %s", err) } return @@ -522,7 +523,7 @@ func (deps *endpointDeps) parseRequest(httpRequest *http.Request, labels *metric return nil, nil, nil, nil, nil, nil, errs } - if err := json.Unmarshal(requestJson, req.BidRequest); err != nil { + if err := jsonutil.UnmarshalValid(requestJson, req.BidRequest); err != nil { errs = []error{err} return } @@ -621,7 +622,7 @@ func mergeBidderParams(req *openrtb_ext.RequestWrapper) error { } bidderParams := map[string]map[string]json.RawMessage{} - if err := json.Unmarshal(bidderParamsJson, &bidderParams); err != nil { + if err := jsonutil.Unmarshal(bidderParamsJson, &bidderParams); err != nil { return nil } @@ -664,7 +665,7 @@ func mergeBidderParamsImpExt(impExt *openrtb_ext.ImpExt, reqExtParams map[string impExtBidderMap := map[string]json.RawMessage{} if len(impExtBidder) > 0 { - if err := json.Unmarshal(impExtBidder, &impExtBidderMap); err != nil { + if err := jsonutil.Unmarshal(impExtBidder, &impExtBidderMap); err != nil { continue } } @@ -678,7 +679,7 @@ func mergeBidderParamsImpExt(impExt *openrtb_ext.ImpExt, reqExtParams map[string } if modified { - impExtBidderJson, err := json.Marshal(impExtBidderMap) + impExtBidderJson, err := jsonutil.Marshal(impExtBidderMap) if err != nil { return fmt.Errorf("error marshalling ext.BIDDER: %s", err.Error()) } @@ -712,7 +713,7 @@ func mergeBidderParamsImpExtPrebid(impExt *openrtb_ext.ImpExt, reqExtParams map[ impExtPrebidBidderMap := map[string]json.RawMessage{} if len(impExtPrebidBidder) > 0 { - if err := json.Unmarshal(impExtPrebidBidder, &impExtPrebidBidderMap); err != nil { + if err := jsonutil.Unmarshal(impExtPrebidBidder, &impExtPrebidBidderMap); err != nil { continue } } @@ -726,7 +727,7 @@ func mergeBidderParamsImpExtPrebid(impExt *openrtb_ext.ImpExt, reqExtParams map[ } if modified { - impExtPrebidBidderJson, err := json.Marshal(impExtPrebidBidderMap) + impExtPrebidBidderJson, err := jsonutil.Marshal(impExtPrebidBidderMap) if err != nil { return fmt.Errorf("error marshalling ext.prebid.bidder.BIDDER: %s", err.Error()) } @@ -1195,7 +1196,7 @@ func fillAndValidateNative(n *openrtb2.Native, impIndex int) error { return fmt.Errorf("request.imp[%d].native missing required property \"request\"", impIndex) } var nativePayload nativeRequests.Request - if err := json.Unmarshal(json.RawMessage(n.Request), &nativePayload); err != nil { + if err := jsonutil.UnmarshalValid(json.RawMessage(n.Request), &nativePayload); err != nil { return err } @@ -1212,7 +1213,7 @@ func fillAndValidateNative(n *openrtb2.Native, impIndex int) error { return err } - serialized, err := json.Marshal(nativePayload) + serialized, err := jsonutil.Marshal(nativePayload) if err != nil { return err } @@ -2086,7 +2087,7 @@ func getJsonSyntaxError(testJSON []byte) (bool, string) { } type jNode map[string]*JsonNode docErrdoc := &jNode{} - docErr := json.Unmarshal(testJSON, docErrdoc) + docErr := jsonutil.UnmarshalValid(testJSON, docErrdoc) if uerror, ok := docErr.(*json.SyntaxError); ok { err := fmt.Sprintf("%s at offset %v", uerror.Error(), uerror.Offset) return true, err @@ -2235,7 +2236,7 @@ func (deps *endpointDeps) processStoredRequests(requestJson []byte, impInfo []Im } } if len(resolvedImps) > 0 { - newImpJson, err := json.Marshal(resolvedImps) + newImpJson, err := jsonutil.Marshal(resolvedImps) if err != nil { return nil, nil, []error{err} } @@ -2255,7 +2256,7 @@ func parseImpInfo(requestJson []byte) (impData []ImpExtPrebidData, errs []error) impExtData, _, _, err := jsonparser.Get(imp, "ext", "prebid") var impExtPrebid openrtb_ext.ExtImpPrebid if impExtData != nil { - if err := json.Unmarshal(impExtData, &impExtPrebid); err != nil { + if err := jsonutil.Unmarshal(impExtData, &impExtPrebid); err != nil { errs = append(errs, err) } } @@ -2384,7 +2385,7 @@ func getAccountID(pub *openrtb2.Publisher) string { if pub != nil { if pub.Ext != nil { var pubExt openrtb_ext.ExtPublisher - err := json.Unmarshal(pub.Ext, &pubExt) + err := jsonutil.Unmarshal(pub.Ext, &pubExt) if err == nil && pubExt.Prebid != nil && pubExt.Prebid.ParentAccount != nil && *pubExt.Prebid.ParentAccount != "" { return *pubExt.Prebid.ParentAccount } diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index 8204a80e3db..530d197e2ae 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -36,6 +36,7 @@ import ( "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" "github.com/prebid/prebid-server/stored_responses" "github.com/prebid/prebid-server/util/iputil" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/util/ptrutil" "github.com/stretchr/testify/assert" ) @@ -192,7 +193,7 @@ func runEndToEndTest(t *testing.T, auctionEndpointHandler httprouter.Handle, tes // Either assert bid response or expected error if len(test.ExpectedErrorMessage) > 0 { - assert.True(t, strings.HasPrefix(actualJsonBidResponse, test.ExpectedErrorMessage), "Actual: %s \nExpected: %s. Filename: %s \n", actualJsonBidResponse, test.ExpectedErrorMessage, testFile) + assert.Contains(t, actualJsonBidResponse, test.ExpectedErrorMessage, "Actual: %s \nExpected: %s. Filename: %s \n", actualJsonBidResponse, test.ExpectedErrorMessage, testFile) } if len(test.ExpectedBidResponse) > 0 { @@ -200,9 +201,9 @@ func runEndToEndTest(t *testing.T, auctionEndpointHandler httprouter.Handle, tes var actualBidResponse openrtb2.BidResponse var err error - err = json.Unmarshal(test.ExpectedBidResponse, &expectedBidResponse) + err = jsonutil.Unmarshal(test.ExpectedBidResponse, &expectedBidResponse) if assert.NoError(t, err, "Could not unmarshal expected bidResponse taken from test file.\n Test file: %s\n Error:%s\n", testFile, err) { - err = json.Unmarshal([]byte(actualJsonBidResponse), &actualBidResponse) + err = jsonutil.UnmarshalValid([]byte(actualJsonBidResponse), &actualBidResponse) if assert.NoError(t, err, "Could not unmarshal actual bidResponse from auction.\n Test file: %s\n Error:%s\n actualJsonBidResponse: %s", testFile, err, actualJsonBidResponse) { assertBidResponseEqual(t, testFile, expectedBidResponse, actualBidResponse) } @@ -222,13 +223,13 @@ func compareWarnings(t *testing.T, expectedBidResponseExt, actualBidResponseExt } var expectedWarn []openrtb_ext.ExtBidderMessage - err = json.Unmarshal(expectedWarnings, &expectedWarn) + err = jsonutil.UnmarshalValid(expectedWarnings, &expectedWarn) if err != nil { assert.Fail(t, "error unmarshalling expected warnings data from response extension") } var actualWarn []openrtb_ext.ExtBidderMessage - err = json.Unmarshal(actualWarnings, &actualWarn) + err = jsonutil.UnmarshalValid(actualWarnings, &actualWarn) if err != nil { assert.Fail(t, "error unmarshalling actual warnings data from response extension") } @@ -476,8 +477,8 @@ func TestExplicitUserId(t *testing.T) { // processes aliases before it processes stored imps. Changing that order // would probably cause this test to fail. func TestBadAliasRequests(t *testing.T) { - doBadAliasRequest(t, "sample-requests/invalid-stored/bad_stored_imp.json", "Invalid request: Invalid JSON in Default Request Settings: invalid character '\"' after object key:value pair at offset 51\n") - doBadAliasRequest(t, "sample-requests/invalid-stored/bad_incoming_imp.json", "Invalid request: Invalid JSON in Incoming Request: invalid character '\"' after object key:value pair at offset 230\n") + doBadAliasRequest(t, "sample-requests/invalid-stored/bad_stored_imp.json", "Invalid request: Invalid JSON Document\n") + doBadAliasRequest(t, "sample-requests/invalid-stored/bad_incoming_imp.json", "Invalid request: Invalid JSON Document\n") } // doBadAliasRequest() is a customized variation of doRequest(), above @@ -1907,7 +1908,7 @@ func TestValidateRequestExt(t *testing.T) { { description: "prebid cache - bids - wrong type", givenRequestExt: json.RawMessage(`{"prebid":{"cache":{"bids":true}}}`), - expectedErrors: []string{`json: cannot unmarshal bool into Go struct field ExtRequestPrebidCache.cache.bids of type openrtb_ext.ExtRequestPrebidCacheBids`}, + expectedErrors: []string{"cannot unmarshal openrtb_ext.ExtRequestPrebidCache.Bids: expect { or n, but found t"}, }, { description: "prebid cache - bids - provided", @@ -1921,7 +1922,7 @@ func TestValidateRequestExt(t *testing.T) { { description: "prebid cache - vastxml - wrong type", givenRequestExt: json.RawMessage(`{"prebid":{"cache":{"vastxml":true}}}`), - expectedErrors: []string{`json: cannot unmarshal bool into Go struct field ExtRequestPrebidCache.cache.vastxml of type openrtb_ext.ExtRequestPrebidCacheVAST`}, + expectedErrors: []string{"cannot unmarshal openrtb_ext.ExtRequestPrebidCache.VastXML: expect { or n, but found t"}, }, { description: "prebid cache - vastxml - provided", @@ -2555,7 +2556,7 @@ func TestStoredRequestGenerateUuid(t *testing.T) { newRequest, _, errList := deps.processStoredRequests(json.RawMessage(test.givenRawData), impInfo, storedRequests, storedImps, storedBidRequestId, hasStoredBidRequest) assert.Empty(t, errList, test.description) - if err := json.Unmarshal(newRequest, req); err != nil { + if err := jsonutil.UnmarshalValid(newRequest, req); err != nil { t.Errorf("processStoredRequests Error: %s", err.Error()) } if test.expectedCur != "" { @@ -3464,7 +3465,7 @@ func TestGetAccountID(t *testing.T) { ParentAccount: &testParentAccount, }, } - testPubExtJSON, err := json.Marshal(testPubExt) + testPubExtJSON, err := jsonutil.Marshal(testPubExt) assert.NoError(t, err) testCases := []struct { @@ -4196,7 +4197,7 @@ func TestParseRequestParseImpInfoError(t *testing.T) { assert.Nil(t, resReq, "Result request should be nil due to incorrect imp") assert.Nil(t, impExtInfoMap, "Impression info map should be nil due to incorrect imp") assert.Len(t, errL, 1, "One error should be returned") - assert.Contains(t, errL[0].Error(), "echovideoattrs of type bool", "Incorrect error message") + assert.Contains(t, errL[0].Error(), "cannot unmarshal openrtb_ext.Options.EchoVideoAttrs", "Incorrect error message") } func TestParseGzipedRequest(t *testing.T) { @@ -4878,20 +4879,20 @@ func TestParseRequestMergeBidderParams(t *testing.T) { assert.NoError(t, resReq.RebuildRequest()) var expIExt, iExt map[string]interface{} - err := json.Unmarshal(test.expectedImpExt, &expIExt) + err := jsonutil.UnmarshalValid(test.expectedImpExt, &expIExt) assert.Nil(t, err, "unmarshal() should return nil error") assert.NotNil(t, resReq.BidRequest.Imp[0].Ext, "imp[0].Ext should not be nil") - err = json.Unmarshal(resReq.BidRequest.Imp[0].Ext, &iExt) + err = jsonutil.UnmarshalValid(resReq.BidRequest.Imp[0].Ext, &iExt) assert.Nil(t, err, "unmarshal() should return nil error") assert.Equal(t, expIExt, iExt, "bidderparams in imp[].Ext should match") var eReqE, reqE map[string]interface{} - err = json.Unmarshal(test.expectedReqExt, &eReqE) + err = jsonutil.UnmarshalValid(test.expectedReqExt, &eReqE) assert.Nil(t, err, "unmarshal() should return nil error") - err = json.Unmarshal(resReq.BidRequest.Ext, &reqE) + err = jsonutil.UnmarshalValid(resReq.BidRequest.Ext, &reqE) assert.Nil(t, err, "unmarshal() should return nil error") assert.Equal(t, eReqE, reqE, "req.Ext should match") @@ -5753,11 +5754,11 @@ func TestValidResponseAfterExecutingStages(t *testing.T) { var actualExt openrtb_ext.ExtBidResponse var expectedExt openrtb_ext.ExtBidResponse - assert.NoError(t, json.Unmarshal(test.ExpectedBidResponse, &expectedResp), "Unable to unmarshal expected BidResponse.") - assert.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &actualResp), "Unable to unmarshal actual BidResponse.") + assert.NoError(t, jsonutil.UnmarshalValid(test.ExpectedBidResponse, &expectedResp), "Unable to unmarshal expected BidResponse.") + assert.NoError(t, jsonutil.UnmarshalValid(recorder.Body.Bytes(), &actualResp), "Unable to unmarshal actual BidResponse.") if expectedResp.Ext != nil { - assert.NoError(t, json.Unmarshal(expectedResp.Ext, &expectedExt), "Unable to unmarshal expected ExtBidResponse.") - assert.NoError(t, json.Unmarshal(actualResp.Ext, &actualExt), "Unable to unmarshal actual ExtBidResponse.") + assert.NoError(t, jsonutil.UnmarshalValid(expectedResp.Ext, &expectedExt), "Unable to unmarshal expected ExtBidResponse.") + assert.NoError(t, jsonutil.UnmarshalValid(actualResp.Ext, &actualExt), "Unable to unmarshal actual ExtBidResponse.") } assertBidResponseEqual(t, tc.file, expectedResp, actualResp) @@ -5959,7 +5960,7 @@ func getObject(t *testing.T, filename, key string) json.RawMessage { assert.NoError(t, err, "Error jsonparsing root.mockBidRequest from file %s. Desc: %v.", filename, err) var obj json.RawMessage - err = json.Unmarshal(testBidRequest, &obj) + err = jsonutil.UnmarshalValid(testBidRequest, &obj) if err != nil { t.Fatalf("Failed to fetch object with key '%s' ... got error: %v", key, err) } diff --git a/endpoints/openrtb2/sample-requests/invalid-stored/bad_incoming_1.json b/endpoints/openrtb2/sample-requests/invalid-stored/bad_incoming_1.json index 812f0664fbb..cf699fea0c9 100644 --- a/endpoints/openrtb2/sample-requests/invalid-stored/bad_incoming_1.json +++ b/endpoints/openrtb2/sample-requests/invalid-stored/bad_incoming_1.json @@ -11,5 +11,5 @@ } }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: Invalid JSON in Incoming Request: invalid character ']' looking for beginning of value at offset" + "expectedErrorMessage": "Invalid request: expect { or n, but found" } diff --git a/endpoints/openrtb2/sample-requests/invalid-stored/bad_incoming_imp.json b/endpoints/openrtb2/sample-requests/invalid-stored/bad_incoming_imp.json index e3960b17399..fb0dc866d10 100644 --- a/endpoints/openrtb2/sample-requests/invalid-stored/bad_incoming_imp.json +++ b/endpoints/openrtb2/sample-requests/invalid-stored/bad_incoming_imp.json @@ -37,5 +37,5 @@ "tmax": 500 }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: Invalid JSON in Imp[0] of Incoming Request: invalid character '\"' after object key:value pair at offset 132\n" + "expectedErrorMessage": "Invalid request: Invalid JSON Document" } diff --git a/endpoints/openrtb2/sample-requests/invalid-stored/bad_stored_imp.json b/endpoints/openrtb2/sample-requests/invalid-stored/bad_stored_imp.json index 0fed6c32adf..ea19855e75a 100644 --- a/endpoints/openrtb2/sample-requests/invalid-stored/bad_stored_imp.json +++ b/endpoints/openrtb2/sample-requests/invalid-stored/bad_stored_imp.json @@ -33,5 +33,5 @@ "tmax": 500 }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: imp.ext.prebid.storedrequest.id 7: Stored Imp has Invalid JSON" + "expectedErrorMessage": "Invalid request: Invalid JSON Document" } diff --git a/endpoints/openrtb2/sample-requests/invalid-stored/bad_stored_req.json b/endpoints/openrtb2/sample-requests/invalid-stored/bad_stored_req.json index 4e9d7f03352..235eb26179b 100644 --- a/endpoints/openrtb2/sample-requests/invalid-stored/bad_stored_req.json +++ b/endpoints/openrtb2/sample-requests/invalid-stored/bad_stored_req.json @@ -23,5 +23,5 @@ } }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: ext.prebid.storedrequest.id refers to Stored Request 3 which contains Invalid JSON" + "expectedErrorMessage": "Invalid request: expect { or n, but found" } diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/interstital-bad-perc.json b/endpoints/openrtb2/sample-requests/invalid-whole/interstital-bad-perc.json index 302372b5e5d..e5031d4597d 100644 --- a/endpoints/openrtb2/sample-requests/invalid-whole/interstital-bad-perc.json +++ b/endpoints/openrtb2/sample-requests/invalid-whole/interstital-bad-perc.json @@ -49,5 +49,5 @@ } }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: request.device.ext.prebid.interstitial.minwidthperc must be a number between 0 and 100\n" + "expectedErrorMessage": "Invalid request: request.device.ext.prebid.interstitial.minwidthperc must be a number between 0 and 100" } diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/invalid-source.json b/endpoints/openrtb2/sample-requests/invalid-whole/invalid-source.json index 5aa7fd4dea1..8db15b82a75 100644 --- a/endpoints/openrtb2/sample-requests/invalid-whole/invalid-source.json +++ b/endpoints/openrtb2/sample-requests/invalid-whole/invalid-source.json @@ -39,5 +39,5 @@ ] }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: json: cannot unmarshal object into Go struct field ExtAppPrebid.source of type string" + "expectedErrorMessage": "Invalid request: cannot unmarshal openrtb_ext.ExtAppPrebid.Source: expects \" or n, but found {" } diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/malformed-bid-request.json b/endpoints/openrtb2/sample-requests/invalid-whole/malformed-bid-request.json index c6fd52304a7..482af257d62 100644 --- a/endpoints/openrtb2/sample-requests/invalid-whole/malformed-bid-request.json +++ b/endpoints/openrtb2/sample-requests/invalid-whole/malformed-bid-request.json @@ -2,5 +2,5 @@ "description": "Malformed bid request throws an error", "mockBidRequest": "malformed", "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: invalid character 'm' looking for beginning of value\n" + "expectedErrorMessage": "Invalid request: expect { or n, but found m" } diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-malformed.json b/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-malformed.json index ab44e3e2428..7ab2631b701 100644 --- a/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-malformed.json +++ b/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-malformed.json @@ -42,5 +42,5 @@ } }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: request.regs.ext is invalid: json: cannot unmarshal string into Go value of type map[string]json.RawMessage\n" + "expectedErrorMessage": "Invalid request: request.regs.ext is invalid: expect { or n, but found " } diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-consent-int.json b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-consent-int.json index a26db8a5695..af04627c3a9 100644 --- a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-consent-int.json +++ b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-consent-int.json @@ -46,5 +46,5 @@ } }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: request.user.ext object is not valid: json: cannot unmarshal number into Go value of type string\n" + "expectedErrorMessage": "Invalid request: request.user.ext object is not valid: expects \" or n, but found 1" } diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/user-gdpr-consent-invalid.json b/endpoints/openrtb2/sample-requests/invalid-whole/user-gdpr-consent-invalid.json index c4646550dd2..b710d589ea5 100644 --- a/endpoints/openrtb2/sample-requests/invalid-whole/user-gdpr-consent-invalid.json +++ b/endpoints/openrtb2/sample-requests/invalid-whole/user-gdpr-consent-invalid.json @@ -41,5 +41,5 @@ } }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: request.user.ext object is not valid: json: cannot unmarshal number into Go value of type string" + "expectedErrorMessage": "Invalid request: request.user.ext object is not valid: expects \" or n, but found 2" } diff --git a/endpoints/openrtb2/test_utils.go b/endpoints/openrtb2/test_utils.go index 365f480eb4c..e8506813eef 100644 --- a/endpoints/openrtb2/test_utils.go +++ b/endpoints/openrtb2/test_utils.go @@ -38,6 +38,7 @@ import ( "github.com/prebid/prebid-server/stored_requests" "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" "github.com/prebid/prebid-server/util/iputil" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/util/uuidutil" jsonpatch "gopkg.in/evanphx/json-patch.v4" ) @@ -925,7 +926,7 @@ func (s mockCurrencyRatesClient) handle(w http.ResponseWriter, req *http.Request s.data.DataAsOfRaw = "2018-09-12" // Marshal the response and http write it - currencyServerJsonResponse, err := json.Marshal(&s.data) + currencyServerJsonResponse, err := jsonutil.Marshal(&s.data) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -949,13 +950,13 @@ func (b mockBidderHandler) bid(w http.ResponseWriter, req *http.Request) { // Unmarshal exit if error var openrtb2Request openrtb2.BidRequest - if err := json.Unmarshal(buf.Bytes(), &openrtb2Request); err != nil { + if err := jsonutil.UnmarshalValid(buf.Bytes(), &openrtb2Request); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } var openrtb2ImpExt map[string]json.RawMessage - if err := json.Unmarshal(openrtb2Request.Imp[0].Ext, &openrtb2ImpExt); err != nil { + if err := jsonutil.UnmarshalValid(openrtb2Request.Imp[0].Ext, &openrtb2ImpExt); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } @@ -986,7 +987,7 @@ func (b mockBidderHandler) bid(w http.ResponseWriter, req *http.Request) { } // Marshal the response and http write it - serverJsonResponse, err := json.Marshal(&serverResponseObject) + serverJsonResponse, err := jsonutil.Marshal(&serverResponseObject) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -1016,7 +1017,7 @@ func (a mockAdapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *ada for _, imp := range request.Imp { requestCopy.Imp = []openrtb2.Imp{imp} - requestJSON, err := json.Marshal(request) + requestJSON, err := jsonutil.Marshal(request) if err != nil { errors = append(errors, err) continue @@ -1049,7 +1050,7 @@ func (a mockAdapter) MakeBids(request *openrtb2.BidRequest, requestData *adapter } var publisherResponse openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &publisherResponse); err != nil { + if err := jsonutil.UnmarshalValid(responseData.Body, &publisherResponse); err != nil { return nil, []error{err} } @@ -1113,7 +1114,7 @@ func parseTestData(fileData []byte, testFile string) (testCase, error) { jsonTestConfig, _, _, err = jsonparser.Get(fileData, "config") if err == nil { - if err = json.Unmarshal(jsonTestConfig, parsedTestData.Config); err != nil { + if err = jsonutil.UnmarshalValid(jsonTestConfig, parsedTestData.Config); err != nil { return parsedTestData, fmt.Errorf("Error unmarshaling root.config from file %s. Desc: %v.", testFile, err) } } diff --git a/endpoints/openrtb2/video_auction.go b/endpoints/openrtb2/video_auction.go index 8faf15543d3..94455e0cb52 100644 --- a/endpoints/openrtb2/video_auction.go +++ b/endpoints/openrtb2/video_auction.go @@ -2,7 +2,6 @@ package openrtb2 import ( "context" - "encoding/json" "errors" "fmt" "io" @@ -36,6 +35,7 @@ import ( "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" "github.com/prebid/prebid-server/usersync" "github.com/prebid/prebid-server/util/iputil" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/util/ptrutil" "github.com/prebid/prebid-server/util/uuidutil" "github.com/prebid/prebid-server/version" @@ -179,7 +179,7 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re resolvedRequest := requestJson if debugLog.DebugEnabledOrOverridden { debugLog.Data.Request = string(requestJson) - if headerBytes, err := json.Marshal(r.Header); err == nil { + if headerBytes, err := jsonutil.Marshal(r.Header); err == nil { debugLog.Data.Headers = string(headerBytes) } else { debugLog.Data.Headers = fmt.Sprintf("Unable to marshal headers data: %s", err.Error()) @@ -219,7 +219,7 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re var bidReq = &openrtb2.BidRequest{} if deps.defaultRequest { - if err := json.Unmarshal(deps.defReqJSON, bidReq); err != nil { + if err := jsonutil.UnmarshalValid(deps.defReqJSON, bidReq); err != nil { err = fmt.Errorf("Invalid JSON in Default Request Settings: %s", err) handleError(&labels, w, []error{err}, &vo, &debugLog) return @@ -374,8 +374,7 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re vo.VideoResponse = bidResp - resp, err := json.Marshal(bidResp) - //resp, err := json.Marshal(response) + resp, err := jsonutil.Marshal(bidResp) if err != nil { errL := []error{err} handleError(&labels, w, errL, &vo, &debugLog) @@ -384,7 +383,6 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re w.Header().Set("Content-Type", "application/json") w.Write(resp) - } func cleanupVideoBidRequest(videoReq *openrtb_ext.BidRequestVideo, podErrors []PodError) *openrtb_ext.BidRequestVideo { @@ -507,7 +505,7 @@ func (deps *endpointDeps) loadStoredImp(storedImpId string) (openrtb2.Imp, []err return impr, err } - if err := json.Unmarshal(imp[storedImpId], &impr); err != nil { + if err := jsonutil.UnmarshalValid(imp[storedImpId], &impr); err != nil { return impr, []error{err} } return impr, nil @@ -536,7 +534,7 @@ func buildVideoResponse(bidresponse *openrtb2.BidResponse, podErrors []PodError) anyBidsReturned = true var tempRespBidExt openrtb_ext.ExtBid - if err := json.Unmarshal(bid.Ext, &tempRespBidExt); err != nil { + if err := jsonutil.UnmarshalValid(bid.Ext, &tempRespBidExt); err != nil { return nil, err } if tempRespBidExt.Prebid.Targeting[formatTargetingKey(openrtb_ext.HbVastCacheKey, seatBid.Seat)] == "" { @@ -705,13 +703,13 @@ func createBidExtension(videoRequest *openrtb_ext.BidRequestVideo) ([]byte, erro } extReq := openrtb_ext.ExtRequest{Prebid: prebid} - return json.Marshal(extReq) + return jsonutil.Marshal(extReq) } func (deps *endpointDeps) parseVideoRequest(request []byte, headers http.Header) (req *openrtb_ext.BidRequestVideo, errs []error, podErrors []PodError) { req = &openrtb_ext.BidRequestVideo{} - if err := json.Unmarshal(request, &req); err != nil { + if err := jsonutil.UnmarshalValid(request, &req); err != nil { errs = []error{err} return } diff --git a/endpoints/openrtb2/video_auction_test.go b/endpoints/openrtb2/video_auction_test.go index 19af821f205..281c80b204d 100644 --- a/endpoints/openrtb2/video_auction_test.go +++ b/endpoints/openrtb2/video_auction_test.go @@ -23,6 +23,7 @@ import ( "github.com/prebid/prebid-server/prebid_cache_client" "github.com/prebid/prebid-server/privacy" "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/util/ptrutil" "github.com/prebid/openrtb/v19/adcom1" @@ -47,7 +48,7 @@ func TestVideoEndpointImpressionsNumber(t *testing.T) { respBytes := recorder.Body.Bytes() resp := &openrtb_ext.BidResponseVideo{} - if err := json.Unmarshal(respBytes, resp); err != nil { + if err := jsonutil.UnmarshalValid(respBytes, resp); err != nil { t.Fatalf("Unable to unmarshal response.") } @@ -80,7 +81,7 @@ func TestVideoEndpointImpressionsDuration(t *testing.T) { } var extData openrtb_ext.ExtRequest - json.Unmarshal(ex.lastRequest.Ext, &extData) + jsonutil.UnmarshalValid(ex.lastRequest.Ext, &extData) assert.NotNil(t, extData.Prebid.Targeting.IncludeBidderKeys, "Request ext incorrect: IncludeBidderKeys should be true ") assert.True(t, *extData.Prebid.Targeting.IncludeBidderKeys, "Request ext incorrect: IncludeBidderKeys should be true ") @@ -135,7 +136,7 @@ func TestCreateBidExtension(t *testing.T) { resExt := &openrtb_ext.ExtRequest{} - if err := json.Unmarshal(res, &resExt); err != nil { + if err := jsonutil.UnmarshalValid(res, &resExt); err != nil { assert.Fail(t, "Unable to unmarshal bid extension") } assert.Equal(t, resExt.Prebid.Targeting.DurationRangeSec, durationRange, "Duration range seconds is incorrect") @@ -178,7 +179,7 @@ func TestVideoEndpointDebugQueryTrue(t *testing.T) { respBytes := recorder.Body.Bytes() resp := &openrtb_ext.BidResponseVideo{} - if err := json.Unmarshal(respBytes, resp); err != nil { + if err := jsonutil.UnmarshalValid(respBytes, resp); err != nil { t.Fatalf("Unable to unmarshal response.") } @@ -216,7 +217,7 @@ func TestVideoEndpointDebugQueryFalse(t *testing.T) { respBytes := recorder.Body.Bytes() resp := &openrtb_ext.BidResponseVideo{} - if err := json.Unmarshal(respBytes, resp); err != nil { + if err := jsonutil.UnmarshalValid(respBytes, resp); err != nil { t.Fatalf("Unable to unmarshal response.") } @@ -272,7 +273,7 @@ func TestVideoEndpointDebugNoAdPods(t *testing.T) { respBytes := recorder.Body.Bytes() resp := &openrtb_ext.BidResponseVideo{} - if err := json.Unmarshal(respBytes, resp); err != nil { + if err := jsonutil.UnmarshalValid(respBytes, resp); err != nil { t.Fatalf("Unable to unmarshal response.") } @@ -1091,7 +1092,7 @@ func TestCCPA(t *testing.T) { t.Fatalf("%s: The request never made it into the exchange.", test.description) } extRegs := &openrtb_ext.ExtRegs{} - if err := json.Unmarshal(ex.lastRequest.Regs.Ext, extRegs); err != nil { + if err := jsonutil.UnmarshalValid(ex.lastRequest.Regs.Ext, extRegs); err != nil { t.Fatalf("%s: Failed to unmarshal reg.ext in request to the exchange: %v", test.description, err) } if test.expectConsentString { @@ -1103,7 +1104,7 @@ func TestCCPA(t *testing.T) { // Validate HTTP Response responseBytes := httpResponseRecorder.Body.Bytes() response := &openrtb_ext.BidResponseVideo{} - if err := json.Unmarshal(responseBytes, response); err != nil { + if err := jsonutil.UnmarshalValid(responseBytes, response); err != nil { t.Fatalf("%s: Unable to unmarshal response.", test.description) } assert.Len(t, ex.lastRequest.Imp, 11, test.description+":imps") @@ -1125,12 +1126,12 @@ func TestVideoEndpointAppendBidderNames(t *testing.T) { } var extData openrtb_ext.ExtRequest - json.Unmarshal(ex.lastRequest.Ext, &extData) + jsonutil.UnmarshalValid(ex.lastRequest.Ext, &extData) assert.True(t, extData.Prebid.Targeting.AppendBidderNames, "Request ext incorrect: AppendBidderNames should be true ") respBytes := recorder.Body.Bytes() resp := &openrtb_ext.BidResponseVideo{} - if err := json.Unmarshal(respBytes, resp); err != nil { + if err := jsonutil.UnmarshalValid(respBytes, resp); err != nil { t.Fatalf("Unable to unmarshal response.") } diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go index 387de6bd05f..8b919c3d596 100644 --- a/endpoints/setuid_test.go +++ b/endpoints/setuid_test.go @@ -1307,14 +1307,14 @@ func TestSetUIDEndpointMetrics(t *testing.T) { cfgAccountRequired: true, expectedResponseCode: 400, expectedMetrics: func(m *metrics.MetricsEngineMock) { - m.On("RecordSetUid", metrics.SetUidBadRequest).Once() + m.On("RecordSetUid", metrics.SetUidAccountConfigMalformed).Once() }, expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 400, Bidder: "pubmatic", UID: "", - Errors: []error{errors.New("unexpected end of JSON input")}, + Errors: []error{errCookieSyncAccountConfigMalformed}, Success: false, } a.On("LogSetUIDObject", &expected).Once() diff --git a/endpoints/version.go b/endpoints/version.go index 00d894963e6..0a837fd8bc3 100644 --- a/endpoints/version.go +++ b/endpoints/version.go @@ -5,6 +5,7 @@ import ( "net/http" "github.com/golang/glog" + "github.com/prebid/prebid-server/util/jsonutil" ) const versionEndpointValueNotSet = "not-set" @@ -29,7 +30,7 @@ func prepareVersionEndpointResponse(version, revision string) (json.RawMessage, revision = versionEndpointValueNotSet } - return json.Marshal(struct { + return jsonutil.Marshal(struct { Revision string `json:"revision"` Version string `json:"version"` }{ diff --git a/errortypes/code.go b/errortypes/code.go index 5cbf3f860b4..1de5e648cef 100644 --- a/errortypes/code.go +++ b/errortypes/code.go @@ -15,6 +15,8 @@ const ( MalformedAcctErrorCode ModuleRejectionErrorCode TmaxTimeoutErrorCode + FailedToMarshalErrorCode + FailedToUnmarshalErrorCode ) // Defines numeric codes for well-known warnings. diff --git a/errortypes/errortypes.go b/errortypes/errortypes.go index 18b70634c48..d31c4166b06 100644 --- a/errortypes/errortypes.go +++ b/errortypes/errortypes.go @@ -217,3 +217,37 @@ func (err *Warning) Code() int { func (err *Warning) Severity() Severity { return SeverityWarning } + +// FailedToUnmarshal should be used to represent errors that occur when unmarshaling raw json. +type FailedToUnmarshal struct { + Message string +} + +func (err *FailedToUnmarshal) Error() string { + return err.Message +} + +func (err *FailedToUnmarshal) Code() int { + return FailedToUnmarshalErrorCode +} + +func (err *FailedToUnmarshal) Severity() Severity { + return SeverityFatal +} + +// FailedToMarshal should be used to represent errors that occur when marshaling to a byte slice. +type FailedToMarshal struct { + Message string +} + +func (err *FailedToMarshal) Error() string { + return err.Message +} + +func (err *FailedToMarshal) Code() int { + return FailedToMarshalErrorCode +} + +func (err *FailedToMarshal) Severity() Severity { + return SeverityFatal +} diff --git a/exchange/auction.go b/exchange/auction.go index b2d6eb571ca..abbf56ba799 100644 --- a/exchange/auction.go +++ b/exchange/auction.go @@ -2,7 +2,6 @@ package exchange import ( "context" - "encoding/json" "encoding/xml" "errors" "fmt" @@ -17,6 +16,7 @@ import ( "github.com/prebid/prebid-server/exchange/entities" "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/prebid_cache_client" + "github.com/prebid/prebid-server/util/jsonutil" ) const ( @@ -83,7 +83,7 @@ func (d *DebugLog) PutDebugLogError(cache prebid_cache_client.Client, timeout in d.CacheKey = rawUUID.String() } - data, err := json.Marshal(d.CacheString) + data, err := jsonutil.Marshal(d.CacheString) if err != nil { return err } @@ -244,7 +244,7 @@ func (a *auction) doCache(ctx context.Context, cache prebid_cache_client.Client, } } if bids { - if jsonBytes, err := json.Marshal(topBid.Bid); err == nil { + if jsonBytes, err := jsonutil.Marshal(topBid.Bid); err == nil { jsonBytes, err = evTracking.modifyBidJSON(topBid, bidderName, jsonBytes) if err != nil { errs = append(errs, err) @@ -265,7 +265,7 @@ func (a *auction) doCache(ctx context.Context, cache prebid_cache_client.Client, } if vast && topBid.BidType == openrtb_ext.BidTypeVideo { vastXML := makeVAST(topBid.Bid) - if jsonBytes, err := json.Marshal(vastXML); err == nil { + if jsonBytes, err := jsonutil.Marshal(vastXML); err == nil { if useCustomCacheKey { toCache = append(toCache, prebid_cache_client.Cacheable{ Type: prebid_cache_client.TypeXML, @@ -292,7 +292,7 @@ func (a *auction) doCache(ctx context.Context, cache prebid_cache_client.Client, if len(toCache) > 0 && debugLog != nil && debugLog.DebugEnabledOrOverridden { debugLog.CacheKey = hbCacheID debugLog.BuildCacheString() - if jsonBytes, err := json.Marshal(debugLog.CacheString); err == nil { + if jsonBytes, err := jsonutil.Marshal(debugLog.CacheString); err == nil { toCache = append(toCache, prebid_cache_client.Cacheable{ Type: debugLog.CacheType, Data: jsonBytes, diff --git a/exchange/auction_test.go b/exchange/auction_test.go index ad0f8d4a72c..199b2abba77 100644 --- a/exchange/auction_test.go +++ b/exchange/auction_test.go @@ -2,7 +2,6 @@ package exchange import ( "context" - "encoding/json" "encoding/xml" "fmt" "os" @@ -17,6 +16,7 @@ import ( "github.com/prebid/prebid-server/exchange/entities" "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/prebid_cache_client" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/util/ptrutil" "github.com/stretchr/testify/assert" @@ -179,7 +179,7 @@ func loadCacheSpec(filename string) (*cacheSpec, error) { } var spec cacheSpec - if err := json.Unmarshal(specData, &spec); err != nil { + if err := jsonutil.UnmarshalValid(specData, &spec); err != nil { return nil, fmt.Errorf("Failed to unmarshal JSON from file: %v", err) } @@ -286,18 +286,18 @@ func runCacheSpec(t *testing.T, fileDisplayName string, specData *cacheSpec) { for i, expectedCacheable := range specData.ExpectedCacheables { found := false var expectedData interface{} - if err := json.Unmarshal(expectedCacheable.Data, &expectedData); err != nil { + if err := jsonutil.UnmarshalValid(expectedCacheable.Data, &expectedData); err != nil { t.Fatalf("Failed to decode expectedCacheables[%d].value: %v", i, err) } if s, ok := expectedData.(string); ok && expectedCacheable.Type == prebid_cache_client.TypeJSON { // decode again if we have pre-encoded json string values - if err := json.Unmarshal([]byte(s), &expectedData); err != nil { + if err := jsonutil.UnmarshalValid([]byte(s), &expectedData); err != nil { t.Fatalf("Failed to re-decode expectedCacheables[%d].value :%v", i, err) } } for j, cachedItem := range cache.items { var actualData interface{} - if err := json.Unmarshal(cachedItem.Data, &actualData); err != nil { + if err := jsonutil.UnmarshalValid(cachedItem.Data, &actualData); err != nil { t.Fatalf("Failed to decode actual cache[%d].value: %s", j, err) } if assert.ObjectsAreEqual(expectedData, actualData) && diff --git a/exchange/bidder.go b/exchange/bidder.go index 40135787b25..677743801f3 100644 --- a/exchange/bidder.go +++ b/exchange/bidder.go @@ -33,6 +33,7 @@ import ( "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/metrics" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/jsonutil" "golang.org/x/net/context/ctxhttp" ) @@ -287,7 +288,7 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest Bidde errs = append(errs, moreErrs...) if nativeMarkup != nil { - markup, err := json.Marshal(*nativeMarkup) + markup, err := jsonutil.Marshal(*nativeMarkup) if err != nil { errs = append(errs, err) } else { @@ -406,7 +407,7 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest Bidde func addNativeTypes(bid *openrtb2.Bid, request *openrtb2.BidRequest) (*nativeResponse.Response, []error) { var errs []error var nativeMarkup *nativeResponse.Response - if err := json.Unmarshal(json.RawMessage(bid.AdM), &nativeMarkup); err != nil || len(nativeMarkup.Assets) == 0 { + if err := jsonutil.UnmarshalValid(json.RawMessage(bid.AdM), &nativeMarkup); err != nil || len(nativeMarkup.Assets) == 0 { // Some bidders are returning non-IAB compliant native markup. In this case Prebid server will not be able to add types. E.g Facebook return nil, errs } @@ -418,7 +419,7 @@ func addNativeTypes(bid *openrtb2.Bid, request *openrtb2.BidRequest) (*nativeRes } var nativePayload nativeRequests.Request - if err := json.Unmarshal(json.RawMessage((*nativeImp).Request), &nativePayload); err != nil { + if err := jsonutil.UnmarshalValid(json.RawMessage((*nativeImp).Request), &nativePayload); err != nil { errs = append(errs, err) } @@ -636,7 +637,7 @@ func (bidder *bidderAdapter) doTimeoutNotification(timeoutBidder adapters.Timeou } } } else if bidder.config.Debug.TimeoutNotification.Log { - reqJSON, err := json.Marshal(req) + reqJSON, err := jsonutil.Marshal(req) var msg string if err == nil { msg = fmt.Sprintf("TimeoutNotification: Failed to generate timeout request: error(%s), bidder request(%s)", errL[0].Error(), string(reqJSON)) diff --git a/exchange/bidder_test.go b/exchange/bidder_test.go index 09c811ba9c6..b7203e33b17 100644 --- a/exchange/bidder_test.go +++ b/exchange/bidder_test.go @@ -31,6 +31,7 @@ import ( "github.com/prebid/prebid-server/metrics" metricsConfig "github.com/prebid/prebid-server/metrics/config" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/version" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -856,7 +857,7 @@ func TestMultiCurrencies(t *testing.T) { mockedHTTPServer := httptest.NewServer(http.HandlerFunc( func(rw http.ResponseWriter, req *http.Request) { - b, err := json.Marshal(tc.rates) + b, err := jsonutil.Marshal(tc.rates) if err == nil { rw.WriteHeader(http.StatusOK) rw.Write(b) @@ -1177,7 +1178,7 @@ func TestMultiCurrencies_RequestCurrencyPick(t *testing.T) { mockedHTTPServer := httptest.NewServer(http.HandlerFunc( func(rw http.ResponseWriter, req *http.Request) { - b, err := json.Marshal(tc.rates) + b, err := jsonutil.Marshal(tc.rates) if err == nil { rw.WriteHeader(http.StatusOK) rw.Write(b) @@ -2344,7 +2345,7 @@ func (bidder *goodSingleBidderWithStoredBidResp) MakeRequests(request *openrtb2. func (bidder *goodSingleBidderWithStoredBidResp) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.UnmarshalValid(response.Body, &bidResp); err != nil { return nil, []error{err} } bidResponse := adapters.NewBidderResponseWithBidsCapacity(5) diff --git a/exchange/events.go b/exchange/events.go index e4f6b0d503f..fb535f6f70e 100644 --- a/exchange/events.go +++ b/exchange/events.go @@ -1,7 +1,6 @@ package exchange import ( - "encoding/json" "time" "github.com/prebid/prebid-server/exchange/entities" @@ -11,6 +10,7 @@ import ( "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/endpoints/events" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/jsonutil" ) // eventTracking has configuration fields needed for adding event tracking to an auction response @@ -91,7 +91,7 @@ func (ev *eventTracking) modifyBidJSON(pbsBid *entities.PbsOrtbBid, bidderName o winEventURL = ev.makeEventURL(analytics.Win, pbsBid, bidderName) } // wurl attribute is not in the schema, so we have to patch - patch, err := json.Marshal(map[string]string{"wurl": winEventURL}) + patch, err := jsonutil.Marshal(map[string]string{"wurl": winEventURL}) if err != nil { return jsonBytes, err } diff --git a/exchange/exchange.go b/exchange/exchange.go index a8c76a5ebb1..6ebde7dca9d 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -35,6 +35,7 @@ import ( "github.com/prebid/prebid-server/stored_requests" "github.com/prebid/prebid-server/stored_responses" "github.com/prebid/prebid-server/usersync" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/util/maputil" "github.com/buger/jsonparser" @@ -278,7 +279,7 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog if err := r.BidRequestWrapper.RebuildRequest(); err != nil { return nil, err } - resolvedBidReq, err := json.Marshal(r.BidRequestWrapper.BidRequest) + resolvedBidReq, err := jsonutil.Marshal(r.BidRequestWrapper.BidRequest) if err != nil { return nil, err } @@ -442,7 +443,7 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog bidResponseExt = e.makeExtBidResponse(adapterBids, adapterExtra, *r, responseDebugAllow, requestExtPrebid.Passthrough, fledge, errs) if debugLog.DebugEnabledOrOverridden { - if bidRespExtBytes, err := json.Marshal(bidResponseExt); err == nil { + if bidRespExtBytes, err := jsonutil.Marshal(bidResponseExt); err == nil { debugLog.Data.Response = string(bidRespExtBytes) } else { debugLog.Data.Response = "Unable to marshal response ext for debugging" @@ -463,7 +464,7 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog if debugLog.DebugEnabledOrOverridden { - if bidRespExtBytes, err := json.Marshal(bidResponseExt); err == nil { + if bidRespExtBytes, err := jsonutil.Marshal(bidResponseExt); err == nil { debugLog.Data.Response = string(bidRespExtBytes) } else { debugLog.Data.Response = "Unable to marshal response ext for debugging" @@ -1292,7 +1293,7 @@ func makeBidExtJSON(ext json.RawMessage, prebid *openrtb_ext.ExtBidPrebid, impEx var extMap map[string]interface{} if len(ext) != 0 { - if err := json.Unmarshal(ext, &extMap); err != nil { + if err := jsonutil.Unmarshal(ext, &extMap); err != nil { return nil, err } } else { @@ -1316,7 +1317,7 @@ func makeBidExtJSON(ext json.RawMessage, prebid *openrtb_ext.ExtBidPrebid, impEx Meta openrtb_ext.ExtBidPrebidMeta `json:"meta"` } `json:"prebid"` }{} - if err := json.Unmarshal(ext, &metaContainer); err != nil { + if err := jsonutil.Unmarshal(ext, &metaContainer); err != nil { return nil, fmt.Errorf("error validaing response from server, %s", err) } prebid.Meta = &metaContainer.Prebid.Meta @@ -1337,7 +1338,7 @@ func makeBidExtJSON(ext json.RawMessage, prebid *openrtb_ext.ExtBidPrebid, impEx } } extMap[openrtb_ext.PrebidExtKey] = prebid - return json.Marshal(extMap) + return jsonutil.Marshal(extMap) } // If bid got cached inside `(a *auction) doCache(ctx context.Context, cache prebid_cache_client.Client, targData *targetData, bidRequest *openrtb2.BidRequest, ttlBuffer int64, defaultTTLs *config.DefaultTTLs, bidCategory map[string]string)`, @@ -1441,7 +1442,7 @@ func buildStoredAuctionResponse(storedAuctionResponses map[string]json.RawMessag for impId, storedResp := range storedAuctionResponses { var seatBids []openrtb2.SeatBid - if err := json.Unmarshal(storedResp, &seatBids); err != nil { + if err := jsonutil.UnmarshalValid(storedResp, &seatBids); err != nil { return nil, nil, nil, err } for _, seat := range seatBids { @@ -1460,7 +1461,7 @@ func buildStoredAuctionResponse(storedAuctionResponses map[string]json.RawMessag if seat.Ext != nil { var seatExt openrtb_ext.ExtBidResponse - if err := json.Unmarshal(seat.Ext, &seatExt); err != nil { + if err := jsonutil.Unmarshal(seat.Ext, &seatExt); err != nil { return nil, nil, nil, err } // add in FLEDGE response with impId substituted diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go index e57900cdfee..ff989bad91d 100644 --- a/exchange/exchange_test.go +++ b/exchange/exchange_test.go @@ -41,6 +41,7 @@ import ( "github.com/prebid/prebid-server/stored_requests" "github.com/prebid/prebid-server/stored_requests/backends/file_fetcher" "github.com/prebid/prebid-server/usersync" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -379,7 +380,7 @@ func TestDebugBehaviour(t *testing.T) { assert.NotNilf(t, outBidResponse.Ext, "%s. outBidResponse.Ext should not be nil \n", test.desc) assert.False(t, auctionRequest.BidderResponseStartTime.IsZero()) actualExt := &openrtb_ext.ExtBidResponse{} - err = json.Unmarshal(outBidResponse.Ext, actualExt) + err = jsonutil.UnmarshalValid(outBidResponse.Ext, actualExt) assert.NoErrorf(t, err, "%s. \"ext\" JSON field could not be unmarshaled. err: \"%v\" \n outBidResponse.Ext: \"%s\" \n", test.desc, err, outBidResponse.Ext) assert.NotEmpty(t, actualExt.Prebid, "%s. ext.prebid should not be empty") @@ -541,7 +542,7 @@ func TestTwoBiddersDebugDisabledAndEnabled(t *testing.T) { assert.False(t, auctionRequest.BidderResponseStartTime.IsZero()) actualExt := &openrtb_ext.ExtBidResponse{} - err = json.Unmarshal(outBidResponse.Ext, actualExt) + err = jsonutil.UnmarshalValid(outBidResponse.Ext, actualExt) assert.NoErrorf(t, err, "JSON field unmarshaling err. ") assert.NotEmpty(t, actualExt.Prebid, "ext.prebid should not be empty") @@ -1143,7 +1144,7 @@ func TestGetAuctionCurrencyRates(t *testing.T) { for _, tc := range testCases { // Test setup: - jsonPbsRates, err := json.Marshal(tc.given.pbsRates) + jsonPbsRates, err := jsonutil.Marshal(tc.given.pbsRates) if err != nil { t.Fatalf("Failed to marshal PBS rates: %v", err) } @@ -1627,7 +1628,7 @@ func TestBidReturnsCreative(t *testing.T) { assert.Equal(t, test.expectedCreativeMarkup, resultingBids[0].AdM, "%s. Ad markup string doesn't match expected \n", test.description) var bidExt openrtb_ext.ExtBid - json.Unmarshal(resultingBids[0].Ext, &bidExt) + jsonutil.UnmarshalValid(resultingBids[0].Ext, &bidExt) assert.Equal(t, 0, bidExt.Prebid.DealPriority, "%s. Test should have DealPriority set to 0", test.description) assert.Equal(t, false, bidExt.Prebid.DealTierSatisfied, "%s. Test should have DealTierSatisfied set to false", test.description) } @@ -1966,7 +1967,7 @@ func TestBidResponseImpExtInfo(t *testing.T) { impExtInfo["some-impression-id"] = ImpExtInfo{ true, []byte(`{"video":{"h":480,"mimes":["video/mp4"]}}`), - json.RawMessage(`{"imp_passthrough_val": 1}`)} + json.RawMessage(`{"imp_passthrough_val":1}`)} expectedBidResponseExt := `{"origbidcpm":0,"prebid":{"type":"video","passthrough":{"imp_passthrough_val":1}},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]}}` @@ -2284,7 +2285,7 @@ func loadFile(filename string) (*exchangeSpec, error) { } var spec exchangeSpec - if err := json.Unmarshal(specData, &spec); err != nil { + if err := jsonutil.UnmarshalValid(specData, &spec); err != nil { return nil, fmt.Errorf("Failed to unmarshal JSON from file: %v", err) } @@ -2381,7 +2382,7 @@ func runSpec(t *testing.T, filename string, spec *exchangeSpec) { auctionRequest.Account.DefaultBidLimit = spec.MultiBid.AccountMaxBid requestExt := &openrtb_ext.ExtRequest{} - err := json.Unmarshal(spec.IncomingRequest.OrtbRequest.Ext, requestExt) + err := jsonutil.UnmarshalValid(spec.IncomingRequest.OrtbRequest.Ext, requestExt) assert.NoError(t, err, "invalid request ext") validatedMultiBids, errs := openrtb_ext.ValidateAndBuildExtMultiBid(&requestExt.Prebid) for _, err := range errs { // same as in validateRequestExt(). @@ -2392,7 +2393,7 @@ func runSpec(t *testing.T, filename string, spec *exchangeSpec) { } requestExt.Prebid.MultiBid = validatedMultiBids - updateReqExt, err := json.Marshal(requestExt) + updateReqExt, err := jsonutil.Marshal(requestExt) assert.NoError(t, err, "invalid request ext") auctionRequest.BidRequestWrapper.Ext = updateReqExt } @@ -2455,7 +2456,7 @@ func runSpec(t *testing.T, filename string, spec *exchangeSpec) { actualPassthrough := "" actualBidRespExt := &openrtb_ext.ExtBidResponse{} if bid.Ext != nil { - if err := json.Unmarshal(bid.Ext, actualBidRespExt); err != nil { + if err := jsonutil.UnmarshalValid(bid.Ext, actualBidRespExt); err != nil { assert.NoError(t, err, fmt.Sprintf("Error when unmarshalling: %s", err)) } if actualBidRespExt.Prebid != nil { @@ -2464,7 +2465,7 @@ func runSpec(t *testing.T, filename string, spec *exchangeSpec) { } expectedBidRespExt := &openrtb_ext.ExtBidResponse{} if spec.Response.Ext != nil { - if err := json.Unmarshal(spec.Response.Ext, expectedBidRespExt); err != nil { + if err := jsonutil.UnmarshalValid(spec.Response.Ext, expectedBidRespExt); err != nil { assert.NoError(t, err, fmt.Sprintf("Error when unmarshalling: %s", err)) } if expectedBidRespExt.Prebid != nil { @@ -2495,11 +2496,11 @@ func runSpec(t *testing.T, filename string, spec *exchangeSpec) { actualBidRespExt := &openrtb_ext.ExtBidResponse{} expectedBidRespExt := &openrtb_ext.ExtBidResponse{} if bid.Ext != nil { - if err := json.Unmarshal(bid.Ext, actualBidRespExt); err != nil { + if err := jsonutil.UnmarshalValid(bid.Ext, actualBidRespExt); err != nil { assert.NoError(t, err, fmt.Sprintf("Error when unmarshalling: %s", err)) } } - if err := json.Unmarshal(spec.Response.Ext, expectedBidRespExt); err != nil { + if err := jsonutil.UnmarshalValid(spec.Response.Ext, expectedBidRespExt); err != nil { assert.NoError(t, err, fmt.Sprintf("Error when unmarshalling: %s", err)) } @@ -2529,7 +2530,7 @@ func extractResponseTimes(t *testing.T, context string, bid *openrtb2.BidRespons return nil } else { responseTimes := make(map[string]int) - if err := json.Unmarshal(data, &responseTimes); err != nil { + if err := jsonutil.UnmarshalValid(data, &responseTimes); err != nil { t.Errorf("%s: Failed to unmarshal ext.responsetimemillis into map[string]int: %v", context, err) return nil } @@ -4180,37 +4181,29 @@ func TestMakeBidExtJSON(t *testing.T) { description: "Invalid extension, valid extBidPrebid and valid imp ext info", ext: json.RawMessage(`{invalid json}`), extBidPrebid: openrtb_ext.ExtBidPrebid{Type: openrtb_ext.BidType("video")}, - impExtInfo: map[string]ImpExtInfo{"test_imp_id": {true, []byte(`{"video":{"h":480,"mimes":["video/mp4"]}}`), json.RawMessage(`"prebid": {"passthrough": {"imp_passthrough_val": some_val}}"`)}}, expectedBidExt: ``, - expectedErrMessage: "invalid character", - }, - { - description: "Valid extension, empty extBidPrebid and invalid imp ext info", - ext: json.RawMessage(`{"video":{"h":100}}`), - extBidPrebid: openrtb_ext.ExtBidPrebid{}, - impExtInfo: map[string]ImpExtInfo{"test_imp_id": {true, []byte(`{"video":{!}}`), nil}}, - expectedBidExt: ``, - expectedErrMessage: "invalid character", + expectedErrMessage: "expects \" or n, but found i", }, { description: "Meta - Invalid", ext: json.RawMessage(`{"prebid":{"meta":{"brandId":"foo"}}}`), // brandId should be an int, but is a string in this test case extBidPrebid: openrtb_ext.ExtBidPrebid{Type: openrtb_ext.BidType("banner")}, impExtInfo: nil, - expectedErrMessage: "error validaing response from server, json: cannot unmarshal string into Go struct field ExtBidPrebidMeta.prebid.meta.brandId of type int", + expectedErrMessage: "error validaing response from server, cannot unmarshal openrtb_ext.ExtBidPrebidMeta.BrandID: unexpected character: \xff", }, - // add invalid } for _, test := range testCases { - result, err := makeBidExtJSON(test.ext, &test.extBidPrebid, test.impExtInfo, "test_imp_id", test.origbidcpm, test.origbidcur) + t.Run(test.description, func(t *testing.T) { + result, err := makeBidExtJSON(test.ext, &test.extBidPrebid, test.impExtInfo, "test_imp_id", test.origbidcpm, test.origbidcur) - if test.expectedErrMessage == "" { - assert.JSONEq(t, test.expectedBidExt, string(result), "Incorrect result") - assert.NoError(t, err, "Error should not be returned") - } else { - assert.Contains(t, err.Error(), test.expectedErrMessage, "incorrect error message") - } + if test.expectedErrMessage == "" { + assert.JSONEq(t, test.expectedBidExt, string(result), "Incorrect result") + assert.NoError(t, err, "Error should not be returned") + } else { + assert.Contains(t, err.Error(), test.expectedErrMessage, "incorrect error message") + } + }) } } @@ -5343,12 +5336,12 @@ func (b *capturingRequestBidder) requestBid(ctx context.Context, bidderRequest B func diffOrtbRequests(t *testing.T, description string, expected *openrtb2.BidRequest, actual *openrtb2.BidRequest) { t.Helper() - actualJSON, err := json.Marshal(actual) + actualJSON, err := jsonutil.Marshal(actual) if err != nil { t.Fatalf("%s failed to marshal actual BidRequest into JSON. %v", description, err) } - expectedJSON, err := json.Marshal(expected) + expectedJSON, err := jsonutil.Marshal(expected) if err != nil { t.Fatalf("%s failed to marshal expected BidRequest into JSON. %v", description, err) } @@ -5366,12 +5359,12 @@ func diffOrtbResponses(t *testing.T, description string, expected *openrtb2.BidR // this implementation detail, I'm cutting a corner and ignoring it here. actualSeats := mapifySeatBids(t, description, actual.SeatBid) expectedSeats := mapifySeatBids(t, description, expected.SeatBid) - actualJSON, err := json.Marshal(actualSeats) + actualJSON, err := jsonutil.Marshal(actualSeats) if err != nil { t.Fatalf("%s failed to marshal actual BidResponse into JSON. %v", description, err) } - expectedJSON, err := json.Marshal(expectedSeats) + expectedJSON, err := jsonutil.Marshal(expectedSeats) if err != nil { t.Fatalf("%s failed to marshal expected BidResponse into JSON. %v", description, err) } @@ -5501,13 +5494,13 @@ func getInfoFromImp(req *openrtb_ext.RequestWrapper) (json.RawMessage, string, e impID := imp.ID var bidderExts map[string]json.RawMessage - if err := json.Unmarshal(imp.Ext, &bidderExts); err != nil { + if err := jsonutil.UnmarshalValid(imp.Ext, &bidderExts); err != nil { return nil, "", err } var extPrebid openrtb_ext.ExtImpPrebid if bidderExts[openrtb_ext.PrebidExtKey] != nil { - if err := json.Unmarshal(bidderExts[openrtb_ext.PrebidExtKey], &extPrebid); err != nil { + if err := jsonutil.UnmarshalValid(bidderExts[openrtb_ext.PrebidExtKey], &extPrebid); err != nil { return nil, "", err } } diff --git a/exchange/targeting_test.go b/exchange/targeting_test.go index a5f49689349..25c6ea1714a 100644 --- a/exchange/targeting_test.go +++ b/exchange/targeting_test.go @@ -16,6 +16,7 @@ import ( "github.com/prebid/prebid-server/hooks/hookexecution" metricsConfig "github.com/prebid/prebid-server/metrics/config" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/util/ptrutil" "github.com/prebid/openrtb/v19/openrtb2" @@ -182,7 +183,7 @@ func buildParams(t *testing.T, mockBids map[openrtb_ext.BidderName][]*openrtb2.B paramsPrebid["bidder"] = paramsPrebidBidders params["prebid"] = paramsPrebid - ext, err := json.Marshal(params) + ext, err := jsonutil.Marshal(params) if err != nil { t.Fatalf("Failed to make imp exts: %v", err) } @@ -224,7 +225,7 @@ func buildBidMap(seatBids []openrtb2.SeatBid, numBids int) map[string]*openrtb2. func parseTargets(t *testing.T, bid *openrtb2.Bid) map[string]string { t.Helper() var parsed openrtb_ext.ExtBid - if err := json.Unmarshal(bid.Ext, &parsed); err != nil { + if err := jsonutil.UnmarshalValid(bid.Ext, &parsed); err != nil { t.Fatalf("Unexpected error parsing targeting params: %v", err) } return parsed.Prebid.Targeting diff --git a/exchange/utils.go b/exchange/utils.go index 70988fbf7b9..c7acfaefce3 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -26,6 +26,7 @@ import ( "github.com/prebid/prebid-server/privacy/lmt" "github.com/prebid/prebid-server/schain" "github.com/prebid/prebid-server/stored_responses" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/util/ptrutil" ) @@ -282,7 +283,7 @@ func ExtractReqExtBidderParamsMap(bidRequest *openrtb2.BidRequest) (map[string]j reqExt := &openrtb_ext.ExtRequest{} if len(bidRequest.Ext) > 0 { - err := json.Unmarshal(bidRequest.Ext, &reqExt) + err := jsonutil.Unmarshal(bidRequest.Ext, &reqExt) if err != nil { return nil, fmt.Errorf("error decoding Request.ext : %s", err.Error()) } @@ -293,7 +294,7 @@ func ExtractReqExtBidderParamsMap(bidRequest *openrtb2.BidRequest) (map[string]j } var bidderParams map[string]json.RawMessage - err := json.Unmarshal(reqExt.Prebid.BidderParams, &bidderParams) + err := jsonutil.Unmarshal(reqExt.Prebid.BidderParams, &bidderParams) if err != nil { return nil, err } @@ -413,7 +414,7 @@ func buildRequestExtForBidder(bidder string, requestExt json.RawMessage, request } // Marshal New Prebid Object - prebidJson, err := json.Marshal(prebid) + prebidJson, err := jsonutil.Marshal(prebid) if err != nil { return nil, err } @@ -421,7 +422,7 @@ func buildRequestExtForBidder(bidder string, requestExt json.RawMessage, request // Parse Existing Ext extMap := make(map[string]json.RawMessage) if len(requestExt) != 0 { - if err := json.Unmarshal(requestExt, &extMap); err != nil { + if err := jsonutil.Unmarshal(requestExt, &extMap); err != nil { return nil, err } } @@ -434,7 +435,7 @@ func buildRequestExtForBidder(bidder string, requestExt json.RawMessage, request } if len(extMap) > 0 { - return json.Marshal(extMap) + return jsonutil.Marshal(extMap) } else { return nil, nil } @@ -518,7 +519,7 @@ func extractBuyerUIDs(user *openrtb2.User) (map[string]string, error) { } var userExt openrtb_ext.ExtUser - if err := json.Unmarshal(user.Ext, &userExt); err != nil { + if err := jsonutil.Unmarshal(user.Ext, &userExt); err != nil { return nil, err } if userExt.Prebid == nil { @@ -532,7 +533,7 @@ func extractBuyerUIDs(user *openrtb2.User) (map[string]string, error) { // Remarshal (instead of removing) if the ext has other known fields if userExt.Consent != "" || len(userExt.Eids) > 0 { - if newUserExtBytes, err := json.Marshal(userExt); err != nil { + if newUserExtBytes, err := jsonutil.Marshal(userExt); err != nil { return nil, err } else { user.Ext = newUserExtBytes @@ -556,20 +557,20 @@ func splitImps(imps []openrtb2.Imp) (map[string][]openrtb2.Imp, error) { for i, imp := range imps { var impExt map[string]json.RawMessage - if err := json.Unmarshal(imp.Ext, &impExt); err != nil { + if err := jsonutil.UnmarshalValid(imp.Ext, &impExt); err != nil { return nil, fmt.Errorf("invalid json for imp[%d]: %v", i, err) } var impExtPrebid map[string]json.RawMessage if impExtPrebidJSON, exists := impExt[openrtb_ext.PrebidExtKey]; exists { // validation already performed by impExt unmarshal. no error is possible here, proven by tests. - json.Unmarshal(impExtPrebidJSON, &impExtPrebid) + jsonutil.Unmarshal(impExtPrebidJSON, &impExtPrebid) } var impExtPrebidBidder map[string]json.RawMessage if impExtPrebidBidderJSON, exists := impExtPrebid[openrtb_ext.PrebidExtBidderKey]; exists { // validation already performed by impExt unmarshal. no error is possible here, proven by tests. - json.Unmarshal(impExtPrebidBidderJSON, &impExtPrebidBidder) + jsonutil.Unmarshal(impExtPrebidBidderJSON, &impExtPrebidBidder) } sanitizedImpExt, err := createSanitizedImpExt(impExt, impExtPrebid) @@ -582,7 +583,7 @@ func splitImps(imps []openrtb2.Imp) (map[string][]openrtb2.Imp, error) { sanitizedImpExt[openrtb_ext.PrebidExtBidderKey] = bidderExt - impExtJSON, err := json.Marshal(sanitizedImpExt) + impExtJSON, err := jsonutil.Marshal(sanitizedImpExt) if err != nil { return nil, fmt.Errorf("unable to remove other bidder fields for imp[%d]: cannot marshal ext: %v", i, err) } @@ -622,7 +623,7 @@ func createSanitizedImpExt(impExt, impExtPrebid map[string]json.RawMessage) (map // marshal sanitized imp[].ext.prebid if len(sanitizedImpPrebidExt) > 0 { - if impExtPrebidJSON, err := json.Marshal(sanitizedImpPrebidExt); err == nil { + if impExtPrebidJSON, err := jsonutil.Marshal(sanitizedImpPrebidExt); err == nil { sanitizedImpExt[openrtb_ext.PrebidExtKey] = impExtPrebidJSON } else { return nil, fmt.Errorf("cannot marshal ext.prebid: %v", err) @@ -686,7 +687,7 @@ func removeUnpermissionedEids(request *openrtb2.BidRequest, bidder string, reque // low level unmarshal to preserve other request.user.ext values. prebid server is non-destructive. var userExt map[string]json.RawMessage - if err := json.Unmarshal(request.User.Ext, &userExt); err != nil { + if err := jsonutil.Unmarshal(request.User.Ext, &userExt); err != nil { return err } @@ -696,7 +697,7 @@ func removeUnpermissionedEids(request *openrtb2.BidRequest, bidder string, reque } var eids []openrtb2.EID - if err := json.Unmarshal(eidsJSON, &eids); err != nil { + if err := jsonutil.Unmarshal(eidsJSON, &eids); err != nil { return err } @@ -739,7 +740,7 @@ func removeUnpermissionedEids(request *openrtb2.BidRequest, bidder string, reque if len(eidsAllowed) == 0 { delete(userExt, "eids") } else { - eidsRaw, err := json.Marshal(eidsAllowed) + eidsRaw, err := jsonutil.Marshal(eidsAllowed) if err != nil { return err } @@ -752,7 +753,7 @@ func removeUnpermissionedEids(request *openrtb2.BidRequest, bidder string, reque return nil } - userExtJSON, err := json.Marshal(userExt) + userExtJSON, err := jsonutil.Marshal(userExt) if err != nil { return err } @@ -781,7 +782,7 @@ func resolveBidder(bidder string, requestAliases map[string]string) (openrtb_ext func parseAliases(orig *openrtb2.BidRequest) (map[string]string, []error) { var aliases map[string]string if value, dataType, _, err := jsonparser.Get(orig.Ext, openrtb_ext.PrebidExtKey, "aliases"); dataType == jsonparser.Object && err == nil { - if err := json.Unmarshal(value, &aliases); err != nil { + if err := jsonutil.Unmarshal(value, &aliases); err != nil { return nil, []error{err} } } else if dataType != jsonparser.NotExist && err != jsonparser.KeyPathNotFoundError { @@ -794,7 +795,7 @@ func parseAliases(orig *openrtb2.BidRequest) (map[string]string, []error) { func parseAliasesGVLIDs(orig *openrtb2.BidRequest) (map[string]uint16, []error) { var aliasesGVLIDs map[string]uint16 if value, dataType, _, err := jsonparser.Get(orig.Ext, openrtb_ext.PrebidExtKey, "aliasgvlids"); dataType == jsonparser.Object && err == nil { - if err := json.Unmarshal(value, &aliasesGVLIDs); err != nil { + if err := jsonutil.Unmarshal(value, &aliasesGVLIDs); err != nil { return nil, []error{err} } } else if dataType != jsonparser.NotExist && err != jsonparser.KeyPathNotFoundError { @@ -1089,7 +1090,7 @@ func getPrebidMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { if bid.Ext != nil { var bidExt openrtb_ext.ExtBid - err = json.Unmarshal(bid.Ext, &bidExt) + err = jsonutil.Unmarshal(bid.Ext, &bidExt) if err == nil && bidExt.Prebid != nil { if bidType, err = openrtb_ext.ParseBidType(string(bidExt.Prebid.Type)); err == nil { return bidType, nil diff --git a/exchange/utils_test.go b/exchange/utils_test.go index 1be1aaa8493..b413a6b292e 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -18,6 +18,7 @@ import ( "github.com/prebid/prebid-server/metrics" "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/privacy" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -187,21 +188,21 @@ func TestSplitImps(t *testing.T) { givenImps: []openrtb2.Imp{ {ID: "imp1", Ext: json.RawMessage(`malformed`)}, }, - expectedError: "invalid json for imp[0]: invalid character 'm' looking for beginning of value", + expectedError: "invalid json for imp[0]: expect { or n, but found m", }, { description: "Malformed imp.ext.prebid", givenImps: []openrtb2.Imp{ {ID: "imp1", Ext: json.RawMessage(`{"prebid": malformed}`)}, }, - expectedError: "invalid json for imp[0]: invalid character 'm' looking for beginning of value", + expectedError: "invalid json for imp[0]: do not know how to skip: 109", }, { description: "Malformed imp.ext.prebid.bidder", givenImps: []openrtb2.Imp{ {ID: "imp1", Ext: json.RawMessage(`{"prebid": {"bidder": malformed}}`)}, }, - expectedError: "invalid json for imp[0]: invalid character 'm' looking for beginning of value", + expectedError: "invalid json for imp[0]: do not know how to skip: 109", }, } @@ -403,22 +404,6 @@ func TestCreateSanitizedImpExt(t *testing.T) { }, expectedError: "", }, - { - description: "Marshal Error - imp.ext.prebid", - givenImpExt: map[string]json.RawMessage{ - "prebid": json.RawMessage(`"ignoredInFavorOfSeparatelyUnmarshalledImpExtPrebid"`), - "data": json.RawMessage(`"anyData"`), - "context": json.RawMessage(`"anyContext"`), - "skadn": json.RawMessage(`"anySKAdNetwork"`), - "gpid": json.RawMessage(`"anyGPID"`), - "tid": json.RawMessage(`"anyTID"`), - }, - givenImpExtPrebid: map[string]json.RawMessage{ - "options": json.RawMessage(`malformed`), // String value without quotes. - }, - expected: nil, - expectedError: "cannot marshal ext.prebid: json: error calling MarshalJSON for type json.RawMessage: invalid character 'm' looking for beginning of value", - }, } for _, test := range testCases { @@ -592,7 +577,7 @@ func TestExtractAdapterReqBidderParamsMap(t *testing.T) { name: "malformed req.ext", givenBidRequest: &openrtb2.BidRequest{Ext: json.RawMessage("malformed")}, want: nil, - wantErr: errors.New("error decoding Request.ext : invalid character 'm' looking for beginning of value"), + wantErr: errors.New("error decoding Request.ext : expect { or n, but found m"), }, { name: "extract bidder params from req.Ext for input request in adapter code", @@ -1081,7 +1066,7 @@ func TestCleanOpenRTBRequestsCCPAErrors(t *testing.T) { req.Regs = &openrtb2.Regs{Ext: test.reqRegsExt} var reqExtStruct openrtb_ext.ExtRequest - err := json.Unmarshal(req.Ext, &reqExtStruct) + err := jsonutil.UnmarshalValid(req.Ext, &reqExtStruct) assert.NoError(t, err, test.description+":marshal_ext") auctionReq := AuctionRequest{ @@ -1240,7 +1225,7 @@ func TestCleanOpenRTBRequestsSChain(t *testing.T) { if test.inExt != nil { req.Ext = test.inExt extRequest = &openrtb_ext.ExtRequest{} - err := json.Unmarshal(req.Ext, extRequest) + err := jsonutil.UnmarshalValid(req.Ext, extRequest) assert.NoErrorf(t, err, test.description+":Error unmarshaling inExt") } @@ -1311,7 +1296,7 @@ func TestCleanOpenRTBRequestsBidderParams(t *testing.T) { if test.inExt != nil { req.Ext = test.inExt extRequest = &openrtb_ext.ExtRequest{} - err := json.Unmarshal(req.Ext, extRequest) + err := jsonutil.UnmarshalValid(req.Ext, extRequest) assert.NoErrorf(t, err, test.description+":Error unmarshaling inExt") } @@ -2492,7 +2477,7 @@ func TestBuildRequestExtForBidder(t *testing.T) { for _, test := range testCases { requestExtParsed := &openrtb_ext.ExtRequest{} if test.requestExt != nil { - err := json.Unmarshal(test.requestExt, requestExtParsed) + err := jsonutil.UnmarshalValid(test.requestExt, requestExtParsed) if !assert.NoError(t, err, test.description+":parse_ext") { continue } @@ -2533,7 +2518,7 @@ func TestBuildRequestExtForBidder_RequestExtMalformed(t *testing.T) { actualJson, actualErr := buildRequestExtForBidder(bidder, requestExt, requestExtParsed, bidderParams, alternateBidderCodes) assert.Equal(t, json.RawMessage(nil), actualJson) - assert.EqualError(t, actualErr, "invalid character 'm' looking for beginning of value") + assert.EqualError(t, actualErr, "expect { or n, but found m") } // newAdapterAliasBidRequest builds a BidRequest with aliases @@ -2864,17 +2849,17 @@ func TestRemoveUnpermissionedEidsUnmarshalErrors(t *testing.T) { { description: "Malformed Ext", userExt: json.RawMessage(`malformed`), - expectedErr: "invalid character 'm' looking for beginning of value", + expectedErr: "expect { or n, but found m", }, { description: "Malformed Eid Array Type", userExt: json.RawMessage(`{"eids":[42]}`), - expectedErr: "json: cannot unmarshal number into Go value of type openrtb2.EID", + expectedErr: "cannot unmarshal []openrtb2.EID: expect { or n, but found 4", }, { description: "Malformed Eid Item Type", userExt: json.RawMessage(`{"eids":[{"source":42,"id":"anyID"}]}`), - expectedErr: "json: cannot unmarshal number into Go struct field EID.source of type string", + expectedErr: "cannot unmarshal openrtb2.EID.Source: expects \" or n, but found 4", }, } @@ -3088,7 +3073,7 @@ func TestCleanOpenRTBRequestsSChainMultipleBidders(t *testing.T) { } extRequest := &openrtb_ext.ExtRequest{} - err := json.Unmarshal(req.Ext, extRequest) + err := jsonutil.UnmarshalValid(req.Ext, extRequest) assert.NoErrorf(t, err, "Error unmarshaling inExt") auctionReq := AuctionRequest{ @@ -3172,7 +3157,7 @@ func TestCleanOpenRTBRequestsBidAdjustment(t *testing.T) { H: 600, }}, }, - Ext: json.RawMessage(`{"bidder":{"placementId":1}}`), + Ext: json.RawMessage(`{"bidder":{"placementId": 1}}`), }}, }, { @@ -3200,7 +3185,7 @@ func TestCleanOpenRTBRequestsBidAdjustment(t *testing.T) { H: 600, }}, }, - Ext: json.RawMessage(`{"bidder":{"placementId":1}}`), + Ext: json.RawMessage(`{"bidder":{"placementId": 1}}`), }}, }, } @@ -3635,7 +3620,7 @@ func TestCleanOpenRTBRequestsFilterBidderRequestExt(t *testing.T) { if test.inExt != nil { req.Ext = test.inExt extRequest = &openrtb_ext.ExtRequest{} - err := json.Unmarshal(req.Ext, extRequest) + err := jsonutil.UnmarshalValid(req.Ext, extRequest) assert.NoErrorf(t, err, test.desc+":Error unmarshaling inExt") } @@ -4396,7 +4381,7 @@ func TestGetPrebidMediaTypeForBid(t *testing.T) { { description: "Invalid bid ext", inputBid: openrtb2.Bid{ID: "bidId", ImpID: "impId", Ext: json.RawMessage(`[true`)}, - expectedError: "Failed to parse bid mediatype for impression \"impId\", unexpected end of JSON input", + expectedError: "Failed to parse bid mediatype for impression \"impId\", expect { or n, but found [", }, { description: "Bid ext is nil", @@ -4437,7 +4422,7 @@ func TestGetMediaTypeForBid(t *testing.T) { { description: "invalid bid ext", inputBid: openrtb2.Bid{ID: "bidId", ImpID: "impId", Ext: json.RawMessage(`{"prebid"`)}, - expectedError: "Failed to parse bid mediatype for impression \"impId\", unexpected end of JSON input", + expectedError: "Failed to parse bid mediatype for impression \"impId\", expect :, but found \x00", }, { description: "Valid bid ext with mtype native", diff --git a/firstpartydata/first_party_data.go b/firstpartydata/first_party_data.go index b63feb1ec52..b23ba576fcf 100644 --- a/firstpartydata/first_party_data.go +++ b/firstpartydata/first_party_data.go @@ -10,6 +10,7 @@ import ( "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/ortb" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/util/ptrutil" ) @@ -215,7 +216,7 @@ func mergeUser(v *openrtb2.User, overrideJSON json.RawMessage) error { } // Merge - if err := json.Unmarshal(overrideJSON, &v); err != nil { + if err := jsonutil.Unmarshal(overrideJSON, &v); err != nil { return err } @@ -309,7 +310,7 @@ func mergeSite(v *openrtb2.Site, overrideJSON json.RawMessage, bidderName string } // Merge - if err := json.Unmarshal(overrideJSON, &v); err != nil { + if err := jsonutil.Unmarshal(overrideJSON, &v); err != nil { return err } @@ -426,7 +427,7 @@ func mergeApp(v *openrtb2.App, overrideJSON json.RawMessage) error { } // Merge - if err := json.Unmarshal(overrideJSON, &v); err != nil { + if err := jsonutil.Unmarshal(overrideJSON, &v); err != nil { return err } diff --git a/firstpartydata/first_party_data_test.go b/firstpartydata/first_party_data_test.go index ffa05a31d17..61369738bf3 100644 --- a/firstpartydata/first_party_data_test.go +++ b/firstpartydata/first_party_data_test.go @@ -10,6 +10,7 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -481,7 +482,7 @@ func TestExtractBidderConfigFPD(t *testing.T) { require.NoError(t, err, "Load Test File") givenRequestExtPrebid := &openrtb_ext.ExtRequestPrebid{} - err = json.Unmarshal(testFile.InputRequestData, givenRequestExtPrebid) + err = jsonutil.UnmarshalValid(testFile.InputRequestData, givenRequestExtPrebid) require.NoError(t, err, "Cannot Load Test Conditions") testRequest := &openrtb_ext.RequestExt{} @@ -537,11 +538,11 @@ func TestResolveFPD(t *testing.T) { require.NoError(t, err, "Load Test File") request := &openrtb2.BidRequest{} - err = json.Unmarshal(testFile.InputRequestData, &request) + err = jsonutil.UnmarshalValid(testFile.InputRequestData, &request) require.NoError(t, err, "Cannot Load Request") originalRequest := &openrtb2.BidRequest{} - err = json.Unmarshal(testFile.InputRequestData, &originalRequest) + err = jsonutil.UnmarshalValid(testFile.InputRequestData, &originalRequest) require.NoError(t, err, "Cannot Load Request") reqExtFPD := make(map[string][]byte) @@ -554,7 +555,7 @@ func TestResolveFPD(t *testing.T) { reqFPDSiteContentData := testFile.GlobalFPD[siteContentDataKey] if len(reqFPDSiteContentData) > 0 { var siteConData []openrtb2.Data - err = json.Unmarshal(reqFPDSiteContentData, &siteConData) + err = jsonutil.UnmarshalValid(reqFPDSiteContentData, &siteConData) if err != nil { t.Errorf("Unable to unmarshal site.content.data:") } @@ -564,7 +565,7 @@ func TestResolveFPD(t *testing.T) { reqFPDAppContentData := testFile.GlobalFPD[appContentDataKey] if len(reqFPDAppContentData) > 0 { var appConData []openrtb2.Data - err = json.Unmarshal(reqFPDAppContentData, &appConData) + err = jsonutil.UnmarshalValid(reqFPDAppContentData, &appConData) if err != nil { t.Errorf("Unable to unmarshal app.content.data: ") } @@ -574,7 +575,7 @@ func TestResolveFPD(t *testing.T) { reqFPDUserData := testFile.GlobalFPD[userDataKey] if len(reqFPDUserData) > 0 { var userData []openrtb2.Data - err = json.Unmarshal(reqFPDUserData, &userData) + err = jsonutil.UnmarshalValid(reqFPDUserData, &userData) if err != nil { t.Errorf("Unable to unmarshal app.content.data: ") } @@ -640,14 +641,14 @@ func TestExtractFPDForBidders(t *testing.T) { require.NoError(t, err, "Load Test File") var expectedRequest openrtb2.BidRequest - err = json.Unmarshal(testFile.OutputRequestData, &expectedRequest) + err = jsonutil.UnmarshalValid(testFile.OutputRequestData, &expectedRequest) if err != nil { t.Errorf("Unable to unmarshal input request: %s", path) } resultRequest := &openrtb_ext.RequestWrapper{} resultRequest.BidRequest = &openrtb2.BidRequest{} - err = json.Unmarshal(testFile.InputRequestData, resultRequest.BidRequest) + err = jsonutil.UnmarshalValid(testFile.InputRequestData, resultRequest.BidRequest) assert.NoError(t, err, "Error should be nil") resultFPD, errL := ExtractFPDForBidders(resultRequest) @@ -725,7 +726,7 @@ func TestResolveUser(t *testing.T) { globalFPD map[string][]byte openRtbGlobalFPD map[string][]openrtb2.Data expectedUser *openrtb2.User - expectedError string + expectError bool }{ { description: "FPD config and bid request user are not specified", @@ -768,7 +769,7 @@ func TestResolveUser(t *testing.T) { fpdConfig: &openrtb_ext.ORTB2{User: json.RawMessage(`{"id": "test1"}`)}, bidRequestUser: &openrtb2.User{ID: "test2", Ext: json.RawMessage(`{"data":{"inputFPDUserData":"inputFPDUserDataValue"}}`)}, globalFPD: map[string][]byte{userKey: []byte(`malformed`)}, - expectedError: "Invalid JSON Patch", + expectError: true, }, { description: "bid request and openrtb global fpd user are specified, no input user ext", @@ -837,18 +838,18 @@ func TestResolveUser(t *testing.T) { }, Ext: json.RawMessage(`{"key":"value","test":1}`), }, - expectedError: "invalid character 'm' looking for beginning of object key string", + expectError: true, }, } for _, test := range testCases { t.Run(test.description, func(t *testing.T) { resultUser, err := resolveUser(test.fpdConfig, test.bidRequestUser, test.globalFPD, test.openRtbGlobalFPD, "bidderA") - if test.expectedError == "" { + if test.expectError { + assert.Error(t, err, "expected error incorrect") + } else { assert.NoError(t, err, "unexpected error returned") assert.Equal(t, test.expectedUser, resultUser, "Result user is incorrect") - } else { - assert.EqualError(t, err, test.expectedError, "expected error incorrect") } }) } @@ -862,16 +863,16 @@ func TestResolveSite(t *testing.T) { globalFPD map[string][]byte openRtbGlobalFPD map[string][]openrtb2.Data expectedSite *openrtb2.Site - expectedError string + expectError bool }{ { description: "FPD config and bid request site are not specified", expectedSite: nil, }, { - description: "FPD config site only is specified", - fpdConfig: &openrtb_ext.ORTB2{Site: json.RawMessage(`{"id": "test"}`)}, - expectedError: "incorrect First Party Data for bidder bidderA: Site object is not defined in request, but defined in FPD config", + description: "FPD config site only is specified", + fpdConfig: &openrtb_ext.ORTB2{Site: json.RawMessage(`{"id": "test"}`)}, + expectError: true, }, { description: "FPD config and bid request site are specified", @@ -905,7 +906,7 @@ func TestResolveSite(t *testing.T) { fpdConfig: &openrtb_ext.ORTB2{Site: json.RawMessage(`{"id": "test1"}`)}, bidRequestSite: &openrtb2.Site{ID: "test2", Ext: json.RawMessage(`{"data":{"inputFPDSiteData":"inputFPDSiteDataValue"}}`)}, globalFPD: map[string][]byte{siteKey: []byte(`malformed`)}, - expectedError: "Invalid JSON Patch", + expectError: true, }, { description: "bid request and openrtb global fpd site are specified, no input site ext", @@ -997,18 +998,18 @@ func TestResolveSite(t *testing.T) { }}, Ext: json.RawMessage(`{"key":"value","test":1}`), }, - expectedError: "invalid character 'm' looking for beginning of object key string", + expectError: true, }, } for _, test := range testCases { t.Run(test.description, func(t *testing.T) { resultSite, err := resolveSite(test.fpdConfig, test.bidRequestSite, test.globalFPD, test.openRtbGlobalFPD, "bidderA") - if test.expectedError == "" { + if test.expectError { + assert.Error(t, err) + } else { assert.NoError(t, err, "unexpected error returned") assert.Equal(t, test.expectedSite, resultSite, "Result site is incorrect") - } else { - assert.EqualError(t, err, test.expectedError, "expected error incorrect") } }) } @@ -1022,16 +1023,16 @@ func TestResolveApp(t *testing.T) { globalFPD map[string][]byte openRtbGlobalFPD map[string][]openrtb2.Data expectedApp *openrtb2.App - expectedError string + expectError bool }{ { description: "FPD config and bid request app are not specified", expectedApp: nil, }, { - description: "FPD config app only is specified", - fpdConfig: &openrtb_ext.ORTB2{App: json.RawMessage(`{"id": "test"}`)}, - expectedError: "incorrect First Party Data for bidder bidderA: App object is not defined in request, but defined in FPD config", + description: "FPD config app only is specified", + fpdConfig: &openrtb_ext.ORTB2{App: json.RawMessage(`{"id": "test"}`)}, + expectError: true, }, { description: "FPD config and bid request app are specified", @@ -1065,7 +1066,7 @@ func TestResolveApp(t *testing.T) { fpdConfig: &openrtb_ext.ORTB2{App: json.RawMessage(`{"id": "test1"}`)}, bidRequestApp: &openrtb2.App{ID: "test2", Ext: json.RawMessage(`{"data":{"inputFPDAppData":"inputFPDAppDataValue"}}`)}, globalFPD: map[string][]byte{appKey: []byte(`malformed`)}, - expectedError: "Invalid JSON Patch", + expectError: true, }, { description: "bid request and openrtb global fpd app are specified, no input app ext", @@ -1157,18 +1158,18 @@ func TestResolveApp(t *testing.T) { }}, Ext: json.RawMessage(`{"key":"value","test":1}`), }, - expectedError: "invalid character 'm' looking for beginning of object key string", + expectError: true, }, } for _, test := range testCases { t.Run(test.description, func(t *testing.T) { resultApp, err := resolveApp(test.fpdConfig, test.bidRequestApp, test.globalFPD, test.openRtbGlobalFPD, "bidderA") - if test.expectedError == "" { - assert.NoError(t, err, "unexpected error returned") - assert.Equal(t, test.expectedApp, resultApp, "Result app is incorrect") + if test.expectError { + assert.Error(t, err) } else { - assert.EqualError(t, err, test.expectedError, "expected error incorrect") + assert.NoError(t, err) + assert.Equal(t, test.expectedApp, resultApp, "Result app is incorrect") } }) } @@ -1219,7 +1220,7 @@ func TestMergeUser(t *testing.T) { givenUser openrtb2.User givenFPD json.RawMessage expectedUser openrtb2.User - expectedErr string + expectError bool }{ { name: "empty", @@ -1243,7 +1244,7 @@ func TestMergeUser(t *testing.T) { name: "toplevel-ext-err", givenUser: openrtb2.User{ID: "1", Ext: []byte(`malformed`)}, givenFPD: []byte(`{"id":"2"}`), - expectedErr: "invalid request ext", + expectError: true, }, { name: "nested-geo", @@ -1267,13 +1268,13 @@ func TestMergeUser(t *testing.T) { name: "nested-geo-ext-err", givenUser: openrtb2.User{Geo: &openrtb2.Geo{Ext: []byte(`malformed`)}}, givenFPD: []byte(`{"geo":{"ext":{"b":100,"c":3}}}`), - expectedErr: "invalid request ext", + expectError: true, }, { name: "fpd-err", givenUser: openrtb2.User{ID: "1", Ext: []byte(`{"a":1}`)}, givenFPD: []byte(`malformed`), - expectedErr: "invalid character 'm' looking for beginning of value", + expectError: true, }, } @@ -1281,11 +1282,11 @@ func TestMergeUser(t *testing.T) { t.Run(test.name, func(t *testing.T) { err := mergeUser(&test.givenUser, test.givenFPD) - if test.expectedErr == "" { - assert.NoError(t, err, "unexpected error returned") - assert.Equal(t, test.expectedUser, test.givenUser, "result user is incorrect") + if test.expectError { + assert.Error(t, err) } else { - assert.EqualError(t, err, test.expectedErr, "expected error incorrect") + assert.NoError(t, err) + assert.Equal(t, test.expectedUser, test.givenUser, "result user is incorrect") } }) } @@ -1297,7 +1298,7 @@ func TestMergeApp(t *testing.T) { givenApp openrtb2.App givenFPD json.RawMessage expectedApp openrtb2.App - expectedErr string + expectError bool }{ { name: "empty", @@ -1321,7 +1322,7 @@ func TestMergeApp(t *testing.T) { name: "toplevel-ext-err", givenApp: openrtb2.App{ID: "1", Ext: []byte(`malformed`)}, givenFPD: []byte(`{"id":"2"}`), - expectedErr: "invalid request ext", + expectError: true, }, { name: "nested-publisher", @@ -1417,37 +1418,37 @@ func TestMergeApp(t *testing.T) { name: "nested-publisher-ext-err", givenApp: openrtb2.App{Publisher: &openrtb2.Publisher{Ext: []byte(`malformed`)}}, givenFPD: []byte(`{"publisher":{"ext":{"b":100,"c":3}}}`), - expectedErr: "invalid request ext", + expectError: true, }, { name: "nested-content-ext-err", givenApp: openrtb2.App{Content: &openrtb2.Content{Ext: []byte(`malformed`)}}, givenFPD: []byte(`{"content":{"ext":{"b":100,"c":3}}}`), - expectedErr: "invalid request ext", + expectError: true, }, { name: "nested-content-producer-ext-err", givenApp: openrtb2.App{Content: &openrtb2.Content{Producer: &openrtb2.Producer{Ext: []byte(`malformed`)}}}, givenFPD: []byte(`{"content":{"producer": {"ext":{"b":100,"c":3}}}}`), - expectedErr: "invalid request ext", + expectError: true, }, { name: "nested-content-network-ext-err", givenApp: openrtb2.App{Content: &openrtb2.Content{Network: &openrtb2.Network{Ext: []byte(`malformed`)}}}, givenFPD: []byte(`{"content":{"network": {"ext":{"b":100,"c":3}}}}`), - expectedErr: "invalid request ext", + expectError: true, }, { name: "nested-content-channel-ext-err", givenApp: openrtb2.App{Content: &openrtb2.Content{Channel: &openrtb2.Channel{Ext: []byte(`malformed`)}}}, givenFPD: []byte(`{"content":{"channelx": {"ext":{"b":100,"c":3}}}}`), - expectedErr: "invalid request ext", + expectError: true, }, { name: "fpd-err", givenApp: openrtb2.App{ID: "1", Ext: []byte(`{"a":1}`)}, givenFPD: []byte(`malformed`), - expectedErr: "invalid character 'm' looking for beginning of value", + expectError: true, }, } @@ -1455,11 +1456,11 @@ func TestMergeApp(t *testing.T) { t.Run(test.name, func(t *testing.T) { err := mergeApp(&test.givenApp, test.givenFPD) - if test.expectedErr == "" { - assert.NoError(t, err, "unexpected error returned") - assert.Equal(t, test.expectedApp, test.givenApp, " result app is incorrect") + if test.expectError { + assert.Error(t, err) } else { - assert.EqualError(t, err, test.expectedErr, "expected error incorrect") + assert.NoError(t, err) + assert.Equal(t, test.expectedApp, test.givenApp, " result app is incorrect") } }) } @@ -1471,13 +1472,13 @@ func TestMergeSite(t *testing.T) { givenSite openrtb2.Site givenFPD json.RawMessage expectedSite openrtb2.Site - expectedErr string + expectError bool }{ { name: "empty", givenSite: openrtb2.Site{}, givenFPD: []byte(`{}`), - expectedErr: "incorrect First Party Data for bidder BidderA: Site object cannot set empty page if req.site.id is empty", + expectError: true, }, { name: "toplevel", @@ -1495,7 +1496,7 @@ func TestMergeSite(t *testing.T) { name: "toplevel-ext-err", givenSite: openrtb2.Site{ID: "1", Ext: []byte(`malformed`)}, givenFPD: []byte(`{"id":"2"}`), - expectedErr: "invalid request ext", + expectError: true, }, { name: "nested-publisher", @@ -1591,37 +1592,37 @@ func TestMergeSite(t *testing.T) { name: "nested-publisher-ext-err", givenSite: openrtb2.Site{ID: "1", Publisher: &openrtb2.Publisher{Ext: []byte(`malformed`)}}, givenFPD: []byte(`{"publisher":{"ext":{"b":100,"c":3}}}`), - expectedErr: "invalid request ext", + expectError: true, }, { name: "nested-content-ext-err", givenSite: openrtb2.Site{ID: "1", Content: &openrtb2.Content{Ext: []byte(`malformed`)}}, givenFPD: []byte(`{"content":{"ext":{"b":100,"c":3}}}`), - expectedErr: "invalid request ext", + expectError: true, }, { name: "nested-content-producer-ext-err", givenSite: openrtb2.Site{ID: "1", Content: &openrtb2.Content{Producer: &openrtb2.Producer{Ext: []byte(`malformed`)}}}, givenFPD: []byte(`{"content":{"producer": {"ext":{"b":100,"c":3}}}}`), - expectedErr: "invalid request ext", + expectError: true, }, { name: "nested-content-network-ext-err", givenSite: openrtb2.Site{ID: "1", Content: &openrtb2.Content{Network: &openrtb2.Network{Ext: []byte(`malformed`)}}}, givenFPD: []byte(`{"content":{"network": {"ext":{"b":100,"c":3}}}}`), - expectedErr: "invalid request ext", + expectError: true, }, { name: "nested-content-channel-ext-err", givenSite: openrtb2.Site{ID: "1", Content: &openrtb2.Content{Channel: &openrtb2.Channel{Ext: []byte(`malformed`)}}}, givenFPD: []byte(`{"content":{"channelx": {"ext":{"b":100,"c":3}}}}`), - expectedErr: "invalid request ext", + expectError: true, }, { name: "fpd-err", givenSite: openrtb2.Site{ID: "1", Ext: []byte(`{"a":1}`)}, givenFPD: []byte(`malformed`), - expectedErr: "invalid character 'm' looking for beginning of value", + expectError: true, }, } @@ -1629,11 +1630,11 @@ func TestMergeSite(t *testing.T) { t.Run(test.name, func(t *testing.T) { err := mergeSite(&test.givenSite, test.givenFPD, "BidderA") - if test.expectedErr == "" { - assert.NoError(t, err, "unexpected error returned") - assert.Equal(t, test.expectedSite, test.givenSite, " result Site is incorrect") + if test.expectError { + assert.Error(t, err) } else { - assert.EqualError(t, err, test.expectedErr, "expected error incorrect") + assert.NoError(t, err) + assert.Equal(t, test.expectedSite, test.givenSite, " result Site is incorrect") } }) } diff --git a/floors/floors_test.go b/floors/floors_test.go index 7f27e1a26d5..b3002c2f155 100644 --- a/floors/floors_test.go +++ b/floors/floors_test.go @@ -9,6 +9,7 @@ import ( "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/currency" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/stretchr/testify/assert" ) @@ -447,7 +448,7 @@ func TestResolveFloors(t *testing.T) { } func printFloors(floors *openrtb_ext.PriceFloorRules) string { - fbytes, _ := json.Marshal(floors) + fbytes, _ := jsonutil.Marshal(floors) return string(fbytes) } diff --git a/floors/rule_test.go b/floors/rule_test.go index 27be6ef0dd2..7c484a7c95f 100644 --- a/floors/rule_test.go +++ b/floors/rule_test.go @@ -760,7 +760,7 @@ func TestGetMinFloorValue(t *testing.T) { }, want: 0.0, want1: "", - wantErr: errors.New("Error in getting FloorMin value : 'unexpected end of JSON input'"), + wantErr: errors.New("Error in getting FloorMin value : 'expects \" or n, but found \x00'"), }, } for _, tc := range testCases { diff --git a/gdpr/full_enforcement_test.go b/gdpr/full_enforcement_test.go index 61f6e8b8520..4a859ecaabb 100644 --- a/gdpr/full_enforcement_test.go +++ b/gdpr/full_enforcement_test.go @@ -1,7 +1,6 @@ package gdpr import ( - "encoding/json" "testing" "github.com/prebid/go-gdpr/consentconstants" @@ -10,6 +9,7 @@ import ( "github.com/prebid/go-gdpr/vendorlist" "github.com/prebid/go-gdpr/vendorlist2" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/stretchr/testify/assert" ) @@ -961,7 +961,7 @@ func TestLegalBasisWithoutVendor(t *testing.T) { func getVendorList(t *testing.T) vendorlist.VendorList { GVL := makeVendorList() - marshaledGVL, err := json.Marshal(GVL) + marshaledGVL, err := jsonutil.Marshal(GVL) if err != nil { t.Fatalf("Failed to marshal GVL") } diff --git a/gdpr/vendorlist-fetching_test.go b/gdpr/vendorlist-fetching_test.go index a1dfb7fefb8..b8c73bbf9a4 100644 --- a/gdpr/vendorlist-fetching_test.go +++ b/gdpr/vendorlist-fetching_test.go @@ -2,7 +2,6 @@ package gdpr import ( "context" - "encoding/json" "net/http" "net/http/httptest" "strconv" @@ -13,6 +12,7 @@ import ( "github.com/prebid/go-gdpr/api" "github.com/prebid/go-gdpr/consentconstants" "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/util/jsonutil" ) func TestFetcherDynamicLoadListExists(t *testing.T) { @@ -305,7 +305,7 @@ type vendor struct { } func MarshalVendorList(vendorList vendorList) string { - json, _ := json.Marshal(vendorList) + json, _ := jsonutil.Marshal(vendorList) return string(json) } diff --git a/go.mod b/go.mod index 6731c177ecf..e52946fbe1e 100644 --- a/go.mod +++ b/go.mod @@ -46,10 +46,13 @@ require ( github.com/golang/protobuf v1.5.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d // indirect + github.com/json-iterator/go v1.1.12 // indirect github.com/magiconair/properties v1.8.6 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/go.sum b/go.sum index 1f76be7af31..eefe0228261 100644 --- a/go.sum +++ b/go.sum @@ -296,6 +296,7 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= @@ -356,9 +357,11 @@ github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= diff --git a/hooks/hookanalytics/analytics_test.go b/hooks/hookanalytics/analytics_test.go index 177a9335da9..abf5e7f2ddc 100644 --- a/hooks/hookanalytics/analytics_test.go +++ b/hooks/hookanalytics/analytics_test.go @@ -1,9 +1,9 @@ package hookanalytics import ( - "encoding/json" "testing" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/stretchr/testify/assert" ) @@ -50,7 +50,7 @@ func TestAnalytics(t *testing.T) { Activity{Name: "define-blocks", Status: ActivityStatusError}, ) - gotAnalytics, err := json.Marshal(analytics) + gotAnalytics, err := jsonutil.Marshal(analytics) assert.NoError(t, err, "Failed to marshal analytics: %s", err) assert.JSONEq(t, string(expectedAnalytics), string(gotAnalytics)) } diff --git a/hooks/hookexecution/enricher.go b/hooks/hookexecution/enricher.go index 2978c21957d..c3dd5a23339 100644 --- a/hooks/hookexecution/enricher.go +++ b/hooks/hookexecution/enricher.go @@ -6,6 +6,7 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/util/jsonutil" jsonpatch "gopkg.in/evanphx/json-patch.v4" ) @@ -52,7 +53,7 @@ func EnrichExtBidResponse( return ext, warnings, err } - response, err := json.Marshal(extPrebid{Prebid: extModules{Modules: modules}}) + response, err := jsonutil.Marshal(extPrebid{Prebid: extModules{Modules: modules}}) if err != nil { return ext, warnings, err } @@ -83,7 +84,7 @@ func GetModulesJSON( return nil, warnings, nil } - data, err := json.Marshal(modulesOutcome) + data, err := jsonutil.Marshal(modulesOutcome) return data, warnings, err } diff --git a/hooks/hookexecution/enricher_test.go b/hooks/hookexecution/enricher_test.go index 7bb19c2ecf2..24f0f1c1d45 100644 --- a/hooks/hookexecution/enricher_test.go +++ b/hooks/hookexecution/enricher_test.go @@ -10,6 +10,7 @@ import ( "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/hooks/hookanalytics" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -258,7 +259,7 @@ func TestGetModulesJSON(t *testing.T) { assert.Empty(t, expectedResponse) } else { var expectedExtBidResponse openrtb_ext.ExtBidResponse - err := json.Unmarshal(expectedResponse, &expectedExtBidResponse) + err := jsonutil.UnmarshalValid(expectedResponse, &expectedExtBidResponse) assert.NoError(t, err, "Failed to unmarshal prebid response extension") assert.JSONEq(t, string(expectedExtBidResponse.Prebid.Modules), string(modules)) } @@ -271,7 +272,7 @@ func getStageOutcomes(t *testing.T, file string) []StageOutcome { var stageOutcomesTest []StageOutcomeTest data := readFile(t, file) - err := json.Unmarshal(data, &stageOutcomesTest) + err := jsonutil.UnmarshalValid(data, &stageOutcomesTest) require.NoError(t, err, "Failed to unmarshal stage outcomes: %s", err) for _, stageT := range stageOutcomesTest { diff --git a/hooks/hookexecution/test_utils.go b/hooks/hookexecution/test_utils.go index bd94d5778b4..2a604d851f5 100644 --- a/hooks/hookexecution/test_utils.go +++ b/hooks/hookexecution/test_utils.go @@ -4,6 +4,7 @@ import ( "encoding/json" "testing" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/stretchr/testify/assert" ) @@ -16,8 +17,8 @@ func AssertEqualModulesData(t *testing.T, expectedData, actualData json.RawMessa var expectedModulesOutcome ModulesOutcome var actualModulesOutcome ModulesOutcome - assert.NoError(t, json.Unmarshal(expectedData, &expectedModulesOutcome), "Failed to unmarshal expected modules data.") - assert.NoError(t, json.Unmarshal(actualData, &actualModulesOutcome), "Failed to unmarshal actual modules data.") + assert.NoError(t, jsonutil.UnmarshalValid(expectedData, &expectedModulesOutcome), "Failed to unmarshal expected modules data.") + assert.NoError(t, jsonutil.UnmarshalValid(actualData, &actualModulesOutcome), "Failed to unmarshal actual modules data.") assert.Equal(t, expectedModulesOutcome.Errors, actualModulesOutcome.Errors, "Invalid error messages.") assert.Equal(t, expectedModulesOutcome.Warnings, actualModulesOutcome.Warnings, "Invalid warning messages.") diff --git a/hooks/plan_test.go b/hooks/plan_test.go index 5d2a504f0d1..8af49b42e17 100644 --- a/hooks/plan_test.go +++ b/hooks/plan_test.go @@ -2,12 +2,12 @@ package hooks import ( "context" - "encoding/json" "testing" "time" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/hooks/hookstage" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/stretchr/testify/assert" ) @@ -227,7 +227,7 @@ func TestPlanForRawAuctionStage(t *testing.T) { for name, test := range testCases { t.Run(name, func(t *testing.T) { account := new(config.Account) - if err := json.Unmarshal(test.giveAccountPlanData, &account.Hooks); err != nil { + if err := jsonutil.UnmarshalValid(test.giveAccountPlanData, &account.Hooks); err != nil { t.Fatal(err) } @@ -333,7 +333,7 @@ func TestPlanForProcessedAuctionStage(t *testing.T) { for name, test := range testCases { t.Run(name, func(t *testing.T) { account := new(config.Account) - if err := json.Unmarshal(test.giveAccountPlanData, &account.Hooks); err != nil { + if err := jsonutil.UnmarshalValid(test.giveAccountPlanData, &account.Hooks); err != nil { t.Fatal(err) } @@ -439,7 +439,7 @@ func TestPlanForBidderRequestStage(t *testing.T) { for name, test := range testCases { t.Run(name, func(t *testing.T) { account := new(config.Account) - if err := json.Unmarshal(test.giveAccountPlanData, &account.Hooks); err != nil { + if err := jsonutil.UnmarshalValid(test.giveAccountPlanData, &account.Hooks); err != nil { t.Fatal(err) } @@ -545,7 +545,7 @@ func TestPlanForRawBidderResponseStage(t *testing.T) { for name, test := range testCases { t.Run(name, func(t *testing.T) { account := new(config.Account) - if err := json.Unmarshal(test.giveAccountPlanData, &account.Hooks); err != nil { + if err := jsonutil.UnmarshalValid(test.giveAccountPlanData, &account.Hooks); err != nil { t.Fatal(err) } @@ -651,7 +651,7 @@ func TestPlanForAllProcessedBidResponsesStage(t *testing.T) { for name, test := range testCases { t.Run(name, func(t *testing.T) { account := new(config.Account) - if err := json.Unmarshal(test.giveAccountPlanData, &account.Hooks); err != nil { + if err := jsonutil.UnmarshalValid(test.giveAccountPlanData, &account.Hooks); err != nil { t.Fatal(err) } @@ -757,7 +757,7 @@ func TestPlanForAuctionResponseStage(t *testing.T) { for name, test := range testCases { t.Run(name, func(t *testing.T) { account := new(config.Account) - if err := json.Unmarshal(test.giveAccountPlanData, &account.Hooks); err != nil { + if err := jsonutil.UnmarshalValid(test.giveAccountPlanData, &account.Hooks); err != nil { t.Fatal(err) } @@ -779,12 +779,12 @@ func getPlanBuilder( var hostPlan config.HookExecutionPlan var defaultAccountPlan config.HookExecutionPlan - err = json.Unmarshal(hostPlanData, &hostPlan) + err = jsonutil.UnmarshalValid(hostPlanData, &hostPlan) if err != nil { return nil, err } - err = json.Unmarshal(accountPlanData, &defaultAccountPlan) + err = jsonutil.UnmarshalValid(accountPlanData, &defaultAccountPlan) if err != nil { return nil, err } diff --git a/modules/modules.go b/modules/modules.go index ac60ec58082..4e60a9eda32 100644 --- a/modules/modules.go +++ b/modules/modules.go @@ -8,6 +8,7 @@ import ( "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/hooks" "github.com/prebid/prebid-server/modules/moduledeps" + "github.com/prebid/prebid-server/util/jsonutil" ) //go:generate go run ./generator/buildergen.go @@ -58,7 +59,7 @@ func (m *builder) Build( id := fmt.Sprintf("%s.%s", vendor, moduleName) if data, ok := cfg[vendor][moduleName]; ok { - if conf, err = json.Marshal(data); err != nil { + if conf, err = jsonutil.Marshal(data); err != nil { return nil, nil, fmt.Errorf(`failed to marshal "%s" module config: %s`, id, err) } diff --git a/modules/modules_test.go b/modules/modules_test.go index 1c70ce4badf..f88a48a2c44 100644 --- a/modules/modules_test.go +++ b/modules/modules_test.go @@ -85,7 +85,7 @@ func TestModuleBuilderBuild(t *testing.T) { givenConfig: map[string]map[string]interface{}{vendor: {moduleName: math.Inf(1)}}, expectedHookRepo: nil, expectedModulesStages: nil, - expectedErr: fmt.Errorf(`failed to marshal "%s.%s" module config: json: unsupported value: +Inf`, vendor, moduleName), + expectedErr: fmt.Errorf(`failed to marshal "%s.%s" module config: unsupported value: +Inf`, vendor, moduleName), }, } diff --git a/modules/prebid/ortb2blocking/config.go b/modules/prebid/ortb2blocking/config.go index cefd436b402..74841eb5b33 100644 --- a/modules/prebid/ortb2blocking/config.go +++ b/modules/prebid/ortb2blocking/config.go @@ -5,11 +5,12 @@ import ( "fmt" "github.com/prebid/openrtb/v19/adcom1" + "github.com/prebid/prebid-server/util/jsonutil" ) func newConfig(data json.RawMessage) (config, error) { var cfg config - if err := json.Unmarshal(data, &cfg); err != nil { + if err := jsonutil.UnmarshalValid(data, &cfg); err != nil { return cfg, fmt.Errorf("failed to parse config: %s", err) } return cfg, nil @@ -112,7 +113,7 @@ type Override struct { func (o *Override) UnmarshalJSON(bytes []byte) error { var overrideData interface{} - if err := json.Unmarshal(bytes, &overrideData); err != nil { + if err := jsonutil.UnmarshalValid(bytes, &overrideData); err != nil { return err } diff --git a/modules/prebid/ortb2blocking/module_test.go b/modules/prebid/ortb2blocking/module_test.go index b47f9f58a02..ecae5ca8c0a 100644 --- a/modules/prebid/ortb2blocking/module_test.go +++ b/modules/prebid/ortb2blocking/module_test.go @@ -488,7 +488,7 @@ func TestHandleBidderRequestHook(t *testing.T) { bidRequest: &openrtb2.BidRequest{}, expectedBidRequest: &openrtb2.BidRequest{}, expectedHookResult: hookstage.HookResult[hookstage.BidderRequestPayload]{}, - expectedError: errors.New("failed to parse config: invalid character '.' looking for beginning of value"), + expectedError: errors.New("failed to parse config: expect { or n, but found ."), }, { description: "Expect error if nil BidRequest provided", diff --git a/openrtb_ext/convert_down_test.go b/openrtb_ext/convert_down_test.go index ea21468e737..3b78337df8b 100644 --- a/openrtb_ext/convert_down_test.go +++ b/openrtb_ext/convert_down_test.go @@ -6,6 +6,7 @@ import ( "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/errortypes" "github.com/stretchr/testify/assert" ) @@ -14,7 +15,7 @@ func TestConvertDownTo25(t *testing.T) { name string givenRequest openrtb2.BidRequest expectedRequest openrtb2.BidRequest - expectedErr string + expectedErrType error }{ { name: "2.6-to-2.5", @@ -87,12 +88,12 @@ func TestConvertDownTo25(t *testing.T) { }, }, { - name: "malformed-shhain", + name: "malformed-schain", givenRequest: openrtb2.BidRequest{ ID: "anyID", Source: &openrtb2.Source{SChain: &openrtb2.SupplyChain{Complete: 1, Nodes: []openrtb2.SupplyChainNode{}, Ver: "2"}, Ext: json.RawMessage(`malformed`)}, }, - expectedErr: "invalid character 'm' looking for beginning of value", + expectedErrType: &errortypes.FailedToUnmarshal{}, }, { name: "malformed-gdpr", @@ -100,7 +101,7 @@ func TestConvertDownTo25(t *testing.T) { ID: "anyID", Regs: &openrtb2.Regs{GDPR: openrtb2.Int8Ptr(1), Ext: json.RawMessage(`malformed`)}, }, - expectedErr: "invalid character 'm' looking for beginning of value", + expectedErrType: &errortypes.FailedToUnmarshal{}, }, { name: "malformed-consent", @@ -108,7 +109,7 @@ func TestConvertDownTo25(t *testing.T) { ID: "anyID", User: &openrtb2.User{Consent: "1", Ext: json.RawMessage(`malformed`)}, }, - expectedErr: "invalid character 'm' looking for beginning of value", + expectedErrType: &errortypes.FailedToUnmarshal{}, }, { name: "malformed-usprivacy", @@ -116,7 +117,7 @@ func TestConvertDownTo25(t *testing.T) { ID: "anyID", Regs: &openrtb2.Regs{USPrivacy: "3", Ext: json.RawMessage(`malformed`)}, }, - expectedErr: "invalid character 'm' looking for beginning of value", + expectedErrType: &errortypes.FailedToUnmarshal{}, }, { name: "malformed-eid", @@ -124,7 +125,7 @@ func TestConvertDownTo25(t *testing.T) { ID: "anyID", User: &openrtb2.User{EIDs: []openrtb2.EID{{Source: "42"}}, Ext: json.RawMessage(`malformed`)}, }, - expectedErr: "invalid character 'm' looking for beginning of value", + expectedErrType: &errortypes.FailedToUnmarshal{}, }, { name: "malformed-imp", @@ -132,7 +133,7 @@ func TestConvertDownTo25(t *testing.T) { ID: "anyID", Imp: []openrtb2.Imp{{Rwdd: 1, Ext: json.RawMessage(`malformed`)}}, }, - expectedErr: "invalid character 'm' looking for beginning of value", + expectedErrType: &errortypes.FailedToUnmarshal{}, }, } @@ -141,8 +142,8 @@ func TestConvertDownTo25(t *testing.T) { w := &RequestWrapper{BidRequest: &test.givenRequest} err := ConvertDownTo25(w) - if len(test.expectedErr) > 0 { - assert.EqualError(t, err, test.expectedErr, "error") + if test.expectedErrType != nil { + assert.IsType(t, test.expectedErrType, err) } else { assert.NoError(t, w.RebuildRequest(), "error") assert.Equal(t, test.expectedRequest, *w.BidRequest, "result") @@ -162,7 +163,7 @@ func TestMoveSupplyChainFrom26To25(t *testing.T) { name string givenRequest openrtb2.BidRequest expectedRequest openrtb2.BidRequest - expectedErr string + expectedErrType error }{ { name: "notpresent-source", @@ -185,9 +186,9 @@ func TestMoveSupplyChainFrom26To25(t *testing.T) { expectedRequest: openrtb2.BidRequest{Source: &openrtb2.Source{Ext: schain1Json}}, }, { - name: "malformed", - givenRequest: openrtb2.BidRequest{Source: &openrtb2.Source{SChain: schain1, Ext: json.RawMessage(`malformed`)}}, - expectedErr: "invalid character 'm' looking for beginning of value", + name: "malformed", + givenRequest: openrtb2.BidRequest{Source: &openrtb2.Source{SChain: schain1, Ext: json.RawMessage(`malformed`)}}, + expectedErrType: &errortypes.FailedToUnmarshal{}, }, } @@ -196,8 +197,8 @@ func TestMoveSupplyChainFrom26To25(t *testing.T) { w := &RequestWrapper{BidRequest: &test.givenRequest} err := moveSupplyChainFrom26To25(w) - if len(test.expectedErr) > 0 { - assert.EqualError(t, err, test.expectedErr, "error") + if test.expectedErrType != nil { + assert.IsType(t, test.expectedErrType, err) } else { assert.NoError(t, w.RebuildRequest(), "error") assert.Equal(t, test.expectedRequest, *w.BidRequest, "result") @@ -211,7 +212,7 @@ func TestMoveGDPRFrom26To25(t *testing.T) { name string givenRequest openrtb2.BidRequest expectedRequest openrtb2.BidRequest - expectedErr string + expectedErrType error }{ { name: "notpresent-regs", @@ -234,9 +235,9 @@ func TestMoveGDPRFrom26To25(t *testing.T) { expectedRequest: openrtb2.BidRequest{Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"gdpr":0}`)}}, }, { - name: "malformed", - givenRequest: openrtb2.BidRequest{Regs: &openrtb2.Regs{GDPR: openrtb2.Int8Ptr(0), Ext: json.RawMessage(`malformed`)}}, - expectedErr: "invalid character 'm' looking for beginning of value", + name: "malformed", + givenRequest: openrtb2.BidRequest{Regs: &openrtb2.Regs{GDPR: openrtb2.Int8Ptr(0), Ext: json.RawMessage(`malformed`)}}, + expectedErrType: &errortypes.FailedToUnmarshal{}, }, } @@ -245,8 +246,8 @@ func TestMoveGDPRFrom26To25(t *testing.T) { w := &RequestWrapper{BidRequest: &test.givenRequest} err := moveGDPRFrom26To25(w) - if len(test.expectedErr) > 0 { - assert.EqualError(t, err, test.expectedErr, "error") + if test.expectedErrType != nil { + assert.IsType(t, test.expectedErrType, err) } else { assert.NoError(t, w.RebuildRequest(), "error") assert.Equal(t, test.expectedRequest, *w.BidRequest, "result") @@ -260,7 +261,7 @@ func TestMoveConsentFrom26To25(t *testing.T) { name string givenRequest openrtb2.BidRequest expectedRequest openrtb2.BidRequest - expectedErr string + expectedErrType error }{ { name: "notpresent-user", @@ -283,9 +284,9 @@ func TestMoveConsentFrom26To25(t *testing.T) { expectedRequest: openrtb2.BidRequest{User: &openrtb2.User{Ext: json.RawMessage(`{"consent":"1"}`)}}, }, { - name: "malformed", - givenRequest: openrtb2.BidRequest{User: &openrtb2.User{Consent: "1", Ext: json.RawMessage(`malformed`)}}, - expectedErr: "invalid character 'm' looking for beginning of value", + name: "malformed", + givenRequest: openrtb2.BidRequest{User: &openrtb2.User{Consent: "1", Ext: json.RawMessage(`malformed`)}}, + expectedErrType: &errortypes.FailedToUnmarshal{}, }, } @@ -294,8 +295,8 @@ func TestMoveConsentFrom26To25(t *testing.T) { w := &RequestWrapper{BidRequest: &test.givenRequest} err := moveConsentFrom26To25(w) - if len(test.expectedErr) > 0 { - assert.EqualError(t, err, test.expectedErr, "error") + if test.expectedErrType != nil { + assert.IsType(t, test.expectedErrType, err) } else { assert.NoError(t, w.RebuildRequest(), "error") assert.Equal(t, test.expectedRequest, *w.BidRequest, "result") @@ -309,7 +310,7 @@ func TestMoveUSPrivacyFrom26To25(t *testing.T) { name string givenRequest openrtb2.BidRequest expectedRequest openrtb2.BidRequest - expectedErr string + expectedErrType error }{ { name: "notpresent-regs", @@ -332,9 +333,9 @@ func TestMoveUSPrivacyFrom26To25(t *testing.T) { expectedRequest: openrtb2.BidRequest{Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"us_privacy":"1"}`)}}, }, { - name: "malformed", - givenRequest: openrtb2.BidRequest{Regs: &openrtb2.Regs{USPrivacy: "1", Ext: json.RawMessage(`malformed`)}}, - expectedErr: "invalid character 'm' looking for beginning of value", + name: "malformed", + givenRequest: openrtb2.BidRequest{Regs: &openrtb2.Regs{USPrivacy: "1", Ext: json.RawMessage(`malformed`)}}, + expectedErrType: &errortypes.FailedToUnmarshal{}, }, } @@ -343,8 +344,8 @@ func TestMoveUSPrivacyFrom26To25(t *testing.T) { w := &RequestWrapper{BidRequest: &test.givenRequest} err := moveUSPrivacyFrom26To25(w) - if len(test.expectedErr) > 0 { - assert.EqualError(t, err, test.expectedErr, "error") + if test.expectedErrType != nil { + assert.IsType(t, test.expectedErrType, err) } else { assert.NoError(t, w.RebuildRequest(), "error") assert.Equal(t, test.expectedRequest, *w.BidRequest, "result") @@ -364,7 +365,7 @@ func TestMoveEIDFrom26To25(t *testing.T) { name string givenRequest openrtb2.BidRequest expectedRequest openrtb2.BidRequest - expectedErr string + expectedErrType error }{ { name: "notpresent-user", @@ -392,9 +393,9 @@ func TestMoveEIDFrom26To25(t *testing.T) { expectedRequest: openrtb2.BidRequest{User: &openrtb2.User{Ext: eid1Json}}, }, { - name: "malformed", - givenRequest: openrtb2.BidRequest{User: &openrtb2.User{EIDs: eid1, Ext: json.RawMessage(`malformed`)}}, - expectedErr: "invalid character 'm' looking for beginning of value", + name: "malformed", + givenRequest: openrtb2.BidRequest{User: &openrtb2.User{EIDs: eid1, Ext: json.RawMessage(`malformed`)}}, + expectedErrType: &errortypes.FailedToUnmarshal{}, }, } @@ -403,8 +404,8 @@ func TestMoveEIDFrom26To25(t *testing.T) { w := &RequestWrapper{BidRequest: &test.givenRequest} err := moveEIDFrom26To25(w) - if len(test.expectedErr) > 0 { - assert.EqualError(t, err, test.expectedErr, "error") + if test.expectedErrType != nil { + assert.IsType(t, test.expectedErrType, err) } else { assert.NoError(t, w.RebuildRequest(), "error") assert.Equal(t, test.expectedRequest, *w.BidRequest, "result") @@ -415,10 +416,10 @@ func TestMoveEIDFrom26To25(t *testing.T) { func TestMoveRewardedFrom26ToPrebidExt(t *testing.T) { testCases := []struct { - name string - givenImp openrtb2.Imp - expectedImp openrtb2.Imp - expectedErr string + name string + givenImp openrtb2.Imp + expectedImp openrtb2.Imp + expectedErrType error }{ { name: "notpresent-prebid", @@ -436,9 +437,9 @@ func TestMoveRewardedFrom26ToPrebidExt(t *testing.T) { expectedImp: openrtb2.Imp{Ext: json.RawMessage(`{"prebid":{"is_rewarded_inventory":1}}`)}, }, { - name: "Malformed", - givenImp: openrtb2.Imp{Rwdd: 1, Ext: json.RawMessage(`malformed`)}, - expectedErr: "invalid character 'm' looking for beginning of value", + name: "Malformed", + givenImp: openrtb2.Imp{Rwdd: 1, Ext: json.RawMessage(`malformed`)}, + expectedErrType: &errortypes.FailedToUnmarshal{}, }, } @@ -447,8 +448,8 @@ func TestMoveRewardedFrom26ToPrebidExt(t *testing.T) { w := &ImpWrapper{Imp: &test.givenImp} err := moveRewardedFrom26ToPrebidExt(w) - if len(test.expectedErr) > 0 { - assert.EqualError(t, err, test.expectedErr, "error") + if test.expectedErrType != nil { + assert.IsType(t, test.expectedErrType, err) } else { assert.NoError(t, w.RebuildImp(), "error") assert.Equal(t, test.expectedImp, *w.Imp, "result") diff --git a/openrtb_ext/convert_up_test.go b/openrtb_ext/convert_up_test.go index d3ba034d07e..3cafe8c1612 100644 --- a/openrtb_ext/convert_up_test.go +++ b/openrtb_ext/convert_up_test.go @@ -20,7 +20,7 @@ func TestConvertUpTo26(t *testing.T) { givenRequest: openrtb2.BidRequest{ Ext: json.RawMessage(`malformed`), }, - expectedErr: "req.ext is invalid: invalid character 'm' looking for beginning of value", + expectedErr: "req.ext is invalid: expect { or n, but found m", }, { description: "2.4 -> 2.6", @@ -120,27 +120,27 @@ func TestConvertUpEnsureExt(t *testing.T) { { description: "Ext", givenRequest: openrtb2.BidRequest{Ext: json.RawMessage("malformed")}, - expectedErr: "req.ext is invalid: invalid character 'm' looking for beginning of value", + expectedErr: "req.ext is invalid: expect { or n, but found m", }, { description: "Source.Ext", givenRequest: openrtb2.BidRequest{Source: &openrtb2.Source{Ext: json.RawMessage("malformed")}}, - expectedErr: "req.source.ext is invalid: invalid character 'm' looking for beginning of value", + expectedErr: "req.source.ext is invalid: expect { or n, but found m", }, { description: "Regs.Ext", givenRequest: openrtb2.BidRequest{Regs: &openrtb2.Regs{Ext: json.RawMessage("malformed")}}, - expectedErr: "req.regs.ext is invalid: invalid character 'm' looking for beginning of value", + expectedErr: "req.regs.ext is invalid: expect { or n, but found m", }, { description: "User.Ext", givenRequest: openrtb2.BidRequest{User: &openrtb2.User{Ext: json.RawMessage("malformed")}}, - expectedErr: "req.user.ext is invalid: invalid character 'm' looking for beginning of value", + expectedErr: "req.user.ext is invalid: expect { or n, but found m", }, { description: "Imp.Ext", givenRequest: openrtb2.BidRequest{Imp: []openrtb2.Imp{{Ext: json.RawMessage("malformed")}}}, - expectedErr: "imp[0].imp.ext is invalid: invalid character 'm' looking for beginning of value", + expectedErr: "imp[0].imp.ext is invalid: expect { or n, but found m", }, } diff --git a/openrtb_ext/deal_tier.go b/openrtb_ext/deal_tier.go index 45285d21663..df386916b77 100644 --- a/openrtb_ext/deal_tier.go +++ b/openrtb_ext/deal_tier.go @@ -1,9 +1,8 @@ package openrtb_ext import ( - "encoding/json" - "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/util/jsonutil" ) // DealTier defines the configuration of a deal tier. @@ -34,7 +33,7 @@ func ReadDealTiersFromImp(imp openrtb2.Imp) (DealTierBidderMap, error) { } `json:"bidder"` } `json:"prebid"` } - if err := json.Unmarshal(imp.Ext, &impPrebidExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &impPrebidExt); err != nil { return nil, err } for bidder, param := range impPrebidExt.Prebid.Bidders { diff --git a/openrtb_ext/deal_tier_test.go b/openrtb_ext/deal_tier_test.go index 0046b788ece..dabecf6a9e7 100644 --- a/openrtb_ext/deal_tier_test.go +++ b/openrtb_ext/deal_tier_test.go @@ -5,15 +5,16 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/errortypes" "github.com/stretchr/testify/assert" ) func TestReadDealTiersFromImp(t *testing.T) { testCases := []struct { - description string - impExt json.RawMessage - expectedResult DealTierBidderMap - expectedError string + description string + impExt json.RawMessage + expectedResult DealTierBidderMap + expectedErrorType error }{ { description: "Nil", @@ -71,9 +72,9 @@ func TestReadDealTiersFromImp(t *testing.T) { expectedResult: DealTierBidderMap{}, }, { - description: "imp.ext.prebid.bidder - error", - impExt: json.RawMessage(`{"prebid": {"bidder": {"appnexus": {"dealTier": "wrong type", "placementId": 12345}}}}`), - expectedError: "json: cannot unmarshal string into Go struct field .prebid.bidder.dealTier of type openrtb_ext.DealTier", + description: "imp.ext.prebid.bidder - error", + impExt: json.RawMessage(`{"prebid": {"bidder": {"appnexus": {"dealTier": "wrong type", "placementId": 12345}}}}`), + expectedErrorType: &errortypes.FailedToUnmarshal{}, }, } @@ -84,10 +85,10 @@ func TestReadDealTiersFromImp(t *testing.T) { assert.Equal(t, test.expectedResult, result, test.description+":result") - if len(test.expectedError) == 0 { - assert.NoError(t, err, test.description+":error") + if test.expectedErrorType != nil { + assert.IsType(t, test.expectedErrorType, err) } else { - assert.EqualError(t, err, test.expectedError, test.description+":error") + assert.NoError(t, err, test.description+":error") } } } diff --git a/openrtb_ext/device_test.go b/openrtb_ext/device_test.go index 1a3dbe8e2f4..86a0e1d7ff2 100644 --- a/openrtb_ext/device_test.go +++ b/openrtb_ext/device_test.go @@ -4,30 +4,31 @@ import ( "encoding/json" "testing" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/stretchr/testify/assert" ) func TestInvalidDeviceExt(t *testing.T) { var s ExtDevice - assert.EqualError(t, json.Unmarshal([]byte(`{"prebid":{"interstitial":{"minheightperc":0}}}`), &s), "request.device.ext.prebid.interstitial.minwidthperc must be a number between 0 and 100") - assert.EqualError(t, json.Unmarshal([]byte(`{"prebid":{"interstitial":{"minwidthperc":105}}}`), &s), "request.device.ext.prebid.interstitial.minwidthperc must be a number between 0 and 100") - assert.EqualError(t, json.Unmarshal([]byte(`{"prebid":{"interstitial":{"minwidthperc":true,"minheightperc":0}}}`), &s), "request.device.ext.prebid.interstitial.minwidthperc must be a number between 0 and 100") - assert.EqualError(t, json.Unmarshal([]byte(`{"prebid":{"interstitial":{"minwidthperc":null,"minheightperc":0}}}`), &s), "request.device.ext.prebid.interstitial.minwidthperc must be a number between 0 and 100") - assert.EqualError(t, json.Unmarshal([]byte(`{"prebid":{"interstitial":{"minwidthperc":"75","minheightperc":0}}}`), &s), "request.device.ext.prebid.interstitial.minwidthperc must be a number between 0 and 100") + assert.EqualError(t, jsonutil.UnmarshalValid([]byte(`{"prebid":{"interstitial":{"minheightperc":0}}}`), &s), "request.device.ext.prebid.interstitial.minwidthperc must be a number between 0 and 100") + assert.EqualError(t, jsonutil.UnmarshalValid([]byte(`{"prebid":{"interstitial":{"minwidthperc":105}}}`), &s), "request.device.ext.prebid.interstitial.minwidthperc must be a number between 0 and 100") + assert.EqualError(t, jsonutil.UnmarshalValid([]byte(`{"prebid":{"interstitial":{"minwidthperc":true,"minheightperc":0}}}`), &s), "request.device.ext.prebid.interstitial.minwidthperc must be a number between 0 and 100") + assert.EqualError(t, jsonutil.UnmarshalValid([]byte(`{"prebid":{"interstitial":{"minwidthperc":null,"minheightperc":0}}}`), &s), "request.device.ext.prebid.interstitial.minwidthperc must be a number between 0 and 100") + assert.EqualError(t, jsonutil.UnmarshalValid([]byte(`{"prebid":{"interstitial":{"minwidthperc":"75","minheightperc":0}}}`), &s), "request.device.ext.prebid.interstitial.minwidthperc must be a number between 0 and 100") - assert.EqualError(t, json.Unmarshal([]byte(`{"prebid":{"interstitial":{"minwidthperc":85}}}`), &s), "request.device.ext.prebid.interstitial.minheightperc must be a number between 0 and 100") - assert.EqualError(t, json.Unmarshal([]byte(`{"prebid":{"interstitial":{"minwidthperc":85,"minheightperc":-5}}}`), &s), "request.device.ext.prebid.interstitial.minheightperc must be a number between 0 and 100") - assert.EqualError(t, json.Unmarshal([]byte(`{"prebid":{"interstitial":{"minwidthperc":85,"minheightperc":false}}}`), &s), "request.device.ext.prebid.interstitial.minheightperc must be a number between 0 and 100") - assert.EqualError(t, json.Unmarshal([]byte(`{"prebid":{"interstitial":{"minwidthperc":85,"minheightperc":"75"}}}`), &s), "request.device.ext.prebid.interstitial.minheightperc must be a number between 0 and 100") + assert.EqualError(t, jsonutil.UnmarshalValid([]byte(`{"prebid":{"interstitial":{"minwidthperc":85}}}`), &s), "request.device.ext.prebid.interstitial.minheightperc must be a number between 0 and 100") + assert.EqualError(t, jsonutil.UnmarshalValid([]byte(`{"prebid":{"interstitial":{"minwidthperc":85,"minheightperc":-5}}}`), &s), "request.device.ext.prebid.interstitial.minheightperc must be a number between 0 and 100") + assert.EqualError(t, jsonutil.UnmarshalValid([]byte(`{"prebid":{"interstitial":{"minwidthperc":85,"minheightperc":false}}}`), &s), "request.device.ext.prebid.interstitial.minheightperc must be a number between 0 and 100") + assert.EqualError(t, jsonutil.UnmarshalValid([]byte(`{"prebid":{"interstitial":{"minwidthperc":85,"minheightperc":"75"}}}`), &s), "request.device.ext.prebid.interstitial.minheightperc must be a number between 0 and 100") } func TestValidDeviceExt(t *testing.T) { var s ExtDevice - assert.NoError(t, json.Unmarshal([]byte(`{"prebid":{}}`), &s)) + assert.NoError(t, jsonutil.UnmarshalValid([]byte(`{"prebid":{}}`), &s)) assert.Nil(t, s.Prebid.Interstitial) - assert.NoError(t, json.Unmarshal([]byte(`{}`), &s)) + assert.NoError(t, jsonutil.UnmarshalValid([]byte(`{}`), &s)) assert.Nil(t, s.Prebid.Interstitial) - assert.NoError(t, json.Unmarshal([]byte(`{"prebid":{"interstitial":{"minwidthperc":75,"minheightperc":60}}}`), &s)) + assert.NoError(t, jsonutil.UnmarshalValid([]byte(`{"prebid":{"interstitial":{"minwidthperc":75,"minheightperc":60}}}`), &s)) assert.EqualValues(t, 75, s.Prebid.Interstitial.MinWidthPerc) assert.EqualValues(t, 60, s.Prebid.Interstitial.MinHeightPerc) } diff --git a/openrtb_ext/imp_appnexus.go b/openrtb_ext/imp_appnexus.go index d9549e74750..02476d6bcf0 100644 --- a/openrtb_ext/imp_appnexus.go +++ b/openrtb_ext/imp_appnexus.go @@ -45,7 +45,7 @@ func (ks *ExtImpAppnexusKeywords) UnmarshalJSON(b []byte) error { switch b[0] { case '{': var results map[string][]string - if err := json.Unmarshal(b, &results); err != nil { + if err := jsonutil.UnmarshalValid(b, &results); err != nil { return err } @@ -64,7 +64,7 @@ func (ks *ExtImpAppnexusKeywords) UnmarshalJSON(b []byte) error { } case '[': var results []extImpAppnexusKeyVal - if err := json.Unmarshal(b, &results); err != nil { + if err := jsonutil.UnmarshalValid(b, &results); err != nil { return err } var kvs strings.Builder @@ -82,7 +82,7 @@ func (ks *ExtImpAppnexusKeywords) UnmarshalJSON(b []byte) error { } case '"': var keywords string - if err := json.Unmarshal(b, &keywords); err != nil { + if err := jsonutil.UnmarshalValid(b, &keywords); err != nil { return err } *ks = ExtImpAppnexusKeywords(keywords) diff --git a/openrtb_ext/imp_appnexus_test.go b/openrtb_ext/imp_appnexus_test.go index cbd6779d5da..a226c0d8410 100644 --- a/openrtb_ext/imp_appnexus_test.go +++ b/openrtb_ext/imp_appnexus_test.go @@ -1,9 +1,9 @@ package openrtb_ext import ( - "encoding/json" "testing" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/stretchr/testify/assert" ) @@ -31,7 +31,7 @@ func TestKeywordsUnmarshalJSON(t *testing.T) { for _, test := range validTestCases { var keywords keywords - assert.NoError(t, json.Unmarshal(test.input, &keywords), test.desc) + assert.NoError(t, jsonutil.UnmarshalValid(test.input, &keywords), test.desc) assert.Equal(t, test.expected, keywords.Keywords.String()) } @@ -42,6 +42,6 @@ func TestKeywordsUnmarshalJSON(t *testing.T) { for _, test := range invalidTestCases { var keywords keywords - assert.Error(t, json.Unmarshal(test.input, &keywords), test.desc) + assert.Error(t, jsonutil.UnmarshalValid(test.input, &keywords), test.desc) } } diff --git a/openrtb_ext/request.go b/openrtb_ext/request.go index f5418ba4d1f..3a41fdf0dbb 100644 --- a/openrtb_ext/request.go +++ b/openrtb_ext/request.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/util/maputil" "github.com/prebid/prebid-server/util/ptrutil" "github.com/prebid/prebid-server/util/sliceutil" @@ -234,7 +235,7 @@ func (pg *PriceGranularity) UnmarshalJSON(b []byte) error { // price granularity used to be a string referencing a predefined value, try to parse // and map the legacy string before falling back to the modern custom model. legacyID := "" - if err := json.Unmarshal(b, &legacyID); err == nil { + if err := jsonutil.Unmarshal(b, &legacyID); err == nil { if legacyValue, ok := NewPriceGranularityFromLegacyID(legacyID); ok { *pg = legacyValue return nil @@ -243,7 +244,7 @@ func (pg *PriceGranularity) UnmarshalJSON(b []byte) error { // use a type-alias to avoid calling back into this UnmarshalJSON implementation modernValue := PriceGranularityRaw{} - err := json.Unmarshal(b, &modernValue) + err := jsonutil.Unmarshal(b, &modernValue) if err == nil { *pg = (PriceGranularity)(modernValue) } diff --git a/openrtb_ext/request_test.go b/openrtb_ext/request_test.go index a05bae3a6bf..ad6a655b022 100644 --- a/openrtb_ext/request_test.go +++ b/openrtb_ext/request_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/util/ptrutil" "github.com/stretchr/testify/assert" ) @@ -37,7 +38,7 @@ func TestGranularityUnmarshal(t *testing.T) { for _, tg := range testGroups { for i, tc := range tg.in { var resolved PriceGranularity - err := json.Unmarshal(tc.json, &resolved) + err := jsonutil.UnmarshalValid(tc.json, &resolved) // Assert validation error if tg.expectError && !assert.Errorf(t, err, "%s test case %d", tg.desc, i) { diff --git a/openrtb_ext/request_wrapper.go b/openrtb_ext/request_wrapper.go index f4ef69b0523..09321e5b0b3 100644 --- a/openrtb_ext/request_wrapper.go +++ b/openrtb_ext/request_wrapper.go @@ -5,6 +5,7 @@ import ( "errors" "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/util/maputil" "github.com/prebid/prebid-server/util/ptrutil" "github.com/prebid/prebid-server/util/sliceutil" @@ -440,13 +441,13 @@ func (ue *UserExt) unmarshal(extJson json.RawMessage) error { return nil } - if err := json.Unmarshal(extJson, &ue.ext); err != nil { + if err := jsonutil.Unmarshal(extJson, &ue.ext); err != nil { return err } consentJson, hasConsent := ue.ext[consentKey] - if hasConsent { - if err := json.Unmarshal(consentJson, &ue.consent); err != nil { + if hasConsent && consentJson != nil { + if err := jsonutil.Unmarshal(consentJson, &ue.consent); err != nil { return err } } @@ -454,7 +455,9 @@ func (ue *UserExt) unmarshal(extJson json.RawMessage) error { prebidJson, hasPrebid := ue.ext[prebidKey] if hasPrebid { ue.prebid = &ExtUserPrebid{} - if err := json.Unmarshal(prebidJson, ue.prebid); err != nil { + } + if prebidJson != nil { + if err := jsonutil.Unmarshal(prebidJson, ue.prebid); err != nil { return err } } @@ -462,21 +465,29 @@ func (ue *UserExt) unmarshal(extJson json.RawMessage) error { eidsJson, hasEids := ue.ext[eidsKey] if hasEids { ue.eids = &[]openrtb2.EID{} - if err := json.Unmarshal(eidsJson, ue.eids); err != nil { + } + if eidsJson != nil { + if err := jsonutil.Unmarshal(eidsJson, ue.eids); err != nil { return err } } - if consentedProviderSettingsJson, hasCPSettings := ue.ext[consentedProvidersSettingsStringKey]; hasCPSettings { + consentedProviderSettingsInJson, hasCPSettingsIn := ue.ext[consentedProvidersSettingsStringKey] + if hasCPSettingsIn { ue.consentedProvidersSettingsIn = &ConsentedProvidersSettingsIn{} - if err := json.Unmarshal(consentedProviderSettingsJson, ue.consentedProvidersSettingsIn); err != nil { + } + if consentedProviderSettingsInJson != nil { + if err := jsonutil.Unmarshal(consentedProviderSettingsInJson, ue.consentedProvidersSettingsIn); err != nil { return err } } - if consentedProviderSettingsJson, hasCPSettings := ue.ext[consentedProvidersSettingsListKey]; hasCPSettings { + consentedProviderSettingsOutJson, hasCPSettingsOut := ue.ext[consentedProvidersSettingsListKey] + if hasCPSettingsOut { ue.consentedProvidersSettingsOut = &ConsentedProvidersSettingsOut{} - if err := json.Unmarshal(consentedProviderSettingsJson, ue.consentedProvidersSettingsOut); err != nil { + } + if consentedProviderSettingsOutJson != nil { + if err := jsonutil.Unmarshal(consentedProviderSettingsOutJson, ue.consentedProvidersSettingsOut); err != nil { return err } } @@ -487,7 +498,7 @@ func (ue *UserExt) unmarshal(extJson json.RawMessage) error { func (ue *UserExt) marshal() (json.RawMessage, error) { if ue.consentDirty { if ue.consent != nil && len(*ue.consent) > 0 { - consentJson, err := json.Marshal(ue.consent) + consentJson, err := jsonutil.Marshal(ue.consent) if err != nil { return nil, err } @@ -500,7 +511,7 @@ func (ue *UserExt) marshal() (json.RawMessage, error) { if ue.prebidDirty { if ue.prebid != nil { - prebidJson, err := json.Marshal(ue.prebid) + prebidJson, err := jsonutil.Marshal(ue.prebid) if err != nil { return nil, err } @@ -517,7 +528,7 @@ func (ue *UserExt) marshal() (json.RawMessage, error) { if ue.consentedProvidersSettingsInDirty { if ue.consentedProvidersSettingsIn != nil { - cpSettingsJson, err := json.Marshal(ue.consentedProvidersSettingsIn) + cpSettingsJson, err := jsonutil.Marshal(ue.consentedProvidersSettingsIn) if err != nil { return nil, err } @@ -534,7 +545,7 @@ func (ue *UserExt) marshal() (json.RawMessage, error) { if ue.consentedProvidersSettingsOutDirty { if ue.consentedProvidersSettingsOut != nil { - cpSettingsJson, err := json.Marshal(ue.consentedProvidersSettingsOut) + cpSettingsJson, err := jsonutil.Marshal(ue.consentedProvidersSettingsOut) if err != nil { return nil, err } @@ -551,7 +562,7 @@ func (ue *UserExt) marshal() (json.RawMessage, error) { if ue.eidsDirty { if ue.eids != nil && len(*ue.eids) > 0 { - eidsJson, err := json.Marshal(ue.eids) + eidsJson, err := jsonutil.Marshal(ue.eids) if err != nil { return nil, err } @@ -566,7 +577,7 @@ func (ue *UserExt) marshal() (json.RawMessage, error) { if len(ue.ext) == 0 { return nil, nil } - return json.Marshal(ue.ext) + return jsonutil.Marshal(ue.ext) } func (ue *UserExt) Dirty() bool { @@ -726,14 +737,16 @@ func (re *RequestExt) unmarshal(extJson json.RawMessage) error { return nil } - if err := json.Unmarshal(extJson, &re.ext); err != nil { + if err := jsonutil.Unmarshal(extJson, &re.ext); err != nil { return err } prebidJson, hasPrebid := re.ext[prebidKey] if hasPrebid { re.prebid = &ExtRequestPrebid{} - if err := json.Unmarshal(prebidJson, re.prebid); err != nil { + } + if prebidJson != nil { + if err := jsonutil.Unmarshal(prebidJson, re.prebid); err != nil { return err } } @@ -741,7 +754,9 @@ func (re *RequestExt) unmarshal(extJson json.RawMessage) error { schainJson, hasSChain := re.ext[schainKey] if hasSChain { re.schain = &openrtb2.SupplyChain{} - if err := json.Unmarshal(schainJson, re.schain); err != nil { + } + if schainJson != nil { + if err := jsonutil.Unmarshal(schainJson, re.schain); err != nil { return err } } @@ -752,7 +767,7 @@ func (re *RequestExt) unmarshal(extJson json.RawMessage) error { func (re *RequestExt) marshal() (json.RawMessage, error) { if re.prebidDirty { if re.prebid != nil { - prebidJson, err := json.Marshal(re.prebid) + prebidJson, err := jsonutil.Marshal(re.prebid) if err != nil { return nil, err } @@ -769,7 +784,7 @@ func (re *RequestExt) marshal() (json.RawMessage, error) { if re.schainDirty { if re.schain != nil { - schainJson, err := json.Marshal(re.schain) + schainJson, err := jsonutil.Marshal(re.schain) if err != nil { return nil, err } @@ -788,7 +803,7 @@ func (re *RequestExt) marshal() (json.RawMessage, error) { if len(re.ext) == 0 { return nil, nil } - return json.Marshal(re.ext) + return jsonutil.Marshal(re.ext) } func (re *RequestExt) Dirty() bool { @@ -880,14 +895,16 @@ func (de *DeviceExt) unmarshal(extJson json.RawMessage) error { return nil } - if err := json.Unmarshal(extJson, &de.ext); err != nil { + if err := jsonutil.Unmarshal(extJson, &de.ext); err != nil { return err } prebidJson, hasPrebid := de.ext[prebidKey] if hasPrebid { de.prebid = &ExtDevicePrebid{} - if err := json.Unmarshal(prebidJson, de.prebid); err != nil { + } + if prebidJson != nil { + if err := jsonutil.Unmarshal(prebidJson, de.prebid); err != nil { return err } } @@ -898,7 +915,7 @@ func (de *DeviceExt) unmarshal(extJson json.RawMessage) error { func (de *DeviceExt) marshal() (json.RawMessage, error) { if de.prebidDirty { if de.prebid != nil { - prebidJson, err := json.Marshal(de.prebid) + prebidJson, err := jsonutil.Marshal(de.prebid) if err != nil { return nil, err } @@ -917,7 +934,7 @@ func (de *DeviceExt) marshal() (json.RawMessage, error) { if len(de.ext) == 0 { return nil, nil } - return json.Marshal(de.ext) + return jsonutil.Marshal(de.ext) } func (de *DeviceExt) Dirty() bool { @@ -992,14 +1009,16 @@ func (ae *AppExt) unmarshal(extJson json.RawMessage) error { return nil } - if err := json.Unmarshal(extJson, &ae.ext); err != nil { + if err := jsonutil.Unmarshal(extJson, &ae.ext); err != nil { return err } prebidJson, hasPrebid := ae.ext[prebidKey] if hasPrebid { ae.prebid = &ExtAppPrebid{} - if err := json.Unmarshal(prebidJson, ae.prebid); err != nil { + } + if prebidJson != nil { + if err := jsonutil.Unmarshal(prebidJson, ae.prebid); err != nil { return err } } @@ -1010,7 +1029,7 @@ func (ae *AppExt) unmarshal(extJson json.RawMessage) error { func (ae *AppExt) marshal() (json.RawMessage, error) { if ae.prebidDirty { if ae.prebid != nil { - prebidJson, err := json.Marshal(ae.prebid) + prebidJson, err := jsonutil.Marshal(ae.prebid) if err != nil { return nil, err } @@ -1029,7 +1048,7 @@ func (ae *AppExt) marshal() (json.RawMessage, error) { if len(ae.ext) == 0 { return nil, nil } - return json.Marshal(ae.ext) + return jsonutil.Marshal(ae.ext) } func (ae *AppExt) Dirty() bool { @@ -1096,7 +1115,7 @@ func (de *DOOHExt) unmarshal(extJson json.RawMessage) error { return nil } - if err := json.Unmarshal(extJson, &de.ext); err != nil { + if err := jsonutil.Unmarshal(extJson, &de.ext); err != nil { return err } @@ -1108,7 +1127,7 @@ func (de *DOOHExt) marshal() (json.RawMessage, error) { if len(de.ext) == 0 { return nil, nil } - return json.Marshal(de.ext) + return jsonutil.Marshal(de.ext) } func (de *DOOHExt) Dirty() bool { @@ -1163,20 +1182,20 @@ func (re *RegExt) unmarshal(extJson json.RawMessage) error { return nil } - if err := json.Unmarshal(extJson, &re.ext); err != nil { + if err := jsonutil.Unmarshal(extJson, &re.ext); err != nil { return err } gdprJson, hasGDPR := re.ext[gdprKey] - if hasGDPR { - if err := json.Unmarshal(gdprJson, &re.gdpr); err != nil { + if hasGDPR && gdprJson != nil { + if err := jsonutil.Unmarshal(gdprJson, &re.gdpr); err != nil { return errors.New("gdpr must be an integer") } } uspJson, hasUsp := re.ext[us_privacyKey] - if hasUsp { - if err := json.Unmarshal(uspJson, &re.usPrivacy); err != nil { + if hasUsp && uspJson != nil { + if err := jsonutil.Unmarshal(uspJson, &re.usPrivacy); err != nil { return err } } @@ -1187,7 +1206,7 @@ func (re *RegExt) unmarshal(extJson json.RawMessage) error { func (re *RegExt) marshal() (json.RawMessage, error) { if re.gdprDirty { if re.gdpr != nil { - rawjson, err := json.Marshal(re.gdpr) + rawjson, err := jsonutil.Marshal(re.gdpr) if err != nil { return nil, err } @@ -1200,7 +1219,7 @@ func (re *RegExt) marshal() (json.RawMessage, error) { if re.usPrivacyDirty { if len(re.usPrivacy) > 0 { - rawjson, err := json.Marshal(re.usPrivacy) + rawjson, err := jsonutil.Marshal(re.usPrivacy) if err != nil { return nil, err } @@ -1215,7 +1234,7 @@ func (re *RegExt) marshal() (json.RawMessage, error) { if len(re.ext) == 0 { return nil, nil } - return json.Marshal(re.ext) + return jsonutil.Marshal(re.ext) } func (re *RegExt) Dirty() bool { @@ -1290,13 +1309,13 @@ func (se *SiteExt) unmarshal(extJson json.RawMessage) error { return nil } - if err := json.Unmarshal(extJson, &se.ext); err != nil { + if err := jsonutil.Unmarshal(extJson, &se.ext); err != nil { return err } ampJson, hasAmp := se.ext[ampKey] - if hasAmp { - if err := json.Unmarshal(ampJson, &se.amp); err != nil { + if hasAmp && ampJson != nil { + if err := jsonutil.Unmarshal(ampJson, &se.amp); err != nil { return errors.New(`request.site.ext.amp must be either 1, 0, or undefined`) } } @@ -1307,7 +1326,7 @@ func (se *SiteExt) unmarshal(extJson json.RawMessage) error { func (se *SiteExt) marshal() (json.RawMessage, error) { if se.ampDirty { if se.amp != nil { - ampJson, err := json.Marshal(se.amp) + ampJson, err := jsonutil.Marshal(se.amp) if err != nil { return nil, err } @@ -1322,7 +1341,7 @@ func (se *SiteExt) marshal() (json.RawMessage, error) { if len(se.ext) == 0 { return nil, nil } - return json.Marshal(se.ext) + return jsonutil.Marshal(se.ext) } func (se *SiteExt) Dirty() bool { @@ -1385,13 +1404,13 @@ func (se *SourceExt) unmarshal(extJson json.RawMessage) error { return nil } - if err := json.Unmarshal(extJson, &se.ext); err != nil { + if err := jsonutil.Unmarshal(extJson, &se.ext); err != nil { return err } schainJson, hasSChain := se.ext[schainKey] - if hasSChain { - if err := json.Unmarshal(schainJson, &se.schain); err != nil { + if hasSChain && schainJson != nil { + if err := jsonutil.Unmarshal(schainJson, &se.schain); err != nil { return err } } @@ -1402,7 +1421,7 @@ func (se *SourceExt) unmarshal(extJson json.RawMessage) error { func (se *SourceExt) marshal() (json.RawMessage, error) { if se.schainDirty { if se.schain != nil { - schainJson, err := json.Marshal(se.schain) + schainJson, err := jsonutil.Marshal(se.schain) if err != nil { return nil, err } @@ -1421,7 +1440,7 @@ func (se *SourceExt) marshal() (json.RawMessage, error) { if len(se.ext) == 0 { return nil, nil } - return json.Marshal(se.ext) + return jsonutil.Marshal(se.ext) } func (se *SourceExt) Dirty() bool { @@ -1550,14 +1569,16 @@ func (e *ImpExt) unmarshal(extJson json.RawMessage) error { return nil } - if err := json.Unmarshal(extJson, &e.ext); err != nil { + if err := jsonutil.Unmarshal(extJson, &e.ext); err != nil { return err } prebidJson, hasPrebid := e.ext[prebidKey] if hasPrebid { e.prebid = &ExtImpPrebid{} - if err := json.Unmarshal(prebidJson, e.prebid); err != nil { + } + if prebidJson != nil { + if err := jsonutil.Unmarshal(prebidJson, e.prebid); err != nil { return err } } @@ -1565,21 +1586,23 @@ func (e *ImpExt) unmarshal(extJson json.RawMessage) error { dataJson, hasData := e.ext[dataKey] if hasData { e.data = &ExtImpData{} - if err := json.Unmarshal(dataJson, e.data); err != nil { + } + if dataJson != nil { + if err := jsonutil.Unmarshal(dataJson, e.data); err != nil { return err } } tidJson, hasTid := e.ext["tid"] - if hasTid { - if err := json.Unmarshal(tidJson, &e.tid); err != nil { + if hasTid && tidJson != nil { + if err := jsonutil.Unmarshal(tidJson, &e.tid); err != nil { return err } } gpIdJson, hasGpId := e.ext["gpid"] - if hasGpId { - if err := json.Unmarshal(gpIdJson, &e.gpId); err != nil { + if hasGpId && gpIdJson != nil { + if err := jsonutil.Unmarshal(gpIdJson, &e.gpId); err != nil { return err } } @@ -1590,7 +1613,7 @@ func (e *ImpExt) unmarshal(extJson json.RawMessage) error { func (e *ImpExt) marshal() (json.RawMessage, error) { if e.prebidDirty { if e.prebid != nil { - prebidJson, err := json.Marshal(e.prebid) + prebidJson, err := jsonutil.Marshal(e.prebid) if err != nil { return nil, err } @@ -1607,7 +1630,7 @@ func (e *ImpExt) marshal() (json.RawMessage, error) { if e.tidDirty { if len(e.tid) > 0 { - tidJson, err := json.Marshal(e.tid) + tidJson, err := jsonutil.Marshal(e.tid) if err != nil { return nil, err } @@ -1622,7 +1645,7 @@ func (e *ImpExt) marshal() (json.RawMessage, error) { if len(e.ext) == 0 { return nil, nil } - return json.Marshal(e.ext) + return jsonutil.Marshal(e.ext) } func (e *ImpExt) Dirty() bool { diff --git a/openrtb_ext/request_wrapper_test.go b/openrtb_ext/request_wrapper_test.go index afa047e6909..0127c545274 100644 --- a/openrtb_ext/request_wrapper_test.go +++ b/openrtb_ext/request_wrapper_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/util/ptrutil" "github.com/stretchr/testify/assert" ) @@ -1792,10 +1793,10 @@ func TestImpWrapperGetImpExt(t *testing.T) { var isRewardedInventoryOne int8 = 1 testCases := []struct { - description string - givenWrapper ImpWrapper - expectedImpExt ImpExt - expectedError string + description string + givenWrapper ImpWrapper + expectedImpExt ImpExt + expectedErrorType error }{ { description: "Empty", @@ -1833,21 +1834,21 @@ func TestImpWrapperGetImpExt(t *testing.T) { expectedImpExt: ImpExt{ext: map[string]json.RawMessage{"foo": json.RawMessage("bar")}}, }, { - description: "Error - Ext", - givenWrapper: ImpWrapper{Imp: &openrtb2.Imp{Ext: json.RawMessage(`malformed`)}}, - expectedError: "invalid character 'm' looking for beginning of value", + description: "Error - Ext", + givenWrapper: ImpWrapper{Imp: &openrtb2.Imp{Ext: json.RawMessage(`malformed`)}}, + expectedErrorType: &errortypes.FailedToUnmarshal{}, }, { - description: "Error - Ext - Prebid", - givenWrapper: ImpWrapper{Imp: &openrtb2.Imp{Ext: json.RawMessage(`{"prebid":malformed}`)}}, - expectedError: "invalid character 'm' looking for beginning of value", + description: "Error - Ext - Prebid", + givenWrapper: ImpWrapper{Imp: &openrtb2.Imp{Ext: json.RawMessage(`{"prebid":malformed}`)}}, + expectedErrorType: &errortypes.FailedToUnmarshal{}, }, } for _, test := range testCases { impExt, err := test.givenWrapper.GetImpExt() - if test.expectedError != "" { - assert.EqualError(t, err, test.expectedError, test.description) + if test.expectedErrorType != nil { + assert.IsType(t, test.expectedErrorType, err) } else { assert.NoError(t, err, test.description) assert.Equal(t, test.expectedImpExt, *impExt, test.description) diff --git a/openrtb_ext/site_test.go b/openrtb_ext/site_test.go index 67ec6cc4f99..7a7140282f2 100644 --- a/openrtb_ext/site_test.go +++ b/openrtb_ext/site_test.go @@ -1,28 +1,28 @@ package openrtb_ext_test import ( - "encoding/json" "testing" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/stretchr/testify/assert" ) func TestInvalidSiteExt(t *testing.T) { var s openrtb_ext.ExtSite - assert.EqualError(t, json.Unmarshal([]byte(`{"amp":-1}`), &s), "request.site.ext.amp must be either 1, 0, or undefined") - assert.EqualError(t, json.Unmarshal([]byte(`{"amp":2}`), &s), "request.site.ext.amp must be either 1, 0, or undefined") - assert.EqualError(t, json.Unmarshal([]byte(`{"amp":true}`), &s), "request.site.ext.amp must be either 1, 0, or undefined") - assert.EqualError(t, json.Unmarshal([]byte(`{"amp":null}`), &s), "request.site.ext.amp must be either 1, 0, or undefined") - assert.EqualError(t, json.Unmarshal([]byte(`{"amp":"1"}`), &s), "request.site.ext.amp must be either 1, 0, or undefined") + assert.EqualError(t, jsonutil.UnmarshalValid([]byte(`{"amp":-1}`), &s), "request.site.ext.amp must be either 1, 0, or undefined") + assert.EqualError(t, jsonutil.UnmarshalValid([]byte(`{"amp":2}`), &s), "request.site.ext.amp must be either 1, 0, or undefined") + assert.EqualError(t, jsonutil.UnmarshalValid([]byte(`{"amp":true}`), &s), "request.site.ext.amp must be either 1, 0, or undefined") + assert.EqualError(t, jsonutil.UnmarshalValid([]byte(`{"amp":null}`), &s), "request.site.ext.amp must be either 1, 0, or undefined") + assert.EqualError(t, jsonutil.UnmarshalValid([]byte(`{"amp":"1"}`), &s), "request.site.ext.amp must be either 1, 0, or undefined") } func TestValidSiteExt(t *testing.T) { var s openrtb_ext.ExtSite - assert.NoError(t, json.Unmarshal([]byte(`{"amp":0}`), &s)) + assert.NoError(t, jsonutil.UnmarshalValid([]byte(`{"amp":0}`), &s)) assert.EqualValues(t, 0, s.AMP) - assert.NoError(t, json.Unmarshal([]byte(`{"amp":1}`), &s)) + assert.NoError(t, jsonutil.UnmarshalValid([]byte(`{"amp":1}`), &s)) assert.EqualValues(t, 1, s.AMP) - assert.NoError(t, json.Unmarshal([]byte(`{"amp": 1 }`), &s)) + assert.NoError(t, jsonutil.UnmarshalValid([]byte(`{"amp": 1 }`), &s)) assert.EqualValues(t, 1, s.AMP) } diff --git a/ortb/default_test.go b/ortb/default_test.go index 04eeeebdcb6..8bda02ef4f5 100644 --- a/ortb/default_test.go +++ b/ortb/default_test.go @@ -8,7 +8,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/util/ptrutil" ) @@ -31,7 +33,7 @@ func TestSetDefaults(t *testing.T) { name: "malformed request.ext", givenRequest: openrtb2.BidRequest{Ext: json.RawMessage(`malformed`)}, expectedRequest: openrtb2.BidRequest{Ext: json.RawMessage(`malformed`)}, - expectedErr: "invalid character 'm' looking for beginning of value", + expectedErr: "expect { or n, but found m", }, { name: "targeting", // tests integration with setDefaultsTargeting @@ -55,6 +57,7 @@ func TestSetDefaults(t *testing.T) { // assert error if len(test.expectedErr) > 0 { assert.EqualError(t, err, test.expectedErr, "Error") + assert.IsType(t, &errortypes.FailedToUnmarshal{}, err) } // rebuild request @@ -66,10 +69,10 @@ func TestSetDefaults(t *testing.T) { assert.Equal(t, &test.expectedRequest, wrapper.BidRequest, "Request") } else { // assert request as json to ignore order in ext fields - expectedRequestJSON, err := json.Marshal(test.expectedRequest) + expectedRequestJSON, err := jsonutil.Marshal(test.expectedRequest) require.NoError(t, err, "Marshal Expected Request") - actualRequestJSON, err := json.Marshal(wrapper.BidRequest) + actualRequestJSON, err := jsonutil.Marshal(wrapper.BidRequest) require.NoError(t, err, "Marshal Actual Request") assert.JSONEq(t, string(expectedRequestJSON), string(actualRequestJSON), "Request") diff --git a/prebid_cache_client/client_test.go b/prebid_cache_client/client_test.go index ec390364849..f20d3c7829f 100644 --- a/prebid_cache_client/client_test.go +++ b/prebid_cache_client/client_test.go @@ -13,6 +13,7 @@ import ( "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/metrics" metricsConf "github.com/prebid/prebid-server/metrics/config" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -297,7 +298,7 @@ func newHandler(numResponses int) http.HandlerFunc { resp.Responses[i].UUID = strconv.Itoa(i) } - respBytes, _ := json.Marshal(resp) + respBytes, _ := jsonutil.Marshal(resp) w.Write(respBytes) }) } diff --git a/privacy/scrubber.go b/privacy/scrubber.go index 59b74a2532b..0cfc7cdd7f4 100644 --- a/privacy/scrubber.go +++ b/privacy/scrubber.go @@ -6,6 +6,7 @@ import ( "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/util/iputil" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/util/ptrutil" "github.com/prebid/openrtb/v19/openrtb2" @@ -103,7 +104,7 @@ func (s scrubber) ScrubRequest(bidRequest *openrtb2.BidRequest, enforcement Enfo if userCopy != nil && (enforcement.UFPD || enforcement.Eids) { if len(userCopy.Ext) != 0 { - json.Unmarshal(userCopy.Ext, &userExtParsed) + jsonutil.Unmarshal(userCopy.Ext, &userExtParsed) } } @@ -148,7 +149,7 @@ func (s scrubber) ScrubRequest(bidRequest *openrtb2.BidRequest, enforcement Enfo } if userExtModified { - userExt, _ := json.Marshal(userExtParsed) + userExt, _ := jsonutil.Marshal(userExtParsed) userCopy.Ext = userExt } @@ -283,7 +284,7 @@ func scrubExtIDs(ext json.RawMessage, fieldName string) json.RawMessage { } var userExtParsed map[string]json.RawMessage - err := json.Unmarshal(ext, &userExtParsed) + err := jsonutil.Unmarshal(ext, &userExtParsed) if err != nil { return ext } @@ -291,7 +292,7 @@ func scrubExtIDs(ext json.RawMessage, fieldName string) json.RawMessage { _, hasField := userExtParsed[fieldName] if hasField { delete(userExtParsed, fieldName) - result, err := json.Marshal(userExtParsed) + result, err := jsonutil.Marshal(userExtParsed) if err == nil { return result } diff --git a/router/router.go b/router/router.go index 29bd8382e78..70b7860d661 100644 --- a/router/router.go +++ b/router/router.go @@ -34,6 +34,7 @@ import ( "github.com/prebid/prebid-server/server/ssl" storedRequestsConf "github.com/prebid/prebid-server/stored_requests/config" "github.com/prebid/prebid-server/usersync" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/prebid/prebid-server/util/uuidutil" "github.com/prebid/prebid-server/version" @@ -91,7 +92,7 @@ func newJsonDirectoryServer(schemaDirectory string, validator openrtb_ext.Bidder data[aliasName] = bidderData } - response, err := json.Marshal(data) + response, err := jsonutil.Marshal(data) if err != nil { glog.Fatalf("Failed to marshal bidder param JSON-schema: %v", err) } @@ -358,7 +359,7 @@ func readDefaultRequest(defReqConfig config.DefReqConfig) (map[string]string, [] return aliases, []byte{} } - if err := json.Unmarshal(defReqJSON, defReq); err != nil { + if err := jsonutil.UnmarshalValid(defReqJSON, defReq); err != nil { // we might not have aliases defined, but will atleast show that the JSON file is parsable. glog.Fatalf("error parsing alias json in file %s: %v", defReqConfig.FileSystem.FileName, err) return aliases, []byte{} diff --git a/router/router_test.go b/router/router_test.go index 41c2a724c91..f4f7715e6c3 100644 --- a/router/router_test.go +++ b/router/router_test.go @@ -9,6 +9,7 @@ import ( "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/stretchr/testify/assert" ) @@ -45,7 +46,7 @@ func TestNewJsonDirectoryServer(t *testing.T) { handler(recorder, request, nil) var data map[string]json.RawMessage - json.Unmarshal(recorder.Body.Bytes(), &data) + jsonutil.UnmarshalValid(recorder.Body.Bytes(), &data) // Make sure that every adapter has a json schema by the same name associated with it. adapterFiles, err := os.ReadDir(adapterDirectory) diff --git a/schain/schainwriter.go b/schain/schainwriter.go index 7e2161adb3b..e7c9dd4ce72 100644 --- a/schain/schainwriter.go +++ b/schain/schainwriter.go @@ -1,10 +1,9 @@ package schain import ( - "encoding/json" - "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/jsonutil" ) // NewSChainWriter creates an ORTB 2.5 schain writer instance @@ -70,7 +69,7 @@ func (w SChainWriter) Write(req *openrtb2.BidRequest, bidder string) { schain.SChain.Nodes = append(schain.SChain.Nodes, *w.hostSChainNode) } - sourceExt, err := json.Marshal(schain) + sourceExt, err := jsonutil.Marshal(schain) if err == nil { req.Source.Ext = sourceExt } diff --git a/schain/schainwriter_test.go b/schain/schainwriter_test.go index e98c962b4fa..9288b531d56 100644 --- a/schain/schainwriter_test.go +++ b/schain/schainwriter_test.go @@ -6,6 +6,7 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/stretchr/testify/assert" ) @@ -197,7 +198,7 @@ func TestSChainWriter(t *testing.T) { var reqExt *openrtb_ext.ExtRequest if tt.giveRequest.Ext != nil { reqExt = &openrtb_ext.ExtRequest{} - err := json.Unmarshal(tt.giveRequest.Ext, reqExt) + err := jsonutil.UnmarshalValid(tt.giveRequest.Ext, reqExt) if err != nil { t.Error("Unable to unmarshal request.ext") } diff --git a/stored_requests/backends/file_fetcher/fetcher.go b/stored_requests/backends/file_fetcher/fetcher.go index 56f5bdf853c..a9bbe919dcf 100644 --- a/stored_requests/backends/file_fetcher/fetcher.go +++ b/stored_requests/backends/file_fetcher/fetcher.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/prebid/prebid-server/stored_requests" + "github.com/prebid/prebid-server/util/jsonutil" jsonpatch "gopkg.in/evanphx/json-patch.v4" ) @@ -78,7 +79,7 @@ func (fetcher *eagerFetcher) FetchCategories(ctx context.Context, primaryAdServe tmp := make(map[string]stored_requests.Category) - if err := json.Unmarshal(file, &tmp); err != nil { + if err := jsonutil.UnmarshalValid(file, &tmp); err != nil { return "", fmt.Errorf("Unable to unmarshal categories for adserver: '%s', publisherId: '%s'", primaryAdServer, publisherId) } fetcher.Categories[fileName] = tmp diff --git a/stored_requests/backends/file_fetcher/fetcher_test.go b/stored_requests/backends/file_fetcher/fetcher_test.go index 3c585f9f456..a69945641f1 100644 --- a/stored_requests/backends/file_fetcher/fetcher_test.go +++ b/stored_requests/backends/file_fetcher/fetcher_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/prebid/prebid-server/stored_requests" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/stretchr/testify/assert" ) @@ -58,7 +59,7 @@ func validateStoredReqOne(t *testing.T, storedRequests map[string]json.RawMessag } var req1Val map[string]string - if err := json.Unmarshal(value, &req1Val); err != nil { + if err := jsonutil.UnmarshalValid(value, &req1Val); err != nil { t.Errorf("Failed to unmarshal 1: %v", err) } if len(req1Val) != 1 { @@ -80,7 +81,7 @@ func validateStoredReqTwo(t *testing.T, storedRequests map[string]json.RawMessag } var req2Val string - if err := json.Unmarshal(value, &req2Val); err != nil { + if err := jsonutil.UnmarshalValid(value, &req2Val); err != nil { t.Errorf("Failed to unmarshal %d: %v", 2, err) } if req2Val != `esca"ped` { @@ -95,7 +96,7 @@ func validateImp(t *testing.T, storedImps map[string]json.RawMessage) { } var impVal map[string]bool - if err := json.Unmarshal(value, &impVal); err != nil { + if err := jsonutil.UnmarshalValid(value, &impVal); err != nil { t.Errorf("Failed to unmarshal some-imp: %v", err) } if len(impVal) != 1 { diff --git a/stored_requests/backends/http_fetcher/fetcher.go b/stored_requests/backends/http_fetcher/fetcher.go index 326b63fce71..88afa39fb1d 100644 --- a/stored_requests/backends/http_fetcher/fetcher.go +++ b/stored_requests/backends/http_fetcher/fetcher.go @@ -1,7 +1,6 @@ package http_fetcher import ( - "bytes" "context" "encoding/json" "fmt" @@ -11,6 +10,7 @@ import ( "strings" "github.com/prebid/prebid-server/stored_requests" + "github.com/prebid/prebid-server/util/jsonutil" jsonpatch "gopkg.in/evanphx/json-patch.v4" "github.com/golang/glog" @@ -142,7 +142,7 @@ func (fetcher *HttpFetcher) FetchAccounts(ctx context.Context, accountIDs []stri } } var responseData accountsResponseContract - if err = json.Unmarshal(respBytes, &responseData); err != nil { + if err = jsonutil.UnmarshalValid(respBytes, &responseData); err != nil { return nil, []error{ fmt.Errorf(`Error fetching accounts %v via http: failed to parse response: %v`, accountIDs, err), } @@ -209,7 +209,7 @@ func (fetcher *HttpFetcher) FetchCategories(ctx context.Context, primaryAdServer respBytes, err := io.ReadAll(httpResp.Body) tmp := make(map[string]stored_requests.Category) - if err := json.Unmarshal(respBytes, &tmp); err != nil { + if err := jsonutil.UnmarshalValid(respBytes, &tmp); err != nil { return "", fmt.Errorf("Unable to unmarshal categories for adserver: '%s', publisherId: '%s'", primaryAdServer, publisherId) } fetcher.Categories[dataName] = tmp @@ -240,7 +240,7 @@ func unpackResponse(resp *http.Response) (requestData map[string]json.RawMessage if resp.StatusCode == http.StatusOK { var responseObj responseContract - if err := json.Unmarshal(respBytes, &responseObj); err != nil { + if err := jsonutil.UnmarshalValid(respBytes, &responseObj); err != nil { errs = append(errs, err) return } @@ -260,7 +260,7 @@ func unpackResponse(resp *http.Response) (requestData map[string]json.RawMessage func convertNullsToErrs(m map[string]json.RawMessage, dataType string, errs []error) []error { for id, val := range m { - if bytes.Equal(val, []byte("null")) { + if val == nil { delete(m, id) errs = append(errs, stored_requests.NotFoundError{ ID: id, diff --git a/stored_requests/backends/http_fetcher/fetcher_test.go b/stored_requests/backends/http_fetcher/fetcher_test.go index 3c8ca7cb070..80be6918ad8 100644 --- a/stored_requests/backends/http_fetcher/fetcher_test.go +++ b/stored_requests/backends/http_fetcher/fetcher_test.go @@ -10,6 +10,7 @@ import ( "testing" "time" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/stretchr/testify/assert" ) @@ -233,7 +234,7 @@ func newHandler(t *testing.T, expectReqIDs []string, expectImpIDs []string, json Imps: impIDResponse, } - if respBytes, err := json.Marshal(respObj); err != nil { + if respBytes, err := jsonutil.Marshal(respObj); err != nil { t.Errorf("failed to marshal responseContract in test: %v", err) w.WriteHeader(http.StatusInternalServerError) } else { @@ -267,7 +268,7 @@ func newAccountHandler(t *testing.T, expectAccIDs []string) func(w http.Response Accounts: accIDResponse, } - if respBytes, err := json.Marshal(respObj); err != nil { + if respBytes, err := jsonutil.Marshal(respObj); err != nil { t.Errorf("failed to marshal responseContract in test: %v", err) w.WriteHeader(http.StatusInternalServerError) } else { @@ -327,7 +328,7 @@ func richSplit(queryVal string) []string { } func jsonifyID(id string) json.RawMessage { - if b, err := json.Marshal(id); err != nil { + if b, err := jsonutil.Marshal(id); err != nil { return json.RawMessage([]byte("\"error encoding ID=" + id + "\"")) } else { return json.RawMessage(b) diff --git a/stored_requests/events/api/api.go b/stored_requests/events/api/api.go index bf8edd2d849..30778f0e11a 100644 --- a/stored_requests/events/api/api.go +++ b/stored_requests/events/api/api.go @@ -1,12 +1,12 @@ package api import ( - "encoding/json" "io" "net/http" "github.com/julienschmidt/httprouter" "github.com/prebid/prebid-server/stored_requests/events" + "github.com/prebid/prebid-server/util/jsonutil" ) type eventsAPI struct { @@ -43,7 +43,7 @@ func (api *eventsAPI) HandleEvent(w http.ResponseWriter, r *http.Request, _ http } var save events.Save - if err := json.Unmarshal(body, &save); err != nil { + if err := jsonutil.UnmarshalValid(body, &save); err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("Invalid update.\n")) return @@ -59,7 +59,7 @@ func (api *eventsAPI) HandleEvent(w http.ResponseWriter, r *http.Request, _ http } var invalidation events.Invalidation - if err := json.Unmarshal(body, &invalidation); err != nil { + if err := jsonutil.UnmarshalValid(body, &invalidation); err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("Invalid invalidation.\n")) return diff --git a/stored_requests/events/http/http.go b/stored_requests/events/http/http.go index 1c4f8fdff73..be5b85a03a6 100644 --- a/stored_requests/events/http/http.go +++ b/stored_requests/events/http/http.go @@ -13,6 +13,7 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/prebid-server/stored_requests/events" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/golang/glog" ) @@ -184,7 +185,7 @@ func (e *HTTPEvents) parse(endpoint string, resp *httpCore.Response, err error) } var respObj responseContract - if err := json.Unmarshal(respBytes, &respObj); err != nil { + if err := jsonutil.UnmarshalValid(respBytes, &respObj); err != nil { glog.Errorf("Failed to unmarshal body of GET %s for Stored Requests: %v", endpoint, err) return nil, false } diff --git a/stored_requests/events/http/http_test.go b/stored_requests/events/http/http_test.go index a185a3c2360..663d8cd193f 100644 --- a/stored_requests/events/http/http_test.go +++ b/stored_requests/events/http/http_test.go @@ -2,13 +2,13 @@ package http import ( "context" - "encoding/json" "fmt" httpCore "net/http" "net/http/httptest" "testing" "time" + "github.com/prebid/prebid-server/util/jsonutil" "github.com/stretchr/testify/assert" ) @@ -151,14 +151,14 @@ func TestStartup(t *testing.T) { t.Run(fmt.Sprintf("Step %d", i+1), func(t *testing.T) { // Check expected Saves if len(test.saves) > 0 { - saves, err := json.Marshal(<-ev.Saves()) + saves, err := jsonutil.Marshal(<-ev.Saves()) assert.NoError(t, err, `Failed to marshal event.Save object: %v`, err) assert.JSONEq(t, test.saves, string(saves)) } assert.Empty(t, ev.Saves(), "Unexpected additional messages in save channel") // Check expected Invalidations if len(test.invalidations) > 0 { - invalidations, err := json.Marshal(<-ev.Invalidations()) + invalidations, err := jsonutil.Marshal(<-ev.Invalidations()) assert.NoError(t, err, `Failed to marshal event.Invalidation object: %v`, err) assert.JSONEq(t, test.invalidations, string(invalidations)) } diff --git a/stored_responses/stored_responses.go b/stored_responses/stored_responses.go index 6a5da01deba..ef8fe50619d 100644 --- a/stored_responses/stored_responses.go +++ b/stored_responses/stored_responses.go @@ -9,6 +9,7 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/stored_requests" + "github.com/prebid/prebid-server/util/jsonutil" ) type ImpsWithAuctionResponseIDs map[string]string @@ -210,7 +211,7 @@ func parseImpInfo(requestJson []byte) (impData []ImpExtPrebidData, errs []error) impExtData, _, _, err := jsonparser.Get(imp, "ext", "prebid") var impExtPrebid openrtb_ext.ExtImpPrebid if impExtData != nil { - if err := json.Unmarshal(impExtData, &impExtPrebid); err != nil { + if err := jsonutil.Unmarshal(impExtData, &impExtPrebid); err != nil { errs = append(errs, err) } } diff --git a/usersync/cookie.go b/usersync/cookie.go index 94ada94ed75..88524018c49 100644 --- a/usersync/cookie.go +++ b/usersync/cookie.go @@ -1,13 +1,13 @@ package usersync import ( - "encoding/json" "errors" "net/http" "time" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/jsonutil" ) const uidCookieName = "uids" @@ -226,7 +226,7 @@ type cookieJson struct { } func (cookie *Cookie) MarshalJSON() ([]byte, error) { - return json.Marshal(cookieJson{ + return jsonutil.Marshal(cookieJson{ UIDs: cookie.uids, OptOut: cookie.optOut, }) @@ -234,7 +234,7 @@ func (cookie *Cookie) MarshalJSON() ([]byte, error) { func (cookie *Cookie) UnmarshalJSON(b []byte) error { var cookieContract cookieJson - if err := json.Unmarshal(b, &cookieContract); err != nil { + if err := jsonutil.Unmarshal(b, &cookieContract); err != nil { return err } diff --git a/usersync/decoder.go b/usersync/decoder.go index 3ff13aa3242..c803fbe2a52 100644 --- a/usersync/decoder.go +++ b/usersync/decoder.go @@ -2,12 +2,12 @@ package usersync import ( "encoding/base64" - "encoding/json" + + "github.com/prebid/prebid-server/util/jsonutil" ) type Decoder interface { - // Decode takes an encoded string and decodes it into a cookie - Decode(v string) *Cookie + Decode(encodedValue string) *Cookie } type Base64Decoder struct{} @@ -19,7 +19,7 @@ func (d Base64Decoder) Decode(encodedValue string) *Cookie { } var cookie Cookie - if err = json.Unmarshal(jsonValue, &cookie); err != nil { + if err = jsonutil.UnmarshalValid(jsonValue, &cookie); err != nil { return NewCookie() } diff --git a/usersync/encoder.go b/usersync/encoder.go index eef7e2ef34f..74472f23307 100644 --- a/usersync/encoder.go +++ b/usersync/encoder.go @@ -2,7 +2,8 @@ package usersync import ( "encoding/base64" - "encoding/json" + + "github.com/prebid/prebid-server/util/jsonutil" ) type Encoder interface { @@ -13,7 +14,7 @@ type Encoder interface { type Base64Encoder struct{} func (e Base64Encoder) Encode(c *Cookie) (string, error) { - j, err := json.Marshal(c) + j, err := jsonutil.Marshal(c) if err != nil { return "", err } diff --git a/util/jsonutil/jsonutil.go b/util/jsonutil/jsonutil.go index 3b468731cad..a8981477dc6 100644 --- a/util/jsonutil/jsonutil.go +++ b/util/jsonutil/jsonutil.go @@ -4,14 +4,16 @@ import ( "bytes" "encoding/json" "io" + "strings" + + jsoniter "github.com/json-iterator/go" + "github.com/prebid/prebid-server/errortypes" ) -var comma = []byte(",")[0] -var colon = []byte(":")[0] -var sqBracket = []byte("]")[0] -var openCurlyBracket = []byte("{")[0] -var closingCurlyBracket = []byte("}")[0] -var quote = []byte(`"`)[0] +var comma = byte(',') +var colon = byte(':') +var sqBracket = byte(']') +var closingCurlyBracket = byte('}') // Finds element in json byte array with any level of nesting func FindElement(extension []byte, elementNames ...string) (bool, int64, int64, error) { @@ -110,3 +112,102 @@ func DropElement(extension []byte, elementNames ...string) ([]byte, error) { } return extension, nil } + +// jsonConfigValidationOn attempts to maintain compatibility with the standard library which +// includes enabling validation +var jsonConfigValidationOn = jsoniter.ConfigCompatibleWithStandardLibrary + +// jsonConfigValidationOff disables validation +var jsonConfigValidationOff = jsoniter.Config{ + EscapeHTML: true, + SortMapKeys: true, + ValidateJsonRawMessage: false, +}.Froze() + +// Unmarshal unmarshals a byte slice into the specified data structure without performing +// any validation on the data. An unmarshal error is returned if a non-validation error occurs. +func Unmarshal(data []byte, v interface{}) error { + err := jsonConfigValidationOff.Unmarshal(data, v) + if err != nil { + return &errortypes.FailedToUnmarshal{ + Message: tryExtractErrorMessage(err), + } + } + return nil +} + +// UnmarshalValid validates and unmarshals a byte slice into the specified data structure +// returning an error if validation fails +func UnmarshalValid(data []byte, v interface{}) error { + if err := jsonConfigValidationOn.Unmarshal(data, v); err != nil { + return &errortypes.FailedToUnmarshal{ + Message: tryExtractErrorMessage(err), + } + } + return nil +} + +// Marshal marshals a data structure into a byte slice without performing any validation +// on the data. A marshal error is returned if a non-validation error occurs. +func Marshal(v interface{}) ([]byte, error) { + data, err := jsonConfigValidationOn.Marshal(v) + if err != nil { + return nil, &errortypes.FailedToMarshal{ + Message: err.Error(), + } + } + return data, nil +} + +// tryExtractErrorMessage attempts to extract a sane error message from the json-iter package. The errors +// returned from that library are not types and include a lot of extra information we don't want to respond with. +// This is hacky, but it's the only downside to the json-iter library. +func tryExtractErrorMessage(err error) string { + msg := err.Error() + + msgEndIndex := strings.LastIndex(msg, ", error found in #") + if msgEndIndex == -1 { + return msg + } + + msgStartIndex := strings.Index(msg, ": ") + if msgStartIndex == -1 { + return msg + } + + operationStack := []string{msg[0:msgStartIndex]} + for { + msgStartIndexNext := strings.Index(msg[msgStartIndex+2:], ": ") + + // no more matches + if msgStartIndexNext == -1 { + break + } + + // matches occur after the end message marker (sanity check) + if (msgStartIndex + msgStartIndexNext) >= msgEndIndex { + break + } + + // match should not contain a space, indicates operation is really an error message + match := msg[msgStartIndex+2 : msgStartIndex+2+msgStartIndexNext] + if strings.Contains(match, " ") { + break + } + + operationStack = append(operationStack, match) + msgStartIndex += msgStartIndexNext + 2 + } + + if len(operationStack) > 1 && isLikelyDetailedErrorMessage(msg[msgStartIndex+2:]) { + return "cannot unmarshal " + operationStack[len(operationStack)-2] + ": " + msg[msgStartIndex+2:msgEndIndex] + } + + return msg[msgStartIndex+2 : msgEndIndex] +} + +// isLikelyDetailedErrorMessage checks if the json unmarshal error contains enough information such +// that the caller clearly understands the context, where the structure name is not needed. +func isLikelyDetailedErrorMessage(msg string) bool { + return !strings.HasPrefix(msg, "request.") +} diff --git a/util/jsonutil/jsonutil_test.go b/util/jsonutil/jsonutil_test.go index 12b1fd5e803..09fb6727309 100644 --- a/util/jsonutil/jsonutil_test.go +++ b/util/jsonutil/jsonutil_test.go @@ -1,13 +1,14 @@ package jsonutil import ( - "github.com/stretchr/testify/assert" + "errors" "strings" "testing" + + "github.com/stretchr/testify/assert" ) func TestDropElement(t *testing.T) { - tests := []struct { description string input []byte @@ -183,3 +184,59 @@ func TestDropElement(t *testing.T) { } } } + +func TestTryExtractErrorMessage(t *testing.T) { + tests := []struct { + name string + givenErr string + expectedMsg string + }{ + { + name: "level-1", + givenErr: "readObjectStart: expect { or n, but found m, error found in #1 byte of ...|malformed|..., bigger context ...|malformed|..", + expectedMsg: "expect { or n, but found m", + }, + { + name: "level-2", + givenErr: "openrtb_ext.ExtRequestPrebidCache.Bids: readObjectStart: expect { or n, but found t, error found in #10 byte of ...|:{\"bids\":true}}|..., bigger context ...|{\"cache\":{\"bids\":true}}|...", + expectedMsg: "cannot unmarshal openrtb_ext.ExtRequestPrebidCache.Bids: expect { or n, but found t", + }, + { + name: "level-3+", + givenErr: "openrtb_ext.ExtRequestPrebid.Cache: openrtb_ext.ExtRequestPrebidCache.Bids: readObjectStart: expect { or n, but found t, error found in #10 byte of ...|:{\"bids\":true}}|..., bigger context ...|{\"cache\":{\"bids\":true}}|...", + expectedMsg: "cannot unmarshal openrtb_ext.ExtRequestPrebidCache.Bids: expect { or n, but found t", + }, + { + name: "error-msg", + givenErr: "Skip: do not know how to skip: 109, error found in #10 byte of ...|prebid\": malformed}|..., bigger context ...|{\"prebid\": malformed}|...", + expectedMsg: "do not know how to skip: 109", + }, + { + name: "specific", + givenErr: "openrtb_ext.ExtDevicePrebid.Interstitial: unmarshalerDecoder: request.device.ext.prebid.interstitial.minwidthperc must be a number between 0 and 100, error found in #10 byte of ...| }\n }|..., bigger context ...|: 120,\n \"minheightperc\": 60\n }\n }|...", + expectedMsg: "request.device.ext.prebid.interstitial.minwidthperc must be a number between 0 and 100", + }, + { + name: "normal", + givenErr: "normal error message", + expectedMsg: "normal error message", + }, + { + name: "norma-false-start", + givenErr: "false: normal error message", + expectedMsg: "false: normal error message", + }, + { + name: "norma-false-end", + givenErr: "normal error message, error found in #10 but doesn't follow format", + expectedMsg: "normal error message, error found in #10 but doesn't follow format", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := tryExtractErrorMessage(errors.New(test.givenErr)) + assert.Equal(t, test.expectedMsg, result) + }) + } +} diff --git a/util/jsonutil/stringInt_test.go b/util/jsonutil/stringInt_test.go index e8639c7acee..cd2f3476e46 100644 --- a/util/jsonutil/stringInt_test.go +++ b/util/jsonutil/stringInt_test.go @@ -1,7 +1,6 @@ package jsonutil import ( - "encoding/json" "testing" "github.com/buger/jsonparser" @@ -16,27 +15,27 @@ func TestStringIntUnmarshalJSON(t *testing.T) { t.Run("string", func(t *testing.T) { jsonData := []byte(`{"item_id":"30"}`) var item Item - assert.NoError(t, json.Unmarshal(jsonData, &item)) + assert.NoError(t, UnmarshalValid(jsonData, &item)) assert.Equal(t, 30, int(item.ItemId)) }) t.Run("int", func(t *testing.T) { jsonData := []byte(`{"item_id":30}`) var item Item - assert.NoError(t, json.Unmarshal(jsonData, &item)) + assert.NoError(t, UnmarshalValid(jsonData, &item)) assert.Equal(t, 30, int(item.ItemId)) }) t.Run("empty_id", func(t *testing.T) { jsonData := []byte(`{"item_id": ""}`) var item Item - assert.NoError(t, json.Unmarshal(jsonData, &item)) + assert.NoError(t, UnmarshalValid(jsonData, &item)) }) t.Run("invalid_input", func(t *testing.T) { jsonData := []byte(`{"item_id":true}`) var item Item - err := json.Unmarshal(jsonData, &item) - assert.Equal(t, jsonparser.MalformedValueError, err) + err := UnmarshalValid(jsonData, &item) + assert.EqualError(t, err, "cannot unmarshal jsonutil.Item.ItemId: "+jsonparser.MalformedValueError.Error()) }) } diff --git a/version/xprebidheader_test.go b/version/xprebidheader_test.go index 90aef6cb420..a1c7b355bb8 100644 --- a/version/xprebidheader_test.go +++ b/version/xprebidheader_test.go @@ -1,13 +1,13 @@ package version import ( - "encoding/json" "testing" "github.com/prebid/openrtb/v19/openrtb2" "github.com/stretchr/testify/assert" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/util/jsonutil" ) func TestBuildXPrebidHeader(t *testing.T) { @@ -134,12 +134,12 @@ func TestBuildXPrebidHeaderForRequest(t *testing.T) { for _, test := range testCases { req := &openrtb2.BidRequest{} if test.requestExt != nil { - reqExt, err := json.Marshal(test.requestExt) + reqExt, err := jsonutil.Marshal(test.requestExt) assert.NoError(t, err, test.description+":err marshalling reqExt") req.Ext = reqExt } if test.requestAppExt != nil { - reqAppExt, err := json.Marshal(test.requestAppExt) + reqAppExt, err := jsonutil.Marshal(test.requestAppExt) assert.NoError(t, err, test.description+":err marshalling reqAppExt") req.App = &openrtb2.App{Ext: reqAppExt} } From cd03a0f25ff0e5e4f8d5bc91429ad243e27cd6a8 Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Thu, 19 Oct 2023 15:56:09 -0400 Subject: [PATCH 193/268] Restore Alias User Syncs (#3244) --- static/bidder-info/adform.yaml | 4 ++++ static/bidder-info/quantumdex.yaml | 9 ++++++++- static/bidder-info/valueimpression.yaml | 9 ++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/static/bidder-info/adform.yaml b/static/bidder-info/adform.yaml index 4aa6e70f1d0..2ad892785ce 100644 --- a/static/bidder-info/adform.yaml +++ b/static/bidder-info/adform.yaml @@ -1 +1,5 @@ aliasOf: adf +userSync: + redirect: + url: "https://cm.adform.net/cookie?redirect_url={{.RedirectURL}}" + userMacro: "$UID" diff --git a/static/bidder-info/quantumdex.yaml b/static/bidder-info/quantumdex.yaml index 32043ad62fb..fae2a987dd7 100644 --- a/static/bidder-info/quantumdex.yaml +++ b/static/bidder-info/quantumdex.yaml @@ -1 +1,8 @@ -aliasOf: "apacdex" \ No newline at end of file +aliasOf: "apacdex" +userSync: + iframe: + url: https://sync.quantumdex.io/usersync/pbs?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}} + userMacro: "[UID]" + redirect: + url: "https://sync.quantumdex.io/getuid?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}" + userMacro: "[UID]" diff --git a/static/bidder-info/valueimpression.yaml b/static/bidder-info/valueimpression.yaml index 32043ad62fb..fae2a987dd7 100644 --- a/static/bidder-info/valueimpression.yaml +++ b/static/bidder-info/valueimpression.yaml @@ -1 +1,8 @@ -aliasOf: "apacdex" \ No newline at end of file +aliasOf: "apacdex" +userSync: + iframe: + url: https://sync.quantumdex.io/usersync/pbs?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}} + userMacro: "[UID]" + redirect: + url: "https://sync.quantumdex.io/getuid?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}" + userMacro: "[UID]" From 50ad642976f3de1e06a310eb87dc694de866123a Mon Sep 17 00:00:00 2001 From: dennisjay Date: Fri, 20 Oct 2023 00:13:29 +0200 Subject: [PATCH 194/268] Revert "Remove Adapter: Define Media" (#3242) --- adapters/definemedia/definemedia.go | 109 +++++++ adapters/definemedia/definemedia_test.go | 21 ++ .../exemplary/sample-conative-banner.json | 270 ++++++++++++++++++ .../exemplary/sample-conative-native.json | 257 +++++++++++++++++ .../supplemental/nobid-response.json | 222 ++++++++++++++ .../supplemental/nocontent-response.json | 219 ++++++++++++++ .../supplemental/status_400.json | 224 +++++++++++++++ .../supplemental/status_418.json | 224 +++++++++++++++ .../supplemental/unmarshal-error.json | 224 +++++++++++++++ .../supplemental/unsupported-type.json | 250 ++++++++++++++++ adapters/definemedia/params_test.go | 48 ++++ exchange/adapter_builders.go | 2 + exchange/adapter_util.go | 1 - openrtb_ext/bidders.go | 2 + openrtb_ext/imp_definemedia.go | 6 + static/bidder-info/definemedia.yaml | 10 + static/bidder-params/definemedia.json | 19 ++ 17 files changed, 2107 insertions(+), 1 deletion(-) create mode 100644 adapters/definemedia/definemedia.go create mode 100644 adapters/definemedia/definemedia_test.go create mode 100644 adapters/definemedia/definemediatest/exemplary/sample-conative-banner.json create mode 100644 adapters/definemedia/definemediatest/exemplary/sample-conative-native.json create mode 100644 adapters/definemedia/definemediatest/supplemental/nobid-response.json create mode 100644 adapters/definemedia/definemediatest/supplemental/nocontent-response.json create mode 100644 adapters/definemedia/definemediatest/supplemental/status_400.json create mode 100644 adapters/definemedia/definemediatest/supplemental/status_418.json create mode 100644 adapters/definemedia/definemediatest/supplemental/unmarshal-error.json create mode 100644 adapters/definemedia/definemediatest/supplemental/unsupported-type.json create mode 100644 adapters/definemedia/params_test.go create mode 100644 openrtb_ext/imp_definemedia.go create mode 100644 static/bidder-info/definemedia.yaml create mode 100644 static/bidder-params/definemedia.json diff --git a/adapters/definemedia/definemedia.go b/adapters/definemedia/definemedia.go new file mode 100644 index 00000000000..3e014e3c16d --- /dev/null +++ b/adapters/definemedia/definemedia.go @@ -0,0 +1,109 @@ +package definemedia + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/openrtb_ext" +) + +type adapter struct { + endpoint string +} + +// Builder builds a new instance of the Foo adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +// MakeRequests makes the HTTP requests which should be made to fetch bids. +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var errors []error + requestJSON, err := json.Marshal(request) + if err != nil { + errors = append(errors, err) + return nil, errors + } + + requestData := &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: requestJSON, + } + + return []*adapters.RequestData{requestData}, errors + +} + +func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if response.StatusCode == http.StatusNoContent { + return nil, nil + } + + if response.StatusCode == http.StatusBadRequest { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), + }} + } + + if response.StatusCode != http.StatusOK { + return nil, []error{&errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), + }} + } + + var bidResp openrtb2.BidResponse + if err := json.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{err} + } + + bidsCapacity := 1 + if len(bidResp.SeatBid) > 0 { + bidsCapacity = len(bidResp.SeatBid[0].Bid) + } + bidResponse := adapters.NewBidderResponseWithBidsCapacity(bidsCapacity) + var errors []error + for _, sb := range bidResp.SeatBid { + for i, bid := range sb.Bid { + bidType, err := getMediaTypeForBid(bid) + if err != nil { + errors = append(errors, err) + continue + } + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &sb.Bid[i], + BidType: bidType, + }) + + } + } + + return bidResponse, errors +} + +func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + if bid.Ext != nil { + var bidExt openrtb_ext.ExtBid + err := json.Unmarshal(bid.Ext, &bidExt) + if err == nil && bidExt.Prebid != nil { + if (bidExt.Prebid.Type == openrtb_ext.BidTypeBanner) || (bidExt.Prebid.Type == openrtb_ext.BidTypeNative) { + return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type)) + } + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Invalid mediatype in the impression"), + } + } + } + + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Failed to parse impression \"%s\" mediatype", bid.ImpID), + } +} diff --git a/adapters/definemedia/definemedia_test.go b/adapters/definemedia/definemedia_test.go new file mode 100644 index 00000000000..3ed0cb938b8 --- /dev/null +++ b/adapters/definemedia/definemedia_test.go @@ -0,0 +1,21 @@ +package definemedia + +import ( + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderDefinemedia, config.Adapter{ + Endpoint: "https://rtb.conative.network/openrtb2/auction"}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "definemediatest", bidder) +} diff --git a/adapters/definemedia/definemediatest/exemplary/sample-conative-banner.json b/adapters/definemedia/definemediatest/exemplary/sample-conative-banner.json new file mode 100644 index 00000000000..a7d7e411f78 --- /dev/null +++ b/adapters/definemedia/definemediatest/exemplary/sample-conative-banner.json @@ -0,0 +1,270 @@ +{ + "mockBidRequest": { + "imp": [ + { + "ext": { + "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9", + "prebid": { + "bidder": { + "definemedia": { + "mandantId": 12 + } + } + } + }, + "id": "div-gpt-ad-1460505748561-0", + "banner": { + "topframe": 1, + "format": [ + { + "w": 300, + "h": 250 + } + ] + } + } + ], + "site": { + "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", + "domain": "localhost:8080", + "publisher": { + "domain": "localhost:8080", + "id": "1" + } + }, + "device": { + "w": 1098, + "h": 1169, + "dnt": 0, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "language": "de", + "sua": { + "source": 2, + "platform": { + "brand": "macOS", + "version": [ + "12", + "3", + "1" + ] + }, + "browsers": [ + { + "brand": "Not?A_Brand", + "version": [ + "8", + "0", + "0", + "0" + ] + }, + { + "brand": "Chromium", + "version": [ + "108", + "0", + "5359", + "124" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "108", + "0", + "5359", + "124" + ] + } + ], + "mobile": 0, + "model": "", + "bitness": "64", + "architecture": "x86" + } + }, + "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", + "test": 0, + "source": { + "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" + }, + "ext": { + "prebid": { + "auctiontimestamp": 1671449004622, + "targeting": { + "includewinners": true, + "includebidderkeys": false + }, + "debug": true, + "channel": { + "name": "pbjs", + "version": "v7.28.0" + } + } + }, + "tmax": 1000 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://rtb.conative.network/openrtb2/auction", + "body": { + "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", + "imp": [ + { + "id": "div-gpt-ad-1460505748561-0", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "topframe": 1 + }, + "ext": { + "prebid": { + "bidder": { + "definemedia": { + "mandantId": 12 + } + } + }, + "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9" + } + } + ], + "site": { + "domain": "localhost:8080", + "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", + "publisher": { + "id": "1", + "domain": "localhost:8080" + } + }, + "device": { + "dnt": 0, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "sua": { + "browsers": [ + { + "brand": "Not?A_Brand", + "version": [ + "8", + "0", + "0", + "0" + ] + }, + { + "brand": "Chromium", + "version": [ + "108", + "0", + "5359", + "124" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "108", + "0", + "5359", + "124" + ] + } + ], + "platform": { + "brand": "macOS", + "version": [ + "12", + "3", + "1" + ] + }, + "mobile": 0, + "architecture": "x86", + "bitness": "64", + "source": 2 + }, + "h": 1169, + "w": 1098, + "language": "de" + }, + "tmax": 1000, + "source": { + "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" + }, + "ext": { + "prebid": { + "auctiontimestamp": 1.671449004622e+12, + "channel": { + "name": "pbjs", + "version": "v7.28.0" + }, + "debug": true, + "targeting": { + "includebidderkeys": false, + "includewinners": true + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "46189656-7e2e-477d-b7f2-e05de224bb89", + "impid": "div-gpt-ad-1460505748561-0", + "price": 100, + "adm": "{banner html}", + "adomain": [ + "test.com" + ], + "crid": "test-creative-id", + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "46189656-7e2e-477d-b7f2-e05de224bb89", + "impid": "div-gpt-ad-1460505748561-0", + "price": 100, + "adm": "{banner html}", + "crid": "test-creative-id", + "adomain": [ + "test.com" + ], + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/definemedia/definemediatest/exemplary/sample-conative-native.json b/adapters/definemedia/definemediatest/exemplary/sample-conative-native.json new file mode 100644 index 00000000000..4fe56a4c22e --- /dev/null +++ b/adapters/definemedia/definemediatest/exemplary/sample-conative-native.json @@ -0,0 +1,257 @@ +{ + "mockBidRequest": { + "imp": [ + { + "ext": { + "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9", + "prebid": { + "bidder": { + "definemedia": { + "mandantId": 12 + } + } + } + }, + "id": "div-gpt-ad-1460505748561-0", + "native": {} + } + ], + "site": { + "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", + "domain": "localhost:8080", + "publisher": { + "domain": "localhost:8080", + "id": "1" + } + }, + "device": { + "w": 1098, + "h": 1169, + "dnt": 0, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "language": "de", + "sua": { + "source": 2, + "platform": { + "brand": "macOS", + "version": [ + "12", + "3", + "1" + ] + }, + "browsers": [ + { + "brand": "Not?A_Brand", + "version": [ + "8", + "0", + "0", + "0" + ] + }, + { + "brand": "Chromium", + "version": [ + "108", + "0", + "5359", + "124" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "108", + "0", + "5359", + "124" + ] + } + ], + "mobile": 0, + "model": "", + "bitness": "64", + "architecture": "x86" + } + }, + "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", + "test": 0, + "source": { + "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" + }, + "ext": { + "prebid": { + "auctiontimestamp": 1671449004622, + "targeting": { + "includewinners": true, + "includebidderkeys": false + }, + "debug": true, + "channel": { + "name": "pbjs", + "version": "v7.28.0" + } + } + }, + "tmax": 1000 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://rtb.conative.network/openrtb2/auction", + "body": { + "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", + "imp": [ + { + "id": "div-gpt-ad-1460505748561-0", + "native": { + "request": "" + }, + "ext": { + "prebid": { + "bidder": { + "definemedia": { + "mandantId": 12 + } + } + }, + "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9" + } + } + ], + "site": { + "domain": "localhost:8080", + "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", + "publisher": { + "id": "1", + "domain": "localhost:8080" + } + }, + "device": { + "dnt": 0, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "sua": { + "browsers": [ + { + "brand": "Not?A_Brand", + "version": [ + "8", + "0", + "0", + "0" + ] + }, + { + "brand": "Chromium", + "version": [ + "108", + "0", + "5359", + "124" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "108", + "0", + "5359", + "124" + ] + } + ], + "platform": { + "brand": "macOS", + "version": [ + "12", + "3", + "1" + ] + }, + "mobile": 0, + "architecture": "x86", + "bitness": "64", + "source": 2 + }, + "h": 1169, + "w": 1098, + "language": "de" + }, + "tmax": 1000, + "source": { + "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" + }, + "ext": { + "prebid": { + "auctiontimestamp": 1.671449004622e+12, + "channel": { + "name": "pbjs", + "version": "v7.28.0" + }, + "debug": true, + "targeting": { + "includebidderkeys": false, + "includewinners": true + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "46189656-7e2e-477d-b7f2-e05de224bb89", + "impid": "div-gpt-ad-1460505748561-0", + "price": 100, + "adm": "{\n \"ver\": \"1.1\",\n \"imptrackers\": [\"http://imptracker.com\"],\n \"jstracker\": \"\u003cscript\u003etrack()\u003c/script\u003e\",\n \"link\": {\n \"url\": \"http://i.am.a/URL\"\n },\n \"assets\": [\n {\n \"id\": 123,\n \"required\": 1,\n \"title\": {\n \"text\": \"Learn about this awesome thing\"\n }\n },\n {\n \"id\": 124,\n \"required\": 1,\n \"img\": {\n \"url\": \"http://www.myads.com/thumbnail1.png\"\n }\n },\n {\n \"id\": 128,\n \"required\": 1,\n \"img\": {\n \"url\": \"http://www.myads.com/largethumb1.png\"\n }\n },\n {\n \"id\": 126,\n \"required\": 1,\n \"data\": {\n \"value\": \"My Brand\"\n }\n },\n {\n \"id\": 127,\n \"required\": 1,\n \"data\": {\n \"value\": \"Learn all about this awesome story of someone using my product.\"\n }\n },\n {\n \"id\": 4,\n \"video\": {\n \"vasttag\": \"\u003cVAST version=\\\"2.0\\\"\u003e\u003c/VAST\u003e\"\n }\n },\n {\n \"id\": 5,\n \"link\": {\n \"url\": \"http://landing.com\",\n \"clicktrackers\": [\"http://tracker.com\"],\n \"fallback\": \"http://fallback.com\"\n }\n }\n ]\n}", + "adomain": [ + "test.com" + ], + "crid": "test-creative-id", + "ext": { + "prebid": { + "type": "native" + } + } + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "46189656-7e2e-477d-b7f2-e05de224bb89", + "impid": "div-gpt-ad-1460505748561-0", + "price": 100, + + "adm": "{\n \"ver\": \"1.1\",\n \"imptrackers\": [\"http://imptracker.com\"],\n \"jstracker\": \"\u003cscript\u003etrack()\u003c/script\u003e\",\n \"link\": {\n \"url\": \"http://i.am.a/URL\"\n },\n \"assets\": [\n {\n \"id\": 123,\n \"required\": 1,\n \"title\": {\n \"text\": \"Learn about this awesome thing\"\n }\n },\n {\n \"id\": 124,\n \"required\": 1,\n \"img\": {\n \"url\": \"http://www.myads.com/thumbnail1.png\"\n }\n },\n {\n \"id\": 128,\n \"required\": 1,\n \"img\": {\n \"url\": \"http://www.myads.com/largethumb1.png\"\n }\n },\n {\n \"id\": 126,\n \"required\": 1,\n \"data\": {\n \"value\": \"My Brand\"\n }\n },\n {\n \"id\": 127,\n \"required\": 1,\n \"data\": {\n \"value\": \"Learn all about this awesome story of someone using my product.\"\n }\n },\n {\n \"id\": 4,\n \"video\": {\n \"vasttag\": \"\u003cVAST version=\\\"2.0\\\"\u003e\u003c/VAST\u003e\"\n }\n },\n {\n \"id\": 5,\n \"link\": {\n \"url\": \"http://landing.com\",\n \"clicktrackers\": [\"http://tracker.com\"],\n \"fallback\": \"http://fallback.com\"\n }\n }\n ]\n}", + "crid": "test-creative-id", + "adomain": [ + "test.com" + ], + "ext": { + "prebid": { + "type": "native" + } + } + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/definemedia/definemediatest/supplemental/nobid-response.json b/adapters/definemedia/definemediatest/supplemental/nobid-response.json new file mode 100644 index 00000000000..aaa942da76e --- /dev/null +++ b/adapters/definemedia/definemediatest/supplemental/nobid-response.json @@ -0,0 +1,222 @@ +{ + "mockBidRequest": { + "imp": [ + { + "ext": { + "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9", + "prebid": { + "bidder": { + "definemedia": {} + } + } + }, + "id": "div-gpt-ad-1460505748561-0", + "banner": { + "topframe": 1, + "format": [ + { + "w": 300, + "h": 250 + } + ] + } + } + ], + "site": { + "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", + "domain": "localhost:8080", + "publisher": { + "domain": "localhost:8080", + "id": "1" + } + }, + "device": { + "w": 1098, + "h": 1169, + "dnt": 0, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "language": "de", + "sua": { + "source": 2, + "platform": { + "brand": "macOS", + "version": [ + "12", + "3", + "1" + ] + }, + "browsers": [ + { + "brand": "Not?A_Brand", + "version": [ + "8", + "0", + "0", + "0" + ] + }, + { + "brand": "Chromium", + "version": [ + "108", + "0", + "5359", + "124" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "108", + "0", + "5359", + "124" + ] + } + ], + "mobile": 0, + "model": "", + "bitness": "64", + "architecture": "x86" + } + }, + "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", + "test": 0, + "source": { + "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" + }, + "ext": { + "prebid": { + "auctiontimestamp": 1671449004622, + "targeting": { + "includewinners": true, + "includebidderkeys": false + }, + "debug": true, + "channel": { + "name": "pbjs", + "version": "v7.28.0" + } + } + }, + "tmax": 1000 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://rtb.conative.network/openrtb2/auction", + "body": { + "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", + "imp": [ + { + "id": "div-gpt-ad-1460505748561-0", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "topframe": 1 + }, + "ext": { + "prebid": { + "bidder": { + "definemedia": {} + } + }, + "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9" + } + } + ], + "site": { + "domain": "localhost:8080", + "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", + "publisher": { + "id": "1", + "domain": "localhost:8080" + } + }, + "device": { + "dnt": 0, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "sua": { + "browsers": [ + { + "brand": "Not?A_Brand", + "version": [ + "8", + "0", + "0", + "0" + ] + }, + { + "brand": "Chromium", + "version": [ + "108", + "0", + "5359", + "124" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "108", + "0", + "5359", + "124" + ] + } + ], + "platform": { + "brand": "macOS", + "version": [ + "12", + "3", + "1" + ] + }, + "mobile": 0, + "architecture": "x86", + "bitness": "64", + "source": 2 + }, + "h": 1169, + "w": 1098, + "language": "de" + }, + "tmax": 1000, + "source": { + "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" + }, + "ext": { + "prebid": { + "auctiontimestamp": 1.671449004622e+12, + "channel": { + "name": "pbjs", + "version": "v7.28.0" + }, + "debug": true, + "targeting": { + "includebidderkeys": false, + "includewinners": true + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": null, + "cur": null + } + } + } + ], + "expectedBidResponses": [{"currency":"USD","bids":[]}] + } diff --git a/adapters/definemedia/definemediatest/supplemental/nocontent-response.json b/adapters/definemedia/definemediatest/supplemental/nocontent-response.json new file mode 100644 index 00000000000..147d2185e1f --- /dev/null +++ b/adapters/definemedia/definemediatest/supplemental/nocontent-response.json @@ -0,0 +1,219 @@ +{ + "mockBidRequest": { + "imp": [ + { + "ext": { + "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9", + "prebid": { + "bidder": { + "definemedia": {} + } + } + }, + "id": "div-gpt-ad-1460505748561-0", + "banner": { + "topframe": 1, + "format": [ + { + "w": 300, + "h": 250 + } + ] + } + } + ], + "site": { + "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", + "domain": "localhost:8080", + "publisher": { + "domain": "localhost:8080", + "id": "1" + } + }, + "device": { + "w": 1098, + "h": 1169, + "dnt": 0, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "language": "de", + "sua": { + "source": 2, + "platform": { + "brand": "macOS", + "version": [ + "12", + "3", + "1" + ] + }, + "browsers": [ + { + "brand": "Not?A_Brand", + "version": [ + "8", + "0", + "0", + "0" + ] + }, + { + "brand": "Chromium", + "version": [ + "108", + "0", + "5359", + "124" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "108", + "0", + "5359", + "124" + ] + } + ], + "mobile": 0, + "model": "", + "bitness": "64", + "architecture": "x86" + } + }, + "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", + "test": 0, + "source": { + "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" + }, + "ext": { + "prebid": { + "auctiontimestamp": 1671449004622, + "targeting": { + "includewinners": true, + "includebidderkeys": false + }, + "debug": true, + "channel": { + "name": "pbjs", + "version": "v7.28.0" + } + } + }, + "tmax": 1000 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://rtb.conative.network/openrtb2/auction", + "body": { + "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", + "imp": [ + { + "id": "div-gpt-ad-1460505748561-0", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "topframe": 1 + }, + "ext": { + "prebid": { + "bidder": { + "definemedia": {} + } + }, + "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9" + } + } + ], + "site": { + "domain": "localhost:8080", + "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", + "publisher": { + "id": "1", + "domain": "localhost:8080" + } + }, + "device": { + "dnt": 0, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "sua": { + "browsers": [ + { + "brand": "Not?A_Brand", + "version": [ + "8", + "0", + "0", + "0" + ] + }, + { + "brand": "Chromium", + "version": [ + "108", + "0", + "5359", + "124" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "108", + "0", + "5359", + "124" + ] + } + ], + "platform": { + "brand": "macOS", + "version": [ + "12", + "3", + "1" + ] + }, + "mobile": 0, + "architecture": "x86", + "bitness": "64", + "source": 2 + }, + "h": 1169, + "w": 1098, + "language": "de" + }, + "tmax": 1000, + "source": { + "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" + }, + "ext": { + "prebid": { + "auctiontimestamp": 1.671449004622e+12, + "channel": { + "name": "pbjs", + "version": "v7.28.0" + }, + "debug": true, + "targeting": { + "includebidderkeys": false, + "includewinners": true + } + } + } + } + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [] + } \ No newline at end of file diff --git a/adapters/definemedia/definemediatest/supplemental/status_400.json b/adapters/definemedia/definemediatest/supplemental/status_400.json new file mode 100644 index 00000000000..ec772bf8428 --- /dev/null +++ b/adapters/definemedia/definemediatest/supplemental/status_400.json @@ -0,0 +1,224 @@ +{ + "mockBidRequest": { + "imp": [ + { + "ext": { + "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9", + "prebid": { + "bidder": { + "definemedia": {} + } + } + }, + "id": "div-gpt-ad-1460505748561-0", + "banner": { + "topframe": 1, + "format": [ + { + "w": 300, + "h": 250 + } + ] + } + } + ], + "site": { + "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", + "domain": "localhost:8080", + "publisher": { + "domain": "localhost:8080", + "id": "1" + } + }, + "device": { + "w": 1098, + "h": 1169, + "dnt": 0, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "language": "de", + "sua": { + "source": 2, + "platform": { + "brand": "macOS", + "version": [ + "12", + "3", + "1" + ] + }, + "browsers": [ + { + "brand": "Not?A_Brand", + "version": [ + "8", + "0", + "0", + "0" + ] + }, + { + "brand": "Chromium", + "version": [ + "108", + "0", + "5359", + "124" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "108", + "0", + "5359", + "124" + ] + } + ], + "mobile": 0, + "model": "", + "bitness": "64", + "architecture": "x86" + } + }, + "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", + "test": 0, + "source": { + "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" + }, + "ext": { + "prebid": { + "auctiontimestamp": 1671449004622, + "targeting": { + "includewinners": true, + "includebidderkeys": false + }, + "debug": true, + "channel": { + "name": "pbjs", + "version": "v7.28.0" + } + } + }, + "tmax": 1000 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://rtb.conative.network/openrtb2/auction", + "body": { + "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", + "imp": [ + { + "id": "div-gpt-ad-1460505748561-0", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "topframe": 1 + }, + "ext": { + "prebid": { + "bidder": { + "definemedia": {} + } + }, + "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9" + } + } + ], + "site": { + "domain": "localhost:8080", + "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", + "publisher": { + "id": "1", + "domain": "localhost:8080" + } + }, + "device": { + "dnt": 0, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "sua": { + "browsers": [ + { + "brand": "Not?A_Brand", + "version": [ + "8", + "0", + "0", + "0" + ] + }, + { + "brand": "Chromium", + "version": [ + "108", + "0", + "5359", + "124" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "108", + "0", + "5359", + "124" + ] + } + ], + "platform": { + "brand": "macOS", + "version": [ + "12", + "3", + "1" + ] + }, + "mobile": 0, + "architecture": "x86", + "bitness": "64", + "source": 2 + }, + "h": 1169, + "w": 1098, + "language": "de" + }, + "tmax": 1000, + "source": { + "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" + }, + "ext": { + "prebid": { + "auctiontimestamp": 1.671449004622e+12, + "channel": { + "name": "pbjs", + "version": "v7.28.0" + }, + "debug": true, + "targeting": { + "includebidderkeys": false, + "includewinners": true + } + } + } + } + }, + "mockResponse": { + "status": 400, + "body": {} + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] + } \ No newline at end of file diff --git a/adapters/definemedia/definemediatest/supplemental/status_418.json b/adapters/definemedia/definemediatest/supplemental/status_418.json new file mode 100644 index 00000000000..6e82f90476e --- /dev/null +++ b/adapters/definemedia/definemediatest/supplemental/status_418.json @@ -0,0 +1,224 @@ +{ + "mockBidRequest": { + "imp": [ + { + "ext": { + "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9", + "prebid": { + "bidder": { + "definemedia": {} + } + } + }, + "id": "div-gpt-ad-1460505748561-0", + "banner": { + "topframe": 1, + "format": [ + { + "w": 300, + "h": 250 + } + ] + } + } + ], + "site": { + "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", + "domain": "localhost:8080", + "publisher": { + "domain": "localhost:8080", + "id": "1" + } + }, + "device": { + "w": 1098, + "h": 1169, + "dnt": 0, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "language": "de", + "sua": { + "source": 2, + "platform": { + "brand": "macOS", + "version": [ + "12", + "3", + "1" + ] + }, + "browsers": [ + { + "brand": "Not?A_Brand", + "version": [ + "8", + "0", + "0", + "0" + ] + }, + { + "brand": "Chromium", + "version": [ + "108", + "0", + "5359", + "124" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "108", + "0", + "5359", + "124" + ] + } + ], + "mobile": 0, + "model": "", + "bitness": "64", + "architecture": "x86" + } + }, + "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", + "test": 0, + "source": { + "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" + }, + "ext": { + "prebid": { + "auctiontimestamp": 1671449004622, + "targeting": { + "includewinners": true, + "includebidderkeys": false + }, + "debug": true, + "channel": { + "name": "pbjs", + "version": "v7.28.0" + } + } + }, + "tmax": 1000 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://rtb.conative.network/openrtb2/auction", + "body": { + "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", + "imp": [ + { + "id": "div-gpt-ad-1460505748561-0", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "topframe": 1 + }, + "ext": { + "prebid": { + "bidder": { + "definemedia": {} + } + }, + "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9" + } + } + ], + "site": { + "domain": "localhost:8080", + "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", + "publisher": { + "id": "1", + "domain": "localhost:8080" + } + }, + "device": { + "dnt": 0, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "sua": { + "browsers": [ + { + "brand": "Not?A_Brand", + "version": [ + "8", + "0", + "0", + "0" + ] + }, + { + "brand": "Chromium", + "version": [ + "108", + "0", + "5359", + "124" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "108", + "0", + "5359", + "124" + ] + } + ], + "platform": { + "brand": "macOS", + "version": [ + "12", + "3", + "1" + ] + }, + "mobile": 0, + "architecture": "x86", + "bitness": "64", + "source": 2 + }, + "h": 1169, + "w": 1098, + "language": "de" + }, + "tmax": 1000, + "source": { + "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" + }, + "ext": { + "prebid": { + "auctiontimestamp": 1.671449004622e+12, + "channel": { + "name": "pbjs", + "version": "v7.28.0" + }, + "debug": true, + "targeting": { + "includebidderkeys": false, + "includewinners": true + } + } + } + } + }, + "mockResponse": { + "status": 418, + "body": {} + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 418. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] + } \ No newline at end of file diff --git a/adapters/definemedia/definemediatest/supplemental/unmarshal-error.json b/adapters/definemedia/definemediatest/supplemental/unmarshal-error.json new file mode 100644 index 00000000000..396d6821c36 --- /dev/null +++ b/adapters/definemedia/definemediatest/supplemental/unmarshal-error.json @@ -0,0 +1,224 @@ +{ + "mockBidRequest": { + "imp": [ + { + "ext": { + "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9", + "prebid": { + "bidder": { + "definemedia": {} + } + } + }, + "id": "div-gpt-ad-1460505748561-0", + "banner": { + "topframe": 1, + "format": [ + { + "w": 300, + "h": 250 + } + ] + } + } + ], + "site": { + "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", + "domain": "localhost:8080", + "publisher": { + "domain": "localhost:8080", + "id": "1" + } + }, + "device": { + "w": 1098, + "h": 1169, + "dnt": 0, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "language": "de", + "sua": { + "source": 2, + "platform": { + "brand": "macOS", + "version": [ + "12", + "3", + "1" + ] + }, + "browsers": [ + { + "brand": "Not?A_Brand", + "version": [ + "8", + "0", + "0", + "0" + ] + }, + { + "brand": "Chromium", + "version": [ + "108", + "0", + "5359", + "124" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "108", + "0", + "5359", + "124" + ] + } + ], + "mobile": 0, + "model": "", + "bitness": "64", + "architecture": "x86" + } + }, + "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", + "test": 0, + "source": { + "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" + }, + "ext": { + "prebid": { + "auctiontimestamp": 1671449004622, + "targeting": { + "includewinners": true, + "includebidderkeys": false + }, + "debug": true, + "channel": { + "name": "pbjs", + "version": "v7.28.0" + } + } + }, + "tmax": 1000 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://rtb.conative.network/openrtb2/auction", + "body": { + "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", + "imp": [ + { + "id": "div-gpt-ad-1460505748561-0", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "topframe": 1 + }, + "ext": { + "prebid": { + "bidder": { + "definemedia": {} + } + }, + "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9" + } + } + ], + "site": { + "domain": "localhost:8080", + "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", + "publisher": { + "id": "1", + "domain": "localhost:8080" + } + }, + "device": { + "dnt": 0, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "sua": { + "browsers": [ + { + "brand": "Not?A_Brand", + "version": [ + "8", + "0", + "0", + "0" + ] + }, + { + "brand": "Chromium", + "version": [ + "108", + "0", + "5359", + "124" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "108", + "0", + "5359", + "124" + ] + } + ], + "platform": { + "brand": "macOS", + "version": [ + "12", + "3", + "1" + ] + }, + "mobile": 0, + "architecture": "x86", + "bitness": "64", + "source": 2 + }, + "h": 1169, + "w": 1098, + "language": "de" + }, + "tmax": 1000, + "source": { + "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" + }, + "ext": { + "prebid": { + "auctiontimestamp": 1.671449004622e+12, + "channel": { + "name": "pbjs", + "version": "v7.28.0" + }, + "debug": true, + "targeting": { + "includebidderkeys": false, + "includewinners": true + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": "fail for unmarshall" + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "comparison": "literal" + } + ] + } \ No newline at end of file diff --git a/adapters/definemedia/definemediatest/supplemental/unsupported-type.json b/adapters/definemedia/definemediatest/supplemental/unsupported-type.json new file mode 100644 index 00000000000..91bfbc413c1 --- /dev/null +++ b/adapters/definemedia/definemediatest/supplemental/unsupported-type.json @@ -0,0 +1,250 @@ +{ + "mockBidRequest": { + "imp": [ + { + "ext": { + "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9", + "prebid": { + "bidder": { + "definemedia": {} + } + } + }, + "id": "div-gpt-ad-1460505748561-0", + "video": { + "w": 300, + "h": 250, + "maxduration": 60, + "minduration": 1, + "api": [1, 2, 5, 6, 7], + "mimes": ["video/mp4"], + "placement": 4, + "protocols": [2] + } + } + ], + "site": { + "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", + "domain": "localhost:8080", + "publisher": { + "domain": "localhost:8080", + "id": "1" + } + }, + "device": { + "w": 1098, + "h": 1169, + "dnt": 0, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "language": "de", + "sua": { + "source": 2, + "platform": { + "brand": "macOS", + "version": [ + "12", + "3", + "1" + ] + }, + "browsers": [ + { + "brand": "Not?A_Brand", + "version": [ + "8", + "0", + "0", + "0" + ] + }, + { + "brand": "Chromium", + "version": [ + "108", + "0", + "5359", + "124" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "108", + "0", + "5359", + "124" + ] + } + ], + "mobile": 0, + "model": "", + "bitness": "64", + "architecture": "x86" + } + }, + "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", + "test": 0, + "source": { + "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" + }, + "ext": { + "prebid": { + "auctiontimestamp": 1671449004622, + "targeting": { + "includewinners": true, + "includebidderkeys": false + }, + "debug": true, + "channel": { + "name": "pbjs", + "version": "v7.28.0" + } + } + }, + "tmax": 1000 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://rtb.conative.network/openrtb2/auction", + "body": { + "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf", + "imp": [ + { + "id": "div-gpt-ad-1460505748561-0", + "video": { + "w": 300, + "h": 250, + "maxduration": 60, + "minduration": 1, + "api": [1, 2, 5, 6, 7], + "mimes": ["video/mp4"], + "placement": 4, + "protocols": [2] + }, + "ext": { + "prebid": { + "bidder": { + "definemedia": {} + } + }, + "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9" + } + } + ], + "site": { + "domain": "localhost:8080", + "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true", + "publisher": { + "id": "1", + "domain": "localhost:8080" + } + }, + "device": { + "dnt": 0, + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36", + "sua": { + "browsers": [ + { + "brand": "Not?A_Brand", + "version": [ + "8", + "0", + "0", + "0" + ] + }, + { + "brand": "Chromium", + "version": [ + "108", + "0", + "5359", + "124" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "108", + "0", + "5359", + "124" + ] + } + ], + "platform": { + "brand": "macOS", + "version": [ + "12", + "3", + "1" + ] + }, + "mobile": 0, + "architecture": "x86", + "bitness": "64", + "source": 2 + }, + "h": 1169, + "w": 1098, + "language": "de" + }, + "tmax": 1000, + "source": { + "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf" + }, + "ext": { + "prebid": { + "auctiontimestamp": 1.671449004622e+12, + "channel": { + "name": "pbjs", + "version": "v7.28.0" + }, + "debug": true, + "targeting": { + "includebidderkeys": false, + "includewinners": true + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "46189656-7e2e-477d-b7f2-e05de224bb89", + "impid": "div-gpt-ad-1460505748561-0", + "price": 100, + "adm": "{banner html}", + "adomain": [ + "test.com" + ], + "crid": "test-creative-id", + "ext": { + "prebid": { + "type": "video" + } + } + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [{"currency":"USD","bids":[]}], + "expectedMakeBidsErrors": [ + { + "value": "Invalid mediatype in the impression", + "comparison": "literal" + } + ] +} diff --git a/adapters/definemedia/params_test.go b/adapters/definemedia/params_test.go new file mode 100644 index 00000000000..63ef5272669 --- /dev/null +++ b/adapters/definemedia/params_test.go @@ -0,0 +1,48 @@ +package definemedia + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range validParams { + if err := validator.Validate(openrtb_ext.BidderDefinemedia, json.RawMessage(p)); err != nil { + t.Errorf("Schema rejected valid params: %s", p) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderDefinemedia, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} + +var validParams = []string{ + `{"mandantId":123}`, + `{"mandantId":123, "adslotId":456}`, +} + +var invalidParams = []string{ + `{"mandantId": "42"}`, + `{"MandantId": "42"}`, + `{"mandantId":123, "adslotId":"456"}`, + `{"adslotId":456}`, + `{"adslotId":"456"}`, + `{}`, +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 6ab0dccfc7c..fd1a99aeffb 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -71,6 +71,7 @@ import ( "github.com/prebid/prebid-server/adapters/datablocks" "github.com/prebid/prebid-server/adapters/decenterads" "github.com/prebid/prebid-server/adapters/deepintent" + "github.com/prebid/prebid-server/adapters/definemedia" "github.com/prebid/prebid-server/adapters/dianomi" "github.com/prebid/prebid-server/adapters/dmx" "github.com/prebid/prebid-server/adapters/dxkulture" @@ -264,6 +265,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderDatablocks: datablocks.Builder, openrtb_ext.BidderDecenterAds: decenterads.Builder, openrtb_ext.BidderDeepintent: deepintent.Builder, + openrtb_ext.BidderDefinemedia: definemedia.Builder, openrtb_ext.BidderDianomi: dianomi.Builder, openrtb_ext.BidderEdge226: edge226.Builder, openrtb_ext.BidderDmx: dmx.Builder, diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index a5a232bbd93..89d58d06800 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -117,7 +117,6 @@ func GetDisabledBidderWarningMessages(infos config.BidderInfos) map[string]strin "engagebdr": `Bidder "engagebdr" is no longer available in Prebid Server. Please update your configuration.`, "ninthdecimal": `Bidder "ninthdecimal" is no longer available in Prebid Server. Please update your configuration.`, "kubient": `Bidder "kubient" is no longer available in Prebid Server. Please update your configuration.`, - "definemedia": `Bidder "definemedia" is no longer available in Prebid Server. Please update your configuration.`, "applogy": `Bidder "applogy" is no longer available in Prebid Server. Please update your configuration.`, "rhythmone": `Bidder "rhythmone" is no longer available in Prebid Server. Please update your configuration.`, "nanointeractive": `Bidder "nanointeractive" is no longer available in Prebid Server. Please update your configuration.`, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 22a915b769f..fbd5bb9f787 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -87,6 +87,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderDatablocks, BidderDecenterAds, BidderDeepintent, + BidderDefinemedia, BidderDianomi, BidderEdge226, BidderDmx, @@ -368,6 +369,7 @@ const ( BidderDatablocks BidderName = "datablocks" BidderDecenterAds BidderName = "decenterads" BidderDeepintent BidderName = "deepintent" + BidderDefinemedia BidderName = "definemedia" BidderDianomi BidderName = "dianomi" BidderEdge226 BidderName = "edge226" BidderDmx BidderName = "dmx" diff --git a/openrtb_ext/imp_definemedia.go b/openrtb_ext/imp_definemedia.go new file mode 100644 index 00000000000..aa94bf5de63 --- /dev/null +++ b/openrtb_ext/imp_definemedia.go @@ -0,0 +1,6 @@ +package openrtb_ext + +type ImpExtDefinemedia struct { + MandantID int64 `json:"mandantId"` + AdslotID int64 `json:"adslotId"` +} diff --git a/static/bidder-info/definemedia.yaml b/static/bidder-info/definemedia.yaml new file mode 100644 index 00000000000..a7be6fb9d23 --- /dev/null +++ b/static/bidder-info/definemedia.yaml @@ -0,0 +1,10 @@ +endpoint: "https://rtb.conative.network/openrtb2/auction" +maintainer: + email: "development@definemedia.de" + gvlVendorID: 440 # GDPR vendor list ID +capabilities: + + site: + mediaTypes: + - banner + - native diff --git a/static/bidder-params/definemedia.json b/static/bidder-params/definemedia.json new file mode 100644 index 00000000000..bf5566b4c89 --- /dev/null +++ b/static/bidder-params/definemedia.json @@ -0,0 +1,19 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Define Media Adapter Params", + "description": "A schema which validates params accepted by the DM adapter", + "type": "object", + + "properties": { + "mandantId": { + "type": "integer", + "description": "The DEFINE-MEDIA mandant id. This is a unique identifier for your account. Please contact your account manager for more information." + }, + + "adslotId":{ + "type": "integer", + "description": "The adslot id. This is a unique identifier for your adslot and may change on subparts on a website. Please contact your account manager for more information." + } + }, + "required": ["mandantId"] + } \ No newline at end of file From 53e0adcaf0af3203fd4e235d1f4fe4a4cce80a79 Mon Sep 17 00:00:00 2001 From: Veronika Solovei Date: Fri, 20 Oct 2023 08:24:10 -0700 Subject: [PATCH 195/268] Adapter Name Case Insensitive: Stored Bid Responses (#3197) --- endpoints/openrtb2/amp_auction.go | 2 +- endpoints/openrtb2/auction.go | 37 +- endpoints/openrtb2/auction_test.go | 43 +- ...ed-bid-resp-case-matching-bidder-name.json | 39 ++ ...d-resp-case-not-matching-bidder-name.json} | 2 +- ...red-bid-resp-non-existing-bidder-name.json | 34 ++ .../imp-with-stored-bid-resp.json | 6 +- .../req-two-imps-stored-bid-responses.json | 10 +- ...with-and-without-stored-bid-responses.json | 4 +- exchange/utils.go | 2 +- exchange/utils_test.go | 23 + stored_responses/stored_responses.go | 115 ++-- stored_responses/stored_responses_test.go | 571 ++++++++++-------- 13 files changed, 529 insertions(+), 359 deletions(-) create mode 100644 endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-case-matching-bidder-name.json rename endpoints/openrtb2/sample-requests/valid-whole/supplementary/{imp-with-stored-bid-resp-insensitive-bidder-name.json => imp-with-stored-bid-resp-case-not-matching-bidder-name.json} (94%) create mode 100644 endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-non-existing-bidder-name.json diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index 76b0e83cf3d..099f5d66c41 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -530,7 +530,7 @@ func (deps *endpointDeps) loadRequestJSONForAmp(httpRequest *http.Request) (req return } - storedAuctionResponses, storedBidResponses, bidderImpReplaceImp, errs = stored_responses.ProcessStoredResponses(ctx, requestJSON, deps.storedRespFetcher, deps.bidderMap) + storedAuctionResponses, storedBidResponses, bidderImpReplaceImp, errs = stored_responses.ProcessStoredResponses(ctx, &openrtb_ext.RequestWrapper{BidRequest: req}, deps.storedRespFetcher) if err != nil { errs = []error{err} return diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 2cad7a2463a..e6c9fe1fbde 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -517,12 +517,6 @@ func (deps *endpointDeps) parseRequest(httpRequest *http.Request, labels *metric return } - //Stored auction responses should be processed after stored requests due to possible impression modification - storedAuctionResponses, storedBidResponses, bidderImpReplaceImpId, errs = stored_responses.ProcessStoredResponses(ctx, requestJson, deps.storedRespFetcher, deps.bidderMap) - if len(errs) > 0 { - return nil, nil, nil, nil, nil, nil, errs - } - if err := jsonutil.UnmarshalValid(requestJson, req.BidRequest); err != nil { errs = []error{err} return @@ -548,6 +542,12 @@ func (deps *endpointDeps) parseRequest(httpRequest *http.Request, labels *metric lmt.ModifyForIOS(req.BidRequest) + //Stored auction responses should be processed after stored requests due to possible impression modification + storedAuctionResponses, storedBidResponses, bidderImpReplaceImpId, errs = stored_responses.ProcessStoredResponses(ctx, req, deps.storedRespFetcher) + if len(errs) > 0 { + return nil, nil, nil, nil, nil, nil, errs + } + hasStoredResponses := len(storedAuctionResponses) > 0 errL := deps.validateRequest(req, false, hasStoredResponses, storedBidResponses, hasStoredBidRequest) if len(errL) > 0 { @@ -1532,10 +1532,8 @@ func (deps *endpointDeps) validateImpExt(imp *openrtb_ext.ImpWrapper, aliases ma return []error{fmt.Errorf("request validation failed. The StoredAuctionResponse.ID field must be completely present with, or completely absent from, all impressions in request. No StoredAuctionResponse data found for request.imp[%d].ext.prebid \n", impIndex)} } - if len(storedBidResp) > 0 { - if err := validateStoredBidRespAndImpExtBidders(prebid.Bidder, storedBidResp, imp.ID); err != nil { - return []error{err} - } + if err := deps.validateStoredBidRespAndImpExtBidders(prebid, storedBidResp, imp.ID); err != nil { + return []error{err} } errL := []error{} @@ -2502,19 +2500,24 @@ func checkIfAppRequest(request []byte) (bool, error) { return false, nil } -func validateStoredBidRespAndImpExtBidders(bidderExts map[string]json.RawMessage, storedBidResp stored_responses.ImpBidderStoredResp, impId string) error { +func (deps *endpointDeps) validateStoredBidRespAndImpExtBidders(prebid *openrtb_ext.ExtImpPrebid, storedBidResp stored_responses.ImpBidderStoredResp, impId string) error { + if storedBidResp == nil && len(prebid.StoredBidResponse) == 0 { + return nil + } + + if storedBidResp == nil { + return generateStoredBidResponseValidationError(impId) + } if bidResponses, ok := storedBidResp[impId]; ok { - if len(bidResponses) != len(bidderExts) { + if len(bidResponses) != len(prebid.Bidder) { return generateStoredBidResponseValidationError(impId) } for bidderName := range bidResponses { - bidder := bidderName - normalizedCoreBidder, ok := openrtb_ext.NormalizeBidderName(bidder) - if ok { - bidder = normalizedCoreBidder.String() + if _, bidderNameOk := deps.normalizeBidderName(bidderName); !bidderNameOk { + return fmt.Errorf(`unrecognized bidder "%v"`, bidderName) } - if _, present := bidderExts[bidder]; !present { + if _, present := prebid.Bidder[bidderName]; !present { return generateStoredBidResponseValidationError(impId) } } diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index 530d197e2ae..bab25261175 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -4991,8 +4991,8 @@ func TestParseRequestStoredResponses(t *testing.T) { } func TestParseRequestStoredBidResponses(t *testing.T) { - bidRespId1 := json.RawMessage(`{"id": "resp_id1", "seatbid": [{"bid": [{"id": "bid_id1"}], "seat": "testBidder1"}], "bidid": "123", "cur": "USD"}`) - bidRespId2 := json.RawMessage(`{"id": "resp_id2", "seatbid": [{"bid": [{"id": "bid_id2"}], "seat": "testBidder2"}], "bidid": "124", "cur": "USD"}`) + bidRespId1 := json.RawMessage(`{"id": "resp_id1", "seatbid": [{"bid": [{"id": "bid_id1"}], "seat": "telaria"}], "bidid": "123", "cur": "USD"}`) + bidRespId2 := json.RawMessage(`{"id": "resp_id2", "seatbid": [{"bid": [{"id": "bid_id2"}], "seat": "amx"}], "bidid": "124", "cur": "USD"}`) bidRespId3 := json.RawMessage(`{"id": "resp_id3", "seatbid": [{"bid": [{"id": "bid_id3"}], "seat": "APPNEXUS"}], "bidid": "125", "cur": "USD"}`) mockStoredBidResponses := map[string]json.RawMessage{ "bidResponseId1": bidRespId1, @@ -5011,15 +5011,23 @@ func TestParseRequestStoredBidResponses(t *testing.T) { name: "req imp has valid stored bid response", givenRequestBody: validRequest(t, "imp-with-stored-bid-resp.json"), expectedStoredBidResponses: map[string]map[string]json.RawMessage{ - "imp-id1": {"testBidder1": bidRespId1}, + "imp-id1": {"telaria": bidRespId1}, }, expectedErrorCount: 0, }, { - name: "req imp has valid stored bid response with case insensitive bidder name", - givenRequestBody: validRequest(t, "imp-with-stored-bid-resp-insensitive-bidder-name.json"), + name: "req imp has valid stored bid response with case not-matching bidder name", + givenRequestBody: validRequest(t, "imp-with-stored-bid-resp-case-not-matching-bidder-name.json"), expectedStoredBidResponses: map[string]map[string]json.RawMessage{ - "imp-id3": {"APPNEXUS": bidRespId3}, + "imp-id3": {"appnexus": bidRespId3}, + }, + expectedErrorCount: 0, + }, + { + name: "req imp has valid stored bid response with case matching bidder name", + givenRequestBody: validRequest(t, "imp-with-stored-bid-resp-case-matching-bidder-name.json"), + expectedStoredBidResponses: map[string]map[string]json.RawMessage{ + "imp-id3": {"appnexus": bidRespId3}, }, expectedErrorCount: 0, }, @@ -5027,8 +5035,8 @@ func TestParseRequestStoredBidResponses(t *testing.T) { name: "req has two imps with valid stored bid responses", givenRequestBody: validRequest(t, "req-two-imps-stored-bid-responses.json"), expectedStoredBidResponses: map[string]map[string]json.RawMessage{ - "imp-id1": {"testBidder1": bidRespId1}, - "imp-id2": {"testBidder2": bidRespId2}, + "imp-id1": {"telaria": bidRespId1}, + "imp-id2": {"amx": bidRespId2}, }, expectedErrorCount: 0, }, @@ -5036,7 +5044,7 @@ func TestParseRequestStoredBidResponses(t *testing.T) { name: "req has two imps one with valid stored bid responses and another one without stored bid responses", givenRequestBody: validRequest(t, "req-two-imps-with-and-without-stored-bid-responses.json"), expectedStoredBidResponses: map[string]map[string]json.RawMessage{ - "imp-id2": {"testBidder2": bidRespId2}, + "imp-id2": {"amx": bidRespId2}, }, expectedErrorCount: 0, }, @@ -5044,7 +5052,13 @@ func TestParseRequestStoredBidResponses(t *testing.T) { name: "req has two imps with missing stored bid responses", givenRequestBody: validRequest(t, "req-two-imps-missing-stored-bid-response.json"), expectedStoredBidResponses: nil, - expectedErrorCount: 2, + expectedErrorCount: 1, + }, + { + name: "req imp has valid stored bid response with non existing bidder name", + givenRequestBody: validRequest(t, "imp-with-stored-bid-resp-non-existing-bidder-name.json"), + expectedStoredBidResponses: nil, + expectedErrorCount: 1, }, } for _, test := range tests { @@ -5063,7 +5077,7 @@ func TestParseRequestStoredBidResponses(t *testing.T) { map[string]string{}, false, []byte{}, - map[string]openrtb_ext.BidderName{"testBidder1": "testBidder1", "testBidder2": "testBidder2", "appnexus": "appnexus"}, + map[string]openrtb_ext.BidderName{"telaria": "telaria", "amx": "amx", "appnexus": "appnexus"}, nil, nil, hardcodedResponseIPValidator{response: true}, @@ -5078,6 +5092,7 @@ func TestParseRequestStoredBidResponses(t *testing.T) { req := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(test.givenRequestBody)) _, _, _, storedBidResponses, _, _, errL := deps.parseRequest(req, &metrics.Labels{}, hookExecutor) if test.expectedErrorCount == 0 { + assert.Empty(t, errL) assert.Equal(t, test.expectedStoredBidResponses, storedBidResponses, "stored responses should match") } else { assert.Contains(t, errL[0].Error(), test.expectedError, "error should match") @@ -5653,8 +5668,10 @@ func TestValidateStoredResp(t *testing.T) { } for _, test := range testCases { - errorList := deps.validateRequest(test.givenRequestWrapper, false, test.hasStoredAuctionResponses, test.storedBidResponses, false) - assert.Equalf(t, test.expectedErrorList, errorList, "Error doesn't match: %s\n", test.description) + t.Run(test.description, func(t *testing.T) { + errorList := deps.validateRequest(test.givenRequestWrapper, false, test.hasStoredAuctionResponses, test.storedBidResponses, false) + assert.Equalf(t, test.expectedErrorList, errorList, "Error doesn't match: %s\n", test.description) + }) } } diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-case-matching-bidder-name.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-case-matching-bidder-name.json new file mode 100644 index 00000000000..49576023b04 --- /dev/null +++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-case-matching-bidder-name.json @@ -0,0 +1,39 @@ +{ + "description": "request with impression with stored bid response with case matching bidder name", + "mockBidRequest": { + "id": "request-with-stored-resp", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "imp-id3", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "appnexus": { + "placementId": 12883451 + }, + "prebid": { + "storedbidresponse": [ + { + "bidder": "appnexus", + "id": "bidResponseId3" + } + ] + } + } + } + ], + "user": { + "yob": 1989 + } + }, + "expectedReturnCode": 200 +} \ No newline at end of file diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-insensitive-bidder-name.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-case-not-matching-bidder-name.json similarity index 94% rename from endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-insensitive-bidder-name.json rename to endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-case-not-matching-bidder-name.json index e7b688d4d83..bcebe81472d 100644 --- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-insensitive-bidder-name.json +++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-case-not-matching-bidder-name.json @@ -1,5 +1,5 @@ { - "description": "request with impression with stored bid response with sensitive bidder name", + "description": "request with impression with stored bid response with case not matching bidder name", "mockBidRequest": { "id": "request-with-stored-resp", "site": { diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-non-existing-bidder-name.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-non-existing-bidder-name.json new file mode 100644 index 00000000000..d8685307e20 --- /dev/null +++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-non-existing-bidder-name.json @@ -0,0 +1,34 @@ +{ + "description": "request with impression with stored bid response", + "mockBidRequest": { + "id": "request-with-stored-resp", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "imp-id1", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidderABC": {}, + "prebid": { + "storedbidresponse": [ + {"bidder":"bidderABC", "id": "bidResponseId1"} + ] + } + } + } + ], + "user": { + "yob": 1989 + } + }, + "expectedReturnCode": 200 +} diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp.json index e72cce49355..692a34c4f41 100644 --- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp.json +++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp.json @@ -17,12 +17,10 @@ ] }, "ext": { - "appnexus": { - "placementId": 12883451 - }, + "telaria": {}, "prebid": { "storedbidresponse": [ - {"bidder":"testBidder1", "id": "bidResponseId1"} + {"bidder":"telaria", "id": "bidResponseId1"} ] } } diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-two-imps-stored-bid-responses.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-two-imps-stored-bid-responses.json index 5906eb9149c..09b4bc57746 100644 --- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-two-imps-stored-bid-responses.json +++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-two-imps-stored-bid-responses.json @@ -17,12 +17,12 @@ ] }, "ext": { - "appnexus": { + "telaria": { "placementId": 12883451 }, "prebid": { "storedbidresponse": [ - {"bidder":"testBidder1", "id": "bidResponseId1"} + {"bidder":"telaria", "id": "bidResponseId1"} ] } } @@ -38,12 +38,10 @@ ] }, "ext": { - "appnexus": { - "placementId": 12883451 - }, + "amx": {}, "prebid": { "storedbidresponse": [ - {"bidder":"testBidder2", "id": "bidResponseId2"} + {"bidder":"amx", "id": "bidResponseId2"} ] } } diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-two-imps-with-and-without-stored-bid-responses.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-two-imps-with-and-without-stored-bid-responses.json index 6122e4df066..5387a9d61ae 100644 --- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-two-imps-with-and-without-stored-bid-responses.json +++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-two-imps-with-and-without-stored-bid-responses.json @@ -33,12 +33,12 @@ ] }, "ext": { - "appnexus": { + "amx": { "placementId": 12883451 }, "prebid": { "storedbidresponse": [ - {"bidder":"testBidder2", "id": "bidResponseId2"} + {"bidder":"amx", "id": "bidResponseId2"} ] } } diff --git a/exchange/utils.go b/exchange/utils.go index c7acfaefce3..ea6b317dae1 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -958,7 +958,7 @@ func buildBidResponseRequest(req *openrtb2.BidRequest, BidderCoreName: resolvedBidder, BidderName: bidderName, BidderStoredResponses: impResps, - ImpReplaceImpId: bidderImpReplaceImpID[string(resolvedBidder)], + ImpReplaceImpId: bidderImpReplaceImpID[string(bidderName)], IsRequestAlias: isRequestAlias, BidderLabels: metrics.AdapterLabels{Adapter: resolvedBidder}, } diff --git a/exchange/utils_test.go b/exchange/utils_test.go index b413a6b292e..3c28a43c33e 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "fmt" + "github.com/prebid/prebid-server/stored_responses" "sort" "testing" @@ -4754,3 +4755,25 @@ func TestApplyBidAdjustmentToFloor(t *testing.T) { }) } } + +func TestBuildBidResponseRequestBidderName(t *testing.T) { + bidderImpResponses := stored_responses.BidderImpsWithBidResponses{ + openrtb_ext.BidderName("appnexus"): {"impId1": json.RawMessage(`{}`), "impId2": json.RawMessage(`{}`)}, + openrtb_ext.BidderName("appneXUS"): {"impId3": json.RawMessage(`{}`), "impId4": json.RawMessage(`{}`)}, + } + + bidderImpReplaceImpID := stored_responses.BidderImpReplaceImpID{ + "appnexus": {"impId1": true, "impId2": false}, + "appneXUS": {"impId3": true, "impId4": false}, + } + result := buildBidResponseRequest(nil, bidderImpResponses, nil, bidderImpReplaceImpID) + + resultAppnexus := result["appnexus"] + assert.Equal(t, resultAppnexus.BidderName, openrtb_ext.BidderName("appnexus")) + assert.Equal(t, resultAppnexus.ImpReplaceImpId, map[string]bool{"impId1": true, "impId2": false}) + + resultAppneXUS := result["appneXUS"] + assert.Equal(t, resultAppneXUS.BidderName, openrtb_ext.BidderName("appneXUS")) + assert.Equal(t, resultAppneXUS.ImpReplaceImpId, map[string]bool{"impId3": true, "impId4": false}) + +} diff --git a/stored_responses/stored_responses.go b/stored_responses/stored_responses.go index ef8fe50619d..d6944a6f30f 100644 --- a/stored_responses/stored_responses.go +++ b/stored_responses/stored_responses.go @@ -4,12 +4,11 @@ import ( "context" "encoding/json" "fmt" + "strings" - "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/util/jsonutil" ) type ImpsWithAuctionResponseIDs map[string]string @@ -57,8 +56,7 @@ func buildStoredResp(storedBidResponses ImpBidderStoredResp) BidderImpsWithBidRe return bidderToImpToResponses } -func extractStoredResponsesIds(impInfo []ImpExtPrebidData, - bidderMap map[string]openrtb_ext.BidderName) ( +func extractStoredResponsesIds(impInfo []*openrtb_ext.ImpWrapper) ( StoredResponseIDs, ImpBiddersWithBidResponseIDs, ImpsWithAuctionResponseIDs, @@ -76,53 +74,62 @@ func extractStoredResponsesIds(impInfo []ImpExtPrebidData, impBidderReplaceImp := ImpBidderReplaceImpID{} for index, impData := range impInfo { - impId, err := jsonparser.GetString(impData.Imp, "id") + impId := impData.ID + impExt, err := impData.GetImpExt() if err != nil { - return nil, nil, nil, nil, fmt.Errorf("request.imp[%d] missing required field: \"id\"", index) + return nil, nil, nil, nil, err + } + impExtPrebid := impExt.GetPrebid() + if impExtPrebid == nil { + continue } - if impData.ImpExtPrebid.StoredAuctionResponse != nil { - if len(impData.ImpExtPrebid.StoredAuctionResponse.ID) == 0 { + if impExtPrebid.StoredAuctionResponse != nil { + if len(impExtPrebid.StoredAuctionResponse.ID) == 0 { return nil, nil, nil, nil, fmt.Errorf("request.imp[%d] has ext.prebid.storedauctionresponse specified, but \"id\" field is missing ", index) } - allStoredResponseIDs = append(allStoredResponseIDs, impData.ImpExtPrebid.StoredAuctionResponse.ID) + allStoredResponseIDs = append(allStoredResponseIDs, impExtPrebid.StoredAuctionResponse.ID) - impAuctionResponseIDs[impId] = impData.ImpExtPrebid.StoredAuctionResponse.ID + impAuctionResponseIDs[impId] = impExtPrebid.StoredAuctionResponse.ID } - if len(impData.ImpExtPrebid.StoredBidResponse) > 0 { + if len(impExtPrebid.StoredBidResponse) > 0 { + + // bidders can be specified in imp.ext and in imp.ext.prebid.bidders + allBidderNames := make([]string, 0) + for bidderName := range impExtPrebid.Bidder { + allBidderNames = append(allBidderNames, bidderName) + } + for extData := range impExt.GetExt() { + // no bidders will not be processed + allBidderNames = append(allBidderNames, extData) + } bidderStoredRespId := make(map[string]string) bidderReplaceImpId := make(map[string]bool) - for _, bidderResp := range impData.ImpExtPrebid.StoredBidResponse { + for _, bidderResp := range impExtPrebid.StoredBidResponse { if len(bidderResp.ID) == 0 || len(bidderResp.Bidder) == 0 { return nil, nil, nil, nil, fmt.Errorf("request.imp[%d] has ext.prebid.storedbidresponse specified, but \"id\" or/and \"bidder\" fields are missing ", index) } - bidderName := bidderResp.Bidder - normalizedCoreBidder, ok := openrtb_ext.NormalizeBidderName(bidderResp.Bidder) - if ok { - bidderName = normalizedCoreBidder.String() - } - //check if bidder is valid/exists - if _, isValid := bidderMap[bidderName]; !isValid { - return nil, nil, nil, nil, fmt.Errorf("request.imp[impId: %s].ext.prebid.bidder contains unknown bidder: %s. Did you forget an alias in request.ext.prebid.aliases?", impId, bidderResp.Bidder) - } - // bidder is unique per one bid stored response - // if more than one bidder specified the last defined bidder id will take precedence - bidderStoredRespId[bidderResp.Bidder] = bidderResp.ID - impBiddersWithBidResponseIDs[impId] = bidderStoredRespId - - // stored response config can specify if imp id should be replaced with imp id from request - replaceImpId := true - if bidderResp.ReplaceImpId != nil { - // replaceimpid is true if not specified - replaceImpId = *bidderResp.ReplaceImpId - } - bidderReplaceImpId[bidderResp.Bidder] = replaceImpId - impBidderReplaceImp[impId] = bidderReplaceImpId - //storedAuctionResponseIds are not unique, but fetch will return single data for repeated ids - allStoredResponseIDs = append(allStoredResponseIDs, bidderResp.ID) + for _, bidderName := range allBidderNames { + if _, found := bidderStoredRespId[bidderName]; !found && strings.EqualFold(bidderName, bidderResp.Bidder) { + bidderStoredRespId[bidderName] = bidderResp.ID + impBiddersWithBidResponseIDs[impId] = bidderStoredRespId + + // stored response config can specify if imp id should be replaced with imp id from request + replaceImpId := true + if bidderResp.ReplaceImpId != nil { + // replaceimpid is true if not specified + replaceImpId = *bidderResp.ReplaceImpId + } + bidderReplaceImpId[bidderName] = replaceImpId + impBidderReplaceImp[impId] = bidderReplaceImpId + + //storedAuctionResponseIds are not unique, but fetch will return single data for repeated ids + allStoredResponseIDs = append(allStoredResponseIDs, bidderResp.ID) + } + } } } } @@ -135,14 +142,11 @@ func extractStoredResponsesIds(impInfo []ImpExtPrebidData, // Note that processStoredResponses must be called after processStoredRequests // because stored imps and stored requests can contain stored auction responses and stored bid responses // so the stored requests/imps have to be merged into the incoming request prior to processing stored auction responses. -func ProcessStoredResponses(ctx context.Context, requestJson []byte, storedRespFetcher stored_requests.Fetcher, bidderMap map[string]openrtb_ext.BidderName) (ImpsWithBidResponses, ImpBidderStoredResp, BidderImpReplaceImpID, []error) { - impInfo, errs := parseImpInfo(requestJson) - if len(errs) > 0 { - return nil, nil, nil, errs - } - storedResponsesIds, impBidderToStoredBidResponseId, impIdToRespId, impBidderReplaceImp, err := extractStoredResponsesIds(impInfo, bidderMap) +func ProcessStoredResponses(ctx context.Context, requestWrapper *openrtb_ext.RequestWrapper, storedRespFetcher stored_requests.Fetcher) (ImpsWithBidResponses, ImpBidderStoredResp, BidderImpReplaceImpID, []error) { + + storedResponsesIds, impBidderToStoredBidResponseId, impIdToRespId, impBidderReplaceImp, err := extractStoredResponsesIds(requestWrapper.GetImp()) if err != nil { - return nil, nil, nil, append(errs, err) + return nil, nil, nil, []error{err} } if len(storedResponsesIds) > 0 { @@ -201,28 +205,3 @@ func buildStoredResponsesMaps(storedResponses StoredResponseIdToStoredResponse, } return impIdToStoredResp, impBidderToStoredBidResponse, errs } - -// parseImpInfo parses the request JSON and returns the impressions with their unmarshalled imp.ext.prebid -// copied from exchange to isolate stored responses code from auction dependencies -func parseImpInfo(requestJson []byte) (impData []ImpExtPrebidData, errs []error) { - - if impArray, dataType, _, err := jsonparser.Get(requestJson, "imp"); err == nil && dataType == jsonparser.Array { - _, err = jsonparser.ArrayEach(impArray, func(imp []byte, _ jsonparser.ValueType, _ int, err error) { - impExtData, _, _, err := jsonparser.Get(imp, "ext", "prebid") - var impExtPrebid openrtb_ext.ExtImpPrebid - if impExtData != nil { - if err := jsonutil.Unmarshal(impExtData, &impExtPrebid); err != nil { - errs = append(errs, err) - } - } - newImpData := ImpExtPrebidData{imp, impExtPrebid} - impData = append(impData, newImpData) - }) - } - return -} - -type ImpExtPrebidData struct { - Imp json.RawMessage - ImpExtPrebid openrtb_ext.ExtImpPrebid -} diff --git a/stored_responses/stored_responses_test.go b/stored_responses/stored_responses_test.go index c4ddea278a7..209b34a650b 100644 --- a/stored_responses/stored_responses_test.go +++ b/stored_responses/stored_responses_test.go @@ -163,136 +163,109 @@ func TestBuildStoredBidResponses(t *testing.T) { } func TestProcessStoredAuctionAndBidResponsesErrors(t *testing.T) { - bidderMap := map[string]openrtb_ext.BidderName{"testBidder": "testBidder"} - testCases := []struct { description string - requestJson []byte + request openrtb2.BidRequest expectedErrorList []error }{ { description: "Invalid stored auction response format: empty stored Auction Response Id", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ "prebid": { - "storedauctionresponse": { - } - } - } - } - ]}`), + "storedauctionresponse": {} + }}`)}, + }, + }, expectedErrorList: []error{errors.New("request.imp[0] has ext.prebid.storedauctionresponse specified, but \"id\" field is missing ")}, }, { description: "Invalid stored bid response format: empty storedbidresponse.bidder", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ "prebid": { "storedbidresponse": [ { "id": "123abc"}] - } - } - } - ]}`), + }}`)}, + }, + }, expectedErrorList: []error{errors.New("request.imp[0] has ext.prebid.storedbidresponse specified, but \"id\" or/and \"bidder\" fields are missing ")}, }, { description: "Invalid stored bid response format: empty storedbidresponse.id", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ "prebid": { "storedbidresponse": [ { "bidder": "testbidder"}] - } - } - } - ]}`), + }}`)}, + }, + }, expectedErrorList: []error{errors.New("request.imp[0] has ext.prebid.storedbidresponse specified, but \"id\" or/and \"bidder\" fields are missing ")}, }, - { - description: "Invalid stored bid response: storedbidresponse.bidder not found", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { - "prebid": { - "storedbidresponse": [ - { "bidder": "testBidder123", "id": "123abc"}] - } - } - } - ]}`), - expectedErrorList: []error{errors.New("request.imp[impId: imp-id1].ext.prebid.bidder contains unknown bidder: testBidder123. Did you forget an alias in request.ext.prebid.aliases?")}, - }, { description: "Invalid stored auction response format: empty stored Auction Response Id in second imp", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ "prebid": { "storedauctionresponse": { "id":"123" } - } - } - }, - { - "id": "imp-id2", - "ext": { + }}`)}, + {ID: "imp-id2", + Ext: json.RawMessage(`{ "prebid": { - "storedauctionresponse": { + "storedauctionresponse": { "id":"" } - } - } - } - ]}`), + }}`)}, + }, + }, expectedErrorList: []error{errors.New("request.imp[1] has ext.prebid.storedauctionresponse specified, but \"id\" field is missing ")}, }, { description: "Invalid stored bid response format: empty stored bid Response Id in second imp", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ "prebid": { - "storedbidresponse": [ + "storedbidresponse": [ {"bidder":"testBidder", "id": "123abc"} ] - } - } - }, - { - "id": "imp-id2", - "ext": { + }}`)}, + {ID: "imp-id2", + Ext: json.RawMessage(`{ "prebid": { - "storedbidresponse": [ + "storedbidresponse": [ {"bidder":"testBidder", "id": ""} ] - } - } - } - ]}`), + }}`)}, + }, + }, expectedErrorList: []error{errors.New("request.imp[1] has ext.prebid.storedbidresponse specified, but \"id\" or/and \"bidder\" fields are missing ")}, }, } for _, test := range testCases { - _, _, _, errorList := ProcessStoredResponses(nil, test.requestJson, nil, bidderMap) - assert.Equalf(t, test.expectedErrorList, errorList, "Error doesn't match: %s\n", test.description) + t.Run(test.description, func(t *testing.T) { + rw := &openrtb_ext.RequestWrapper{BidRequest: &test.request} + _, _, _, errorList := ProcessStoredResponses(nil, rw, nil) + assert.Equalf(t, test.expectedErrorList, errorList, "Error doesn't match: %s\n", test.description) + }) } } func TestProcessStoredAuctionAndBidResponses(t *testing.T) { - bidderMap := map[string]openrtb_ext.BidderName{"bidderA": "bidderA", "bidderB": "bidderB"} bidStoredResp1 := json.RawMessage(`[{"bid": [{"id": "bid_id1"],"seat": "bidderA"}]`) bidStoredResp2 := json.RawMessage(`[{"bid": [{"id": "bid_id2"],"seat": "bidderB"}]`) bidStoredResp3 := json.RawMessage(`[{"bid": [{"id": "bid_id3"],"seat": "bidderA"}]`) @@ -305,33 +278,31 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { testCases := []struct { description string - requestJson []byte + request openrtb2.BidRequest expectedStoredAuctionResponses ImpsWithBidResponses expectedStoredBidResponses ImpBidderStoredResp expectedBidderImpReplaceImpID BidderImpReplaceImpID }{ { description: "No stored responses", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { - "prebid": { - - } - } - } - ]}`), + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ + "prebid": {} + }`)}, + }, + }, expectedStoredAuctionResponses: nil, expectedStoredBidResponses: nil, expectedBidderImpReplaceImpID: nil, }, { description: "Stored auction response one imp", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ "appnexus": { "placementId": 123 }, @@ -340,9 +311,9 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { "id": "1" } } - } - } - ]}`), + }`)}, + }, + }, expectedStoredAuctionResponses: ImpsWithBidResponses{ "imp-id1": bidStoredResp1, }, @@ -351,11 +322,11 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { }, { description: "Stored bid response one imp", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { - "appnexus": { + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ + "bidderA": { "placementId": 123 }, "prebid": { @@ -363,9 +334,9 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { {"bidder":"bidderA", "id": "1"} ] } - } - } - ]}`), + }`)}, + }, + }, expectedStoredAuctionResponses: ImpsWithBidResponses{}, expectedStoredBidResponses: ImpBidderStoredResp{ "imp-id1": {"bidderA": bidStoredResp1}, @@ -376,11 +347,14 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { }, { description: "Stored bid responses two bidders one imp", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { - "appnexus": { + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ + "bidderA": { + "placementId": 123 + }, + "bidderB": { "placementId": 123 }, "prebid": { @@ -389,9 +363,9 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { {"bidder":"bidderB", "id": "2", "replaceimpid": false} ] } - } - } - ]}`), + }`)}, + }, + }, expectedStoredAuctionResponses: ImpsWithBidResponses{}, expectedStoredBidResponses: ImpBidderStoredResp{ "imp-id1": {"bidderA": bidStoredResp1, "bidderB": bidStoredResp2}, @@ -401,14 +375,120 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { "bidderB": map[string]bool{"imp-id1": false}, }, }, + { + description: "Stored bid responses two same mixed case bidders one imp", + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ + "bidderA": { + "placementId": 123 + }, + "BIDDERa": { + "placementId": 123 + }, + "prebid": { + "storedbidresponse": [ + {"bidder":"bidderA", "id": "1", "replaceimpid": true}, + {"bidder":"bidderB", "id": "2", "replaceimpid": false} + ] + } + }`)}, + }, + }, + expectedStoredAuctionResponses: ImpsWithBidResponses{}, + expectedStoredBidResponses: ImpBidderStoredResp{ + "imp-id1": {"bidderA": bidStoredResp1, "BIDDERa": bidStoredResp1}, + }, + expectedBidderImpReplaceImpID: BidderImpReplaceImpID{ + "BIDDERa": map[string]bool{"imp-id1": true}, + "bidderA": map[string]bool{"imp-id1": true}, + }, + }, + { + description: "Stored bid responses 3 same mixed case bidders in imp.ext and imp.ext.prebid.bidders one imp", + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ + "bidderA": { + "placementId": 123 + }, + "BIDDERa": { + "placementId": 123 + }, + "prebid": { + "bidder": { + "BiddeRa": { + "placementId": 12883451 + } + }, + "storedbidresponse": [ + {"bidder":"bidderA", "id": "1", "replaceimpid": true}, + {"bidder":"bidderB", "id": "2", "replaceimpid": false} + ] + } + }`)}, + }, + }, + expectedStoredAuctionResponses: ImpsWithBidResponses{}, + expectedStoredBidResponses: ImpBidderStoredResp{ + "imp-id1": {"bidderA": bidStoredResp1, "BIDDERa": bidStoredResp1, "BiddeRa": bidStoredResp1}, + }, + expectedBidderImpReplaceImpID: BidderImpReplaceImpID{ + "BIDDERa": map[string]bool{"imp-id1": true}, + "bidderA": map[string]bool{"imp-id1": true}, + "BiddeRa": map[string]bool{"imp-id1": true}, + }, + }, + { + description: "Stored bid responses 3 same mixed case bidders in imp.ext and imp.ext.prebid.bidders one imp, duplicated stored response", + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ + "bidderA": { + "placementId": 123 + }, + "BIDDERa": { + "placementId": 123 + }, + "prebid": { + "bidder": { + "BiddeRa": { + "placementId": 12883451 + } + }, + "storedbidresponse": [ + {"bidder":"bidderA", "id": "1", "replaceimpid": true}, + {"bidder":"bidderA", "id": "2", "replaceimpid": true}, + {"bidder":"bidderB", "id": "2", "replaceimpid": false} + ] + } + }`)}, + }, + }, + expectedStoredAuctionResponses: ImpsWithBidResponses{}, + expectedStoredBidResponses: ImpBidderStoredResp{ + "imp-id1": {"bidderA": bidStoredResp1, "BIDDERa": bidStoredResp1, "BiddeRa": bidStoredResp1}, + }, + expectedBidderImpReplaceImpID: BidderImpReplaceImpID{ + "BIDDERa": map[string]bool{"imp-id1": true}, + "bidderA": map[string]bool{"imp-id1": true}, + "BiddeRa": map[string]bool{"imp-id1": true}, + }, + }, { //This is not a valid scenario for real auction request, added for testing purposes description: "Stored auction and bid responses one imp", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { - "appnexus": { + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ + "bidderA": { + "placementId": 123 + }, + "bidderB": { "placementId": 123 }, "prebid": { @@ -420,9 +500,9 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { {"bidder":"bidderB", "id": "2"} ] } - } - } - ]}`), + }`)}, + }, + }, expectedStoredAuctionResponses: ImpsWithBidResponses{ "imp-id1": bidStoredResp1, }, @@ -436,10 +516,10 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { }, { description: "Stored auction response three imps", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ "appnexus": { "placementId": 123 }, @@ -448,11 +528,9 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { "id": "1" } } - } - }, - { - "id": "imp-id2", - "ext": { + }`)}, + {ID: "imp-id2", + Ext: json.RawMessage(`{ "appnexus": { "placementId": 123 }, @@ -461,11 +539,10 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { "id": "2" } } - } - }, + }`)}, { - "id": "imp-id3", - "ext": { + ID: "imp-id3", + Ext: json.RawMessage(`{ "appnexus": { "placementId": 123 }, @@ -474,9 +551,10 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { "id": "3" } } - } - } - ]}`), + }`), + }, + }, + }, expectedStoredAuctionResponses: ImpsWithBidResponses{ "imp-id1": bidStoredResp1, "imp-id2": bidStoredResp2, @@ -487,10 +565,10 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { }, { description: "Stored auction response three imps duplicated stored auction response", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ "appnexus": { "placementId": 123 }, @@ -499,11 +577,9 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { "id": "1" } } - } - }, - { - "id": "imp-id2", - "ext": { + }`)}, + {ID: "imp-id2", + Ext: json.RawMessage(`{ "appnexus": { "placementId": 123 }, @@ -512,11 +588,10 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { "id": "2" } } - } - }, + }`)}, { - "id": "imp-id3", - "ext": { + ID: "imp-id3", + Ext: json.RawMessage(`{ "appnexus": { "placementId": 123 }, @@ -525,9 +600,10 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { "id": "2" } } - } - } - ]}`), + }`), + }, + }, + }, expectedStoredAuctionResponses: ImpsWithBidResponses{ "imp-id1": bidStoredResp1, "imp-id2": bidStoredResp2, @@ -538,11 +614,14 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { }, { description: "Stored bid responses two bidders two imp", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { - "appnexus": { + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ + "bidderA": { + "placementId": 123 + }, + "bidderB": { "placementId": 123 }, "prebid": { @@ -551,12 +630,13 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { {"bidder":"bidderB", "id": "2"} ] } - } - }, - { - "id": "imp-id2", - "ext": { - "appnexus": { + }`)}, + {ID: "imp-id2", + Ext: json.RawMessage(`{ + "bidderA": { + "placementId": 123 + }, + "bidderB": { "placementId": 123 }, "prebid": { @@ -565,9 +645,9 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { {"bidder":"bidderB", "id": "2", "replaceimpid": false} ] } - } - } - ]}`), + }`)}, + }, + }, expectedStoredAuctionResponses: ImpsWithBidResponses{}, expectedStoredBidResponses: ImpBidderStoredResp{ "imp-id1": {"bidderA": bidStoredResp1, "bidderB": bidStoredResp2}, @@ -581,17 +661,19 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) { } for _, test := range testCases { - storedAuctionResponses, storedBidResponses, bidderImpReplaceImpId, errorList := ProcessStoredResponses(nil, test.requestJson, fetcher, bidderMap) - assert.Equal(t, test.expectedStoredAuctionResponses, storedAuctionResponses, "storedAuctionResponses doesn't match: %s\n", test.description) - assert.Equalf(t, test.expectedStoredBidResponses, storedBidResponses, "storedBidResponses doesn't match: %s\n", test.description) - assert.Equal(t, test.expectedBidderImpReplaceImpID, bidderImpReplaceImpId, "bidderImpReplaceImpId doesn't match: %s\n", test.description) - assert.Nil(t, errorList, "Error should be nil") + t.Run(test.description, func(t *testing.T) { + rw := openrtb_ext.RequestWrapper{BidRequest: &test.request} + storedAuctionResponses, storedBidResponses, bidderImpReplaceImpId, errorList := ProcessStoredResponses(nil, &rw, fetcher) + assert.Equal(t, test.expectedStoredAuctionResponses, storedAuctionResponses) + assert.Equal(t, test.expectedStoredBidResponses, storedBidResponses) + assert.Equal(t, test.expectedBidderImpReplaceImpID, bidderImpReplaceImpId) + assert.Nil(t, errorList, "Error should be nil") + }) } } func TestProcessStoredResponsesNotFoundResponse(t *testing.T) { - bidderMap := map[string]openrtb_ext.BidderName{"bidderA": "bidderA", "bidderB": "bidderB"} bidStoredResp1 := json.RawMessage(`[{"bid": [{"id": "bid_id1"],"seat": "bidderA"}]`) bidStoredResp2 := json.RawMessage(`[{"bid": [{"id": "bid_id2"],"seat": "bidderB"}]`) mockStoredResponses := map[string]json.RawMessage{ @@ -604,16 +686,16 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) { testCases := []struct { description string - requestJson []byte + request openrtb2.BidRequest expectedErrors []error }{ { description: "Stored bid response with nil data, one bidder one imp", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { - "appnexus": { + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ + "bidderB": { "placementId": 123 }, "prebid": { @@ -621,20 +703,20 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) { {"bidder":"bidderB", "id": "3"} ] } - } - } - ]}`), + }`)}, + }, + }, expectedErrors: []error{ errors.New("failed to fetch stored bid response for impId = imp-id1, bidder = bidderB and storedBidResponse id = 3"), }, }, { description: "Stored bid response with nil data, one bidder, two imps, one with correct stored response", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { - "appnexus": { + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ + "bidderB": { "placementId": 123 }, "prebid": { @@ -642,12 +724,10 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) { {"bidder":"bidderB", "id": "1"} ] } - } - }, - { - "id": "imp-id2", - "ext": { - "appnexus": { + }`)}, + {ID: "imp-id2", + Ext: json.RawMessage(`{ + "bidderB": { "placementId": 123 }, "prebid": { @@ -655,20 +735,20 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) { {"bidder":"bidderB", "id": "3"} ] } - } - } - ]}`), + }`)}, + }, + }, expectedErrors: []error{ errors.New("failed to fetch stored bid response for impId = imp-id2, bidder = bidderB and storedBidResponse id = 3"), }, }, { description: "Stored bid response with nil data, one bidder, two imps, both with correct stored response", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { - "appnexus": { + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ + "bidderB": { "placementId": 123 }, "prebid": { @@ -676,12 +756,10 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) { {"bidder":"bidderB", "id": "4"} ] } - } - }, - { - "id": "imp-id2", - "ext": { - "appnexus": { + }`)}, + {ID: "imp-id2", + Ext: json.RawMessage(`{ + "bidderB": { "placementId": 123 }, "prebid": { @@ -689,9 +767,9 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) { {"bidder":"bidderB", "id": "3"} ] } - } - } - ]}`), + }`)}, + }, + }, expectedErrors: []error{ errors.New("failed to fetch stored bid response for impId = imp-id1, bidder = bidderB and storedBidResponse id = 4"), errors.New("failed to fetch stored bid response for impId = imp-id2, bidder = bidderB and storedBidResponse id = 3"), @@ -699,10 +777,10 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) { }, { description: "Stored auction response with nil data and one imp", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ "appnexus": { "placementId": 123 }, @@ -711,19 +789,19 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) { "id": "4" } } - } - } - ]}`), + }`)}, + }, + }, expectedErrors: []error{ errors.New("failed to fetch stored auction response for impId = imp-id1 and storedAuctionResponse id = 4"), }, }, { description: "Stored auction response with nil data, and two imps with nil responses", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ "appnexus": { "placementId": 123 }, @@ -732,11 +810,9 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) { "id": "4" } } - } - }, - { - "id": "imp-id2", - "ext": { + }`)}, + {ID: "imp-id2", + Ext: json.RawMessage(`{ "appnexus": { "placementId": 123 }, @@ -745,9 +821,9 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) { "id": "3" } } - } - } - ]}`), + }`)}, + }, + }, expectedErrors: []error{ errors.New("failed to fetch stored auction response for impId = imp-id1 and storedAuctionResponse id = 4"), errors.New("failed to fetch stored auction response for impId = imp-id2 and storedAuctionResponse id = 3"), @@ -755,10 +831,10 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) { }, { description: "Stored auction response with nil data, two imps, one with nil responses", - requestJson: []byte(`{"imp": [ - { - "id": "imp-id1", - "ext": { + request: openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1", + Ext: json.RawMessage(`{ "appnexus": { "placementId": 123 }, @@ -767,11 +843,9 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) { "id": "2" } } - } - }, - { - "id": "imp-id2", - "ext": { + }`)}, + {ID: "imp-id2", + Ext: json.RawMessage(`{ "appnexus": { "placementId": 123 }, @@ -780,9 +854,9 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) { "id": "3" } } - } - } - ]}`), + }`)}, + }, + }, expectedErrors: []error{ errors.New("failed to fetch stored auction response for impId = imp-id2 and storedAuctionResponse id = 3"), }, @@ -790,10 +864,13 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) { } for _, test := range testCases { - _, _, _, errorList := ProcessStoredResponses(nil, test.requestJson, fetcher, bidderMap) - for _, err := range test.expectedErrors { - assert.Contains(t, errorList, err, "incorrect errors returned: %s", test.description) - } + t.Run(test.description, func(t *testing.T) { + rw := openrtb_ext.RequestWrapper{BidRequest: &test.request} + _, _, _, errorList := ProcessStoredResponses(nil, &rw, fetcher) + for _, err := range test.expectedErrors { + assert.Contains(t, errorList, err) + } + }) } } @@ -847,8 +924,10 @@ func TestFlipMap(t *testing.T) { } for _, test := range testCases { - actualResult := flipMap(test.inImpBidderReplaceImpID) - assert.Equal(t, test.outBidderImpReplaceImpID, actualResult, "Incorrect flipped map for test case %s\n", test.description) + t.Run(test.description, func(t *testing.T) { + actualResult := flipMap(test.inImpBidderReplaceImpID) + assert.Equal(t, test.outBidderImpReplaceImpID, actualResult) + }) } } From 6b98a812c2d8adf69e9ff45eaeb108f8097231f3 Mon Sep 17 00:00:00 2001 From: guscarreon Date: Fri, 20 Oct 2023 14:26:41 -0400 Subject: [PATCH 196/268] Adapter Name Case Insensitive: alternate bidder codes (#3229) --- .../exchangetest/alternate-bidder-codes.json | 272 ++++++++++++++++++ exchange/utils.go | 30 +- exchange/utils_test.go | 221 +++++++++++++- openrtb_ext/alternatebiddercodes.go | 31 +- openrtb_ext/alternatebiddercodes_test.go | 148 ++++++++++ 5 files changed, 683 insertions(+), 19 deletions(-) create mode 100644 exchange/exchangetest/alternate-bidder-codes.json diff --git a/exchange/exchangetest/alternate-bidder-codes.json b/exchange/exchangetest/alternate-bidder-codes.json new file mode 100644 index 00000000000..26a7a05d4e1 --- /dev/null +++ b/exchange/exchangetest/alternate-bidder-codes.json @@ -0,0 +1,272 @@ +{ + "incomingRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "imp-id-1", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "prebid": { + "bidder": { + "pubmatic": { + "publisherId": 5890 + }, + "appnexus": { + "placementId": 1 + } + } + } + } + } + ], + "ext": { + "prebid": { + "alternatebiddercodes": { + "enabled": true, + "bidders": { + "PUBmatic": { + "enabled": true, + "allowedbiddercodes": [ + "groupm" + ] + } + } + } + } + } + } + }, + "outgoingRequests": { + "pubmatic": { + "expectRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "imp-id-1", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "publisherId": 5890 + } + } + } + ], + "ext": { + "prebid": { + "alternatebiddercodes": { + "enabled": true, + "bidders": { + "pubmatic": { + "enabled": true, + "allowedbiddercodes": [ + "groupm" + ] + } + } + } + } + } + } + }, + "mockResponse": { + "pbsSeatBids": [ + { + "pbsBids": [ + { + "ortbBid": { + "id": "pubmatic-bid-1", + "impid": "imp-id-1", + "price": 0.71 + }, + "bidType": "video", + "bidMeta": { + "adaptercode": "pubmatic" + } + } + ], + "seat": "pubmatic" + }, + { + "pbsBids": [ + { + "ortbBid": { + "id": "pubmatic-bid-2", + "impid": "imp-id-1", + "price": 0.51 + }, + "bidType": "video", + "bidMeta": { + "adaptercode": "pubmatic" + } + } + ], + "seat": "groupm" + } + ] + } + }, + "appnexus": { + "expectRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "imp-id-1", + "video": { + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "placementId": 1 + } + } + } + ], + "ext": { + "prebid": { + "alternatebiddercodes": { + "enabled": true, + "bidders": null + } + } + } + } + }, + "mockResponse": { + "pbsSeatBids": [ + { + "pbsBids": [ + { + "ortbBid": { + "id": "appnexus-bid-1", + "impid": "imp-id-1", + "price": 0.3 + }, + "bidType": "banner", + "bidMeta": { + "adaptercode": "appnexus" + } + } + ], + "seat": "appnexus" + }, + { + "pbsBids": [ + { + "ortbBid": { + "id": "appnexus-bid-2", + "impid": "imp-id-1", + "price": 0.3 + }, + "bidType": "banner", + "bidMeta": { + "adaptercode": "appnexus" + } + } + ], + "seat": "groupm" + } + ] + } + } + }, + "response": { + "bids": { + "id": "some-request-id", + "seatbid": [ + { + "seat": "groupm", + "bid": [ + { + "id": "pubmatic-bid-2", + "impid": "imp-id-1", + "price": 0.51, + "ext": { + "origbidcpm": 0.51, + "prebid": { + "meta": { + "adaptercode": "pubmatic" + }, + "type": "video" + } + } + }, + { + "id": "appnexus-bid-2", + "impid": "imp-id-1", + "price": 0.3, + "ext": { + "origbidcpm": 0.3, + "prebid": { + "meta": { + "adaptercode": "appnexus" + }, + "type": "banner" + } + } + } + ] + }, + { + "seat": "pubmatic", + "bid": [ + { + "id": "pubmatic-bid-1", + "impid": "imp-id-1", + "price": 0.71, + "ext": { + "origbidcpm": 0.71, + "prebid": { + "meta": { + "adaptercode": "pubmatic" + }, + "type": "video" + } + } + } + ] + }, + { + "seat": "appnexus", + "bid": [ + { + "id": "appnexus-bid-1", + "impid": "imp-id-1", + "price": 0.3, + "ext": { + "origbidcpm": 0.3, + "prebid": { + "meta": { + "adaptercode": "appnexus" + }, + "type": "banner" + } + } + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/exchange/utils.go b/exchange/utils.go index ea6b317dae1..8b4774a36f4 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -442,30 +442,32 @@ func buildRequestExtForBidder(bidder string, requestExt json.RawMessage, request } func buildRequestExtAlternateBidderCodes(bidder string, accABC *openrtb_ext.ExtAlternateBidderCodes, reqABC *openrtb_ext.ExtAlternateBidderCodes) *openrtb_ext.ExtAlternateBidderCodes { - if reqABC != nil { - alternateBidderCodes := &openrtb_ext.ExtAlternateBidderCodes{ - Enabled: reqABC.Enabled, - } - if bidderCodes, ok := reqABC.Bidders[bidder]; ok { - alternateBidderCodes.Bidders = map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{ - bidder: bidderCodes, - } - } - return alternateBidderCodes + + if altBidderCodes := copyExtAlternateBidderCodes(bidder, reqABC); altBidderCodes != nil { + return altBidderCodes } - if accABC != nil { + if altBidderCodes := copyExtAlternateBidderCodes(bidder, accABC); altBidderCodes != nil { + return altBidderCodes + } + + return nil +} + +func copyExtAlternateBidderCodes(bidder string, altBidderCodes *openrtb_ext.ExtAlternateBidderCodes) *openrtb_ext.ExtAlternateBidderCodes { + if altBidderCodes != nil { alternateBidderCodes := &openrtb_ext.ExtAlternateBidderCodes{ - Enabled: accABC.Enabled, + Enabled: altBidderCodes.Enabled, } - if bidderCodes, ok := accABC.Bidders[bidder]; ok { + + if bidderCodes, ok := altBidderCodes.IsBidderInAlternateBidderCodes(bidder); ok { alternateBidderCodes.Bidders = map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{ bidder: bidderCodes, } } + return alternateBidderCodes } - return nil } diff --git a/exchange/utils_test.go b/exchange/utils_test.go index 3c28a43c33e..3a00c37c7b1 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -5,10 +5,11 @@ import ( "encoding/json" "errors" "fmt" - "github.com/prebid/prebid-server/stored_responses" "sort" "testing" + "github.com/prebid/prebid-server/stored_responses" + gpplib "github.com/prebid/go-gpp" "github.com/prebid/go-gpp/constants" "github.com/prebid/openrtb/v19/openrtb2" @@ -4756,6 +4757,224 @@ func TestApplyBidAdjustmentToFloor(t *testing.T) { } } +func TestBuildRequestExtAlternateBidderCodes(t *testing.T) { + type testInput struct { + bidderNameRaw string + accABC *openrtb_ext.ExtAlternateBidderCodes + reqABC *openrtb_ext.ExtAlternateBidderCodes + } + testCases := []struct { + desc string + in testInput + expected *openrtb_ext.ExtAlternateBidderCodes + }{ + { + desc: "No biddername, nil reqABC and accABC", + in: testInput{}, + expected: nil, + }, + { + desc: "No biddername, non-nil reqABC", + in: testInput{ + reqABC: &openrtb_ext.ExtAlternateBidderCodes{}, + }, + expected: &openrtb_ext.ExtAlternateBidderCodes{}, + }, + { + desc: "No biddername, non-nil accABC", + in: testInput{ + accABC: &openrtb_ext.ExtAlternateBidderCodes{}, + }, + expected: &openrtb_ext.ExtAlternateBidderCodes{}, + }, + { + desc: "No biddername, non-nil reqABC nor accABC", + in: testInput{ + reqABC: &openrtb_ext.ExtAlternateBidderCodes{}, + accABC: &openrtb_ext.ExtAlternateBidderCodes{}, + }, + expected: &openrtb_ext.ExtAlternateBidderCodes{}, + }, + { + desc: "non-nil reqABC", + in: testInput{ + bidderNameRaw: "pubmatic", + reqABC: &openrtb_ext.ExtAlternateBidderCodes{}, + }, + expected: &openrtb_ext.ExtAlternateBidderCodes{}, + }, + { + desc: "non-nil accABC", + in: testInput{ + bidderNameRaw: "pubmatic", + accABC: &openrtb_ext.ExtAlternateBidderCodes{}, + }, + expected: &openrtb_ext.ExtAlternateBidderCodes{}, + }, + { + desc: "both reqABC and accABC enabled and bidder matches elements in accABC but reqABC comes first", + in: testInput{ + bidderNameRaw: "PUBmatic", + reqABC: &openrtb_ext.ExtAlternateBidderCodes{ + Enabled: true, + Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{ + "appnexus": { + AllowedBidderCodes: []string{"pubCode1"}, + }, + }, + }, + accABC: &openrtb_ext.ExtAlternateBidderCodes{ + Enabled: true, + Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{ + "PubMatic": { + AllowedBidderCodes: []string{"pubCode2"}, + }, + }, + }, + }, + expected: &openrtb_ext.ExtAlternateBidderCodes{Enabled: true}, + }, + { + desc: "both reqABC and accABC enabled and bidder matches elements in both but we prioritize reqABC", + in: testInput{ + bidderNameRaw: "pubmatic", + reqABC: &openrtb_ext.ExtAlternateBidderCodes{ + Enabled: true, + Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{ + "PubMatic": { + AllowedBidderCodes: []string{"pubCode"}, + }, + }, + }, + accABC: &openrtb_ext.ExtAlternateBidderCodes{ + Enabled: true, + Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{ + "appnexus": { + AllowedBidderCodes: []string{"anxsCode"}, + }, + }, + }, + }, + expected: &openrtb_ext.ExtAlternateBidderCodes{ + Enabled: true, + Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{ + "pubmatic": { + AllowedBidderCodes: []string{"pubCode"}, + }, + }, + }, + }, + { + desc: "nil reqABC non-nil accABC enabled and bidder matches elements in accABC", + in: testInput{ + bidderNameRaw: "APPnexus", + accABC: &openrtb_ext.ExtAlternateBidderCodes{ + Enabled: true, + Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{ + "appnexus": { + AllowedBidderCodes: []string{"anxsCode"}, + }, + }, + }, + }, + expected: &openrtb_ext.ExtAlternateBidderCodes{ + Enabled: true, + Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{ + "APPnexus": { + AllowedBidderCodes: []string{"anxsCode"}, + }, + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + alternateBidderCodes := buildRequestExtAlternateBidderCodes(tc.in.bidderNameRaw, tc.in.accABC, tc.in.reqABC) + assert.Equal(t, tc.expected, alternateBidderCodes) + }) + } +} + +func TestCopyExtAlternateBidderCodes(t *testing.T) { + type testInput struct { + bidder string + alternateBidderCodes *openrtb_ext.ExtAlternateBidderCodes + } + testCases := []struct { + desc string + in testInput + expected *openrtb_ext.ExtAlternateBidderCodes + }{ + { + desc: "pass a nil alternateBidderCodes argument, expect nil output", + in: testInput{}, + expected: nil, + }, + { + desc: "non-nil alternateBidderCodes argument but bidder doesn't match", + in: testInput{ + alternateBidderCodes: &openrtb_ext.ExtAlternateBidderCodes{ + Enabled: true, + }, + }, + expected: &openrtb_ext.ExtAlternateBidderCodes{ + Enabled: true, + }, + }, + { + desc: "non-nil alternateBidderCodes argument bidder is identical to one element in map", + in: testInput{ + bidder: "appnexus", + alternateBidderCodes: &openrtb_ext.ExtAlternateBidderCodes{ + Enabled: true, + Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{ + "appnexus": { + AllowedBidderCodes: []string{"adnxs"}, + }, + }, + }, + }, + expected: &openrtb_ext.ExtAlternateBidderCodes{ + Enabled: true, + Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{ + "appnexus": { + AllowedBidderCodes: []string{"adnxs"}, + }, + }, + }, + }, + { + desc: "case insensitive match, keep bidder casing in output", + in: testInput{ + bidder: "AppNexus", + alternateBidderCodes: &openrtb_ext.ExtAlternateBidderCodes{ + Enabled: true, + Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{ + "appnexus": { + AllowedBidderCodes: []string{"adnxs"}, + }, + }, + }, + }, + expected: &openrtb_ext.ExtAlternateBidderCodes{ + Enabled: true, + Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{ + "AppNexus": { + AllowedBidderCodes: []string{"adnxs"}, + }, + }, + }, + }, + } + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + alternateBidderCodes := copyExtAlternateBidderCodes(tc.in.bidder, tc.in.alternateBidderCodes) + assert.Equal(t, tc.expected, alternateBidderCodes) + }) + } +} + func TestBuildBidResponseRequestBidderName(t *testing.T) { bidderImpResponses := stored_responses.BidderImpsWithBidResponses{ openrtb_ext.BidderName("appnexus"): {"impId1": json.RawMessage(`{}`), "impId2": json.RawMessage(`{}`)}, diff --git a/openrtb_ext/alternatebiddercodes.go b/openrtb_ext/alternatebiddercodes.go index 49291a3e5e8..3dcb6c781fa 100644 --- a/openrtb_ext/alternatebiddercodes.go +++ b/openrtb_ext/alternatebiddercodes.go @@ -1,6 +1,9 @@ package openrtb_ext -import "fmt" +import ( + "fmt" + "strings" +) // ExtAlternateBidderCodes defines list of alternate bidder codes allowed by adatpers. This overrides host level configs. type ExtAlternateBidderCodes struct { @@ -14,7 +17,7 @@ type ExtAdapterAlternateBidderCodes struct { } func (bidderCodes *ExtAlternateBidderCodes) IsValidBidderCode(bidder, alternateBidder string) (bool, error) { - if alternateBidder == "" || bidder == alternateBidder { + if alternateBidder == "" || strings.EqualFold(bidder, alternateBidder) { return true, nil } @@ -26,8 +29,8 @@ func (bidderCodes *ExtAlternateBidderCodes) IsValidBidderCode(bidder, alternateB return false, alternateBidderNotDefinedError(bidder, alternateBidder) } - adapterCfg, ok := bidderCodes.Bidders[bidder] - if !ok { + adapterCfg, found := bidderCodes.IsBidderInAlternateBidderCodes(bidder) + if !found { return false, alternateBidderNotDefinedError(bidder, alternateBidder) } @@ -56,3 +59,23 @@ func alternateBidderDisabledError(bidder, alternateBidder string) error { func alternateBidderNotDefinedError(bidder, alternateBidder string) error { return fmt.Errorf("alternateBidderCodes not defined for adapter %q, rejecting bids for %q", bidder, alternateBidder) } + +// IsBidderInAlternateBidderCodes tries to find bidder in the altBidderCodes.Bidders map in a case sensitive +// manner first. If no match is found it'll try it in a case insensitive way in linear time +func (bidderCodes *ExtAlternateBidderCodes) IsBidderInAlternateBidderCodes(bidder string) (ExtAdapterAlternateBidderCodes, bool) { + if len(bidder) > 0 && bidderCodes != nil && len(bidderCodes.Bidders) > 0 { + // try constant time exact match + if adapterCfg, found := bidderCodes.Bidders[bidder]; found { + return adapterCfg, true + } + + // check if we can find with a case insensitive comparison + for bidderName, adapterCfg := range bidderCodes.Bidders { + if strings.EqualFold(bidder, bidderName) { + return adapterCfg, true + } + } + } + + return ExtAdapterAlternateBidderCodes{}, false +} diff --git a/openrtb_ext/alternatebiddercodes_test.go b/openrtb_ext/alternatebiddercodes_test.go index 438aebad559..f9229b13d2a 100644 --- a/openrtb_ext/alternatebiddercodes_test.go +++ b/openrtb_ext/alternatebiddercodes_test.go @@ -35,6 +35,14 @@ func TestAlternateBidderCodes_IsValidBidderCode(t *testing.T) { }, wantIsValid: true, }, + { + name: "alternateBidder and bidder are the same under Unicode case-folding (default non-extra bid case with seat's alternateBidder explicitly set)", + args: args{ + bidder: "pubmatic", + alternateBidder: "pubmatic", + }, + wantIsValid: true, + }, { name: "account.alternatebiddercodes config not defined (default, reject bid)", args: args{ @@ -98,6 +106,20 @@ func TestAlternateBidderCodes_IsValidBidderCode(t *testing.T) { }, wantIsValid: true, }, + { + name: "bidder is different in casing than the entry in account.alternatebiddercodes but they match because our case insensitive comparison", + args: args{ + bidder: "PUBmatic", + alternateBidder: "groupm", + }, + fields: fields{ + Enabled: true, + Bidders: map[string]ExtAdapterAlternateBidderCodes{ + "pubmatic": {Enabled: true}, + }, + }, + wantIsValid: true, + }, { name: "allowedBidderCodes is *", args: args{ @@ -178,3 +200,129 @@ func TestAlternateBidderCodes_IsValidBidderCode(t *testing.T) { }) } } + +func TestIsBidderInAlternateBidderCodes(t *testing.T) { + type testInput struct { + bidder string + bidderCodes *ExtAlternateBidderCodes + } + type testOutput struct { + adapterCfg ExtAdapterAlternateBidderCodes + found bool + } + testCases := []struct { + desc string + in testInput + expected testOutput + }{ + { + desc: "empty bidder", + in: testInput{ + bidderCodes: &ExtAlternateBidderCodes{}, + }, + expected: testOutput{ + adapterCfg: ExtAdapterAlternateBidderCodes{}, + found: false, + }, + }, + { + desc: "nil ExtAlternateBidderCodes", + in: testInput{ + bidder: "appnexus", + bidderCodes: nil, + }, + expected: testOutput{ + adapterCfg: ExtAdapterAlternateBidderCodes{}, + found: false, + }, + }, + { + desc: "nil ExtAlternateBidderCodes.Bidder map", + in: testInput{ + bidder: "appnexus", + bidderCodes: &ExtAlternateBidderCodes{}, + }, + expected: testOutput{ + adapterCfg: ExtAdapterAlternateBidderCodes{}, + found: false, + }, + }, + { + desc: "nil ExtAlternateBidderCodes.Bidder map", + in: testInput{ + bidder: "appnexus", + bidderCodes: &ExtAlternateBidderCodes{ + Bidders: nil, + }, + }, + expected: testOutput{ + adapterCfg: ExtAdapterAlternateBidderCodes{}, + found: false, + }, + }, + { + desc: "bidder arg identical to entry in Bidders map", + in: testInput{ + bidder: "appnexus", + bidderCodes: &ExtAlternateBidderCodes{ + Bidders: map[string]ExtAdapterAlternateBidderCodes{ + "appnexus": { + Enabled: true, + AllowedBidderCodes: []string{"abcCode"}, + }, + }, + }, + }, + expected: testOutput{ + adapterCfg: ExtAdapterAlternateBidderCodes{ + Enabled: true, + AllowedBidderCodes: []string{"abcCode"}, + }, + found: true, + }, + }, + { + desc: "bidder arg matches an entry in Bidders map with case insensitive comparisson", + in: testInput{ + bidder: "appnexus", + bidderCodes: &ExtAlternateBidderCodes{ + Bidders: map[string]ExtAdapterAlternateBidderCodes{ + "AppNexus": {AllowedBidderCodes: []string{"adnxsCode"}}, + "PubMatic": {AllowedBidderCodes: []string{"pubCode"}}, + "Rubicon": {AllowedBidderCodes: []string{"rCode"}}, + }, + }, + }, + expected: testOutput{ + adapterCfg: ExtAdapterAlternateBidderCodes{ + AllowedBidderCodes: []string{"adnxsCode"}, + }, + found: true, + }, + }, + { + desc: "bidder arg doesn't match any entry in map", + in: testInput{ + bidder: "unknown", + bidderCodes: &ExtAlternateBidderCodes{ + Bidders: map[string]ExtAdapterAlternateBidderCodes{ + "AppNexus": {AllowedBidderCodes: []string{"adnxsCode"}}, + "PubMatic": {AllowedBidderCodes: []string{"pubCode"}}, + "Rubicon": {AllowedBidderCodes: []string{"rCode"}}, + }, + }, + }, + expected: testOutput{ + adapterCfg: ExtAdapterAlternateBidderCodes{}, + found: false, + }, + }, + } + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + adapterCfg, found := tc.in.bidderCodes.IsBidderInAlternateBidderCodes(tc.in.bidder) + assert.Equal(t, tc.expected.adapterCfg, adapterCfg) + assert.Equal(t, tc.expected.found, found) + }) + } +} From ec729e6e5d50a1306d76332fda52108b9d313c1d Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Fri, 20 Oct 2023 16:22:32 -0400 Subject: [PATCH 197/268] Increment Package Version To V2 (#3245) --- .gitignore | 4 +- account/account.go | 14 +- account/account_test.go | 12 +- adapters/33across/33across.go | 8 +- adapters/33across/33across_test.go | 6 +- adapters/33across/params_test.go | 2 +- adapters/aax/aax.go | 8 +- adapters/aax/aax_test.go | 6 +- adapters/aax/params_test.go | 2 +- adapters/aceex/aceex.go | 10 +- adapters/aceex/aceex_test.go | 6 +- adapters/aceex/params_test.go | 2 +- adapters/acuityads/acuityads.go | 10 +- adapters/acuityads/acuityads_test.go | 6 +- adapters/acuityads/params_test.go | 2 +- adapters/adapterstest/test_json.go | 6 +- adapters/adf/adf.go | 8 +- adapters/adf/adf_test.go | 6 +- adapters/adf/params_test.go | 2 +- adapters/adgeneration/adgeneration.go | 8 +- adapters/adgeneration/adgeneration_test.go | 8 +- adapters/adgeneration/params_test.go | 2 +- adapters/adhese/adhese.go | 10 +- adapters/adhese/adhese_test.go | 6 +- adapters/adhese/params_test.go | 2 +- adapters/adkernel/adkernel.go | 10 +- adapters/adkernel/adkernel_test.go | 6 +- adapters/adkernelAdn/adkernelAdn.go | 10 +- adapters/adkernelAdn/adkernelAdn_test.go | 6 +- adapters/adman/adman.go | 8 +- adapters/adman/adman_test.go | 6 +- adapters/adman/params_test.go | 2 +- adapters/admixer/admixer.go | 8 +- adapters/admixer/admixer_test.go | 6 +- adapters/admixer/params_test.go | 2 +- adapters/adnuntius/adnuntius.go | 10 +- adapters/adnuntius/adnuntius_test.go | 8 +- adapters/adnuntius/params_test.go | 2 +- adapters/adocean/adocean.go | 10 +- adapters/adocean/adocean_test.go | 6 +- adapters/adocean/params_test.go | 2 +- adapters/adoppler/adoppler.go | 10 +- adapters/adoppler/adoppler_test.go | 6 +- adapters/adot/adot.go | 8 +- adapters/adot/adot_test.go | 8 +- adapters/adot/params_test.go | 2 +- adapters/adpone/adpone.go | 8 +- adapters/adpone/adpone_test.go | 6 +- adapters/adprime/adprime.go | 8 +- adapters/adprime/adprime_test.go | 6 +- adapters/adprime/params_test.go | 2 +- adapters/adquery/adquery.go | 8 +- adapters/adquery/adquery_test.go | 7 +- adapters/adquery/params_test.go | 2 +- adapters/adquery/types.go | 2 +- adapters/adrino/adrino.go | 8 +- adapters/adrino/adrino_test.go | 6 +- adapters/adrino/params_test.go | 2 +- adapters/adsinteractive/adsinteractive.go | 8 +- .../adsinteractive/adsinteractive_test.go | 6 +- adapters/adsinteractive/params_test.go | 2 +- adapters/adtarget/adtarget.go | 8 +- adapters/adtarget/adtarget_test.go | 6 +- adapters/adtarget/params_test.go | 2 +- adapters/adtelligent/adtelligent.go | 8 +- adapters/adtelligent/adtelligent_test.go | 6 +- adapters/adtelligent/params_test.go | 2 +- adapters/adtrgtme/adtrgtme.go | 8 +- adapters/adtrgtme/adtrgtme_test.go | 6 +- adapters/adtrgtme/params_test.go | 2 +- adapters/advangelists/advangelists.go | 10 +- adapters/advangelists/advangelists_test.go | 6 +- adapters/advangelists/params_test.go | 3 +- adapters/adview/adview.go | 10 +- adapters/adview/adview_test.go | 6 +- adapters/adview/params_test.go | 2 +- adapters/adxcg/adxcg.go | 8 +- adapters/adxcg/adxcg_test.go | 6 +- adapters/adyoulike/adyoulike.go | 8 +- adapters/adyoulike/adyoulike_test.go | 6 +- adapters/adyoulike/params_test.go | 2 +- adapters/aidem/aidem.go | 8 +- adapters/aidem/aidem_test.go | 6 +- adapters/aidem/params_test.go | 2 +- adapters/aja/aja.go | 8 +- adapters/aja/aja_test.go | 6 +- adapters/algorix/algorix.go | 10 +- adapters/algorix/algorix_test.go | 6 +- adapters/algorix/params_test.go | 3 +- adapters/amx/amx.go | 8 +- adapters/amx/amx_test.go | 8 +- adapters/amx/params_test.go | 2 +- adapters/apacdex/apacdex.go | 8 +- adapters/apacdex/apacdex_test.go | 6 +- adapters/apacdex/params_test.go | 2 +- adapters/appnexus/appnexus.go | 18 +- adapters/appnexus/appnexus_test.go | 6 +- adapters/appnexus/params_test.go | 2 +- adapters/appush/appush.go | 8 +- adapters/appush/appush_test.go | 6 +- adapters/appush/params_test.go | 2 +- adapters/audienceNetwork/facebook.go | 12 +- adapters/audienceNetwork/facebook_test.go | 8 +- adapters/automatad/automatad.go | 8 +- adapters/automatad/automatad_test.go | 6 +- adapters/automatad/params_test.go | 2 +- adapters/avocet/avocet.go | 8 +- adapters/avocet/avocet_test.go | 10 +- adapters/axis/axis.go | 8 +- adapters/axis/axis_test.go | 6 +- adapters/axis/params_test.go | 2 +- adapters/axonix/axonix.go | 10 +- adapters/axonix/axonix_test.go | 6 +- adapters/axonix/params_test.go | 2 +- adapters/beachfront/beachfront.go | 8 +- adapters/beachfront/beachfront_test.go | 6 +- adapters/beachfront/params_test.go | 2 +- adapters/beintoo/beintoo.go | 8 +- adapters/beintoo/beintoo_test.go | 6 +- adapters/beintoo/params_test.go | 2 +- adapters/bematterfull/bematterfull.go | 10 +- .../bematterfull/bematterfulltest_test.go | 6 +- adapters/bematterfull/params_test.go | 2 +- adapters/between/between.go | 10 +- adapters/between/between_test.go | 6 +- adapters/between/params_test.go | 2 +- adapters/beyondmedia/beyondmedia.go | 8 +- adapters/beyondmedia/beyondmedia_test.go | 6 +- adapters/beyondmedia/params_test.go | 2 +- adapters/bidder.go | 8 +- adapters/bidmachine/bidmachine.go | 10 +- adapters/bidmachine/bidmachine_test.go | 6 +- adapters/bidmachine/params_test.go | 2 +- adapters/bidmyadz/bidmyadz.go | 8 +- adapters/bidmyadz/bidmyadz_test.go | 6 +- adapters/bidmyadz/params_test.go | 2 +- adapters/bidscube/bidscube.go | 8 +- adapters/bidscube/bidscube_test.go | 6 +- adapters/bidscube/params_test.go | 2 +- adapters/bidstack/bidstack.go | 6 +- adapters/bidstack/bidstack_test.go | 6 +- adapters/bidstack/params_test.go | 2 +- adapters/bizzclick/bizzclick.go | 10 +- adapters/bizzclick/bizzclick_test.go | 6 +- adapters/bizzclick/params_test.go | 2 +- adapters/bliink/bliink.go | 8 +- adapters/bliink/bliink_test.go | 6 +- adapters/bliink/params_test.go | 3 +- adapters/blue/blue.go | 8 +- adapters/blue/blue_test.go | 6 +- adapters/bluesea/bluesea.go | 8 +- adapters/bluesea/bluesea_test.go | 6 +- adapters/bluesea/params_test.go | 2 +- adapters/bmtm/brightmountainmedia.go | 8 +- adapters/bmtm/brightmountainmedia_test.go | 6 +- adapters/bmtm/params_test.go | 2 +- adapters/boldwin/boldwin.go | 8 +- adapters/boldwin/boldwin_test.go | 6 +- adapters/boldwin/params_test.go | 2 +- adapters/brave/brave.go | 10 +- adapters/brave/brave_test.go | 6 +- adapters/brave/params_test.go | 2 +- .../cadent_aperture_mx/cadentaperturemx.go | 8 +- .../cadentaperturemx_test.go | 8 +- adapters/cadent_aperture_mx/params_test.go | 2 +- adapters/ccx/ccx.go | 8 +- adapters/ccx/ccx_test.go | 6 +- adapters/ccx/params_test.go | 2 +- adapters/coinzilla/coinzilla.go | 8 +- adapters/coinzilla/coinzilla_test.go | 6 +- adapters/coinzilla/params_test.go | 2 +- adapters/colossus/colossus.go | 8 +- adapters/colossus/colossus_test.go | 6 +- adapters/colossus/params_test.go | 2 +- adapters/compass/compass.go | 8 +- adapters/compass/compass_test.go | 6 +- adapters/compass/params_test.go | 2 +- adapters/connectad/connectad.go | 8 +- adapters/connectad/connectad_test.go | 6 +- adapters/connectad/params_test.go | 2 +- adapters/consumable/consumable.go | 10 +- adapters/consumable/consumable_test.go | 8 +- adapters/consumable/params_test.go | 2 +- adapters/conversant/conversant.go | 8 +- adapters/conversant/conversant_test.go | 6 +- adapters/cpmstar/cpmstar.go | 8 +- adapters/cpmstar/cpmstar_test.go | 6 +- adapters/cpmstar/params_test.go | 2 +- adapters/criteo/criteo.go | 8 +- adapters/criteo/criteo_test.go | 7 +- adapters/criteo/params_test.go | 2 +- adapters/cwire/cwire.go | 8 +- adapters/cwire/cwire_test.go | 6 +- adapters/cwire/params_test.go | 2 +- adapters/datablocks/datablocks.go | 10 +- adapters/datablocks/datablocks_test.go | 6 +- adapters/decenterads/decenterads.go | 8 +- adapters/decenterads/decenterads_test.go | 6 +- adapters/decenterads/params_test.go | 2 +- adapters/deepintent/deepintent.go | 8 +- adapters/deepintent/deepintent_test.go | 6 +- adapters/deepintent/params_test.go | 2 +- adapters/definemedia/definemedia.go | 8 +- adapters/definemedia/definemedia_test.go | 6 +- adapters/definemedia/params_test.go | 2 +- adapters/dianomi/dianomi.go | 8 +- adapters/dianomi/dianomi_test.go | 6 +- adapters/dianomi/params_test.go | 2 +- adapters/dmx/dmx.go | 8 +- adapters/dmx/dmx_test.go | 8 +- adapters/dmx/params_test.go | 3 +- adapters/dxkulture/dxkulture.go | 8 +- adapters/dxkulture/dxkulture_test.go | 4 +- adapters/dxkulture/params_test.go | 2 +- adapters/e_volution/evolution.go | 8 +- adapters/e_volution/evolution_test.go | 6 +- adapters/e_volution/params_test.go | 2 +- adapters/edge226/edge226.go | 6 +- adapters/edge226/edge226_test.go | 6 +- adapters/edge226/params_test.go | 2 +- adapters/emtv/emtv.go | 8 +- adapters/emtv/emtv_test.go | 6 +- adapters/emtv/params_test.go | 2 +- adapters/eplanning/eplanning.go | 8 +- adapters/eplanning/eplanning_test.go | 8 +- adapters/epom/epom.go | 8 +- adapters/epom/epom_test.go | 6 +- adapters/flipp/flipp.go | 6 +- adapters/flipp/flipp_params.go | 2 +- adapters/flipp/flipp_test.go | 6 +- adapters/flipp/params_test.go | 2 +- adapters/freewheelssp/freewheelssp.go | 8 +- adapters/freewheelssp/freewheelssp_test.go | 7 +- adapters/frvradn/frvradn.go | 8 +- adapters/frvradn/frvradn_test.go | 9 +- adapters/frvradn/params_test.go | 2 +- adapters/gamma/gamma.go | 8 +- adapters/gamma/gamma_test.go | 6 +- adapters/gamma/params_test.go | 2 +- adapters/gamoshi/gamoshi.go | 8 +- adapters/gamoshi/gamoshi_test.go | 6 +- adapters/gamoshi/params_test.go | 2 +- adapters/globalsun/globalsun.go | 8 +- adapters/globalsun/globalsun_test.go | 6 +- adapters/globalsun/params_test.go | 2 +- adapters/gothamads/gothamads.go | 10 +- adapters/gothamads/gothamads_test.go | 6 +- adapters/gothamads/params_test.go | 2 +- adapters/grid/grid.go | 10 +- adapters/grid/grid_test.go | 6 +- adapters/gumgum/gumgum.go | 8 +- adapters/gumgum/gumgum_test.go | 6 +- adapters/gumgum/params_test.go | 3 +- adapters/huaweiads/huaweiads.go | 8 +- adapters/huaweiads/huaweiads_test.go | 6 +- adapters/huaweiads/params_test.go | 3 +- adapters/imds/imds.go | 10 +- adapters/imds/imds_test.go | 6 +- adapters/imds/params_test.go | 2 +- adapters/impactify/impactify.go | 8 +- adapters/impactify/impactify_test.go | 6 +- adapters/impactify/params_test.go | 2 +- adapters/improvedigital/improvedigital.go | 11 +- .../improvedigital/improvedigital_test.go | 6 +- adapters/improvedigital/params_test.go | 3 +- adapters/infoawarebidder.go | 6 +- adapters/infoawarebidder_test.go | 8 +- adapters/infytv/infytv.go | 8 +- adapters/infytv/infytv_test.go | 6 +- adapters/infytv/params_test.go | 2 +- adapters/inmobi/inmobi.go | 8 +- adapters/inmobi/inmobi_test.go | 6 +- .../interactiveoffers/interactiveoffers.go | 10 +- .../interactiveoffers_test.go | 6 +- adapters/interactiveoffers/params_test.go | 3 +- adapters/invibes/invibes.go | 12 +- adapters/invibes/invibes_test.go | 6 +- adapters/invibes/params_test.go | 2 +- adapters/iqx/iqx.go | 10 +- adapters/iqx/iqxtest_test.go | 6 +- adapters/iqx/params_test.go | 2 +- adapters/iqzone/iqzone.go | 8 +- adapters/iqzone/iqzone_test.go | 6 +- adapters/iqzone/params_test.go | 2 +- adapters/ix/ix.go | 10 +- adapters/ix/ix_test.go | 10 +- adapters/ix/params_test.go | 2 +- adapters/jixie/jixie.go | 8 +- adapters/jixie/jixie_test.go | 6 +- adapters/jixie/params_test.go | 2 +- adapters/kargo/kargo.go | 8 +- adapters/kargo/kargo_test.go | 6 +- adapters/kargo/params_test.go | 2 +- adapters/kayzen/kayzen.go | 10 +- adapters/kayzen/kayzen_test.go | 6 +- adapters/kayzen/params_test.go | 2 +- adapters/kidoz/kidoz.go | 8 +- adapters/kidoz/kidoz_test.go | 8 +- adapters/kidoz/params_test.go | 2 +- adapters/kiviads/kiviads.go | 8 +- adapters/kiviads/kiviads_test.go | 6 +- adapters/kiviads/params_test.go | 2 +- adapters/krushmedia/krushmedia.go | 10 +- adapters/krushmedia/krushmedia_test.go | 6 +- adapters/krushmedia/params_test.go | 2 +- adapters/lemmadigital/lemmadigital.go | 10 +- adapters/lemmadigital/lemmadigital_test.go | 6 +- adapters/lemmadigital/params_test.go | 2 +- adapters/liftoff/liftoff.go | 6 +- adapters/liftoff/liftoff_test.go | 6 +- adapters/liftoff/param_test.go | 2 +- adapters/limelightDigital/limelightDigital.go | 10 +- .../limelightDigital/limelightDigital_test.go | 9 +- adapters/limelightDigital/params_test.go | 2 +- adapters/lm_kiviads/lmkiviads.go | 10 +- adapters/lm_kiviads/lmkiviads_test.go | 6 +- adapters/lm_kiviads/params_test.go | 2 +- adapters/lockerdome/lockerdome.go | 8 +- adapters/lockerdome/lockerdome_test.go | 6 +- adapters/lockerdome/params_test.go | 2 +- adapters/logan/logan.go | 8 +- adapters/logan/logan_test.go | 6 +- adapters/logan/params_test.go | 2 +- adapters/logicad/logicad.go | 8 +- adapters/logicad/logicad_test.go | 6 +- adapters/logicad/params_test.go | 3 +- adapters/lunamedia/lunamedia.go | 10 +- adapters/lunamedia/lunamedia_test.go | 6 +- adapters/lunamedia/params_test.go | 3 +- adapters/mabidder/mabidder.go | 6 +- adapters/mabidder/mabidder_test.go | 6 +- adapters/mabidder/params_test.go | 2 +- adapters/madvertise/madvertise.go | 10 +- adapters/madvertise/madvertise_test.go | 6 +- adapters/madvertise/params_test.go | 2 +- adapters/marsmedia/marsmedia.go | 8 +- adapters/marsmedia/marsmedia_test.go | 6 +- adapters/marsmedia/params_test.go | 2 +- adapters/medianet/medianet.go | 8 +- adapters/medianet/medianet_test.go | 6 +- adapters/medianet/params_test.go | 2 +- adapters/mgid/mgid.go | 8 +- adapters/mgid/mgid_test.go | 6 +- adapters/mgidX/mgidX.go | 6 +- adapters/mgidX/mgidX_test.go | 6 +- adapters/mgidX/params_test.go | 2 +- adapters/mobfoxpb/mobfoxpb.go | 8 +- adapters/mobfoxpb/mobfoxpb_test.go | 6 +- adapters/mobfoxpb/params_test.go | 2 +- adapters/mobilefuse/mobilefuse.go | 10 +- adapters/mobilefuse/mobilefuse_test.go | 6 +- adapters/mobilefuse/params_test.go | 2 +- adapters/motorik/motorik.go | 10 +- adapters/motorik/motorik_test.go | 6 +- adapters/motorik/params_test.go | 2 +- adapters/nextmillennium/nextmillennium.go | 8 +- .../nextmillennium/nextmillennium_test.go | 6 +- adapters/nextmillennium/params_test.go | 2 +- adapters/nobid/nobid.go | 8 +- adapters/nobid/nobid_test.go | 6 +- adapters/nobid/params_test.go | 2 +- adapters/onetag/onetag.go | 10 +- adapters/onetag/onetag_test.go | 6 +- adapters/onetag/params_test.go | 2 +- adapters/openweb/openweb.go | 8 +- adapters/openweb/openweb_test.go | 6 +- adapters/openweb/params_test.go | 2 +- adapters/openx/openx.go | 8 +- adapters/openx/openx_test.go | 8 +- adapters/openx/params_test.go | 2 +- adapters/operaads/operaads.go | 10 +- adapters/operaads/operaads_test.go | 6 +- adapters/operaads/params_test.go | 2 +- adapters/orbidder/orbidder.go | 8 +- adapters/orbidder/orbidder_test.go | 8 +- adapters/orbidder/params_test.go | 2 +- adapters/outbrain/outbrain.go | 8 +- adapters/outbrain/outbrain_test.go | 6 +- adapters/outbrain/params_test.go | 2 +- adapters/ownadx/ownadx.go | 13 +- adapters/ownadx/ownadx_test.go | 9 +- adapters/pangle/pangle.go | 8 +- adapters/pangle/pangle_test.go | 6 +- adapters/pangle/param_test.go | 2 +- adapters/pgamssp/params_test.go | 2 +- adapters/pgamssp/pgamssp.go | 6 +- adapters/pgamssp/pgamssp_test.go | 6 +- adapters/pubmatic/params_test.go | 2 +- adapters/pubmatic/pubmatic.go | 8 +- adapters/pubmatic/pubmatic_test.go | 8 +- adapters/pubnative/pubnative.go | 8 +- adapters/pubnative/pubnative_test.go | 6 +- adapters/pulsepoint/params_test.go | 2 +- adapters/pulsepoint/pulsepoint.go | 8 +- adapters/pulsepoint/pulsepoint_test.go | 6 +- adapters/pwbid/params_test.go | 2 +- adapters/pwbid/pwbid.go | 8 +- adapters/pwbid/pwbid_test.go | 6 +- adapters/response.go | 2 +- adapters/response_test.go | 2 +- adapters/revcontent/revcontent.go | 8 +- adapters/revcontent/revcontent_test.go | 6 +- adapters/richaudience/params_test.go | 2 +- adapters/richaudience/richaudience.go | 8 +- adapters/richaudience/richaudience_test.go | 8 +- adapters/rise/rise.go | 6 +- adapters/rise/rise_test.go | 6 +- adapters/rtbhouse/rtbhouse.go | 8 +- adapters/rtbhouse/rtbhouse_test.go | 6 +- adapters/rubicon/rubicon.go | 10 +- adapters/rubicon/rubicon_test.go | 10 +- adapters/sa_lunamedia/params_test.go | 2 +- adapters/sa_lunamedia/salunamedia.go | 8 +- adapters/sa_lunamedia/salunamedia_test.go | 6 +- adapters/screencore/params_test.go | 2 +- adapters/screencore/screencore.go | 10 +- adapters/screencore/screencore_test.go | 6 +- adapters/seedingAlliance/params_test.go | 2 +- adapters/seedingAlliance/seedingAlliance.go | 8 +- .../seedingAlliance/seedingAlliance_test.go | 8 +- adapters/sharethrough/params_test.go | 2 +- adapters/sharethrough/sharethrough.go | 10 +- adapters/sharethrough/sharethrough_test.go | 6 +- adapters/silvermob/params_test.go | 2 +- adapters/silvermob/silvermob.go | 10 +- adapters/silvermob/silvermob_test.go | 6 +- adapters/silverpush/params_test.go | 2 +- adapters/silverpush/silverpush.go | 8 +- adapters/silverpush/silverpush_test.go | 8 +- adapters/smaato/image.go | 3 +- adapters/smaato/native.go | 3 +- adapters/smaato/params_test.go | 2 +- adapters/smaato/richmedia.go | 3 +- adapters/smaato/smaato.go | 12 +- adapters/smaato/smaato_test.go | 8 +- adapters/smartadserver/params_test.go | 2 +- adapters/smartadserver/smartadserver.go | 8 +- adapters/smartadserver/smartadserver_test.go | 6 +- adapters/smarthub/params_test.go | 2 +- adapters/smarthub/smarthub.go | 10 +- adapters/smarthub/smarthub_test.go | 6 +- adapters/smartrtb/smartrtb.go | 10 +- adapters/smartrtb/smartrtb_test.go | 6 +- adapters/smartx/params_test.go | 2 +- adapters/smartx/smartx.go | 6 +- adapters/smartx/smartx_test.go | 6 +- adapters/smartyads/params_test.go | 2 +- adapters/smartyads/smartyads.go | 10 +- adapters/smartyads/smartyads_test.go | 6 +- adapters/smilewanted/params_test.go | 2 +- adapters/smilewanted/smilewanted.go | 8 +- adapters/smilewanted/smilewanted_test.go | 6 +- adapters/sonobi/params_test.go | 2 +- adapters/sonobi/sonobi.go | 8 +- adapters/sonobi/sonobi_test.go | 6 +- adapters/sovrn/sovrn.go | 8 +- adapters/sovrn/sovrn_test.go | 6 +- adapters/sspBC/sspbc.go | 8 +- adapters/sspBC/sspbc_test.go | 6 +- adapters/stroeerCore/params_test.go | 3 +- adapters/stroeerCore/stroeercore.go | 8 +- adapters/stroeerCore/stroeercore_test.go | 6 +- adapters/suntContent/params_test.go | 2 +- adapters/suntContent/suntContent.go | 8 +- adapters/suntContent/suntContent_test.go | 8 +- adapters/taboola/params_test.go | 3 +- adapters/taboola/taboola.go | 10 +- adapters/taboola/taboola_test.go | 10 +- adapters/tappx/params_test.go | 3 +- adapters/tappx/tappx.go | 10 +- adapters/tappx/tappx_test.go | 6 +- adapters/teads/teads.go | 10 +- adapters/teads/teads_test.go | 9 +- adapters/telaria/params_test.go | 3 +- adapters/telaria/telaria.go | 8 +- adapters/telaria/telaria_test.go | 6 +- adapters/tpmn/params_test.go | 3 +- adapters/tpmn/tpmn.go | 6 +- adapters/tpmn/tpmn_test.go | 6 +- adapters/trafficgate/params_test.go | 2 +- adapters/trafficgate/trafficgate.go | 10 +- adapters/trafficgate/trafficgate_test.go | 6 +- adapters/triplelift/triplelift.go | 8 +- adapters/triplelift/triplelift_test.go | 6 +- .../triplelift_native/triplelift_native.go | 8 +- .../triplelift_native_test.go | 6 +- adapters/ucfunnel/params_test.go | 2 +- adapters/ucfunnel/ucfunnel.go | 8 +- adapters/ucfunnel/ucfunnel_test.go | 6 +- adapters/undertone/params_test.go | 3 +- adapters/undertone/undertone.go | 8 +- adapters/undertone/undertone_test.go | 7 +- adapters/unicorn/params_test.go | 2 +- adapters/unicorn/unicorn.go | 8 +- adapters/unicorn/unicorn_test.go | 6 +- adapters/unruly/params_test.go | 2 +- adapters/unruly/unruly.go | 8 +- adapters/unruly/unruly_test.go | 6 +- adapters/videobyte/params_test.go | 2 +- adapters/videobyte/videobyte.go | 8 +- adapters/videobyte/videobyte_test.go | 4 +- adapters/videoheroes/params_test.go | 2 +- adapters/videoheroes/videoheroes.go | 10 +- adapters/videoheroes/videoheroes_test.go | 6 +- adapters/vidoomy/params_test.go | 2 +- adapters/vidoomy/vidoomy.go | 8 +- adapters/vidoomy/vidoomy_test.go | 6 +- adapters/visiblemeasures/params_test.go | 2 +- adapters/visiblemeasures/visiblemeasures.go | 8 +- .../visiblemeasures/visiblemeasures_test.go | 6 +- adapters/visx/params_test.go | 2 +- adapters/visx/visx.go | 8 +- adapters/visx/visx_test.go | 6 +- adapters/vox/params_test.go | 2 +- adapters/vox/vox.go | 7 +- adapters/vox/vox_test.go | 6 +- adapters/vrtcal/params_test.go | 2 +- adapters/vrtcal/vrtcal.go | 8 +- adapters/vrtcal/vrtcal_test.go | 6 +- adapters/xeworks/params_test.go | 2 +- adapters/xeworks/xeworks.go | 10 +- adapters/xeworks/xeworks_test.go | 6 +- adapters/yahooAds/params_test.go | 2 +- adapters/yahooAds/yahooAds.go | 8 +- adapters/yahooAds/yahooAds_test.go | 6 +- adapters/yeahmobi/params_test.go | 3 +- adapters/yeahmobi/yeahmobi.go | 10 +- adapters/yeahmobi/yeahmobi_test.go | 6 +- adapters/yieldlab/params_test.go | 2 +- adapters/yieldlab/yieldlab.go | 8 +- adapters/yieldlab/yieldlab_test.go | 6 +- adapters/yieldmo/params_test.go | 2 +- adapters/yieldmo/yieldmo.go | 8 +- adapters/yieldmo/yieldmo_test.go | 6 +- adapters/yieldone/params_test.go | 3 +- adapters/yieldone/yieldone.go | 8 +- adapters/yieldone/yieldone_test.go | 6 +- adapters/zeroclickfraud/zeroclickfraud.go | 10 +- .../zeroclickfraud/zeroclickfraud_test.go | 6 +- adapters/zeta_global_ssp/zeta_global_ssp.go | 8 +- .../zeta_global_ssp/zeta_global_ssp_test.go | 6 +- adservertargeting/adservertargeting.go | 2 +- adservertargeting/adservertargeting_test.go | 4 +- adservertargeting/reqcache.go | 2 +- adservertargeting/requestlookup.go | 7 +- adservertargeting/requestlookup_test.go | 2 +- adservertargeting/respdataprocessor.go | 4 +- adservertargeting/respdataprocessor_test.go | 2 +- adservertargeting/utils.go | 7 +- amp/parse.go | 8 +- amp/parse_test.go | 8 +- analytics/build/build.go | 12 +- analytics/build/build_test.go | 8 +- analytics/core.go | 6 +- analytics/filesystem/file_module.go | 4 +- analytics/filesystem/file_module_test.go | 4 +- analytics/filesystem/model.go | 8 +- analytics/pubstack/configupdate.go | 2 +- analytics/pubstack/helpers/json.go | 4 +- analytics/pubstack/helpers/json_test.go | 2 +- analytics/pubstack/helpers/model.go | 8 +- analytics/pubstack/pubstack_module.go | 6 +- analytics/pubstack/pubstack_module_test.go | 4 +- analytics/runner.go | 2 +- bidadjustment/apply.go | 4 +- bidadjustment/apply_test.go | 4 +- bidadjustment/build_rules.go | 4 +- bidadjustment/build_rules_test.go | 4 +- bidadjustment/validate.go | 2 +- bidadjustment/validate_test.go | 2 +- config/account.go | 4 +- config/account_test.go | 2 +- config/bidderinfo.go | 4 +- config/bidderinfo_test.go | 2 +- config/compression.go | 2 +- config/compression_test.go | 2 +- config/config.go | 6 +- config/config_test.go | 2 +- currency/rate_converter.go | 6 +- currency/rate_converter_test.go | 2 +- currency/rates_test.go | 2 +- currency/validation.go | 4 +- currency/validation_test.go | 4 +- endpoints/cookie_sync.go | 30 +- endpoints/cookie_sync_test.go | 22 +- endpoints/currency_rates.go | 4 +- endpoints/currency_rates_test.go | 2 +- endpoints/events/account_test.go | 8 +- endpoints/events/event.go | 19 +- endpoints/events/event_test.go | 12 +- endpoints/events/vtrack.go | 18 +- endpoints/events/vtrack_test.go | 10 +- endpoints/getuids.go | 4 +- endpoints/getuids_test.go | 2 +- endpoints/info/bidders.go | 4 +- endpoints/info/bidders_detail.go | 6 +- endpoints/info/bidders_detail_test.go | 4 +- endpoints/info/bidders_test.go | 2 +- endpoints/openrtb2/amp_auction.go | 42 +- endpoints/openrtb2/amp_auction_test.go | 30 +- endpoints/openrtb2/auction.go | 54 +-- endpoints/openrtb2/auction_benchmark_test.go | 22 +- endpoints/openrtb2/auction_test.go | 32 +- endpoints/openrtb2/interstitial.go | 6 +- endpoints/openrtb2/interstitial_test.go | 2 +- endpoints/openrtb2/test_utils.go | 44 +- endpoints/openrtb2/video_auction.go | 40 +- endpoints/openrtb2/video_auction_test.go | 28 +- endpoints/setuid.go | 26 +- endpoints/setuid_test.go | 20 +- endpoints/version.go | 2 +- exchange/adapter_builders.go | 376 +++++++++--------- exchange/adapter_util.go | 8 +- exchange/adapter_util_test.go | 12 +- exchange/auction.go | 10 +- exchange/auction_response.go | 2 +- exchange/auction_test.go | 12 +- exchange/bidder.go | 26 +- exchange/bidder_test.go | 24 +- exchange/bidder_validate_bids.go | 12 +- exchange/bidder_validate_bids_test.go | 12 +- exchange/entities/entities.go | 2 +- exchange/events.go | 12 +- exchange/events_test.go | 4 +- exchange/exchange.go | 46 +-- exchange/exchange_test.go | 44 +- exchange/gdpr.go | 6 +- exchange/gdpr_test.go | 4 +- exchange/price_granularity.go | 5 +- exchange/price_granularity_test.go | 4 +- exchange/seat_non_bids.go | 4 +- exchange/seat_non_bids_test.go | 4 +- exchange/targeting.go | 2 +- exchange/targeting_test.go | 20 +- exchange/tmax_adjustments.go | 2 +- exchange/tmax_adjustments_test.go | 2 +- exchange/utils.go | 26 +- exchange/utils_test.go | 20 +- experiment/adscert/inprocesssigner.go | 5 +- experiment/adscert/remotesigner.go | 5 +- experiment/adscert/signer.go | 3 +- experiment/adscert/signer_test.go | 5 +- firstpartydata/extmerger.go | 2 +- firstpartydata/extmerger_test.go | 2 +- firstpartydata/first_party_data.go | 10 +- firstpartydata/first_party_data_test.go | 6 +- floors/enforce.go | 8 +- floors/enforce_test.go | 10 +- floors/floors.go | 6 +- floors/floors_test.go | 8 +- floors/rule.go | 4 +- floors/rule_test.go | 4 +- floors/validate.go | 4 +- floors/validate_test.go | 4 +- gdpr/aggregated_config.go | 4 +- gdpr/aggregated_config_test.go | 4 +- gdpr/basic_enforcement.go | 2 +- gdpr/basic_enforcement_test.go | 2 +- gdpr/full_enforcement.go | 2 +- gdpr/full_enforcement_test.go | 4 +- gdpr/gdpr.go | 4 +- gdpr/gdpr_test.go | 4 +- gdpr/impl.go | 2 +- gdpr/impl_test.go | 4 +- gdpr/purpose_config.go | 4 +- gdpr/purpose_config_test.go | 2 +- gdpr/purpose_enforcer.go | 4 +- gdpr/purpose_enforcer_test.go | 4 +- gdpr/signal.go | 2 +- gdpr/vendorlist-fetching.go | 2 +- gdpr/vendorlist-fetching_test.go | 4 +- go.mod | 2 +- hooks/empty_plan.go | 4 +- hooks/hookanalytics/analytics_test.go | 2 +- hooks/hookexecution/context.go | 4 +- hooks/hookexecution/enricher.go | 4 +- hooks/hookexecution/enricher_test.go | 8 +- hooks/hookexecution/errors.go | 2 +- hooks/hookexecution/execution.go | 6 +- hooks/hookexecution/executor.go | 14 +- hooks/hookexecution/executor_test.go | 18 +- hooks/hookexecution/mocks_test.go | 4 +- hooks/hookexecution/outcome.go | 2 +- hooks/hookexecution/test_utils.go | 2 +- hooks/hookstage/allprocessedbidresponses.go | 4 +- hooks/hookstage/invocation.go | 2 +- hooks/hookstage/processedauctionrequest.go | 2 +- hooks/hookstage/rawbidderresponse.go | 2 +- .../hookstage/rawbidderresponse_mutations.go | 2 +- hooks/plan.go | 4 +- hooks/plan_test.go | 6 +- hooks/repo.go | 2 +- hooks/repo_test.go | 2 +- macros/provider.go | 4 +- macros/provider_test.go | 4 +- macros/string_index_based_replacer_test.go | 4 +- main.go | 12 +- main_test.go | 2 +- metrics/config/metrics.go | 8 +- metrics/config/metrics_test.go | 6 +- metrics/go_metrics.go | 4 +- metrics/go_metrics_test.go | 4 +- metrics/metrics.go | 2 +- metrics/metrics_mock.go | 2 +- metrics/prometheus/preload.go | 4 +- metrics/prometheus/prometheus.go | 6 +- metrics/prometheus/prometheus_test.go | 6 +- modules/builder.go | 2 +- modules/generator/builder.tmpl | 2 +- modules/helpers.go | 4 +- modules/modules.go | 8 +- modules/modules_test.go | 8 +- modules/prebid/ortb2blocking/analytics.go | 4 +- modules/prebid/ortb2blocking/config.go | 2 +- .../ortb2blocking/hook_bidderrequest.go | 6 +- .../ortb2blocking/hook_raw_bidder_response.go | 6 +- modules/prebid/ortb2blocking/module.go | 4 +- modules/prebid/ortb2blocking/module_test.go | 10 +- openrtb_ext/convert_down_test.go | 2 +- openrtb_ext/deal_tier.go | 2 +- openrtb_ext/deal_tier_test.go | 2 +- openrtb_ext/device.go | 2 +- openrtb_ext/device_test.go | 2 +- openrtb_ext/imp_appnexus.go | 2 +- openrtb_ext/imp_appnexus_test.go | 2 +- openrtb_ext/imp_freewheelssp.go | 2 +- openrtb_ext/multibid_test.go | 2 +- openrtb_ext/request.go | 8 +- openrtb_ext/request_test.go | 4 +- openrtb_ext/request_wrapper.go | 8 +- openrtb_ext/request_wrapper_test.go | 4 +- openrtb_ext/site_test.go | 4 +- openrtb_ext/supplyChain.go | 2 +- openrtb_ext/supplyChain_test.go | 2 +- ortb/clone.go | 4 +- ortb/clone_test.go | 2 +- ortb/default.go | 4 +- ortb/default_test.go | 8 +- pbs/usersync.go | 6 +- prebid_cache_client/client.go | 4 +- prebid_cache_client/client_test.go | 8 +- privacy/activitycontrol.go | 4 +- privacy/activitycontrol_test.go | 6 +- privacy/ccpa/consentwriter.go | 2 +- privacy/ccpa/consentwriter_test.go | 2 +- privacy/ccpa/parsedpolicy.go | 2 +- privacy/ccpa/policy.go | 6 +- privacy/ccpa/policy_test.go | 2 +- privacy/enforcement.go | 2 +- privacy/gdpr/consentwriter.go | 2 +- privacy/lmt/ios.go | 4 +- privacy/lmt/ios_test.go | 2 +- privacy/rule_condition_test.go | 2 +- privacy/scrubber.go | 8 +- privacy/scrubber_test.go | 3 +- router/admin.go | 6 +- router/aspects/request_timeout_handler.go | 4 +- .../aspects/request_timeout_handler_test.go | 4 +- router/router.go | 54 +-- router/router_test.go | 6 +- schain/schain.go | 2 +- schain/schain_test.go | 2 +- schain/schainwriter.go | 4 +- schain/schainwriter_test.go | 4 +- scripts/check_coverage.sh | 3 +- server/listener.go | 2 +- server/listener_test.go | 4 +- server/prometheus.go | 4 +- server/server.go | 6 +- server/server_test.go | 4 +- .../backends/db_fetcher/fetcher.go | 4 +- .../backends/db_fetcher/fetcher_test.go | 2 +- .../backends/db_provider/db_provider.go | 2 +- .../backends/db_provider/db_provider_mock.go | 2 +- .../backends/db_provider/mysql_dbprovider.go | 2 +- .../db_provider/mysql_dbprovider_test.go | 2 +- .../db_provider/postgres_dbprovider.go | 2 +- .../db_provider/postgres_dbprovider_test.go | 2 +- .../backends/empty_fetcher/fetcher.go | 2 +- .../backends/file_fetcher/fetcher.go | 4 +- .../backends/file_fetcher/fetcher_test.go | 4 +- .../backends/http_fetcher/fetcher.go | 4 +- .../backends/http_fetcher/fetcher_test.go | 2 +- stored_requests/caches/cachestest/reliable.go | 2 +- stored_requests/caches/memory/cache.go | 2 +- stored_requests/caches/memory/cache_test.go | 4 +- stored_requests/config/config.go | 30 +- stored_requests/config/config_test.go | 16 +- stored_requests/events/api/api.go | 4 +- stored_requests/events/api/api_test.go | 6 +- stored_requests/events/database/database.go | 10 +- .../events/database/database_test.go | 8 +- stored_requests/events/events.go | 2 +- stored_requests/events/events_test.go | 4 +- stored_requests/events/http/http.go | 4 +- stored_requests/events/http/http_test.go | 2 +- stored_requests/fetcher.go | 2 +- stored_requests/fetcher_test.go | 4 +- stored_responses/stored_responses.go | 4 +- stored_responses/stored_responses_test.go | 2 +- usersync/chooser.go | 3 +- usersync/chooser_test.go | 9 +- usersync/cookie.go | 6 +- usersync/cookie_test.go | 4 +- usersync/decoder.go | 2 +- usersync/encoder.go | 2 +- usersync/syncer.go | 4 +- usersync/syncer_test.go | 4 +- usersync/syncersbuilder.go | 2 +- usersync/syncersbuilder_test.go | 4 +- util/httputil/httputil.go | 2 +- util/httputil/httputil_test.go | 2 +- util/jsonutil/jsonutil.go | 2 +- util/task/ticker_task_test.go | 2 +- version/xprebidheader.go | 2 +- version/xprebidheader_test.go | 4 +- 816 files changed, 2697 insertions(+), 2657 deletions(-) diff --git a/.gitignore b/.gitignore index 4e298f2a3d9..0df7cde54fd 100644 --- a/.gitignore +++ b/.gitignore @@ -30,8 +30,8 @@ vendor # build artifacts prebid-server -build -debug +/build +/debug __debug_bin # config files diff --git a/account/account.go b/account/account.go index 1f5a3feee14..2c243e0dd90 100644 --- a/account/account.go +++ b/account/account.go @@ -6,13 +6,13 @@ import ( "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/util/iputil" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/util/iputil" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) // GetAccount looks up the config.Account object referenced by the given accountID, with access rules applied diff --git a/account/account_test.go b/account/account_test.go index 7a242f21188..369c2d2c40d 100644 --- a/account/account_test.go +++ b/account/account_test.go @@ -6,12 +6,12 @@ import ( "fmt" "testing" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/util/iputil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/util/iputil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) diff --git a/adapters/33across/33across.go b/adapters/33across/33across.go index 26349e8426b..c7c3300a648 100644 --- a/adapters/33across/33across.go +++ b/adapters/33across/33across.go @@ -7,10 +7,10 @@ import ( "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type TtxAdapter struct { diff --git a/adapters/33across/33across_test.go b/adapters/33across/33across_test.go index bdc546a9627..c84ca0ad1d2 100644 --- a/adapters/33across/33across_test.go +++ b/adapters/33across/33across_test.go @@ -3,9 +3,9 @@ package ttx import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/33across/params_test.go b/adapters/33across/params_test.go index 2d488c4148c..ba985b2b250 100644 --- a/adapters/33across/params_test.go +++ b/adapters/33across/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/33across.json diff --git a/adapters/aax/aax.go b/adapters/aax/aax.go index 86994c6dea2..a36bf3ad37e 100644 --- a/adapters/aax/aax.go +++ b/adapters/aax/aax.go @@ -7,10 +7,10 @@ import ( "net/url" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/aax/aax_test.go b/adapters/aax/aax_test.go index 6a5eaed5dfe..c4fd1c392aa 100644 --- a/adapters/aax/aax_test.go +++ b/adapters/aax/aax_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/aax/params_test.go b/adapters/aax/params_test.go index edf9fb6fc48..bdfa46a9e63 100644 --- a/adapters/aax/params_test.go +++ b/adapters/aax/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/aax.json diff --git a/adapters/aceex/aceex.go b/adapters/aceex/aceex.go index 61863f0b8a8..a87a2b11fcf 100644 --- a/adapters/aceex/aceex.go +++ b/adapters/aceex/aceex.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/aceex/aceex_test.go b/adapters/aceex/aceex_test.go index ec0e0fec710..71c26ed0bed 100644 --- a/adapters/aceex/aceex_test.go +++ b/adapters/aceex/aceex_test.go @@ -3,9 +3,9 @@ package aceex import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/aceex/params_test.go b/adapters/aceex/params_test.go index 220adb23379..cb6445c491a 100644 --- a/adapters/aceex/params_test.go +++ b/adapters/aceex/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/acuityads/acuityads.go b/adapters/acuityads/acuityads.go index 4370beb72d1..9152e80b83f 100644 --- a/adapters/acuityads/acuityads.go +++ b/adapters/acuityads/acuityads.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type AcuityAdsAdapter struct { diff --git a/adapters/acuityads/acuityads_test.go b/adapters/acuityads/acuityads_test.go index ea9d4f24352..c426d02c533 100644 --- a/adapters/acuityads/acuityads_test.go +++ b/adapters/acuityads/acuityads_test.go @@ -3,9 +3,9 @@ package acuityads import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/acuityads/params_test.go b/adapters/acuityads/params_test.go index 892fe9a646d..3c7b3a97914 100644 --- a/adapters/acuityads/params_test.go +++ b/adapters/acuityads/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/adapterstest/test_json.go b/adapters/adapterstest/test_json.go index 39b1e945f7d..d14ff015ced 100644 --- a/adapters/adapterstest/test_json.go +++ b/adapters/adapterstest/test_json.go @@ -12,9 +12,9 @@ import ( "github.com/mitchellh/copystructure" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/yudai/gojsondiff" "github.com/yudai/gojsondiff/formatter" diff --git a/adapters/adf/adf.go b/adapters/adf/adf.go index 7ff817559cc..0f14a05e947 100644 --- a/adapters/adf/adf.go +++ b/adapters/adf/adf.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/adf/adf_test.go b/adapters/adf/adf_test.go index bf8af8d6845..20e4f3dde32 100644 --- a/adapters/adf/adf_test.go +++ b/adapters/adf/adf_test.go @@ -3,9 +3,9 @@ package adf import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adf/params_test.go b/adapters/adf/params_test.go index 0b05519df3b..dc0d84927bc 100644 --- a/adapters/adf/params_test.go +++ b/adapters/adf/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/adf.json diff --git a/adapters/adgeneration/adgeneration.go b/adapters/adgeneration/adgeneration.go index a2a10ed51f2..88166ec237d 100644 --- a/adapters/adgeneration/adgeneration.go +++ b/adapters/adgeneration/adgeneration.go @@ -11,10 +11,10 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type AdgenerationAdapter struct { diff --git a/adapters/adgeneration/adgeneration_test.go b/adapters/adgeneration/adgeneration_test.go index c204fbd320d..3e94ac6c382 100644 --- a/adapters/adgeneration/adgeneration_test.go +++ b/adapters/adgeneration/adgeneration_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adgeneration/params_test.go b/adapters/adgeneration/params_test.go index 062d122ac08..58400e96656 100644 --- a/adapters/adgeneration/params_test.go +++ b/adapters/adgeneration/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adhese/adhese.go b/adapters/adhese/adhese.go index 9c84676c379..56d60be2505 100644 --- a/adapters/adhese/adhese.go +++ b/adapters/adhese/adhese.go @@ -11,11 +11,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type AdheseAdapter struct { diff --git a/adapters/adhese/adhese_test.go b/adapters/adhese/adhese_test.go index d09a29ee9bd..2b70bb001a6 100644 --- a/adapters/adhese/adhese_test.go +++ b/adapters/adhese/adhese_test.go @@ -3,9 +3,9 @@ package adhese import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adhese/params_test.go b/adapters/adhese/params_test.go index 45024749b2d..1a0aa381cb1 100644 --- a/adapters/adhese/params_test.go +++ b/adapters/adhese/params_test.go @@ -5,7 +5,7 @@ import ( "fmt" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adkernel/adkernel.go b/adapters/adkernel/adkernel.go index 5fae001d7dd..e8ccc360e0e 100644 --- a/adapters/adkernel/adkernel.go +++ b/adapters/adkernel/adkernel.go @@ -8,11 +8,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adkernelAdapter struct { diff --git a/adapters/adkernel/adkernel_test.go b/adapters/adkernel/adkernel_test.go index ae35f712400..2639eb25624 100644 --- a/adapters/adkernel/adkernel_test.go +++ b/adapters/adkernel/adkernel_test.go @@ -3,9 +3,9 @@ package adkernel import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adkernelAdn/adkernelAdn.go b/adapters/adkernelAdn/adkernelAdn.go index 45e9e41c10c..218708cb697 100644 --- a/adapters/adkernelAdn/adkernelAdn.go +++ b/adapters/adkernelAdn/adkernelAdn.go @@ -8,11 +8,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adkernelAdnAdapter struct { diff --git a/adapters/adkernelAdn/adkernelAdn_test.go b/adapters/adkernelAdn/adkernelAdn_test.go index 651d82be3b6..e43d00bf0bf 100644 --- a/adapters/adkernelAdn/adkernelAdn_test.go +++ b/adapters/adkernelAdn/adkernelAdn_test.go @@ -3,9 +3,9 @@ package adkernelAdn import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adman/adman.go b/adapters/adman/adman.go index 5350fa7cb86..48a4dff961c 100644 --- a/adapters/adman/adman.go +++ b/adapters/adman/adman.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // AdmanAdapter struct diff --git a/adapters/adman/adman_test.go b/adapters/adman/adman_test.go index 608232cc4b8..5617035c713 100644 --- a/adapters/adman/adman_test.go +++ b/adapters/adman/adman_test.go @@ -3,9 +3,9 @@ package adman import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adman/params_test.go b/adapters/adman/params_test.go index a80c2a44b8b..9d7e0c16d51 100644 --- a/adapters/adman/params_test.go +++ b/adapters/adman/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // TestValidParams makes sure that the adman schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/admixer/admixer.go b/adapters/admixer/admixer.go index 9a07a8922a9..5c68518ee52 100644 --- a/adapters/admixer/admixer.go +++ b/adapters/admixer/admixer.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type AdmixerAdapter struct { diff --git a/adapters/admixer/admixer_test.go b/adapters/admixer/admixer_test.go index 766f890cdf7..5985d4303c9 100644 --- a/adapters/admixer/admixer_test.go +++ b/adapters/admixer/admixer_test.go @@ -3,9 +3,9 @@ package admixer import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/admixer/params_test.go b/adapters/admixer/params_test.go index bfa75a4884f..af85569b460 100644 --- a/adapters/admixer/params_test.go +++ b/adapters/admixer/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/admixer.json diff --git a/adapters/adnuntius/adnuntius.go b/adapters/adnuntius/adnuntius.go index fd667ddc506..cb8d876fb53 100644 --- a/adapters/adnuntius/adnuntius.go +++ b/adapters/adnuntius/adnuntius.go @@ -10,11 +10,11 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/timeutil" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/timeutil" ) type QueryString map[string]string diff --git a/adapters/adnuntius/adnuntius_test.go b/adapters/adnuntius/adnuntius_test.go index 9c431c2a315..f6edb313708 100644 --- a/adapters/adnuntius/adnuntius_test.go +++ b/adapters/adnuntius/adnuntius_test.go @@ -4,10 +4,10 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adnuntius/params_test.go b/adapters/adnuntius/params_test.go index c3b42018340..259b5145801 100644 --- a/adapters/adnuntius/params_test.go +++ b/adapters/adnuntius/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/adnuntius.json diff --git a/adapters/adocean/adocean.go b/adapters/adocean/adocean.go index a4e6223be6d..aa9446d76f0 100644 --- a/adapters/adocean/adocean.go +++ b/adapters/adocean/adocean.go @@ -14,11 +14,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const adapterVersion = "1.3.0" diff --git a/adapters/adocean/adocean_test.go b/adapters/adocean/adocean_test.go index 8d646cb9ca0..d7fe33b8de5 100644 --- a/adapters/adocean/adocean_test.go +++ b/adapters/adocean/adocean_test.go @@ -3,9 +3,9 @@ package adocean import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adocean/params_test.go b/adapters/adocean/params_test.go index 18625b5e85e..f35dc1aaf87 100644 --- a/adapters/adocean/params_test.go +++ b/adapters/adocean/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adoppler/adoppler.go b/adapters/adoppler/adoppler.go index 90070e8145d..42661206ea6 100644 --- a/adapters/adoppler/adoppler.go +++ b/adapters/adoppler/adoppler.go @@ -9,11 +9,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const DefaultClient = "app" diff --git a/adapters/adoppler/adoppler_test.go b/adapters/adoppler/adoppler_test.go index 9f026b2f29c..d05118c4800 100644 --- a/adapters/adoppler/adoppler_test.go +++ b/adapters/adoppler/adoppler_test.go @@ -3,9 +3,9 @@ package adoppler import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adot/adot.go b/adapters/adot/adot.go index fbba9fee467..39c665b4f12 100644 --- a/adapters/adot/adot.go +++ b/adapters/adot/adot.go @@ -8,10 +8,10 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/adot/adot_test.go b/adapters/adot/adot_test.go index 2f35f2a85fa..1d2de9fa8ea 100644 --- a/adapters/adot/adot_test.go +++ b/adapters/adot/adot_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adot/params_test.go b/adapters/adot/params_test.go index 6760419b470..a47ff2ff4eb 100644 --- a/adapters/adot/params_test.go +++ b/adapters/adot/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/adot.json diff --git a/adapters/adpone/adpone.go b/adapters/adpone/adpone.go index bf7ffb93992..77c7c8e0858 100644 --- a/adapters/adpone/adpone.go +++ b/adapters/adpone/adpone.go @@ -6,11 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/errortypes" ) // Builder builds a new instance of the Adpone adapter for the given bidder with the given config. diff --git a/adapters/adpone/adpone_test.go b/adapters/adpone/adpone_test.go index 7b01a382587..bd4f5ed514e 100644 --- a/adapters/adpone/adpone_test.go +++ b/adapters/adpone/adpone_test.go @@ -3,9 +3,9 @@ package adpone import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const testsDir = "adponetest" diff --git a/adapters/adprime/adprime.go b/adapters/adprime/adprime.go index 836abe26d83..56193c9133b 100644 --- a/adapters/adprime/adprime.go +++ b/adapters/adprime/adprime.go @@ -7,10 +7,10 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // AdprimeAdapter struct diff --git a/adapters/adprime/adprime_test.go b/adapters/adprime/adprime_test.go index e5cf7df8df5..34dde15d1ba 100644 --- a/adapters/adprime/adprime_test.go +++ b/adapters/adprime/adprime_test.go @@ -3,9 +3,9 @@ package adprime import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adprime/params_test.go b/adapters/adprime/params_test.go index b466c658ede..67bbebf0086 100644 --- a/adapters/adprime/params_test.go +++ b/adapters/adprime/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // TestValidParams makes sure that the adprime schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/adquery/adquery.go b/adapters/adquery/adquery.go index 6a7dafa0ccb..92a1733dae6 100644 --- a/adapters/adquery/adquery.go +++ b/adapters/adquery/adquery.go @@ -9,10 +9,10 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const ( diff --git a/adapters/adquery/adquery_test.go b/adapters/adquery/adquery_test.go index 228d835d6c4..2b88c3b82c7 100644 --- a/adapters/adquery/adquery_test.go +++ b/adapters/adquery/adquery_test.go @@ -1,10 +1,11 @@ package adquery import ( - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adquery/params_test.go b/adapters/adquery/params_test.go index cba021007d3..e72b0b02ea3 100644 --- a/adapters/adquery/params_test.go +++ b/adapters/adquery/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adquery/types.go b/adapters/adquery/types.go index e46afaea63e..5013ecf488a 100644 --- a/adapters/adquery/types.go +++ b/adapters/adquery/types.go @@ -1,6 +1,6 @@ package adquery -import "github.com/prebid/prebid-server/openrtb_ext" +import "github.com/prebid/prebid-server/v2/openrtb_ext" type BidderRequest struct { V string `json:"v"` diff --git a/adapters/adrino/adrino.go b/adapters/adrino/adrino.go index a63ad9beef6..44de44f5cf8 100644 --- a/adapters/adrino/adrino.go +++ b/adapters/adrino/adrino.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/adrino/adrino_test.go b/adapters/adrino/adrino_test.go index 7566f3ed499..e969868c135 100644 --- a/adapters/adrino/adrino_test.go +++ b/adapters/adrino/adrino_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adrino/params_test.go b/adapters/adrino/params_test.go index f82f08ce9e0..0ad36e6e4d6 100644 --- a/adapters/adrino/params_test.go +++ b/adapters/adrino/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/adrino.json diff --git a/adapters/adsinteractive/adsinteractive.go b/adapters/adsinteractive/adsinteractive.go index 04edf774b80..d50dad0aabd 100644 --- a/adapters/adsinteractive/adsinteractive.go +++ b/adapters/adsinteractive/adsinteractive.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/adsinteractive/adsinteractive_test.go b/adapters/adsinteractive/adsinteractive_test.go index 9a1397b799f..bed577c6003 100644 --- a/adapters/adsinteractive/adsinteractive_test.go +++ b/adapters/adsinteractive/adsinteractive_test.go @@ -3,9 +3,9 @@ package adsinteractive import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const testsDir = "adsinteractivetest" diff --git a/adapters/adsinteractive/params_test.go b/adapters/adsinteractive/params_test.go index 2561fc864da..caff03a2697 100644 --- a/adapters/adsinteractive/params_test.go +++ b/adapters/adsinteractive/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/adsinteractive.json diff --git a/adapters/adtarget/adtarget.go b/adapters/adtarget/adtarget.go index 00f797eccf8..ccd362830fc 100644 --- a/adapters/adtarget/adtarget.go +++ b/adapters/adtarget/adtarget.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type AdtargetAdapter struct { diff --git a/adapters/adtarget/adtarget_test.go b/adapters/adtarget/adtarget_test.go index 2ee45041b09..2813ea2c195 100644 --- a/adapters/adtarget/adtarget_test.go +++ b/adapters/adtarget/adtarget_test.go @@ -3,9 +3,9 @@ package adtarget import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adtarget/params_test.go b/adapters/adtarget/params_test.go index 4c39639fb7b..d0993215086 100644 --- a/adapters/adtarget/params_test.go +++ b/adapters/adtarget/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/adtarget.json diff --git a/adapters/adtelligent/adtelligent.go b/adapters/adtelligent/adtelligent.go index e2f5ef82cab..281d79233a0 100644 --- a/adapters/adtelligent/adtelligent.go +++ b/adapters/adtelligent/adtelligent.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type AdtelligentAdapter struct { diff --git a/adapters/adtelligent/adtelligent_test.go b/adapters/adtelligent/adtelligent_test.go index 948710387b3..905ce013840 100644 --- a/adapters/adtelligent/adtelligent_test.go +++ b/adapters/adtelligent/adtelligent_test.go @@ -3,9 +3,9 @@ package adtelligent import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adtelligent/params_test.go b/adapters/adtelligent/params_test.go index 227920b25b4..f86a7641af9 100644 --- a/adapters/adtelligent/params_test.go +++ b/adapters/adtelligent/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/adtelligent.json diff --git a/adapters/adtrgtme/adtrgtme.go b/adapters/adtrgtme/adtrgtme.go index 254bf5051e9..47feaceefa7 100644 --- a/adapters/adtrgtme/adtrgtme.go +++ b/adapters/adtrgtme/adtrgtme.go @@ -7,10 +7,10 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/adtrgtme/adtrgtme_test.go b/adapters/adtrgtme/adtrgtme_test.go index 91d9b233ffe..07bfea3c652 100644 --- a/adapters/adtrgtme/adtrgtme_test.go +++ b/adapters/adtrgtme/adtrgtme_test.go @@ -3,9 +3,9 @@ package adtrgtme import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adtrgtme/params_test.go b/adapters/adtrgtme/params_test.go index e89f8423ed4..4745c323887 100644 --- a/adapters/adtrgtme/params_test.go +++ b/adapters/adtrgtme/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/advangelists/advangelists.go b/adapters/advangelists/advangelists.go index 19bb4c326e2..c779483d64a 100644 --- a/adapters/advangelists/advangelists.go +++ b/adapters/advangelists/advangelists.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type AdvangelistsAdapter struct { diff --git a/adapters/advangelists/advangelists_test.go b/adapters/advangelists/advangelists_test.go index e4c5debaa79..5165ef1f3a7 100644 --- a/adapters/advangelists/advangelists_test.go +++ b/adapters/advangelists/advangelists_test.go @@ -3,9 +3,9 @@ package advangelists import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/advangelists/params_test.go b/adapters/advangelists/params_test.go index a58217a0ffd..966967ba312 100644 --- a/adapters/advangelists/params_test.go +++ b/adapters/advangelists/params_test.go @@ -2,8 +2,9 @@ package advangelists import ( "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adview/adview.go b/adapters/adview/adview.go index d2181b6591a..9937b6ae3ee 100644 --- a/adapters/adview/adview.go +++ b/adapters/adview/adview.go @@ -8,11 +8,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/adview/adview_test.go b/adapters/adview/adview_test.go index d0c993cfb56..2045586e97d 100644 --- a/adapters/adview/adview_test.go +++ b/adapters/adview/adview_test.go @@ -3,9 +3,9 @@ package adview import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adview/params_test.go b/adapters/adview/params_test.go index 6d124e9b556..d5e498645e0 100644 --- a/adapters/adview/params_test.go +++ b/adapters/adview/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adxcg/adxcg.go b/adapters/adxcg/adxcg.go index 6b489d322b0..a8cb380f6c0 100644 --- a/adapters/adxcg/adxcg.go +++ b/adapters/adxcg/adxcg.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // Builder builds a new instance of the Adxcg adapter for the given bidder with the given config. diff --git a/adapters/adxcg/adxcg_test.go b/adapters/adxcg/adxcg_test.go index aa5f955c372..f117f7b2ba1 100644 --- a/adapters/adxcg/adxcg_test.go +++ b/adapters/adxcg/adxcg_test.go @@ -3,9 +3,9 @@ package adxcg import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const testsDir = "adxcgtest" diff --git a/adapters/adyoulike/adyoulike.go b/adapters/adyoulike/adyoulike.go index e00e95dccb5..72e6612b675 100644 --- a/adapters/adyoulike/adyoulike.go +++ b/adapters/adyoulike/adyoulike.go @@ -8,10 +8,10 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { diff --git a/adapters/adyoulike/adyoulike_test.go b/adapters/adyoulike/adyoulike_test.go index d3000f673fc..2cf7a2b49ec 100644 --- a/adapters/adyoulike/adyoulike_test.go +++ b/adapters/adyoulike/adyoulike_test.go @@ -3,9 +3,9 @@ package adyoulike import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const testsBidderEndpoint = "https://localhost/bid/4" diff --git a/adapters/adyoulike/params_test.go b/adapters/adyoulike/params_test.go index 8aebaf2844e..6eb9e09a3cb 100644 --- a/adapters/adyoulike/params_test.go +++ b/adapters/adyoulike/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/adyoulike.json diff --git a/adapters/aidem/aidem.go b/adapters/aidem/aidem.go index 9748f32c957..dc8d42a07ed 100644 --- a/adapters/aidem/aidem.go +++ b/adapters/aidem/aidem.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/aidem/aidem_test.go b/adapters/aidem/aidem_test.go index 03bcc7e0fb5..8cf6e3d16a2 100644 --- a/adapters/aidem/aidem_test.go +++ b/adapters/aidem/aidem_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/aidem/params_test.go b/adapters/aidem/params_test.go index 36190c0bc9f..4d2c5c14cbc 100644 --- a/adapters/aidem/params_test.go +++ b/adapters/aidem/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/aidem.json TODO: MUST BE CREATED diff --git a/adapters/aja/aja.go b/adapters/aja/aja.go index 5a8afb00045..178c7f6ca68 100644 --- a/adapters/aja/aja.go +++ b/adapters/aja/aja.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type AJAAdapter struct { diff --git a/adapters/aja/aja_test.go b/adapters/aja/aja_test.go index 75e35bedeb0..de4f1d13dab 100644 --- a/adapters/aja/aja_test.go +++ b/adapters/aja/aja_test.go @@ -3,9 +3,9 @@ package aja import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const testsBidderEndpoint = "https://localhost/bid/4" diff --git a/adapters/algorix/algorix.go b/adapters/algorix/algorix.go index 07f2b123389..e646467f744 100644 --- a/adapters/algorix/algorix.go +++ b/adapters/algorix/algorix.go @@ -8,11 +8,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/algorix/algorix_test.go b/adapters/algorix/algorix_test.go index 762b00dcee4..a401713d290 100644 --- a/adapters/algorix/algorix_test.go +++ b/adapters/algorix/algorix_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/algorix/params_test.go b/adapters/algorix/params_test.go index 227b9e0a6d4..7017a43c730 100644 --- a/adapters/algorix/params_test.go +++ b/adapters/algorix/params_test.go @@ -2,8 +2,9 @@ package algorix import ( "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/amx/amx.go b/adapters/amx/amx.go index 6b4ba20b4fd..8ff30baef79 100644 --- a/adapters/amx/amx.go +++ b/adapters/amx/amx.go @@ -7,10 +7,10 @@ import ( "net/url" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const nbrHeaderName = "x-nbr" diff --git a/adapters/amx/amx_test.go b/adapters/amx/amx_test.go index 9b068e5aa82..7286f221997 100644 --- a/adapters/amx/amx_test.go +++ b/adapters/amx/amx_test.go @@ -6,12 +6,12 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" ) const ( diff --git a/adapters/amx/params_test.go b/adapters/amx/params_test.go index 89e9a3adeb4..4d9d646e426 100644 --- a/adapters/amx/params_test.go +++ b/adapters/amx/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/apacdex/apacdex.go b/adapters/apacdex/apacdex.go index fdf30f4061f..ee10247638c 100644 --- a/adapters/apacdex/apacdex.go +++ b/adapters/apacdex/apacdex.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/apacdex/apacdex_test.go b/adapters/apacdex/apacdex_test.go index 1435850e3eb..ba5f1e7a3e6 100644 --- a/adapters/apacdex/apacdex_test.go +++ b/adapters/apacdex/apacdex_test.go @@ -3,9 +3,9 @@ package apacdex import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/apacdex/params_test.go b/adapters/apacdex/params_test.go index 07d846506e5..a7dcf7bcb04 100644 --- a/adapters/apacdex/params_test.go +++ b/adapters/apacdex/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/apacdex.json diff --git a/adapters/appnexus/appnexus.go b/adapters/appnexus/appnexus.go index ddba6a58de7..ad3be2dbb2d 100644 --- a/adapters/appnexus/appnexus.go +++ b/adapters/appnexus/appnexus.go @@ -12,15 +12,15 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/util/maputil" - "github.com/prebid/prebid-server/util/ptrutil" - "github.com/prebid/prebid-server/util/randomutil" - - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/util/maputil" + "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v2/util/randomutil" + + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const ( diff --git a/adapters/appnexus/appnexus_test.go b/adapters/appnexus/appnexus_test.go index bb04b61bb97..72937b25927 100644 --- a/adapters/appnexus/appnexus_test.go +++ b/adapters/appnexus/appnexus_test.go @@ -4,9 +4,9 @@ import ( "net/url" "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/adapters/appnexus/params_test.go b/adapters/appnexus/params_test.go index ed9adedcc6b..12e43f8659b 100644 --- a/adapters/appnexus/params_test.go +++ b/adapters/appnexus/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/appnexus.json diff --git a/adapters/appush/appush.go b/adapters/appush/appush.go index 18b294be7f0..36eccef0a0c 100644 --- a/adapters/appush/appush.go +++ b/adapters/appush/appush.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/appush/appush_test.go b/adapters/appush/appush_test.go index 65be1c32f0a..92f458f1525 100644 --- a/adapters/appush/appush_test.go +++ b/adapters/appush/appush_test.go @@ -3,9 +3,9 @@ package appush import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/appush/params_test.go b/adapters/appush/params_test.go index a471c3f0300..725882cb2ac 100644 --- a/adapters/appush/params_test.go +++ b/adapters/appush/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/audienceNetwork/facebook.go b/adapters/audienceNetwork/facebook.go index 753b8a2cf70..8a288bb0338 100644 --- a/adapters/audienceNetwork/facebook.go +++ b/adapters/audienceNetwork/facebook.go @@ -13,12 +13,12 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/maputil" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/maputil" ) var supportedBannerHeights = map[int64]struct{}{ diff --git a/adapters/audienceNetwork/facebook_test.go b/adapters/audienceNetwork/facebook_test.go index 27af5506ab4..e2320c1eaea 100644 --- a/adapters/audienceNetwork/facebook_test.go +++ b/adapters/audienceNetwork/facebook_test.go @@ -4,10 +4,10 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/automatad/automatad.go b/adapters/automatad/automatad.go index 75f1dcf3b5a..3f74d290245 100644 --- a/adapters/automatad/automatad.go +++ b/adapters/automatad/automatad.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/automatad/automatad_test.go b/adapters/automatad/automatad_test.go index 914692741d1..790b2b42c67 100644 --- a/adapters/automatad/automatad_test.go +++ b/adapters/automatad/automatad_test.go @@ -3,9 +3,9 @@ package automatad import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/automatad/params_test.go b/adapters/automatad/params_test.go index df7f676b70a..468624c1eb3 100644 --- a/adapters/automatad/params_test.go +++ b/adapters/automatad/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/avocet/avocet.go b/adapters/avocet/avocet.go index 888fcab0fe2..b50b626792e 100644 --- a/adapters/avocet/avocet.go +++ b/adapters/avocet/avocet.go @@ -7,10 +7,10 @@ import ( "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // AvocetAdapter implements a adapters.Bidder compatible with the Avocet advertising platform. diff --git a/adapters/avocet/avocet_test.go b/adapters/avocet/avocet_test.go index 1dcf81c7d78..a7e01cdb65d 100644 --- a/adapters/avocet/avocet_test.go +++ b/adapters/avocet/avocet_test.go @@ -8,11 +8,11 @@ import ( "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/axis/axis.go b/adapters/axis/axis.go index f03a572e625..afda6045a1e 100644 --- a/adapters/axis/axis.go +++ b/adapters/axis/axis.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/axis/axis_test.go b/adapters/axis/axis_test.go index 56cb7f0b6e8..451141d8458 100644 --- a/adapters/axis/axis_test.go +++ b/adapters/axis/axis_test.go @@ -3,9 +3,9 @@ package axis import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/axis/params_test.go b/adapters/axis/params_test.go index ba374c80b0f..1c0391d6954 100644 --- a/adapters/axis/params_test.go +++ b/adapters/axis/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/axonix/axonix.go b/adapters/axonix/axonix.go index 2289050b462..d5d0b0a41ee 100644 --- a/adapters/axonix/axonix.go +++ b/adapters/axonix/axonix.go @@ -10,11 +10,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/axonix/axonix_test.go b/adapters/axonix/axonix_test.go index aa7fdf96b7c..9634a54fe65 100644 --- a/adapters/axonix/axonix_test.go +++ b/adapters/axonix/axonix_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/axonix/params_test.go b/adapters/axonix/params_test.go index d44fcd15e88..59b62220746 100644 --- a/adapters/axonix/params_test.go +++ b/adapters/axonix/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/axonix.json diff --git a/adapters/beachfront/beachfront.go b/adapters/beachfront/beachfront.go index 51e1d02d026..2eba35b91cb 100644 --- a/adapters/beachfront/beachfront.go +++ b/adapters/beachfront/beachfront.go @@ -10,10 +10,10 @@ import ( "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const Seat = "beachfront" diff --git a/adapters/beachfront/beachfront_test.go b/adapters/beachfront/beachfront_test.go index 3e1f75d6c41..23c4dcf6a9e 100644 --- a/adapters/beachfront/beachfront_test.go +++ b/adapters/beachfront/beachfront_test.go @@ -3,9 +3,9 @@ package beachfront import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/beachfront/params_test.go b/adapters/beachfront/params_test.go index a387a2f0af3..23e9ae7f492 100644 --- a/adapters/beachfront/params_test.go +++ b/adapters/beachfront/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/beintoo/beintoo.go b/adapters/beintoo/beintoo.go index 9fc51d6a3df..b4e7626a6f6 100644 --- a/adapters/beintoo/beintoo.go +++ b/adapters/beintoo/beintoo.go @@ -8,10 +8,10 @@ import ( "strconv" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type BeintooAdapter struct { diff --git a/adapters/beintoo/beintoo_test.go b/adapters/beintoo/beintoo_test.go index f95be60169b..11ef7ec9e7b 100644 --- a/adapters/beintoo/beintoo_test.go +++ b/adapters/beintoo/beintoo_test.go @@ -3,9 +3,9 @@ package beintoo import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/beintoo/params_test.go b/adapters/beintoo/params_test.go index b92b2a108dd..0392e08bb9b 100644 --- a/adapters/beintoo/params_test.go +++ b/adapters/beintoo/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/bematterfull/bematterfull.go b/adapters/bematterfull/bematterfull.go index bf63e7c8c8b..61b98d771ba 100644 --- a/adapters/bematterfull/bematterfull.go +++ b/adapters/bematterfull/bematterfull.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type bidType struct { diff --git a/adapters/bematterfull/bematterfulltest_test.go b/adapters/bematterfull/bematterfulltest_test.go index f3d1f412761..36198bc4f2a 100644 --- a/adapters/bematterfull/bematterfulltest_test.go +++ b/adapters/bematterfull/bematterfulltest_test.go @@ -3,9 +3,9 @@ package bematterfull import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/bematterfull/params_test.go b/adapters/bematterfull/params_test.go index 5983dd3e375..a093edbe6ac 100644 --- a/adapters/bematterfull/params_test.go +++ b/adapters/bematterfull/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/between/between.go b/adapters/between/between.go index 6e313374c86..9629f747657 100644 --- a/adapters/between/between.go +++ b/adapters/between/between.go @@ -9,11 +9,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type BetweenAdapter struct { diff --git a/adapters/between/between_test.go b/adapters/between/between_test.go index 453a331794f..332ba00b5d0 100644 --- a/adapters/between/between_test.go +++ b/adapters/between/between_test.go @@ -3,9 +3,9 @@ package between import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/between/params_test.go b/adapters/between/params_test.go index 1907084f9be..5772c218bc0 100644 --- a/adapters/between/params_test.go +++ b/adapters/between/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/between.json diff --git a/adapters/beyondmedia/beyondmedia.go b/adapters/beyondmedia/beyondmedia.go index 57674d58d52..50091aba03b 100644 --- a/adapters/beyondmedia/beyondmedia.go +++ b/adapters/beyondmedia/beyondmedia.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/beyondmedia/beyondmedia_test.go b/adapters/beyondmedia/beyondmedia_test.go index 9b22d1bb5d1..1f828e50b3a 100644 --- a/adapters/beyondmedia/beyondmedia_test.go +++ b/adapters/beyondmedia/beyondmedia_test.go @@ -3,9 +3,9 @@ package beyondmedia import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/beyondmedia/params_test.go b/adapters/beyondmedia/params_test.go index 9b0f8e8f6bb..8796b200ede 100644 --- a/adapters/beyondmedia/params_test.go +++ b/adapters/beyondmedia/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/bidder.go b/adapters/bidder.go index bb7424f3e00..b56f02e5156 100644 --- a/adapters/bidder.go +++ b/adapters/bidder.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // Bidder describes how to connect to external demand. diff --git a/adapters/bidmachine/bidmachine.go b/adapters/bidmachine/bidmachine.go index 3b760a3d530..da46a784625 100644 --- a/adapters/bidmachine/bidmachine.go +++ b/adapters/bidmachine/bidmachine.go @@ -12,11 +12,11 @@ import ( "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/bidmachine/bidmachine_test.go b/adapters/bidmachine/bidmachine_test.go index 8f32a2fc60d..282241c3d72 100644 --- a/adapters/bidmachine/bidmachine_test.go +++ b/adapters/bidmachine/bidmachine_test.go @@ -3,9 +3,9 @@ package bidmachine import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/bidmachine/params_test.go b/adapters/bidmachine/params_test.go index 15ebbcbf128..d396ee09cd3 100644 --- a/adapters/bidmachine/params_test.go +++ b/adapters/bidmachine/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/bidmyadz/bidmyadz.go b/adapters/bidmyadz/bidmyadz.go index 42af572c391..55b2da54e44 100644 --- a/adapters/bidmyadz/bidmyadz.go +++ b/adapters/bidmyadz/bidmyadz.go @@ -7,10 +7,10 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/bidmyadz/bidmyadz_test.go b/adapters/bidmyadz/bidmyadz_test.go index 1eb3ef67328..41badb559af 100644 --- a/adapters/bidmyadz/bidmyadz_test.go +++ b/adapters/bidmyadz/bidmyadz_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/bidmyadz/params_test.go b/adapters/bidmyadz/params_test.go index 857cde86d22..262dcf0880d 100644 --- a/adapters/bidmyadz/params_test.go +++ b/adapters/bidmyadz/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/bidscube/bidscube.go b/adapters/bidscube/bidscube.go index e654abb5564..a1bd72c171b 100644 --- a/adapters/bidscube/bidscube.go +++ b/adapters/bidscube/bidscube.go @@ -9,10 +9,10 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/bidscube/bidscube_test.go b/adapters/bidscube/bidscube_test.go index 137ba061f65..e64ccdbef63 100644 --- a/adapters/bidscube/bidscube_test.go +++ b/adapters/bidscube/bidscube_test.go @@ -3,9 +3,9 @@ package bidscube import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/bidscube/params_test.go b/adapters/bidscube/params_test.go index ff8ade9283c..9337c4dfb40 100644 --- a/adapters/bidscube/params_test.go +++ b/adapters/bidscube/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // TestValidParams makes sure that the bidscube schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/bidstack/bidstack.go b/adapters/bidstack/bidstack.go index c5c7f5b4865..a88b503a0f8 100644 --- a/adapters/bidstack/bidstack.go +++ b/adapters/bidstack/bidstack.go @@ -9,9 +9,9 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const ( diff --git a/adapters/bidstack/bidstack_test.go b/adapters/bidstack/bidstack_test.go index f1d476459bc..d6050bdad96 100644 --- a/adapters/bidstack/bidstack_test.go +++ b/adapters/bidstack/bidstack_test.go @@ -7,9 +7,9 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/bidstack/params_test.go b/adapters/bidstack/params_test.go index 832d6000f4c..d7dc18e4a03 100644 --- a/adapters/bidstack/params_test.go +++ b/adapters/bidstack/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/bizzclick/bizzclick.go b/adapters/bizzclick/bizzclick.go index 7f65f903b4b..fee2829dd6f 100644 --- a/adapters/bizzclick/bizzclick.go +++ b/adapters/bizzclick/bizzclick.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/bizzclick/bizzclick_test.go b/adapters/bizzclick/bizzclick_test.go index 91a9fcd1da4..971f06ae70f 100644 --- a/adapters/bizzclick/bizzclick_test.go +++ b/adapters/bizzclick/bizzclick_test.go @@ -3,9 +3,9 @@ package bizzclick import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/bizzclick/params_test.go b/adapters/bizzclick/params_test.go index 34211b006f5..496643a506f 100644 --- a/adapters/bizzclick/params_test.go +++ b/adapters/bizzclick/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/bliink/bliink.go b/adapters/bliink/bliink.go index 017b69bc683..bfd8aeb1dcc 100644 --- a/adapters/bliink/bliink.go +++ b/adapters/bliink/bliink.go @@ -7,10 +7,10 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/bliink/bliink_test.go b/adapters/bliink/bliink_test.go index a57a82e1765..02cafb37a4b 100644 --- a/adapters/bliink/bliink_test.go +++ b/adapters/bliink/bliink_test.go @@ -3,9 +3,9 @@ package bliink import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/bliink/params_test.go b/adapters/bliink/params_test.go index dc45a3249fe..d1066e8c4ed 100644 --- a/adapters/bliink/params_test.go +++ b/adapters/bliink/params_test.go @@ -2,8 +2,9 @@ package bliink import ( "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/blue/blue.go b/adapters/blue/blue.go index ae896d00760..d1743378c0b 100644 --- a/adapters/blue/blue.go +++ b/adapters/blue/blue.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/blue/blue_test.go b/adapters/blue/blue_test.go index d9febec66af..695984a3383 100644 --- a/adapters/blue/blue_test.go +++ b/adapters/blue/blue_test.go @@ -3,9 +3,9 @@ package blue import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestBidderBlue(t *testing.T) { diff --git a/adapters/bluesea/bluesea.go b/adapters/bluesea/bluesea.go index 44745ef00e8..7d8ff7d92b2 100644 --- a/adapters/bluesea/bluesea.go +++ b/adapters/bluesea/bluesea.go @@ -7,10 +7,10 @@ import ( "net/url" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/bluesea/bluesea_test.go b/adapters/bluesea/bluesea_test.go index 6b5ad16eb85..8bfe42ce150 100644 --- a/adapters/bluesea/bluesea_test.go +++ b/adapters/bluesea/bluesea_test.go @@ -3,9 +3,9 @@ package bluesea import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/bluesea/params_test.go b/adapters/bluesea/params_test.go index 62f14ee8c57..e1f7661ac09 100644 --- a/adapters/bluesea/params_test.go +++ b/adapters/bluesea/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // TestValidParams makes sure that the bluesea schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/bmtm/brightmountainmedia.go b/adapters/bmtm/brightmountainmedia.go index 591f03b4c1c..90bac4ac8ae 100644 --- a/adapters/bmtm/brightmountainmedia.go +++ b/adapters/bmtm/brightmountainmedia.go @@ -7,10 +7,10 @@ import ( "strconv" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/bmtm/brightmountainmedia_test.go b/adapters/bmtm/brightmountainmedia_test.go index 0455c8b99b6..f98cbde0063 100644 --- a/adapters/bmtm/brightmountainmedia_test.go +++ b/adapters/bmtm/brightmountainmedia_test.go @@ -3,9 +3,9 @@ package bmtm import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/bmtm/params_test.go b/adapters/bmtm/params_test.go index 8b196f1eec8..d4a07e5a294 100644 --- a/adapters/bmtm/params_test.go +++ b/adapters/bmtm/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/boldwin/boldwin.go b/adapters/boldwin/boldwin.go index 4d88ff01458..9425cd80fbb 100644 --- a/adapters/boldwin/boldwin.go +++ b/adapters/boldwin/boldwin.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/boldwin/boldwin_test.go b/adapters/boldwin/boldwin_test.go index 33d5c68f8de..a8921a9d27f 100644 --- a/adapters/boldwin/boldwin_test.go +++ b/adapters/boldwin/boldwin_test.go @@ -3,9 +3,9 @@ package boldwin import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/boldwin/params_test.go b/adapters/boldwin/params_test.go index f3855746160..2cef0d59cd6 100644 --- a/adapters/boldwin/params_test.go +++ b/adapters/boldwin/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/brave/brave.go b/adapters/brave/brave.go index b1270b6a866..bde07b66641 100755 --- a/adapters/brave/brave.go +++ b/adapters/brave/brave.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/brave/brave_test.go b/adapters/brave/brave_test.go index e8d0a474be9..e4f58252425 100644 --- a/adapters/brave/brave_test.go +++ b/adapters/brave/brave_test.go @@ -3,9 +3,9 @@ package brave import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/brave/params_test.go b/adapters/brave/params_test.go index 1120a13c2f9..c4bcd99959b 100644 --- a/adapters/brave/params_test.go +++ b/adapters/brave/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/cadent_aperture_mx/cadentaperturemx.go b/adapters/cadent_aperture_mx/cadentaperturemx.go index 5df000bf547..4b4ccc6b2e4 100644 --- a/adapters/cadent_aperture_mx/cadentaperturemx.go +++ b/adapters/cadent_aperture_mx/cadentaperturemx.go @@ -11,10 +11,10 @@ import ( "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/cadent_aperture_mx/cadentaperturemx_test.go b/adapters/cadent_aperture_mx/cadentaperturemx_test.go index 60034322797..961459a2ea8 100644 --- a/adapters/cadent_aperture_mx/cadentaperturemx_test.go +++ b/adapters/cadent_aperture_mx/cadentaperturemx_test.go @@ -3,10 +3,10 @@ package cadentaperturemx import ( "testing" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/cadent_aperture_mx/params_test.go b/adapters/cadent_aperture_mx/params_test.go index b5b7355376f..6691537d02c 100644 --- a/adapters/cadent_aperture_mx/params_test.go +++ b/adapters/cadent_aperture_mx/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/ccx/ccx.go b/adapters/ccx/ccx.go index 09b89b2c9af..ef5a6a17a9a 100644 --- a/adapters/ccx/ccx.go +++ b/adapters/ccx/ccx.go @@ -6,11 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/errortypes" ) type adapter struct { diff --git a/adapters/ccx/ccx_test.go b/adapters/ccx/ccx_test.go index 4d02c9848fd..86f85dc6eb7 100644 --- a/adapters/ccx/ccx_test.go +++ b/adapters/ccx/ccx_test.go @@ -3,9 +3,9 @@ package ccx import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/ccx/params_test.go b/adapters/ccx/params_test.go index ecd9421333b..cb500fec509 100644 --- a/adapters/ccx/params_test.go +++ b/adapters/ccx/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/coinzilla/coinzilla.go b/adapters/coinzilla/coinzilla.go index 039f3ecaf25..bc04758e537 100644 --- a/adapters/coinzilla/coinzilla.go +++ b/adapters/coinzilla/coinzilla.go @@ -6,11 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/errortypes" ) func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { diff --git a/adapters/coinzilla/coinzilla_test.go b/adapters/coinzilla/coinzilla_test.go index 6c79a2b12d1..39b3bb1f6e5 100644 --- a/adapters/coinzilla/coinzilla_test.go +++ b/adapters/coinzilla/coinzilla_test.go @@ -3,9 +3,9 @@ package coinzilla import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const testsDir = "coinzillatest" diff --git a/adapters/coinzilla/params_test.go b/adapters/coinzilla/params_test.go index fa24b144769..dd2cd757496 100644 --- a/adapters/coinzilla/params_test.go +++ b/adapters/coinzilla/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/colossus/colossus.go b/adapters/colossus/colossus.go index 65dd5c5dc9d..bc9836984ce 100644 --- a/adapters/colossus/colossus.go +++ b/adapters/colossus/colossus.go @@ -7,10 +7,10 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type ColossusAdapter struct { diff --git a/adapters/colossus/colossus_test.go b/adapters/colossus/colossus_test.go index 3b0f0fc5efe..6298b7f3958 100644 --- a/adapters/colossus/colossus_test.go +++ b/adapters/colossus/colossus_test.go @@ -3,9 +3,9 @@ package colossus import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/colossus/params_test.go b/adapters/colossus/params_test.go index 09fea5981c6..ebafd637d6a 100644 --- a/adapters/colossus/params_test.go +++ b/adapters/colossus/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // TestValidParams makes sure that the colossus schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/compass/compass.go b/adapters/compass/compass.go index 460d5307b45..3edf9b6f157 100644 --- a/adapters/compass/compass.go +++ b/adapters/compass/compass.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/compass/compass_test.go b/adapters/compass/compass_test.go index ad7a4ecf61b..08d9d1bb46e 100644 --- a/adapters/compass/compass_test.go +++ b/adapters/compass/compass_test.go @@ -3,9 +3,9 @@ package compass import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/compass/params_test.go b/adapters/compass/params_test.go index fca398b06fb..37074bb40f7 100644 --- a/adapters/compass/params_test.go +++ b/adapters/compass/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/connectad/connectad.go b/adapters/connectad/connectad.go index 1c33d6bf3c6..ee2e8eeb699 100644 --- a/adapters/connectad/connectad.go +++ b/adapters/connectad/connectad.go @@ -8,10 +8,10 @@ import ( "strconv" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type ConnectAdAdapter struct { diff --git a/adapters/connectad/connectad_test.go b/adapters/connectad/connectad_test.go index 037ccbb0a3d..6ce9dd3eade 100644 --- a/adapters/connectad/connectad_test.go +++ b/adapters/connectad/connectad_test.go @@ -3,9 +3,9 @@ package connectad import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/connectad/params_test.go b/adapters/connectad/params_test.go index 6d55b1ce7d9..2ab3c4902e7 100644 --- a/adapters/connectad/params_test.go +++ b/adapters/connectad/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/consumable/consumable.go b/adapters/consumable/consumable.go index 0e16497774c..635bc7058ed 100644 --- a/adapters/consumable/consumable.go +++ b/adapters/consumable/consumable.go @@ -9,11 +9,11 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/privacy/ccpa" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/privacy/ccpa" ) type ConsumableAdapter struct { diff --git a/adapters/consumable/consumable_test.go b/adapters/consumable/consumable_test.go index 5cfe3fe2824..e3bedce5e2f 100644 --- a/adapters/consumable/consumable_test.go +++ b/adapters/consumable/consumable_test.go @@ -4,10 +4,10 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/consumable/params_test.go b/adapters/consumable/params_test.go index 570b4128339..fdb3edec41b 100644 --- a/adapters/consumable/params_test.go +++ b/adapters/consumable/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/consumable.json diff --git a/adapters/conversant/conversant.go b/adapters/conversant/conversant.go index ec4d2078df8..56ed4b0865c 100644 --- a/adapters/conversant/conversant.go +++ b/adapters/conversant/conversant.go @@ -7,10 +7,10 @@ import ( "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type ConversantAdapter struct { diff --git a/adapters/conversant/conversant_test.go b/adapters/conversant/conversant_test.go index ac3f5a2b633..1c08ea557ed 100644 --- a/adapters/conversant/conversant_test.go +++ b/adapters/conversant/conversant_test.go @@ -3,9 +3,9 @@ package conversant import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/cpmstar/cpmstar.go b/adapters/cpmstar/cpmstar.go index ecb963311b9..f337c1477c5 100644 --- a/adapters/cpmstar/cpmstar.go +++ b/adapters/cpmstar/cpmstar.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type Adapter struct { diff --git a/adapters/cpmstar/cpmstar_test.go b/adapters/cpmstar/cpmstar_test.go index 9218ef4ce2c..2a08258358b 100644 --- a/adapters/cpmstar/cpmstar_test.go +++ b/adapters/cpmstar/cpmstar_test.go @@ -3,9 +3,9 @@ package cpmstar import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/cpmstar/params_test.go b/adapters/cpmstar/params_test.go index 45b1fbefd96..e0dcb9ced52 100644 --- a/adapters/cpmstar/params_test.go +++ b/adapters/cpmstar/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/cpmstar.json diff --git a/adapters/criteo/criteo.go b/adapters/criteo/criteo.go index 11d8d166ba6..cef79d46756 100644 --- a/adapters/criteo/criteo.go +++ b/adapters/criteo/criteo.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/criteo/criteo_test.go b/adapters/criteo/criteo_test.go index 28654acd310..ae538246444 100644 --- a/adapters/criteo/criteo_test.go +++ b/adapters/criteo/criteo_test.go @@ -1,10 +1,11 @@ package criteo import ( - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/criteo/params_test.go b/adapters/criteo/params_test.go index c373de0a83f..aa17aa87e2e 100644 --- a/adapters/criteo/params_test.go +++ b/adapters/criteo/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/criteo.json diff --git a/adapters/cwire/cwire.go b/adapters/cwire/cwire.go index 97a51ed764b..0c51fed908d 100644 --- a/adapters/cwire/cwire.go +++ b/adapters/cwire/cwire.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) /* diff --git a/adapters/cwire/cwire_test.go b/adapters/cwire/cwire_test.go index b51b4e1b007..bd5f32e99ff 100644 --- a/adapters/cwire/cwire_test.go +++ b/adapters/cwire/cwire_test.go @@ -3,9 +3,9 @@ package cwire import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/cwire/params_test.go b/adapters/cwire/params_test.go index 99689977530..d8c8b117069 100644 --- a/adapters/cwire/params_test.go +++ b/adapters/cwire/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/cwire.json diff --git a/adapters/datablocks/datablocks.go b/adapters/datablocks/datablocks.go index a39721a44a3..22bf67bdbbe 100644 --- a/adapters/datablocks/datablocks.go +++ b/adapters/datablocks/datablocks.go @@ -8,11 +8,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type DatablocksAdapter struct { diff --git a/adapters/datablocks/datablocks_test.go b/adapters/datablocks/datablocks_test.go index 3d4d746d357..d97560ce332 100644 --- a/adapters/datablocks/datablocks_test.go +++ b/adapters/datablocks/datablocks_test.go @@ -3,9 +3,9 @@ package datablocks import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/decenterads/decenterads.go b/adapters/decenterads/decenterads.go index d959c9b41ca..bf673ee1691 100644 --- a/adapters/decenterads/decenterads.go +++ b/adapters/decenterads/decenterads.go @@ -8,10 +8,10 @@ import ( "strconv" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/decenterads/decenterads_test.go b/adapters/decenterads/decenterads_test.go index 3c1ed971833..dfb5161b9c4 100644 --- a/adapters/decenterads/decenterads_test.go +++ b/adapters/decenterads/decenterads_test.go @@ -3,9 +3,9 @@ package decenterads import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/decenterads/params_test.go b/adapters/decenterads/params_test.go index 3d3708be789..ef8b47cce41 100644 --- a/adapters/decenterads/params_test.go +++ b/adapters/decenterads/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // TestValidParams makes sure that the decenterads schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/deepintent/deepintent.go b/adapters/deepintent/deepintent.go index 765c43e5c13..1bda503ae32 100644 --- a/adapters/deepintent/deepintent.go +++ b/adapters/deepintent/deepintent.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const displayManager string = "di_prebid" diff --git a/adapters/deepintent/deepintent_test.go b/adapters/deepintent/deepintent_test.go index 97f685d2f7e..9b2c92967b4 100644 --- a/adapters/deepintent/deepintent_test.go +++ b/adapters/deepintent/deepintent_test.go @@ -3,10 +3,10 @@ package deepintent import ( "testing" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/deepintent/params_test.go b/adapters/deepintent/params_test.go index 8f37e5a9bd6..4cd43b73ebe 100644 --- a/adapters/deepintent/params_test.go +++ b/adapters/deepintent/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // TestValidParams makes sure that the deepintent schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/definemedia/definemedia.go b/adapters/definemedia/definemedia.go index 3e014e3c16d..789902d0485 100644 --- a/adapters/definemedia/definemedia.go +++ b/adapters/definemedia/definemedia.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/definemedia/definemedia_test.go b/adapters/definemedia/definemedia_test.go index 3ed0cb938b8..8a2a860d0c0 100644 --- a/adapters/definemedia/definemedia_test.go +++ b/adapters/definemedia/definemedia_test.go @@ -3,9 +3,9 @@ package definemedia import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/definemedia/params_test.go b/adapters/definemedia/params_test.go index 63ef5272669..45b5be4eae5 100644 --- a/adapters/definemedia/params_test.go +++ b/adapters/definemedia/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/dianomi/dianomi.go b/adapters/dianomi/dianomi.go index 10605ef24a7..f7b97748c5b 100644 --- a/adapters/dianomi/dianomi.go +++ b/adapters/dianomi/dianomi.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/dianomi/dianomi_test.go b/adapters/dianomi/dianomi_test.go index 95c94a02f14..1baa4b591b3 100644 --- a/adapters/dianomi/dianomi_test.go +++ b/adapters/dianomi/dianomi_test.go @@ -3,9 +3,9 @@ package dianomi import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/dianomi/params_test.go b/adapters/dianomi/params_test.go index 462d6d75edd..43a9bf6f4f5 100644 --- a/adapters/dianomi/params_test.go +++ b/adapters/dianomi/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/dianomi.json diff --git a/adapters/dmx/dmx.go b/adapters/dmx/dmx.go index 4f1f23a625c..488c3d46453 100644 --- a/adapters/dmx/dmx.go +++ b/adapters/dmx/dmx.go @@ -10,10 +10,10 @@ import ( "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type DmxAdapter struct { diff --git a/adapters/dmx/dmx_test.go b/adapters/dmx/dmx_test.go index 1634e6b5956..c709d5b1617 100644 --- a/adapters/dmx/dmx_test.go +++ b/adapters/dmx/dmx_test.go @@ -6,11 +6,11 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" ) func TestFetchParams(t *testing.T) { diff --git a/adapters/dmx/params_test.go b/adapters/dmx/params_test.go index 0e5250b173e..4470fb23057 100644 --- a/adapters/dmx/params_test.go +++ b/adapters/dmx/params_test.go @@ -2,8 +2,9 @@ package dmx import ( "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/dxkulture/dxkulture.go b/adapters/dxkulture/dxkulture.go index 5347c71a303..8155f59a203 100644 --- a/adapters/dxkulture/dxkulture.go +++ b/adapters/dxkulture/dxkulture.go @@ -6,10 +6,10 @@ import ( "net/http" "net/url" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/prebid/openrtb/v19/openrtb2" ) diff --git a/adapters/dxkulture/dxkulture_test.go b/adapters/dxkulture/dxkulture_test.go index 9b2da4f27ab..fb14c2b3c6a 100644 --- a/adapters/dxkulture/dxkulture_test.go +++ b/adapters/dxkulture/dxkulture_test.go @@ -3,9 +3,9 @@ package dxkulture import ( "testing" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/dxkulture/params_test.go b/adapters/dxkulture/params_test.go index 838d092df8f..d1c2f91a7ce 100644 --- a/adapters/dxkulture/params_test.go +++ b/adapters/dxkulture/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/dxkulture.json diff --git a/adapters/e_volution/evolution.go b/adapters/e_volution/evolution.go index af2c680f99c..4beb488f801 100644 --- a/adapters/e_volution/evolution.go +++ b/adapters/e_volution/evolution.go @@ -7,10 +7,10 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/e_volution/evolution_test.go b/adapters/e_volution/evolution_test.go index 9752a4c7587..4529a742077 100644 --- a/adapters/e_volution/evolution_test.go +++ b/adapters/e_volution/evolution_test.go @@ -3,9 +3,9 @@ package evolution import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/e_volution/params_test.go b/adapters/e_volution/params_test.go index 2d3602fd72b..6049bce7780 100644 --- a/adapters/e_volution/params_test.go +++ b/adapters/e_volution/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/edge226/edge226.go b/adapters/edge226/edge226.go index a124cb47eca..2196006b766 100644 --- a/adapters/edge226/edge226.go +++ b/adapters/edge226/edge226.go @@ -6,9 +6,9 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/edge226/edge226_test.go b/adapters/edge226/edge226_test.go index c5e40ce726d..fea4abff1a9 100644 --- a/adapters/edge226/edge226_test.go +++ b/adapters/edge226/edge226_test.go @@ -3,9 +3,9 @@ package edge226 import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/edge226/params_test.go b/adapters/edge226/params_test.go index 3191bc62136..21a83bd65fd 100644 --- a/adapters/edge226/params_test.go +++ b/adapters/edge226/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/emtv/emtv.go b/adapters/emtv/emtv.go index 5dbd1e1bde7..0f0cae04f1f 100644 --- a/adapters/emtv/emtv.go +++ b/adapters/emtv/emtv.go @@ -7,10 +7,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/emtv/emtv_test.go b/adapters/emtv/emtv_test.go index b1287357681..238e463a0d5 100644 --- a/adapters/emtv/emtv_test.go +++ b/adapters/emtv/emtv_test.go @@ -3,9 +3,9 @@ package emtv import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/emtv/params_test.go b/adapters/emtv/params_test.go index 966dd7dd460..40769b97942 100644 --- a/adapters/emtv/params_test.go +++ b/adapters/emtv/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/eplanning/eplanning.go b/adapters/eplanning/eplanning.go index 8342da63ec2..16c30296b83 100644 --- a/adapters/eplanning/eplanning.go +++ b/adapters/eplanning/eplanning.go @@ -13,10 +13,10 @@ import ( "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" "strconv" ) diff --git a/adapters/eplanning/eplanning_test.go b/adapters/eplanning/eplanning_test.go index c4a33e54c3d..44ab91413d4 100644 --- a/adapters/eplanning/eplanning_test.go +++ b/adapters/eplanning/eplanning_test.go @@ -3,10 +3,10 @@ package eplanning import ( "testing" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/epom/epom.go b/adapters/epom/epom.go index a4e3040f079..37ef9543979 100644 --- a/adapters/epom/epom.go +++ b/adapters/epom/epom.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/epom/epom_test.go b/adapters/epom/epom_test.go index 6769ff6beb1..4e31c2ab982 100644 --- a/adapters/epom/epom_test.go +++ b/adapters/epom/epom_test.go @@ -3,9 +3,9 @@ package epom import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/flipp/flipp.go b/adapters/flipp/flipp.go index 14f31a91efb..c119ec078cc 100644 --- a/adapters/flipp/flipp.go +++ b/adapters/flipp/flipp.go @@ -10,9 +10,9 @@ import ( "github.com/buger/jsonparser" "github.com/gofrs/uuid" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const ( diff --git a/adapters/flipp/flipp_params.go b/adapters/flipp/flipp_params.go index 0eef61b4b89..11f00560ba4 100644 --- a/adapters/flipp/flipp_params.go +++ b/adapters/flipp/flipp_params.go @@ -1,6 +1,6 @@ package flipp -import "github.com/prebid/prebid-server/openrtb_ext" +import "github.com/prebid/prebid-server/v2/openrtb_ext" type CampaignRequestBodyUser struct { Key *string `json:"key"` diff --git a/adapters/flipp/flipp_test.go b/adapters/flipp/flipp_test.go index 79b79e20769..e9ba0d138fd 100644 --- a/adapters/flipp/flipp_test.go +++ b/adapters/flipp/flipp_test.go @@ -3,9 +3,9 @@ package flipp import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/flipp/params_test.go b/adapters/flipp/params_test.go index 56f2fadbbdd..37f1fda6324 100644 --- a/adapters/flipp/params_test.go +++ b/adapters/flipp/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/freewheelssp/freewheelssp.go b/adapters/freewheelssp/freewheelssp.go index 06f975b3501..1a1738a4ef7 100644 --- a/adapters/freewheelssp/freewheelssp.go +++ b/adapters/freewheelssp/freewheelssp.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/freewheelssp/freewheelssp_test.go b/adapters/freewheelssp/freewheelssp_test.go index 5f06a29c2fd..ea1b5b7c980 100644 --- a/adapters/freewheelssp/freewheelssp_test.go +++ b/adapters/freewheelssp/freewheelssp_test.go @@ -1,10 +1,11 @@ package freewheelssp import ( - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/frvradn/frvradn.go b/adapters/frvradn/frvradn.go index 4088bf9cdf6..6781dbc50cf 100644 --- a/adapters/frvradn/frvradn.go +++ b/adapters/frvradn/frvradn.go @@ -7,10 +7,10 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/frvradn/frvradn_test.go b/adapters/frvradn/frvradn_test.go index f50f319b04f..89f3dc50b42 100644 --- a/adapters/frvradn/frvradn_test.go +++ b/adapters/frvradn/frvradn_test.go @@ -1,12 +1,13 @@ package frvradn import ( - "github.com/stretchr/testify/assert" "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/stretchr/testify/assert" + + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/frvradn/params_test.go b/adapters/frvradn/params_test.go index 2d4836c1e13..74a51b26fa2 100644 --- a/adapters/frvradn/params_test.go +++ b/adapters/frvradn/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/gamma/gamma.go b/adapters/gamma/gamma.go index 37862424ac7..fac38735507 100644 --- a/adapters/gamma/gamma.go +++ b/adapters/gamma/gamma.go @@ -9,10 +9,10 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/openrtb/v19/openrtb3" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type GammaAdapter struct { diff --git a/adapters/gamma/gamma_test.go b/adapters/gamma/gamma_test.go index 08709364ce9..78cde32984e 100644 --- a/adapters/gamma/gamma_test.go +++ b/adapters/gamma/gamma_test.go @@ -3,9 +3,9 @@ package gamma import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/gamma/params_test.go b/adapters/gamma/params_test.go index c6a149c23bc..7d2d211b054 100644 --- a/adapters/gamma/params_test.go +++ b/adapters/gamma/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/gamma.json diff --git a/adapters/gamoshi/gamoshi.go b/adapters/gamoshi/gamoshi.go index 10c5127e613..db066364bf0 100644 --- a/adapters/gamoshi/gamoshi.go +++ b/adapters/gamoshi/gamoshi.go @@ -7,10 +7,10 @@ import ( "strconv" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type GamoshiAdapter struct { diff --git a/adapters/gamoshi/gamoshi_test.go b/adapters/gamoshi/gamoshi_test.go index 979f54cddab..4c787aeb700 100644 --- a/adapters/gamoshi/gamoshi_test.go +++ b/adapters/gamoshi/gamoshi_test.go @@ -3,9 +3,9 @@ package gamoshi import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamplesWithConfiguredURI(t *testing.T) { diff --git a/adapters/gamoshi/params_test.go b/adapters/gamoshi/params_test.go index b9659aaa68a..6fb5d9ee08b 100644 --- a/adapters/gamoshi/params_test.go +++ b/adapters/gamoshi/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/gamoshi.json diff --git a/adapters/globalsun/globalsun.go b/adapters/globalsun/globalsun.go index 6c381fbc0e4..3406f36b704 100644 --- a/adapters/globalsun/globalsun.go +++ b/adapters/globalsun/globalsun.go @@ -7,10 +7,10 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/globalsun/globalsun_test.go b/adapters/globalsun/globalsun_test.go index 0237422dc84..a2f33770486 100644 --- a/adapters/globalsun/globalsun_test.go +++ b/adapters/globalsun/globalsun_test.go @@ -3,9 +3,9 @@ package globalsun import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/globalsun/params_test.go b/adapters/globalsun/params_test.go index af71ad516c2..87d6427ad8b 100644 --- a/adapters/globalsun/params_test.go +++ b/adapters/globalsun/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/gothamads/gothamads.go b/adapters/gothamads/gothamads.go index e486585c958..301a4613677 100644 --- a/adapters/gothamads/gothamads.go +++ b/adapters/gothamads/gothamads.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/gothamads/gothamads_test.go b/adapters/gothamads/gothamads_test.go index 82e34dde1b3..5dde1527f3f 100644 --- a/adapters/gothamads/gothamads_test.go +++ b/adapters/gothamads/gothamads_test.go @@ -3,9 +3,9 @@ package gothamads import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/gothamads/params_test.go b/adapters/gothamads/params_test.go index 1290216d28e..1db984321e1 100644 --- a/adapters/gothamads/params_test.go +++ b/adapters/gothamads/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/grid/grid.go b/adapters/grid/grid.go index 4f44f90ab11..0d6bdd76d9b 100644 --- a/adapters/grid/grid.go +++ b/adapters/grid/grid.go @@ -8,11 +8,11 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/maputil" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/maputil" ) type GridAdapter struct { diff --git a/adapters/grid/grid_test.go b/adapters/grid/grid_test.go index 38e9341cdaf..f35f0c66582 100644 --- a/adapters/grid/grid_test.go +++ b/adapters/grid/grid_test.go @@ -3,9 +3,9 @@ package grid import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/gumgum/gumgum.go b/adapters/gumgum/gumgum.go index a500376e72a..3b954bf5837 100644 --- a/adapters/gumgum/gumgum.go +++ b/adapters/gumgum/gumgum.go @@ -8,10 +8,10 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // GumGumAdapter implements Bidder interface. diff --git a/adapters/gumgum/gumgum_test.go b/adapters/gumgum/gumgum_test.go index fa78eb10e11..621b4a96b04 100644 --- a/adapters/gumgum/gumgum_test.go +++ b/adapters/gumgum/gumgum_test.go @@ -3,9 +3,9 @@ package gumgum import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/gumgum/params_test.go b/adapters/gumgum/params_test.go index a578ce65762..afee017be03 100644 --- a/adapters/gumgum/params_test.go +++ b/adapters/gumgum/params_test.go @@ -2,8 +2,9 @@ package gumgum import ( "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/huaweiads/huaweiads.go b/adapters/huaweiads/huaweiads.go index d156c2f750f..68622bf9f9e 100644 --- a/adapters/huaweiads/huaweiads.go +++ b/adapters/huaweiads/huaweiads.go @@ -19,10 +19,10 @@ import ( nativeRequests "github.com/prebid/openrtb/v19/native1/request" nativeResponse "github.com/prebid/openrtb/v19/native1/response" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const huaweiAdxApiVersion = "3.4" diff --git a/adapters/huaweiads/huaweiads_test.go b/adapters/huaweiads/huaweiads_test.go index f523f0b9d94..9e7d0b55364 100644 --- a/adapters/huaweiads/huaweiads_test.go +++ b/adapters/huaweiads/huaweiads_test.go @@ -3,9 +3,9 @@ package huaweiads import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/huaweiads/params_test.go b/adapters/huaweiads/params_test.go index 7347725b299..c93c3c3ac55 100644 --- a/adapters/huaweiads/params_test.go +++ b/adapters/huaweiads/params_test.go @@ -2,8 +2,9 @@ package huaweiads import ( "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/imds/imds.go b/adapters/imds/imds.go index 02d30828966..c5ef45176ab 100644 --- a/adapters/imds/imds.go +++ b/adapters/imds/imds.go @@ -8,11 +8,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const adapterVersion string = "pbs-go/1.0.0" diff --git a/adapters/imds/imds_test.go b/adapters/imds/imds_test.go index 5fab0509c1d..6e8165fbe6a 100644 --- a/adapters/imds/imds_test.go +++ b/adapters/imds/imds_test.go @@ -3,9 +3,9 @@ package imds import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/imds/params_test.go b/adapters/imds/params_test.go index e2052b4c262..740105c3183 100644 --- a/adapters/imds/params_test.go +++ b/adapters/imds/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/imds.json diff --git a/adapters/impactify/impactify.go b/adapters/impactify/impactify.go index bfbcdfbf8a2..73dc9450a3b 100644 --- a/adapters/impactify/impactify.go +++ b/adapters/impactify/impactify.go @@ -8,10 +8,10 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/impactify/impactify_test.go b/adapters/impactify/impactify_test.go index 550ea7ad498..b9518d5e2a3 100644 --- a/adapters/impactify/impactify_test.go +++ b/adapters/impactify/impactify_test.go @@ -3,9 +3,9 @@ package impactify import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/impactify/params_test.go b/adapters/impactify/params_test.go index 845ea29f00b..2fa8b24d627 100644 --- a/adapters/impactify/params_test.go +++ b/adapters/impactify/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/improvedigital/improvedigital.go b/adapters/improvedigital/improvedigital.go index c26a200a486..2cad15fa033 100644 --- a/adapters/improvedigital/improvedigital.go +++ b/adapters/improvedigital/improvedigital.go @@ -3,15 +3,16 @@ package improvedigital import ( "encoding/json" "fmt" - "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" "net/http" "regexp" "strconv" "strings" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const ( diff --git a/adapters/improvedigital/improvedigital_test.go b/adapters/improvedigital/improvedigital_test.go index 15ca5d5f033..b89e03320fa 100644 --- a/adapters/improvedigital/improvedigital_test.go +++ b/adapters/improvedigital/improvedigital_test.go @@ -3,9 +3,9 @@ package improvedigital import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/improvedigital/params_test.go b/adapters/improvedigital/params_test.go index 13bdd807560..3767c0316a5 100644 --- a/adapters/improvedigital/params_test.go +++ b/adapters/improvedigital/params_test.go @@ -2,8 +2,9 @@ package improvedigital import ( "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/infoawarebidder.go b/adapters/infoawarebidder.go index 538a46ae05c..3131a6404b1 100644 --- a/adapters/infoawarebidder.go +++ b/adapters/infoawarebidder.go @@ -4,9 +4,9 @@ import ( "fmt" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // InfoAwareBidder wraps a Bidder to ensure all requests abide by the capabilities and diff --git a/adapters/infoawarebidder_test.go b/adapters/infoawarebidder_test.go index 87d9d4d442a..38570e262d4 100644 --- a/adapters/infoawarebidder_test.go +++ b/adapters/infoawarebidder_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/adapters/infytv/infytv.go b/adapters/infytv/infytv.go index b403e710911..7e93a7296a5 100644 --- a/adapters/infytv/infytv.go +++ b/adapters/infytv/infytv.go @@ -7,10 +7,10 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/infytv/infytv_test.go b/adapters/infytv/infytv_test.go index 6834e99fa36..80527bbc4ae 100644 --- a/adapters/infytv/infytv_test.go +++ b/adapters/infytv/infytv_test.go @@ -3,9 +3,9 @@ package infytv import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/infytv/params_test.go b/adapters/infytv/params_test.go index 6719b102622..53230cbf263 100644 --- a/adapters/infytv/params_test.go +++ b/adapters/infytv/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/inmobi/inmobi.go b/adapters/inmobi/inmobi.go index a5773c83be9..54d644cdc7d 100644 --- a/adapters/inmobi/inmobi.go +++ b/adapters/inmobi/inmobi.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type InMobiAdapter struct { diff --git a/adapters/inmobi/inmobi_test.go b/adapters/inmobi/inmobi_test.go index 0b6f5ffbd0e..40e77f5fbc3 100644 --- a/adapters/inmobi/inmobi_test.go +++ b/adapters/inmobi/inmobi_test.go @@ -3,9 +3,9 @@ package inmobi import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/interactiveoffers/interactiveoffers.go b/adapters/interactiveoffers/interactiveoffers.go index 2f90b707244..2e1a6417f14 100644 --- a/adapters/interactiveoffers/interactiveoffers.go +++ b/adapters/interactiveoffers/interactiveoffers.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/interactiveoffers/interactiveoffers_test.go b/adapters/interactiveoffers/interactiveoffers_test.go index 7805ae665bb..daf83869a95 100644 --- a/adapters/interactiveoffers/interactiveoffers_test.go +++ b/adapters/interactiveoffers/interactiveoffers_test.go @@ -3,9 +3,9 @@ package interactiveoffers import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/interactiveoffers/params_test.go b/adapters/interactiveoffers/params_test.go index 193c1b84839..8f14a51b512 100644 --- a/adapters/interactiveoffers/params_test.go +++ b/adapters/interactiveoffers/params_test.go @@ -2,8 +2,9 @@ package interactiveoffers import ( "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/invibes/invibes.go b/adapters/invibes/invibes.go index b1272415d93..e1b978831b8 100644 --- a/adapters/invibes/invibes.go +++ b/adapters/invibes/invibes.go @@ -10,12 +10,12 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const adapterVersion = "prebid_1.0.0" diff --git a/adapters/invibes/invibes_test.go b/adapters/invibes/invibes_test.go index 1ade5d276cd..e09837764f9 100644 --- a/adapters/invibes/invibes_test.go +++ b/adapters/invibes/invibes_test.go @@ -3,9 +3,9 @@ package invibes import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/invibes/params_test.go b/adapters/invibes/params_test.go index 8c3a26b4eac..88e08d1dc80 100644 --- a/adapters/invibes/params_test.go +++ b/adapters/invibes/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/iqx/iqx.go b/adapters/iqx/iqx.go index 543d988bce5..edfefa1895e 100644 --- a/adapters/iqx/iqx.go +++ b/adapters/iqx/iqx.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type bidType struct { diff --git a/adapters/iqx/iqxtest_test.go b/adapters/iqx/iqxtest_test.go index 18eaf5fa5ba..7385d37af91 100644 --- a/adapters/iqx/iqxtest_test.go +++ b/adapters/iqx/iqxtest_test.go @@ -3,9 +3,9 @@ package iqx import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/iqx/params_test.go b/adapters/iqx/params_test.go index 94bfb1d0926..23c4d007acb 100644 --- a/adapters/iqx/params_test.go +++ b/adapters/iqx/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/iqzone/iqzone.go b/adapters/iqzone/iqzone.go index 9c36a021e21..ce095c97009 100644 --- a/adapters/iqzone/iqzone.go +++ b/adapters/iqzone/iqzone.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/iqzone/iqzone_test.go b/adapters/iqzone/iqzone_test.go index 3e1afbe1909..c5713953f40 100644 --- a/adapters/iqzone/iqzone_test.go +++ b/adapters/iqzone/iqzone_test.go @@ -3,9 +3,9 @@ package iqzone import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/iqzone/params_test.go b/adapters/iqzone/params_test.go index c06f5e7fab4..2c6bb223845 100644 --- a/adapters/iqzone/params_test.go +++ b/adapters/iqzone/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/ix/ix.go b/adapters/ix/ix.go index 300858e3205..f000cbc1625 100644 --- a/adapters/ix/ix.go +++ b/adapters/ix/ix.go @@ -7,11 +7,11 @@ import ( "sort" "strings" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/version" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/version" "github.com/prebid/openrtb/v19/native1" native1response "github.com/prebid/openrtb/v19/native1/response" diff --git a/adapters/ix/ix_test.go b/adapters/ix/ix_test.go index a64e3d0c661..e2651ca523e 100644 --- a/adapters/ix/ix_test.go +++ b/adapters/ix/ix_test.go @@ -4,11 +4,11 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/version" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/version" "github.com/stretchr/testify/assert" "github.com/prebid/openrtb/v19/adcom1" diff --git a/adapters/ix/params_test.go b/adapters/ix/params_test.go index 8ba937c12f4..ba426c0b27b 100644 --- a/adapters/ix/params_test.go +++ b/adapters/ix/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/jixie/jixie.go b/adapters/jixie/jixie.go index 6018b73709b..fa87bd5da03 100644 --- a/adapters/jixie/jixie.go +++ b/adapters/jixie/jixie.go @@ -7,10 +7,10 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/jixie/jixie_test.go b/adapters/jixie/jixie_test.go index 56260a6c04d..dff2b3574d3 100644 --- a/adapters/jixie/jixie_test.go +++ b/adapters/jixie/jixie_test.go @@ -3,9 +3,9 @@ package jixie import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/jixie/params_test.go b/adapters/jixie/params_test.go index 4bc2e3080c1..cbcdbe959de 100644 --- a/adapters/jixie/params_test.go +++ b/adapters/jixie/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/kargo/kargo.go b/adapters/kargo/kargo.go index e10bbbe466b..003275c51d3 100644 --- a/adapters/kargo/kargo.go +++ b/adapters/kargo/kargo.go @@ -7,10 +7,10 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/kargo/kargo_test.go b/adapters/kargo/kargo_test.go index 482ef2361cf..f2ceb46f643 100644 --- a/adapters/kargo/kargo_test.go +++ b/adapters/kargo/kargo_test.go @@ -3,9 +3,9 @@ package kargo import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/kargo/params_test.go b/adapters/kargo/params_test.go index cb9ffaf1028..9907d67116c 100644 --- a/adapters/kargo/params_test.go +++ b/adapters/kargo/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/kayzen/kayzen.go b/adapters/kayzen/kayzen.go index 3dac0a50e86..a4c459ac2a2 100644 --- a/adapters/kayzen/kayzen.go +++ b/adapters/kayzen/kayzen.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/kayzen/kayzen_test.go b/adapters/kayzen/kayzen_test.go index dc6a7db4735..a2cc98a7798 100644 --- a/adapters/kayzen/kayzen_test.go +++ b/adapters/kayzen/kayzen_test.go @@ -3,9 +3,9 @@ package kayzen import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/kayzen/params_test.go b/adapters/kayzen/params_test.go index 07bd0851a97..bd03e23df5b 100644 --- a/adapters/kayzen/params_test.go +++ b/adapters/kayzen/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/kidoz/kidoz.go b/adapters/kidoz/kidoz.go index b2637768bb1..f18ed98c07b 100644 --- a/adapters/kidoz/kidoz.go +++ b/adapters/kidoz/kidoz.go @@ -7,10 +7,10 @@ import ( "strconv" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type KidozAdapter struct { diff --git a/adapters/kidoz/kidoz_test.go b/adapters/kidoz/kidoz_test.go index ffde298ee0e..0a5e21fd62d 100644 --- a/adapters/kidoz/kidoz_test.go +++ b/adapters/kidoz/kidoz_test.go @@ -6,10 +6,10 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/kidoz/params_test.go b/adapters/kidoz/params_test.go index 073d7382d68..fad4e681288 100644 --- a/adapters/kidoz/params_test.go +++ b/adapters/kidoz/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/kiviads/kiviads.go b/adapters/kiviads/kiviads.go index 88d245a5db2..8bdf72145d4 100644 --- a/adapters/kiviads/kiviads.go +++ b/adapters/kiviads/kiviads.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/kiviads/kiviads_test.go b/adapters/kiviads/kiviads_test.go index 41e9bcbcdee..a6725234e6a 100644 --- a/adapters/kiviads/kiviads_test.go +++ b/adapters/kiviads/kiviads_test.go @@ -3,9 +3,9 @@ package kiviads import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/kiviads/params_test.go b/adapters/kiviads/params_test.go index 177e2f149b3..09ee3e24265 100644 --- a/adapters/kiviads/params_test.go +++ b/adapters/kiviads/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/krushmedia/krushmedia.go b/adapters/krushmedia/krushmedia.go index 71a869a42a1..e809960db8c 100644 --- a/adapters/krushmedia/krushmedia.go +++ b/adapters/krushmedia/krushmedia.go @@ -8,11 +8,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type KrushmediaAdapter struct { diff --git a/adapters/krushmedia/krushmedia_test.go b/adapters/krushmedia/krushmedia_test.go index 7ffbc0a9361..e7d71422dfe 100644 --- a/adapters/krushmedia/krushmedia_test.go +++ b/adapters/krushmedia/krushmedia_test.go @@ -3,9 +3,9 @@ package krushmedia import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/krushmedia/params_test.go b/adapters/krushmedia/params_test.go index 26daa56e10b..4129fa1bd29 100644 --- a/adapters/krushmedia/params_test.go +++ b/adapters/krushmedia/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/lemmadigital/lemmadigital.go b/adapters/lemmadigital/lemmadigital.go index 3b77de52984..d09793fa4e8 100644 --- a/adapters/lemmadigital/lemmadigital.go +++ b/adapters/lemmadigital/lemmadigital.go @@ -8,11 +8,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/lemmadigital/lemmadigital_test.go b/adapters/lemmadigital/lemmadigital_test.go index 0372fa81d6b..e0062c0b565 100644 --- a/adapters/lemmadigital/lemmadigital_test.go +++ b/adapters/lemmadigital/lemmadigital_test.go @@ -3,9 +3,9 @@ package lemmadigital import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/lemmadigital/params_test.go b/adapters/lemmadigital/params_test.go index 57bc7d83e79..4ba61319b33 100644 --- a/adapters/lemmadigital/params_test.go +++ b/adapters/lemmadigital/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // Tests for static/bidder-params/lemmadigital.json diff --git a/adapters/liftoff/liftoff.go b/adapters/liftoff/liftoff.go index b649da6f631..538e6aa1cda 100644 --- a/adapters/liftoff/liftoff.go +++ b/adapters/liftoff/liftoff.go @@ -8,9 +8,9 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const SupportedCurrency = "USD" diff --git a/adapters/liftoff/liftoff_test.go b/adapters/liftoff/liftoff_test.go index 0cb717dcc5a..4003bd21171 100644 --- a/adapters/liftoff/liftoff_test.go +++ b/adapters/liftoff/liftoff_test.go @@ -3,9 +3,9 @@ package liftoff import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/liftoff/param_test.go b/adapters/liftoff/param_test.go index d7cd5d73c09..a5e5a61fb9a 100644 --- a/adapters/liftoff/param_test.go +++ b/adapters/liftoff/param_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/limelightDigital/limelightDigital.go b/adapters/limelightDigital/limelightDigital.go index 86d8df94233..d9920c72383 100644 --- a/adapters/limelightDigital/limelightDigital.go +++ b/adapters/limelightDigital/limelightDigital.go @@ -10,11 +10,11 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/limelightDigital/limelightDigital_test.go b/adapters/limelightDigital/limelightDigital_test.go index 0c4105b59c9..beb4222f5c8 100644 --- a/adapters/limelightDigital/limelightDigital_test.go +++ b/adapters/limelightDigital/limelightDigital_test.go @@ -1,12 +1,13 @@ package limelightDigital import ( - "github.com/stretchr/testify/assert" "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/stretchr/testify/assert" + + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/limelightDigital/params_test.go b/adapters/limelightDigital/params_test.go index 4ccef77c338..9a61e9ba7c9 100644 --- a/adapters/limelightDigital/params_test.go +++ b/adapters/limelightDigital/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/lm_kiviads/lmkiviads.go b/adapters/lm_kiviads/lmkiviads.go index c121be3b24b..03c17e6439c 100644 --- a/adapters/lm_kiviads/lmkiviads.go +++ b/adapters/lm_kiviads/lmkiviads.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type bidType struct { diff --git a/adapters/lm_kiviads/lmkiviads_test.go b/adapters/lm_kiviads/lmkiviads_test.go index dfc8a5db0c4..01bf47ef8a7 100644 --- a/adapters/lm_kiviads/lmkiviads_test.go +++ b/adapters/lm_kiviads/lmkiviads_test.go @@ -3,9 +3,9 @@ package lmkiviads import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/lm_kiviads/params_test.go b/adapters/lm_kiviads/params_test.go index f40ad516684..1f3361b2581 100644 --- a/adapters/lm_kiviads/params_test.go +++ b/adapters/lm_kiviads/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/lockerdome/lockerdome.go b/adapters/lockerdome/lockerdome.go index 7aa46080c73..c52a51a1003 100644 --- a/adapters/lockerdome/lockerdome.go +++ b/adapters/lockerdome/lockerdome.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const unexpectedStatusCodeMessage = "Unexpected status code: %d. Run with request.debug = 1 for more info" diff --git a/adapters/lockerdome/lockerdome_test.go b/adapters/lockerdome/lockerdome_test.go index 1f807044b27..892fce2183a 100644 --- a/adapters/lockerdome/lockerdome_test.go +++ b/adapters/lockerdome/lockerdome_test.go @@ -3,9 +3,9 @@ package lockerdome import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/lockerdome/params_test.go b/adapters/lockerdome/params_test.go index c2c9185e374..9b90ec0b888 100644 --- a/adapters/lockerdome/params_test.go +++ b/adapters/lockerdome/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file tests static/bidder-params/lockerdome.json diff --git a/adapters/logan/logan.go b/adapters/logan/logan.go index db0888f8905..e5e76bca75b 100644 --- a/adapters/logan/logan.go +++ b/adapters/logan/logan.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/logan/logan_test.go b/adapters/logan/logan_test.go index da3a8741cff..219fbb50fe0 100644 --- a/adapters/logan/logan_test.go +++ b/adapters/logan/logan_test.go @@ -3,9 +3,9 @@ package logan import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/logan/params_test.go b/adapters/logan/params_test.go index 48da1912e61..55633b47c36 100644 --- a/adapters/logan/params_test.go +++ b/adapters/logan/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/logicad/logicad.go b/adapters/logicad/logicad.go index ffbb783bafb..2bd60077ae0 100644 --- a/adapters/logicad/logicad.go +++ b/adapters/logicad/logicad.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type LogicadAdapter struct { diff --git a/adapters/logicad/logicad_test.go b/adapters/logicad/logicad_test.go index 98295cc4a28..551bd133a9c 100644 --- a/adapters/logicad/logicad_test.go +++ b/adapters/logicad/logicad_test.go @@ -3,9 +3,9 @@ package logicad import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/logicad/params_test.go b/adapters/logicad/params_test.go index eb34452811b..c45297d15c2 100644 --- a/adapters/logicad/params_test.go +++ b/adapters/logicad/params_test.go @@ -2,8 +2,9 @@ package logicad import ( "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/lunamedia/lunamedia.go b/adapters/lunamedia/lunamedia.go index 24717e6ba52..99a54deb82f 100644 --- a/adapters/lunamedia/lunamedia.go +++ b/adapters/lunamedia/lunamedia.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type LunaMediaAdapter struct { diff --git a/adapters/lunamedia/lunamedia_test.go b/adapters/lunamedia/lunamedia_test.go index 961cd545303..c950ce4d25f 100644 --- a/adapters/lunamedia/lunamedia_test.go +++ b/adapters/lunamedia/lunamedia_test.go @@ -3,9 +3,9 @@ package lunamedia import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/lunamedia/params_test.go b/adapters/lunamedia/params_test.go index b4faeea1f77..12ecc65f420 100644 --- a/adapters/lunamedia/params_test.go +++ b/adapters/lunamedia/params_test.go @@ -2,8 +2,9 @@ package lunamedia import ( "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/mabidder/mabidder.go b/adapters/mabidder/mabidder.go index 184f068b333..9f7323c005d 100644 --- a/adapters/mabidder/mabidder.go +++ b/adapters/mabidder/mabidder.go @@ -4,9 +4,9 @@ import ( "encoding/json" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type serverResponse struct { diff --git a/adapters/mabidder/mabidder_test.go b/adapters/mabidder/mabidder_test.go index 89cfd31633e..31c28788ad2 100644 --- a/adapters/mabidder/mabidder_test.go +++ b/adapters/mabidder/mabidder_test.go @@ -3,9 +3,9 @@ package mabidder import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/mabidder/params_test.go b/adapters/mabidder/params_test.go index b0f3762d843..878e278438d 100644 --- a/adapters/mabidder/params_test.go +++ b/adapters/mabidder/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/madvertise/madvertise.go b/adapters/madvertise/madvertise.go index 32b84c6e65a..41097f62ab6 100644 --- a/adapters/madvertise/madvertise.go +++ b/adapters/madvertise/madvertise.go @@ -8,11 +8,11 @@ import ( "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/madvertise/madvertise_test.go b/adapters/madvertise/madvertise_test.go index 1d48b6dab3c..3d412b1e154 100644 --- a/adapters/madvertise/madvertise_test.go +++ b/adapters/madvertise/madvertise_test.go @@ -3,9 +3,9 @@ package madvertise import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/madvertise/params_test.go b/adapters/madvertise/params_test.go index 4b73d57d43e..55454399155 100644 --- a/adapters/madvertise/params_test.go +++ b/adapters/madvertise/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/Madvertise.json diff --git a/adapters/marsmedia/marsmedia.go b/adapters/marsmedia/marsmedia.go index 6bba910aee0..c75b4f7ad6b 100644 --- a/adapters/marsmedia/marsmedia.go +++ b/adapters/marsmedia/marsmedia.go @@ -7,10 +7,10 @@ import ( "strconv" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type MarsmediaAdapter struct { diff --git a/adapters/marsmedia/marsmedia_test.go b/adapters/marsmedia/marsmedia_test.go index 8fe01a72f73..6c75ef76c37 100644 --- a/adapters/marsmedia/marsmedia_test.go +++ b/adapters/marsmedia/marsmedia_test.go @@ -3,9 +3,9 @@ package marsmedia import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/marsmedia/params_test.go b/adapters/marsmedia/params_test.go index f78ad1c3dc4..ee79015b05c 100644 --- a/adapters/marsmedia/params_test.go +++ b/adapters/marsmedia/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/marsmedia.json diff --git a/adapters/medianet/medianet.go b/adapters/medianet/medianet.go index a5bf8e60df4..f84705aaa28 100644 --- a/adapters/medianet/medianet.go +++ b/adapters/medianet/medianet.go @@ -7,10 +7,10 @@ import ( "net/url" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/medianet/medianet_test.go b/adapters/medianet/medianet_test.go index 6403b3f2eb0..097e8e48727 100644 --- a/adapters/medianet/medianet_test.go +++ b/adapters/medianet/medianet_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/medianet/params_test.go b/adapters/medianet/params_test.go index a1e5e834ba6..7c999a66428 100644 --- a/adapters/medianet/params_test.go +++ b/adapters/medianet/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/medianet.json diff --git a/adapters/mgid/mgid.go b/adapters/mgid/mgid.go index 99d1946d3f1..712c6cd8928 100644 --- a/adapters/mgid/mgid.go +++ b/adapters/mgid/mgid.go @@ -7,10 +7,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type MgidAdapter struct { diff --git a/adapters/mgid/mgid_test.go b/adapters/mgid/mgid_test.go index fba3d8b09c3..21311f5477d 100644 --- a/adapters/mgid/mgid_test.go +++ b/adapters/mgid/mgid_test.go @@ -3,9 +3,9 @@ package mgid import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/mgidX/mgidX.go b/adapters/mgidX/mgidX.go index 29d2df4617c..084fdaebca9 100644 --- a/adapters/mgidX/mgidX.go +++ b/adapters/mgidX/mgidX.go @@ -7,9 +7,9 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/mgidX/mgidX_test.go b/adapters/mgidX/mgidX_test.go index 5a71750788a..7ff4eb93627 100644 --- a/adapters/mgidX/mgidX_test.go +++ b/adapters/mgidX/mgidX_test.go @@ -3,9 +3,9 @@ package mgidX import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/mgidX/params_test.go b/adapters/mgidX/params_test.go index 85779ec6e8c..b3d80207811 100644 --- a/adapters/mgidX/params_test.go +++ b/adapters/mgidX/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/mobfoxpb/mobfoxpb.go b/adapters/mobfoxpb/mobfoxpb.go index 6684d0c3fc2..24e13e26584 100644 --- a/adapters/mobfoxpb/mobfoxpb.go +++ b/adapters/mobfoxpb/mobfoxpb.go @@ -8,10 +8,10 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const ( diff --git a/adapters/mobfoxpb/mobfoxpb_test.go b/adapters/mobfoxpb/mobfoxpb_test.go index 401396adc8d..b3aa4ae4b2c 100644 --- a/adapters/mobfoxpb/mobfoxpb_test.go +++ b/adapters/mobfoxpb/mobfoxpb_test.go @@ -3,9 +3,9 @@ package mobfoxpb import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/mobfoxpb/params_test.go b/adapters/mobfoxpb/params_test.go index 799fdcfa61b..ea785163609 100644 --- a/adapters/mobfoxpb/params_test.go +++ b/adapters/mobfoxpb/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // TestValidParams makes sure that the mobfoxpb schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/mobilefuse/mobilefuse.go b/adapters/mobilefuse/mobilefuse.go index c13dbe8a6ae..24461ade471 100644 --- a/adapters/mobilefuse/mobilefuse.go +++ b/adapters/mobilefuse/mobilefuse.go @@ -8,11 +8,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type MobileFuseAdapter struct { diff --git a/adapters/mobilefuse/mobilefuse_test.go b/adapters/mobilefuse/mobilefuse_test.go index 09d46faff66..e1a3a018bb9 100644 --- a/adapters/mobilefuse/mobilefuse_test.go +++ b/adapters/mobilefuse/mobilefuse_test.go @@ -3,9 +3,9 @@ package mobilefuse import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/mobilefuse/params_test.go b/adapters/mobilefuse/params_test.go index dbfd8894e70..8599af5ece0 100644 --- a/adapters/mobilefuse/params_test.go +++ b/adapters/mobilefuse/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(test *testing.T) { diff --git a/adapters/motorik/motorik.go b/adapters/motorik/motorik.go index c804c0951fc..95bb4837c9a 100644 --- a/adapters/motorik/motorik.go +++ b/adapters/motorik/motorik.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/motorik/motorik_test.go b/adapters/motorik/motorik_test.go index 1a14fedac7b..5bdd102ddd3 100644 --- a/adapters/motorik/motorik_test.go +++ b/adapters/motorik/motorik_test.go @@ -3,9 +3,9 @@ package motorik import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/motorik/params_test.go b/adapters/motorik/params_test.go index 9ee05b58e07..2cfdf0f965b 100644 --- a/adapters/motorik/params_test.go +++ b/adapters/motorik/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/nextmillennium/nextmillennium.go b/adapters/nextmillennium/nextmillennium.go index f24bb6f7df8..5d10cac2d9e 100644 --- a/adapters/nextmillennium/nextmillennium.go +++ b/adapters/nextmillennium/nextmillennium.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/nextmillennium/nextmillennium_test.go b/adapters/nextmillennium/nextmillennium_test.go index bd75596691f..ec813ba2412 100644 --- a/adapters/nextmillennium/nextmillennium_test.go +++ b/adapters/nextmillennium/nextmillennium_test.go @@ -3,9 +3,9 @@ package nextmillennium import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/nextmillennium/params_test.go b/adapters/nextmillennium/params_test.go index 50a9c377f70..d8ae93d2c5a 100644 --- a/adapters/nextmillennium/params_test.go +++ b/adapters/nextmillennium/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/nobid/nobid.go b/adapters/nobid/nobid.go index 6ea76e1283e..63d20d87fc0 100644 --- a/adapters/nobid/nobid.go +++ b/adapters/nobid/nobid.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // NoBidAdapter - NoBid Adapter definition diff --git a/adapters/nobid/nobid_test.go b/adapters/nobid/nobid_test.go index a8775b74d18..8b48a303053 100644 --- a/adapters/nobid/nobid_test.go +++ b/adapters/nobid/nobid_test.go @@ -3,9 +3,9 @@ package nobid import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/nobid/params_test.go b/adapters/nobid/params_test.go index 75d69943d35..395230df797 100644 --- a/adapters/nobid/params_test.go +++ b/adapters/nobid/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/onetag/onetag.go b/adapters/onetag/onetag.go index 6e642ef1979..9036de80ced 100644 --- a/adapters/onetag/onetag.go +++ b/adapters/onetag/onetag.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/onetag/onetag_test.go b/adapters/onetag/onetag_test.go index 5550f076a99..7a1e539ca29 100644 --- a/adapters/onetag/onetag_test.go +++ b/adapters/onetag/onetag_test.go @@ -3,9 +3,9 @@ package onetag import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/onetag/params_test.go b/adapters/onetag/params_test.go index 4c7326ac9f0..bfc7c6ac27a 100644 --- a/adapters/onetag/params_test.go +++ b/adapters/onetag/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/openweb/openweb.go b/adapters/openweb/openweb.go index 8ef4007f959..45fd2853aec 100644 --- a/adapters/openweb/openweb.go +++ b/adapters/openweb/openweb.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/openweb/openweb_test.go b/adapters/openweb/openweb_test.go index 6332c409623..a63dafd06c2 100644 --- a/adapters/openweb/openweb_test.go +++ b/adapters/openweb/openweb_test.go @@ -3,9 +3,9 @@ package openweb import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/openweb/params_test.go b/adapters/openweb/params_test.go index df614df715f..7a53124fa30 100644 --- a/adapters/openweb/params_test.go +++ b/adapters/openweb/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/openweb.json diff --git a/adapters/openx/openx.go b/adapters/openx/openx.go index bd5e5555a40..f86b7b143fb 100644 --- a/adapters/openx/openx.go +++ b/adapters/openx/openx.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const hbconfig = "hb_pbs_1.0.0" diff --git a/adapters/openx/openx_test.go b/adapters/openx/openx_test.go index c25bd02e52c..d998148da87 100644 --- a/adapters/openx/openx_test.go +++ b/adapters/openx/openx_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/openx/params_test.go b/adapters/openx/params_test.go index 94775b57cb0..4e081dba7e5 100644 --- a/adapters/openx/params_test.go +++ b/adapters/openx/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/openx.json diff --git a/adapters/operaads/operaads.go b/adapters/operaads/operaads.go index 4fad9fe0894..f6af4039fb6 100644 --- a/adapters/operaads/operaads.go +++ b/adapters/operaads/operaads.go @@ -8,11 +8,11 @@ import ( "strings" "text/template" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/prebid/openrtb/v19/openrtb2" ) diff --git a/adapters/operaads/operaads_test.go b/adapters/operaads/operaads_test.go index fca277fa937..4e51c8393aa 100644 --- a/adapters/operaads/operaads_test.go +++ b/adapters/operaads/operaads_test.go @@ -3,9 +3,9 @@ package operaads import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/operaads/params_test.go b/adapters/operaads/params_test.go index 57a60ce9c53..1da80aa8ce3 100644 --- a/adapters/operaads/params_test.go +++ b/adapters/operaads/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/operaads.json diff --git a/adapters/orbidder/orbidder.go b/adapters/orbidder/orbidder.go index b4f1a16c114..8f1c582afe7 100644 --- a/adapters/orbidder/orbidder.go +++ b/adapters/orbidder/orbidder.go @@ -8,10 +8,10 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type OrbidderAdapter struct { diff --git a/adapters/orbidder/orbidder_test.go b/adapters/orbidder/orbidder_test.go index 5a80514ccae..39919da06e0 100644 --- a/adapters/orbidder/orbidder_test.go +++ b/adapters/orbidder/orbidder_test.go @@ -8,10 +8,10 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" "github.com/stretchr/testify/mock" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/orbidder/params_test.go b/adapters/orbidder/params_test.go index 2e130f7a9bd..cd95e222aee 100644 --- a/adapters/orbidder/params_test.go +++ b/adapters/orbidder/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/orbidder.json diff --git a/adapters/outbrain/outbrain.go b/adapters/outbrain/outbrain.go index a7d727a57c6..1d07c082507 100644 --- a/adapters/outbrain/outbrain.go +++ b/adapters/outbrain/outbrain.go @@ -8,10 +8,10 @@ import ( "github.com/prebid/openrtb/v19/native1" nativeResponse "github.com/prebid/openrtb/v19/native1/response" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/outbrain/outbrain_test.go b/adapters/outbrain/outbrain_test.go index 9e667dae83a..4a42679f660 100644 --- a/adapters/outbrain/outbrain_test.go +++ b/adapters/outbrain/outbrain_test.go @@ -3,9 +3,9 @@ package outbrain import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/outbrain/params_test.go b/adapters/outbrain/params_test.go index a8d81d6234d..666724cd6eb 100644 --- a/adapters/outbrain/params_test.go +++ b/adapters/outbrain/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/ownadx/ownadx.go b/adapters/ownadx/ownadx.go index c19343ba47f..77baa63b4cd 100644 --- a/adapters/ownadx/ownadx.go +++ b/adapters/ownadx/ownadx.go @@ -3,14 +3,15 @@ package ownadx import ( "encoding/json" "fmt" - "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" "net/http" "text/template" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/ownadx/ownadx_test.go b/adapters/ownadx/ownadx_test.go index 9bd7ba70353..07dc928b9b0 100644 --- a/adapters/ownadx/ownadx_test.go +++ b/adapters/ownadx/ownadx_test.go @@ -1,11 +1,12 @@ package ownadx import ( - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/stretchr/testify/assert" "testing" + + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/stretchr/testify/assert" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/pangle/pangle.go b/adapters/pangle/pangle.go index fcdc0264935..7c18a840025 100644 --- a/adapters/pangle/pangle.go +++ b/adapters/pangle/pangle.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/pangle/pangle_test.go b/adapters/pangle/pangle_test.go index 3653a60c81c..243bbadc90a 100644 --- a/adapters/pangle/pangle_test.go +++ b/adapters/pangle/pangle_test.go @@ -3,9 +3,9 @@ package pangle import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/pangle/param_test.go b/adapters/pangle/param_test.go index 5e1d30b3c7b..e25b7d740c4 100644 --- a/adapters/pangle/param_test.go +++ b/adapters/pangle/param_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/pgamssp/params_test.go b/adapters/pgamssp/params_test.go index 3e603237535..d2f06cbcfa8 100644 --- a/adapters/pgamssp/params_test.go +++ b/adapters/pgamssp/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/pgamssp/pgamssp.go b/adapters/pgamssp/pgamssp.go index 378b8e5cbf6..3e315fedc95 100644 --- a/adapters/pgamssp/pgamssp.go +++ b/adapters/pgamssp/pgamssp.go @@ -6,9 +6,9 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/pgamssp/pgamssp_test.go b/adapters/pgamssp/pgamssp_test.go index 596b813c888..10e72f5d093 100644 --- a/adapters/pgamssp/pgamssp_test.go +++ b/adapters/pgamssp/pgamssp_test.go @@ -3,9 +3,9 @@ package pgamssp import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/pubmatic/params_test.go b/adapters/pubmatic/params_test.go index a5a7773f7af..d5d1d46842f 100644 --- a/adapters/pubmatic/params_test.go +++ b/adapters/pubmatic/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/pubmatic.json diff --git a/adapters/pubmatic/pubmatic.go b/adapters/pubmatic/pubmatic.go index bd406d68631..17f43ea0f0a 100644 --- a/adapters/pubmatic/pubmatic.go +++ b/adapters/pubmatic/pubmatic.go @@ -11,10 +11,10 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const MAX_IMPRESSIONS_PUBMATIC = 30 diff --git a/adapters/pubmatic/pubmatic_test.go b/adapters/pubmatic/pubmatic_test.go index 7553519f990..b40bf2d4fb2 100644 --- a/adapters/pubmatic/pubmatic_test.go +++ b/adapters/pubmatic/pubmatic_test.go @@ -8,10 +8,10 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/pubnative/pubnative.go b/adapters/pubnative/pubnative.go index 35265c8a4c3..da3cab34dae 100644 --- a/adapters/pubnative/pubnative.go +++ b/adapters/pubnative/pubnative.go @@ -8,10 +8,10 @@ import ( "strconv" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type PubnativeAdapter struct { diff --git a/adapters/pubnative/pubnative_test.go b/adapters/pubnative/pubnative_test.go index 338575a51b0..b1b1bf85e05 100644 --- a/adapters/pubnative/pubnative_test.go +++ b/adapters/pubnative/pubnative_test.go @@ -3,9 +3,9 @@ package pubnative import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/pulsepoint/params_test.go b/adapters/pulsepoint/params_test.go index ac2b314b96f..4b3c6c017db 100644 --- a/adapters/pulsepoint/params_test.go +++ b/adapters/pulsepoint/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/pulsepoint/pulsepoint.go b/adapters/pulsepoint/pulsepoint.go index 6c17a6c30f4..f65e010341e 100644 --- a/adapters/pulsepoint/pulsepoint.go +++ b/adapters/pulsepoint/pulsepoint.go @@ -6,10 +6,10 @@ import ( "net/http" "strconv" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/prebid/openrtb/v19/openrtb2" ) diff --git a/adapters/pulsepoint/pulsepoint_test.go b/adapters/pulsepoint/pulsepoint_test.go index d30f49cabcf..20f73c89ecb 100644 --- a/adapters/pulsepoint/pulsepoint_test.go +++ b/adapters/pulsepoint/pulsepoint_test.go @@ -3,9 +3,9 @@ package pulsepoint import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/pwbid/params_test.go b/adapters/pwbid/params_test.go index e16fd13c4dc..44d36379cca 100644 --- a/adapters/pwbid/params_test.go +++ b/adapters/pwbid/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/pwbid/pwbid.go b/adapters/pwbid/pwbid.go index 21b564ff124..2452c08a863 100644 --- a/adapters/pwbid/pwbid.go +++ b/adapters/pwbid/pwbid.go @@ -5,10 +5,10 @@ import ( "fmt" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/pwbid/pwbid_test.go b/adapters/pwbid/pwbid_test.go index 194e4bdea02..9abad59d97c 100644 --- a/adapters/pwbid/pwbid_test.go +++ b/adapters/pwbid/pwbid_test.go @@ -3,9 +3,9 @@ package pwbid import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/response.go b/adapters/response.go index 8b7d59bd2c0..747b6ddf9c0 100644 --- a/adapters/response.go +++ b/adapters/response.go @@ -4,7 +4,7 @@ import ( "fmt" "net/http" - "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/v2/errortypes" ) func CheckResponseStatusCodeForErrors(response *ResponseData) error { diff --git a/adapters/response_test.go b/adapters/response_test.go index 0651ff2646f..11ef1abcc5a 100644 --- a/adapters/response_test.go +++ b/adapters/response_test.go @@ -3,7 +3,7 @@ package adapters import ( "testing" - "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/v2/errortypes" "github.com/stretchr/testify/assert" ) diff --git a/adapters/revcontent/revcontent.go b/adapters/revcontent/revcontent.go index b825708a72b..b53f8962d4d 100644 --- a/adapters/revcontent/revcontent.go +++ b/adapters/revcontent/revcontent.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/revcontent/revcontent_test.go b/adapters/revcontent/revcontent_test.go index c4816a09a0c..a39a78a81dd 100644 --- a/adapters/revcontent/revcontent_test.go +++ b/adapters/revcontent/revcontent_test.go @@ -3,9 +3,9 @@ package revcontent import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/richaudience/params_test.go b/adapters/richaudience/params_test.go index 038936f3cbf..4f7ede9bd55 100644 --- a/adapters/richaudience/params_test.go +++ b/adapters/richaudience/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/richaudience/richaudience.go b/adapters/richaudience/richaudience.go index 16fbe229acf..2d976cc7c7b 100644 --- a/adapters/richaudience/richaudience.go +++ b/adapters/richaudience/richaudience.go @@ -7,10 +7,10 @@ import ( "net/url" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/richaudience/richaudience_test.go b/adapters/richaudience/richaudience_test.go index 30d04775c44..ee1ece29a91 100644 --- a/adapters/richaudience/richaudience_test.go +++ b/adapters/richaudience/richaudience_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/rise/rise.go b/adapters/rise/rise.go index e18b7c93852..56fdc4a8fff 100644 --- a/adapters/rise/rise.go +++ b/adapters/rise/rise.go @@ -9,9 +9,9 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // adapter is a Rise implementation of the adapters.Bidder interface. diff --git a/adapters/rise/rise_test.go b/adapters/rise/rise_test.go index 1ba3f8a865d..79d34bde64f 100644 --- a/adapters/rise/rise_test.go +++ b/adapters/rise/rise_test.go @@ -3,9 +3,9 @@ package rise import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const testsDir = "risetest" diff --git a/adapters/rtbhouse/rtbhouse.go b/adapters/rtbhouse/rtbhouse.go index dc67df9aa2b..089634cbd86 100644 --- a/adapters/rtbhouse/rtbhouse.go +++ b/adapters/rtbhouse/rtbhouse.go @@ -7,10 +7,10 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const ( diff --git a/adapters/rtbhouse/rtbhouse_test.go b/adapters/rtbhouse/rtbhouse_test.go index e367b921957..7bccfa36266 100644 --- a/adapters/rtbhouse/rtbhouse_test.go +++ b/adapters/rtbhouse/rtbhouse_test.go @@ -3,9 +3,9 @@ package rtbhouse import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const testsDir = "rtbhousetest" diff --git a/adapters/rubicon/rubicon.go b/adapters/rubicon/rubicon.go index 635f6e14b42..7d09224e8b4 100644 --- a/adapters/rubicon/rubicon.go +++ b/adapters/rubicon/rubicon.go @@ -8,11 +8,11 @@ import ( "strconv" "strings" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/maputil" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/maputil" "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/adcom1" diff --git a/adapters/rubicon/rubicon_test.go b/adapters/rubicon/rubicon_test.go index 893cceb8cf7..334a5e269c0 100644 --- a/adapters/rubicon/rubicon_test.go +++ b/adapters/rubicon/rubicon_test.go @@ -8,11 +8,11 @@ import ( "strconv" "testing" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/adcom1" diff --git a/adapters/sa_lunamedia/params_test.go b/adapters/sa_lunamedia/params_test.go index 070c97741b0..568ac83d9cf 100644 --- a/adapters/sa_lunamedia/params_test.go +++ b/adapters/sa_lunamedia/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/sa_lunamedia/salunamedia.go b/adapters/sa_lunamedia/salunamedia.go index 9c9c34a6bf3..0d7d253114b 100644 --- a/adapters/sa_lunamedia/salunamedia.go +++ b/adapters/sa_lunamedia/salunamedia.go @@ -7,10 +7,10 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/sa_lunamedia/salunamedia_test.go b/adapters/sa_lunamedia/salunamedia_test.go index 9aa15187ab1..4bcfb96f28e 100644 --- a/adapters/sa_lunamedia/salunamedia_test.go +++ b/adapters/sa_lunamedia/salunamedia_test.go @@ -3,9 +3,9 @@ package salunamedia import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/screencore/params_test.go b/adapters/screencore/params_test.go index faa2f854928..7220f9945cf 100644 --- a/adapters/screencore/params_test.go +++ b/adapters/screencore/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/screencore/screencore.go b/adapters/screencore/screencore.go index 668e8b5e131..d5c2899af20 100644 --- a/adapters/screencore/screencore.go +++ b/adapters/screencore/screencore.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/screencore/screencore_test.go b/adapters/screencore/screencore_test.go index 6ee7f3ad554..4dc22b3cd6a 100644 --- a/adapters/screencore/screencore_test.go +++ b/adapters/screencore/screencore_test.go @@ -3,9 +3,9 @@ package screencore import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/seedingAlliance/params_test.go b/adapters/seedingAlliance/params_test.go index cdf29aed9e7..03817cf2d8f 100644 --- a/adapters/seedingAlliance/params_test.go +++ b/adapters/seedingAlliance/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/seedingAlliance/seedingAlliance.go b/adapters/seedingAlliance/seedingAlliance.go index 683cb6db8b7..b470dc757a5 100644 --- a/adapters/seedingAlliance/seedingAlliance.go +++ b/adapters/seedingAlliance/seedingAlliance.go @@ -8,10 +8,10 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/seedingAlliance/seedingAlliance_test.go b/adapters/seedingAlliance/seedingAlliance_test.go index 6946ead03ca..9d061e5feb6 100644 --- a/adapters/seedingAlliance/seedingAlliance_test.go +++ b/adapters/seedingAlliance/seedingAlliance_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/sharethrough/params_test.go b/adapters/sharethrough/params_test.go index 4edae1246d9..3c2d80dfa8b 100644 --- a/adapters/sharethrough/params_test.go +++ b/adapters/sharethrough/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/sharethrough/sharethrough.go b/adapters/sharethrough/sharethrough.go index 009ce0aa1d5..7287ca6b86e 100644 --- a/adapters/sharethrough/sharethrough.go +++ b/adapters/sharethrough/sharethrough.go @@ -7,11 +7,11 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/version" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/version" ) var adapterVersion = "10.0" diff --git a/adapters/sharethrough/sharethrough_test.go b/adapters/sharethrough/sharethrough_test.go index 4aab8fc56cc..2983487ac40 100644 --- a/adapters/sharethrough/sharethrough_test.go +++ b/adapters/sharethrough/sharethrough_test.go @@ -3,9 +3,9 @@ package sharethrough import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/silvermob/params_test.go b/adapters/silvermob/params_test.go index 13009f6a08b..d69171ed78d 100644 --- a/adapters/silvermob/params_test.go +++ b/adapters/silvermob/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // TestValidParams makes sure that the silvermob schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/silvermob/silvermob.go b/adapters/silvermob/silvermob.go index d4a1b55b45f..eaa45cb4be0 100644 --- a/adapters/silvermob/silvermob.go +++ b/adapters/silvermob/silvermob.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type SilverMobAdapter struct { diff --git a/adapters/silvermob/silvermob_test.go b/adapters/silvermob/silvermob_test.go index 5b7d60e2ead..ce08651ff59 100644 --- a/adapters/silvermob/silvermob_test.go +++ b/adapters/silvermob/silvermob_test.go @@ -3,9 +3,9 @@ package silvermob import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/silverpush/params_test.go b/adapters/silverpush/params_test.go index 8003b49ac3d..2a20aa2ff71 100644 --- a/adapters/silverpush/params_test.go +++ b/adapters/silverpush/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file intends to test static/bidder-params/silverpush.json diff --git a/adapters/silverpush/silverpush.go b/adapters/silverpush/silverpush.go index b5726cb28b7..805ef96657a 100644 --- a/adapters/silverpush/silverpush.go +++ b/adapters/silverpush/silverpush.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const ( diff --git a/adapters/silverpush/silverpush_test.go b/adapters/silverpush/silverpush_test.go index 87aa2867061..630539c0697 100644 --- a/adapters/silverpush/silverpush_test.go +++ b/adapters/silverpush/silverpush_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/smaato/image.go b/adapters/smaato/image.go index a4dad157bd1..8e601187ccd 100644 --- a/adapters/smaato/image.go +++ b/adapters/smaato/image.go @@ -3,9 +3,10 @@ package smaato import ( "encoding/json" "fmt" - "github.com/prebid/prebid-server/errortypes" "net/url" "strings" + + "github.com/prebid/prebid-server/v2/errortypes" ) type imageAd struct { diff --git a/adapters/smaato/native.go b/adapters/smaato/native.go index d0d40d35c57..b18a5fc4490 100644 --- a/adapters/smaato/native.go +++ b/adapters/smaato/native.go @@ -3,7 +3,8 @@ package smaato import ( "encoding/json" "fmt" - "github.com/prebid/prebid-server/errortypes" + + "github.com/prebid/prebid-server/v2/errortypes" ) type nativeAd struct { diff --git a/adapters/smaato/params_test.go b/adapters/smaato/params_test.go index 2e29550a394..d1c334acbfa 100644 --- a/adapters/smaato/params_test.go +++ b/adapters/smaato/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file intends to test static/bidder-params/smaato.json diff --git a/adapters/smaato/richmedia.go b/adapters/smaato/richmedia.go index a8865361d38..09e1f2bf3d6 100644 --- a/adapters/smaato/richmedia.go +++ b/adapters/smaato/richmedia.go @@ -3,9 +3,10 @@ package smaato import ( "encoding/json" "fmt" - "github.com/prebid/prebid-server/errortypes" "net/url" "strings" + + "github.com/prebid/prebid-server/v2/errortypes" ) type richMediaAd struct { diff --git a/adapters/smaato/smaato.go b/adapters/smaato/smaato.go index e0892ef50fb..ffdeca06d7a 100644 --- a/adapters/smaato/smaato.go +++ b/adapters/smaato/smaato.go @@ -9,12 +9,12 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/timeutil" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/timeutil" ) const clientVersion = "prebid_server_0.6" diff --git a/adapters/smaato/smaato_test.go b/adapters/smaato/smaato_test.go index a9caf86fe65..0d7d39027ea 100644 --- a/adapters/smaato/smaato_test.go +++ b/adapters/smaato/smaato_test.go @@ -9,10 +9,10 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/smartadserver/params_test.go b/adapters/smartadserver/params_test.go index ec4a7f7ec6c..fcd07278be6 100644 --- a/adapters/smartadserver/params_test.go +++ b/adapters/smartadserver/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/smartadserver.json diff --git a/adapters/smartadserver/smartadserver.go b/adapters/smartadserver/smartadserver.go index ecc26f9a1cc..ce14533f78b 100644 --- a/adapters/smartadserver/smartadserver.go +++ b/adapters/smartadserver/smartadserver.go @@ -9,10 +9,10 @@ import ( "strconv" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type SmartAdserverAdapter struct { diff --git a/adapters/smartadserver/smartadserver_test.go b/adapters/smartadserver/smartadserver_test.go index f0a4ae8b48c..be5c13d54e2 100644 --- a/adapters/smartadserver/smartadserver_test.go +++ b/adapters/smartadserver/smartadserver_test.go @@ -3,9 +3,9 @@ package smartadserver import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/smarthub/params_test.go b/adapters/smarthub/params_test.go index 7797d4a82c9..3d9a6c351bc 100644 --- a/adapters/smarthub/params_test.go +++ b/adapters/smarthub/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/smarthub/smarthub.go b/adapters/smarthub/smarthub.go index 018f51aabc7..877987dd2e0 100644 --- a/adapters/smarthub/smarthub.go +++ b/adapters/smarthub/smarthub.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const ( diff --git a/adapters/smarthub/smarthub_test.go b/adapters/smarthub/smarthub_test.go index 837d219c9fd..d231f77703a 100644 --- a/adapters/smarthub/smarthub_test.go +++ b/adapters/smarthub/smarthub_test.go @@ -3,9 +3,9 @@ package smarthub import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/smartrtb/smartrtb.go b/adapters/smartrtb/smartrtb.go index ffc9854670c..875d9fc2aac 100644 --- a/adapters/smartrtb/smartrtb.go +++ b/adapters/smartrtb/smartrtb.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // Base adapter structure. diff --git a/adapters/smartrtb/smartrtb_test.go b/adapters/smartrtb/smartrtb_test.go index b80955e6401..c0e83d3b826 100644 --- a/adapters/smartrtb/smartrtb_test.go +++ b/adapters/smartrtb/smartrtb_test.go @@ -3,9 +3,9 @@ package smartrtb import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/smartx/params_test.go b/adapters/smartx/params_test.go index fd28f4ead9b..81ee269a5ef 100644 --- a/adapters/smartx/params_test.go +++ b/adapters/smartx/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/smartx/smartx.go b/adapters/smartx/smartx.go index 6fbc94968ca..7b928ec198c 100644 --- a/adapters/smartx/smartx.go +++ b/adapters/smartx/smartx.go @@ -7,9 +7,9 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/smartx/smartx_test.go b/adapters/smartx/smartx_test.go index ba6f6ba7762..503a547d2fc 100644 --- a/adapters/smartx/smartx_test.go +++ b/adapters/smartx/smartx_test.go @@ -3,9 +3,9 @@ package smartx import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const testsDir = "smartxtest" diff --git a/adapters/smartyads/params_test.go b/adapters/smartyads/params_test.go index 3aa5c0e837d..0e1b7186397 100644 --- a/adapters/smartyads/params_test.go +++ b/adapters/smartyads/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/smartyads/smartyads.go b/adapters/smartyads/smartyads.go index c4455a62ccf..ce50e926444 100644 --- a/adapters/smartyads/smartyads.go +++ b/adapters/smartyads/smartyads.go @@ -8,11 +8,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type SmartyAdsAdapter struct { diff --git a/adapters/smartyads/smartyads_test.go b/adapters/smartyads/smartyads_test.go index b7edf2cadd2..6a697c1d5f4 100644 --- a/adapters/smartyads/smartyads_test.go +++ b/adapters/smartyads/smartyads_test.go @@ -3,9 +3,9 @@ package smartyads import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/smilewanted/params_test.go b/adapters/smilewanted/params_test.go index 3217cafabab..ac055542417 100644 --- a/adapters/smilewanted/params_test.go +++ b/adapters/smilewanted/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/smilewanted.json diff --git a/adapters/smilewanted/smilewanted.go b/adapters/smilewanted/smilewanted.go index 34ffdf20711..93278c2c25e 100644 --- a/adapters/smilewanted/smilewanted.go +++ b/adapters/smilewanted/smilewanted.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/smilewanted/smilewanted_test.go b/adapters/smilewanted/smilewanted_test.go index 73fe15387c6..3df23f42911 100644 --- a/adapters/smilewanted/smilewanted_test.go +++ b/adapters/smilewanted/smilewanted_test.go @@ -3,9 +3,9 @@ package smilewanted import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/sonobi/params_test.go b/adapters/sonobi/params_test.go index 46c31015dae..c84a99edfdf 100644 --- a/adapters/sonobi/params_test.go +++ b/adapters/sonobi/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/sonobi.json diff --git a/adapters/sonobi/sonobi.go b/adapters/sonobi/sonobi.go index 2b2a04c27da..f85e6959464 100644 --- a/adapters/sonobi/sonobi.go +++ b/adapters/sonobi/sonobi.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // SonobiAdapter - Sonobi SonobiAdapter definition diff --git a/adapters/sonobi/sonobi_test.go b/adapters/sonobi/sonobi_test.go index 8e9790bd6f0..3123781323d 100644 --- a/adapters/sonobi/sonobi_test.go +++ b/adapters/sonobi/sonobi_test.go @@ -3,9 +3,9 @@ package sonobi import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/sovrn/sovrn.go b/adapters/sovrn/sovrn.go index 15b07800b78..849e9c0b5d0 100644 --- a/adapters/sovrn/sovrn.go +++ b/adapters/sovrn/sovrn.go @@ -8,10 +8,10 @@ import ( "strconv" "strings" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/prebid/openrtb/v19/openrtb2" ) diff --git a/adapters/sovrn/sovrn_test.go b/adapters/sovrn/sovrn_test.go index 4a382d9b58e..1e041933e6c 100644 --- a/adapters/sovrn/sovrn_test.go +++ b/adapters/sovrn/sovrn_test.go @@ -3,9 +3,9 @@ package sovrn import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/sspBC/sspbc.go b/adapters/sspBC/sspbc.go index 6b601c120e0..f1a91322999 100644 --- a/adapters/sspBC/sspbc.go +++ b/adapters/sspBC/sspbc.go @@ -11,10 +11,10 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const ( diff --git a/adapters/sspBC/sspbc_test.go b/adapters/sspBC/sspbc_test.go index 47a8ae5d183..3c1f931bfb3 100644 --- a/adapters/sspBC/sspbc_test.go +++ b/adapters/sspBC/sspbc_test.go @@ -3,9 +3,9 @@ package sspBC import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/stroeerCore/params_test.go b/adapters/stroeerCore/params_test.go index 92586189b6f..ac8075c2251 100644 --- a/adapters/stroeerCore/params_test.go +++ b/adapters/stroeerCore/params_test.go @@ -2,8 +2,9 @@ package stroeerCore import ( "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/stroeerCore/stroeercore.go b/adapters/stroeerCore/stroeercore.go index 08ba83a9544..5f0194061a8 100644 --- a/adapters/stroeerCore/stroeercore.go +++ b/adapters/stroeerCore/stroeercore.go @@ -7,10 +7,10 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/stroeerCore/stroeercore_test.go b/adapters/stroeerCore/stroeercore_test.go index fc7a680add0..153f3137c07 100644 --- a/adapters/stroeerCore/stroeercore_test.go +++ b/adapters/stroeerCore/stroeercore_test.go @@ -3,9 +3,9 @@ package stroeerCore import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/suntContent/params_test.go b/adapters/suntContent/params_test.go index 653ed948d46..a0da79df48a 100644 --- a/adapters/suntContent/params_test.go +++ b/adapters/suntContent/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/suntContent/suntContent.go b/adapters/suntContent/suntContent.go index f5440737bd9..d9dd590e0aa 100644 --- a/adapters/suntContent/suntContent.go +++ b/adapters/suntContent/suntContent.go @@ -8,10 +8,10 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/suntContent/suntContent_test.go b/adapters/suntContent/suntContent_test.go index 52be77efb60..f356f85a5eb 100644 --- a/adapters/suntContent/suntContent_test.go +++ b/adapters/suntContent/suntContent_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/taboola/params_test.go b/adapters/taboola/params_test.go index 51a9833cdcb..adcaa0334f7 100644 --- a/adapters/taboola/params_test.go +++ b/adapters/taboola/params_test.go @@ -2,8 +2,9 @@ package taboola import ( "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/taboola/taboola.go b/adapters/taboola/taboola.go index 087f661104f..8f4e6220143 100644 --- a/adapters/taboola/taboola.go +++ b/adapters/taboola/taboola.go @@ -11,11 +11,11 @@ import ( "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/taboola/taboola_test.go b/adapters/taboola/taboola_test.go index 320d08da22f..bd674440150 100644 --- a/adapters/taboola/taboola_test.go +++ b/adapters/taboola/taboola_test.go @@ -1,14 +1,12 @@ package taboola import ( - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/stretchr/testify/assert" "testing" -) -import ( - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/stretchr/testify/assert" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/tappx/params_test.go b/adapters/tappx/params_test.go index 8a248345994..ddfcbeb021f 100644 --- a/adapters/tappx/params_test.go +++ b/adapters/tappx/params_test.go @@ -2,8 +2,9 @@ package tappx import ( "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/tappx/tappx.go b/adapters/tappx/tappx.go index d66a10a2bbe..d05a59316ae 100644 --- a/adapters/tappx/tappx.go +++ b/adapters/tappx/tappx.go @@ -11,11 +11,11 @@ import ( "time" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const TAPPX_BIDDER_VERSION = "1.5" diff --git a/adapters/tappx/tappx_test.go b/adapters/tappx/tappx_test.go index c1b711426fb..b3c6f3fe625 100644 --- a/adapters/tappx/tappx_test.go +++ b/adapters/tappx/tappx_test.go @@ -4,9 +4,9 @@ import ( "regexp" "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/teads/teads.go b/adapters/teads/teads.go index 9c2bb57fc57..72ee97f5a6e 100644 --- a/adapters/teads/teads.go +++ b/adapters/teads/teads.go @@ -9,11 +9,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // Builder builds a new instance of the Teads adapter for the given bidder with the given config. diff --git a/adapters/teads/teads_test.go b/adapters/teads/teads_test.go index 791ce7aed6f..4f492b66b1e 100644 --- a/adapters/teads/teads_test.go +++ b/adapters/teads/teads_test.go @@ -1,11 +1,12 @@ package teads import ( - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/stretchr/testify/assert" "testing" + + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/stretchr/testify/assert" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/telaria/params_test.go b/adapters/telaria/params_test.go index efa3fba1be9..9e451ca091e 100644 --- a/adapters/telaria/params_test.go +++ b/adapters/telaria/params_test.go @@ -2,8 +2,9 @@ package telaria import ( "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/telaria/telaria.go b/adapters/telaria/telaria.go index bbe600178f4..a1ac5611e1f 100644 --- a/adapters/telaria/telaria.go +++ b/adapters/telaria/telaria.go @@ -7,10 +7,10 @@ import ( "strconv" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const Endpoint = "https://ads.tremorhub.com/ad/rtb/prebid" diff --git a/adapters/telaria/telaria_test.go b/adapters/telaria/telaria_test.go index f8008835ac3..3c7d1bea46e 100644 --- a/adapters/telaria/telaria_test.go +++ b/adapters/telaria/telaria_test.go @@ -3,9 +3,9 @@ package telaria import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/tpmn/params_test.go b/adapters/tpmn/params_test.go index 7bd7c478638..4715d910855 100644 --- a/adapters/tpmn/params_test.go +++ b/adapters/tpmn/params_test.go @@ -2,8 +2,9 @@ package tpmn import ( "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/tpmn/tpmn.go b/adapters/tpmn/tpmn.go index 7afe94e5f79..443b8837bac 100644 --- a/adapters/tpmn/tpmn.go +++ b/adapters/tpmn/tpmn.go @@ -7,9 +7,9 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // TpmnAdapter struct diff --git a/adapters/tpmn/tpmn_test.go b/adapters/tpmn/tpmn_test.go index 6fbd85936f1..7170dbb3d5f 100644 --- a/adapters/tpmn/tpmn_test.go +++ b/adapters/tpmn/tpmn_test.go @@ -3,9 +3,9 @@ package tpmn import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/trafficgate/params_test.go b/adapters/trafficgate/params_test.go index 4dc2c792bc9..adc11c08335 100644 --- a/adapters/trafficgate/params_test.go +++ b/adapters/trafficgate/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // TestValidParams makes sure that the trafficgate schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/trafficgate/trafficgate.go b/adapters/trafficgate/trafficgate.go index 3c9ebe9ba98..1462fe59bd5 100644 --- a/adapters/trafficgate/trafficgate.go +++ b/adapters/trafficgate/trafficgate.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/trafficgate/trafficgate_test.go b/adapters/trafficgate/trafficgate_test.go index 326c50523fe..473c9d5d5c3 100644 --- a/adapters/trafficgate/trafficgate_test.go +++ b/adapters/trafficgate/trafficgate_test.go @@ -3,9 +3,9 @@ package trafficgate import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/triplelift/triplelift.go b/adapters/triplelift/triplelift.go index 0e7fbe4a462..793647bccaa 100644 --- a/adapters/triplelift/triplelift.go +++ b/adapters/triplelift/triplelift.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type TripleliftAdapter struct { diff --git a/adapters/triplelift/triplelift_test.go b/adapters/triplelift/triplelift_test.go index add71b05788..c4468a93faa 100644 --- a/adapters/triplelift/triplelift_test.go +++ b/adapters/triplelift/triplelift_test.go @@ -3,9 +3,9 @@ package triplelift import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/triplelift_native/triplelift_native.go b/adapters/triplelift_native/triplelift_native.go index 9131c79a975..08aefb3b135 100644 --- a/adapters/triplelift_native/triplelift_native.go +++ b/adapters/triplelift_native/triplelift_native.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type TripleliftNativeAdapter struct { diff --git a/adapters/triplelift_native/triplelift_native_test.go b/adapters/triplelift_native/triplelift_native_test.go index 18e157a41cd..c1c82501b32 100644 --- a/adapters/triplelift_native/triplelift_native_test.go +++ b/adapters/triplelift_native/triplelift_native_test.go @@ -3,9 +3,9 @@ package triplelift_native import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/ucfunnel/params_test.go b/adapters/ucfunnel/params_test.go index b721925e72a..9bba397a084 100644 --- a/adapters/ucfunnel/params_test.go +++ b/adapters/ucfunnel/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/ucfunnel.json diff --git a/adapters/ucfunnel/ucfunnel.go b/adapters/ucfunnel/ucfunnel.go index a0d86a0fa29..cb4a6093c99 100644 --- a/adapters/ucfunnel/ucfunnel.go +++ b/adapters/ucfunnel/ucfunnel.go @@ -7,10 +7,10 @@ import ( "net/url" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type UcfunnelAdapter struct { diff --git a/adapters/ucfunnel/ucfunnel_test.go b/adapters/ucfunnel/ucfunnel_test.go index a906b9279e8..6e5000c3205 100644 --- a/adapters/ucfunnel/ucfunnel_test.go +++ b/adapters/ucfunnel/ucfunnel_test.go @@ -6,9 +6,9 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestMakeRequests(t *testing.T) { diff --git a/adapters/undertone/params_test.go b/adapters/undertone/params_test.go index b48d08188d5..3144f757078 100644 --- a/adapters/undertone/params_test.go +++ b/adapters/undertone/params_test.go @@ -2,8 +2,9 @@ package undertone import ( "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/undertone/undertone.go b/adapters/undertone/undertone.go index 7f8dde35abb..a5f428b12ca 100644 --- a/adapters/undertone/undertone.go +++ b/adapters/undertone/undertone.go @@ -8,10 +8,10 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const adapterId = 4 diff --git a/adapters/undertone/undertone_test.go b/adapters/undertone/undertone_test.go index d7e6d52339b..c08460e8627 100644 --- a/adapters/undertone/undertone_test.go +++ b/adapters/undertone/undertone_test.go @@ -1,10 +1,11 @@ package undertone import ( - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/unicorn/params_test.go b/adapters/unicorn/params_test.go index 9313183fbfa..fd76995d1c0 100644 --- a/adapters/unicorn/params_test.go +++ b/adapters/unicorn/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/unicorn/unicorn.go b/adapters/unicorn/unicorn.go index 5048d9d2394..6351ad059cf 100644 --- a/adapters/unicorn/unicorn.go +++ b/adapters/unicorn/unicorn.go @@ -8,10 +8,10 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/unicorn/unicorn_test.go b/adapters/unicorn/unicorn_test.go index 084be78498a..6c1e5aa73f2 100644 --- a/adapters/unicorn/unicorn_test.go +++ b/adapters/unicorn/unicorn_test.go @@ -3,9 +3,9 @@ package unicorn import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/unruly/params_test.go b/adapters/unruly/params_test.go index e9607358a59..f8feea872c8 100644 --- a/adapters/unruly/params_test.go +++ b/adapters/unruly/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/unruly/unruly.go b/adapters/unruly/unruly.go index 1f4bf6b0203..b96da9eb93e 100644 --- a/adapters/unruly/unruly.go +++ b/adapters/unruly/unruly.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/unruly/unruly_test.go b/adapters/unruly/unruly_test.go index b5d837abea5..8407ba15212 100644 --- a/adapters/unruly/unruly_test.go +++ b/adapters/unruly/unruly_test.go @@ -3,9 +3,9 @@ package unruly import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/videobyte/params_test.go b/adapters/videobyte/params_test.go index b638d4585c6..dbc815fd76d 100644 --- a/adapters/videobyte/params_test.go +++ b/adapters/videobyte/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/videobyte.json diff --git a/adapters/videobyte/videobyte.go b/adapters/videobyte/videobyte.go index 2dc6df84895..afbce1376f9 100644 --- a/adapters/videobyte/videobyte.go +++ b/adapters/videobyte/videobyte.go @@ -6,10 +6,10 @@ import ( "net/http" "net/url" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/prebid/openrtb/v19/openrtb2" ) diff --git a/adapters/videobyte/videobyte_test.go b/adapters/videobyte/videobyte_test.go index d4dda0606f8..9e566a20ef2 100644 --- a/adapters/videobyte/videobyte_test.go +++ b/adapters/videobyte/videobyte_test.go @@ -3,9 +3,9 @@ package videobyte import ( "testing" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/videoheroes/params_test.go b/adapters/videoheroes/params_test.go index d79f83245a4..66e1e6a2788 100644 --- a/adapters/videoheroes/params_test.go +++ b/adapters/videoheroes/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/videoheroes/videoheroes.go b/adapters/videoheroes/videoheroes.go index d4efcab2c90..0014c1613e4 100755 --- a/adapters/videoheroes/videoheroes.go +++ b/adapters/videoheroes/videoheroes.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/videoheroes/videoheroes_test.go b/adapters/videoheroes/videoheroes_test.go index ac60d56e175..7c0b2268f51 100644 --- a/adapters/videoheroes/videoheroes_test.go +++ b/adapters/videoheroes/videoheroes_test.go @@ -3,9 +3,9 @@ package videoheroes import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/vidoomy/params_test.go b/adapters/vidoomy/params_test.go index 63ffb462c19..40c17029f9e 100644 --- a/adapters/vidoomy/params_test.go +++ b/adapters/vidoomy/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/vidoomy.json diff --git a/adapters/vidoomy/vidoomy.go b/adapters/vidoomy/vidoomy.go index 7e7e9d64eb3..09e924e596c 100644 --- a/adapters/vidoomy/vidoomy.go +++ b/adapters/vidoomy/vidoomy.go @@ -7,10 +7,10 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/vidoomy/vidoomy_test.go b/adapters/vidoomy/vidoomy_test.go index 60cd2c9d967..7acc477ae1c 100644 --- a/adapters/vidoomy/vidoomy_test.go +++ b/adapters/vidoomy/vidoomy_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestVidoomyBidderEndpointConfig(t *testing.T) { diff --git a/adapters/visiblemeasures/params_test.go b/adapters/visiblemeasures/params_test.go index 7bcc1cf60cf..ed74ef1ad35 100644 --- a/adapters/visiblemeasures/params_test.go +++ b/adapters/visiblemeasures/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/visiblemeasures/visiblemeasures.go b/adapters/visiblemeasures/visiblemeasures.go index 3d6a96640e9..7b8cb9a9dd3 100644 --- a/adapters/visiblemeasures/visiblemeasures.go +++ b/adapters/visiblemeasures/visiblemeasures.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/visiblemeasures/visiblemeasures_test.go b/adapters/visiblemeasures/visiblemeasures_test.go index 8c1759c010e..8970ccb1e43 100644 --- a/adapters/visiblemeasures/visiblemeasures_test.go +++ b/adapters/visiblemeasures/visiblemeasures_test.go @@ -3,9 +3,9 @@ package visiblemeasures import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/visx/params_test.go b/adapters/visx/params_test.go index e53d2cda007..0646d221e27 100644 --- a/adapters/visx/params_test.go +++ b/adapters/visx/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/visx/visx.go b/adapters/visx/visx.go index 713c2693990..a7cc232c01a 100644 --- a/adapters/visx/visx.go +++ b/adapters/visx/visx.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type VisxAdapter struct { diff --git a/adapters/visx/visx_test.go b/adapters/visx/visx_test.go index 5fc58a1f83d..8cdccc2e653 100644 --- a/adapters/visx/visx_test.go +++ b/adapters/visx/visx_test.go @@ -3,9 +3,9 @@ package visx import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/vox/params_test.go b/adapters/vox/params_test.go index be148d3b32d..e23a57d9b30 100644 --- a/adapters/vox/params_test.go +++ b/adapters/vox/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/vox/vox.go b/adapters/vox/vox.go index 0b56fcbf9d7..740fe84e611 100644 --- a/adapters/vox/vox.go +++ b/adapters/vox/vox.go @@ -3,10 +3,11 @@ package vox import ( "encoding/json" "fmt" + "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/vox/vox_test.go b/adapters/vox/vox_test.go index 95d11a8ad79..dfb345b2e02 100644 --- a/adapters/vox/vox_test.go +++ b/adapters/vox/vox_test.go @@ -3,9 +3,9 @@ package vox import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/vrtcal/params_test.go b/adapters/vrtcal/params_test.go index d45d3b39013..0e30dd6fcc9 100644 --- a/adapters/vrtcal/params_test.go +++ b/adapters/vrtcal/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) //Vrtcal doesn't currently require any custom fields. This file is included for conformity only diff --git a/adapters/vrtcal/vrtcal.go b/adapters/vrtcal/vrtcal.go index ab47eddb441..01ef178b352 100644 --- a/adapters/vrtcal/vrtcal.go +++ b/adapters/vrtcal/vrtcal.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type VrtcalAdapter struct { diff --git a/adapters/vrtcal/vrtcal_test.go b/adapters/vrtcal/vrtcal_test.go index 31e6c78e2c1..a4ba917922f 100644 --- a/adapters/vrtcal/vrtcal_test.go +++ b/adapters/vrtcal/vrtcal_test.go @@ -3,9 +3,9 @@ package vrtcal import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/xeworks/params_test.go b/adapters/xeworks/params_test.go index 68d36096049..1c14b3a0989 100644 --- a/adapters/xeworks/params_test.go +++ b/adapters/xeworks/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/xeworks/xeworks.go b/adapters/xeworks/xeworks.go index 35e551b1034..e892fcfc932 100644 --- a/adapters/xeworks/xeworks.go +++ b/adapters/xeworks/xeworks.go @@ -7,11 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type bidType struct { diff --git a/adapters/xeworks/xeworks_test.go b/adapters/xeworks/xeworks_test.go index 4869a05a229..db7e26c9bae 100644 --- a/adapters/xeworks/xeworks_test.go +++ b/adapters/xeworks/xeworks_test.go @@ -3,9 +3,9 @@ package xeworks import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/yahooAds/params_test.go b/adapters/yahooAds/params_test.go index c0deaaa32c9..dbbc2c84adb 100644 --- a/adapters/yahooAds/params_test.go +++ b/adapters/yahooAds/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/yahooAds.json diff --git a/adapters/yahooAds/yahooAds.go b/adapters/yahooAds/yahooAds.go index 3597d0e359c..241f4eba506 100644 --- a/adapters/yahooAds/yahooAds.go +++ b/adapters/yahooAds/yahooAds.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/yahooAds/yahooAds_test.go b/adapters/yahooAds/yahooAds_test.go index 924eabd5ec1..ae9103d141e 100644 --- a/adapters/yahooAds/yahooAds_test.go +++ b/adapters/yahooAds/yahooAds_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestYahooAdsBidderEndpointConfig(t *testing.T) { diff --git a/adapters/yeahmobi/params_test.go b/adapters/yeahmobi/params_test.go index 997bf93a53f..805be75da30 100644 --- a/adapters/yeahmobi/params_test.go +++ b/adapters/yeahmobi/params_test.go @@ -2,8 +2,9 @@ package yeahmobi import ( "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/yeahmobi/yeahmobi.go b/adapters/yeahmobi/yeahmobi.go index ede25387ce2..35434d05473 100644 --- a/adapters/yeahmobi/yeahmobi.go +++ b/adapters/yeahmobi/yeahmobi.go @@ -8,11 +8,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/yeahmobi/yeahmobi_test.go b/adapters/yeahmobi/yeahmobi_test.go index 0b1c39ef214..c1c7be35105 100644 --- a/adapters/yeahmobi/yeahmobi_test.go +++ b/adapters/yeahmobi/yeahmobi_test.go @@ -3,9 +3,9 @@ package yeahmobi import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/yieldlab/params_test.go b/adapters/yieldlab/params_test.go index ed0d2863629..74a91ac3bf7 100644 --- a/adapters/yieldlab/params_test.go +++ b/adapters/yieldlab/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/yieldlab.json diff --git a/adapters/yieldlab/yieldlab.go b/adapters/yieldlab/yieldlab.go index 74ee6bd7220..c6aa7f27dac 100644 --- a/adapters/yieldlab/yieldlab.go +++ b/adapters/yieldlab/yieldlab.go @@ -12,10 +12,10 @@ import ( "golang.org/x/text/currency" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // YieldlabAdapter connects the Yieldlab API to prebid server diff --git a/adapters/yieldlab/yieldlab_test.go b/adapters/yieldlab/yieldlab_test.go index d3fc9f3eb1d..4c4f8f56330 100644 --- a/adapters/yieldlab/yieldlab_test.go +++ b/adapters/yieldlab/yieldlab_test.go @@ -8,9 +8,9 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const testURL = "https://ad.yieldlab.net/testing/" diff --git a/adapters/yieldmo/params_test.go b/adapters/yieldmo/params_test.go index d94c7ff035b..647c21abb90 100644 --- a/adapters/yieldmo/params_test.go +++ b/adapters/yieldmo/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // This file actually intends to test static/bidder-params/yieldmo.json diff --git a/adapters/yieldmo/yieldmo.go b/adapters/yieldmo/yieldmo.go index bf8410b294b..795d32b8846 100644 --- a/adapters/yieldmo/yieldmo.go +++ b/adapters/yieldmo/yieldmo.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type YieldmoAdapter struct { diff --git a/adapters/yieldmo/yieldmo_test.go b/adapters/yieldmo/yieldmo_test.go index 1d9426d0643..f89d4849a2c 100644 --- a/adapters/yieldmo/yieldmo_test.go +++ b/adapters/yieldmo/yieldmo_test.go @@ -3,9 +3,9 @@ package yieldmo import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/yieldone/params_test.go b/adapters/yieldone/params_test.go index 6048ea5d7dc..623928839ef 100644 --- a/adapters/yieldone/params_test.go +++ b/adapters/yieldone/params_test.go @@ -2,8 +2,9 @@ package yieldone import ( "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/yieldone/yieldone.go b/adapters/yieldone/yieldone.go index 2d5f1d81173..e852c5cb6ba 100644 --- a/adapters/yieldone/yieldone.go +++ b/adapters/yieldone/yieldone.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type YieldoneAdapter struct { diff --git a/adapters/yieldone/yieldone_test.go b/adapters/yieldone/yieldone_test.go index 12d634d463d..1847ef9bf06 100644 --- a/adapters/yieldone/yieldone_test.go +++ b/adapters/yieldone/yieldone_test.go @@ -3,9 +3,9 @@ package yieldone import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/zeroclickfraud/zeroclickfraud.go b/adapters/zeroclickfraud/zeroclickfraud.go index 235f678d7bb..6f477352652 100644 --- a/adapters/zeroclickfraud/zeroclickfraud.go +++ b/adapters/zeroclickfraud/zeroclickfraud.go @@ -8,11 +8,11 @@ import ( "text/template" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type ZeroClickFraudAdapter struct { diff --git a/adapters/zeroclickfraud/zeroclickfraud_test.go b/adapters/zeroclickfraud/zeroclickfraud_test.go index e07c43ff7a2..6e2a7e23b4c 100644 --- a/adapters/zeroclickfraud/zeroclickfraud_test.go +++ b/adapters/zeroclickfraud/zeroclickfraud_test.go @@ -3,9 +3,9 @@ package zeroclickfraud import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/zeta_global_ssp/zeta_global_ssp.go b/adapters/zeta_global_ssp/zeta_global_ssp.go index 7a5f3395724..dcfffc8b342 100644 --- a/adapters/zeta_global_ssp/zeta_global_ssp.go +++ b/adapters/zeta_global_ssp/zeta_global_ssp.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { diff --git a/adapters/zeta_global_ssp/zeta_global_ssp_test.go b/adapters/zeta_global_ssp/zeta_global_ssp_test.go index 3b7be288fa1..f5384cdec0f 100644 --- a/adapters/zeta_global_ssp/zeta_global_ssp_test.go +++ b/adapters/zeta_global_ssp/zeta_global_ssp_test.go @@ -3,9 +3,9 @@ package zeta_global_ssp import ( "testing" - "github.com/prebid/prebid-server/adapters/adapterstest" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adservertargeting/adservertargeting.go b/adservertargeting/adservertargeting.go index 94d64579e66..e79b521e1f5 100644 --- a/adservertargeting/adservertargeting.go +++ b/adservertargeting/adservertargeting.go @@ -7,7 +7,7 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type DataSource string diff --git a/adservertargeting/adservertargeting_test.go b/adservertargeting/adservertargeting_test.go index 0da3635d9b7..d0a90ce0813 100644 --- a/adservertargeting/adservertargeting_test.go +++ b/adservertargeting/adservertargeting_test.go @@ -7,8 +7,8 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/openrtb/v19/openrtb3" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/adservertargeting/reqcache.go b/adservertargeting/reqcache.go index b8b147af84e..f2a4636c2f8 100644 --- a/adservertargeting/reqcache.go +++ b/adservertargeting/reqcache.go @@ -5,7 +5,7 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) type requestCache struct { diff --git a/adservertargeting/requestlookup.go b/adservertargeting/requestlookup.go index debf19830db..d3284525b50 100644 --- a/adservertargeting/requestlookup.go +++ b/adservertargeting/requestlookup.go @@ -3,11 +3,12 @@ package adservertargeting import ( "encoding/json" "fmt" - "github.com/buger/jsonparser" - "github.com/pkg/errors" - "github.com/prebid/prebid-server/openrtb_ext" "net/url" "strings" + + "github.com/buger/jsonparser" + "github.com/pkg/errors" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func getAdServerTargeting(reqWrapper *openrtb_ext.RequestWrapper) ([]openrtb_ext.AdServerTarget, error) { diff --git a/adservertargeting/requestlookup_test.go b/adservertargeting/requestlookup_test.go index cd86364558e..1b54beb03e7 100644 --- a/adservertargeting/requestlookup_test.go +++ b/adservertargeting/requestlookup_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adservertargeting/respdataprocessor.go b/adservertargeting/respdataprocessor.go index 649f802f6e2..ab3ca070f89 100644 --- a/adservertargeting/respdataprocessor.go +++ b/adservertargeting/respdataprocessor.go @@ -7,8 +7,8 @@ import ( "github.com/pkg/errors" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" jsonpatch "gopkg.in/evanphx/json-patch.v4" ) diff --git a/adservertargeting/respdataprocessor_test.go b/adservertargeting/respdataprocessor_test.go index 1118458e0f6..95404cef733 100644 --- a/adservertargeting/respdataprocessor_test.go +++ b/adservertargeting/respdataprocessor_test.go @@ -8,7 +8,7 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/openrtb/v19/openrtb3" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adservertargeting/utils.go b/adservertargeting/utils.go index 8093a4b6974..136f7900e24 100644 --- a/adservertargeting/utils.go +++ b/adservertargeting/utils.go @@ -1,11 +1,12 @@ package adservertargeting import ( + "strings" + "github.com/buger/jsonparser" "github.com/pkg/errors" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" - "strings" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func splitAndGet(path string, data []byte, delimiter string) (string, error) { diff --git a/amp/parse.go b/amp/parse.go index 34f1a3cacb4..a42ef6fa399 100644 --- a/amp/parse.go +++ b/amp/parse.go @@ -10,10 +10,10 @@ import ( tcf2 "github.com/prebid/go-gdpr/vendorconsent/tcf2" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/privacy" - "github.com/prebid/prebid-server/privacy/ccpa" - "github.com/prebid/prebid-server/privacy/gdpr" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v2/privacy/ccpa" + "github.com/prebid/prebid-server/v2/privacy/gdpr" ) // Params defines the parameters of an AMP request. diff --git a/amp/parse_test.go b/amp/parse_test.go index 9f981fd30e0..38c7a05a615 100644 --- a/amp/parse_test.go +++ b/amp/parse_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/privacy" - "github.com/prebid/prebid-server/privacy/ccpa" - "github.com/prebid/prebid-server/privacy/gdpr" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v2/privacy/ccpa" + "github.com/prebid/prebid-server/v2/privacy/gdpr" "github.com/stretchr/testify/assert" ) diff --git a/analytics/build/build.go b/analytics/build/build.go index 6fb48705981..7fc577daedf 100644 --- a/analytics/build/build.go +++ b/analytics/build/build.go @@ -3,12 +3,12 @@ package build import ( "github.com/benbjohnson/clock" "github.com/golang/glog" - "github.com/prebid/prebid-server/analytics" - "github.com/prebid/prebid-server/analytics/clients" - "github.com/prebid/prebid-server/analytics/filesystem" - "github.com/prebid/prebid-server/analytics/pubstack" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/privacy" + "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v2/analytics/clients" + "github.com/prebid/prebid-server/v2/analytics/filesystem" + "github.com/prebid/prebid-server/v2/analytics/pubstack" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/privacy" ) // Modules that need to be logged to need to be initialized here diff --git a/analytics/build/build_test.go b/analytics/build/build_test.go index dbd129a7afd..efc0c862564 100644 --- a/analytics/build/build_test.go +++ b/analytics/build/build_test.go @@ -1,15 +1,15 @@ package build import ( - "github.com/prebid/prebid-server/analytics" "net/http" "os" "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/privacy" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/analytics/core.go b/analytics/core.go index 0279ae83868..122a3da8ad3 100644 --- a/analytics/core.go +++ b/analytics/core.go @@ -4,9 +4,9 @@ import ( "time" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/hooks/hookexecution" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/hooks/hookexecution" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // Module must be implemented by analytics modules to extract the required information and logging diff --git a/analytics/filesystem/file_module.go b/analytics/filesystem/file_module.go index 24b7be6b599..4f7886c1206 100644 --- a/analytics/filesystem/file_module.go +++ b/analytics/filesystem/file_module.go @@ -6,8 +6,8 @@ import ( "github.com/chasex/glog" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/analytics" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) type RequestType string diff --git a/analytics/filesystem/file_module_test.go b/analytics/filesystem/file_module_test.go index 9843a8ab108..f2f81bcdf77 100644 --- a/analytics/filesystem/file_module_test.go +++ b/analytics/filesystem/file_module_test.go @@ -6,8 +6,8 @@ import ( "strings" "testing" - "github.com/prebid/prebid-server/analytics" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v2/config" "github.com/prebid/openrtb/v19/openrtb2" ) diff --git a/analytics/filesystem/model.go b/analytics/filesystem/model.go index 9fc7a6e19a2..61987ed3b53 100644 --- a/analytics/filesystem/model.go +++ b/analytics/filesystem/model.go @@ -4,10 +4,10 @@ import ( "time" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/analytics" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/hooks/hookexecution" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/hooks/hookexecution" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type logAuction struct { diff --git a/analytics/pubstack/configupdate.go b/analytics/pubstack/configupdate.go index 622161a04f2..0ecaaef05c3 100644 --- a/analytics/pubstack/configupdate.go +++ b/analytics/pubstack/configupdate.go @@ -6,7 +6,7 @@ import ( "net/url" "time" - "github.com/prebid/prebid-server/util/task" + "github.com/prebid/prebid-server/v2/util/task" ) // ConfigUpdateTask publishes configurations until the stop channel is signaled. diff --git a/analytics/pubstack/helpers/json.go b/analytics/pubstack/helpers/json.go index f56a4c6194b..c516cb56ae8 100644 --- a/analytics/pubstack/helpers/json.go +++ b/analytics/pubstack/helpers/json.go @@ -4,8 +4,8 @@ import ( "fmt" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/analytics" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) func JsonifyAuctionObject(ao *analytics.AuctionObject, scope string) ([]byte, error) { diff --git a/analytics/pubstack/helpers/json_test.go b/analytics/pubstack/helpers/json_test.go index 07ead724929..7ec46e53f83 100644 --- a/analytics/pubstack/helpers/json_test.go +++ b/analytics/pubstack/helpers/json_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/analytics" + "github.com/prebid/prebid-server/v2/analytics" "github.com/stretchr/testify/assert" ) diff --git a/analytics/pubstack/helpers/model.go b/analytics/pubstack/helpers/model.go index 91b86d7fc86..1d6ede1c59b 100644 --- a/analytics/pubstack/helpers/model.go +++ b/analytics/pubstack/helpers/model.go @@ -4,10 +4,10 @@ import ( "time" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/analytics" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/hooks/hookexecution" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/hooks/hookexecution" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type logAuction struct { diff --git a/analytics/pubstack/pubstack_module.go b/analytics/pubstack/pubstack_module.go index f2d8726d356..535118c0000 100644 --- a/analytics/pubstack/pubstack_module.go +++ b/analytics/pubstack/pubstack_module.go @@ -12,9 +12,9 @@ import ( "github.com/benbjohnson/clock" "github.com/golang/glog" - "github.com/prebid/prebid-server/analytics" - "github.com/prebid/prebid-server/analytics/pubstack/eventchannel" - "github.com/prebid/prebid-server/analytics/pubstack/helpers" + "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v2/analytics/pubstack/eventchannel" + "github.com/prebid/prebid-server/v2/analytics/pubstack/helpers" ) type Configuration struct { diff --git a/analytics/pubstack/pubstack_module_test.go b/analytics/pubstack/pubstack_module_test.go index 23e110df9c1..911de4c6959 100644 --- a/analytics/pubstack/pubstack_module_test.go +++ b/analytics/pubstack/pubstack_module_test.go @@ -8,8 +8,8 @@ import ( "time" "github.com/benbjohnson/clock" - "github.com/prebid/prebid-server/analytics" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/analytics/runner.go b/analytics/runner.go index 08f67561f8a..7a2c56f77dd 100644 --- a/analytics/runner.go +++ b/analytics/runner.go @@ -1,7 +1,7 @@ package analytics import ( - "github.com/prebid/prebid-server/privacy" + "github.com/prebid/prebid-server/v2/privacy" ) type Runner interface { diff --git a/bidadjustment/apply.go b/bidadjustment/apply.go index 4fa3b737b16..16b8305a01a 100644 --- a/bidadjustment/apply.go +++ b/bidadjustment/apply.go @@ -3,8 +3,8 @@ package bidadjustment import ( "math" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const ( diff --git a/bidadjustment/apply_test.go b/bidadjustment/apply_test.go index c0eb74ab419..a1fa9f7c486 100644 --- a/bidadjustment/apply_test.go +++ b/bidadjustment/apply_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) diff --git a/bidadjustment/build_rules.go b/bidadjustment/build_rules.go index bccb3bc86cf..f028d78616a 100644 --- a/bidadjustment/build_rules.go +++ b/bidadjustment/build_rules.go @@ -1,8 +1,8 @@ package bidadjustment import ( - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const ( diff --git a/bidadjustment/build_rules_test.go b/bidadjustment/build_rules_test.go index 263a782130e..9ae1b477e8f 100644 --- a/bidadjustment/build_rules_test.go +++ b/bidadjustment/build_rules_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/bidadjustment/validate.go b/bidadjustment/validate.go index c0ae3d4a27b..f34ef48ba49 100644 --- a/bidadjustment/validate.go +++ b/bidadjustment/validate.go @@ -3,7 +3,7 @@ package bidadjustment import ( "math" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // Validate checks whether all provided bid adjustments are valid or not against the requirements defined in the issue diff --git a/bidadjustment/validate_test.go b/bidadjustment/validate_test.go index a0b4eb436eb..caf4188bb5e 100644 --- a/bidadjustment/validate_test.go +++ b/bidadjustment/validate_test.go @@ -3,7 +3,7 @@ package bidadjustment import ( "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/config/account.go b/config/account.go index 92af6c8a97f..f1de54f79a2 100644 --- a/config/account.go +++ b/config/account.go @@ -7,8 +7,8 @@ import ( "strings" "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/iputil" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/iputil" ) // ChannelType enumerates the values of integrations Prebid Server can configure for an account diff --git a/config/account_test.go b/config/account_test.go index d0c8507deef..648618f2706 100644 --- a/config/account_test.go +++ b/config/account_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/config/bidderinfo.go b/config/bidderinfo.go index f1f437c5c93..45abc85227a 100644 --- a/config/bidderinfo.go +++ b/config/bidderinfo.go @@ -9,8 +9,8 @@ import ( "strings" "text/template" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" validator "github.com/asaskevich/govalidator" "gopkg.in/yaml.v3" diff --git a/config/bidderinfo_test.go b/config/bidderinfo_test.go index 7b134314609..ad242bd0a47 100644 --- a/config/bidderinfo_test.go +++ b/config/bidderinfo_test.go @@ -7,7 +7,7 @@ import ( "gopkg.in/yaml.v3" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/config/compression.go b/config/compression.go index db85202b4a8..2fe8e7b22ac 100644 --- a/config/compression.go +++ b/config/compression.go @@ -1,6 +1,6 @@ package config -import "github.com/prebid/prebid-server/util/httputil" +import "github.com/prebid/prebid-server/v2/util/httputil" type Compression struct { Request CompressionInfo `mapstructure:"request"` diff --git a/config/compression_test.go b/config/compression_test.go index cd9048cd99e..230d1912345 100644 --- a/config/compression_test.go +++ b/config/compression_test.go @@ -3,7 +3,7 @@ package config import ( "testing" - "github.com/prebid/prebid-server/util/httputil" + "github.com/prebid/prebid-server/v2/util/httputil" "github.com/stretchr/testify/assert" ) diff --git a/config/config.go b/config/config.go index 4bd7f807002..11b7eb5841e 100644 --- a/config/config.go +++ b/config/config.go @@ -12,9 +12,9 @@ import ( "github.com/golang/glog" "github.com/prebid/go-gdpr/consentconstants" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/spf13/viper" ) diff --git a/config/config_test.go b/config/config_test.go index 21d1681c1e7..535b4e7b099 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -9,7 +9,7 @@ import ( "time" "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/spf13/viper" "github.com/stretchr/testify/assert" ) diff --git a/currency/rate_converter.go b/currency/rate_converter.go index cda8d763048..a9ab9547f83 100644 --- a/currency/rate_converter.go +++ b/currency/rate_converter.go @@ -8,9 +8,9 @@ import ( "time" "github.com/golang/glog" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/timeutil" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/timeutil" ) // RateConverter holds the currencies conversion rates dictionary diff --git a/currency/rate_converter_test.go b/currency/rate_converter_test.go index 617aa02e96a..96003c7d986 100644 --- a/currency/rate_converter_test.go +++ b/currency/rate_converter_test.go @@ -9,7 +9,7 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/util/task" + "github.com/prebid/prebid-server/v2/util/task" "github.com/stretchr/testify/assert" ) diff --git a/currency/rates_test.go b/currency/rates_test.go index 86c25d14ac0..254bc282dec 100644 --- a/currency/rates_test.go +++ b/currency/rates_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) func TestUnMarshallRates(t *testing.T) { diff --git a/currency/validation.go b/currency/validation.go index 7a0e2aa02bd..d6429c357b6 100644 --- a/currency/validation.go +++ b/currency/validation.go @@ -5,8 +5,8 @@ import ( "golang.org/x/text/currency" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // ValidateCustomRates throws a bad input error if any of the 3-digit currency codes found in diff --git a/currency/validation_test.go b/currency/validation_test.go index d49b9824986..65f93a5f9e9 100644 --- a/currency/validation_test.go +++ b/currency/validation_test.go @@ -3,8 +3,8 @@ package currency import ( "testing" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/cookie_sync.go b/endpoints/cookie_sync.go index ff801de988f..bbf91330be5 100644 --- a/endpoints/cookie_sync.go +++ b/endpoints/cookie_sync.go @@ -14,21 +14,21 @@ import ( "github.com/julienschmidt/httprouter" gpplib "github.com/prebid/go-gpp" gppConstants "github.com/prebid/go-gpp/constants" - accountService "github.com/prebid/prebid-server/account" - "github.com/prebid/prebid-server/analytics" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/gdpr" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/privacy" - "github.com/prebid/prebid-server/privacy/ccpa" - gppPrivacy "github.com/prebid/prebid-server/privacy/gpp" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/usersync" - "github.com/prebid/prebid-server/util/jsonutil" - stringutil "github.com/prebid/prebid-server/util/stringutil" + accountService "github.com/prebid/prebid-server/v2/account" + "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/gdpr" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v2/privacy/ccpa" + gppPrivacy "github.com/prebid/prebid-server/v2/privacy/gpp" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/usersync" + "github.com/prebid/prebid-server/v2/util/jsonutil" + stringutil "github.com/prebid/prebid-server/v2/util/stringutil" ) var ( diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go index 1b02357dc5d..956123006ca 100644 --- a/endpoints/cookie_sync_test.go +++ b/endpoints/cookie_sync_test.go @@ -12,17 +12,17 @@ import ( "testing" "testing/iotest" - "github.com/prebid/prebid-server/analytics" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/gdpr" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/privacy" - "github.com/prebid/prebid-server/privacy/ccpa" - "github.com/prebid/prebid-server/usersync" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/gdpr" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v2/privacy/ccpa" + "github.com/prebid/prebid-server/v2/usersync" + "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" diff --git a/endpoints/currency_rates.go b/endpoints/currency_rates.go index 49ae9963cd9..f08154471fe 100644 --- a/endpoints/currency_rates.go +++ b/endpoints/currency_rates.go @@ -5,8 +5,8 @@ import ( "time" "github.com/golang/glog" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) // currencyRatesInfo holds currency rates information. diff --git a/endpoints/currency_rates_test.go b/endpoints/currency_rates_test.go index 7fc513e7dbe..0b953c640e2 100644 --- a/endpoints/currency_rates_test.go +++ b/endpoints/currency_rates_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/currency" + "github.com/prebid/prebid-server/v2/currency" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/events/account_test.go b/endpoints/events/account_test.go index 8477b43b49b..d19a3912f59 100644 --- a/endpoints/events/account_test.go +++ b/endpoints/events/account_test.go @@ -9,10 +9,10 @@ import ( "testing" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/stored_requests" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/stored_requests" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/endpoints/events/event.go b/endpoints/events/event.go index ffcb4e006e1..b92b72f17ad 100644 --- a/endpoints/events/event.go +++ b/endpoints/events/event.go @@ -4,22 +4,23 @@ import ( "context" "errors" "fmt" - "github.com/prebid/prebid-server/openrtb_ext" "net/http" "net/url" "strconv" "time" "unicode" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/julienschmidt/httprouter" - accountService "github.com/prebid/prebid-server/account" - "github.com/prebid/prebid-server/analytics" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/privacy" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/util/httputil" + accountService "github.com/prebid/prebid-server/v2/account" + "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/util/httputil" ) const ( diff --git a/endpoints/events/event_test.go b/endpoints/events/event_test.go index 5fc115786fe..81d000fd8a4 100644 --- a/endpoints/events/event_test.go +++ b/endpoints/events/event_test.go @@ -12,12 +12,12 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/analytics" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/privacy" - "github.com/prebid/prebid-server/stored_requests" + "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v2/stored_requests" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/events/vtrack.go b/endpoints/events/vtrack.go index eeb409e24ae..5d794651ba4 100644 --- a/endpoints/events/vtrack.go +++ b/endpoints/events/vtrack.go @@ -11,15 +11,15 @@ import ( "github.com/golang/glog" "github.com/julienschmidt/httprouter" - accountService "github.com/prebid/prebid-server/account" - "github.com/prebid/prebid-server/analytics" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/prebid_cache_client" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/util/jsonutil" + accountService "github.com/prebid/prebid-server/v2/account" + "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/prebid_cache_client" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) const ( diff --git a/endpoints/events/vtrack_test.go b/endpoints/events/vtrack_test.go index d950a443afe..3ccfeacf82f 100644 --- a/endpoints/events/vtrack_test.go +++ b/endpoints/events/vtrack_test.go @@ -12,11 +12,11 @@ import ( "strings" "testing" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/prebid_cache_client" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/prebid_cache_client" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/getuids.go b/endpoints/getuids.go index f420c64fa6b..ea87ce70568 100644 --- a/endpoints/getuids.go +++ b/endpoints/getuids.go @@ -4,8 +4,8 @@ import ( "net/http" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/usersync" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/usersync" "encoding/json" ) diff --git a/endpoints/getuids_test.go b/endpoints/getuids_test.go index 7988acbaffe..c496d3e270b 100644 --- a/endpoints/getuids_test.go +++ b/endpoints/getuids_test.go @@ -5,7 +5,7 @@ import ( "net/http/httptest" "testing" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/config" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/info/bidders.go b/endpoints/info/bidders.go index bd6d078b3ba..7cbad5e26f6 100644 --- a/endpoints/info/bidders.go +++ b/endpoints/info/bidders.go @@ -7,8 +7,8 @@ import ( "github.com/golang/glog" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) var invalidEnabledOnlyMsg = []byte(`Invalid value for 'enabledonly' query param, must be of boolean type`) diff --git a/endpoints/info/bidders_detail.go b/endpoints/info/bidders_detail.go index 34d14efde1b..fbc9ab43486 100644 --- a/endpoints/info/bidders_detail.go +++ b/endpoints/info/bidders_detail.go @@ -8,9 +8,9 @@ import ( "github.com/golang/glog" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) const ( diff --git a/endpoints/info/bidders_detail_test.go b/endpoints/info/bidders_detail_test.go index 435d0cec92c..2911aa8e0e9 100644 --- a/endpoints/info/bidders_detail_test.go +++ b/endpoints/info/bidders_detail_test.go @@ -9,8 +9,8 @@ import ( "testing" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/info/bidders_test.go b/endpoints/info/bidders_test.go index 1f483e5de27..189eb865551 100644 --- a/endpoints/info/bidders_test.go +++ b/endpoints/info/bidders_test.go @@ -6,7 +6,7 @@ import ( "net/http/httptest" "testing" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/config" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index 099f5d66c41..8f8d32c8fb9 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -16,29 +16,29 @@ import ( "github.com/julienschmidt/httprouter" "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/openrtb/v19/openrtb3" - "github.com/prebid/prebid-server/hooks/hookexecution" - "github.com/prebid/prebid-server/ortb" - "github.com/prebid/prebid-server/util/uuidutil" + "github.com/prebid/prebid-server/v2/hooks/hookexecution" + "github.com/prebid/prebid-server/v2/ortb" + "github.com/prebid/prebid-server/v2/util/uuidutil" jsonpatch "gopkg.in/evanphx/json-patch.v4" - accountService "github.com/prebid/prebid-server/account" - "github.com/prebid/prebid-server/amp" - "github.com/prebid/prebid-server/analytics" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/exchange" - "github.com/prebid/prebid-server/gdpr" - "github.com/prebid/prebid-server/hooks" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/privacy" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/stored_responses" - "github.com/prebid/prebid-server/usersync" - "github.com/prebid/prebid-server/util/iputil" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/version" + accountService "github.com/prebid/prebid-server/v2/account" + "github.com/prebid/prebid-server/v2/amp" + "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/exchange" + "github.com/prebid/prebid-server/v2/gdpr" + "github.com/prebid/prebid-server/v2/hooks" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v2/stored_responses" + "github.com/prebid/prebid-server/v2/usersync" + "github.com/prebid/prebid-server/v2/util/iputil" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/version" ) const defaultAmpRequestTimeoutMillis = 900 diff --git a/endpoints/openrtb2/amp_auction_test.go b/endpoints/openrtb2/amp_auction_test.go index 7de8995754a..bd56457b3d7 100644 --- a/endpoints/openrtb2/amp_auction_test.go +++ b/endpoints/openrtb2/amp_auction_test.go @@ -18,21 +18,21 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/prebid/prebid-server/amp" - "github.com/prebid/prebid-server/analytics" - analyticsBuild "github.com/prebid/prebid-server/analytics/build" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/exchange" - "github.com/prebid/prebid-server/hooks" - "github.com/prebid/prebid-server/hooks/hookexecution" - "github.com/prebid/prebid-server/hooks/hookstage" - "github.com/prebid/prebid-server/metrics" - metricsConfig "github.com/prebid/prebid-server/metrics/config" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/privacy" - "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/amp" + "github.com/prebid/prebid-server/v2/analytics" + analyticsBuild "github.com/prebid/prebid-server/v2/analytics/build" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/exchange" + "github.com/prebid/prebid-server/v2/hooks" + "github.com/prebid/prebid-server/v2/hooks/hookexecution" + "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v2/metrics" + metricsConfig "github.com/prebid/prebid-server/v2/metrics/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v2/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) // TestGoodRequests makes sure that the auction runs properly-formatted stored bids correctly. diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index e6c9fe1fbde..72382f36b04 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -25,36 +25,36 @@ import ( nativeRequests "github.com/prebid/openrtb/v19/native1/request" "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/openrtb/v19/openrtb3" - "github.com/prebid/prebid-server/bidadjustment" - "github.com/prebid/prebid-server/hooks" - "github.com/prebid/prebid-server/ortb" - "github.com/prebid/prebid-server/privacy" + "github.com/prebid/prebid-server/v2/bidadjustment" + "github.com/prebid/prebid-server/v2/hooks" + "github.com/prebid/prebid-server/v2/ortb" + "github.com/prebid/prebid-server/v2/privacy" "golang.org/x/net/publicsuffix" jsonpatch "gopkg.in/evanphx/json-patch.v4" - accountService "github.com/prebid/prebid-server/account" - "github.com/prebid/prebid-server/analytics" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/exchange" - "github.com/prebid/prebid-server/gdpr" - "github.com/prebid/prebid-server/hooks/hookexecution" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/prebid_cache_client" - "github.com/prebid/prebid-server/privacy/ccpa" - "github.com/prebid/prebid-server/privacy/lmt" - "github.com/prebid/prebid-server/schain" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/stored_responses" - "github.com/prebid/prebid-server/usersync" - "github.com/prebid/prebid-server/util/httputil" - "github.com/prebid/prebid-server/util/iputil" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/uuidutil" - "github.com/prebid/prebid-server/version" + accountService "github.com/prebid/prebid-server/v2/account" + "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/exchange" + "github.com/prebid/prebid-server/v2/gdpr" + "github.com/prebid/prebid-server/v2/hooks/hookexecution" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/prebid_cache_client" + "github.com/prebid/prebid-server/v2/privacy/ccpa" + "github.com/prebid/prebid-server/v2/privacy/lmt" + "github.com/prebid/prebid-server/v2/schain" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v2/stored_responses" + "github.com/prebid/prebid-server/v2/usersync" + "github.com/prebid/prebid-server/v2/util/httputil" + "github.com/prebid/prebid-server/v2/util/iputil" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/uuidutil" + "github.com/prebid/prebid-server/v2/version" ) const storedRequestTimeoutMillis = 50 diff --git a/endpoints/openrtb2/auction_benchmark_test.go b/endpoints/openrtb2/auction_benchmark_test.go index f3e82dca099..88a55e627e7 100644 --- a/endpoints/openrtb2/auction_benchmark_test.go +++ b/endpoints/openrtb2/auction_benchmark_test.go @@ -10,17 +10,17 @@ import ( "testing" "time" - analyticsBuild "github.com/prebid/prebid-server/analytics/build" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/exchange" - "github.com/prebid/prebid-server/experiment/adscert" - "github.com/prebid/prebid-server/hooks" - "github.com/prebid/prebid-server/macros" - metricsConfig "github.com/prebid/prebid-server/metrics/config" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/usersync" + analyticsBuild "github.com/prebid/prebid-server/v2/analytics/build" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/exchange" + "github.com/prebid/prebid-server/v2/experiment/adscert" + "github.com/prebid/prebid-server/v2/hooks" + "github.com/prebid/prebid-server/v2/macros" + metricsConfig "github.com/prebid/prebid-server/v2/metrics/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v2/usersync" ) // benchmarkTestServer returns the header bidding test ad. This response was scraped from a real appnexus server response. diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index bab25261175..c521d653cac 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -22,22 +22,22 @@ import ( "github.com/prebid/openrtb/v19/native1" nativeRequests "github.com/prebid/openrtb/v19/native1/request" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/analytics" - analyticsBuild "github.com/prebid/prebid-server/analytics/build" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/exchange" - "github.com/prebid/prebid-server/hooks" - "github.com/prebid/prebid-server/hooks/hookexecution" - "github.com/prebid/prebid-server/hooks/hookstage" - "github.com/prebid/prebid-server/metrics" - metricsConfig "github.com/prebid/prebid-server/metrics/config" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/stored_responses" - "github.com/prebid/prebid-server/util/iputil" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/analytics" + analyticsBuild "github.com/prebid/prebid-server/v2/analytics/build" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/exchange" + "github.com/prebid/prebid-server/v2/hooks" + "github.com/prebid/prebid-server/v2/hooks/hookexecution" + "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v2/metrics" + metricsConfig "github.com/prebid/prebid-server/v2/metrics/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v2/stored_responses" + "github.com/prebid/prebid-server/v2/util/iputil" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/openrtb2/interstitial.go b/endpoints/openrtb2/interstitial.go index 46dc7a61510..330119b6f8f 100644 --- a/endpoints/openrtb2/interstitial.go +++ b/endpoints/openrtb2/interstitial.go @@ -4,9 +4,9 @@ import ( "fmt" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func processInterstitials(req *openrtb_ext.RequestWrapper) error { diff --git a/endpoints/openrtb2/interstitial_test.go b/endpoints/openrtb2/interstitial_test.go index 947817803b2..eb69bc91f08 100644 --- a/endpoints/openrtb2/interstitial_test.go +++ b/endpoints/openrtb2/interstitial_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/openrtb2/test_utils.go b/endpoints/openrtb2/test_utils.go index e8506813eef..cfc8f5d8dac 100644 --- a/endpoints/openrtb2/test_utils.go +++ b/endpoints/openrtb2/test_utils.go @@ -18,28 +18,28 @@ import ( "github.com/julienschmidt/httprouter" "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/openrtb/v19/openrtb3" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/analytics" - analyticsBuild "github.com/prebid/prebid-server/analytics/build" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/exchange" - "github.com/prebid/prebid-server/experiment/adscert" - "github.com/prebid/prebid-server/gdpr" - "github.com/prebid/prebid-server/hooks" - "github.com/prebid/prebid-server/hooks/hookexecution" - "github.com/prebid/prebid-server/hooks/hookstage" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/metrics" - metricsConfig "github.com/prebid/prebid-server/metrics/config" - "github.com/prebid/prebid-server/openrtb_ext" - pbc "github.com/prebid/prebid-server/prebid_cache_client" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/util/iputil" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/uuidutil" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/analytics" + analyticsBuild "github.com/prebid/prebid-server/v2/analytics/build" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/exchange" + "github.com/prebid/prebid-server/v2/experiment/adscert" + "github.com/prebid/prebid-server/v2/gdpr" + "github.com/prebid/prebid-server/v2/hooks" + "github.com/prebid/prebid-server/v2/hooks/hookexecution" + "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/metrics" + metricsConfig "github.com/prebid/prebid-server/v2/metrics/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" + pbc "github.com/prebid/prebid-server/v2/prebid_cache_client" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v2/util/iputil" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/uuidutil" jsonpatch "gopkg.in/evanphx/json-patch.v4" ) diff --git a/endpoints/openrtb2/video_auction.go b/endpoints/openrtb2/video_auction.go index 94455e0cb52..05802bbd506 100644 --- a/endpoints/openrtb2/video_auction.go +++ b/endpoints/openrtb2/video_auction.go @@ -17,28 +17,28 @@ import ( "github.com/golang/glog" "github.com/julienschmidt/httprouter" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/hooks" - "github.com/prebid/prebid-server/hooks/hookexecution" - "github.com/prebid/prebid-server/ortb" - "github.com/prebid/prebid-server/privacy" + "github.com/prebid/prebid-server/v2/hooks" + "github.com/prebid/prebid-server/v2/hooks/hookexecution" + "github.com/prebid/prebid-server/v2/ortb" + "github.com/prebid/prebid-server/v2/privacy" jsonpatch "gopkg.in/evanphx/json-patch.v4" - accountService "github.com/prebid/prebid-server/account" - "github.com/prebid/prebid-server/analytics" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/exchange" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/prebid_cache_client" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/usersync" - "github.com/prebid/prebid-server/util/iputil" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/ptrutil" - "github.com/prebid/prebid-server/util/uuidutil" - "github.com/prebid/prebid-server/version" + accountService "github.com/prebid/prebid-server/v2/account" + "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/exchange" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/prebid_cache_client" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v2/usersync" + "github.com/prebid/prebid-server/v2/util/iputil" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v2/util/uuidutil" + "github.com/prebid/prebid-server/v2/version" ) var defaultRequestTimeout int64 = 5000 diff --git a/endpoints/openrtb2/video_auction_test.go b/endpoints/openrtb2/video_auction_test.go index 281c80b204d..70a37aab5df 100644 --- a/endpoints/openrtb2/video_auction_test.go +++ b/endpoints/openrtb2/video_auction_test.go @@ -11,20 +11,20 @@ import ( "strings" "testing" - "github.com/prebid/prebid-server/analytics" - analyticsBuild "github.com/prebid/prebid-server/analytics/build" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/exchange" - "github.com/prebid/prebid-server/hooks" - "github.com/prebid/prebid-server/metrics" - metricsConfig "github.com/prebid/prebid-server/metrics/config" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/prebid_cache_client" - "github.com/prebid/prebid-server/privacy" - "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/analytics" + analyticsBuild "github.com/prebid/prebid-server/v2/analytics/build" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/exchange" + "github.com/prebid/prebid-server/v2/hooks" + "github.com/prebid/prebid-server/v2/metrics" + metricsConfig "github.com/prebid/prebid-server/v2/metrics/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/prebid_cache_client" + "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v2/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" diff --git a/endpoints/setuid.go b/endpoints/setuid.go index 7af70d002b5..f9c55fc84de 100644 --- a/endpoints/setuid.go +++ b/endpoints/setuid.go @@ -12,19 +12,19 @@ import ( "github.com/julienschmidt/httprouter" gpplib "github.com/prebid/go-gpp" gppConstants "github.com/prebid/go-gpp/constants" - accountService "github.com/prebid/prebid-server/account" - "github.com/prebid/prebid-server/analytics" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/gdpr" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/privacy" - gppPrivacy "github.com/prebid/prebid-server/privacy/gpp" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/usersync" - "github.com/prebid/prebid-server/util/httputil" - stringutil "github.com/prebid/prebid-server/util/stringutil" + accountService "github.com/prebid/prebid-server/v2/account" + "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/gdpr" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/privacy" + gppPrivacy "github.com/prebid/prebid-server/v2/privacy/gpp" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/usersync" + "github.com/prebid/prebid-server/v2/util/httputil" + stringutil "github.com/prebid/prebid-server/v2/util/stringutil" ) const ( diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go index 8b919c3d596..fe66379702c 100644 --- a/endpoints/setuid_test.go +++ b/endpoints/setuid_test.go @@ -12,18 +12,18 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/analytics" - analyticsBuild "github.com/prebid/prebid-server/analytics/build" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/gdpr" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/usersync" + "github.com/prebid/prebid-server/v2/analytics" + analyticsBuild "github.com/prebid/prebid-server/v2/analytics/build" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/gdpr" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/usersync" "github.com/stretchr/testify/assert" - metricsConf "github.com/prebid/prebid-server/metrics/config" + metricsConf "github.com/prebid/prebid-server/v2/metrics/config" ) func TestSetUIDEndpoint(t *testing.T) { diff --git a/endpoints/version.go b/endpoints/version.go index 0a837fd8bc3..f9e07da9a0d 100644 --- a/endpoints/version.go +++ b/endpoints/version.go @@ -5,7 +5,7 @@ import ( "net/http" "github.com/golang/glog" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) const versionEndpointValueNotSet = "not-set" diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index fd1a99aeffb..a5179f75d53 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -1,194 +1,194 @@ package exchange import ( - "github.com/prebid/prebid-server/adapters" - ttx "github.com/prebid/prebid-server/adapters/33across" - "github.com/prebid/prebid-server/adapters/aax" - "github.com/prebid/prebid-server/adapters/aceex" - "github.com/prebid/prebid-server/adapters/acuityads" - "github.com/prebid/prebid-server/adapters/adf" - "github.com/prebid/prebid-server/adapters/adgeneration" - "github.com/prebid/prebid-server/adapters/adhese" - "github.com/prebid/prebid-server/adapters/adkernel" - "github.com/prebid/prebid-server/adapters/adkernelAdn" - "github.com/prebid/prebid-server/adapters/adman" - "github.com/prebid/prebid-server/adapters/admixer" - "github.com/prebid/prebid-server/adapters/adnuntius" - "github.com/prebid/prebid-server/adapters/adocean" - "github.com/prebid/prebid-server/adapters/adoppler" - "github.com/prebid/prebid-server/adapters/adot" - "github.com/prebid/prebid-server/adapters/adpone" - "github.com/prebid/prebid-server/adapters/adprime" - "github.com/prebid/prebid-server/adapters/adquery" - "github.com/prebid/prebid-server/adapters/adrino" - "github.com/prebid/prebid-server/adapters/adsinteractive" - "github.com/prebid/prebid-server/adapters/adtarget" - "github.com/prebid/prebid-server/adapters/adtelligent" - "github.com/prebid/prebid-server/adapters/adtrgtme" - "github.com/prebid/prebid-server/adapters/advangelists" - "github.com/prebid/prebid-server/adapters/adview" - "github.com/prebid/prebid-server/adapters/adxcg" - "github.com/prebid/prebid-server/adapters/adyoulike" - "github.com/prebid/prebid-server/adapters/aidem" - "github.com/prebid/prebid-server/adapters/aja" - "github.com/prebid/prebid-server/adapters/algorix" - "github.com/prebid/prebid-server/adapters/amx" - "github.com/prebid/prebid-server/adapters/apacdex" - "github.com/prebid/prebid-server/adapters/appnexus" - "github.com/prebid/prebid-server/adapters/appush" - "github.com/prebid/prebid-server/adapters/audienceNetwork" - "github.com/prebid/prebid-server/adapters/automatad" - "github.com/prebid/prebid-server/adapters/avocet" - "github.com/prebid/prebid-server/adapters/axis" - "github.com/prebid/prebid-server/adapters/axonix" - "github.com/prebid/prebid-server/adapters/beachfront" - "github.com/prebid/prebid-server/adapters/beintoo" - "github.com/prebid/prebid-server/adapters/bematterfull" - "github.com/prebid/prebid-server/adapters/between" - "github.com/prebid/prebid-server/adapters/beyondmedia" - "github.com/prebid/prebid-server/adapters/bidmachine" - "github.com/prebid/prebid-server/adapters/bidmyadz" - "github.com/prebid/prebid-server/adapters/bidscube" - "github.com/prebid/prebid-server/adapters/bidstack" - "github.com/prebid/prebid-server/adapters/bizzclick" - "github.com/prebid/prebid-server/adapters/bliink" - "github.com/prebid/prebid-server/adapters/blue" - "github.com/prebid/prebid-server/adapters/bluesea" - "github.com/prebid/prebid-server/adapters/bmtm" - "github.com/prebid/prebid-server/adapters/boldwin" - "github.com/prebid/prebid-server/adapters/brave" - cadentaperturemx "github.com/prebid/prebid-server/adapters/cadent_aperture_mx" - "github.com/prebid/prebid-server/adapters/ccx" - "github.com/prebid/prebid-server/adapters/coinzilla" - "github.com/prebid/prebid-server/adapters/colossus" - "github.com/prebid/prebid-server/adapters/compass" - "github.com/prebid/prebid-server/adapters/connectad" - "github.com/prebid/prebid-server/adapters/consumable" - "github.com/prebid/prebid-server/adapters/conversant" - "github.com/prebid/prebid-server/adapters/cpmstar" - "github.com/prebid/prebid-server/adapters/criteo" - "github.com/prebid/prebid-server/adapters/cwire" - "github.com/prebid/prebid-server/adapters/datablocks" - "github.com/prebid/prebid-server/adapters/decenterads" - "github.com/prebid/prebid-server/adapters/deepintent" - "github.com/prebid/prebid-server/adapters/definemedia" - "github.com/prebid/prebid-server/adapters/dianomi" - "github.com/prebid/prebid-server/adapters/dmx" - "github.com/prebid/prebid-server/adapters/dxkulture" - evolution "github.com/prebid/prebid-server/adapters/e_volution" - "github.com/prebid/prebid-server/adapters/edge226" - "github.com/prebid/prebid-server/adapters/emtv" - "github.com/prebid/prebid-server/adapters/eplanning" - "github.com/prebid/prebid-server/adapters/epom" - "github.com/prebid/prebid-server/adapters/flipp" - "github.com/prebid/prebid-server/adapters/freewheelssp" - "github.com/prebid/prebid-server/adapters/frvradn" - "github.com/prebid/prebid-server/adapters/gamma" - "github.com/prebid/prebid-server/adapters/gamoshi" - "github.com/prebid/prebid-server/adapters/globalsun" - "github.com/prebid/prebid-server/adapters/gothamads" - "github.com/prebid/prebid-server/adapters/grid" - "github.com/prebid/prebid-server/adapters/gumgum" - "github.com/prebid/prebid-server/adapters/huaweiads" - "github.com/prebid/prebid-server/adapters/imds" - "github.com/prebid/prebid-server/adapters/impactify" - "github.com/prebid/prebid-server/adapters/improvedigital" - "github.com/prebid/prebid-server/adapters/infytv" - "github.com/prebid/prebid-server/adapters/inmobi" - "github.com/prebid/prebid-server/adapters/interactiveoffers" - "github.com/prebid/prebid-server/adapters/invibes" - "github.com/prebid/prebid-server/adapters/iqx" - "github.com/prebid/prebid-server/adapters/iqzone" - "github.com/prebid/prebid-server/adapters/ix" - "github.com/prebid/prebid-server/adapters/jixie" - "github.com/prebid/prebid-server/adapters/kargo" - "github.com/prebid/prebid-server/adapters/kayzen" - "github.com/prebid/prebid-server/adapters/kidoz" - "github.com/prebid/prebid-server/adapters/kiviads" - "github.com/prebid/prebid-server/adapters/krushmedia" - "github.com/prebid/prebid-server/adapters/lemmadigital" - "github.com/prebid/prebid-server/adapters/liftoff" - "github.com/prebid/prebid-server/adapters/limelightDigital" - lmkiviads "github.com/prebid/prebid-server/adapters/lm_kiviads" - "github.com/prebid/prebid-server/adapters/lockerdome" - "github.com/prebid/prebid-server/adapters/logan" - "github.com/prebid/prebid-server/adapters/logicad" - "github.com/prebid/prebid-server/adapters/lunamedia" - mabidder "github.com/prebid/prebid-server/adapters/mabidder" - "github.com/prebid/prebid-server/adapters/madvertise" - "github.com/prebid/prebid-server/adapters/marsmedia" - "github.com/prebid/prebid-server/adapters/medianet" - "github.com/prebid/prebid-server/adapters/mgid" - "github.com/prebid/prebid-server/adapters/mgidX" - "github.com/prebid/prebid-server/adapters/mobfoxpb" - "github.com/prebid/prebid-server/adapters/mobilefuse" - "github.com/prebid/prebid-server/adapters/motorik" - "github.com/prebid/prebid-server/adapters/nextmillennium" - "github.com/prebid/prebid-server/adapters/nobid" - "github.com/prebid/prebid-server/adapters/onetag" - "github.com/prebid/prebid-server/adapters/openweb" - "github.com/prebid/prebid-server/adapters/openx" - "github.com/prebid/prebid-server/adapters/operaads" - "github.com/prebid/prebid-server/adapters/orbidder" - "github.com/prebid/prebid-server/adapters/outbrain" - "github.com/prebid/prebid-server/adapters/ownadx" - "github.com/prebid/prebid-server/adapters/pangle" - "github.com/prebid/prebid-server/adapters/pgamssp" - "github.com/prebid/prebid-server/adapters/pubmatic" - "github.com/prebid/prebid-server/adapters/pubnative" - "github.com/prebid/prebid-server/adapters/pulsepoint" - "github.com/prebid/prebid-server/adapters/pwbid" - "github.com/prebid/prebid-server/adapters/revcontent" - "github.com/prebid/prebid-server/adapters/richaudience" - "github.com/prebid/prebid-server/adapters/rise" - "github.com/prebid/prebid-server/adapters/rtbhouse" - "github.com/prebid/prebid-server/adapters/rubicon" - salunamedia "github.com/prebid/prebid-server/adapters/sa_lunamedia" - "github.com/prebid/prebid-server/adapters/screencore" - "github.com/prebid/prebid-server/adapters/seedingAlliance" - "github.com/prebid/prebid-server/adapters/sharethrough" - "github.com/prebid/prebid-server/adapters/silvermob" - "github.com/prebid/prebid-server/adapters/silverpush" - "github.com/prebid/prebid-server/adapters/smaato" - "github.com/prebid/prebid-server/adapters/smartadserver" - "github.com/prebid/prebid-server/adapters/smarthub" - "github.com/prebid/prebid-server/adapters/smartrtb" - "github.com/prebid/prebid-server/adapters/smartx" - "github.com/prebid/prebid-server/adapters/smartyads" - "github.com/prebid/prebid-server/adapters/smilewanted" - "github.com/prebid/prebid-server/adapters/sonobi" - "github.com/prebid/prebid-server/adapters/sovrn" - "github.com/prebid/prebid-server/adapters/sspBC" - "github.com/prebid/prebid-server/adapters/stroeerCore" - "github.com/prebid/prebid-server/adapters/suntContent" - "github.com/prebid/prebid-server/adapters/taboola" - "github.com/prebid/prebid-server/adapters/tappx" - "github.com/prebid/prebid-server/adapters/teads" - "github.com/prebid/prebid-server/adapters/telaria" - "github.com/prebid/prebid-server/adapters/tpmn" - "github.com/prebid/prebid-server/adapters/trafficgate" - "github.com/prebid/prebid-server/adapters/triplelift" - "github.com/prebid/prebid-server/adapters/triplelift_native" - "github.com/prebid/prebid-server/adapters/ucfunnel" - "github.com/prebid/prebid-server/adapters/undertone" - "github.com/prebid/prebid-server/adapters/unicorn" - "github.com/prebid/prebid-server/adapters/unruly" - "github.com/prebid/prebid-server/adapters/videobyte" - "github.com/prebid/prebid-server/adapters/videoheroes" - "github.com/prebid/prebid-server/adapters/vidoomy" - "github.com/prebid/prebid-server/adapters/visiblemeasures" - "github.com/prebid/prebid-server/adapters/visx" - "github.com/prebid/prebid-server/adapters/vox" - "github.com/prebid/prebid-server/adapters/vrtcal" - "github.com/prebid/prebid-server/adapters/xeworks" - "github.com/prebid/prebid-server/adapters/yahooAds" - "github.com/prebid/prebid-server/adapters/yeahmobi" - "github.com/prebid/prebid-server/adapters/yieldlab" - "github.com/prebid/prebid-server/adapters/yieldmo" - "github.com/prebid/prebid-server/adapters/yieldone" - "github.com/prebid/prebid-server/adapters/zeroclickfraud" - "github.com/prebid/prebid-server/adapters/zeta_global_ssp" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + ttx "github.com/prebid/prebid-server/v2/adapters/33across" + "github.com/prebid/prebid-server/v2/adapters/aax" + "github.com/prebid/prebid-server/v2/adapters/aceex" + "github.com/prebid/prebid-server/v2/adapters/acuityads" + "github.com/prebid/prebid-server/v2/adapters/adf" + "github.com/prebid/prebid-server/v2/adapters/adgeneration" + "github.com/prebid/prebid-server/v2/adapters/adhese" + "github.com/prebid/prebid-server/v2/adapters/adkernel" + "github.com/prebid/prebid-server/v2/adapters/adkernelAdn" + "github.com/prebid/prebid-server/v2/adapters/adman" + "github.com/prebid/prebid-server/v2/adapters/admixer" + "github.com/prebid/prebid-server/v2/adapters/adnuntius" + "github.com/prebid/prebid-server/v2/adapters/adocean" + "github.com/prebid/prebid-server/v2/adapters/adoppler" + "github.com/prebid/prebid-server/v2/adapters/adot" + "github.com/prebid/prebid-server/v2/adapters/adpone" + "github.com/prebid/prebid-server/v2/adapters/adprime" + "github.com/prebid/prebid-server/v2/adapters/adquery" + "github.com/prebid/prebid-server/v2/adapters/adrino" + "github.com/prebid/prebid-server/v2/adapters/adsinteractive" + "github.com/prebid/prebid-server/v2/adapters/adtarget" + "github.com/prebid/prebid-server/v2/adapters/adtelligent" + "github.com/prebid/prebid-server/v2/adapters/adtrgtme" + "github.com/prebid/prebid-server/v2/adapters/advangelists" + "github.com/prebid/prebid-server/v2/adapters/adview" + "github.com/prebid/prebid-server/v2/adapters/adxcg" + "github.com/prebid/prebid-server/v2/adapters/adyoulike" + "github.com/prebid/prebid-server/v2/adapters/aidem" + "github.com/prebid/prebid-server/v2/adapters/aja" + "github.com/prebid/prebid-server/v2/adapters/algorix" + "github.com/prebid/prebid-server/v2/adapters/amx" + "github.com/prebid/prebid-server/v2/adapters/apacdex" + "github.com/prebid/prebid-server/v2/adapters/appnexus" + "github.com/prebid/prebid-server/v2/adapters/appush" + "github.com/prebid/prebid-server/v2/adapters/audienceNetwork" + "github.com/prebid/prebid-server/v2/adapters/automatad" + "github.com/prebid/prebid-server/v2/adapters/avocet" + "github.com/prebid/prebid-server/v2/adapters/axis" + "github.com/prebid/prebid-server/v2/adapters/axonix" + "github.com/prebid/prebid-server/v2/adapters/beachfront" + "github.com/prebid/prebid-server/v2/adapters/beintoo" + "github.com/prebid/prebid-server/v2/adapters/bematterfull" + "github.com/prebid/prebid-server/v2/adapters/between" + "github.com/prebid/prebid-server/v2/adapters/beyondmedia" + "github.com/prebid/prebid-server/v2/adapters/bidmachine" + "github.com/prebid/prebid-server/v2/adapters/bidmyadz" + "github.com/prebid/prebid-server/v2/adapters/bidscube" + "github.com/prebid/prebid-server/v2/adapters/bidstack" + "github.com/prebid/prebid-server/v2/adapters/bizzclick" + "github.com/prebid/prebid-server/v2/adapters/bliink" + "github.com/prebid/prebid-server/v2/adapters/blue" + "github.com/prebid/prebid-server/v2/adapters/bluesea" + "github.com/prebid/prebid-server/v2/adapters/bmtm" + "github.com/prebid/prebid-server/v2/adapters/boldwin" + "github.com/prebid/prebid-server/v2/adapters/brave" + cadentaperturemx "github.com/prebid/prebid-server/v2/adapters/cadent_aperture_mx" + "github.com/prebid/prebid-server/v2/adapters/ccx" + "github.com/prebid/prebid-server/v2/adapters/coinzilla" + "github.com/prebid/prebid-server/v2/adapters/colossus" + "github.com/prebid/prebid-server/v2/adapters/compass" + "github.com/prebid/prebid-server/v2/adapters/connectad" + "github.com/prebid/prebid-server/v2/adapters/consumable" + "github.com/prebid/prebid-server/v2/adapters/conversant" + "github.com/prebid/prebid-server/v2/adapters/cpmstar" + "github.com/prebid/prebid-server/v2/adapters/criteo" + "github.com/prebid/prebid-server/v2/adapters/cwire" + "github.com/prebid/prebid-server/v2/adapters/datablocks" + "github.com/prebid/prebid-server/v2/adapters/decenterads" + "github.com/prebid/prebid-server/v2/adapters/deepintent" + "github.com/prebid/prebid-server/v2/adapters/definemedia" + "github.com/prebid/prebid-server/v2/adapters/dianomi" + "github.com/prebid/prebid-server/v2/adapters/dmx" + "github.com/prebid/prebid-server/v2/adapters/dxkulture" + evolution "github.com/prebid/prebid-server/v2/adapters/e_volution" + "github.com/prebid/prebid-server/v2/adapters/edge226" + "github.com/prebid/prebid-server/v2/adapters/emtv" + "github.com/prebid/prebid-server/v2/adapters/eplanning" + "github.com/prebid/prebid-server/v2/adapters/epom" + "github.com/prebid/prebid-server/v2/adapters/flipp" + "github.com/prebid/prebid-server/v2/adapters/freewheelssp" + "github.com/prebid/prebid-server/v2/adapters/frvradn" + "github.com/prebid/prebid-server/v2/adapters/gamma" + "github.com/prebid/prebid-server/v2/adapters/gamoshi" + "github.com/prebid/prebid-server/v2/adapters/globalsun" + "github.com/prebid/prebid-server/v2/adapters/gothamads" + "github.com/prebid/prebid-server/v2/adapters/grid" + "github.com/prebid/prebid-server/v2/adapters/gumgum" + "github.com/prebid/prebid-server/v2/adapters/huaweiads" + "github.com/prebid/prebid-server/v2/adapters/imds" + "github.com/prebid/prebid-server/v2/adapters/impactify" + "github.com/prebid/prebid-server/v2/adapters/improvedigital" + "github.com/prebid/prebid-server/v2/adapters/infytv" + "github.com/prebid/prebid-server/v2/adapters/inmobi" + "github.com/prebid/prebid-server/v2/adapters/interactiveoffers" + "github.com/prebid/prebid-server/v2/adapters/invibes" + "github.com/prebid/prebid-server/v2/adapters/iqx" + "github.com/prebid/prebid-server/v2/adapters/iqzone" + "github.com/prebid/prebid-server/v2/adapters/ix" + "github.com/prebid/prebid-server/v2/adapters/jixie" + "github.com/prebid/prebid-server/v2/adapters/kargo" + "github.com/prebid/prebid-server/v2/adapters/kayzen" + "github.com/prebid/prebid-server/v2/adapters/kidoz" + "github.com/prebid/prebid-server/v2/adapters/kiviads" + "github.com/prebid/prebid-server/v2/adapters/krushmedia" + "github.com/prebid/prebid-server/v2/adapters/lemmadigital" + "github.com/prebid/prebid-server/v2/adapters/liftoff" + "github.com/prebid/prebid-server/v2/adapters/limelightDigital" + lmkiviads "github.com/prebid/prebid-server/v2/adapters/lm_kiviads" + "github.com/prebid/prebid-server/v2/adapters/lockerdome" + "github.com/prebid/prebid-server/v2/adapters/logan" + "github.com/prebid/prebid-server/v2/adapters/logicad" + "github.com/prebid/prebid-server/v2/adapters/lunamedia" + mabidder "github.com/prebid/prebid-server/v2/adapters/mabidder" + "github.com/prebid/prebid-server/v2/adapters/madvertise" + "github.com/prebid/prebid-server/v2/adapters/marsmedia" + "github.com/prebid/prebid-server/v2/adapters/medianet" + "github.com/prebid/prebid-server/v2/adapters/mgid" + "github.com/prebid/prebid-server/v2/adapters/mgidX" + "github.com/prebid/prebid-server/v2/adapters/mobfoxpb" + "github.com/prebid/prebid-server/v2/adapters/mobilefuse" + "github.com/prebid/prebid-server/v2/adapters/motorik" + "github.com/prebid/prebid-server/v2/adapters/nextmillennium" + "github.com/prebid/prebid-server/v2/adapters/nobid" + "github.com/prebid/prebid-server/v2/adapters/onetag" + "github.com/prebid/prebid-server/v2/adapters/openweb" + "github.com/prebid/prebid-server/v2/adapters/openx" + "github.com/prebid/prebid-server/v2/adapters/operaads" + "github.com/prebid/prebid-server/v2/adapters/orbidder" + "github.com/prebid/prebid-server/v2/adapters/outbrain" + "github.com/prebid/prebid-server/v2/adapters/ownadx" + "github.com/prebid/prebid-server/v2/adapters/pangle" + "github.com/prebid/prebid-server/v2/adapters/pgamssp" + "github.com/prebid/prebid-server/v2/adapters/pubmatic" + "github.com/prebid/prebid-server/v2/adapters/pubnative" + "github.com/prebid/prebid-server/v2/adapters/pulsepoint" + "github.com/prebid/prebid-server/v2/adapters/pwbid" + "github.com/prebid/prebid-server/v2/adapters/revcontent" + "github.com/prebid/prebid-server/v2/adapters/richaudience" + "github.com/prebid/prebid-server/v2/adapters/rise" + "github.com/prebid/prebid-server/v2/adapters/rtbhouse" + "github.com/prebid/prebid-server/v2/adapters/rubicon" + salunamedia "github.com/prebid/prebid-server/v2/adapters/sa_lunamedia" + "github.com/prebid/prebid-server/v2/adapters/screencore" + "github.com/prebid/prebid-server/v2/adapters/seedingAlliance" + "github.com/prebid/prebid-server/v2/adapters/sharethrough" + "github.com/prebid/prebid-server/v2/adapters/silvermob" + "github.com/prebid/prebid-server/v2/adapters/silverpush" + "github.com/prebid/prebid-server/v2/adapters/smaato" + "github.com/prebid/prebid-server/v2/adapters/smartadserver" + "github.com/prebid/prebid-server/v2/adapters/smarthub" + "github.com/prebid/prebid-server/v2/adapters/smartrtb" + "github.com/prebid/prebid-server/v2/adapters/smartx" + "github.com/prebid/prebid-server/v2/adapters/smartyads" + "github.com/prebid/prebid-server/v2/adapters/smilewanted" + "github.com/prebid/prebid-server/v2/adapters/sonobi" + "github.com/prebid/prebid-server/v2/adapters/sovrn" + "github.com/prebid/prebid-server/v2/adapters/sspBC" + "github.com/prebid/prebid-server/v2/adapters/stroeerCore" + "github.com/prebid/prebid-server/v2/adapters/suntContent" + "github.com/prebid/prebid-server/v2/adapters/taboola" + "github.com/prebid/prebid-server/v2/adapters/tappx" + "github.com/prebid/prebid-server/v2/adapters/teads" + "github.com/prebid/prebid-server/v2/adapters/telaria" + "github.com/prebid/prebid-server/v2/adapters/tpmn" + "github.com/prebid/prebid-server/v2/adapters/trafficgate" + "github.com/prebid/prebid-server/v2/adapters/triplelift" + "github.com/prebid/prebid-server/v2/adapters/triplelift_native" + "github.com/prebid/prebid-server/v2/adapters/ucfunnel" + "github.com/prebid/prebid-server/v2/adapters/undertone" + "github.com/prebid/prebid-server/v2/adapters/unicorn" + "github.com/prebid/prebid-server/v2/adapters/unruly" + "github.com/prebid/prebid-server/v2/adapters/videobyte" + "github.com/prebid/prebid-server/v2/adapters/videoheroes" + "github.com/prebid/prebid-server/v2/adapters/vidoomy" + "github.com/prebid/prebid-server/v2/adapters/visiblemeasures" + "github.com/prebid/prebid-server/v2/adapters/visx" + "github.com/prebid/prebid-server/v2/adapters/vox" + "github.com/prebid/prebid-server/v2/adapters/vrtcal" + "github.com/prebid/prebid-server/v2/adapters/xeworks" + "github.com/prebid/prebid-server/v2/adapters/yahooAds" + "github.com/prebid/prebid-server/v2/adapters/yeahmobi" + "github.com/prebid/prebid-server/v2/adapters/yieldlab" + "github.com/prebid/prebid-server/v2/adapters/yieldmo" + "github.com/prebid/prebid-server/v2/adapters/yieldone" + "github.com/prebid/prebid-server/v2/adapters/zeroclickfraud" + "github.com/prebid/prebid-server/v2/adapters/zeta_global_ssp" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // Adapter registration is kept in this separate file for ease of use and to aid diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index 89d58d06800..cd70530bfc3 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -4,10 +4,10 @@ import ( "fmt" "net/http" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func BuildAdapters(client *http.Client, cfg *config.Configuration, infos config.BidderInfos, me metrics.MetricsEngine) (map[openrtb_ext.BidderName]AdaptedBidder, []error) { diff --git a/exchange/adapter_util_test.go b/exchange/adapter_util_test.go index 08d751cdadf..8f765305248 100644 --- a/exchange/adapter_util_test.go +++ b/exchange/adapter_util_test.go @@ -6,12 +6,12 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adapters/appnexus" - "github.com/prebid/prebid-server/adapters/rubicon" - "github.com/prebid/prebid-server/config" - metrics "github.com/prebid/prebid-server/metrics/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/appnexus" + "github.com/prebid/prebid-server/v2/adapters/rubicon" + "github.com/prebid/prebid-server/v2/config" + metrics "github.com/prebid/prebid-server/v2/metrics/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/exchange/auction.go b/exchange/auction.go index abbf56ba799..17a843fb5ed 100644 --- a/exchange/auction.go +++ b/exchange/auction.go @@ -12,11 +12,11 @@ import ( uuid "github.com/gofrs/uuid" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/prebid_cache_client" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/prebid_cache_client" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) const ( diff --git a/exchange/auction_response.go b/exchange/auction_response.go index 3b85a4472c2..c92798d0f3b 100644 --- a/exchange/auction_response.go +++ b/exchange/auction_response.go @@ -2,7 +2,7 @@ package exchange import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // AuctionResponse contains OpenRTB Bid Response object and its extension (un-marshalled) object diff --git a/exchange/auction_test.go b/exchange/auction_test.go index 199b2abba77..10c4b9a5e67 100644 --- a/exchange/auction_test.go +++ b/exchange/auction_test.go @@ -12,12 +12,12 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/prebid_cache_client" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/prebid_cache_client" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/exchange/bidder.go b/exchange/bidder.go index 677743801f3..db654bf47ae 100644 --- a/exchange/bidder.go +++ b/exchange/bidder.go @@ -16,24 +16,24 @@ import ( "time" "github.com/golang/glog" - "github.com/prebid/prebid-server/bidadjustment" - "github.com/prebid/prebid-server/config/util" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/experiment/adscert" - "github.com/prebid/prebid-server/hooks/hookexecution" - "github.com/prebid/prebid-server/version" + "github.com/prebid/prebid-server/v2/bidadjustment" + "github.com/prebid/prebid-server/v2/config/util" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/experiment/adscert" + "github.com/prebid/prebid-server/v2/hooks/hookexecution" + "github.com/prebid/prebid-server/v2/version" "github.com/prebid/openrtb/v19/adcom1" nativeRequests "github.com/prebid/openrtb/v19/native1/request" nativeResponse "github.com/prebid/openrtb/v19/native1/response" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" "golang.org/x/net/context/ctxhttp" ) diff --git a/exchange/bidder_test.go b/exchange/bidder_test.go index b7203e33b17..824aecc8583 100644 --- a/exchange/bidder_test.go +++ b/exchange/bidder_test.go @@ -21,18 +21,18 @@ import ( nativeRequests "github.com/prebid/openrtb/v19/native1/request" nativeResponse "github.com/prebid/openrtb/v19/native1/response" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/experiment/adscert" - "github.com/prebid/prebid-server/hooks/hookexecution" - "github.com/prebid/prebid-server/metrics" - metricsConfig "github.com/prebid/prebid-server/metrics/config" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/version" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/experiment/adscert" + "github.com/prebid/prebid-server/v2/hooks/hookexecution" + "github.com/prebid/prebid-server/v2/metrics" + metricsConfig "github.com/prebid/prebid-server/v2/metrics/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/version" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) diff --git a/exchange/bidder_validate_bids.go b/exchange/bidder_validate_bids.go index 9b5771a3497..651b2c0f420 100644 --- a/exchange/bidder_validate_bids.go +++ b/exchange/bidder_validate_bids.go @@ -7,12 +7,12 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/experiment/adscert" - "github.com/prebid/prebid-server/hooks/hookexecution" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/experiment/adscert" + "github.com/prebid/prebid-server/v2/hooks/hookexecution" + "github.com/prebid/prebid-server/v2/openrtb_ext" goCurrency "golang.org/x/text/currency" ) diff --git a/exchange/bidder_validate_bids_test.go b/exchange/bidder_validate_bids_test.go index ed6173b64ad..a495556f424 100644 --- a/exchange/bidder_validate_bids_test.go +++ b/exchange/bidder_validate_bids_test.go @@ -5,12 +5,12 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/experiment/adscert" - "github.com/prebid/prebid-server/hooks/hookexecution" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/experiment/adscert" + "github.com/prebid/prebid-server/v2/hooks/hookexecution" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/exchange/entities/entities.go b/exchange/entities/entities.go index 1220da5c812..f106003d8ca 100644 --- a/exchange/entities/entities.go +++ b/exchange/entities/entities.go @@ -2,7 +2,7 @@ package entities import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // PbsOrtbSeatBid is a SeatBid returned by an AdaptedBidder. diff --git a/exchange/events.go b/exchange/events.go index fb535f6f70e..b20eea328f6 100644 --- a/exchange/events.go +++ b/exchange/events.go @@ -3,14 +3,14 @@ package exchange import ( "time" - "github.com/prebid/prebid-server/exchange/entities" + "github.com/prebid/prebid-server/v2/exchange/entities" jsonpatch "gopkg.in/evanphx/json-patch.v4" - "github.com/prebid/prebid-server/analytics" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/endpoints/events" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/endpoints/events" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) // eventTracking has configuration fields needed for adding event tracking to an auction response diff --git a/exchange/events_test.go b/exchange/events_test.go index 24dedf1a6f1..3d191f5f63c 100644 --- a/exchange/events_test.go +++ b/exchange/events_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/exchange/exchange.go b/exchange/exchange.go index 6ebde7dca9d..b07c4bdf2a5 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -14,29 +14,29 @@ import ( "strings" "time" - "github.com/prebid/prebid-server/privacy" - - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/adservertargeting" - "github.com/prebid/prebid-server/bidadjustment" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/experiment/adscert" - "github.com/prebid/prebid-server/firstpartydata" - "github.com/prebid/prebid-server/floors" - "github.com/prebid/prebid-server/gdpr" - "github.com/prebid/prebid-server/hooks/hookexecution" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/prebid_cache_client" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/stored_responses" - "github.com/prebid/prebid-server/usersync" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/maputil" + "github.com/prebid/prebid-server/v2/privacy" + + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adservertargeting" + "github.com/prebid/prebid-server/v2/bidadjustment" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/experiment/adscert" + "github.com/prebid/prebid-server/v2/firstpartydata" + "github.com/prebid/prebid-server/v2/floors" + "github.com/prebid/prebid-server/v2/gdpr" + "github.com/prebid/prebid-server/v2/hooks/hookexecution" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/prebid_cache_client" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/stored_responses" + "github.com/prebid/prebid-server/v2/usersync" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/maputil" "github.com/buger/jsonparser" "github.com/gofrs/uuid" diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go index ff989bad91d..bfeb9374af3 100644 --- a/exchange/exchange_test.go +++ b/exchange/exchange_test.go @@ -21,28 +21,28 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/experiment/adscert" - "github.com/prebid/prebid-server/gdpr" - "github.com/prebid/prebid-server/hooks" - "github.com/prebid/prebid-server/hooks/hookexecution" - "github.com/prebid/prebid-server/hooks/hookstage" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/metrics" - metricsConf "github.com/prebid/prebid-server/metrics/config" - metricsConfig "github.com/prebid/prebid-server/metrics/config" - "github.com/prebid/prebid-server/openrtb_ext" - pbc "github.com/prebid/prebid-server/prebid_cache_client" - "github.com/prebid/prebid-server/privacy" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/stored_requests/backends/file_fetcher" - "github.com/prebid/prebid-server/usersync" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/experiment/adscert" + "github.com/prebid/prebid-server/v2/gdpr" + "github.com/prebid/prebid-server/v2/hooks" + "github.com/prebid/prebid-server/v2/hooks/hookexecution" + "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/metrics" + metricsConf "github.com/prebid/prebid-server/v2/metrics/config" + metricsConfig "github.com/prebid/prebid-server/v2/metrics/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" + pbc "github.com/prebid/prebid-server/v2/prebid_cache_client" + "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/stored_requests/backends/file_fetcher" + "github.com/prebid/prebid-server/v2/usersync" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" jsonpatch "gopkg.in/evanphx/json-patch.v4" diff --git a/exchange/gdpr.go b/exchange/gdpr.go index d503eb5da27..52fb860f5df 100644 --- a/exchange/gdpr.go +++ b/exchange/gdpr.go @@ -3,9 +3,9 @@ package exchange import ( gpplib "github.com/prebid/go-gpp" gppConstants "github.com/prebid/go-gpp/constants" - "github.com/prebid/prebid-server/gdpr" - "github.com/prebid/prebid-server/openrtb_ext" - gppPolicy "github.com/prebid/prebid-server/privacy/gpp" + "github.com/prebid/prebid-server/v2/gdpr" + "github.com/prebid/prebid-server/v2/openrtb_ext" + gppPolicy "github.com/prebid/prebid-server/v2/privacy/gpp" ) // getGDPR will pull the gdpr flag from an openrtb request diff --git a/exchange/gdpr_test.go b/exchange/gdpr_test.go index 44573b59167..0e12ec66568 100644 --- a/exchange/gdpr_test.go +++ b/exchange/gdpr_test.go @@ -7,8 +7,8 @@ import ( gpplib "github.com/prebid/go-gpp" gppConstants "github.com/prebid/go-gpp/constants" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/gdpr" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/gdpr" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/exchange/price_granularity.go b/exchange/price_granularity.go index af9e46b20fe..ee3104605d7 100644 --- a/exchange/price_granularity.go +++ b/exchange/price_granularity.go @@ -1,10 +1,11 @@ package exchange import ( - "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" "math" "strconv" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // GetPriceBucket is the externally facing function for computing CPM buckets diff --git a/exchange/price_granularity_test.go b/exchange/price_granularity_test.go index 4f9337aadc3..810dbcdf45a 100644 --- a/exchange/price_granularity_test.go +++ b/exchange/price_granularity_test.go @@ -6,8 +6,8 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/exchange/seat_non_bids.go b/exchange/seat_non_bids.go index 463a4595c85..78c1b23e3f3 100644 --- a/exchange/seat_non_bids.go +++ b/exchange/seat_non_bids.go @@ -1,8 +1,8 @@ package exchange import ( - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type nonBids struct { diff --git a/exchange/seat_non_bids_test.go b/exchange/seat_non_bids_test.go index d9f7aa88ca0..1a6b488b542 100644 --- a/exchange/seat_non_bids_test.go +++ b/exchange/seat_non_bids_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/exchange/targeting.go b/exchange/targeting.go index dbbf10041c9..d278c2f5873 100644 --- a/exchange/targeting.go +++ b/exchange/targeting.go @@ -5,7 +5,7 @@ import ( "strconv" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const MaxKeyLength = 20 diff --git a/exchange/targeting_test.go b/exchange/targeting_test.go index 25c6ea1714a..8742a4f5d2a 100644 --- a/exchange/targeting_test.go +++ b/exchange/targeting_test.go @@ -8,16 +8,16 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/gdpr" - "github.com/prebid/prebid-server/hooks/hookexecution" - metricsConfig "github.com/prebid/prebid-server/metrics/config" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/gdpr" + "github.com/prebid/prebid-server/v2/hooks/hookexecution" + metricsConfig "github.com/prebid/prebid-server/v2/metrics/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/prebid/openrtb/v19/openrtb2" "github.com/stretchr/testify/assert" diff --git a/exchange/tmax_adjustments.go b/exchange/tmax_adjustments.go index 29e732995af..55e2b18ad01 100644 --- a/exchange/tmax_adjustments.go +++ b/exchange/tmax_adjustments.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/config" ) type TmaxAdjustmentsPreprocessed struct { diff --git a/exchange/tmax_adjustments_test.go b/exchange/tmax_adjustments_test.go index 7e6a02ab81e..ce6f1736adf 100644 --- a/exchange/tmax_adjustments_test.go +++ b/exchange/tmax_adjustments_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/config" "github.com/stretchr/testify/assert" ) diff --git a/exchange/utils.go b/exchange/utils.go index 8b4774a36f4..150fac3ca53 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -15,19 +15,19 @@ import ( gppConstants "github.com/prebid/go-gpp/constants" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/firstpartydata" - "github.com/prebid/prebid-server/gdpr" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/privacy" - "github.com/prebid/prebid-server/privacy/ccpa" - "github.com/prebid/prebid-server/privacy/lmt" - "github.com/prebid/prebid-server/schain" - "github.com/prebid/prebid-server/stored_responses" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/firstpartydata" + "github.com/prebid/prebid-server/v2/gdpr" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v2/privacy/ccpa" + "github.com/prebid/prebid-server/v2/privacy/lmt" + "github.com/prebid/prebid-server/v2/schain" + "github.com/prebid/prebid-server/v2/stored_responses" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/ptrutil" ) var channelTypeMap = map[metrics.RequestType]config.ChannelType{ diff --git a/exchange/utils_test.go b/exchange/utils_test.go index 3a00c37c7b1..03184b7402d 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -8,20 +8,20 @@ import ( "sort" "testing" - "github.com/prebid/prebid-server/stored_responses" + "github.com/prebid/prebid-server/v2/stored_responses" gpplib "github.com/prebid/go-gpp" "github.com/prebid/go-gpp/constants" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/firstpartydata" - "github.com/prebid/prebid-server/gdpr" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/privacy" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/firstpartydata" + "github.com/prebid/prebid-server/v2/gdpr" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) diff --git a/experiment/adscert/inprocesssigner.go b/experiment/adscert/inprocesssigner.go index 604287f9ed6..eabd35ebb95 100644 --- a/experiment/adscert/inprocesssigner.go +++ b/experiment/adscert/inprocesssigner.go @@ -2,12 +2,13 @@ package adscert import ( "crypto/rand" + "time" + "github.com/IABTechLab/adscert/pkg/adscert/api" "github.com/IABTechLab/adscert/pkg/adscert/discovery" "github.com/IABTechLab/adscert/pkg/adscert/signatory" "github.com/benbjohnson/clock" - "github.com/prebid/prebid-server/config" - "time" + "github.com/prebid/prebid-server/v2/config" ) // inProcessSigner holds the signatory to add adsCert header to requests using in process go library diff --git a/experiment/adscert/remotesigner.go b/experiment/adscert/remotesigner.go index 3c9479560b2..d23dad201d3 100644 --- a/experiment/adscert/remotesigner.go +++ b/experiment/adscert/remotesigner.go @@ -2,12 +2,13 @@ package adscert import ( "fmt" + "time" + "github.com/IABTechLab/adscert/pkg/adscert/api" "github.com/IABTechLab/adscert/pkg/adscert/signatory" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/config" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - "time" ) // remoteSigner holds the signatory to add adsCert header to requests using remote signing server diff --git a/experiment/adscert/signer.go b/experiment/adscert/signer.go index 08b3f655fa2..f060f957149 100644 --- a/experiment/adscert/signer.go +++ b/experiment/adscert/signer.go @@ -2,10 +2,11 @@ package adscert import ( "fmt" + "github.com/IABTechLab/adscert/pkg/adscert/api" "github.com/IABTechLab/adscert/pkg/adscert/logger" "github.com/IABTechLab/adscert/pkg/adscert/signatory" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/config" ) const SignHeader = "X-Ads-Cert-Auth" diff --git a/experiment/adscert/signer_test.go b/experiment/adscert/signer_test.go index d6d02175d95..fceb2e5c79c 100644 --- a/experiment/adscert/signer_test.go +++ b/experiment/adscert/signer_test.go @@ -2,10 +2,11 @@ package adscert import ( "errors" + "testing" + "github.com/IABTechLab/adscert/pkg/adscert/api" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/config" "github.com/stretchr/testify/assert" - "testing" ) func TestNilSigner(t *testing.T) { diff --git a/firstpartydata/extmerger.go b/firstpartydata/extmerger.go index 119fa8a4c3c..f3196bea996 100644 --- a/firstpartydata/extmerger.go +++ b/firstpartydata/extmerger.go @@ -5,7 +5,7 @@ import ( "errors" "fmt" - "github.com/prebid/prebid-server/util/sliceutil" + "github.com/prebid/prebid-server/v2/util/sliceutil" jsonpatch "gopkg.in/evanphx/json-patch.v4" ) diff --git a/firstpartydata/extmerger_test.go b/firstpartydata/extmerger_test.go index 784163ac313..4107b0d1144 100644 --- a/firstpartydata/extmerger_test.go +++ b/firstpartydata/extmerger_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/util/sliceutil" + "github.com/prebid/prebid-server/v2/util/sliceutil" "github.com/stretchr/testify/assert" ) diff --git a/firstpartydata/first_party_data.go b/firstpartydata/first_party_data.go index b23ba576fcf..8e482ce700b 100644 --- a/firstpartydata/first_party_data.go +++ b/firstpartydata/first_party_data.go @@ -7,11 +7,11 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" jsonpatch "gopkg.in/evanphx/json-patch.v4" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/ortb" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/ortb" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/ptrutil" ) const ( diff --git a/firstpartydata/first_party_data_test.go b/firstpartydata/first_party_data_test.go index 61369738bf3..aa00c981fa7 100644 --- a/firstpartydata/first_party_data_test.go +++ b/firstpartydata/first_party_data_test.go @@ -8,9 +8,9 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/floors/enforce.go b/floors/enforce.go index 9318c9d278e..e1f4d8d015b 100644 --- a/floors/enforce.go +++ b/floors/enforce.go @@ -6,10 +6,10 @@ import ( "math/rand" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // Enforce does floors enforcement for bids from all bidders based on floors provided in request, account level floors config diff --git a/floors/enforce_test.go b/floors/enforce_test.go index 725ac22b193..085506c3411 100644 --- a/floors/enforce_test.go +++ b/floors/enforce_test.go @@ -7,11 +7,11 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/floors/floors.go b/floors/floors.go index 52591915058..c1e930298ac 100644 --- a/floors/floors.go +++ b/floors/floors.go @@ -5,9 +5,9 @@ import ( "math" "math/rand" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type Price struct { diff --git a/floors/floors_test.go b/floors/floors_test.go index b3002c2f155..56b21a1a209 100644 --- a/floors/floors_test.go +++ b/floors/floors_test.go @@ -6,10 +6,10 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/floors/rule.go b/floors/rule.go index f5f74cb6acf..db12719c337 100644 --- a/floors/rule.go +++ b/floors/rule.go @@ -9,8 +9,8 @@ import ( "github.com/golang/glog" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const ( diff --git a/floors/rule_test.go b/floors/rule_test.go index 7c484a7c95f..1e75956243d 100644 --- a/floors/rule_test.go +++ b/floors/rule_test.go @@ -6,8 +6,8 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/floors/validate.go b/floors/validate.go index 5624735c852..5dd843b13e0 100644 --- a/floors/validate.go +++ b/floors/validate.go @@ -4,8 +4,8 @@ import ( "fmt" "strings" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) var validSchemaDimensions = map[string]struct{}{ diff --git a/floors/validate_test.go b/floors/validate_test.go index 96dad819e06..59d08afc5c0 100644 --- a/floors/validate_test.go +++ b/floors/validate_test.go @@ -5,8 +5,8 @@ import ( "fmt" "testing" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/aggregated_config.go b/gdpr/aggregated_config.go index bbfb503225d..4bd1533de0f 100644 --- a/gdpr/aggregated_config.go +++ b/gdpr/aggregated_config.go @@ -3,8 +3,8 @@ package gdpr import ( "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // TCF2ConfigReader is an interface to access TCF2 configurations diff --git a/gdpr/aggregated_config_test.go b/gdpr/aggregated_config_test.go index bf2d3bbb8f8..54d1c901853 100644 --- a/gdpr/aggregated_config_test.go +++ b/gdpr/aggregated_config_test.go @@ -5,8 +5,8 @@ import ( "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/basic_enforcement.go b/gdpr/basic_enforcement.go index f4559c4643d..322bb30986f 100644 --- a/gdpr/basic_enforcement.go +++ b/gdpr/basic_enforcement.go @@ -2,7 +2,7 @@ package gdpr import ( tcf2 "github.com/prebid/go-gdpr/vendorconsent/tcf2" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // BasicEnforcement determines if legal basis is satisfied for a given purpose and bidder using diff --git a/gdpr/basic_enforcement_test.go b/gdpr/basic_enforcement_test.go index c49e59ea595..06472618a83 100644 --- a/gdpr/basic_enforcement_test.go +++ b/gdpr/basic_enforcement_test.go @@ -6,7 +6,7 @@ import ( "github.com/prebid/go-gdpr/consentconstants" "github.com/prebid/go-gdpr/vendorconsent" tcf2 "github.com/prebid/go-gdpr/vendorconsent/tcf2" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/full_enforcement.go b/gdpr/full_enforcement.go index eefa28d5499..c872e13e454 100644 --- a/gdpr/full_enforcement.go +++ b/gdpr/full_enforcement.go @@ -2,7 +2,7 @@ package gdpr import ( tcf2 "github.com/prebid/go-gdpr/vendorconsent/tcf2" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const ( diff --git a/gdpr/full_enforcement_test.go b/gdpr/full_enforcement_test.go index 4a859ecaabb..dac9d7ef76a 100644 --- a/gdpr/full_enforcement_test.go +++ b/gdpr/full_enforcement_test.go @@ -8,8 +8,8 @@ import ( tcf2 "github.com/prebid/go-gdpr/vendorconsent/tcf2" "github.com/prebid/go-gdpr/vendorlist" "github.com/prebid/go-gdpr/vendorlist2" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/gdpr.go b/gdpr/gdpr.go index db6aa125383..1b4f6cb4680 100644 --- a/gdpr/gdpr.go +++ b/gdpr/gdpr.go @@ -3,8 +3,8 @@ package gdpr import ( "context" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type Permissions interface { diff --git a/gdpr/gdpr_test.go b/gdpr/gdpr_test.go index 1e56c5fdede..9604e24f4f0 100644 --- a/gdpr/gdpr_test.go +++ b/gdpr/gdpr_test.go @@ -6,8 +6,8 @@ import ( "github.com/prebid/go-gdpr/consentconstants" "github.com/prebid/go-gdpr/vendorlist" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/impl.go b/gdpr/impl.go index cc88a1fd3c6..fd3ad2b2dd9 100644 --- a/gdpr/impl.go +++ b/gdpr/impl.go @@ -6,7 +6,7 @@ import ( "github.com/prebid/go-gdpr/api" "github.com/prebid/go-gdpr/consentconstants" tcf2 "github.com/prebid/go-gdpr/vendorconsent/tcf2" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const noBidder openrtb_ext.BidderName = "" diff --git a/gdpr/impl_test.go b/gdpr/impl_test.go index 835a580f6e2..fc3d69d9c57 100644 --- a/gdpr/impl_test.go +++ b/gdpr/impl_test.go @@ -9,8 +9,8 @@ import ( "github.com/prebid/go-gdpr/consentconstants" "github.com/prebid/go-gdpr/vendorlist" "github.com/prebid/go-gdpr/vendorlist2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/purpose_config.go b/gdpr/purpose_config.go index 015f23269ef..09edef94384 100644 --- a/gdpr/purpose_config.go +++ b/gdpr/purpose_config.go @@ -2,8 +2,8 @@ package gdpr import ( "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // purposeConfig represents all of the config info selected from the host and account configs for diff --git a/gdpr/purpose_config_test.go b/gdpr/purpose_config_test.go index e80733cc8ca..4837b62a2aa 100644 --- a/gdpr/purpose_config_test.go +++ b/gdpr/purpose_config_test.go @@ -3,7 +3,7 @@ package gdpr import ( "testing" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/purpose_enforcer.go b/gdpr/purpose_enforcer.go index c8e76f988aa..4a138e76cf8 100644 --- a/gdpr/purpose_enforcer.go +++ b/gdpr/purpose_enforcer.go @@ -4,8 +4,8 @@ import ( "github.com/prebid/go-gdpr/api" "github.com/prebid/go-gdpr/consentconstants" tcf2 "github.com/prebid/go-gdpr/vendorconsent/tcf2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // PurposeEnforcer represents the enforcement strategy for determining if legal basis is achieved for a purpose diff --git a/gdpr/purpose_enforcer_test.go b/gdpr/purpose_enforcer_test.go index ea2075d9c65..ed1176b12f3 100644 --- a/gdpr/purpose_enforcer_test.go +++ b/gdpr/purpose_enforcer_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/signal.go b/gdpr/signal.go index ed7fe1dd8ea..3d2e4de1251 100644 --- a/gdpr/signal.go +++ b/gdpr/signal.go @@ -3,7 +3,7 @@ package gdpr import ( "strconv" - "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/v2/errortypes" ) type Signal int diff --git a/gdpr/vendorlist-fetching.go b/gdpr/vendorlist-fetching.go index da6bdbae415..64424f5ee69 100644 --- a/gdpr/vendorlist-fetching.go +++ b/gdpr/vendorlist-fetching.go @@ -14,7 +14,7 @@ import ( "github.com/prebid/go-gdpr/api" "github.com/prebid/go-gdpr/vendorlist" "github.com/prebid/go-gdpr/vendorlist2" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/config" "golang.org/x/net/context/ctxhttp" ) diff --git a/gdpr/vendorlist-fetching_test.go b/gdpr/vendorlist-fetching_test.go index b8c73bbf9a4..98dc4ba5aa3 100644 --- a/gdpr/vendorlist-fetching_test.go +++ b/gdpr/vendorlist-fetching_test.go @@ -11,8 +11,8 @@ import ( "github.com/prebid/go-gdpr/api" "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) func TestFetcherDynamicLoadListExists(t *testing.T) { diff --git a/go.mod b/go.mod index e52946fbe1e..912cdaa2aad 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/prebid/prebid-server +module github.com/prebid/prebid-server/v2 go 1.20 diff --git a/hooks/empty_plan.go b/hooks/empty_plan.go index 01e01843324..514d3824898 100644 --- a/hooks/empty_plan.go +++ b/hooks/empty_plan.go @@ -1,8 +1,8 @@ package hooks import ( - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/hooks/hookstage" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/hooks/hookstage" ) // EmptyPlanBuilder implements the ExecutionPlanBuilder interface diff --git a/hooks/hookanalytics/analytics_test.go b/hooks/hookanalytics/analytics_test.go index abf5e7f2ddc..27584cf0d39 100644 --- a/hooks/hookanalytics/analytics_test.go +++ b/hooks/hookanalytics/analytics_test.go @@ -3,7 +3,7 @@ package hookanalytics import ( "testing" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/hooks/hookexecution/context.go b/hooks/hookexecution/context.go index 5f7cc3ab188..0817078137f 100644 --- a/hooks/hookexecution/context.go +++ b/hooks/hookexecution/context.go @@ -4,8 +4,8 @@ import ( "sync" "github.com/golang/glog" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/hooks/hookstage" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/hooks/hookstage" ) // executionContext holds information passed to module's hook during hook execution. diff --git a/hooks/hookexecution/enricher.go b/hooks/hookexecution/enricher.go index c3dd5a23339..ff7f8dd562e 100644 --- a/hooks/hookexecution/enricher.go +++ b/hooks/hookexecution/enricher.go @@ -5,8 +5,8 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/util/jsonutil" jsonpatch "gopkg.in/evanphx/json-patch.v4" ) diff --git a/hooks/hookexecution/enricher_test.go b/hooks/hookexecution/enricher_test.go index 24f0f1c1d45..e0732dfe13b 100644 --- a/hooks/hookexecution/enricher_test.go +++ b/hooks/hookexecution/enricher_test.go @@ -7,10 +7,10 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/hooks/hookanalytics" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/hooks/hookanalytics" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/hooks/hookexecution/errors.go b/hooks/hookexecution/errors.go index b1cf912ccee..1d016e26019 100644 --- a/hooks/hookexecution/errors.go +++ b/hooks/hookexecution/errors.go @@ -3,7 +3,7 @@ package hookexecution import ( "fmt" - "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/v2/errortypes" ) // TimeoutError indicates exceeding of the max execution time allotted for hook. diff --git a/hooks/hookexecution/execution.go b/hooks/hookexecution/execution.go index 18c927896b9..90ee9b46a9c 100644 --- a/hooks/hookexecution/execution.go +++ b/hooks/hookexecution/execution.go @@ -7,9 +7,9 @@ import ( "sync" "time" - "github.com/prebid/prebid-server/hooks" - "github.com/prebid/prebid-server/hooks/hookstage" - "github.com/prebid/prebid-server/metrics" + "github.com/prebid/prebid-server/v2/hooks" + "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v2/metrics" ) type hookResponse[T any] struct { diff --git a/hooks/hookexecution/executor.go b/hooks/hookexecution/executor.go index 5074d4b9ab9..dd6953fb73c 100644 --- a/hooks/hookexecution/executor.go +++ b/hooks/hookexecution/executor.go @@ -6,13 +6,13 @@ import ( "sync" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/hooks" - "github.com/prebid/prebid-server/hooks/hookstage" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/hooks" + "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const ( diff --git a/hooks/hookexecution/executor_test.go b/hooks/hookexecution/executor_test.go index 68b990bb595..6f50e089b40 100644 --- a/hooks/hookexecution/executor_test.go +++ b/hooks/hookexecution/executor_test.go @@ -9,15 +9,15 @@ import ( "time" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/hooks" - "github.com/prebid/prebid-server/hooks/hookanalytics" - "github.com/prebid/prebid-server/hooks/hookstage" - "github.com/prebid/prebid-server/metrics" - metricsConfig "github.com/prebid/prebid-server/metrics/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/hooks" + "github.com/prebid/prebid-server/v2/hooks/hookanalytics" + "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v2/metrics" + metricsConfig "github.com/prebid/prebid-server/v2/metrics/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) diff --git a/hooks/hookexecution/mocks_test.go b/hooks/hookexecution/mocks_test.go index ff543c38a07..420a44e8fe9 100644 --- a/hooks/hookexecution/mocks_test.go +++ b/hooks/hookexecution/mocks_test.go @@ -5,8 +5,8 @@ import ( "errors" "time" - "github.com/prebid/prebid-server/hooks/hookstage" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type mockUpdateHeaderEntrypointHook struct{} diff --git a/hooks/hookexecution/outcome.go b/hooks/hookexecution/outcome.go index 3eeb7bcef5e..ff8bf1e973e 100644 --- a/hooks/hookexecution/outcome.go +++ b/hooks/hookexecution/outcome.go @@ -3,7 +3,7 @@ package hookexecution import ( "time" - "github.com/prebid/prebid-server/hooks/hookanalytics" + "github.com/prebid/prebid-server/v2/hooks/hookanalytics" ) // Status indicates the result of hook execution. diff --git a/hooks/hookexecution/test_utils.go b/hooks/hookexecution/test_utils.go index 2a604d851f5..32ae9fd7a22 100644 --- a/hooks/hookexecution/test_utils.go +++ b/hooks/hookexecution/test_utils.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/hooks/hookstage/allprocessedbidresponses.go b/hooks/hookstage/allprocessedbidresponses.go index 3f90c5624ee..233a68b6efd 100644 --- a/hooks/hookstage/allprocessedbidresponses.go +++ b/hooks/hookstage/allprocessedbidresponses.go @@ -3,8 +3,8 @@ package hookstage import ( "context" - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // AllProcessedBidResponses hooks are invoked over a list of all diff --git a/hooks/hookstage/invocation.go b/hooks/hookstage/invocation.go index 7f465382b20..73b210957e2 100644 --- a/hooks/hookstage/invocation.go +++ b/hooks/hookstage/invocation.go @@ -3,7 +3,7 @@ package hookstage import ( "encoding/json" - "github.com/prebid/prebid-server/hooks/hookanalytics" + "github.com/prebid/prebid-server/v2/hooks/hookanalytics" ) // HookResult represents the result of execution the concrete hook instance. diff --git a/hooks/hookstage/processedauctionrequest.go b/hooks/hookstage/processedauctionrequest.go index fe06bc6fdbd..9ee06fabb2f 100644 --- a/hooks/hookstage/processedauctionrequest.go +++ b/hooks/hookstage/processedauctionrequest.go @@ -3,7 +3,7 @@ package hookstage import ( "context" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // ProcessedAuctionRequest hooks are invoked after the request is parsed diff --git a/hooks/hookstage/rawbidderresponse.go b/hooks/hookstage/rawbidderresponse.go index d450d6d0681..7d08a7d2e02 100644 --- a/hooks/hookstage/rawbidderresponse.go +++ b/hooks/hookstage/rawbidderresponse.go @@ -3,7 +3,7 @@ package hookstage import ( "context" - "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/v2/adapters" ) // RawBidderResponse hooks are invoked for each bidder participating in auction. diff --git a/hooks/hookstage/rawbidderresponse_mutations.go b/hooks/hookstage/rawbidderresponse_mutations.go index 61c0de10bde..efab874fa15 100644 --- a/hooks/hookstage/rawbidderresponse_mutations.go +++ b/hooks/hookstage/rawbidderresponse_mutations.go @@ -3,7 +3,7 @@ package hookstage import ( "errors" - "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/v2/adapters" ) func (c *ChangeSet[T]) RawBidderResponse() ChangeSetRawBidderResponse[T] { diff --git a/hooks/plan.go b/hooks/plan.go index c6fda959762..a3a0e9af661 100644 --- a/hooks/plan.go +++ b/hooks/plan.go @@ -4,8 +4,8 @@ import ( "time" "github.com/golang/glog" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/hooks/hookstage" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/hooks/hookstage" ) type Stage string diff --git a/hooks/plan_test.go b/hooks/plan_test.go index 8af49b42e17..064403cb8cf 100644 --- a/hooks/plan_test.go +++ b/hooks/plan_test.go @@ -5,9 +5,9 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/hooks/hookstage" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/hooks/repo.go b/hooks/repo.go index 40276701b34..3d8db581bda 100644 --- a/hooks/repo.go +++ b/hooks/repo.go @@ -3,7 +3,7 @@ package hooks import ( "fmt" - "github.com/prebid/prebid-server/hooks/hookstage" + "github.com/prebid/prebid-server/v2/hooks/hookstage" ) // HookRepository is the interface that exposes methods diff --git a/hooks/repo_test.go b/hooks/repo_test.go index ae523c98773..1ffbf0bfbed 100644 --- a/hooks/repo_test.go +++ b/hooks/repo_test.go @@ -5,7 +5,7 @@ import ( "fmt" "testing" - "github.com/prebid/prebid-server/hooks/hookstage" + "github.com/prebid/prebid-server/v2/hooks/hookstage" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/macros/provider.go b/macros/provider.go index 0b0fc0de454..3cae540e22a 100644 --- a/macros/provider.go +++ b/macros/provider.go @@ -5,8 +5,8 @@ import ( "strconv" "time" - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const ( diff --git a/macros/provider_test.go b/macros/provider_test.go index b6465a7f2e6..ee9663e3269 100644 --- a/macros/provider_test.go +++ b/macros/provider_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/macros/string_index_based_replacer_test.go b/macros/string_index_based_replacer_test.go index 97379a6d965..c9a05a83df4 100644 --- a/macros/string_index_based_replacer_test.go +++ b/macros/string_index_based_replacer_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/exchange/entities" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/main.go b/main.go index a83266665f0..e72f02f1f0e 100644 --- a/main.go +++ b/main.go @@ -8,12 +8,12 @@ import ( "runtime" "time" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/router" - "github.com/prebid/prebid-server/server" - "github.com/prebid/prebid-server/util/task" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/router" + "github.com/prebid/prebid-server/v2/server" + "github.com/prebid/prebid-server/v2/util/task" "github.com/golang/glog" "github.com/spf13/viper" diff --git a/main_test.go b/main_test.go index 25812ba96ab..79ae373d473 100644 --- a/main_test.go +++ b/main_test.go @@ -4,7 +4,7 @@ import ( "os" "testing" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/config" "github.com/stretchr/testify/assert" "github.com/spf13/viper" diff --git a/metrics/config/metrics.go b/metrics/config/metrics.go index d5cb00344ec..7ed387512fd 100644 --- a/metrics/config/metrics.go +++ b/metrics/config/metrics.go @@ -3,10 +3,10 @@ package config import ( "time" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/metrics" - prometheusmetrics "github.com/prebid/prebid-server/metrics/prometheus" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/metrics" + prometheusmetrics "github.com/prebid/prebid-server/v2/metrics/prometheus" + "github.com/prebid/prebid-server/v2/openrtb_ext" gometrics "github.com/rcrowley/go-metrics" influxdb "github.com/vrischmann/go-metrics-influxdb" ) diff --git a/metrics/config/metrics_test.go b/metrics/config/metrics_test.go index 1eae1a25545..5badc348e61 100644 --- a/metrics/config/metrics_test.go +++ b/metrics/config/metrics_test.go @@ -6,9 +6,9 @@ import ( "testing" "time" - mainConfig "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" + mainConfig "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" gometrics "github.com/rcrowley/go-metrics" ) diff --git a/metrics/go_metrics.go b/metrics/go_metrics.go index 13cc022c9c8..5bc4ab965f6 100644 --- a/metrics/go_metrics.go +++ b/metrics/go_metrics.go @@ -7,8 +7,8 @@ import ( "time" "github.com/golang/glog" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" metrics "github.com/rcrowley/go-metrics" ) diff --git a/metrics/go_metrics_test.go b/metrics/go_metrics_test.go index 08ee65f52ac..05529220f16 100644 --- a/metrics/go_metrics_test.go +++ b/metrics/go_metrics_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" metrics "github.com/rcrowley/go-metrics" "github.com/stretchr/testify/assert" ) diff --git a/metrics/metrics.go b/metrics/metrics.go index 0c3025bd296..7d3dc819341 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -3,7 +3,7 @@ package metrics import ( "time" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // Labels defines the labels that can be attached to the metrics. diff --git a/metrics/metrics_mock.go b/metrics/metrics_mock.go index eb092f0d972..ef9fdcaf7a4 100644 --- a/metrics/metrics_mock.go +++ b/metrics/metrics_mock.go @@ -3,7 +3,7 @@ package metrics import ( "time" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/mock" ) diff --git a/metrics/prometheus/preload.go b/metrics/prometheus/preload.go index db40feabbd8..a4a70017355 100644 --- a/metrics/prometheus/preload.go +++ b/metrics/prometheus/preload.go @@ -1,8 +1,8 @@ package prometheusmetrics import ( - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/prometheus/client_golang/prometheus" ) diff --git a/metrics/prometheus/prometheus.go b/metrics/prometheus/prometheus.go index bd63997f0d2..6bd30544662 100644 --- a/metrics/prometheus/prometheus.go +++ b/metrics/prometheus/prometheus.go @@ -6,9 +6,9 @@ import ( "strings" "time" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/prometheus/client_golang/prometheus" promCollector "github.com/prometheus/client_golang/prometheus/collectors" ) diff --git a/metrics/prometheus/prometheus_test.go b/metrics/prometheus/prometheus_test.go index a2b0e84d2ea..a74c8b6c0fa 100644 --- a/metrics/prometheus/prometheus_test.go +++ b/metrics/prometheus/prometheus_test.go @@ -5,9 +5,9 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/prometheus/client_golang/prometheus" dto "github.com/prometheus/client_model/go" "github.com/stretchr/testify/assert" diff --git a/modules/builder.go b/modules/builder.go index ffb814e6407..e5d04e149af 100644 --- a/modules/builder.go +++ b/modules/builder.go @@ -1,7 +1,7 @@ package modules import ( - prebidOrtb2blocking "github.com/prebid/prebid-server/modules/prebid/ortb2blocking" + prebidOrtb2blocking "github.com/prebid/prebid-server/v2/modules/prebid/ortb2blocking" ) // builders returns mapping between module name and its builder diff --git a/modules/generator/builder.tmpl b/modules/generator/builder.tmpl index f89cc21c87f..b7b78103dbe 100644 --- a/modules/generator/builder.tmpl +++ b/modules/generator/builder.tmpl @@ -3,7 +3,7 @@ package modules {{if .}} import ( {{- range .}} - {{.Vendor}}{{.Module | Title}} "github.com/prebid/prebid-server/modules/{{.Vendor}}/{{.Module}}" + {{.Vendor}}{{.Module | Title}} "github.com/prebid/prebid-server/v2/modules/{{.Vendor}}/{{.Module}}" {{- end}} ) {{end}} diff --git a/modules/helpers.go b/modules/helpers.go index c7fe9f73f31..10890743691 100644 --- a/modules/helpers.go +++ b/modules/helpers.go @@ -4,8 +4,8 @@ import ( "fmt" "strings" - "github.com/prebid/prebid-server/hooks" - "github.com/prebid/prebid-server/hooks/hookstage" + "github.com/prebid/prebid-server/v2/hooks" + "github.com/prebid/prebid-server/v2/hooks/hookstage" ) var moduleReplacer = strings.NewReplacer(".", "_", "-", "_") diff --git a/modules/modules.go b/modules/modules.go index 4e60a9eda32..f3ccd6b1ece 100644 --- a/modules/modules.go +++ b/modules/modules.go @@ -5,10 +5,10 @@ import ( "fmt" "github.com/golang/glog" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/hooks" - "github.com/prebid/prebid-server/modules/moduledeps" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/hooks" + "github.com/prebid/prebid-server/v2/modules/moduledeps" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) //go:generate go run ./generator/buildergen.go diff --git a/modules/modules_test.go b/modules/modules_test.go index f88a48a2c44..008c1e75c51 100644 --- a/modules/modules_test.go +++ b/modules/modules_test.go @@ -9,10 +9,10 @@ import ( "net/http" "testing" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/hooks" - "github.com/prebid/prebid-server/hooks/hookstage" - "github.com/prebid/prebid-server/modules/moduledeps" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/hooks" + "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v2/modules/moduledeps" "github.com/stretchr/testify/assert" ) diff --git a/modules/prebid/ortb2blocking/analytics.go b/modules/prebid/ortb2blocking/analytics.go index 4026b6722b9..1309858c7b6 100644 --- a/modules/prebid/ortb2blocking/analytics.go +++ b/modules/prebid/ortb2blocking/analytics.go @@ -1,8 +1,8 @@ package ortb2blocking import ( - "github.com/prebid/prebid-server/hooks/hookanalytics" - "github.com/prebid/prebid-server/hooks/hookstage" + "github.com/prebid/prebid-server/v2/hooks/hookanalytics" + "github.com/prebid/prebid-server/v2/hooks/hookstage" ) const enforceBlockingTag = "enforce_blocking" diff --git a/modules/prebid/ortb2blocking/config.go b/modules/prebid/ortb2blocking/config.go index 74841eb5b33..4b832cb1977 100644 --- a/modules/prebid/ortb2blocking/config.go +++ b/modules/prebid/ortb2blocking/config.go @@ -5,7 +5,7 @@ import ( "fmt" "github.com/prebid/openrtb/v19/adcom1" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) func newConfig(data json.RawMessage) (config, error) { diff --git a/modules/prebid/ortb2blocking/hook_bidderrequest.go b/modules/prebid/ortb2blocking/hook_bidderrequest.go index 8f7ce42021c..0bd990eb50c 100644 --- a/modules/prebid/ortb2blocking/hook_bidderrequest.go +++ b/modules/prebid/ortb2blocking/hook_bidderrequest.go @@ -7,9 +7,9 @@ import ( "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/hooks/hookexecution" - "github.com/prebid/prebid-server/hooks/hookstage" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/hooks/hookexecution" + "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) func handleBidderRequestHook( diff --git a/modules/prebid/ortb2blocking/hook_raw_bidder_response.go b/modules/prebid/ortb2blocking/hook_raw_bidder_response.go index 1c51256211b..615ceda9e04 100644 --- a/modules/prebid/ortb2blocking/hook_raw_bidder_response.go +++ b/modules/prebid/ortb2blocking/hook_raw_bidder_response.go @@ -7,9 +7,9 @@ import ( "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/hooks/hookexecution" - "github.com/prebid/prebid-server/hooks/hookstage" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/hooks/hookexecution" + "github.com/prebid/prebid-server/v2/hooks/hookstage" ) func handleRawBidderResponseHook( diff --git a/modules/prebid/ortb2blocking/module.go b/modules/prebid/ortb2blocking/module.go index 7386aa62bad..93ca15ff31e 100644 --- a/modules/prebid/ortb2blocking/module.go +++ b/modules/prebid/ortb2blocking/module.go @@ -5,8 +5,8 @@ import ( "encoding/json" "github.com/prebid/openrtb/v19/adcom1" - "github.com/prebid/prebid-server/hooks/hookstage" - "github.com/prebid/prebid-server/modules/moduledeps" + "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v2/modules/moduledeps" ) func Builder(_ json.RawMessage, _ moduledeps.ModuleDeps) (interface{}, error) { diff --git a/modules/prebid/ortb2blocking/module_test.go b/modules/prebid/ortb2blocking/module_test.go index ecae5ca8c0a..b4499a4bbfb 100644 --- a/modules/prebid/ortb2blocking/module_test.go +++ b/modules/prebid/ortb2blocking/module_test.go @@ -8,11 +8,11 @@ import ( "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/adapters" - "github.com/prebid/prebid-server/hooks/hookanalytics" - "github.com/prebid/prebid-server/hooks/hookexecution" - "github.com/prebid/prebid-server/hooks/hookstage" - "github.com/prebid/prebid-server/modules/moduledeps" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/hooks/hookanalytics" + "github.com/prebid/prebid-server/v2/hooks/hookexecution" + "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v2/modules/moduledeps" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/convert_down_test.go b/openrtb_ext/convert_down_test.go index 3b78337df8b..a72ba3a48ad 100644 --- a/openrtb_ext/convert_down_test.go +++ b/openrtb_ext/convert_down_test.go @@ -6,7 +6,7 @@ import ( "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/v2/errortypes" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/deal_tier.go b/openrtb_ext/deal_tier.go index df386916b77..b1d8ee11bc2 100644 --- a/openrtb_ext/deal_tier.go +++ b/openrtb_ext/deal_tier.go @@ -2,7 +2,7 @@ package openrtb_ext import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) // DealTier defines the configuration of a deal tier. diff --git a/openrtb_ext/deal_tier_test.go b/openrtb_ext/deal_tier_test.go index dabecf6a9e7..b8607748ca9 100644 --- a/openrtb_ext/deal_tier_test.go +++ b/openrtb_ext/deal_tier_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/v2/errortypes" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/device.go b/openrtb_ext/device.go index 8c5b36733b9..0888d06160f 100644 --- a/openrtb_ext/device.go +++ b/openrtb_ext/device.go @@ -6,7 +6,7 @@ import ( "strconv" "github.com/buger/jsonparser" - "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/v2/errortypes" ) // PrebidExtKey represents the prebid extension key used in requests diff --git a/openrtb_ext/device_test.go b/openrtb_ext/device_test.go index 86a0e1d7ff2..f40e9650061 100644 --- a/openrtb_ext/device_test.go +++ b/openrtb_ext/device_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/imp_appnexus.go b/openrtb_ext/imp_appnexus.go index 02476d6bcf0..db949f661fd 100644 --- a/openrtb_ext/imp_appnexus.go +++ b/openrtb_ext/imp_appnexus.go @@ -5,7 +5,7 @@ import ( "fmt" "strings" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) // ExtImpAppnexus defines the contract for bidrequest.imp[i].ext.prebid.bidder.appnexus diff --git a/openrtb_ext/imp_appnexus_test.go b/openrtb_ext/imp_appnexus_test.go index a226c0d8410..9d65f3be3ad 100644 --- a/openrtb_ext/imp_appnexus_test.go +++ b/openrtb_ext/imp_appnexus_test.go @@ -3,7 +3,7 @@ package openrtb_ext import ( "testing" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/imp_freewheelssp.go b/openrtb_ext/imp_freewheelssp.go index 110f018f512..3d015d96722 100644 --- a/openrtb_ext/imp_freewheelssp.go +++ b/openrtb_ext/imp_freewheelssp.go @@ -1,7 +1,7 @@ package openrtb_ext import ( - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) type ImpExtFreewheelSSP struct { diff --git a/openrtb_ext/multibid_test.go b/openrtb_ext/multibid_test.go index a27631d6891..926ab261b0f 100644 --- a/openrtb_ext/multibid_test.go +++ b/openrtb_ext/multibid_test.go @@ -4,7 +4,7 @@ import ( "fmt" "testing" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/request.go b/openrtb_ext/request.go index 3a41fdf0dbb..1a98e34d13f 100644 --- a/openrtb_ext/request.go +++ b/openrtb_ext/request.go @@ -5,10 +5,10 @@ import ( "fmt" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/maputil" - "github.com/prebid/prebid-server/util/ptrutil" - "github.com/prebid/prebid-server/util/sliceutil" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/maputil" + "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v2/util/sliceutil" ) // FirstPartyDataExtKey defines a field name within request.ext and request.imp.ext reserved for first party data. diff --git a/openrtb_ext/request_test.go b/openrtb_ext/request_test.go index ad6a655b022..3163150e57c 100644 --- a/openrtb_ext/request_test.go +++ b/openrtb_ext/request_test.go @@ -6,8 +6,8 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/request_wrapper.go b/openrtb_ext/request_wrapper.go index 09321e5b0b3..5adc192d36f 100644 --- a/openrtb_ext/request_wrapper.go +++ b/openrtb_ext/request_wrapper.go @@ -5,10 +5,10 @@ import ( "errors" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/maputil" - "github.com/prebid/prebid-server/util/ptrutil" - "github.com/prebid/prebid-server/util/sliceutil" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/maputil" + "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v2/util/sliceutil" ) // RequestWrapper wraps the OpenRTB request to provide a storage location for unmarshalled ext fields, so they diff --git a/openrtb_ext/request_wrapper_test.go b/openrtb_ext/request_wrapper_test.go index 0127c545274..bd55c86beb2 100644 --- a/openrtb_ext/request_wrapper_test.go +++ b/openrtb_ext/request_wrapper_test.go @@ -5,8 +5,8 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/site_test.go b/openrtb_ext/site_test.go index 7a7140282f2..f6fb04c50ee 100644 --- a/openrtb_ext/site_test.go +++ b/openrtb_ext/site_test.go @@ -3,8 +3,8 @@ package openrtb_ext_test import ( "testing" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/supplyChain.go b/openrtb_ext/supplyChain.go index 6f023542dfb..0ccbd0957fa 100644 --- a/openrtb_ext/supplyChain.go +++ b/openrtb_ext/supplyChain.go @@ -2,7 +2,7 @@ package openrtb_ext import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/util/ptrutil" ) func cloneSupplyChain(schain *openrtb2.SupplyChain) *openrtb2.SupplyChain { diff --git a/openrtb_ext/supplyChain_test.go b/openrtb_ext/supplyChain_test.go index 12fd5c337fb..728fbc68cc4 100644 --- a/openrtb_ext/supplyChain_test.go +++ b/openrtb_ext/supplyChain_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/ortb/clone.go b/ortb/clone.go index c0e5a4ddada..0dd210a986e 100644 --- a/ortb/clone.go +++ b/ortb/clone.go @@ -2,8 +2,8 @@ package ortb import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/util/ptrutil" - "github.com/prebid/prebid-server/util/sliceutil" + "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v2/util/sliceutil" ) func CloneApp(s *openrtb2.App) *openrtb2.App { diff --git a/ortb/clone_test.go b/ortb/clone_test.go index 24e43bda1e5..50dd94057ee 100644 --- a/ortb/clone_test.go +++ b/ortb/clone_test.go @@ -7,7 +7,7 @@ import ( "github.com/prebid/openrtb/v19/adcom1" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/ortb/default.go b/ortb/default.go index cd9d8c24759..c5e43e2e770 100644 --- a/ortb/default.go +++ b/ortb/default.go @@ -1,8 +1,8 @@ package ortb import ( - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/ptrutil" ) const ( diff --git a/ortb/default_test.go b/ortb/default_test.go index 8bda02ef4f5..2d99da4bec2 100644 --- a/ortb/default_test.go +++ b/ortb/default_test.go @@ -8,10 +8,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/ptrutil" ) func TestSetDefaults(t *testing.T) { diff --git a/pbs/usersync.go b/pbs/usersync.go index a5b49f6db03..bfe12689177 100644 --- a/pbs/usersync.go +++ b/pbs/usersync.go @@ -10,9 +10,9 @@ import ( "github.com/golang/glog" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/server/ssl" - "github.com/prebid/prebid-server/usersync" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/server/ssl" + "github.com/prebid/prebid-server/v2/usersync" ) // Recaptcha code from https://github.com/haisum/recaptcha/blob/master/recaptcha.go diff --git a/prebid_cache_client/client.go b/prebid_cache_client/client.go index 872420001ea..fb3fb24d9cc 100644 --- a/prebid_cache_client/client.go +++ b/prebid_cache_client/client.go @@ -12,8 +12,8 @@ import ( "strings" "time" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/metrics" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/metrics" "github.com/buger/jsonparser" "github.com/golang/glog" diff --git a/prebid_cache_client/client_test.go b/prebid_cache_client/client_test.go index f20d3c7829f..f3ee3065ff1 100644 --- a/prebid_cache_client/client_test.go +++ b/prebid_cache_client/client_test.go @@ -10,10 +10,10 @@ import ( "strconv" "testing" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/metrics" - metricsConf "github.com/prebid/prebid-server/metrics/config" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/metrics" + metricsConf "github.com/prebid/prebid-server/v2/metrics/config" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" diff --git a/privacy/activitycontrol.go b/privacy/activitycontrol.go index 9d6668b3e44..1bb3fc6cdf6 100644 --- a/privacy/activitycontrol.go +++ b/privacy/activitycontrol.go @@ -1,8 +1,8 @@ package privacy import ( - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type ActivityResult int diff --git a/privacy/activitycontrol_test.go b/privacy/activitycontrol_test.go index 743888df029..b8b06ee8886 100644 --- a/privacy/activitycontrol_test.go +++ b/privacy/activitycontrol_test.go @@ -3,9 +3,9 @@ package privacy import ( "testing" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/privacy/ccpa/consentwriter.go b/privacy/ccpa/consentwriter.go index 1d65a272f90..339eb3438fb 100644 --- a/privacy/ccpa/consentwriter.go +++ b/privacy/ccpa/consentwriter.go @@ -2,7 +2,7 @@ package ccpa import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // ConsentWriter implements the old PolicyWriter interface for CCPA. diff --git a/privacy/ccpa/consentwriter_test.go b/privacy/ccpa/consentwriter_test.go index 015f1328f61..e8414a8e2f5 100644 --- a/privacy/ccpa/consentwriter_test.go +++ b/privacy/ccpa/consentwriter_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/privacy/ccpa/parsedpolicy.go b/privacy/ccpa/parsedpolicy.go index 7b9c2d1fa7c..056cc99ee1b 100644 --- a/privacy/ccpa/parsedpolicy.go +++ b/privacy/ccpa/parsedpolicy.go @@ -4,7 +4,7 @@ import ( "errors" "fmt" - "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/v2/errortypes" ) const ( diff --git a/privacy/ccpa/policy.go b/privacy/ccpa/policy.go index fbafd8a8a2e..e5412b7d4c7 100644 --- a/privacy/ccpa/policy.go +++ b/privacy/ccpa/policy.go @@ -7,9 +7,9 @@ import ( gpplib "github.com/prebid/go-gpp" gppConstants "github.com/prebid/go-gpp/constants" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/openrtb_ext" - gppPolicy "github.com/prebid/prebid-server/privacy/gpp" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" + gppPolicy "github.com/prebid/prebid-server/v2/privacy/gpp" ) // Policy represents the CCPA regulatory information from an OpenRTB bid request. diff --git a/privacy/ccpa/policy_test.go b/privacy/ccpa/policy_test.go index 3a1433333c0..e18820b221b 100644 --- a/privacy/ccpa/policy_test.go +++ b/privacy/ccpa/policy_test.go @@ -8,7 +8,7 @@ import ( gpplib "github.com/prebid/go-gpp" gppConstants "github.com/prebid/go-gpp/constants" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/privacy/enforcement.go b/privacy/enforcement.go index 8074d96acf3..901c062ea4e 100644 --- a/privacy/enforcement.go +++ b/privacy/enforcement.go @@ -2,7 +2,7 @@ package privacy import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/config" ) // Enforcement represents the privacy policies to enforce for an OpenRTB bid request. diff --git a/privacy/gdpr/consentwriter.go b/privacy/gdpr/consentwriter.go index 00e3558fd40..25bc2bf0ca0 100644 --- a/privacy/gdpr/consentwriter.go +++ b/privacy/gdpr/consentwriter.go @@ -2,7 +2,7 @@ package gdpr import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // ConsentWriter implements the PolicyWriter interface for GDPR TCF. diff --git a/privacy/lmt/ios.go b/privacy/lmt/ios.go index 0b308a9ce32..ee08225f8c7 100644 --- a/privacy/lmt/ios.go +++ b/privacy/lmt/ios.go @@ -4,8 +4,8 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/iosutil" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/iosutil" ) var ( diff --git a/privacy/lmt/ios_test.go b/privacy/lmt/ios_test.go index 2a679bfbd99..7afaf7843e1 100644 --- a/privacy/lmt/ios_test.go +++ b/privacy/lmt/ios_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/util/iosutil" + "github.com/prebid/prebid-server/v2/util/iosutil" "github.com/stretchr/testify/assert" ) diff --git a/privacy/rule_condition_test.go b/privacy/rule_condition_test.go index bb1d81c00d2..23973bd06d0 100644 --- a/privacy/rule_condition_test.go +++ b/privacy/rule_condition_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/privacy/scrubber.go b/privacy/scrubber.go index 0cfc7cdd7f4..54941669ab9 100644 --- a/privacy/scrubber.go +++ b/privacy/scrubber.go @@ -4,10 +4,10 @@ import ( "encoding/json" "net" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/util/iputil" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/ptrutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/util/iputil" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/prebid/openrtb/v19/openrtb2" ) diff --git a/privacy/scrubber_test.go b/privacy/scrubber_test.go index 59e593fc167..299acd9eba3 100644 --- a/privacy/scrubber_test.go +++ b/privacy/scrubber_test.go @@ -2,9 +2,10 @@ package privacy import ( "encoding/json" - "github.com/prebid/prebid-server/config" "testing" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/openrtb/v19/openrtb2" "github.com/stretchr/testify/assert" ) diff --git a/router/admin.go b/router/admin.go index 29cdbbe5e23..1be7c8656da 100644 --- a/router/admin.go +++ b/router/admin.go @@ -5,9 +5,9 @@ import ( "net/http/pprof" "time" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/endpoints" - "github.com/prebid/prebid-server/version" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/endpoints" + "github.com/prebid/prebid-server/v2/version" ) func Admin(rateConverter *currency.RateConverter, rateConverterFetchingInterval time.Duration) *http.ServeMux { diff --git a/router/aspects/request_timeout_handler.go b/router/aspects/request_timeout_handler.go index 39a4341f995..7b94c96b11b 100644 --- a/router/aspects/request_timeout_handler.go +++ b/router/aspects/request_timeout_handler.go @@ -6,8 +6,8 @@ import ( "time" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/metrics" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/metrics" ) func QueuedRequestTimeout(f httprouter.Handle, reqTimeoutHeaders config.RequestTimeoutHeaders, metricsEngine metrics.MetricsEngine, requestType metrics.RequestType) httprouter.Handle { diff --git a/router/aspects/request_timeout_handler_test.go b/router/aspects/request_timeout_handler_test.go index 26e546dcd40..4ece14208e8 100644 --- a/router/aspects/request_timeout_handler_test.go +++ b/router/aspects/request_timeout_handler_test.go @@ -8,8 +8,8 @@ import ( "time" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/metrics" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/metrics" "github.com/stretchr/testify/assert" ) diff --git a/router/router.go b/router/router.go index 70b7860d661..0ee9fc7c30e 100644 --- a/router/router.go +++ b/router/router.go @@ -10,33 +10,33 @@ import ( "strings" "time" - analyticsBuild "github.com/prebid/prebid-server/analytics/build" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/currency" - "github.com/prebid/prebid-server/endpoints" - "github.com/prebid/prebid-server/endpoints/events" - infoEndpoints "github.com/prebid/prebid-server/endpoints/info" - "github.com/prebid/prebid-server/endpoints/openrtb2" - "github.com/prebid/prebid-server/errortypes" - "github.com/prebid/prebid-server/exchange" - "github.com/prebid/prebid-server/experiment/adscert" - "github.com/prebid/prebid-server/gdpr" - "github.com/prebid/prebid-server/hooks" - "github.com/prebid/prebid-server/macros" - "github.com/prebid/prebid-server/metrics" - metricsConf "github.com/prebid/prebid-server/metrics/config" - "github.com/prebid/prebid-server/modules" - "github.com/prebid/prebid-server/modules/moduledeps" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/pbs" - pbc "github.com/prebid/prebid-server/prebid_cache_client" - "github.com/prebid/prebid-server/router/aspects" - "github.com/prebid/prebid-server/server/ssl" - storedRequestsConf "github.com/prebid/prebid-server/stored_requests/config" - "github.com/prebid/prebid-server/usersync" - "github.com/prebid/prebid-server/util/jsonutil" - "github.com/prebid/prebid-server/util/uuidutil" - "github.com/prebid/prebid-server/version" + analyticsBuild "github.com/prebid/prebid-server/v2/analytics/build" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v2/endpoints" + "github.com/prebid/prebid-server/v2/endpoints/events" + infoEndpoints "github.com/prebid/prebid-server/v2/endpoints/info" + "github.com/prebid/prebid-server/v2/endpoints/openrtb2" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/exchange" + "github.com/prebid/prebid-server/v2/experiment/adscert" + "github.com/prebid/prebid-server/v2/gdpr" + "github.com/prebid/prebid-server/v2/hooks" + "github.com/prebid/prebid-server/v2/macros" + "github.com/prebid/prebid-server/v2/metrics" + metricsConf "github.com/prebid/prebid-server/v2/metrics/config" + "github.com/prebid/prebid-server/v2/modules" + "github.com/prebid/prebid-server/v2/modules/moduledeps" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/pbs" + pbc "github.com/prebid/prebid-server/v2/prebid_cache_client" + "github.com/prebid/prebid-server/v2/router/aspects" + "github.com/prebid/prebid-server/v2/server/ssl" + storedRequestsConf "github.com/prebid/prebid-server/v2/stored_requests/config" + "github.com/prebid/prebid-server/v2/usersync" + "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/uuidutil" + "github.com/prebid/prebid-server/v2/version" _ "github.com/go-sql-driver/mysql" "github.com/golang/glog" diff --git a/router/router_test.go b/router/router_test.go index f4f7715e6c3..cc2f077e5e6 100644 --- a/router/router_test.go +++ b/router/router_test.go @@ -7,9 +7,9 @@ import ( "os" "testing" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/schain/schain.go b/schain/schain.go index 6f084a65a2a..a4139a93f5e 100644 --- a/schain/schain.go +++ b/schain/schain.go @@ -5,7 +5,7 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // BidderToPrebidSChains organizes the ORTB 2.5 multiple root schain nodes into a map of schain nodes by bidder diff --git a/schain/schain_test.go b/schain/schain_test.go index dbe38d4014b..310608420d9 100644 --- a/schain/schain_test.go +++ b/schain/schain_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/schain/schainwriter.go b/schain/schainwriter.go index e7c9dd4ce72..0873e14f199 100644 --- a/schain/schainwriter.go +++ b/schain/schainwriter.go @@ -2,8 +2,8 @@ package schain import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) // NewSChainWriter creates an ORTB 2.5 schain writer instance diff --git a/schain/schainwriter_test.go b/schain/schainwriter_test.go index 9288b531d56..26777306fdf 100644 --- a/schain/schainwriter_test.go +++ b/schain/schainwriter_test.go @@ -5,8 +5,8 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/scripts/check_coverage.sh b/scripts/check_coverage.sh index 0dd6235b96b..63e89297c42 100755 --- a/scripts/check_coverage.sh +++ b/scripts/check_coverage.sh @@ -25,8 +25,7 @@ while IFS= read -r LINE; do if [[ $LINE =~ "%" ]]; then PERCENT=$(echo "$LINE"|cut -d: -f2-|cut -d% -f1|cut -d. -f1|tr -d ' ') if [[ $PERCENT -lt $COV_MIN ]]; then - echo "Package has less than ${COV_MIN}% code coverage. Run ./scripts/coverage.sh --html to see a detailed coverage report, and add tests to improve your coverage" - exit 1 + echo "WARNING: Package has less than ${COV_MIN}% code coverage. Run ./scripts/coverage.sh --html to see a detailed coverage report, and add tests to improve your coverage" fi fi done <<< "$OUTPUT" diff --git a/server/listener.go b/server/listener.go index 43917ac0a05..a10aef6441e 100644 --- a/server/listener.go +++ b/server/listener.go @@ -6,7 +6,7 @@ import ( "time" "github.com/golang/glog" - "github.com/prebid/prebid-server/metrics" + "github.com/prebid/prebid-server/v2/metrics" ) // monitorableListener tracks any opened connections in the metrics. diff --git a/server/listener_test.go b/server/listener_test.go index d10a3bdfbf9..c729f2ba55e 100644 --- a/server/listener_test.go +++ b/server/listener_test.go @@ -6,8 +6,8 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/metrics" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/metrics" gometrics "github.com/rcrowley/go-metrics" ) diff --git a/server/prometheus.go b/server/prometheus.go index 33114c86a0b..8b841f5151a 100644 --- a/server/prometheus.go +++ b/server/prometheus.go @@ -7,8 +7,8 @@ import ( "github.com/golang/glog" "github.com/prometheus/client_golang/prometheus/promhttp" - "github.com/prebid/prebid-server/config" - metricsconfig "github.com/prebid/prebid-server/metrics/config" + "github.com/prebid/prebid-server/v2/config" + metricsconfig "github.com/prebid/prebid-server/v2/metrics/config" ) func newPrometheusServer(cfg *config.Configuration, metrics *metricsconfig.DetailedMetricsEngine) *http.Server { diff --git a/server/server.go b/server/server.go index 9282f0fcf15..dd4813adb7f 100644 --- a/server/server.go +++ b/server/server.go @@ -13,9 +13,9 @@ import ( "github.com/NYTimes/gziphandler" "github.com/golang/glog" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/metrics" - metricsconfig "github.com/prebid/prebid-server/metrics/config" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/metrics" + metricsconfig "github.com/prebid/prebid-server/v2/metrics/config" ) // Listen blocks forever, serving PBS requests on the given port. This will block forever, until the process is shut down. diff --git a/server/server_test.go b/server/server_test.go index 7af892d3567..03a2fc911b5 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -9,8 +9,8 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/config" - metricsconfig "github.com/prebid/prebid-server/metrics/config" + "github.com/prebid/prebid-server/v2/config" + metricsconfig "github.com/prebid/prebid-server/v2/metrics/config" "github.com/stretchr/testify/assert" ) diff --git a/stored_requests/backends/db_fetcher/fetcher.go b/stored_requests/backends/db_fetcher/fetcher.go index 3ea36bc0fc7..3a9b83f7779 100644 --- a/stored_requests/backends/db_fetcher/fetcher.go +++ b/stored_requests/backends/db_fetcher/fetcher.go @@ -7,8 +7,8 @@ import ( "github.com/lib/pq" "github.com/golang/glog" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/stored_requests/backends/db_provider" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/stored_requests/backends/db_provider" ) func NewFetcher( diff --git a/stored_requests/backends/db_fetcher/fetcher_test.go b/stored_requests/backends/db_fetcher/fetcher_test.go index 04753fb8af5..f736e1bea15 100644 --- a/stored_requests/backends/db_fetcher/fetcher_test.go +++ b/stored_requests/backends/db_fetcher/fetcher_test.go @@ -11,7 +11,7 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" - "github.com/prebid/prebid-server/stored_requests/backends/db_provider" + "github.com/prebid/prebid-server/v2/stored_requests/backends/db_provider" "github.com/stretchr/testify/assert" ) diff --git a/stored_requests/backends/db_provider/db_provider.go b/stored_requests/backends/db_provider/db_provider.go index 0f79a7737e0..6e623356ed8 100644 --- a/stored_requests/backends/db_provider/db_provider.go +++ b/stored_requests/backends/db_provider/db_provider.go @@ -5,7 +5,7 @@ import ( "database/sql" "github.com/golang/glog" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/config" ) type DbProvider interface { diff --git a/stored_requests/backends/db_provider/db_provider_mock.go b/stored_requests/backends/db_provider/db_provider_mock.go index 3d4cfda76c3..c0ec3458eee 100644 --- a/stored_requests/backends/db_provider/db_provider_mock.go +++ b/stored_requests/backends/db_provider/db_provider_mock.go @@ -6,7 +6,7 @@ import ( "reflect" "github.com/DATA-DOG/go-sqlmock" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/config" ) func NewDbProviderMock() (*DbProviderMock, sqlmock.Sqlmock, error) { diff --git a/stored_requests/backends/db_provider/mysql_dbprovider.go b/stored_requests/backends/db_provider/mysql_dbprovider.go index 6301a119c45..38ad0836024 100644 --- a/stored_requests/backends/db_provider/mysql_dbprovider.go +++ b/stored_requests/backends/db_provider/mysql_dbprovider.go @@ -15,7 +15,7 @@ import ( "strings" "github.com/go-sql-driver/mysql" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/config" ) const customTLSKey = "prebid-tls" diff --git a/stored_requests/backends/db_provider/mysql_dbprovider_test.go b/stored_requests/backends/db_provider/mysql_dbprovider_test.go index e47280ef26b..b91352d08d6 100644 --- a/stored_requests/backends/db_provider/mysql_dbprovider_test.go +++ b/stored_requests/backends/db_provider/mysql_dbprovider_test.go @@ -6,7 +6,7 @@ import ( "runtime" "testing" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/config" "github.com/stretchr/testify/assert" ) diff --git a/stored_requests/backends/db_provider/postgres_dbprovider.go b/stored_requests/backends/db_provider/postgres_dbprovider.go index ef945faebc9..e2081f27df4 100644 --- a/stored_requests/backends/db_provider/postgres_dbprovider.go +++ b/stored_requests/backends/db_provider/postgres_dbprovider.go @@ -10,7 +10,7 @@ import ( "strconv" "strings" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/config" ) type PostgresDbProvider struct { diff --git a/stored_requests/backends/db_provider/postgres_dbprovider_test.go b/stored_requests/backends/db_provider/postgres_dbprovider_test.go index 9e98c0b5763..4b31e6f8ec3 100644 --- a/stored_requests/backends/db_provider/postgres_dbprovider_test.go +++ b/stored_requests/backends/db_provider/postgres_dbprovider_test.go @@ -4,7 +4,7 @@ import ( "errors" "testing" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/config" "github.com/stretchr/testify/assert" ) diff --git a/stored_requests/backends/empty_fetcher/fetcher.go b/stored_requests/backends/empty_fetcher/fetcher.go index 0246990c02e..c851a997df9 100644 --- a/stored_requests/backends/empty_fetcher/fetcher.go +++ b/stored_requests/backends/empty_fetcher/fetcher.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" - "github.com/prebid/prebid-server/stored_requests" + "github.com/prebid/prebid-server/v2/stored_requests" ) // EmptyFetcher is a nil-object which has no Stored Requests. diff --git a/stored_requests/backends/file_fetcher/fetcher.go b/stored_requests/backends/file_fetcher/fetcher.go index a9bbe919dcf..21a54039cda 100644 --- a/stored_requests/backends/file_fetcher/fetcher.go +++ b/stored_requests/backends/file_fetcher/fetcher.go @@ -7,8 +7,8 @@ import ( "os" "strings" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/util/jsonutil" jsonpatch "gopkg.in/evanphx/json-patch.v4" ) diff --git a/stored_requests/backends/file_fetcher/fetcher_test.go b/stored_requests/backends/file_fetcher/fetcher_test.go index a69945641f1..0155c1aa82c 100644 --- a/stored_requests/backends/file_fetcher/fetcher_test.go +++ b/stored_requests/backends/file_fetcher/fetcher_test.go @@ -6,8 +6,8 @@ import ( "fmt" "testing" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/stored_requests/backends/http_fetcher/fetcher.go b/stored_requests/backends/http_fetcher/fetcher.go index 88afa39fb1d..75aa1090ce4 100644 --- a/stored_requests/backends/http_fetcher/fetcher.go +++ b/stored_requests/backends/http_fetcher/fetcher.go @@ -9,8 +9,8 @@ import ( "net/url" "strings" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/util/jsonutil" jsonpatch "gopkg.in/evanphx/json-patch.v4" "github.com/golang/glog" diff --git a/stored_requests/backends/http_fetcher/fetcher_test.go b/stored_requests/backends/http_fetcher/fetcher_test.go index 80be6918ad8..1358ce413c1 100644 --- a/stored_requests/backends/http_fetcher/fetcher_test.go +++ b/stored_requests/backends/http_fetcher/fetcher_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/stored_requests/caches/cachestest/reliable.go b/stored_requests/caches/cachestest/reliable.go index 7fbaf7238af..517668318c7 100644 --- a/stored_requests/caches/cachestest/reliable.go +++ b/stored_requests/caches/cachestest/reliable.go @@ -5,7 +5,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/stored_requests" + "github.com/prebid/prebid-server/v2/stored_requests" ) const ( diff --git a/stored_requests/caches/memory/cache.go b/stored_requests/caches/memory/cache.go index 5939c26ddec..eb6317a3487 100644 --- a/stored_requests/caches/memory/cache.go +++ b/stored_requests/caches/memory/cache.go @@ -7,7 +7,7 @@ import ( "github.com/coocood/freecache" "github.com/golang/glog" - "github.com/prebid/prebid-server/stored_requests" + "github.com/prebid/prebid-server/v2/stored_requests" ) // NewCache returns an in-memory Cache which evicts items if: diff --git a/stored_requests/caches/memory/cache_test.go b/stored_requests/caches/memory/cache_test.go index b89bd5af26f..67ff661c7c5 100644 --- a/stored_requests/caches/memory/cache_test.go +++ b/stored_requests/caches/memory/cache_test.go @@ -7,8 +7,8 @@ import ( "strconv" "testing" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/stored_requests/caches/cachestest" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/stored_requests/caches/cachestest" ) func TestLRURobustness(t *testing.T) { diff --git a/stored_requests/config/config.go b/stored_requests/config/config.go index 9cb349d1f72..112b11122f9 100644 --- a/stored_requests/config/config.go +++ b/stored_requests/config/config.go @@ -5,24 +5,24 @@ import ( "net/http" "time" - "github.com/prebid/prebid-server/metrics" + "github.com/prebid/prebid-server/v2/metrics" "github.com/golang/glog" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/stored_requests/backends/db_fetcher" - "github.com/prebid/prebid-server/stored_requests/backends/db_provider" - "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/stored_requests/backends/file_fetcher" - "github.com/prebid/prebid-server/stored_requests/backends/http_fetcher" - "github.com/prebid/prebid-server/stored_requests/caches/memory" - "github.com/prebid/prebid-server/stored_requests/caches/nil_cache" - "github.com/prebid/prebid-server/stored_requests/events" - apiEvents "github.com/prebid/prebid-server/stored_requests/events/api" - databaseEvents "github.com/prebid/prebid-server/stored_requests/events/database" - httpEvents "github.com/prebid/prebid-server/stored_requests/events/http" - "github.com/prebid/prebid-server/util/task" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/stored_requests/backends/db_fetcher" + "github.com/prebid/prebid-server/v2/stored_requests/backends/db_provider" + "github.com/prebid/prebid-server/v2/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v2/stored_requests/backends/file_fetcher" + "github.com/prebid/prebid-server/v2/stored_requests/backends/http_fetcher" + "github.com/prebid/prebid-server/v2/stored_requests/caches/memory" + "github.com/prebid/prebid-server/v2/stored_requests/caches/nil_cache" + "github.com/prebid/prebid-server/v2/stored_requests/events" + apiEvents "github.com/prebid/prebid-server/v2/stored_requests/events/api" + databaseEvents "github.com/prebid/prebid-server/v2/stored_requests/events/database" + httpEvents "github.com/prebid/prebid-server/v2/stored_requests/events/http" + "github.com/prebid/prebid-server/v2/util/task" ) // CreateStoredRequests returns three things: diff --git a/stored_requests/config/config_test.go b/stored_requests/config/config_test.go index b06feea7d31..2e5a8c2a079 100644 --- a/stored_requests/config/config_test.go +++ b/stored_requests/config/config_test.go @@ -13,14 +13,14 @@ import ( sqlmock "github.com/DATA-DOG/go-sqlmock" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/stored_requests/backends/db_provider" - "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/stored_requests/backends/http_fetcher" - "github.com/prebid/prebid-server/stored_requests/events" - httpEvents "github.com/prebid/prebid-server/stored_requests/events/http" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/stored_requests/backends/db_provider" + "github.com/prebid/prebid-server/v2/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v2/stored_requests/backends/http_fetcher" + "github.com/prebid/prebid-server/v2/stored_requests/events" + httpEvents "github.com/prebid/prebid-server/v2/stored_requests/events/http" "github.com/stretchr/testify/mock" ) diff --git a/stored_requests/events/api/api.go b/stored_requests/events/api/api.go index 30778f0e11a..2d489bded38 100644 --- a/stored_requests/events/api/api.go +++ b/stored_requests/events/api/api.go @@ -5,8 +5,8 @@ import ( "net/http" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/stored_requests/events" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/stored_requests/events" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) type eventsAPI struct { diff --git a/stored_requests/events/api/api_test.go b/stored_requests/events/api/api_test.go index 67ba836cb00..536afe820af 100644 --- a/stored_requests/events/api/api_test.go +++ b/stored_requests/events/api/api_test.go @@ -9,9 +9,9 @@ import ( "strings" "testing" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/stored_requests/caches/memory" - "github.com/prebid/prebid-server/stored_requests/events" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/stored_requests/caches/memory" + "github.com/prebid/prebid-server/v2/stored_requests/events" ) func TestGoodRequests(t *testing.T) { diff --git a/stored_requests/events/database/database.go b/stored_requests/events/database/database.go index 24eddf214eb..260a58029cb 100644 --- a/stored_requests/events/database/database.go +++ b/stored_requests/events/database/database.go @@ -9,11 +9,11 @@ import ( "time" "github.com/golang/glog" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/stored_requests/backends/db_provider" - "github.com/prebid/prebid-server/stored_requests/events" - "github.com/prebid/prebid-server/util/timeutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/stored_requests/backends/db_provider" + "github.com/prebid/prebid-server/v2/stored_requests/events" + "github.com/prebid/prebid-server/v2/util/timeutil" ) func bytesNull() []byte { diff --git a/stored_requests/events/database/database_test.go b/stored_requests/events/database/database_test.go index 8ce21bfde95..27a56b67fe3 100644 --- a/stored_requests/events/database/database_test.go +++ b/stored_requests/events/database/database_test.go @@ -7,10 +7,10 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/stored_requests/backends/db_provider" - "github.com/prebid/prebid-server/stored_requests/events" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/stored_requests/backends/db_provider" + "github.com/prebid/prebid-server/v2/stored_requests/events" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" diff --git a/stored_requests/events/events.go b/stored_requests/events/events.go index 725df4279d8..e042b7c3513 100644 --- a/stored_requests/events/events.go +++ b/stored_requests/events/events.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" - "github.com/prebid/prebid-server/stored_requests" + "github.com/prebid/prebid-server/v2/stored_requests" ) // Save represents a bulk save diff --git a/stored_requests/events/events_test.go b/stored_requests/events/events_test.go index 580f1eddf37..165e6a6beb0 100644 --- a/stored_requests/events/events_test.go +++ b/stored_requests/events/events_test.go @@ -7,8 +7,8 @@ import ( "reflect" "testing" - "github.com/prebid/prebid-server/stored_requests" - "github.com/prebid/prebid-server/stored_requests/caches/memory" + "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v2/stored_requests/caches/memory" ) func TestListen(t *testing.T) { diff --git a/stored_requests/events/http/http.go b/stored_requests/events/http/http.go index be5b85a03a6..6c2145da2f3 100644 --- a/stored_requests/events/http/http.go +++ b/stored_requests/events/http/http.go @@ -12,8 +12,8 @@ import ( "golang.org/x/net/context/ctxhttp" "github.com/buger/jsonparser" - "github.com/prebid/prebid-server/stored_requests/events" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/stored_requests/events" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/golang/glog" ) diff --git a/stored_requests/events/http/http_test.go b/stored_requests/events/http/http_test.go index 663d8cd193f..fa7f64f227f 100644 --- a/stored_requests/events/http/http_test.go +++ b/stored_requests/events/http/http_test.go @@ -8,7 +8,7 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/stored_requests/fetcher.go b/stored_requests/fetcher.go index 433b33427b8..cd3855c9eb8 100644 --- a/stored_requests/fetcher.go +++ b/stored_requests/fetcher.go @@ -5,7 +5,7 @@ import ( "encoding/json" "fmt" - "github.com/prebid/prebid-server/metrics" + "github.com/prebid/prebid-server/v2/metrics" ) // Fetcher knows how to fetch Stored Request data by id. diff --git a/stored_requests/fetcher_test.go b/stored_requests/fetcher_test.go index 684b867165c..34c15f61f96 100644 --- a/stored_requests/fetcher_test.go +++ b/stored_requests/fetcher_test.go @@ -6,8 +6,8 @@ import ( "errors" "testing" - "github.com/prebid/prebid-server/metrics" - "github.com/prebid/prebid-server/stored_requests/caches/nil_cache" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/stored_requests/caches/nil_cache" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" diff --git a/stored_responses/stored_responses.go b/stored_responses/stored_responses.go index d6944a6f30f..802602904bc 100644 --- a/stored_responses/stored_responses.go +++ b/stored_responses/stored_responses.go @@ -7,8 +7,8 @@ import ( "strings" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/stored_requests" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/stored_requests" ) type ImpsWithAuctionResponseIDs map[string]string diff --git a/stored_responses/stored_responses_test.go b/stored_responses/stored_responses_test.go index 209b34a650b..196466b7323 100644 --- a/stored_responses/stored_responses_test.go +++ b/stored_responses/stored_responses_test.go @@ -7,7 +7,7 @@ import ( "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/usersync/chooser.go b/usersync/chooser.go index 578c63717de..3b97359e1ce 100644 --- a/usersync/chooser.go +++ b/usersync/chooser.go @@ -1,8 +1,9 @@ package usersync import ( - "github.com/prebid/prebid-server/openrtb_ext" "strings" + + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // Chooser determines which syncers are eligible for a given request. diff --git a/usersync/chooser_test.go b/usersync/chooser_test.go index 6ab5a6b53e3..e73122b784a 100644 --- a/usersync/chooser_test.go +++ b/usersync/chooser_test.go @@ -1,13 +1,14 @@ package usersync import ( - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" "testing" "time" - "github.com/prebid/prebid-server/macros" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + "github.com/prebid/prebid-server/v2/macros" ) func TestNewChooser(t *testing.T) { diff --git a/usersync/cookie.go b/usersync/cookie.go index 88524018c49..b4bc821c9d7 100644 --- a/usersync/cookie.go +++ b/usersync/cookie.go @@ -5,9 +5,9 @@ import ( "net/http" "time" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) const uidCookieName = "uids" diff --git a/usersync/cookie_test.go b/usersync/cookie_test.go index 340069767b1..1ecfe51b5b5 100644 --- a/usersync/cookie_test.go +++ b/usersync/cookie_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/usersync/decoder.go b/usersync/decoder.go index c803fbe2a52..a73e37fc560 100644 --- a/usersync/decoder.go +++ b/usersync/decoder.go @@ -3,7 +3,7 @@ package usersync import ( "encoding/base64" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) type Decoder interface { diff --git a/usersync/encoder.go b/usersync/encoder.go index 74472f23307..2baf5d86524 100644 --- a/usersync/encoder.go +++ b/usersync/encoder.go @@ -3,7 +3,7 @@ package usersync import ( "encoding/base64" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) type Encoder interface { diff --git a/usersync/syncer.go b/usersync/syncer.go index e561614f4a2..3add47e5873 100644 --- a/usersync/syncer.go +++ b/usersync/syncer.go @@ -9,8 +9,8 @@ import ( "text/template" validator "github.com/asaskevich/govalidator" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/macros" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/macros" ) var ( diff --git a/usersync/syncer_test.go b/usersync/syncer_test.go index 72167addae5..6aa3103211e 100644 --- a/usersync/syncer_test.go +++ b/usersync/syncer_test.go @@ -4,8 +4,8 @@ import ( "testing" "text/template" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/macros" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/macros" "github.com/stretchr/testify/assert" ) diff --git a/usersync/syncersbuilder.go b/usersync/syncersbuilder.go index 9a52a740f31..9c916b821b4 100644 --- a/usersync/syncersbuilder.go +++ b/usersync/syncersbuilder.go @@ -5,7 +5,7 @@ import ( "sort" "strings" - "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/v2/config" ) type namedSyncerConfig struct { diff --git a/usersync/syncersbuilder_test.go b/usersync/syncersbuilder_test.go index 15c53dba2a4..a8f396aa714 100644 --- a/usersync/syncersbuilder_test.go +++ b/usersync/syncersbuilder_test.go @@ -4,8 +4,8 @@ import ( "errors" "testing" - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/macros" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/macros" "github.com/stretchr/testify/assert" ) diff --git a/util/httputil/httputil.go b/util/httputil/httputil.go index 28334a54b87..cabb197fa37 100644 --- a/util/httputil/httputil.go +++ b/util/httputil/httputil.go @@ -5,7 +5,7 @@ import ( "net/http" "strings" - "github.com/prebid/prebid-server/util/iputil" + "github.com/prebid/prebid-server/v2/util/iputil" ) var ( diff --git a/util/httputil/httputil_test.go b/util/httputil/httputil_test.go index 5da3b0ab735..d056db245f3 100644 --- a/util/httputil/httputil_test.go +++ b/util/httputil/httputil_test.go @@ -5,7 +5,7 @@ import ( "net/http" "testing" - "github.com/prebid/prebid-server/util/iputil" + "github.com/prebid/prebid-server/v2/util/iputil" "github.com/stretchr/testify/assert" ) diff --git a/util/jsonutil/jsonutil.go b/util/jsonutil/jsonutil.go index a8981477dc6..b5bb47cca9a 100644 --- a/util/jsonutil/jsonutil.go +++ b/util/jsonutil/jsonutil.go @@ -7,7 +7,7 @@ import ( "strings" jsoniter "github.com/json-iterator/go" - "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/v2/errortypes" ) var comma = byte(',') diff --git a/util/task/ticker_task_test.go b/util/task/ticker_task_test.go index c02eec158a1..3ca0280d23e 100644 --- a/util/task/ticker_task_test.go +++ b/util/task/ticker_task_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/util/task" + "github.com/prebid/prebid-server/v2/util/task" "github.com/stretchr/testify/assert" ) diff --git a/version/xprebidheader.go b/version/xprebidheader.go index fc71bacb1a3..613a76d80b6 100644 --- a/version/xprebidheader.go +++ b/version/xprebidheader.go @@ -5,7 +5,7 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) const xPrebidHeaderVersionPrefix = "pbs-go" diff --git a/version/xprebidheader_test.go b/version/xprebidheader_test.go index a1c7b355bb8..db31ea63620 100644 --- a/version/xprebidheader_test.go +++ b/version/xprebidheader_test.go @@ -6,8 +6,8 @@ import ( "github.com/prebid/openrtb/v19/openrtb2" "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/jsonutil" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/jsonutil" ) func TestBuildXPrebidHeader(t *testing.T) { From 2540dd884950f6c582d01263479f3e7973cda2eb Mon Sep 17 00:00:00 2001 From: Piotr Jaworski <109736938+piotrj-rtbh@users.noreply.github.com> Date: Mon, 30 Oct 2023 09:00:24 +0100 Subject: [PATCH 198/268] RTBHouse: native support (#3212) --- adapters/rtbhouse/rtbhouse.go | 65 +++++++- .../bidfloor-as-bidder-param-without-cur.json | 130 ++++++++++++++++ .../exemplary/bidfloor-as-bidder-param.json | 133 +++++++++++++++++ .../bidfloor-as-impbidfloor-with-cur.json | 130 ++++++++++++++++ .../bidfloor-as-impbidfloor-without-cur.json | 128 ++++++++++++++++ .../exemplary/currency-conversion.json | 123 --------------- .../native-with-deprecated-native-prop.json | 100 +++++++++++++ .../native-with-proper-native-response.json | 100 +++++++++++++ .../rtbhousetest/exemplary/simple-banner.json | 6 +- ...bidfloors-given-param-and-impbidfloor.json | 132 ++++++++++++++++ ...ner-native-req-faulty-mtype-in-native.json | 141 ++++++++++++++++++ .../faulty-request-bidder-params.json | 30 ++++ .../faulty-request-no-impext.json | 25 ++++ .../native-with-faulty-adm-native-prop.json | 90 +++++++++++ .../native-with-faulty-adm-response.json | 90 +++++++++++ .../supplemental/simple-banner-bad-mtype.json | 94 ++++++++++++ .../supplemental/simple-banner-no-mtype.json | 93 ++++++++++++ static/bidder-info/rtbhouse.yaml | 1 + 18 files changed, 1481 insertions(+), 130 deletions(-) create mode 100644 adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param-without-cur.json create mode 100644 adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param.json create mode 100644 adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-with-cur.json create mode 100644 adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-without-cur.json delete mode 100644 adapters/rtbhouse/rtbhousetest/exemplary/currency-conversion.json create mode 100644 adapters/rtbhouse/rtbhousetest/exemplary/native-with-deprecated-native-prop.json create mode 100644 adapters/rtbhouse/rtbhousetest/exemplary/native-with-proper-native-response.json create mode 100644 adapters/rtbhouse/rtbhousetest/exemplary/two-bidfloors-given-param-and-impbidfloor.json create mode 100644 adapters/rtbhouse/rtbhousetest/supplemental/banner-native-req-faulty-mtype-in-native.json create mode 100644 adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-bidder-params.json create mode 100644 adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-no-impext.json create mode 100644 adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-native-prop.json create mode 100644 adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-response.json create mode 100644 adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-bad-mtype.json create mode 100644 adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-no-mtype.json diff --git a/adapters/rtbhouse/rtbhouse.go b/adapters/rtbhouse/rtbhouse.go index 089634cbd86..92e0e57b287 100644 --- a/adapters/rtbhouse/rtbhouse.go +++ b/adapters/rtbhouse/rtbhouse.go @@ -2,10 +2,12 @@ package rtbhouse import ( "encoding/json" + "errors" "fmt" "net/http" "strings" + "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/v2/adapters" "github.com/prebid/prebid-server/v2/config" @@ -49,9 +51,12 @@ func (adapter *RTBHouseAdapter) MakeRequests( if err != nil { return nil, []error{err} } - if rtbhouseExt.BidFloor > 0 && len(reqCopy.Cur) > 0 { - bidFloorCur = reqCopy.Cur[0] + if rtbhouseExt.BidFloor > 0 { bidFloor = rtbhouseExt.BidFloor + bidFloorCur = BidderCurrency + if len(reqCopy.Cur) > 0 { + bidFloorCur = reqCopy.Cur[0] + } } } @@ -156,13 +161,63 @@ func (adapter *RTBHouseAdapter) MakeBids( for _, seatBid := range openRTBBidderResponse.SeatBid { for _, bid := range seatBid.Bid { bid := bid // pin! -> https://github.com/kyoh86/scopelint#whats-this - typedBid = &adapters.TypedBid{Bid: &bid, BidType: "banner"} - bidderResponse.Bids = append(bidderResponse.Bids, typedBid) + bidType, err := getMediaTypeForBid(bid) + if err != nil { + errs = append(errs, err) + continue + } else { + typedBid = &adapters.TypedBid{ + Bid: &bid, + BidType: bidType, + } + + // for native bid responses fix Adm field + if typedBid.BidType == openrtb_ext.BidTypeNative { + bid.AdM, err = getNativeAdm(bid.AdM) + if err != nil { + errs = append(errs, err) + continue + } + } + + bidderResponse.Bids = append(bidderResponse.Bids, typedBid) + } } } bidderResponse.Currency = BidderCurrency - return bidderResponse, nil + return bidderResponse, errs + +} + +func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + return "", fmt.Errorf("unrecognized bid type in response from rtbhouse for bid %s", bid.ImpID) + } +} + +func getNativeAdm(adm string) (string, error) { + nativeAdm := make(map[string]interface{}) + err := json.Unmarshal([]byte(adm), &nativeAdm) + if err != nil { + return adm, errors.New("unable to unmarshal native adm") + } + + // move bid.adm.native to bid.adm + if _, ok := nativeAdm["native"]; ok { + //using jsonparser to avoid marshaling, encode escape, etc. + value, dataType, _, err := jsonparser.Get([]byte(adm), string(openrtb_ext.BidTypeNative)) + if err != nil || dataType != jsonparser.Object { + return adm, errors.New("unable to get native adm") + } + adm = string(value) + } + return adm, nil } diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param-without-cur.json b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param-without-cur.json new file mode 100644 index 00000000000..79aa038c3ca --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param-without-cur.json @@ -0,0 +1,130 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "publisherId": "12345", + "bidfloor": 3.00 + } + } + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server", + "body": { + "id": "test-request-id", + "cur": [ + "USD" + ], + "imp": [ + { + "banner": { + "format": [ + { + "h": 250, + "w": 300 + } + ] + }, + "bidfloor": 3.00, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "publisherId": "12345", + "bidfloor": 3.00 + } + }, + "id": "test-imp-id" + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "cur": "USD", + "seatbid": [ + { + "seat": "rtbhouse", + "bid": [ + { + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param.json b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param.json new file mode 100644 index 00000000000..99b3a87ebfa --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param.json @@ -0,0 +1,133 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "cur": [ + "EUR" + ], + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "publisherId": "12345", + "bidfloor": 2 + } + } + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server", + "body": { + "id": "test-request-id", + "cur": [ + "USD" + ], + "imp": [ + { + "banner": { + "format": [ + { + "h": 250, + "w": 300 + } + ] + }, + "bidfloor": 0.1, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "publisherId": "12345", + "bidfloor": 2 + } + }, + "id": "test-imp-id" + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "cur": "USD", + "seatbid": [ + { + "seat": "rtbhouse", + "bid": [ + { + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-with-cur.json b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-with-cur.json new file mode 100644 index 00000000000..85e8a1c28cf --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-with-cur.json @@ -0,0 +1,130 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "bidfloor": 1.00, + "bidfloorcur": "EUR", + "ext": { + "bidder": { + "publisherId": "12345" + } + } + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server", + "body": { + "id": "test-request-id", + "cur": [ + "USD" + ], + "imp": [ + { + "banner": { + "format": [ + { + "h": 250, + "w": 300 + } + ] + }, + "bidfloor": 0.05, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "publisherId": "12345" + } + }, + "id": "test-imp-id" + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "cur": "USD", + "seatbid": [ + { + "seat": "rtbhouse", + "bid": [ + { + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-without-cur.json b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-without-cur.json new file mode 100644 index 00000000000..1417965741e --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-without-cur.json @@ -0,0 +1,128 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "bidfloor": 1.00, + "ext": { + "bidder": { + "publisherId": "12345" + } + } + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server", + "body": { + "id": "test-request-id", + "cur": [ + "USD" + ], + "imp": [ + { + "banner": { + "format": [ + { + "h": 250, + "w": 300 + } + ] + }, + "bidfloor": 1, + "ext": { + "bidder": { + "publisherId": "12345" + } + }, + "id": "test-imp-id" + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "cur": "USD", + "seatbid": [ + { + "seat": "rtbhouse", + "bid": [ + { + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/currency-conversion.json b/adapters/rtbhouse/rtbhousetest/exemplary/currency-conversion.json deleted file mode 100644 index 95bfb1e4420..00000000000 --- a/adapters/rtbhouse/rtbhousetest/exemplary/currency-conversion.json +++ /dev/null @@ -1,123 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "bidfloor": 1.00, - "bidfloorcur": "EUR", - "ext": { - "bidder": { - "placementId": "12345" - } - } - } - ], - "ext": { - "prebid": { - "currency": { - "rates": { - "EUR": { - "USD": 0.05 - } - }, - "usepbsrates": false - } - } - } - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://localhost/prebid_server", - "body": { - "id": "test-request-id", - "cur": ["USD"], - "imp": [ - { - "banner": { - "format": [ - { - "h": 250, - "w": 300 - } - ] - }, - "bidfloor": 0.05, - "bidfloorcur": "USD", - "ext": { - "bidder": { - "placementId": "12345" - } - }, - "id": "test-imp-id" - } - ], - "ext": { - "prebid": { - "currency": { - "rates": { - "EUR": { - "USD": 0.05 - } - }, - "usepbsrates": false - } - } - } - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-response-id", - "cur": "USD", - "seatbid": [{ - "seat": "rtbhouse", - "bid": [{ - "id": "randomid", - "impid": "test-imp-id", - "price": 300, - "adid": "12345678", - "adm": "some-test-ad", - "cid": "987", - "crid": "12345678", - "h": 250, - "w": 300 - } - ] - }] - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "randomid", - "impid": "test-imp-id", - "price": 300, - "adid": "12345678", - "adm": "some-test-ad", - "cid": "987", - "crid": "12345678", - "h": 250, - "w": 300 - }, - "type": "banner" - } - ] - } - ] - } diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/native-with-deprecated-native-prop.json b/adapters/rtbhouse/rtbhousetest/exemplary/native-with-deprecated-native-prop.json new file mode 100644 index 00000000000..e79b21a1207 --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/exemplary/native-with-deprecated-native-prop.json @@ -0,0 +1,100 @@ +{ + "mockBidRequest": { + "imp": [ + { + "ext": { + "bidder": {} + }, + "id": "test-native-imp", + "native": { + "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", + "ver": "1.2" + } + } + ], + "site": { + "page": "https://good.site/url" + }, + "id": "test-native-request", + "ext": {}, + "debug": 1 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server", + "body": { + "id": "test-native-request", + "cur": [ + "USD" + ], + "imp": [ + { + "id": "test-native-imp", + "native": { + "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", + "ver": "1.2" + }, + "ext": { + "bidder": {} + } + } + ], + "site": { + "page": "https://good.site/url" + }, + "ext": {} + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-native-request", + "bidid": "test-bidid", + "cur": "USD", + "seatbid": [ + { + "seat": "rtbhouse", + "bid": [ + { + "id": "test-native-request", + "impid": "test-native-imp", + "price": 0.5, + "adid": "test-adid", + "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"title text\"}},{\"id\":1,\"data\":{\"value\":\"data value\"}},{\"id\":2,\"img\":{\"url\":\"image.url\",\"w\":1200,\"h\":628}}],\"link\":{\"url\":\"link.url\"},\"imptrackers\":[\"imp.tracker.url\"],\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"event.tracker.url\"}]}}", + "adomain": [ "adomain.com" ], + "cid": "test-cid", + "crid": "test-crid", + "dealid": "test-dealid", + "mtype": 4 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-native-request", + "impid": "test-native-imp", + "price": 0.5, + "adid": "test-adid", + "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"title text\"}},{\"id\":1,\"data\":{\"value\":\"data value\"}},{\"id\":2,\"img\":{\"url\":\"image.url\",\"w\":1200,\"h\":628}}],\"link\":{\"url\":\"link.url\"},\"imptrackers\":[\"imp.tracker.url\"],\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"event.tracker.url\"}]}", + "adomain": [ "adomain.com" ], + "cid": "test-cid", + "crid": "test-crid", + "dealid": "test-dealid", + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/native-with-proper-native-response.json b/adapters/rtbhouse/rtbhousetest/exemplary/native-with-proper-native-response.json new file mode 100644 index 00000000000..9f5962fd3a1 --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/exemplary/native-with-proper-native-response.json @@ -0,0 +1,100 @@ +{ + "mockBidRequest": { + "imp": [ + { + "ext": { + "bidder": {} + }, + "id": "test-native-imp", + "native": { + "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", + "ver": "1.2" + } + } + ], + "site": { + "page": "https://good.site/url" + }, + "id": "test-native-request", + "ext": {}, + "debug": 1 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server", + "body": { + "id": "test-native-request", + "cur": [ + "USD" + ], + "imp": [ + { + "id": "test-native-imp", + "native": { + "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", + "ver": "1.2" + }, + "ext": { + "bidder": {} + } + } + ], + "site": { + "page": "https://good.site/url" + }, + "ext": {} + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-native-request", + "bidid": "test-bidid", + "cur": "USD", + "seatbid": [ + { + "seat": "rtbhouse", + "bid": [ + { + "id": "test-native-request", + "impid": "test-native-imp", + "price": 0.5, + "adid": "test-adid", + "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"title text\"}},{\"id\":1,\"data\":{\"value\":\"data value\"}},{\"id\":2,\"img\":{\"url\":\"image.url\",\"w\":1200,\"h\":628}}],\"link\":{\"url\":\"link.url\"},\"imptrackers\":[\"imp.tracker.url\"],\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"event.tracker.url\"}]}", + "adomain": [ "adomain.com" ], + "cid": "test-cid", + "crid": "test-crid", + "dealid": "test-dealid", + "mtype": 4 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-native-request", + "impid": "test-native-imp", + "price": 0.5, + "adid": "test-adid", + "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"title text\"}},{\"id\":1,\"data\":{\"value\":\"data value\"}},{\"id\":2,\"img\":{\"url\":\"image.url\",\"w\":1200,\"h\":628}}],\"link\":{\"url\":\"link.url\"},\"imptrackers\":[\"imp.tracker.url\"],\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"event.tracker.url\"}]}", + "adomain": [ "adomain.com" ], + "cid": "test-cid", + "crid": "test-crid", + "dealid": "test-dealid", + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json b/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json index 2a8c4681ffa..468e73f2aca 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json @@ -56,7 +56,8 @@ "cid": "987", "crid": "12345678", "h": 250, - "w": 300 + "w": 300, + "mtype": 1 }] }], "cur": "USD" @@ -76,7 +77,8 @@ "cid": "987", "crid": "12345678", "w": 300, - "h": 250 + "h": 250, + "mtype": 1 }, "type": "banner" }] diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/two-bidfloors-given-param-and-impbidfloor.json b/adapters/rtbhouse/rtbhousetest/exemplary/two-bidfloors-given-param-and-impbidfloor.json new file mode 100644 index 00000000000..fc706d97004 --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/exemplary/two-bidfloors-given-param-and-impbidfloor.json @@ -0,0 +1,132 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "bidfloor": 1.00, + "bidfloorcur": "EUR", + "ext": { + "bidder": { + "publisherId": "12345", + "bidfloor": 2.00 + } + } + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server", + "body": { + "id": "test-request-id", + "cur": [ + "USD" + ], + "imp": [ + { + "banner": { + "format": [ + { + "h": 250, + "w": 300 + } + ] + }, + "bidfloor": 0.05, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "publisherId": "12345", + "bidfloor": 2 + } + }, + "id": "test-imp-id" + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "cur": "USD", + "seatbid": [ + { + "seat": "rtbhouse", + "bid": [ + { + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/banner-native-req-faulty-mtype-in-native.json b/adapters/rtbhouse/rtbhousetest/supplemental/banner-native-req-faulty-mtype-in-native.json new file mode 100644 index 00000000000..6e6f415acbc --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/supplemental/banner-native-req-faulty-mtype-in-native.json @@ -0,0 +1,141 @@ +{ + "mockBidRequest": { + "imp": [ + { + "ext": { + "bidder": {} + }, + "id": "test-native-imp", + "native": { + "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", + "ver": "1.2" + } + }, + { + "id": "test-banner-imp", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": {} + } + } + ], + "site": { + "page": "https://good.site/url" + }, + "id": "test-multi-slot-request", + "ext": {}, + "debug": 1 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server", + "body": { + "id": "test-multi-slot-request", + "cur": [ + "USD" + ], + "imp": [ + { + "id": "test-native-imp", + "native": { + "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", + "ver": "1.2" + }, + "ext": { + "bidder": {} + } + }, + { + "id": "test-banner-imp", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": {} + } + } + ], + "site": { + "page": "https://good.site/url" + }, + "ext": {} + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-multi-slot-request", + "bidid": "test-bidid", + "cur": "USD", + "seatbid": [ + { + "seat": "rtbhouse", + "bid": [ + { + "id": "randomid-native", + "impid": "test-native-imp", + "price": 0.5, + "adid": "test-adid", + "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"title text\"}},{\"id\":1,\"data\":{\"value\":\"data value\"}},{\"id\":2,\"img\":{\"url\":\"image.url\",\"w\":1200,\"h\":628}}],\"link\":{\"url\":\"link.url\"},\"imptrackers\":[\"imp.tracker.url\"],\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"event.tracker.url\"}]}}", + "adomain": [ "adomain.com" ], + "cid": "test-cid", + "crid": "test-crid", + "dealid": "test-dealid", + "mtype": 99 + }, + { + "id": "randomid-banner", + "impid": "test-banner-imp", + "price": 0.500000, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [{ + "bid": { + "id": "randomid-banner", + "impid": "test-banner-imp", + "price": 0.500000, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "unrecognized bid type in response from rtbhouse for bid test-native-imp", + "comparison": "literal" + } + ] +} diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-bidder-params.json b/adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-bidder-params.json new file mode 100644 index 00000000000..70fddf620e6 --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-bidder-params.json @@ -0,0 +1,30 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "banner-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "publisherId": 12345 + } + } + } + ], + "ext": {} + }, + "expectedMakeRequestsErrors": [ + { + "value": "Error while unmarshaling bidder extension", + "comparison": "literal" + } + ] +} diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-no-impext.json b/adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-no-impext.json new file mode 100644 index 00000000000..f416f8106fa --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-no-impext.json @@ -0,0 +1,25 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "banner-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + } + } + ], + "ext": {} + }, + "expectedMakeRequestsErrors": [ + { + "value": "Bidder extension not provided or can't be unmarshalled", + "comparison": "literal" + } + ] +} diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-native-prop.json b/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-native-prop.json new file mode 100644 index 00000000000..5e1aa0ef4b7 --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-native-prop.json @@ -0,0 +1,90 @@ +{ + "mockBidRequest": { + "imp": [ + { + "ext": { + "bidder": {} + }, + "id": "test-native-imp", + "native": { + "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", + "ver": "1.2" + } + } + ], + "site": { + "page": "https://good.site/url" + }, + "id": "test-native-request", + "ext": {}, + "debug": 1 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server", + "body": { + "id": "test-native-request", + "cur": [ + "USD" + ], + "imp": [ + { + "id": "test-native-imp", + "native": { + "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", + "ver": "1.2" + }, + "ext": { + "bidder": {} + } + } + ], + "site": { + "page": "https://good.site/url" + }, + "ext": {} + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-native-request", + "bidid": "test-bidid", + "cur": "USD", + "seatbid": [ + { + "seat": "rtbhouse", + "bid": [ + { + "id": "test-native-request", + "impid": "test-native-imp", + "price": 0.5, + "adid": "test-adid", + "adm": "{\"native\":\"faulty object\"}", + "adomain": [ "adomain.com" ], + "cid": "test-cid", + "crid": "test-crid", + "dealid": "test-dealid", + "mtype": 4 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "unable to get native adm", + "comparison": "literal" + } + ] +} diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-response.json b/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-response.json new file mode 100644 index 00000000000..41cc909f304 --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-response.json @@ -0,0 +1,90 @@ +{ + "mockBidRequest": { + "imp": [ + { + "ext": { + "bidder": {} + }, + "id": "test-native-imp", + "native": { + "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", + "ver": "1.2" + } + } + ], + "site": { + "page": "https://good.site/url" + }, + "id": "test-native-request", + "ext": {}, + "debug": 1 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server", + "body": { + "id": "test-native-request", + "cur": [ + "USD" + ], + "imp": [ + { + "id": "test-native-imp", + "native": { + "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", + "ver": "1.2" + }, + "ext": { + "bidder": {} + } + } + ], + "site": { + "page": "https://good.site/url" + }, + "ext": {} + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-native-request", + "bidid": "test-bidid", + "cur": "USD", + "seatbid": [ + { + "seat": "rtbhouse", + "bid": [ + { + "id": "test-native-request", + "impid": "test-native-imp", + "price": 0.5, + "adid": "test-adid", + "adm": "{\"ver\":\"1.2\"", + "adomain": [ "adomain.com" ], + "cid": "test-cid", + "crid": "test-crid", + "dealid": "test-dealid", + "mtype": 4 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "unable to unmarshal native adm", + "comparison": "literal" + } + ] +} diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-bad-mtype.json b/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-bad-mtype.json new file mode 100644 index 00000000000..fc52cc30601 --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-bad-mtype.json @@ -0,0 +1,94 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": {} + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server", + "body": { + "id": "test-request-id", + "cur": [ + "USD" + ], + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": {} + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "rtbhouse", + "bid": [ + { + "id": "randomid", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 99 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "unrecognized bid type in response from rtbhouse for bid test-imp-id", + "comparison": "literal" + } + ] +} diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-no-mtype.json b/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-no-mtype.json new file mode 100644 index 00000000000..8bb9e8a1f89 --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-no-mtype.json @@ -0,0 +1,93 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": {} + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server", + "body": { + "id": "test-request-id", + "cur": [ + "USD" + ], + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": {} + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "rtbhouse", + "bid": [ + { + "id": "randomid", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "unrecognized bid type in response from rtbhouse for bid test-imp-id", + "comparison": "literal" + } + ] +} diff --git a/static/bidder-info/rtbhouse.yaml b/static/bidder-info/rtbhouse.yaml index ad2fbfcbc95..b80cc0ff4f8 100644 --- a/static/bidder-info/rtbhouse.yaml +++ b/static/bidder-info/rtbhouse.yaml @@ -7,6 +7,7 @@ capabilities: site: mediaTypes: - banner + - native userSync: # rtbhouse supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. From 8e9f3f359416289a8b988f5d2403daf68edc4593 Mon Sep 17 00:00:00 2001 From: SerhiiNahornyi Date: Mon, 30 Oct 2023 14:19:46 +0200 Subject: [PATCH 199/268] Rubicon: Add `imp[].ext.rp.rtb.formats` logic (#3255) --- adapters/rubicon/rubicon.go | 30 +- .../bidonmultiformat-with-formats-param.json | 323 ++++++++++++++++++ .../exemplary/bidonmultiformat.json | 12 + ...n-bidonmultiformat-with-formats-param.json | 187 ++++++++++ openrtb_ext/imp_rubicon.go | 1 + 5 files changed, 550 insertions(+), 3 deletions(-) create mode 100644 adapters/rubicon/rubicontest/exemplary/bidonmultiformat-with-formats-param.json create mode 100644 adapters/rubicon/rubicontest/exemplary/non-bidonmultiformat-with-formats-param.json diff --git a/adapters/rubicon/rubicon.go b/adapters/rubicon/rubicon.go index 7d09224e8b4..431359c0b33 100644 --- a/adapters/rubicon/rubicon.go +++ b/adapters/rubicon/rubicon.go @@ -87,6 +87,11 @@ type rubiconImpExtRP struct { ZoneID int `json:"zone_id"` Target json.RawMessage `json:"target,omitempty"` Track rubiconImpExtRPTrack `json:"track"` + RTB *rubiconImpExtRpRtb `json:"rtb,omitempty"` +} + +type rubiconImpExtRpRtb struct { + Formats []openrtb_ext.BidType `json:"formats,omitempty"` } type rubiconUserExtRP struct { @@ -299,6 +304,10 @@ func (a *RubiconAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ada Skadn: bidderExt.Skadn, } + if len(bidderExt.Bidder.Formats) > 0 { + impExt.RP.RTB = &rubiconImpExtRpRtb{bidderExt.Bidder.Formats} + } + imp.Ext, err = json.Marshal(&impExt) if err != nil { errs = append(errs, err) @@ -592,9 +601,19 @@ func prepareImpsToExtMap(impsToExtMap map[*openrtb2.Imp]rubiconExtImpBidder) map continue } - splitImps := splitMultiFormatImp(imp) + splitImps, formats := splitMultiFormatImp(imp) for _, imp := range splitImps { impCopy := imp + + existingFormats := bidderExt.Bidder.Formats + var resolvedFormats []openrtb_ext.BidType + if len(existingFormats) > 0 { + resolvedFormats = existingFormats + } else { + resolvedFormats = formats + } + bidderExt.Bidder.Formats = resolvedFormats + preparedImpsToExtMap[impCopy] = bidderExt } } @@ -602,9 +621,11 @@ func prepareImpsToExtMap(impsToExtMap map[*openrtb2.Imp]rubiconExtImpBidder) map return preparedImpsToExtMap } -func splitMultiFormatImp(imp *openrtb2.Imp) []*openrtb2.Imp { +func splitMultiFormatImp(imp *openrtb2.Imp) ([]*openrtb2.Imp, []openrtb_ext.BidType) { splitImps := make([]*openrtb2.Imp, 0) + mediaTypes := make([]openrtb_ext.BidType, 0) if imp.Banner != nil { + mediaTypes = append(mediaTypes, openrtb_ext.BidTypeBanner) impCopy := *imp impCopy.Video = nil impCopy.Native = nil @@ -613,6 +634,7 @@ func splitMultiFormatImp(imp *openrtb2.Imp) []*openrtb2.Imp { } if imp.Video != nil { + mediaTypes = append(mediaTypes, openrtb_ext.BidTypeVideo) impCopy := *imp impCopy.Banner = nil impCopy.Native = nil @@ -621,6 +643,7 @@ func splitMultiFormatImp(imp *openrtb2.Imp) []*openrtb2.Imp { } if imp.Native != nil { + mediaTypes = append(mediaTypes, openrtb_ext.BidTypeNative) impCopy := *imp impCopy.Banner = nil impCopy.Video = nil @@ -629,6 +652,7 @@ func splitMultiFormatImp(imp *openrtb2.Imp) []*openrtb2.Imp { } if imp.Audio != nil { + mediaTypes = append(mediaTypes, openrtb_ext.BidTypeAudio) impCopy := *imp impCopy.Banner = nil impCopy.Video = nil @@ -636,7 +660,7 @@ func splitMultiFormatImp(imp *openrtb2.Imp) []*openrtb2.Imp { splitImps = append(splitImps, &impCopy) } - return splitImps + return splitImps, mediaTypes } func resolveBidFloor(bidFloor float64, bidFloorCur string, reqInfo *adapters.ExtraRequestInfo) (float64, error) { diff --git a/adapters/rubicon/rubicontest/exemplary/bidonmultiformat-with-formats-param.json b/adapters/rubicon/rubicontest/exemplary/bidonmultiformat-with-formats-param.json new file mode 100644 index 00000000000..72efd23e298 --- /dev/null +++ b/adapters/rubicon/rubicontest/exemplary/bidonmultiformat-with-formats-param.json @@ -0,0 +1,323 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" + }, + "site": { + "page": "somePage", + "ref": "someRef", + "search": "someSearch" + }, + "imp": [ + { + "id": "test-imp-id", + "instl": 1, + "banner": { + "format": [ + { + "w": 300, + "h": 400 + } + ] + }, + "video": { + "placement": 3, + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "bidonmultiformat": true, + "accountId": 1001, + "siteId": 113932, + "zoneId": 535510, + "formats": [ + "banner", + "video", + "native" + ] + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "uri?tk_xint=pbs-test-tracker", + "body": { + "id": "test-request-id", + "device": { + "ext": { + "rp": { + "pixelratio": 0 + } + }, + "ip": "123.123.123.123", + "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" + }, + "site": { + "page": "somePage", + "ref": "someRef", + "search": "someSearch", + "ext": { + "rp": { + "site_id": 113932 + } + }, + "publisher": { + "ext": { + "rp": { + "account_id": 1001 + } + } + } + }, + "imp": [ + { + "id": "test-imp-id", + "instl": 1, + "secure": 1, + "banner": { + "format": [ + { + "w": 300, + "h": 400 + } + ], + "ext": { + "rp": { + "mime": "text/html" + } + } + }, + "ext": { + "rp": { + "rtb": { + "formats": [ + "banner", + "video", + "native" + ] + }, + "target": { + "page": [ + "somePage" + ], + "ref": [ + "someRef" + ], + "search": [ + "someSearch" + ] + }, + "track": { + "mint": "", + "mint_version": "" + }, + "zone_id": 535510 + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "some-test-ad", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "adman" + } + ], + "cur": "USD" + } + } + }, + { + "expectedRequest": { + "uri": "uri?tk_xint=pbs-test-tracker", + "body": { + "id": "test-request-id", + "device": { + "ext": { + "rp": { + "pixelratio": 0 + } + }, + "ip": "123.123.123.123", + "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" + }, + "site": { + "page": "somePage", + "ref": "someRef", + "search": "someSearch", + "ext": { + "rp": { + "site_id": 113932 + } + }, + "publisher": { + "ext": { + "rp": { + "account_id": 1001 + } + } + } + }, + "imp": [ + { + "id": "test-imp-id", + "instl": 1, + "secure": 1, + "video": { + "placement": 3, + "ext": { + "rp": { + "size_id": 203 + } + }, + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "rp": { + "rtb": { + "formats": [ + "banner", + "video", + "native" + ] + }, + "target": { + "page": [ + "somePage" + ], + "ref": [ + "someRef" + ], + "search": [ + "someSearch" + ] + }, + "track": { + "mint": "", + "mint_version": "" + }, + "zone_id": 535510 + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id-2", + "impid": "test-imp-id", + "price": 0.9, + "adm": "some-test-ad", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "ext": { + "prebid": { + "type": "video" + } + } + } + ], + "seat": "adman" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "some-test-ad", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + }, + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test_bid_id-2", + "impid": "test-imp-id", + "price": 0.9, + "adm": "some-test-ad", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/rubicon/rubicontest/exemplary/bidonmultiformat.json b/adapters/rubicon/rubicontest/exemplary/bidonmultiformat.json index 71043771d1d..28b901bdb01 100644 --- a/adapters/rubicon/rubicontest/exemplary/bidonmultiformat.json +++ b/adapters/rubicon/rubicontest/exemplary/bidonmultiformat.json @@ -97,6 +97,12 @@ }, "ext": { "rp": { + "rtb": { + "formats": [ + "banner", + "video" + ] + }, "target": { "page": [ "somePage" @@ -203,6 +209,12 @@ }, "ext": { "rp": { + "rtb": { + "formats": [ + "banner", + "video" + ] + }, "target": { "page": [ "somePage" diff --git a/adapters/rubicon/rubicontest/exemplary/non-bidonmultiformat-with-formats-param.json b/adapters/rubicon/rubicontest/exemplary/non-bidonmultiformat-with-formats-param.json new file mode 100644 index 00000000000..a7d10421757 --- /dev/null +++ b/adapters/rubicon/rubicontest/exemplary/non-bidonmultiformat-with-formats-param.json @@ -0,0 +1,187 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" + }, + "site": { + "page": "somePage", + "ref": "someRef", + "search": "someSearch" + }, + "imp": [ + { + "id": "test-imp-id", + "instl": 1, + "banner": { + "format": [ + { + "w": 300, + "h": 400 + } + ] + }, + "video": { + "placement": 3, + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "accountId": 1001, + "siteId": 113932, + "zoneId": 535510, + "formats": [ + "banner", + "video", + "native" + ] + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "uri?tk_xint=pbs-test-tracker", + "body": { + "id": "test-request-id", + "device": { + "ext": { + "rp": { + "pixelratio": 0 + } + }, + "ip": "123.123.123.123", + "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" + }, + "site": { + "page": "somePage", + "ref": "someRef", + "search": "someSearch", + "ext": { + "rp": { + "site_id": 113932 + } + }, + "publisher": { + "ext": { + "rp": { + "account_id": 1001 + } + } + } + }, + "imp": [ + { + "id": "test-imp-id", + "instl": 1, + "secure": 1, + "banner": { + "format": [ + { + "w": 300, + "h": 400 + } + ], + "ext": { + "rp": { + "mime": "text/html" + } + } + }, + "ext": { + "rp": { + "rtb": { + "formats": [ + "banner", + "video", + "native" + ] + }, + "target": { + "page": [ + "somePage" + ], + "ref": [ + "someRef" + ], + "search": [ + "someSearch" + ] + }, + "track": { + "mint": "", + "mint_version": "" + }, + "zone_id": 535510 + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "some-test-ad", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "adman" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "some-test-ad", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/openrtb_ext/imp_rubicon.go b/openrtb_ext/imp_rubicon.go index 7264be1374c..7075b101637 100644 --- a/openrtb_ext/imp_rubicon.go +++ b/openrtb_ext/imp_rubicon.go @@ -16,6 +16,7 @@ type ExtImpRubicon struct { Video rubiconVideoParams `json:"video"` Debug impExtRubiconDebug `json:"debug,omitempty"` PChain string `json:"pchain,omitempty"` + Formats []BidType `json:"formats"` } // rubiconVideoParams defines the contract for bidrequest.imp[i].ext.prebid.bidder.rubicon.video From 3834c22f6c39035d529aede3a059fcff78489c38 Mon Sep 17 00:00:00 2001 From: Sonali-More-Xandr <87759626+Sonali-More-Xandr@users.noreply.github.com> Date: Mon, 30 Oct 2023 23:58:14 +0530 Subject: [PATCH 200/268] Revert "Rubicon: Add `imp[].ext.rp.rtb.formats` logic (#3255)" (#3268) This reverts commit 8e9f3f359416289a8b988f5d2403daf68edc4593. --- adapters/rubicon/rubicon.go | 30 +- .../bidonmultiformat-with-formats-param.json | 323 ------------------ .../exemplary/bidonmultiformat.json | 12 - ...n-bidonmultiformat-with-formats-param.json | 187 ---------- openrtb_ext/imp_rubicon.go | 1 - 5 files changed, 3 insertions(+), 550 deletions(-) delete mode 100644 adapters/rubicon/rubicontest/exemplary/bidonmultiformat-with-formats-param.json delete mode 100644 adapters/rubicon/rubicontest/exemplary/non-bidonmultiformat-with-formats-param.json diff --git a/adapters/rubicon/rubicon.go b/adapters/rubicon/rubicon.go index 431359c0b33..7d09224e8b4 100644 --- a/adapters/rubicon/rubicon.go +++ b/adapters/rubicon/rubicon.go @@ -87,11 +87,6 @@ type rubiconImpExtRP struct { ZoneID int `json:"zone_id"` Target json.RawMessage `json:"target,omitempty"` Track rubiconImpExtRPTrack `json:"track"` - RTB *rubiconImpExtRpRtb `json:"rtb,omitempty"` -} - -type rubiconImpExtRpRtb struct { - Formats []openrtb_ext.BidType `json:"formats,omitempty"` } type rubiconUserExtRP struct { @@ -304,10 +299,6 @@ func (a *RubiconAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ada Skadn: bidderExt.Skadn, } - if len(bidderExt.Bidder.Formats) > 0 { - impExt.RP.RTB = &rubiconImpExtRpRtb{bidderExt.Bidder.Formats} - } - imp.Ext, err = json.Marshal(&impExt) if err != nil { errs = append(errs, err) @@ -601,19 +592,9 @@ func prepareImpsToExtMap(impsToExtMap map[*openrtb2.Imp]rubiconExtImpBidder) map continue } - splitImps, formats := splitMultiFormatImp(imp) + splitImps := splitMultiFormatImp(imp) for _, imp := range splitImps { impCopy := imp - - existingFormats := bidderExt.Bidder.Formats - var resolvedFormats []openrtb_ext.BidType - if len(existingFormats) > 0 { - resolvedFormats = existingFormats - } else { - resolvedFormats = formats - } - bidderExt.Bidder.Formats = resolvedFormats - preparedImpsToExtMap[impCopy] = bidderExt } } @@ -621,11 +602,9 @@ func prepareImpsToExtMap(impsToExtMap map[*openrtb2.Imp]rubiconExtImpBidder) map return preparedImpsToExtMap } -func splitMultiFormatImp(imp *openrtb2.Imp) ([]*openrtb2.Imp, []openrtb_ext.BidType) { +func splitMultiFormatImp(imp *openrtb2.Imp) []*openrtb2.Imp { splitImps := make([]*openrtb2.Imp, 0) - mediaTypes := make([]openrtb_ext.BidType, 0) if imp.Banner != nil { - mediaTypes = append(mediaTypes, openrtb_ext.BidTypeBanner) impCopy := *imp impCopy.Video = nil impCopy.Native = nil @@ -634,7 +613,6 @@ func splitMultiFormatImp(imp *openrtb2.Imp) ([]*openrtb2.Imp, []openrtb_ext.BidT } if imp.Video != nil { - mediaTypes = append(mediaTypes, openrtb_ext.BidTypeVideo) impCopy := *imp impCopy.Banner = nil impCopy.Native = nil @@ -643,7 +621,6 @@ func splitMultiFormatImp(imp *openrtb2.Imp) ([]*openrtb2.Imp, []openrtb_ext.BidT } if imp.Native != nil { - mediaTypes = append(mediaTypes, openrtb_ext.BidTypeNative) impCopy := *imp impCopy.Banner = nil impCopy.Video = nil @@ -652,7 +629,6 @@ func splitMultiFormatImp(imp *openrtb2.Imp) ([]*openrtb2.Imp, []openrtb_ext.BidT } if imp.Audio != nil { - mediaTypes = append(mediaTypes, openrtb_ext.BidTypeAudio) impCopy := *imp impCopy.Banner = nil impCopy.Video = nil @@ -660,7 +636,7 @@ func splitMultiFormatImp(imp *openrtb2.Imp) ([]*openrtb2.Imp, []openrtb_ext.BidT splitImps = append(splitImps, &impCopy) } - return splitImps, mediaTypes + return splitImps } func resolveBidFloor(bidFloor float64, bidFloorCur string, reqInfo *adapters.ExtraRequestInfo) (float64, error) { diff --git a/adapters/rubicon/rubicontest/exemplary/bidonmultiformat-with-formats-param.json b/adapters/rubicon/rubicontest/exemplary/bidonmultiformat-with-formats-param.json deleted file mode 100644 index 72efd23e298..00000000000 --- a/adapters/rubicon/rubicontest/exemplary/bidonmultiformat-with-formats-param.json +++ /dev/null @@ -1,323 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "device": { - "ip": "123.123.123.123", - "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" - }, - "site": { - "page": "somePage", - "ref": "someRef", - "search": "someSearch" - }, - "imp": [ - { - "id": "test-imp-id", - "instl": 1, - "banner": { - "format": [ - { - "w": 300, - "h": 400 - } - ] - }, - "video": { - "placement": 3, - "mimes": [ - "video/mp4" - ], - "protocols": [ - 2, - 5 - ], - "w": 1024, - "h": 576 - }, - "ext": { - "bidder": { - "bidonmultiformat": true, - "accountId": 1001, - "siteId": 113932, - "zoneId": 535510, - "formats": [ - "banner", - "video", - "native" - ] - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "uri?tk_xint=pbs-test-tracker", - "body": { - "id": "test-request-id", - "device": { - "ext": { - "rp": { - "pixelratio": 0 - } - }, - "ip": "123.123.123.123", - "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" - }, - "site": { - "page": "somePage", - "ref": "someRef", - "search": "someSearch", - "ext": { - "rp": { - "site_id": 113932 - } - }, - "publisher": { - "ext": { - "rp": { - "account_id": 1001 - } - } - } - }, - "imp": [ - { - "id": "test-imp-id", - "instl": 1, - "secure": 1, - "banner": { - "format": [ - { - "w": 300, - "h": 400 - } - ], - "ext": { - "rp": { - "mime": "text/html" - } - } - }, - "ext": { - "rp": { - "rtb": { - "formats": [ - "banner", - "video", - "native" - ] - }, - "target": { - "page": [ - "somePage" - ], - "ref": [ - "someRef" - ], - "search": [ - "someSearch" - ] - }, - "track": { - "mint": "", - "mint_version": "" - }, - "zone_id": 535510 - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "bid": [ - { - "id": "test_bid_id", - "impid": "test-imp-id", - "price": 0.27543, - "adm": "some-test-ad", - "cid": "test_cid", - "crid": "test_crid", - "dealid": "test_dealid", - "ext": { - "prebid": { - "type": "banner" - } - } - } - ], - "seat": "adman" - } - ], - "cur": "USD" - } - } - }, - { - "expectedRequest": { - "uri": "uri?tk_xint=pbs-test-tracker", - "body": { - "id": "test-request-id", - "device": { - "ext": { - "rp": { - "pixelratio": 0 - } - }, - "ip": "123.123.123.123", - "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" - }, - "site": { - "page": "somePage", - "ref": "someRef", - "search": "someSearch", - "ext": { - "rp": { - "site_id": 113932 - } - }, - "publisher": { - "ext": { - "rp": { - "account_id": 1001 - } - } - } - }, - "imp": [ - { - "id": "test-imp-id", - "instl": 1, - "secure": 1, - "video": { - "placement": 3, - "ext": { - "rp": { - "size_id": 203 - } - }, - "mimes": [ - "video/mp4" - ], - "protocols": [ - 2, - 5 - ], - "w": 1024, - "h": 576 - }, - "ext": { - "rp": { - "rtb": { - "formats": [ - "banner", - "video", - "native" - ] - }, - "target": { - "page": [ - "somePage" - ], - "ref": [ - "someRef" - ], - "search": [ - "someSearch" - ] - }, - "track": { - "mint": "", - "mint_version": "" - }, - "zone_id": 535510 - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "bid": [ - { - "id": "test_bid_id-2", - "impid": "test-imp-id", - "price": 0.9, - "adm": "some-test-ad", - "cid": "test_cid", - "crid": "test_crid", - "dealid": "test_dealid", - "ext": { - "prebid": { - "type": "video" - } - } - } - ], - "seat": "adman" - } - ], - "cur": "USD" - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "test_bid_id", - "impid": "test-imp-id", - "price": 0.27543, - "adm": "some-test-ad", - "cid": "test_cid", - "crid": "test_crid", - "dealid": "test_dealid", - "ext": { - "prebid": { - "type": "banner" - } - } - }, - "type": "banner" - } - ] - }, - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "test_bid_id-2", - "impid": "test-imp-id", - "price": 0.9, - "adm": "some-test-ad", - "cid": "test_cid", - "crid": "test_crid", - "dealid": "test_dealid", - "ext": { - "prebid": { - "type": "video" - } - } - }, - "type": "video" - } - ] - } - ] -} diff --git a/adapters/rubicon/rubicontest/exemplary/bidonmultiformat.json b/adapters/rubicon/rubicontest/exemplary/bidonmultiformat.json index 28b901bdb01..71043771d1d 100644 --- a/adapters/rubicon/rubicontest/exemplary/bidonmultiformat.json +++ b/adapters/rubicon/rubicontest/exemplary/bidonmultiformat.json @@ -97,12 +97,6 @@ }, "ext": { "rp": { - "rtb": { - "formats": [ - "banner", - "video" - ] - }, "target": { "page": [ "somePage" @@ -209,12 +203,6 @@ }, "ext": { "rp": { - "rtb": { - "formats": [ - "banner", - "video" - ] - }, "target": { "page": [ "somePage" diff --git a/adapters/rubicon/rubicontest/exemplary/non-bidonmultiformat-with-formats-param.json b/adapters/rubicon/rubicontest/exemplary/non-bidonmultiformat-with-formats-param.json deleted file mode 100644 index a7d10421757..00000000000 --- a/adapters/rubicon/rubicontest/exemplary/non-bidonmultiformat-with-formats-param.json +++ /dev/null @@ -1,187 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "device": { - "ip": "123.123.123.123", - "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" - }, - "site": { - "page": "somePage", - "ref": "someRef", - "search": "someSearch" - }, - "imp": [ - { - "id": "test-imp-id", - "instl": 1, - "banner": { - "format": [ - { - "w": 300, - "h": 400 - } - ] - }, - "video": { - "placement": 3, - "mimes": [ - "video/mp4" - ], - "protocols": [ - 2, - 5 - ], - "w": 1024, - "h": 576 - }, - "ext": { - "bidder": { - "accountId": 1001, - "siteId": 113932, - "zoneId": 535510, - "formats": [ - "banner", - "video", - "native" - ] - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "uri?tk_xint=pbs-test-tracker", - "body": { - "id": "test-request-id", - "device": { - "ext": { - "rp": { - "pixelratio": 0 - } - }, - "ip": "123.123.123.123", - "ifa": "zxcjbzxmc-zxcbmz-zxbcz-zxczx" - }, - "site": { - "page": "somePage", - "ref": "someRef", - "search": "someSearch", - "ext": { - "rp": { - "site_id": 113932 - } - }, - "publisher": { - "ext": { - "rp": { - "account_id": 1001 - } - } - } - }, - "imp": [ - { - "id": "test-imp-id", - "instl": 1, - "secure": 1, - "banner": { - "format": [ - { - "w": 300, - "h": 400 - } - ], - "ext": { - "rp": { - "mime": "text/html" - } - } - }, - "ext": { - "rp": { - "rtb": { - "formats": [ - "banner", - "video", - "native" - ] - }, - "target": { - "page": [ - "somePage" - ], - "ref": [ - "someRef" - ], - "search": [ - "someSearch" - ] - }, - "track": { - "mint": "", - "mint_version": "" - }, - "zone_id": 535510 - } - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "bid": [ - { - "id": "test_bid_id", - "impid": "test-imp-id", - "price": 0.27543, - "adm": "some-test-ad", - "cid": "test_cid", - "crid": "test_crid", - "dealid": "test_dealid", - "ext": { - "prebid": { - "type": "banner" - } - } - } - ], - "seat": "adman" - } - ], - "cur": "USD" - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "test_bid_id", - "impid": "test-imp-id", - "price": 0.27543, - "adm": "some-test-ad", - "cid": "test_cid", - "crid": "test_crid", - "dealid": "test_dealid", - "ext": { - "prebid": { - "type": "banner" - } - } - }, - "type": "banner" - } - ] - } - ] -} diff --git a/openrtb_ext/imp_rubicon.go b/openrtb_ext/imp_rubicon.go index 7075b101637..7264be1374c 100644 --- a/openrtb_ext/imp_rubicon.go +++ b/openrtb_ext/imp_rubicon.go @@ -16,7 +16,6 @@ type ExtImpRubicon struct { Video rubiconVideoParams `json:"video"` Debug impExtRubiconDebug `json:"debug,omitempty"` PChain string `json:"pchain,omitempty"` - Formats []BidType `json:"formats"` } // rubiconVideoParams defines the contract for bidrequest.imp[i].ext.prebid.bidder.rubicon.video From 72463be04b6e9a5b969839024f43899fd8be533f Mon Sep 17 00:00:00 2001 From: Brian Sardo <1168933+bsardo@users.noreply.github.com> Date: Mon, 30 Oct 2023 15:21:56 -0400 Subject: [PATCH 201/268] Revert "RTBHouse: native support (#3212)" (#3271) This reverts commit 2540dd884950f6c582d01263479f3e7973cda2eb. --- adapters/rtbhouse/rtbhouse.go | 65 +------- .../bidfloor-as-bidder-param-without-cur.json | 130 ---------------- .../exemplary/bidfloor-as-bidder-param.json | 133 ----------------- .../bidfloor-as-impbidfloor-with-cur.json | 130 ---------------- .../bidfloor-as-impbidfloor-without-cur.json | 128 ---------------- .../exemplary/currency-conversion.json | 123 +++++++++++++++ .../native-with-deprecated-native-prop.json | 100 ------------- .../native-with-proper-native-response.json | 100 ------------- .../rtbhousetest/exemplary/simple-banner.json | 6 +- ...bidfloors-given-param-and-impbidfloor.json | 132 ---------------- ...ner-native-req-faulty-mtype-in-native.json | 141 ------------------ .../faulty-request-bidder-params.json | 30 ---- .../faulty-request-no-impext.json | 25 ---- .../native-with-faulty-adm-native-prop.json | 90 ----------- .../native-with-faulty-adm-response.json | 90 ----------- .../supplemental/simple-banner-bad-mtype.json | 94 ------------ .../supplemental/simple-banner-no-mtype.json | 93 ------------ static/bidder-info/rtbhouse.yaml | 1 - 18 files changed, 130 insertions(+), 1481 deletions(-) delete mode 100644 adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param-without-cur.json delete mode 100644 adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param.json delete mode 100644 adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-with-cur.json delete mode 100644 adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-without-cur.json create mode 100644 adapters/rtbhouse/rtbhousetest/exemplary/currency-conversion.json delete mode 100644 adapters/rtbhouse/rtbhousetest/exemplary/native-with-deprecated-native-prop.json delete mode 100644 adapters/rtbhouse/rtbhousetest/exemplary/native-with-proper-native-response.json delete mode 100644 adapters/rtbhouse/rtbhousetest/exemplary/two-bidfloors-given-param-and-impbidfloor.json delete mode 100644 adapters/rtbhouse/rtbhousetest/supplemental/banner-native-req-faulty-mtype-in-native.json delete mode 100644 adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-bidder-params.json delete mode 100644 adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-no-impext.json delete mode 100644 adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-native-prop.json delete mode 100644 adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-response.json delete mode 100644 adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-bad-mtype.json delete mode 100644 adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-no-mtype.json diff --git a/adapters/rtbhouse/rtbhouse.go b/adapters/rtbhouse/rtbhouse.go index 92e0e57b287..089634cbd86 100644 --- a/adapters/rtbhouse/rtbhouse.go +++ b/adapters/rtbhouse/rtbhouse.go @@ -2,12 +2,10 @@ package rtbhouse import ( "encoding/json" - "errors" "fmt" "net/http" "strings" - "github.com/buger/jsonparser" "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/v2/adapters" "github.com/prebid/prebid-server/v2/config" @@ -51,12 +49,9 @@ func (adapter *RTBHouseAdapter) MakeRequests( if err != nil { return nil, []error{err} } - if rtbhouseExt.BidFloor > 0 { + if rtbhouseExt.BidFloor > 0 && len(reqCopy.Cur) > 0 { + bidFloorCur = reqCopy.Cur[0] bidFloor = rtbhouseExt.BidFloor - bidFloorCur = BidderCurrency - if len(reqCopy.Cur) > 0 { - bidFloorCur = reqCopy.Cur[0] - } } } @@ -161,63 +156,13 @@ func (adapter *RTBHouseAdapter) MakeBids( for _, seatBid := range openRTBBidderResponse.SeatBid { for _, bid := range seatBid.Bid { bid := bid // pin! -> https://github.com/kyoh86/scopelint#whats-this - bidType, err := getMediaTypeForBid(bid) - if err != nil { - errs = append(errs, err) - continue - } else { - typedBid = &adapters.TypedBid{ - Bid: &bid, - BidType: bidType, - } - - // for native bid responses fix Adm field - if typedBid.BidType == openrtb_ext.BidTypeNative { - bid.AdM, err = getNativeAdm(bid.AdM) - if err != nil { - errs = append(errs, err) - continue - } - } - - bidderResponse.Bids = append(bidderResponse.Bids, typedBid) - } + typedBid = &adapters.TypedBid{Bid: &bid, BidType: "banner"} + bidderResponse.Bids = append(bidderResponse.Bids, typedBid) } } bidderResponse.Currency = BidderCurrency - return bidderResponse, errs - -} - -func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { - switch bid.MType { - case openrtb2.MarkupBanner: - return openrtb_ext.BidTypeBanner, nil - case openrtb2.MarkupNative: - return openrtb_ext.BidTypeNative, nil - default: - return "", fmt.Errorf("unrecognized bid type in response from rtbhouse for bid %s", bid.ImpID) - } -} - -func getNativeAdm(adm string) (string, error) { - nativeAdm := make(map[string]interface{}) - err := json.Unmarshal([]byte(adm), &nativeAdm) - if err != nil { - return adm, errors.New("unable to unmarshal native adm") - } - - // move bid.adm.native to bid.adm - if _, ok := nativeAdm["native"]; ok { - //using jsonparser to avoid marshaling, encode escape, etc. - value, dataType, _, err := jsonparser.Get([]byte(adm), string(openrtb_ext.BidTypeNative)) - if err != nil || dataType != jsonparser.Object { - return adm, errors.New("unable to get native adm") - } - adm = string(value) - } + return bidderResponse, nil - return adm, nil } diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param-without-cur.json b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param-without-cur.json deleted file mode 100644 index 79aa038c3ca..00000000000 --- a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param-without-cur.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": { - "publisherId": "12345", - "bidfloor": 3.00 - } - } - } - ], - "ext": { - "prebid": { - "currency": { - "rates": { - "EUR": { - "USD": 0.05 - } - }, - "usepbsrates": false - } - } - } - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://localhost/prebid_server", - "body": { - "id": "test-request-id", - "cur": [ - "USD" - ], - "imp": [ - { - "banner": { - "format": [ - { - "h": 250, - "w": 300 - } - ] - }, - "bidfloor": 3.00, - "bidfloorcur": "USD", - "ext": { - "bidder": { - "publisherId": "12345", - "bidfloor": 3.00 - } - }, - "id": "test-imp-id" - } - ], - "ext": { - "prebid": { - "currency": { - "rates": { - "EUR": { - "USD": 0.05 - } - }, - "usepbsrates": false - } - } - } - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-response-id", - "cur": "USD", - "seatbid": [ - { - "seat": "rtbhouse", - "bid": [ - { - "id": "randomid", - "impid": "test-imp-id", - "price": 300, - "adid": "12345678", - "adm": "some-test-ad", - "cid": "987", - "crid": "12345678", - "h": 250, - "w": 300, - "mtype": 1 - } - ] - } - ] - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "randomid", - "impid": "test-imp-id", - "price": 300, - "adid": "12345678", - "adm": "some-test-ad", - "cid": "987", - "crid": "12345678", - "h": 250, - "w": 300, - "mtype": 1 - }, - "type": "banner" - } - ] - } - ] -} diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param.json b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param.json deleted file mode 100644 index 99b3a87ebfa..00000000000 --- a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param.json +++ /dev/null @@ -1,133 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "cur": [ - "EUR" - ], - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": { - "publisherId": "12345", - "bidfloor": 2 - } - } - } - ], - "ext": { - "prebid": { - "currency": { - "rates": { - "EUR": { - "USD": 0.05 - } - }, - "usepbsrates": false - } - } - } - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://localhost/prebid_server", - "body": { - "id": "test-request-id", - "cur": [ - "USD" - ], - "imp": [ - { - "banner": { - "format": [ - { - "h": 250, - "w": 300 - } - ] - }, - "bidfloor": 0.1, - "bidfloorcur": "USD", - "ext": { - "bidder": { - "publisherId": "12345", - "bidfloor": 2 - } - }, - "id": "test-imp-id" - } - ], - "ext": { - "prebid": { - "currency": { - "rates": { - "EUR": { - "USD": 0.05 - } - }, - "usepbsrates": false - } - } - } - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-response-id", - "cur": "USD", - "seatbid": [ - { - "seat": "rtbhouse", - "bid": [ - { - "id": "randomid", - "impid": "test-imp-id", - "price": 300, - "adid": "12345678", - "adm": "some-test-ad", - "cid": "987", - "crid": "12345678", - "h": 250, - "w": 300, - "mtype": 1 - } - ] - } - ] - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "randomid", - "impid": "test-imp-id", - "price": 300, - "adid": "12345678", - "adm": "some-test-ad", - "cid": "987", - "crid": "12345678", - "h": 250, - "w": 300, - "mtype": 1 - }, - "type": "banner" - } - ] - } - ] -} diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-with-cur.json b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-with-cur.json deleted file mode 100644 index 85e8a1c28cf..00000000000 --- a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-with-cur.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "bidfloor": 1.00, - "bidfloorcur": "EUR", - "ext": { - "bidder": { - "publisherId": "12345" - } - } - } - ], - "ext": { - "prebid": { - "currency": { - "rates": { - "EUR": { - "USD": 0.05 - } - }, - "usepbsrates": false - } - } - } - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://localhost/prebid_server", - "body": { - "id": "test-request-id", - "cur": [ - "USD" - ], - "imp": [ - { - "banner": { - "format": [ - { - "h": 250, - "w": 300 - } - ] - }, - "bidfloor": 0.05, - "bidfloorcur": "USD", - "ext": { - "bidder": { - "publisherId": "12345" - } - }, - "id": "test-imp-id" - } - ], - "ext": { - "prebid": { - "currency": { - "rates": { - "EUR": { - "USD": 0.05 - } - }, - "usepbsrates": false - } - } - } - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-response-id", - "cur": "USD", - "seatbid": [ - { - "seat": "rtbhouse", - "bid": [ - { - "id": "randomid", - "impid": "test-imp-id", - "price": 300, - "adid": "12345678", - "adm": "some-test-ad", - "cid": "987", - "crid": "12345678", - "h": 250, - "w": 300, - "mtype": 1 - } - ] - } - ] - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "randomid", - "impid": "test-imp-id", - "price": 300, - "adid": "12345678", - "adm": "some-test-ad", - "cid": "987", - "crid": "12345678", - "h": 250, - "w": 300, - "mtype": 1 - }, - "type": "banner" - } - ] - } - ] -} diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-without-cur.json b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-without-cur.json deleted file mode 100644 index 1417965741e..00000000000 --- a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-without-cur.json +++ /dev/null @@ -1,128 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "bidfloor": 1.00, - "ext": { - "bidder": { - "publisherId": "12345" - } - } - } - ], - "ext": { - "prebid": { - "currency": { - "rates": { - "EUR": { - "USD": 0.05 - } - }, - "usepbsrates": false - } - } - } - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://localhost/prebid_server", - "body": { - "id": "test-request-id", - "cur": [ - "USD" - ], - "imp": [ - { - "banner": { - "format": [ - { - "h": 250, - "w": 300 - } - ] - }, - "bidfloor": 1, - "ext": { - "bidder": { - "publisherId": "12345" - } - }, - "id": "test-imp-id" - } - ], - "ext": { - "prebid": { - "currency": { - "rates": { - "EUR": { - "USD": 0.05 - } - }, - "usepbsrates": false - } - } - } - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-response-id", - "cur": "USD", - "seatbid": [ - { - "seat": "rtbhouse", - "bid": [ - { - "id": "randomid", - "impid": "test-imp-id", - "price": 300, - "adid": "12345678", - "adm": "some-test-ad", - "cid": "987", - "crid": "12345678", - "h": 250, - "w": 300, - "mtype": 1 - } - ] - } - ] - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "randomid", - "impid": "test-imp-id", - "price": 300, - "adid": "12345678", - "adm": "some-test-ad", - "cid": "987", - "crid": "12345678", - "h": 250, - "w": 300, - "mtype": 1 - }, - "type": "banner" - } - ] - } - ] -} diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/currency-conversion.json b/adapters/rtbhouse/rtbhousetest/exemplary/currency-conversion.json new file mode 100644 index 00000000000..95bfb1e4420 --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/exemplary/currency-conversion.json @@ -0,0 +1,123 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "bidfloor": 1.00, + "bidfloorcur": "EUR", + "ext": { + "bidder": { + "placementId": "12345" + } + } + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server", + "body": { + "id": "test-request-id", + "cur": ["USD"], + "imp": [ + { + "banner": { + "format": [ + { + "h": 250, + "w": 300 + } + ] + }, + "bidfloor": 0.05, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "placementId": "12345" + } + }, + "id": "test-imp-id" + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "cur": "USD", + "seatbid": [{ + "seat": "rtbhouse", + "bid": [{ + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300 + } + ] + }] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid", + "impid": "test-imp-id", + "price": 300, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300 + }, + "type": "banner" + } + ] + } + ] + } diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/native-with-deprecated-native-prop.json b/adapters/rtbhouse/rtbhousetest/exemplary/native-with-deprecated-native-prop.json deleted file mode 100644 index e79b21a1207..00000000000 --- a/adapters/rtbhouse/rtbhousetest/exemplary/native-with-deprecated-native-prop.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "mockBidRequest": { - "imp": [ - { - "ext": { - "bidder": {} - }, - "id": "test-native-imp", - "native": { - "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", - "ver": "1.2" - } - } - ], - "site": { - "page": "https://good.site/url" - }, - "id": "test-native-request", - "ext": {}, - "debug": 1 - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://localhost/prebid_server", - "body": { - "id": "test-native-request", - "cur": [ - "USD" - ], - "imp": [ - { - "id": "test-native-imp", - "native": { - "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", - "ver": "1.2" - }, - "ext": { - "bidder": {} - } - } - ], - "site": { - "page": "https://good.site/url" - }, - "ext": {} - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-native-request", - "bidid": "test-bidid", - "cur": "USD", - "seatbid": [ - { - "seat": "rtbhouse", - "bid": [ - { - "id": "test-native-request", - "impid": "test-native-imp", - "price": 0.5, - "adid": "test-adid", - "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"title text\"}},{\"id\":1,\"data\":{\"value\":\"data value\"}},{\"id\":2,\"img\":{\"url\":\"image.url\",\"w\":1200,\"h\":628}}],\"link\":{\"url\":\"link.url\"},\"imptrackers\":[\"imp.tracker.url\"],\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"event.tracker.url\"}]}}", - "adomain": [ "adomain.com" ], - "cid": "test-cid", - "crid": "test-crid", - "dealid": "test-dealid", - "mtype": 4 - } - ] - } - ] - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "test-native-request", - "impid": "test-native-imp", - "price": 0.5, - "adid": "test-adid", - "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"title text\"}},{\"id\":1,\"data\":{\"value\":\"data value\"}},{\"id\":2,\"img\":{\"url\":\"image.url\",\"w\":1200,\"h\":628}}],\"link\":{\"url\":\"link.url\"},\"imptrackers\":[\"imp.tracker.url\"],\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"event.tracker.url\"}]}", - "adomain": [ "adomain.com" ], - "cid": "test-cid", - "crid": "test-crid", - "dealid": "test-dealid", - "mtype": 4 - }, - "type": "native" - } - ] - } - ] -} diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/native-with-proper-native-response.json b/adapters/rtbhouse/rtbhousetest/exemplary/native-with-proper-native-response.json deleted file mode 100644 index 9f5962fd3a1..00000000000 --- a/adapters/rtbhouse/rtbhousetest/exemplary/native-with-proper-native-response.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "mockBidRequest": { - "imp": [ - { - "ext": { - "bidder": {} - }, - "id": "test-native-imp", - "native": { - "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", - "ver": "1.2" - } - } - ], - "site": { - "page": "https://good.site/url" - }, - "id": "test-native-request", - "ext": {}, - "debug": 1 - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://localhost/prebid_server", - "body": { - "id": "test-native-request", - "cur": [ - "USD" - ], - "imp": [ - { - "id": "test-native-imp", - "native": { - "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", - "ver": "1.2" - }, - "ext": { - "bidder": {} - } - } - ], - "site": { - "page": "https://good.site/url" - }, - "ext": {} - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-native-request", - "bidid": "test-bidid", - "cur": "USD", - "seatbid": [ - { - "seat": "rtbhouse", - "bid": [ - { - "id": "test-native-request", - "impid": "test-native-imp", - "price": 0.5, - "adid": "test-adid", - "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"title text\"}},{\"id\":1,\"data\":{\"value\":\"data value\"}},{\"id\":2,\"img\":{\"url\":\"image.url\",\"w\":1200,\"h\":628}}],\"link\":{\"url\":\"link.url\"},\"imptrackers\":[\"imp.tracker.url\"],\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"event.tracker.url\"}]}", - "adomain": [ "adomain.com" ], - "cid": "test-cid", - "crid": "test-crid", - "dealid": "test-dealid", - "mtype": 4 - } - ] - } - ] - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "test-native-request", - "impid": "test-native-imp", - "price": 0.5, - "adid": "test-adid", - "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"title text\"}},{\"id\":1,\"data\":{\"value\":\"data value\"}},{\"id\":2,\"img\":{\"url\":\"image.url\",\"w\":1200,\"h\":628}}],\"link\":{\"url\":\"link.url\"},\"imptrackers\":[\"imp.tracker.url\"],\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"event.tracker.url\"}]}", - "adomain": [ "adomain.com" ], - "cid": "test-cid", - "crid": "test-crid", - "dealid": "test-dealid", - "mtype": 4 - }, - "type": "native" - } - ] - } - ] -} diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json b/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json index 468e73f2aca..2a8c4681ffa 100644 --- a/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json +++ b/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json @@ -56,8 +56,7 @@ "cid": "987", "crid": "12345678", "h": 250, - "w": 300, - "mtype": 1 + "w": 300 }] }], "cur": "USD" @@ -77,8 +76,7 @@ "cid": "987", "crid": "12345678", "w": 300, - "h": 250, - "mtype": 1 + "h": 250 }, "type": "banner" }] diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/two-bidfloors-given-param-and-impbidfloor.json b/adapters/rtbhouse/rtbhousetest/exemplary/two-bidfloors-given-param-and-impbidfloor.json deleted file mode 100644 index fc706d97004..00000000000 --- a/adapters/rtbhouse/rtbhousetest/exemplary/two-bidfloors-given-param-and-impbidfloor.json +++ /dev/null @@ -1,132 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "bidfloor": 1.00, - "bidfloorcur": "EUR", - "ext": { - "bidder": { - "publisherId": "12345", - "bidfloor": 2.00 - } - } - } - ], - "ext": { - "prebid": { - "currency": { - "rates": { - "EUR": { - "USD": 0.05 - } - }, - "usepbsrates": false - } - } - } - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://localhost/prebid_server", - "body": { - "id": "test-request-id", - "cur": [ - "USD" - ], - "imp": [ - { - "banner": { - "format": [ - { - "h": 250, - "w": 300 - } - ] - }, - "bidfloor": 0.05, - "bidfloorcur": "USD", - "ext": { - "bidder": { - "publisherId": "12345", - "bidfloor": 2 - } - }, - "id": "test-imp-id" - } - ], - "ext": { - "prebid": { - "currency": { - "rates": { - "EUR": { - "USD": 0.05 - } - }, - "usepbsrates": false - } - } - } - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-response-id", - "cur": "USD", - "seatbid": [ - { - "seat": "rtbhouse", - "bid": [ - { - "id": "randomid", - "impid": "test-imp-id", - "price": 300, - "adid": "12345678", - "adm": "some-test-ad", - "cid": "987", - "crid": "12345678", - "h": 250, - "w": 300, - "mtype": 1 - } - ] - } - ] - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "randomid", - "impid": "test-imp-id", - "price": 300, - "adid": "12345678", - "adm": "some-test-ad", - "cid": "987", - "crid": "12345678", - "h": 250, - "w": 300, - "mtype": 1 - }, - "type": "banner" - } - ] - } - ] -} diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/banner-native-req-faulty-mtype-in-native.json b/adapters/rtbhouse/rtbhousetest/supplemental/banner-native-req-faulty-mtype-in-native.json deleted file mode 100644 index 6e6f415acbc..00000000000 --- a/adapters/rtbhouse/rtbhousetest/supplemental/banner-native-req-faulty-mtype-in-native.json +++ /dev/null @@ -1,141 +0,0 @@ -{ - "mockBidRequest": { - "imp": [ - { - "ext": { - "bidder": {} - }, - "id": "test-native-imp", - "native": { - "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", - "ver": "1.2" - } - }, - { - "id": "test-banner-imp", - "banner": { - "format": [{ - "w": 300, - "h": 250 - }] - }, - "ext": { - "bidder": {} - } - } - ], - "site": { - "page": "https://good.site/url" - }, - "id": "test-multi-slot-request", - "ext": {}, - "debug": 1 - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://localhost/prebid_server", - "body": { - "id": "test-multi-slot-request", - "cur": [ - "USD" - ], - "imp": [ - { - "id": "test-native-imp", - "native": { - "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", - "ver": "1.2" - }, - "ext": { - "bidder": {} - } - }, - { - "id": "test-banner-imp", - "banner": { - "format": [{ - "w": 300, - "h": 250 - }] - }, - "ext": { - "bidder": {} - } - } - ], - "site": { - "page": "https://good.site/url" - }, - "ext": {} - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-multi-slot-request", - "bidid": "test-bidid", - "cur": "USD", - "seatbid": [ - { - "seat": "rtbhouse", - "bid": [ - { - "id": "randomid-native", - "impid": "test-native-imp", - "price": 0.5, - "adid": "test-adid", - "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"title text\"}},{\"id\":1,\"data\":{\"value\":\"data value\"}},{\"id\":2,\"img\":{\"url\":\"image.url\",\"w\":1200,\"h\":628}}],\"link\":{\"url\":\"link.url\"},\"imptrackers\":[\"imp.tracker.url\"],\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"event.tracker.url\"}]}}", - "adomain": [ "adomain.com" ], - "cid": "test-cid", - "crid": "test-crid", - "dealid": "test-dealid", - "mtype": 99 - }, - { - "id": "randomid-banner", - "impid": "test-banner-imp", - "price": 0.500000, - "adid": "12345678", - "adm": "some-test-ad", - "cid": "987", - "crid": "12345678", - "h": 250, - "w": 300, - "mtype": 1 - } - ] - } - ] - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [{ - "bid": { - "id": "randomid-banner", - "impid": "test-banner-imp", - "price": 0.500000, - "adid": "12345678", - "adm": "some-test-ad", - "cid": "987", - "crid": "12345678", - "h": 250, - "w": 300, - "mtype": 1 - }, - "type": "banner" - } - ] - } - ], - "expectedMakeBidsErrors": [ - { - "value": "unrecognized bid type in response from rtbhouse for bid test-native-imp", - "comparison": "literal" - } - ] -} diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-bidder-params.json b/adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-bidder-params.json deleted file mode 100644 index 70fddf620e6..00000000000 --- a/adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-bidder-params.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "banner-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": { - "publisherId": 12345 - } - } - } - ], - "ext": {} - }, - "expectedMakeRequestsErrors": [ - { - "value": "Error while unmarshaling bidder extension", - "comparison": "literal" - } - ] -} diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-no-impext.json b/adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-no-impext.json deleted file mode 100644 index f416f8106fa..00000000000 --- a/adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-no-impext.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "banner-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - } - } - ], - "ext": {} - }, - "expectedMakeRequestsErrors": [ - { - "value": "Bidder extension not provided or can't be unmarshalled", - "comparison": "literal" - } - ] -} diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-native-prop.json b/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-native-prop.json deleted file mode 100644 index 5e1aa0ef4b7..00000000000 --- a/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-native-prop.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "mockBidRequest": { - "imp": [ - { - "ext": { - "bidder": {} - }, - "id": "test-native-imp", - "native": { - "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", - "ver": "1.2" - } - } - ], - "site": { - "page": "https://good.site/url" - }, - "id": "test-native-request", - "ext": {}, - "debug": 1 - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://localhost/prebid_server", - "body": { - "id": "test-native-request", - "cur": [ - "USD" - ], - "imp": [ - { - "id": "test-native-imp", - "native": { - "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", - "ver": "1.2" - }, - "ext": { - "bidder": {} - } - } - ], - "site": { - "page": "https://good.site/url" - }, - "ext": {} - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-native-request", - "bidid": "test-bidid", - "cur": "USD", - "seatbid": [ - { - "seat": "rtbhouse", - "bid": [ - { - "id": "test-native-request", - "impid": "test-native-imp", - "price": 0.5, - "adid": "test-adid", - "adm": "{\"native\":\"faulty object\"}", - "adomain": [ "adomain.com" ], - "cid": "test-cid", - "crid": "test-crid", - "dealid": "test-dealid", - "mtype": 4 - } - ] - } - ] - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [] - } - ], - "expectedMakeBidsErrors": [ - { - "value": "unable to get native adm", - "comparison": "literal" - } - ] -} diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-response.json b/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-response.json deleted file mode 100644 index 41cc909f304..00000000000 --- a/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-response.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "mockBidRequest": { - "imp": [ - { - "ext": { - "bidder": {} - }, - "id": "test-native-imp", - "native": { - "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", - "ver": "1.2" - } - } - ], - "site": { - "page": "https://good.site/url" - }, - "id": "test-native-request", - "ext": {}, - "debug": 1 - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://localhost/prebid_server", - "body": { - "id": "test-native-request", - "cur": [ - "USD" - ], - "imp": [ - { - "id": "test-native-imp", - "native": { - "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}", - "ver": "1.2" - }, - "ext": { - "bidder": {} - } - } - ], - "site": { - "page": "https://good.site/url" - }, - "ext": {} - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-native-request", - "bidid": "test-bidid", - "cur": "USD", - "seatbid": [ - { - "seat": "rtbhouse", - "bid": [ - { - "id": "test-native-request", - "impid": "test-native-imp", - "price": 0.5, - "adid": "test-adid", - "adm": "{\"ver\":\"1.2\"", - "adomain": [ "adomain.com" ], - "cid": "test-cid", - "crid": "test-crid", - "dealid": "test-dealid", - "mtype": 4 - } - ] - } - ] - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [] - } - ], - "expectedMakeBidsErrors": [ - { - "value": "unable to unmarshal native adm", - "comparison": "literal" - } - ] -} diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-bad-mtype.json b/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-bad-mtype.json deleted file mode 100644 index fc52cc30601..00000000000 --- a/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-bad-mtype.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "site": { - "page": "https://good.site/url" - }, - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": {} - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://localhost/prebid_server", - "body": { - "id": "test-request-id", - "cur": [ - "USD" - ], - "site": { - "page": "https://good.site/url" - }, - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": {} - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "rtbhouse", - "bid": [ - { - "id": "randomid", - "impid": "test-imp-id", - "price": 0.500000, - "adid": "12345678", - "adm": "some-test-ad", - "cid": "987", - "crid": "12345678", - "h": 250, - "w": 300, - "mtype": 99 - } - ] - } - ], - "cur": "USD" - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [] - } - ], - "expectedMakeBidsErrors": [ - { - "value": "unrecognized bid type in response from rtbhouse for bid test-imp-id", - "comparison": "literal" - } - ] -} diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-no-mtype.json b/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-no-mtype.json deleted file mode 100644 index 8bb9e8a1f89..00000000000 --- a/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-no-mtype.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "site": { - "page": "https://good.site/url" - }, - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": {} - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://localhost/prebid_server", - "body": { - "id": "test-request-id", - "cur": [ - "USD" - ], - "site": { - "page": "https://good.site/url" - }, - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - } - ] - }, - "ext": { - "bidder": {} - } - } - ] - } - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "rtbhouse", - "bid": [ - { - "id": "randomid", - "impid": "test-imp-id", - "price": 0.500000, - "adid": "12345678", - "adm": "some-test-ad", - "cid": "987", - "crid": "12345678", - "h": 250, - "w": 300 - } - ] - } - ], - "cur": "USD" - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [] - } - ], - "expectedMakeBidsErrors": [ - { - "value": "unrecognized bid type in response from rtbhouse for bid test-imp-id", - "comparison": "literal" - } - ] -} diff --git a/static/bidder-info/rtbhouse.yaml b/static/bidder-info/rtbhouse.yaml index b80cc0ff4f8..ad2fbfcbc95 100644 --- a/static/bidder-info/rtbhouse.yaml +++ b/static/bidder-info/rtbhouse.yaml @@ -7,7 +7,6 @@ capabilities: site: mediaTypes: - banner - - native userSync: # rtbhouse supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. From b200357f116b7c5ece866bf21f5c62e002787b0a Mon Sep 17 00:00:00 2001 From: guscarreon Date: Tue, 31 Oct 2023 11:57:02 -0400 Subject: [PATCH 202/268] Increment to V2 in Dockerfile and Makefile (#3272) --- Dockerfile | 2 +- Makefile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 090d9a79954..bff68b614b3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,7 @@ RUN go mod tidy RUN go mod vendor ARG TEST="true" RUN if [ "$TEST" != "false" ]; then ./validate.sh ; fi -RUN go build -mod=vendor -ldflags "-X github.com/prebid/prebid-server/version.Ver=`git describe --tags | sed 's/^v//'` -X github.com/prebid/prebid-server/version.Rev=`git rev-parse HEAD`" . +RUN go build -mod=vendor -ldflags "-X github.com/prebid/prebid-server/v2/version.Ver=`git describe --tags | sed 's/^v//'` -X github.com/prebid/prebid-server/v2/version.Rev=`git rev-parse HEAD`" . FROM ubuntu:20.04 AS release LABEL maintainer="hans.hjort@xandr.com" diff --git a/Makefile b/Makefile index b5b7281e5ed..2d8aae6c78a 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ test: deps ifeq "$(adapter)" "" ./validate.sh else - go test github.com/prebid/prebid-server/adapters/$(adapter) -bench=. + go test github.com/prebid/prebid-server/v2/adapters/$(adapter) -bench=. endif # build-modules generates modules/builder.go file which provides a list of all available modules @@ -32,4 +32,4 @@ image: # format runs format format: - ./scripts/format.sh -f true \ No newline at end of file + ./scripts/format.sh -f true From 5941d46efe3a59015750e56d293838b44c309701 Mon Sep 17 00:00:00 2001 From: ashishshinde-pubm <109787960+ashishshinde-pubm@users.noreply.github.com> Date: Mon, 13 Nov 2023 23:36:39 +0530 Subject: [PATCH 203/268] Fix: BidderInfo OpenRTB field data lost on start up (#3178) --- config/bidderinfo.go | 3 +++ config/bidderinfo_test.go | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/config/bidderinfo.go b/config/bidderinfo.go index 45abc85227a..e4015b8e00b 100644 --- a/config/bidderinfo.go +++ b/config/bidderinfo.go @@ -605,6 +605,9 @@ func applyBidderInfoConfigOverrides(configBidderInfos BidderInfos, fsBidderInfos if bidderInfo.EndpointCompression == "" && fsBidderCfg.EndpointCompression != "" { bidderInfo.EndpointCompression = fsBidderCfg.EndpointCompression } + if bidderInfo.OpenRTB == nil && fsBidderCfg.OpenRTB != nil { + bidderInfo.OpenRTB = fsBidderCfg.OpenRTB + } fsBidderInfos[string(normalizedBidderName)] = bidderInfo } else { diff --git a/config/bidderinfo_test.go b/config/bidderinfo_test.go index ad242bd0a47..afb48c2fe81 100644 --- a/config/bidderinfo_test.go +++ b/config/bidderinfo_test.go @@ -1649,6 +1649,18 @@ func TestApplyBidderInfoConfigOverrides(t *testing.T) { givenConfigBidderInfos: BidderInfos{"a": {EndpointCompression: "LZ77", Syncer: &Syncer{Key: "override"}}}, expectedBidderInfos: BidderInfos{"a": {EndpointCompression: "LZ77", Syncer: &Syncer{Key: "override"}}}, }, + { + description: "Don't override OpenRTB", + givenFsBidderInfos: BidderInfos{"a": {OpenRTB: &OpenRTBInfo{Version: "v1", GPPSupported: true}}}, + givenConfigBidderInfos: BidderInfos{"a": {}}, + expectedBidderInfos: BidderInfos{"a": {OpenRTB: &OpenRTBInfo{Version: "v1", GPPSupported: true}}}, + }, + { + description: "Override OpenRTB", + givenFsBidderInfos: BidderInfos{"a": {OpenRTB: &OpenRTBInfo{Version: "v1", GPPSupported: true}}}, + givenConfigBidderInfos: BidderInfos{"a": {OpenRTB: &OpenRTBInfo{Version: "v2", GPPSupported: false}}}, + expectedBidderInfos: BidderInfos{"a": {OpenRTB: &OpenRTBInfo{Version: "v2", GPPSupported: false}}}, + }, } for _, test := range testCases { bidderInfos, resultErr := applyBidderInfoConfigOverrides(test.givenConfigBidderInfos, test.givenFsBidderInfos, mockNormalizeBidderName) From 909926477ee48c0f2dffbbe2663649e4c586c75c Mon Sep 17 00:00:00 2001 From: Veronika Solovei Date: Mon, 13 Nov 2023 10:24:34 -0800 Subject: [PATCH 204/268] Fix for null string unmarshal error (#3284) --- exchange/bidder.go | 4 ++-- exchange/bidder_test.go | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/exchange/bidder.go b/exchange/bidder.go index db654bf47ae..610122fbbf2 100644 --- a/exchange/bidder.go +++ b/exchange/bidder.go @@ -406,7 +406,7 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest Bidde func addNativeTypes(bid *openrtb2.Bid, request *openrtb2.BidRequest) (*nativeResponse.Response, []error) { var errs []error - var nativeMarkup *nativeResponse.Response + var nativeMarkup nativeResponse.Response if err := jsonutil.UnmarshalValid(json.RawMessage(bid.AdM), &nativeMarkup); err != nil || len(nativeMarkup.Assets) == 0 { // Some bidders are returning non-IAB compliant native markup. In this case Prebid server will not be able to add types. E.g Facebook return nil, errs @@ -429,7 +429,7 @@ func addNativeTypes(bid *openrtb2.Bid, request *openrtb2.BidRequest) (*nativeRes } } - return nativeMarkup, errs + return &nativeMarkup, errs } func setAssetTypes(asset nativeResponse.Asset, nativePayload nativeRequests.Request) error { diff --git a/exchange/bidder_test.go b/exchange/bidder_test.go index 824aecc8583..6db61d0d883 100644 --- a/exchange/bidder_test.go +++ b/exchange/bidder_test.go @@ -1568,6 +1568,46 @@ func TestMobileNativeTypes(t *testing.T) { } } +func TestAddNativeTypes(t *testing.T) { + testCases := []struct { + description string + bidderRequest *openrtb2.BidRequest + bid *openrtb2.Bid + expectedResponse *nativeResponse.Response + expectedErrors []error + }{ + { + description: "Null in bid.Adm in response", + bidderRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + ID: "some-imp-id", + Native: &openrtb2.Native{ + Request: "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}}]}", + }, + }, + }, + App: &openrtb2.App{}, + }, + bid: &openrtb2.Bid{ + ImpID: "some-imp-id", + AdM: "null", + Price: 10, + }, + expectedResponse: nil, + expectedErrors: nil, + }, + } + + for _, tt := range testCases { + t.Run(tt.description, func(t *testing.T) { + resp, errs := addNativeTypes(tt.bid, tt.bidderRequest) + assert.Equal(t, tt.expectedResponse, resp, "response") + assert.Equal(t, tt.expectedErrors, errs, "errors") + }) + } +} + func TestRequestBidsStoredBidResponses(t *testing.T) { respBody := "{\"bid\":false}" respStatus := 200 From f52dbb192288d677044733f1f12b0e9c12e9ed50 Mon Sep 17 00:00:00 2001 From: Brian Sardo <1168933+bsardo@users.noreply.github.com> Date: Mon, 13 Nov 2023 23:51:25 -0500 Subject: [PATCH 205/268] Fix: use bidder info fs config as base when merging overrides (#3289) --- config/bidderinfo.go | 116 ++++++++++++++++------------ config/bidderinfo_test.go | 155 +++++++++++++++++++++++++++----------- config/config.go | 36 ++++++++- config/config_test.go | 150 ++++++++++++++++++++++++++++++++++++ 4 files changed, 362 insertions(+), 95 deletions(-) diff --git a/config/bidderinfo.go b/config/bidderinfo.go index e4015b8e00b..d6d0ba79ba0 100644 --- a/config/bidderinfo.go +++ b/config/bidderinfo.go @@ -560,61 +560,79 @@ func validateSyncer(bidderInfo BidderInfo) error { return nil } -func applyBidderInfoConfigOverrides(configBidderInfos BidderInfos, fsBidderInfos BidderInfos, normalizeBidderName func(string) (openrtb_ext.BidderName, bool)) (BidderInfos, error) { - for bidderName, bidderInfo := range configBidderInfos { - normalizedBidderName, bidderNameExists := normalizeBidderName(bidderName) - if !bidderNameExists { +func applyBidderInfoConfigOverrides(configBidderInfos nillableFieldBidderInfos, fsBidderInfos BidderInfos, normalizeBidderName func(string) (openrtb_ext.BidderName, bool)) (BidderInfos, error) { + mergedBidderInfos := make(map[string]BidderInfo, len(fsBidderInfos)) + + for bidderName, configBidderInfo := range configBidderInfos { + normalizedBidderName, exists := normalizeBidderName(bidderName) + if !exists { return nil, fmt.Errorf("error setting configuration for bidder %s: unknown bidder", bidderName) } - if fsBidderCfg, exists := fsBidderInfos[string(normalizedBidderName)]; exists { - bidderInfo.Syncer = bidderInfo.Syncer.Override(fsBidderCfg.Syncer) + fsBidderInfo, exists := fsBidderInfos[string(normalizedBidderName)] + if !exists { + return nil, fmt.Errorf("error finding configuration for bidder %s: unknown bidder", bidderName) + } - if bidderInfo.Endpoint == "" && len(fsBidderCfg.Endpoint) > 0 { - bidderInfo.Endpoint = fsBidderCfg.Endpoint - } - if bidderInfo.ExtraAdapterInfo == "" && len(fsBidderCfg.ExtraAdapterInfo) > 0 { - bidderInfo.ExtraAdapterInfo = fsBidderCfg.ExtraAdapterInfo - } - if bidderInfo.Maintainer == nil && fsBidderCfg.Maintainer != nil { - bidderInfo.Maintainer = fsBidderCfg.Maintainer - } - if bidderInfo.Capabilities == nil && fsBidderCfg.Capabilities != nil { - bidderInfo.Capabilities = fsBidderCfg.Capabilities - } - if bidderInfo.Debug == nil && fsBidderCfg.Debug != nil { - bidderInfo.Debug = fsBidderCfg.Debug - } - if bidderInfo.GVLVendorID == 0 && fsBidderCfg.GVLVendorID > 0 { - bidderInfo.GVLVendorID = fsBidderCfg.GVLVendorID - } - if bidderInfo.XAPI.Username == "" && fsBidderCfg.XAPI.Username != "" { - bidderInfo.XAPI.Username = fsBidderCfg.XAPI.Username - } - if bidderInfo.XAPI.Password == "" && fsBidderCfg.XAPI.Password != "" { - bidderInfo.XAPI.Password = fsBidderCfg.XAPI.Password - } - if bidderInfo.XAPI.Tracker == "" && fsBidderCfg.XAPI.Tracker != "" { - bidderInfo.XAPI.Tracker = fsBidderCfg.XAPI.Tracker - } - if bidderInfo.PlatformID == "" && fsBidderCfg.PlatformID != "" { - bidderInfo.PlatformID = fsBidderCfg.PlatformID - } - if bidderInfo.AppSecret == "" && fsBidderCfg.AppSecret != "" { - bidderInfo.AppSecret = fsBidderCfg.AppSecret - } - if bidderInfo.EndpointCompression == "" && fsBidderCfg.EndpointCompression != "" { - bidderInfo.EndpointCompression = fsBidderCfg.EndpointCompression - } - if bidderInfo.OpenRTB == nil && fsBidderCfg.OpenRTB != nil { - bidderInfo.OpenRTB = fsBidderCfg.OpenRTB - } + mergedBidderInfo := fsBidderInfo + mergedBidderInfo.Syncer = configBidderInfo.bidderInfo.Syncer.Override(fsBidderInfo.Syncer) + if len(configBidderInfo.bidderInfo.Endpoint) > 0 { + mergedBidderInfo.Endpoint = configBidderInfo.bidderInfo.Endpoint + } + if len(configBidderInfo.bidderInfo.ExtraAdapterInfo) > 0 { + mergedBidderInfo.ExtraAdapterInfo = configBidderInfo.bidderInfo.ExtraAdapterInfo + } + if configBidderInfo.bidderInfo.Maintainer != nil { + mergedBidderInfo.Maintainer = configBidderInfo.bidderInfo.Maintainer + } + if configBidderInfo.bidderInfo.Capabilities != nil { + mergedBidderInfo.Capabilities = configBidderInfo.bidderInfo.Capabilities + } + if configBidderInfo.bidderInfo.Debug != nil { + mergedBidderInfo.Debug = configBidderInfo.bidderInfo.Debug + } + if configBidderInfo.bidderInfo.GVLVendorID > 0 { + mergedBidderInfo.GVLVendorID = configBidderInfo.bidderInfo.GVLVendorID + } + if configBidderInfo.bidderInfo.XAPI.Username != "" { + mergedBidderInfo.XAPI.Username = configBidderInfo.bidderInfo.XAPI.Username + } + if configBidderInfo.bidderInfo.XAPI.Password != "" { + mergedBidderInfo.XAPI.Password = configBidderInfo.bidderInfo.XAPI.Password + } + if configBidderInfo.bidderInfo.XAPI.Tracker != "" { + mergedBidderInfo.XAPI.Tracker = configBidderInfo.bidderInfo.XAPI.Tracker + } + if configBidderInfo.bidderInfo.PlatformID != "" { + mergedBidderInfo.PlatformID = configBidderInfo.bidderInfo.PlatformID + } + if configBidderInfo.bidderInfo.AppSecret != "" { + mergedBidderInfo.AppSecret = configBidderInfo.bidderInfo.AppSecret + } + if configBidderInfo.nillableFields.Disabled != nil { + mergedBidderInfo.Disabled = configBidderInfo.bidderInfo.Disabled + } + if configBidderInfo.nillableFields.ModifyingVastXmlAllowed != nil { + mergedBidderInfo.ModifyingVastXmlAllowed = configBidderInfo.bidderInfo.ModifyingVastXmlAllowed + } + if configBidderInfo.bidderInfo.Experiment.AdsCert.Enabled == true { + mergedBidderInfo.Experiment.AdsCert.Enabled = true + } + if configBidderInfo.bidderInfo.EndpointCompression != "" { + mergedBidderInfo.EndpointCompression = configBidderInfo.bidderInfo.EndpointCompression + } + if configBidderInfo.bidderInfo.OpenRTB != nil { + mergedBidderInfo.OpenRTB = configBidderInfo.bidderInfo.OpenRTB + } - fsBidderInfos[string(normalizedBidderName)] = bidderInfo - } else { - return nil, fmt.Errorf("error finding configuration for bidder %s: unknown bidder", bidderName) + mergedBidderInfos[string(normalizedBidderName)] = mergedBidderInfo + } + for bidderName, fsBidderInfo := range fsBidderInfos { + if _, exists := mergedBidderInfos[bidderName]; !exists { + mergedBidderInfos[bidderName] = fsBidderInfo } } - return fsBidderInfos, nil + + return mergedBidderInfos, nil } // Override returns a new Syncer object where values in the original are replaced by non-empty/non-default diff --git a/config/bidderinfo_test.go b/config/bidderinfo_test.go index afb48c2fe81..ee1b35d4994 100644 --- a/config/bidderinfo_test.go +++ b/config/bidderinfo_test.go @@ -1490,8 +1490,12 @@ func TestSyncerEndpointOverride(t *testing.T) { func TestApplyBidderInfoConfigSyncerOverrides(t *testing.T) { var ( givenFileSystem = BidderInfos{"a": {Syncer: &Syncer{Key: "original"}}} - givenConfig = BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}} - expected = BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}} + givenConfig = nillableFieldBidderInfos{ + "a": { + bidderInfo: BidderInfo{Syncer: &Syncer{Key: "override"}}, + }, + } + expected = BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}} ) result, resultErr := applyBidderInfoConfigOverrides(givenConfig, givenFileSystem, mockNormalizeBidderName) @@ -1500,47 +1504,49 @@ func TestApplyBidderInfoConfigSyncerOverrides(t *testing.T) { } func TestApplyBidderInfoConfigOverrides(t *testing.T) { + falseValue := false + var testCases = []struct { description string givenFsBidderInfos BidderInfos - givenConfigBidderInfos BidderInfos + givenConfigBidderInfos nillableFieldBidderInfos expectedError string expectedBidderInfos BidderInfos }{ { description: "Don't override endpoint", givenFsBidderInfos: BidderInfos{"a": {Endpoint: "original"}}, - givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{Syncer: &Syncer{Key: "override"}}}}, expectedBidderInfos: BidderInfos{"a": {Endpoint: "original", Syncer: &Syncer{Key: "override"}}}, }, { description: "Override endpoint", givenFsBidderInfos: BidderInfos{"a": {Endpoint: "original"}}, - givenConfigBidderInfos: BidderInfos{"a": {Endpoint: "override", Syncer: &Syncer{Key: "override"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{Endpoint: "override", Syncer: &Syncer{Key: "override"}}}}, expectedBidderInfos: BidderInfos{"a": {Endpoint: "override", Syncer: &Syncer{Key: "override"}}}, }, { description: "Don't override ExtraAdapterInfo", givenFsBidderInfos: BidderInfos{"a": {ExtraAdapterInfo: "original"}}, - givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{Syncer: &Syncer{Key: "override"}}}}, expectedBidderInfos: BidderInfos{"a": {ExtraAdapterInfo: "original", Syncer: &Syncer{Key: "override"}}}, }, { description: "Override ExtraAdapterInfo", givenFsBidderInfos: BidderInfos{"a": {ExtraAdapterInfo: "original"}}, - givenConfigBidderInfos: BidderInfos{"a": {ExtraAdapterInfo: "override", Syncer: &Syncer{Key: "override"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{ExtraAdapterInfo: "override", Syncer: &Syncer{Key: "override"}}}}, expectedBidderInfos: BidderInfos{"a": {ExtraAdapterInfo: "override", Syncer: &Syncer{Key: "override"}}}, }, { description: "Don't override Maintainer", givenFsBidderInfos: BidderInfos{"a": {Maintainer: &MaintainerInfo{Email: "original"}}}, - givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{Syncer: &Syncer{Key: "override"}}}}, expectedBidderInfos: BidderInfos{"a": {Maintainer: &MaintainerInfo{Email: "original"}, Syncer: &Syncer{Key: "override"}}}, }, { description: "Override maintainer", givenFsBidderInfos: BidderInfos{"a": {Maintainer: &MaintainerInfo{Email: "original"}}}, - givenConfigBidderInfos: BidderInfos{"a": {Maintainer: &MaintainerInfo{Email: "override"}, Syncer: &Syncer{Key: "override"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{Maintainer: &MaintainerInfo{Email: "override"}, Syncer: &Syncer{Key: "override"}}}}, expectedBidderInfos: BidderInfos{"a": {Maintainer: &MaintainerInfo{Email: "override"}, Syncer: &Syncer{Key: "override"}}}, }, { @@ -1548,7 +1554,7 @@ func TestApplyBidderInfoConfigOverrides(t *testing.T) { givenFsBidderInfos: BidderInfos{"a": { Capabilities: &CapabilitiesInfo{App: &PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeVideo}}}, }}, - givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{Syncer: &Syncer{Key: "override"}}}}, expectedBidderInfos: BidderInfos{"a": { Syncer: &Syncer{Key: "override"}, Capabilities: &CapabilitiesInfo{App: &PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeVideo}}}, @@ -1559,10 +1565,10 @@ func TestApplyBidderInfoConfigOverrides(t *testing.T) { givenFsBidderInfos: BidderInfos{"a": { Capabilities: &CapabilitiesInfo{App: &PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeVideo}}}, }}, - givenConfigBidderInfos: BidderInfos{"a": { + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{ Syncer: &Syncer{Key: "override"}, Capabilities: &CapabilitiesInfo{App: &PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}}}, - }}, + }}}, expectedBidderInfos: BidderInfos{"a": { Syncer: &Syncer{Key: "override"}, Capabilities: &CapabilitiesInfo{App: &PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}}}, @@ -1571,25 +1577,25 @@ func TestApplyBidderInfoConfigOverrides(t *testing.T) { { description: "Don't override Debug", givenFsBidderInfos: BidderInfos{"a": {Debug: &DebugInfo{Allow: true}}}, - givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{Syncer: &Syncer{Key: "override"}}}}, expectedBidderInfos: BidderInfos{"a": {Debug: &DebugInfo{Allow: true}, Syncer: &Syncer{Key: "override"}}}, }, { description: "Override Debug", givenFsBidderInfos: BidderInfos{"a": {Debug: &DebugInfo{Allow: true}}}, - givenConfigBidderInfos: BidderInfos{"a": {Debug: &DebugInfo{Allow: false}, Syncer: &Syncer{Key: "override"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{Debug: &DebugInfo{Allow: false}, Syncer: &Syncer{Key: "override"}}}}, expectedBidderInfos: BidderInfos{"a": {Debug: &DebugInfo{Allow: false}, Syncer: &Syncer{Key: "override"}}}, }, { description: "Don't override GVLVendorID", givenFsBidderInfos: BidderInfos{"a": {GVLVendorID: 5}}, - givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{Syncer: &Syncer{Key: "override"}}}}, expectedBidderInfos: BidderInfos{"a": {GVLVendorID: 5, Syncer: &Syncer{Key: "override"}}}, }, { description: "Override GVLVendorID", givenFsBidderInfos: BidderInfos{"a": {}}, - givenConfigBidderInfos: BidderInfos{"a": {GVLVendorID: 5, Syncer: &Syncer{Key: "override"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{GVLVendorID: 5, Syncer: &Syncer{Key: "override"}}}}, expectedBidderInfos: BidderInfos{"a": {GVLVendorID: 5, Syncer: &Syncer{Key: "override"}}}, }, { @@ -1597,7 +1603,7 @@ func TestApplyBidderInfoConfigOverrides(t *testing.T) { givenFsBidderInfos: BidderInfos{"a": { XAPI: AdapterXAPI{Username: "username1", Password: "password2", Tracker: "tracker3"}, }}, - givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{Syncer: &Syncer{Key: "override"}}}}, expectedBidderInfos: BidderInfos{"a": { XAPI: AdapterXAPI{Username: "username1", Password: "password2", Tracker: "tracker3"}, Syncer: &Syncer{Key: "override"}}}, @@ -1606,9 +1612,9 @@ func TestApplyBidderInfoConfigOverrides(t *testing.T) { description: "Override XAPI", givenFsBidderInfos: BidderInfos{"a": { XAPI: AdapterXAPI{Username: "username", Password: "password", Tracker: "tracker"}}}, - givenConfigBidderInfos: BidderInfos{"a": { + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{ XAPI: AdapterXAPI{Username: "username1", Password: "password2", Tracker: "tracker3"}, - Syncer: &Syncer{Key: "override"}}}, + Syncer: &Syncer{Key: "override"}}}}, expectedBidderInfos: BidderInfos{"a": { XAPI: AdapterXAPI{Username: "username1", Password: "password2", Tracker: "tracker3"}, Syncer: &Syncer{Key: "override"}}}, @@ -1616,50 +1622,92 @@ func TestApplyBidderInfoConfigOverrides(t *testing.T) { { description: "Don't override PlatformID", givenFsBidderInfos: BidderInfos{"a": {PlatformID: "PlatformID"}}, - givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{Syncer: &Syncer{Key: "override"}}}}, expectedBidderInfos: BidderInfos{"a": {PlatformID: "PlatformID", Syncer: &Syncer{Key: "override"}}}, }, { description: "Override PlatformID", givenFsBidderInfos: BidderInfos{"a": {PlatformID: "PlatformID1"}}, - givenConfigBidderInfos: BidderInfos{"a": {PlatformID: "PlatformID2", Syncer: &Syncer{Key: "override"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{PlatformID: "PlatformID2", Syncer: &Syncer{Key: "override"}}}}, expectedBidderInfos: BidderInfos{"a": {PlatformID: "PlatformID2", Syncer: &Syncer{Key: "override"}}}, }, { description: "Don't override AppSecret", givenFsBidderInfos: BidderInfos{"a": {AppSecret: "AppSecret"}}, - givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{Syncer: &Syncer{Key: "override"}}}}, expectedBidderInfos: BidderInfos{"a": {AppSecret: "AppSecret", Syncer: &Syncer{Key: "override"}}}, }, { description: "Override AppSecret", givenFsBidderInfos: BidderInfos{"a": {AppSecret: "AppSecret1"}}, - givenConfigBidderInfos: BidderInfos{"a": {AppSecret: "AppSecret2", Syncer: &Syncer{Key: "override"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{AppSecret: "AppSecret2", Syncer: &Syncer{Key: "override"}}}}, expectedBidderInfos: BidderInfos{"a": {AppSecret: "AppSecret2", Syncer: &Syncer{Key: "override"}}}, }, { description: "Don't override EndpointCompression", givenFsBidderInfos: BidderInfos{"a": {EndpointCompression: "GZIP"}}, - givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{Syncer: &Syncer{Key: "override"}}}}, expectedBidderInfos: BidderInfos{"a": {EndpointCompression: "GZIP", Syncer: &Syncer{Key: "override"}}}, }, { description: "Override EndpointCompression", givenFsBidderInfos: BidderInfos{"a": {EndpointCompression: "GZIP"}}, - givenConfigBidderInfos: BidderInfos{"a": {EndpointCompression: "LZ77", Syncer: &Syncer{Key: "override"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{EndpointCompression: "LZ77", Syncer: &Syncer{Key: "override"}}}}, expectedBidderInfos: BidderInfos{"a": {EndpointCompression: "LZ77", Syncer: &Syncer{Key: "override"}}}, }, + { + description: "Don't override Disabled", + givenFsBidderInfos: BidderInfos{"a": {Disabled: true}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{Disabled: false, Syncer: &Syncer{Key: "override"}}, nillableFields: bidderInfoNillableFields{Disabled: nil}}}, + expectedBidderInfos: BidderInfos{"a": {Disabled: true, Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Override Disabled", + givenFsBidderInfos: BidderInfos{"a": {Disabled: true}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{Disabled: false, Syncer: &Syncer{Key: "override"}}, nillableFields: bidderInfoNillableFields{Disabled: &falseValue}}}, + expectedBidderInfos: BidderInfos{"a": {Disabled: false, Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Don't override ModifyingVastXmlAllowed", + givenFsBidderInfos: BidderInfos{"a": {ModifyingVastXmlAllowed: true}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{ModifyingVastXmlAllowed: false, Syncer: &Syncer{Key: "override"}}, nillableFields: bidderInfoNillableFields{ModifyingVastXmlAllowed: nil}}}, + expectedBidderInfos: BidderInfos{"a": {ModifyingVastXmlAllowed: true, Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Override ModifyingVastXmlAllowed", + givenFsBidderInfos: BidderInfos{"a": {ModifyingVastXmlAllowed: true}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{ModifyingVastXmlAllowed: false, Syncer: &Syncer{Key: "override"}}, nillableFields: bidderInfoNillableFields{ModifyingVastXmlAllowed: &falseValue}}}, + expectedBidderInfos: BidderInfos{"a": {ModifyingVastXmlAllowed: false, Syncer: &Syncer{Key: "override"}}}, + }, { description: "Don't override OpenRTB", - givenFsBidderInfos: BidderInfos{"a": {OpenRTB: &OpenRTBInfo{Version: "v1", GPPSupported: true}}}, - givenConfigBidderInfos: BidderInfos{"a": {}}, - expectedBidderInfos: BidderInfos{"a": {OpenRTB: &OpenRTBInfo{Version: "v1", GPPSupported: true}}}, + givenFsBidderInfos: BidderInfos{"a": {OpenRTB: &OpenRTBInfo{Version: "1"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{Syncer: &Syncer{Key: "override"}}}}, + expectedBidderInfos: BidderInfos{"a": {OpenRTB: &OpenRTBInfo{Version: "1"}, Syncer: &Syncer{Key: "override"}}}, }, { description: "Override OpenRTB", - givenFsBidderInfos: BidderInfos{"a": {OpenRTB: &OpenRTBInfo{Version: "v1", GPPSupported: true}}}, - givenConfigBidderInfos: BidderInfos{"a": {OpenRTB: &OpenRTBInfo{Version: "v2", GPPSupported: false}}}, - expectedBidderInfos: BidderInfos{"a": {OpenRTB: &OpenRTBInfo{Version: "v2", GPPSupported: false}}}, + givenFsBidderInfos: BidderInfos{"a": {OpenRTB: &OpenRTBInfo{Version: "1"}}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{OpenRTB: &OpenRTBInfo{Version: "2"}, Syncer: &Syncer{Key: "override"}}}}, + expectedBidderInfos: BidderInfos{"a": {OpenRTB: &OpenRTBInfo{Version: "2"}, Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Don't override AliasOf", + givenFsBidderInfos: BidderInfos{"a": {AliasOf: "Alias1"}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{}}}, + expectedBidderInfos: BidderInfos{"a": {AliasOf: "Alias1"}}, + }, + { + description: "Attempt override AliasOf but ignored", + givenFsBidderInfos: BidderInfos{"a": {AliasOf: "Alias1"}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{AliasOf: "Alias2"}}}, + expectedBidderInfos: BidderInfos{"a": {AliasOf: "Alias1"}}, + }, + { + description: "Two bidder infos: One with overrides and one without", + givenFsBidderInfos: BidderInfos{"a": {Endpoint: "original"}, "b": {Endpoint: "b endpoint"}}, + givenConfigBidderInfos: nillableFieldBidderInfos{"a": {bidderInfo: BidderInfo{Endpoint: "override", Syncer: &Syncer{Key: "override"}}}}, + expectedBidderInfos: BidderInfos{"a": {Endpoint: "override", Syncer: &Syncer{Key: "override"}}, "b": {Endpoint: "b endpoint"}}, }, } for _, test := range testCases { @@ -1671,26 +1719,31 @@ func TestApplyBidderInfoConfigOverrides(t *testing.T) { func TestApplyBidderInfoConfigOverridesInvalid(t *testing.T) { var testCases = []struct { - description string - givenFsBidderInfos BidderInfos - givenConfigBidderInfos BidderInfos - expectedError string - expectedBidderInfos BidderInfos + description string + givenFsBidderInfos BidderInfos + givenNillableFieldBidderInfos nillableFieldBidderInfos + expectedError string + expectedBidderInfos BidderInfos }{ { - description: "Bidder doesn't exists in bidder list", - givenConfigBidderInfos: BidderInfos{"unknown": {Syncer: &Syncer{Key: "override"}}}, - expectedError: "error setting configuration for bidder unknown: unknown bidder", + description: "Bidder doesn't exists in bidder list", + givenNillableFieldBidderInfos: nillableFieldBidderInfos{"unknown": nillableFieldBidderInfo{ + bidderInfo: BidderInfo{Syncer: &Syncer{Key: "override"}}, + }}, + expectedError: "error setting configuration for bidder unknown: unknown bidder", }, { - description: "Bidder doesn't exists in file system", - givenFsBidderInfos: BidderInfos{"unknown": {Endpoint: "original"}}, - givenConfigBidderInfos: BidderInfos{"bidderA": {Syncer: &Syncer{Key: "override"}}}, - expectedError: "error finding configuration for bidder bidderA: unknown bidder", + description: "Bidder doesn't exists in file system", + givenFsBidderInfos: BidderInfos{"unknown": {Endpoint: "original"}}, + givenNillableFieldBidderInfos: nillableFieldBidderInfos{"bidderA": nillableFieldBidderInfo{ + bidderInfo: BidderInfo{Syncer: &Syncer{Key: "override"}}, + }}, + expectedError: "error finding configuration for bidder bidderA: unknown bidder", }, } for _, test := range testCases { - _, err := applyBidderInfoConfigOverrides(test.givenConfigBidderInfos, test.givenFsBidderInfos, mockNormalizeBidderName) + + _, err := applyBidderInfoConfigOverrides(test.givenNillableFieldBidderInfos, test.givenFsBidderInfos, mockNormalizeBidderName) assert.ErrorContains(t, err, test.expectedError, test.description+":err") } } @@ -1702,7 +1755,19 @@ func TestReadFullYamlBidderConfig(t *testing.T) { err := yaml.Unmarshal([]byte(fullBidderYAMLConfig), &bidderInf) require.NoError(t, err) - actualBidderInfo, err := applyBidderInfoConfigOverrides(BidderInfos{bidder: bidderInf}, BidderInfos{bidder: {Syncer: &Syncer{Supports: []string{"iframe"}}}}, mockNormalizeBidderName) + bidderInfoOverrides := nillableFieldBidderInfos{ + bidder: nillableFieldBidderInfo{ + bidderInfo: bidderInf, + nillableFields: bidderInfoNillableFields{ + Disabled: &bidderInf.Disabled, + ModifyingVastXmlAllowed: &bidderInf.ModifyingVastXmlAllowed, + }, + }, + } + bidderInfoBase := BidderInfos{ + bidder: {Syncer: &Syncer{Supports: []string{"iframe"}}}, + } + actualBidderInfo, err := applyBidderInfoConfigOverrides(bidderInfoOverrides, bidderInfoBase, mockNormalizeBidderName) require.NoError(t, err) expectedBidderInfo := BidderInfos{ diff --git a/config/config.go b/config/config.go index 11b7eb5841e..34c95822b3d 100644 --- a/config/config.go +++ b/config/config.go @@ -758,7 +758,11 @@ func New(v *viper.Viper, bidderInfos BidderInfos, normalizeBidderName func(strin // Migrate combo stored request config to separate stored_reqs and amp stored_reqs configs. resolvedStoredRequestsConfig(&c) - mergedBidderInfos, err := applyBidderInfoConfigOverrides(c.BidderInfos, bidderInfos, normalizeBidderName) + configBidderInfosWithNillableFields, err := setConfigBidderInfoNillableFields(v, c.BidderInfos) + if err != nil { + return nil, err + } + mergedBidderInfos, err := applyBidderInfoConfigOverrides(configBidderInfosWithNillableFields, bidderInfos, normalizeBidderName) if err != nil { return nil, err } @@ -773,6 +777,36 @@ func New(v *viper.Viper, bidderInfos BidderInfos, normalizeBidderName func(strin return &c, nil } +type bidderInfoNillableFields struct { + Disabled *bool `yaml:"disabled" mapstructure:"disabled"` + ModifyingVastXmlAllowed *bool `yaml:"modifyingVastXmlAllowed" mapstructure:"modifyingVastXmlAllowed"` +} +type nillableFieldBidderInfos map[string]nillableFieldBidderInfo +type nillableFieldBidderInfo struct { + nillableFields bidderInfoNillableFields + bidderInfo BidderInfo +} + +func setConfigBidderInfoNillableFields(v *viper.Viper, bidderInfos BidderInfos) (nillableFieldBidderInfos, error) { + if len(bidderInfos) == 0 || v == nil { + return nil, nil + } + infos := make(nillableFieldBidderInfos, len(bidderInfos)) + + for bidderName, bidderInfo := range bidderInfos { + info := nillableFieldBidderInfo{bidderInfo: bidderInfo} + + if err := v.UnmarshalKey("adapters."+bidderName+".disabled", &info.nillableFields.Disabled); err != nil { + return nil, fmt.Errorf("viper failed to unmarshal bidder config disabled: %v", err) + } + if err := v.UnmarshalKey("adapters."+bidderName+".modifyingvastxmlallowed", &info.nillableFields.ModifyingVastXmlAllowed); err != nil { + return nil, fmt.Errorf("viper failed to unmarshal bidder config modifyingvastxmlallowed: %v", err) + } + infos[bidderName] = info + } + return infos, nil +} + // MarshalAccountDefaults compiles AccountDefaults into the JSON format used for merge patch func (cfg *Configuration) MarshalAccountDefaults() error { var err error diff --git a/config/config_test.go b/config/config_test.go index 535b4e7b099..b3c43dfa4d3 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -5,6 +5,7 @@ import ( "errors" "net" "os" + "strings" "testing" "time" @@ -1294,6 +1295,155 @@ func TestSpecialFeature1VendorExceptionMap(t *testing.T) { } } +func TestSetConfigBidderInfoNillableFields(t *testing.T) { + falseValue := false + trueValue := true + + bidder1ConfigFalses := []byte(` + adapters: + bidder1: + disabled: false + modifyingVastXmlAllowed: false`) + bidder1ConfigTrues := []byte(` + adapters: + bidder1: + disabled: true + modifyingVastXmlAllowed: true`) + bidder1ConfigNils := []byte(` + adapters: + bidder1: + disabled: null + modifyingVastXmlAllowed: null`) + bidder1Bidder2ConfigMixed := []byte(` + adapters: + bidder1: + disabled: true + modifyingVastXmlAllowed: false + bidder2: + disabled: false + modifyingVastXmlAllowed: true`) + + tests := []struct { + name string + rawConfig []byte + bidderInfos BidderInfos + expected nillableFieldBidderInfos + expectError bool + }{ + { + name: "viper and bidder infos are nil", + expected: nil, + }, + { + name: "viper is nil", + bidderInfos: map[string]BidderInfo{}, + expected: nil, + }, + { + name: "bidder infos is nil", + rawConfig: []byte{}, + expected: nil, + }, + { + name: "bidder infos is empty", + bidderInfos: map[string]BidderInfo{}, + expected: nil, + }, + { + name: "one: bidder info has nillable fields as false, viper has as nil", + bidderInfos: map[string]BidderInfo{ + "bidder1": {Disabled: false, ModifyingVastXmlAllowed: false}, + }, + rawConfig: bidder1ConfigNils, + expected: nillableFieldBidderInfos{ + "bidder1": nillableFieldBidderInfo{ + nillableFields: bidderInfoNillableFields{ + Disabled: nil, + ModifyingVastXmlAllowed: nil, + }, + bidderInfo: BidderInfo{Disabled: false, ModifyingVastXmlAllowed: false}, + }, + }, + }, + { + name: "one: bidder info has nillable fields as false, viper has as false", + bidderInfos: map[string]BidderInfo{ + "bidder1": {Disabled: false, ModifyingVastXmlAllowed: false}, + }, + rawConfig: bidder1ConfigFalses, + expected: nillableFieldBidderInfos{ + "bidder1": nillableFieldBidderInfo{ + nillableFields: bidderInfoNillableFields{ + Disabled: &falseValue, + ModifyingVastXmlAllowed: &falseValue, + }, + bidderInfo: BidderInfo{Disabled: false, ModifyingVastXmlAllowed: false}, + }, + }, + }, + { + name: "one: bidder info has nillable fields as false, viper has as true", + bidderInfos: map[string]BidderInfo{ + "bidder1": {Disabled: false, ModifyingVastXmlAllowed: false}, + }, + rawConfig: bidder1ConfigTrues, + expected: nillableFieldBidderInfos{ + "bidder1": nillableFieldBidderInfo{ + nillableFields: bidderInfoNillableFields{ + Disabled: &trueValue, + ModifyingVastXmlAllowed: &trueValue, + }, + bidderInfo: BidderInfo{Disabled: false, ModifyingVastXmlAllowed: false}, + }, + }, + }, + { + name: "many with extra info: bidder infos have nillable fields as false and true, viper has as true and false", + bidderInfos: map[string]BidderInfo{ + "bidder1": {Disabled: false, ModifyingVastXmlAllowed: true, Endpoint: "endpoint a"}, + "bidder2": {Disabled: true, ModifyingVastXmlAllowed: false, Endpoint: "endpoint b"}, + }, + rawConfig: bidder1Bidder2ConfigMixed, + expected: nillableFieldBidderInfos{ + "bidder1": nillableFieldBidderInfo{ + nillableFields: bidderInfoNillableFields{ + Disabled: &trueValue, + ModifyingVastXmlAllowed: &falseValue, + }, + bidderInfo: BidderInfo{Disabled: false, ModifyingVastXmlAllowed: true, Endpoint: "endpoint a"}, + }, + "bidder2": nillableFieldBidderInfo{ + nillableFields: bidderInfoNillableFields{ + Disabled: &falseValue, + ModifyingVastXmlAllowed: &trueValue, + }, + bidderInfo: BidderInfo{Disabled: true, ModifyingVastXmlAllowed: false, Endpoint: "endpoint b"}, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + v := viper.New() + v.SetConfigType("yaml") + for bidderName := range tt.bidderInfos { + setBidderDefaults(v, strings.ToLower(bidderName)) + } + v.ReadConfig(bytes.NewBuffer(tt.rawConfig)) + + result, err := setConfigBidderInfoNillableFields(v, tt.bidderInfos) + + assert.Equal(t, tt.expected, result) + if tt.expectError { + assert.NotNil(t, err) + } else { + assert.Nil(t, err) + } + }) + } +} + func TestTCF2PurposeEnforced(t *testing.T) { tests := []struct { description string From 180eb410cb9f6e1751621797171cec7fa2096122 Mon Sep 17 00:00:00 2001 From: Brian Sardo <1168933+bsardo@users.noreply.github.com> Date: Wed, 15 Nov 2023 13:47:22 -0500 Subject: [PATCH 206/268] Fix: Revert JSON lib used to prepare /bidders/params response (#3300) --- router/router.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/router/router.go b/router/router.go index 0ee9fc7c30e..80d972a9f5b 100644 --- a/router/router.go +++ b/router/router.go @@ -92,7 +92,7 @@ func newJsonDirectoryServer(schemaDirectory string, validator openrtb_ext.Bidder data[aliasName] = bidderData } - response, err := jsonutil.Marshal(data) + response, err := json.Marshal(data) if err != nil { glog.Fatalf("Failed to marshal bidder param JSON-schema: %v", err) } From ea04a390902c9a793f3667827b0e1912d25af13e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Nov 2023 10:02:41 -0500 Subject: [PATCH 207/268] Bump golang.org/x/net from 0.7.0 to 0.17.0 (#3202) --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 912cdaa2aad..9f752b88257 100644 --- a/go.mod +++ b/go.mod @@ -31,8 +31,8 @@ require ( github.com/vrischmann/go-metrics-influxdb v0.1.1 github.com/xeipuuv/gojsonschema v1.2.0 github.com/yudai/gojsondiff v1.0.0 - golang.org/x/net v0.7.0 - golang.org/x/text v0.7.0 + golang.org/x/net v0.17.0 + golang.org/x/text v0.13.0 google.golang.org/grpc v1.53.0 gopkg.in/evanphx/json-patch.v4 v4.12.0 gopkg.in/yaml.v3 v3.0.1 @@ -69,8 +69,8 @@ require ( github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect github.com/yudai/pp v2.0.1+incompatible // indirect - golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect - golang.org/x/sys v0.5.0 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/sys v0.13.0 // indirect google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/ini.v1 v1.66.4 // indirect diff --git a/go.sum b/go.sum index eefe0228261..76ced28500a 100644 --- a/go.sum +++ b/go.sum @@ -527,8 +527,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -613,8 +613,8 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -725,8 +725,8 @@ golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -739,8 +739,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From ee0869d21d31a7a2891e31e3c2b8bf75e08e600e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Nov 2023 11:34:24 -0500 Subject: [PATCH 208/268] Bump google.golang.org/grpc from 1.53.0 to 1.56.3 (#3258) --- go.mod | 12 ++++++------ go.sum | 19 ++++++++++--------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 9f752b88257..d152a3b6614 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,8 @@ require ( github.com/docker/go-units v0.4.0 github.com/go-sql-driver/mysql v1.6.0 github.com/gofrs/uuid v4.2.0+incompatible - github.com/golang/glog v1.0.0 + github.com/golang/glog v1.1.0 + github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/lib/pq v1.10.4 github.com/mitchellh/copystructure v1.2.0 @@ -33,7 +34,7 @@ require ( github.com/yudai/gojsondiff v1.0.0 golang.org/x/net v0.17.0 golang.org/x/text v0.13.0 - google.golang.org/grpc v1.53.0 + google.golang.org/grpc v1.56.3 gopkg.in/evanphx/json-patch.v4 v4.12.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -43,10 +44,9 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d // indirect - github.com/json-iterator/go v1.1.12 // indirect github.com/magiconair/properties v1.8.6 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -71,8 +71,8 @@ require ( github.com/yudai/pp v2.0.1+incompatible // indirect golang.org/x/crypto v0.14.0 // indirect golang.org/x/sys v0.13.0 // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect - google.golang.org/protobuf v1.28.1 // indirect + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/ini.v1 v1.66.4 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 76ced28500a..d05f428cef5 100644 --- a/go.sum +++ b/go.sum @@ -160,8 +160,8 @@ github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -191,8 +191,9 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -911,8 +912,8 @@ google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -943,8 +944,8 @@ google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -959,8 +960,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From fb94284028447674c65eef901cb7d42665d4e521 Mon Sep 17 00:00:00 2001 From: Nikhil Vaidya <102963966+pm-nikhil-vaidya@users.noreply.github.com> Date: Thu, 16 Nov 2023 22:27:01 +0530 Subject: [PATCH 209/268] Floors: Dynamic fetch (#2732) --- config/account.go | 57 +- config/account_test.go | 128 +- config/config.go | 36 +- config/config_test.go | 62 + endpoints/openrtb2/auction_benchmark_test.go | 1 + endpoints/openrtb2/test_utils.go | 1 + exchange/exchange.go | 16 +- exchange/exchange_test.go | 32 +- floors/fetcher.go | 331 +++++ floors/fetcher_test.go | 1279 ++++++++++++++++++ floors/floors.go | 105 +- floors/floors_test.go | 919 ++++++++++++- floors/rule.go | 7 +- go.mod | 1 + go.sum | 2 + openrtb_ext/floors.go | 62 + openrtb_ext/floors_test.go | 262 ++++ router/router.go | 15 +- 18 files changed, 3270 insertions(+), 46 deletions(-) create mode 100644 floors/fetcher.go create mode 100644 floors/fetcher_test.go diff --git a/config/account.go b/config/account.go index f1de54f79a2..ee131873e35 100644 --- a/config/account.go +++ b/config/account.go @@ -58,17 +58,30 @@ type AccountCCPA struct { } type AccountPriceFloors struct { - Enabled bool `mapstructure:"enabled" json:"enabled"` - EnforceFloorsRate int `mapstructure:"enforce_floors_rate" json:"enforce_floors_rate"` - AdjustForBidAdjustment bool `mapstructure:"adjust_for_bid_adjustment" json:"adjust_for_bid_adjustment"` - EnforceDealFloors bool `mapstructure:"enforce_deal_floors" json:"enforce_deal_floors"` - UseDynamicData bool `mapstructure:"use_dynamic_data" json:"use_dynamic_data"` - MaxRule int `mapstructure:"max_rules" json:"max_rules"` - MaxSchemaDims int `mapstructure:"max_schema_dims" json:"max_schema_dims"` + Enabled bool `mapstructure:"enabled" json:"enabled"` + EnforceFloorsRate int `mapstructure:"enforce_floors_rate" json:"enforce_floors_rate"` + AdjustForBidAdjustment bool `mapstructure:"adjust_for_bid_adjustment" json:"adjust_for_bid_adjustment"` + EnforceDealFloors bool `mapstructure:"enforce_deal_floors" json:"enforce_deal_floors"` + UseDynamicData bool `mapstructure:"use_dynamic_data" json:"use_dynamic_data"` + MaxRule int `mapstructure:"max_rules" json:"max_rules"` + MaxSchemaDims int `mapstructure:"max_schema_dims" json:"max_schema_dims"` + Fetcher AccountFloorFetch `mapstructure:"fetch" json:"fetch"` } -func (pf *AccountPriceFloors) validate(errs []error) []error { +// AccountFloorFetch defines the configuration for dynamic floors fetching. +type AccountFloorFetch struct { + Enabled bool `mapstructure:"enabled" json:"enabled"` + URL string `mapstructure:"url" json:"url"` + Timeout int `mapstructure:"timeout_ms" json:"timeout_ms"` + MaxFileSizeKB int `mapstructure:"max_file_size_kb" json:"max_file_size_kb"` + MaxRules int `mapstructure:"max_rules" json:"max_rules"` + MaxAge int `mapstructure:"max_age_sec" json:"max_age_sec"` + Period int `mapstructure:"period_sec" json:"period_sec"` + MaxSchemaDims int `mapstructure:"max_schema_dims" json:"max_schema_dims"` + AccountID string `mapstructure:"accountID" json:"accountID"` +} +func (pf *AccountPriceFloors) validate(errs []error) []error { if pf.EnforceFloorsRate < 0 || pf.EnforceFloorsRate > 100 { errs = append(errs, fmt.Errorf(`account_defaults.price_floors.enforce_floors_rate should be between 0 and 100`)) } @@ -81,6 +94,34 @@ func (pf *AccountPriceFloors) validate(errs []error) []error { errs = append(errs, fmt.Errorf(`account_defaults.price_floors.max_schema_dims should be between 0 and 20`)) } + if pf.Fetcher.Period > pf.Fetcher.MaxAge { + errs = append(errs, fmt.Errorf(`account_defaults.price_floors.fetch.period_sec should be less than account_defaults.price_floors.fetch.max_age_sec`)) + } + + if pf.Fetcher.Period < 300 { + errs = append(errs, fmt.Errorf(`account_defaults.price_floors.fetch.period_sec should not be less than 300 seconds`)) + } + + if pf.Fetcher.MaxAge < 600 { + errs = append(errs, fmt.Errorf(`account_defaults.price_floors.fetch.max_age_sec should not be less than 600 seconds and greater than maximum integer value`)) + } + + if !(pf.Fetcher.Timeout > 10 && pf.Fetcher.Timeout < 10000) { + errs = append(errs, fmt.Errorf(`account_defaults.price_floors.fetch.timeout_ms should be between 10 to 10,000 miliseconds`)) + } + + if pf.Fetcher.MaxRules < 0 { + errs = append(errs, fmt.Errorf(`account_defaults.price_floors.fetch.max_rules should be greater than or equal to 0`)) + } + + if pf.Fetcher.MaxFileSizeKB < 0 { + errs = append(errs, fmt.Errorf(`account_defaults.price_floors.fetch.max_file_size_kb should be greater than or equal to 0`)) + } + + if !(pf.Fetcher.MaxSchemaDims >= 0 && pf.Fetcher.MaxSchemaDims < 20) { + errs = append(errs, fmt.Errorf(`account_defaults.price_floors.fetch.max_schema_dims should not be less than 0 and greater than 20`)) + } + return errs } diff --git a/config/account_test.go b/config/account_test.go index 648618f2706..65e7f3e8716 100644 --- a/config/account_test.go +++ b/config/account_test.go @@ -795,7 +795,6 @@ func TestModulesGetConfig(t *testing.T) { } func TestAccountPriceFloorsValidate(t *testing.T) { - tests := []struct { description string pf *AccountPriceFloors @@ -807,12 +806,22 @@ func TestAccountPriceFloorsValidate(t *testing.T) { EnforceFloorsRate: 100, MaxRule: 200, MaxSchemaDims: 10, + Fetcher: AccountFloorFetch{ + Period: 300, + MaxAge: 600, + Timeout: 12, + }, }, }, { description: "Invalid configuration: EnforceFloorRate:110", pf: &AccountPriceFloors{ EnforceFloorsRate: 110, + Fetcher: AccountFloorFetch{ + Period: 300, + MaxAge: 600, + Timeout: 12, + }, }, want: []error{errors.New("account_defaults.price_floors.enforce_floors_rate should be between 0 and 100")}, }, @@ -820,6 +829,11 @@ func TestAccountPriceFloorsValidate(t *testing.T) { description: "Invalid configuration: EnforceFloorRate:-10", pf: &AccountPriceFloors{ EnforceFloorsRate: -10, + Fetcher: AccountFloorFetch{ + Period: 300, + MaxAge: 600, + Timeout: 12, + }, }, want: []error{errors.New("account_defaults.price_floors.enforce_floors_rate should be between 0 and 100")}, }, @@ -827,6 +841,11 @@ func TestAccountPriceFloorsValidate(t *testing.T) { description: "Invalid configuration: MaxRule:-20", pf: &AccountPriceFloors{ MaxRule: -20, + Fetcher: AccountFloorFetch{ + Period: 300, + MaxAge: 600, + Timeout: 12, + }, }, want: []error{errors.New("account_defaults.price_floors.max_rules should be between 0 and 2147483647")}, }, @@ -834,9 +853,116 @@ func TestAccountPriceFloorsValidate(t *testing.T) { description: "Invalid configuration: MaxSchemaDims:100", pf: &AccountPriceFloors{ MaxSchemaDims: 100, + Fetcher: AccountFloorFetch{ + Period: 300, + MaxAge: 600, + Timeout: 12, + }, }, want: []error{errors.New("account_defaults.price_floors.max_schema_dims should be between 0 and 20")}, }, + { + description: "Invalid period for fetch", + pf: &AccountPriceFloors{ + EnforceFloorsRate: 100, + MaxRule: 200, + MaxSchemaDims: 10, + Fetcher: AccountFloorFetch{ + Period: 100, + MaxAge: 600, + Timeout: 12, + }, + }, + want: []error{errors.New("account_defaults.price_floors.fetch.period_sec should not be less than 300 seconds")}, + }, + { + description: "Invalid max age for fetch", + pf: &AccountPriceFloors{ + EnforceFloorsRate: 100, + MaxRule: 200, + MaxSchemaDims: 10, + Fetcher: AccountFloorFetch{ + Period: 300, + MaxAge: 500, + Timeout: 12, + }, + }, + want: []error{errors.New("account_defaults.price_floors.fetch.max_age_sec should not be less than 600 seconds and greater than maximum integer value")}, + }, + { + description: "Period is greater than max age", + pf: &AccountPriceFloors{ + EnforceFloorsRate: 100, + MaxRule: 200, + MaxSchemaDims: 10, + Fetcher: AccountFloorFetch{ + Period: 700, + MaxAge: 600, + Timeout: 12, + }, + }, + want: []error{errors.New("account_defaults.price_floors.fetch.period_sec should be less than account_defaults.price_floors.fetch.max_age_sec")}, + }, + { + description: "Invalid timeout", + pf: &AccountPriceFloors{ + EnforceFloorsRate: 100, + MaxRule: 200, + MaxSchemaDims: 10, + Fetcher: AccountFloorFetch{ + Period: 300, + MaxAge: 600, + Timeout: 4, + }, + }, + want: []error{errors.New("account_defaults.price_floors.fetch.timeout_ms should be between 10 to 10,000 miliseconds")}, + }, + { + description: "Invalid Max Rules", + pf: &AccountPriceFloors{ + EnforceFloorsRate: 100, + MaxRule: 200, + MaxSchemaDims: 10, + Fetcher: AccountFloorFetch{ + Period: 300, + MaxAge: 600, + Timeout: 12, + MaxRules: -2, + }, + }, + want: []error{errors.New("account_defaults.price_floors.fetch.max_rules should be greater than or equal to 0")}, + }, + { + description: "Invalid Max File size", + pf: &AccountPriceFloors{ + EnforceFloorsRate: 100, + MaxRule: 200, + MaxSchemaDims: 10, + Fetcher: AccountFloorFetch{ + Period: 300, + MaxAge: 600, + Timeout: 12, + MaxFileSizeKB: -1, + }, + }, + want: []error{errors.New("account_defaults.price_floors.fetch.max_file_size_kb should be greater than or equal to 0")}, + }, + { + description: "Invalid max_schema_dims", + pf: &AccountPriceFloors{ + EnforceFloorsRate: 100, + MaxRule: 200, + MaxSchemaDims: 10, + Fetcher: AccountFloorFetch{ + Period: 300, + MaxAge: 600, + Timeout: 12, + MaxFileSizeKB: 10, + MaxSchemaDims: 40, + }, + }, + want: []error{errors.New("account_defaults.price_floors.fetch.max_schema_dims should not be less than 0 and greater than 20")}, + }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { diff --git a/config/config.go b/config/config.go index 34c95822b3d..60a541e2ed0 100644 --- a/config/config.go +++ b/config/config.go @@ -103,7 +103,16 @@ type Configuration struct { } type PriceFloors struct { - Enabled bool `mapstructure:"enabled"` + Enabled bool `mapstructure:"enabled"` + Fetcher PriceFloorFetcher `mapstructure:"fetcher"` +} + +type PriceFloorFetcher struct { + HttpClient HTTPClient `mapstructure:"http_client"` + CacheSize int `mapstructure:"cache_size_mb"` + Worker int `mapstructure:"worker"` + Capacity int `mapstructure:"capacity"` + MaxRetries int `mapstructure:"max_retries"` } const MIN_COOKIE_SIZE_BYTES = 500 @@ -140,10 +149,6 @@ func (cfg *Configuration) validate(v *viper.Viper) []error { glog.Warning(`account_defaults.events has no effect as the feature is under development.`) } - if cfg.PriceFloors.Enabled { - glog.Warning(`cfg.PriceFloors.Enabled will currently not do anything as price floors feature is still under development.`) - } - errs = cfg.Experiment.validate(errs) errs = cfg.BidderInfos.validate(errs) errs = cfg.AccountDefaults.Privacy.IPv6Config.Validate(errs) @@ -1094,9 +1099,30 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { v.SetDefault("account_defaults.price_floors.use_dynamic_data", false) v.SetDefault("account_defaults.price_floors.max_rules", 100) v.SetDefault("account_defaults.price_floors.max_schema_dims", 3) + v.SetDefault("account_defaults.price_floors.fetch.enabled", false) + v.SetDefault("account_defaults.price_floors.fetch.url", "") + v.SetDefault("account_defaults.price_floors.fetch.timeout_ms", 3000) + v.SetDefault("account_defaults.price_floors.fetch.max_file_size_kb", 100) + v.SetDefault("account_defaults.price_floors.fetch.max_rules", 1000) + v.SetDefault("account_defaults.price_floors.fetch.max_age_sec", 86400) + v.SetDefault("account_defaults.price_floors.fetch.period_sec", 3600) + v.SetDefault("account_defaults.price_floors.fetch.max_schema_dims", 0) + + v.SetDefault("account_defaults.events_enabled", false) v.SetDefault("account_defaults.privacy.ipv6.anon_keep_bits", 56) v.SetDefault("account_defaults.privacy.ipv4.anon_keep_bits", 24) + //Defaults for Price floor fetcher + v.SetDefault("price_floors.fetcher.worker", 20) + v.SetDefault("price_floors.fetcher.capacity", 20000) + v.SetDefault("price_floors.fetcher.cache_size_mb", 64) + v.SetDefault("price_floors.fetcher.http_client.max_connections_per_host", 0) // unlimited + v.SetDefault("price_floors.fetcher.http_client.max_idle_connections", 40) + v.SetDefault("price_floors.fetcher.http_client.max_idle_connections_per_host", 2) + v.SetDefault("price_floors.fetcher.http_client.idle_connection_timeout_seconds", 60) + v.SetDefault("price_floors.fetcher.max_retries", 10) + + v.SetDefault("account_defaults.events_enabled", false) v.SetDefault("compression.response.enable_gzip", false) v.SetDefault("compression.request.enable_gzip", false) diff --git a/config/config_test.go b/config/config_test.go index b3c43dfa4d3..a551c1be66e 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -175,6 +175,14 @@ func TestDefaults(t *testing.T) { //Assert the price floor default values cmpBools(t, "price_floors.enabled", false, cfg.PriceFloors.Enabled) + cmpInts(t, "price_floors.fetcher.worker", 20, cfg.PriceFloors.Fetcher.Worker) + cmpInts(t, "price_floors.fetcher.capacity", 20000, cfg.PriceFloors.Fetcher.Capacity) + cmpInts(t, "price_floors.fetcher.cache_size_mb", 64, cfg.PriceFloors.Fetcher.CacheSize) + cmpInts(t, "price_floors.fetcher.http_client.max_connections_per_host", 0, cfg.PriceFloors.Fetcher.HttpClient.MaxConnsPerHost) + cmpInts(t, "price_floors.fetcher.http_client.max_idle_connections", 40, cfg.PriceFloors.Fetcher.HttpClient.MaxIdleConns) + cmpInts(t, "price_floors.fetcher.http_client.max_idle_connections_per_host", 2, cfg.PriceFloors.Fetcher.HttpClient.MaxIdleConnsPerHost) + cmpInts(t, "price_floors.fetcher.http_client.idle_connection_timeout_seconds", 60, cfg.PriceFloors.Fetcher.HttpClient.IdleConnTimeout) + cmpInts(t, "price_floors.fetcher.max_retries", 10, cfg.PriceFloors.Fetcher.MaxRetries) // Assert compression related defaults cmpBools(t, "compression.request.enable_gzip", false, cfg.Compression.Request.GZIP) @@ -187,6 +195,15 @@ func TestDefaults(t *testing.T) { cmpBools(t, "account_defaults.price_floors.use_dynamic_data", false, cfg.AccountDefaults.PriceFloors.UseDynamicData) cmpInts(t, "account_defaults.price_floors.max_rules", 100, cfg.AccountDefaults.PriceFloors.MaxRule) cmpInts(t, "account_defaults.price_floors.max_schema_dims", 3, cfg.AccountDefaults.PriceFloors.MaxSchemaDims) + cmpBools(t, "account_defaults.price_floors.fetch.enabled", false, cfg.AccountDefaults.PriceFloors.Fetcher.Enabled) + cmpStrings(t, "account_defaults.price_floors.fetch.url", "", cfg.AccountDefaults.PriceFloors.Fetcher.URL) + cmpInts(t, "account_defaults.price_floors.fetch.timeout_ms", 3000, cfg.AccountDefaults.PriceFloors.Fetcher.Timeout) + cmpInts(t, "account_defaults.price_floors.fetch.max_file_size_kb", 100, cfg.AccountDefaults.PriceFloors.Fetcher.MaxFileSizeKB) + cmpInts(t, "account_defaults.price_floors.fetch.max_rules", 1000, cfg.AccountDefaults.PriceFloors.Fetcher.MaxRules) + cmpInts(t, "account_defaults.price_floors.fetch.period_sec", 3600, cfg.AccountDefaults.PriceFloors.Fetcher.Period) + cmpInts(t, "account_defaults.price_floors.fetch.max_age_sec", 86400, cfg.AccountDefaults.PriceFloors.Fetcher.MaxAge) + cmpInts(t, "account_defaults.price_floors.fetch.max_schema_dims", 0, cfg.AccountDefaults.PriceFloors.Fetcher.MaxSchemaDims) + cmpBools(t, "account_defaults.events.enabled", false, cfg.AccountDefaults.Events.Enabled) cmpBools(t, "hooks.enabled", false, cfg.Hooks.Enabled) @@ -451,6 +468,16 @@ hooks: enabled: true price_floors: enabled: true + fetcher: + worker: 20 + capacity: 20000 + cache_size_mb: 8 + http_client: + max_connections_per_host: 5 + max_idle_connections: 1 + max_idle_connections_per_host: 2 + idle_connection_timeout_seconds: 10 + max_retries: 5 account_defaults: events: enabled: true @@ -462,6 +489,15 @@ account_defaults: use_dynamic_data: true max_rules: 120 max_schema_dims: 5 + fetch: + enabled: true + url: http://test.com/floors + timeout_ms: 500 + max_file_size_kb: 200 + max_rules: 500 + period_sec: 2000 + max_age_sec: 6000 + max_schema_dims: 10 privacy: ipv6: anon_keep_bits: 50 @@ -557,6 +593,14 @@ func TestFullConfig(t *testing.T) { //Assert the price floor values cmpBools(t, "price_floors.enabled", true, cfg.PriceFloors.Enabled) + cmpInts(t, "price_floors.fetcher.worker", 20, cfg.PriceFloors.Fetcher.Worker) + cmpInts(t, "price_floors.fetcher.capacity", 20000, cfg.PriceFloors.Fetcher.Capacity) + cmpInts(t, "price_floors.fetcher.cache_size_mb", 8, cfg.PriceFloors.Fetcher.CacheSize) + cmpInts(t, "price_floors.fetcher.http_client.max_connections_per_host", 5, cfg.PriceFloors.Fetcher.HttpClient.MaxConnsPerHost) + cmpInts(t, "price_floors.fetcher.http_client.max_idle_connections", 1, cfg.PriceFloors.Fetcher.HttpClient.MaxIdleConns) + cmpInts(t, "price_floors.fetcher.http_client.max_idle_connections_per_host", 2, cfg.PriceFloors.Fetcher.HttpClient.MaxIdleConnsPerHost) + cmpInts(t, "price_floors.fetcher.http_client.idle_connection_timeout_seconds", 10, cfg.PriceFloors.Fetcher.HttpClient.IdleConnTimeout) + cmpInts(t, "price_floors.fetcher.max_retries", 5, cfg.PriceFloors.Fetcher.MaxRetries) cmpBools(t, "account_defaults.price_floors.enabled", true, cfg.AccountDefaults.PriceFloors.Enabled) cmpInts(t, "account_defaults.price_floors.enforce_floors_rate", 50, cfg.AccountDefaults.PriceFloors.EnforceFloorsRate) cmpBools(t, "account_defaults.price_floors.adjust_for_bid_adjustment", false, cfg.AccountDefaults.PriceFloors.AdjustForBidAdjustment) @@ -564,6 +608,15 @@ func TestFullConfig(t *testing.T) { cmpBools(t, "account_defaults.price_floors.use_dynamic_data", true, cfg.AccountDefaults.PriceFloors.UseDynamicData) cmpInts(t, "account_defaults.price_floors.max_rules", 120, cfg.AccountDefaults.PriceFloors.MaxRule) cmpInts(t, "account_defaults.price_floors.max_schema_dims", 5, cfg.AccountDefaults.PriceFloors.MaxSchemaDims) + cmpBools(t, "account_defaults.price_floors.fetch.enabled", true, cfg.AccountDefaults.PriceFloors.Fetcher.Enabled) + cmpStrings(t, "account_defaults.price_floors.fetch.url", "http://test.com/floors", cfg.AccountDefaults.PriceFloors.Fetcher.URL) + cmpInts(t, "account_defaults.price_floors.fetch.timeout_ms", 500, cfg.AccountDefaults.PriceFloors.Fetcher.Timeout) + cmpInts(t, "account_defaults.price_floors.fetch.max_file_size_kb", 200, cfg.AccountDefaults.PriceFloors.Fetcher.MaxFileSizeKB) + cmpInts(t, "account_defaults.price_floors.fetch.max_rules", 500, cfg.AccountDefaults.PriceFloors.Fetcher.MaxRules) + cmpInts(t, "account_defaults.price_floors.fetch.period_sec", 2000, cfg.AccountDefaults.PriceFloors.Fetcher.Period) + cmpInts(t, "account_defaults.price_floors.fetch.max_age_sec", 6000, cfg.AccountDefaults.PriceFloors.Fetcher.MaxAge) + cmpInts(t, "account_defaults.price_floors.fetch.max_schema_dims", 10, cfg.AccountDefaults.PriceFloors.Fetcher.MaxSchemaDims) + cmpBools(t, "account_defaults.events.enabled", true, cfg.AccountDefaults.Events.Enabled) cmpInts(t, "account_defaults.privacy.ipv6.anon_keep_bits", 50, cfg.AccountDefaults.Privacy.IPv6Config.AnonKeepBits) @@ -772,6 +825,15 @@ func TestValidateConfig(t *testing.T) { Files: FileFetcherConfig{Enabled: true}, InMemoryCache: InMemoryCache{Type: "none"}, }, + AccountDefaults: Account{ + PriceFloors: AccountPriceFloors{ + Fetcher: AccountFloorFetch{ + Timeout: 100, + Period: 300, + MaxAge: 600, + }, + }, + }, } v := viper.New() diff --git a/endpoints/openrtb2/auction_benchmark_test.go b/endpoints/openrtb2/auction_benchmark_test.go index 88a55e627e7..835d2920af4 100644 --- a/endpoints/openrtb2/auction_benchmark_test.go +++ b/endpoints/openrtb2/auction_benchmark_test.go @@ -95,6 +95,7 @@ func BenchmarkOpenrtbEndpoint(b *testing.B) { empty_fetcher.EmptyFetcher{}, &adscert.NilSigner{}, macros.NewStringIndexBasedReplacer(), + nil, ) endpoint, _ := NewEndpoint( diff --git a/endpoints/openrtb2/test_utils.go b/endpoints/openrtb2/test_utils.go index cfc8f5d8dac..e3e7803e551 100644 --- a/endpoints/openrtb2/test_utils.go +++ b/endpoints/openrtb2/test_utils.go @@ -1204,6 +1204,7 @@ func buildTestExchange(testCfg *testConfigValues, adapterMap map[openrtb_ext.Bid mockFetcher, &adscert.NilSigner{}, macros.NewStringIndexBasedReplacer(), + nil, ) testExchange = &exchangeTestWrapper{ diff --git a/exchange/exchange.go b/exchange/exchange.go index b07c4bdf2a5..bb59fe90d43 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -81,7 +81,8 @@ type exchange struct { bidValidationEnforcement config.Validations requestSplitter requestSplitter macroReplacer macros.Replacer - floor config.PriceFloors + priceFloorEnabled bool + priceFloorFetcher floors.FloorFetcher } // Container to pass out response ext data from the GetAllBids goroutines back into the main thread @@ -130,7 +131,7 @@ func (randomDeduplicateBidBooleanGenerator) Generate() bool { return rand.Intn(100) < 50 } -func NewExchange(adapters map[openrtb_ext.BidderName]AdaptedBidder, cache prebid_cache_client.Client, cfg *config.Configuration, syncersByBidder map[string]usersync.Syncer, metricsEngine metrics.MetricsEngine, infos config.BidderInfos, gdprPermsBuilder gdpr.PermissionsBuilder, currencyConverter *currency.RateConverter, categoriesFetcher stored_requests.CategoryFetcher, adsCertSigner adscert.Signer, macroReplacer macros.Replacer) Exchange { +func NewExchange(adapters map[openrtb_ext.BidderName]AdaptedBidder, cache prebid_cache_client.Client, cfg *config.Configuration, syncersByBidder map[string]usersync.Syncer, metricsEngine metrics.MetricsEngine, infos config.BidderInfos, gdprPermsBuilder gdpr.PermissionsBuilder, currencyConverter *currency.RateConverter, categoriesFetcher stored_requests.CategoryFetcher, adsCertSigner adscert.Signer, macroReplacer macros.Replacer, priceFloorFetcher floors.FloorFetcher) Exchange { bidderToSyncerKey := map[string]string{} for bidder, syncer := range syncersByBidder { bidderToSyncerKey[bidder] = syncer.Key() @@ -175,7 +176,8 @@ func NewExchange(adapters map[openrtb_ext.BidderName]AdaptedBidder, cache prebid bidValidationEnforcement: cfg.Validations, requestSplitter: requestSplitter, macroReplacer: macroReplacer, - floor: cfg.PriceFloors, + priceFloorEnabled: cfg.PriceFloors.Enabled, + priceFloorFetcher: priceFloorFetcher, } } @@ -233,7 +235,6 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog return nil, nil } - var floorErrs []error err := r.HookExecutor.ExecuteProcessedAuctionStage(r.BidRequestWrapper) if err != nil { return nil, err @@ -268,8 +269,9 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog // Get currency rates conversions for the auction conversions := e.getAuctionCurrencyRates(requestExtPrebid.CurrencyConversions) - if e.floor.Enabled { - floorErrs = floors.EnrichWithPriceFloors(r.BidRequestWrapper, r.Account, conversions) + var floorErrs []error + if e.priceFloorEnabled { + floorErrs = floors.EnrichWithPriceFloors(r.BidRequestWrapper, r.Account, conversions, e.priceFloorFetcher) } responseDebugAllow, accountDebugAllow, debugLog := getDebugInfo(r.BidRequestWrapper.Test, requestExtPrebid, r.Account.DebugAllow, debugLog) @@ -386,7 +388,7 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog ) if anyBidsReturned { - if e.floor.Enabled { + if e.priceFloorEnabled { var rejectedBids []*entities.PbsOrtbSeatBid var enforceErrs []error diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go index bfeb9374af3..a537054cbce 100644 --- a/exchange/exchange_test.go +++ b/exchange/exchange_test.go @@ -83,7 +83,7 @@ func TestNewExchange(t *testing.T) { }, }.Builder - e := NewExchange(adapters, nil, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, biddersInfo, gdprPermsBuilder, currencyConverter, nilCategoryFetcher{}, &adscert.NilSigner{}, macros.NewStringIndexBasedReplacer()).(*exchange) + e := NewExchange(adapters, nil, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, biddersInfo, gdprPermsBuilder, currencyConverter, nilCategoryFetcher{}, &adscert.NilSigner{}, macros.NewStringIndexBasedReplacer(), nil).(*exchange) for _, bidderName := range knownAdapters { if _, ok := e.adapterMap[bidderName]; !ok { if biddersInfo[string(bidderName)].IsEnabled() { @@ -133,7 +133,7 @@ func TestCharacterEscape(t *testing.T) { }, }.Builder - e := NewExchange(adapters, nil, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, biddersInfo, gdprPermsBuilder, currencyConverter, nilCategoryFetcher{}, &adscert.NilSigner{}, macros.NewStringIndexBasedReplacer()).(*exchange) + e := NewExchange(adapters, nil, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, biddersInfo, gdprPermsBuilder, currencyConverter, nilCategoryFetcher{}, &adscert.NilSigner{}, macros.NewStringIndexBasedReplacer(), nil).(*exchange) // 3) Build all the parameters e.buildBidResponse(ctx.Background(), liveA... ) needs //liveAdapters []openrtb_ext.BidderName, @@ -816,6 +816,14 @@ func TestAdapterCurrency(t *testing.T) { } } +type mockPriceFloorFetcher struct{} + +func (mpf *mockPriceFloorFetcher) Fetch(configs config.AccountPriceFloors) (*openrtb_ext.PriceFloorRules, string) { + return nil, openrtb_ext.FetchNone +} + +func (mpf *mockPriceFloorFetcher) Stop() {} + func TestFloorsSignalling(t *testing.T) { fakeCurrencyClient := &fakeCurrencyRatesHttpClient{ @@ -840,7 +848,8 @@ func TestFloorsSignalling(t *testing.T) { currencyConverter: currencyConverter, categoriesFetcher: nilCategoryFetcher{}, bidIDGenerator: &mockBidIDGenerator{false, false}, - floor: config.PriceFloors{Enabled: true}, + priceFloorEnabled: true, + priceFloorFetcher: &mockPriceFloorFetcher{}, } e.requestSplitter = requestSplitter{ me: e.me, @@ -1428,7 +1437,7 @@ func TestGetBidCacheInfoEndToEnd(t *testing.T) { }, }.Builder - e := NewExchange(adapters, pbc, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, biddersInfo, gdprPermsBuilder, currencyConverter, nilCategoryFetcher{}, &adscert.NilSigner{}, macros.NewStringIndexBasedReplacer()).(*exchange) + e := NewExchange(adapters, pbc, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, biddersInfo, gdprPermsBuilder, currencyConverter, nilCategoryFetcher{}, &adscert.NilSigner{}, macros.NewStringIndexBasedReplacer(), nil).(*exchange) // 3) Build all the parameters e.buildBidResponse(ctx.Background(), liveA... ) needs liveAdapters := []openrtb_ext.BidderName{bidderName} @@ -1785,7 +1794,7 @@ func TestBidResponseCurrency(t *testing.T) { }, }.Builder - e := NewExchange(adapters, nil, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, biddersInfo, gdprPermsBuilder, currencyConverter, nilCategoryFetcher{}, &adscert.NilSigner{}, macros.NewStringIndexBasedReplacer()).(*exchange) + e := NewExchange(adapters, nil, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, biddersInfo, gdprPermsBuilder, currencyConverter, nilCategoryFetcher{}, &adscert.NilSigner{}, macros.NewStringIndexBasedReplacer(), nil).(*exchange) liveAdapters := make([]openrtb_ext.BidderName, 1) liveAdapters[0] = "appnexus" @@ -1931,7 +1940,7 @@ func TestBidResponseImpExtInfo(t *testing.T) { t.Fatalf("Error intializing adapters: %v", adaptersErr) } - e := NewExchange(adapters, nil, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, nil, gdprPermsBuilder, nil, nilCategoryFetcher{}, &adscert.NilSigner{}, macros.NewStringIndexBasedReplacer()).(*exchange) + e := NewExchange(adapters, nil, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, nil, gdprPermsBuilder, nil, nilCategoryFetcher{}, &adscert.NilSigner{}, macros.NewStringIndexBasedReplacer(), nil).(*exchange) liveAdapters := make([]openrtb_ext.BidderName, 1) liveAdapters[0] = "appnexus" @@ -2023,7 +2032,7 @@ func TestRaceIntegration(t *testing.T) { }, }.Builder - ex := NewExchange(adapters, &wellBehavedCache{}, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, biddersInfo, gdprPermsBuilder, currencyConverter, &nilCategoryFetcher{}, &adscert.NilSigner{}, macros.NewStringIndexBasedReplacer()).(*exchange) + ex := NewExchange(adapters, &wellBehavedCache{}, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, biddersInfo, gdprPermsBuilder, currencyConverter, &nilCategoryFetcher{}, &adscert.NilSigner{}, macros.NewStringIndexBasedReplacer(), nil).(*exchange) _, err = ex.HoldAuction(context.Background(), auctionRequest, &debugLog) if err != nil { t.Errorf("HoldAuction returned unexpected error: %v", err) @@ -2121,7 +2130,7 @@ func TestPanicRecovery(t *testing.T) { }, }.Builder - e := NewExchange(adapters, nil, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, biddersInfo, gdprPermsBuilder, currencyConverter, nilCategoryFetcher{}, &adscert.NilSigner{}, macros.NewStringIndexBasedReplacer()).(*exchange) + e := NewExchange(adapters, nil, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, biddersInfo, gdprPermsBuilder, currencyConverter, nilCategoryFetcher{}, &adscert.NilSigner{}, macros.NewStringIndexBasedReplacer(), nil).(*exchange) chBids := make(chan *bidResponseWrapper, 1) panicker := func(bidderRequest BidderRequest, conversions currency.Conversions) { @@ -2191,7 +2200,7 @@ func TestPanicRecoveryHighLevel(t *testing.T) { allowAllBidders: true, }, }.Builder - e := NewExchange(adapters, &mockCache{}, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, biddersInfo, gdprPermsBuilder, currencyConverter, categoriesFetcher, &adscert.NilSigner{}, macros.NewStringIndexBasedReplacer()).(*exchange) + e := NewExchange(adapters, &mockCache{}, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, biddersInfo, gdprPermsBuilder, currencyConverter, categoriesFetcher, &adscert.NilSigner{}, macros.NewStringIndexBasedReplacer(), nil).(*exchange) e.adapterMap[openrtb_ext.BidderBeachfront] = panicingAdapter{} e.adapterMap[openrtb_ext.BidderAppnexus] = panicingAdapter{} @@ -2634,7 +2643,8 @@ func newExchangeForTests(t *testing.T, filename string, expectations map[string] server: config.Server{ExternalUrl: server.ExternalUrl, GvlID: server.GvlID, DataCenter: server.DataCenter}, bidValidationEnforcement: hostBidValidation, requestSplitter: requestSplitter, - floor: config.PriceFloors{Enabled: floorsFlag}, + priceFloorEnabled: floorsFlag, + priceFloorFetcher: &mockPriceFloorFetcher{}, } } @@ -4660,7 +4670,7 @@ func TestPassExperimentConfigsToHoldAuction(t *testing.T) { }, }.Builder - e := NewExchange(adapters, nil, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, biddersInfo, gdprPermsBuilder, currencyConverter, nilCategoryFetcher{}, &signer, macros.NewStringIndexBasedReplacer()).(*exchange) + e := NewExchange(adapters, nil, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, biddersInfo, gdprPermsBuilder, currencyConverter, nilCategoryFetcher{}, &signer, macros.NewStringIndexBasedReplacer(), nil).(*exchange) // Define mock incoming bid requeset mockBidRequest := &openrtb2.BidRequest{ diff --git a/floors/fetcher.go b/floors/fetcher.go new file mode 100644 index 00000000000..6df43445010 --- /dev/null +++ b/floors/fetcher.go @@ -0,0 +1,331 @@ +package floors + +import ( + "container/heap" + "context" + "encoding/json" + "errors" + "io" + "math" + "net/http" + "strconv" + "time" + + "github.com/alitto/pond" + validator "github.com/asaskevich/govalidator" + "github.com/coocood/freecache" + "github.com/golang/glog" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/timeutil" +) + +var refetchCheckInterval = 300 + +type fetchInfo struct { + config.AccountFloorFetch + fetchTime int64 + refetchRequest bool + retryCount int +} + +type WorkerPool interface { + TrySubmit(task func()) bool + Stop() +} + +type FloorFetcher interface { + Fetch(configs config.AccountPriceFloors) (*openrtb_ext.PriceFloorRules, string) + Stop() +} + +type PriceFloorFetcher struct { + pool WorkerPool // Goroutines worker pool + fetchQueue FetchQueue // Priority Queue to fetch floor data + fetchInProgress map[string]bool // Map of URL with fetch status + configReceiver chan fetchInfo // Channel which recieves URLs to be fetched + done chan struct{} // Channel to close fetcher + cache *freecache.Cache // cache + httpClient *http.Client // http client to fetch data from url + time timeutil.Time // time interface to record request timings + metricEngine metrics.MetricsEngine // Records malfunctions in dynamic fetch + maxRetries int // Max number of retries for failing URLs +} + +type FetchQueue []*fetchInfo + +func (fq FetchQueue) Len() int { + return len(fq) +} + +func (fq FetchQueue) Less(i, j int) bool { + return fq[i].fetchTime < fq[j].fetchTime +} + +func (fq FetchQueue) Swap(i, j int) { + fq[i], fq[j] = fq[j], fq[i] +} + +func (fq *FetchQueue) Push(element interface{}) { + fetchInfo := element.(*fetchInfo) + *fq = append(*fq, fetchInfo) +} + +func (fq *FetchQueue) Pop() interface{} { + old := *fq + n := len(old) + fetchInfo := old[n-1] + old[n-1] = nil + *fq = old[0 : n-1] + return fetchInfo +} + +func (fq *FetchQueue) Top() *fetchInfo { + old := *fq + if len(old) == 0 { + return nil + } + return old[0] +} + +func workerPanicHandler(p interface{}) { + glog.Errorf("floor fetcher worker panicked: %v", p) +} + +func NewPriceFloorFetcher(config config.PriceFloors, httpClient *http.Client, metricEngine metrics.MetricsEngine) *PriceFloorFetcher { + if !config.Enabled { + return nil + } + + floorFetcher := PriceFloorFetcher{ + pool: pond.New(config.Fetcher.Worker, config.Fetcher.Capacity, pond.PanicHandler(workerPanicHandler)), + fetchQueue: make(FetchQueue, 0, 100), + fetchInProgress: make(map[string]bool), + configReceiver: make(chan fetchInfo, config.Fetcher.Capacity), + done: make(chan struct{}), + cache: freecache.NewCache(config.Fetcher.CacheSize * 1024 * 1024), + httpClient: httpClient, + time: &timeutil.RealTime{}, + metricEngine: metricEngine, + maxRetries: config.Fetcher.MaxRetries, + } + + go floorFetcher.Fetcher() + + return &floorFetcher +} + +func (f *PriceFloorFetcher) SetWithExpiry(key string, value json.RawMessage, cacheExpiry int) { + f.cache.Set([]byte(key), value, cacheExpiry) +} + +func (f *PriceFloorFetcher) Get(key string) (json.RawMessage, bool) { + data, err := f.cache.Get([]byte(key)) + if err != nil { + return nil, false + } + + return data, true +} + +func (f *PriceFloorFetcher) Fetch(config config.AccountPriceFloors) (*openrtb_ext.PriceFloorRules, string) { + if f == nil || !config.UseDynamicData || len(config.Fetcher.URL) == 0 || !validator.IsURL(config.Fetcher.URL) { + return nil, openrtb_ext.FetchNone + } + + // Check for floors JSON in cache + if result, found := f.Get(config.Fetcher.URL); found { + var fetchedFloorData openrtb_ext.PriceFloorRules + if err := json.Unmarshal(result, &fetchedFloorData); err != nil || fetchedFloorData.Data == nil { + return nil, openrtb_ext.FetchError + } + return &fetchedFloorData, openrtb_ext.FetchSuccess + } + + //miss: push to channel to fetch and return empty response + if config.Enabled && config.Fetcher.Enabled && config.Fetcher.Timeout > 0 { + fetchConfig := fetchInfo{AccountFloorFetch: config.Fetcher, fetchTime: f.time.Now().Unix(), refetchRequest: false, retryCount: 0} + f.configReceiver <- fetchConfig + } + + return nil, openrtb_ext.FetchInprogress +} + +func (f *PriceFloorFetcher) worker(fetchConfig fetchInfo) { + floorData, fetchedMaxAge := f.fetchAndValidate(fetchConfig.AccountFloorFetch) + if floorData != nil { + // Reset retry count when data is successfully fetched + fetchConfig.retryCount = 0 + + // Update cache with new floor rules + cacheExpiry := fetchConfig.AccountFloorFetch.MaxAge + if fetchedMaxAge != 0 { + cacheExpiry = fetchedMaxAge + } + floorData, err := json.Marshal(floorData) + if err != nil { + glog.Errorf("Error while marshaling fetched floor data for url %s", fetchConfig.AccountFloorFetch.URL) + } else { + f.SetWithExpiry(fetchConfig.AccountFloorFetch.URL, floorData, cacheExpiry) + } + } else { + fetchConfig.retryCount++ + } + + // Send to refetch channel + if fetchConfig.retryCount < f.maxRetries { + fetchConfig.fetchTime = f.time.Now().Add(time.Duration(fetchConfig.AccountFloorFetch.Period) * time.Second).Unix() + fetchConfig.refetchRequest = true + f.configReceiver <- fetchConfig + } +} + +// Stop terminates price floor fetcher +func (f *PriceFloorFetcher) Stop() { + if f == nil { + return + } + + close(f.done) + f.pool.Stop() + close(f.configReceiver) +} + +func (f *PriceFloorFetcher) submit(fetchConfig *fetchInfo) { + status := f.pool.TrySubmit(func() { + f.worker(*fetchConfig) + }) + if !status { + heap.Push(&f.fetchQueue, fetchConfig) + } +} + +func (f *PriceFloorFetcher) Fetcher() { + //Create Ticker of 5 minutes + ticker := time.NewTicker(time.Duration(refetchCheckInterval) * time.Second) + + for { + select { + case fetchConfig := <-f.configReceiver: + if fetchConfig.refetchRequest { + heap.Push(&f.fetchQueue, &fetchConfig) + } else { + if _, ok := f.fetchInProgress[fetchConfig.URL]; !ok { + f.fetchInProgress[fetchConfig.URL] = true + f.submit(&fetchConfig) + } + } + case <-ticker.C: + currentTime := f.time.Now().Unix() + for top := f.fetchQueue.Top(); top != nil && top.fetchTime <= currentTime; top = f.fetchQueue.Top() { + nextFetch := heap.Pop(&f.fetchQueue) + f.submit(nextFetch.(*fetchInfo)) + } + case <-f.done: + ticker.Stop() + glog.Info("Price Floor fetcher terminated") + return + } + } +} + +func (f *PriceFloorFetcher) fetchAndValidate(config config.AccountFloorFetch) (*openrtb_ext.PriceFloorRules, int) { + floorResp, maxAge, err := f.fetchFloorRulesFromURL(config) + if floorResp == nil || err != nil { + glog.Errorf("Error while fetching floor data from URL: %s, reason : %s", config.URL, err.Error()) + return nil, 0 + } + + if len(floorResp) > (config.MaxFileSizeKB * 1024) { + glog.Errorf("Recieved invalid floor data from URL: %s, reason : floor file size is greater than MaxFileSize", config.URL) + return nil, 0 + } + + var priceFloors openrtb_ext.PriceFloorRules + if err = json.Unmarshal(floorResp, &priceFloors.Data); err != nil { + glog.Errorf("Recieved invalid price floor json from URL: %s", config.URL) + return nil, 0 + } + + if err := validateRules(config, &priceFloors); err != nil { + glog.Errorf("Validation failed for floor JSON from URL: %s, reason: %s", config.URL, err.Error()) + return nil, 0 + } + + return &priceFloors, maxAge +} + +// fetchFloorRulesFromURL returns a price floor JSON and time for which this JSON is valid +// from provided URL with timeout constraints +func (f *PriceFloorFetcher) fetchFloorRulesFromURL(config config.AccountFloorFetch) ([]byte, int, error) { + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(config.Timeout)*time.Millisecond) + defer cancel() + + httpReq, err := http.NewRequestWithContext(ctx, http.MethodGet, config.URL, nil) + if err != nil { + return nil, 0, errors.New("error while forming http fetch request : " + err.Error()) + } + + httpResp, err := f.httpClient.Do(httpReq) + if err != nil { + return nil, 0, errors.New("error while getting response from url : " + err.Error()) + } + + if httpResp.StatusCode != http.StatusOK { + return nil, 0, errors.New("no response from server") + } + + var maxAge int + if maxAgeStr := httpResp.Header.Get("max-age"); maxAgeStr != "" { + maxAge, err = strconv.Atoi(maxAgeStr) + if err != nil { + glog.Errorf("max-age in header is malformed for url %s", config.URL) + } + if maxAge <= config.Period || maxAge > math.MaxInt32 { + glog.Errorf("Invalid max-age = %s provided, value should be valid integer and should be within (%v, %v)", maxAgeStr, config.Period, math.MaxInt32) + } + } + + respBody, err := io.ReadAll(httpResp.Body) + if err != nil { + return nil, 0, errors.New("unable to read response") + } + defer httpResp.Body.Close() + + return respBody, maxAge, nil +} + +func validateRules(config config.AccountFloorFetch, priceFloors *openrtb_ext.PriceFloorRules) error { + if priceFloors.Data == nil { + return errors.New("empty data in floor JSON") + } + + if len(priceFloors.Data.ModelGroups) == 0 { + return errors.New("no model groups found in price floor data") + } + + if priceFloors.Data.SkipRate < 0 || priceFloors.Data.SkipRate > 100 { + return errors.New("skip rate should be greater than or equal to 0 and less than 100") + } + + for _, modelGroup := range priceFloors.Data.ModelGroups { + if len(modelGroup.Values) == 0 || len(modelGroup.Values) > config.MaxRules { + return errors.New("invalid number of floor rules, floor rules should be greater than zero and less than MaxRules specified in account config") + } + + if modelGroup.ModelWeight != nil && (*modelGroup.ModelWeight < 1 || *modelGroup.ModelWeight > 100) { + return errors.New("modelGroup[].modelWeight should be greater than or equal to 1 and less than 100") + } + + if modelGroup.SkipRate < 0 || modelGroup.SkipRate > 100 { + return errors.New("model group skip rate should be greater than or equal to 0 and less than 100") + } + + if modelGroup.Default < 0 { + return errors.New("modelGroup.Default should be greater than 0") + } + } + + return nil +} diff --git a/floors/fetcher_test.go b/floors/fetcher_test.go new file mode 100644 index 00000000000..085fd3edd1b --- /dev/null +++ b/floors/fetcher_test.go @@ -0,0 +1,1279 @@ +package floors + +import ( + "encoding/json" + "fmt" + "math/rand" + "net/http" + "net/http/httptest" + "reflect" + "testing" + "time" + + "github.com/alitto/pond" + "github.com/coocood/freecache" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/metrics" + metricsConf "github.com/prebid/prebid-server/v2/metrics/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/timeutil" + "github.com/stretchr/testify/assert" +) + +const MaxAge = "max-age" + +func TestFetchQueueLen(t *testing.T) { + tests := []struct { + name string + fq FetchQueue + want int + }{ + { + name: "Queue is empty", + fq: make(FetchQueue, 0), + want: 0, + }, + { + name: "Queue is of lenght 1", + fq: make(FetchQueue, 1), + want: 1, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.fq.Len(); got != tt.want { + t.Errorf("FetchQueue.Len() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestFetchQueueLess(t *testing.T) { + type args struct { + i int + j int + } + tests := []struct { + name string + fq FetchQueue + args args + want bool + }{ + { + name: "first fetchperiod is less than second", + fq: FetchQueue{&fetchInfo{fetchTime: 10}, &fetchInfo{fetchTime: 20}}, + args: args{i: 0, j: 1}, + want: true, + }, + { + name: "first fetchperiod is greater than second", + fq: FetchQueue{&fetchInfo{fetchTime: 30}, &fetchInfo{fetchTime: 10}}, + args: args{i: 0, j: 1}, + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.fq.Less(tt.args.i, tt.args.j); got != tt.want { + t.Errorf("FetchQueue.Less() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestFetchQueueSwap(t *testing.T) { + type args struct { + i int + j int + } + tests := []struct { + name string + fq FetchQueue + args args + }{ + { + name: "Swap two elements at index i and j", + fq: FetchQueue{&fetchInfo{fetchTime: 30}, &fetchInfo{fetchTime: 10}}, + args: args{i: 0, j: 1}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + fInfo1, fInfo2 := tt.fq[0], tt.fq[1] + tt.fq.Swap(tt.args.i, tt.args.j) + assert.Equal(t, fInfo1, tt.fq[1], "elements are not swapped") + assert.Equal(t, fInfo2, tt.fq[0], "elements are not swapped") + }) + } +} + +func TestFetchQueuePush(t *testing.T) { + type args struct { + element interface{} + } + tests := []struct { + name string + fq *FetchQueue + args args + }{ + { + name: "Push element to queue", + fq: &FetchQueue{}, + args: args{element: &fetchInfo{fetchTime: 10}}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.fq.Push(tt.args.element) + q := *tt.fq + assert.Equal(t, q[0], &fetchInfo{fetchTime: 10}) + }) + } +} + +func TestFetchQueuePop(t *testing.T) { + tests := []struct { + name string + fq *FetchQueue + want interface{} + }{ + { + name: "Pop element from queue", + fq: &FetchQueue{&fetchInfo{fetchTime: 10}}, + want: &fetchInfo{fetchTime: 10}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.fq.Pop(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("FetchQueue.Pop() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestFetchQueueTop(t *testing.T) { + tests := []struct { + name string + fq *FetchQueue + want *fetchInfo + }{ + { + name: "Get top element from queue", + fq: &FetchQueue{&fetchInfo{fetchTime: 20}}, + want: &fetchInfo{fetchTime: 20}, + }, + { + name: "Queue is empty", + fq: &FetchQueue{}, + want: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.fq.Top(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("FetchQueue.Top() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestValidatePriceFloorRules(t *testing.T) { + var zero = 0 + var one_o_one = 101 + var testURL = "abc.com" + type args struct { + configs config.AccountFloorFetch + priceFloors *openrtb_ext.PriceFloorRules + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Price floor data is empty", + args: args{ + configs: config.AccountFloorFetch{ + Enabled: true, + URL: testURL, + Timeout: 5, + MaxFileSizeKB: 20, + MaxRules: 5, + MaxAge: 20, + Period: 10, + }, + priceFloors: &openrtb_ext.PriceFloorRules{}, + }, + wantErr: true, + }, + { + name: "Model group array is empty", + args: args{ + configs: config.AccountFloorFetch{ + Enabled: true, + URL: testURL, + Timeout: 5, + MaxFileSizeKB: 20, + MaxRules: 5, + MaxAge: 20, + Period: 10, + }, + priceFloors: &openrtb_ext.PriceFloorRules{ + Data: &openrtb_ext.PriceFloorData{}, + }, + }, + wantErr: true, + }, + { + name: "floor rules is empty", + args: args{ + configs: config.AccountFloorFetch{ + Enabled: true, + URL: testURL, + Timeout: 5, + MaxFileSizeKB: 20, + MaxRules: 5, + MaxAge: 20, + Period: 10, + }, + priceFloors: &openrtb_ext.PriceFloorRules{ + Data: &openrtb_ext.PriceFloorData{ + ModelGroups: []openrtb_ext.PriceFloorModelGroup{{ + Values: map[string]float64{}, + }}, + }, + }, + }, + wantErr: true, + }, + { + name: "floor rules is grater than max floor rules", + args: args{ + configs: config.AccountFloorFetch{ + Enabled: true, + URL: testURL, + Timeout: 5, + MaxFileSizeKB: 20, + MaxRules: 0, + MaxAge: 20, + Period: 10, + }, + priceFloors: &openrtb_ext.PriceFloorRules{ + Data: &openrtb_ext.PriceFloorData{ + ModelGroups: []openrtb_ext.PriceFloorModelGroup{{ + Values: map[string]float64{ + "*|*|www.website.com": 15.01, + }, + }}, + }, + }, + }, + wantErr: true, + }, + { + name: "Modelweight is zero", + args: args{ + configs: config.AccountFloorFetch{ + Enabled: true, + URL: testURL, + Timeout: 5, + MaxFileSizeKB: 20, + MaxRules: 1, + MaxAge: 20, + Period: 10, + }, + priceFloors: &openrtb_ext.PriceFloorRules{ + Data: &openrtb_ext.PriceFloorData{ + ModelGroups: []openrtb_ext.PriceFloorModelGroup{{ + Values: map[string]float64{ + "*|*|www.website.com": 15.01, + }, + ModelWeight: &zero, + }}, + }, + }, + }, + wantErr: true, + }, + { + name: "Modelweight is 101", + args: args{ + configs: config.AccountFloorFetch{ + Enabled: true, + URL: testURL, + Timeout: 5, + MaxFileSizeKB: 20, + MaxRules: 1, + MaxAge: 20, + Period: 10, + }, + priceFloors: &openrtb_ext.PriceFloorRules{ + Data: &openrtb_ext.PriceFloorData{ + ModelGroups: []openrtb_ext.PriceFloorModelGroup{{ + Values: map[string]float64{ + "*|*|www.website.com": 15.01, + }, + ModelWeight: &one_o_one, + }}, + }, + }, + }, + wantErr: true, + }, + { + name: "skiprate is 101", + args: args{ + configs: config.AccountFloorFetch{ + Enabled: true, + URL: testURL, + Timeout: 5, + MaxFileSizeKB: 20, + MaxRules: 1, + MaxAge: 20, + Period: 10, + }, + priceFloors: &openrtb_ext.PriceFloorRules{ + Data: &openrtb_ext.PriceFloorData{ + ModelGroups: []openrtb_ext.PriceFloorModelGroup{{ + Values: map[string]float64{ + "*|*|www.website.com": 15.01, + }, + SkipRate: 101, + }}, + }, + }, + }, + wantErr: true, + }, + { + name: "Default is -1", + args: args{ + configs: config.AccountFloorFetch{ + Enabled: true, + URL: testURL, + Timeout: 5, + MaxFileSizeKB: 20, + MaxRules: 1, + MaxAge: 20, + Period: 10, + }, + priceFloors: &openrtb_ext.PriceFloorRules{ + Data: &openrtb_ext.PriceFloorData{ + ModelGroups: []openrtb_ext.PriceFloorModelGroup{{ + Values: map[string]float64{ + "*|*|www.website.com": 15.01, + }, + Default: -1, + }}, + }, + }, + }, + wantErr: true, + }, + { + name: "Invalid skip rate in data", + args: args{ + configs: config.AccountFloorFetch{ + Enabled: true, + URL: testURL, + Timeout: 5, + MaxFileSizeKB: 20, + MaxRules: 1, + MaxAge: 20, + Period: 10, + }, + priceFloors: &openrtb_ext.PriceFloorRules{ + Data: &openrtb_ext.PriceFloorData{ + SkipRate: -44, + ModelGroups: []openrtb_ext.PriceFloorModelGroup{{ + Values: map[string]float64{ + "*|*|www.website.com": 15.01, + }, + }}, + }, + }, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := validateRules(tt.args.configs, tt.args.priceFloors); (err != nil) != tt.wantErr { + t.Errorf("validatePriceFloorRules() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestFetchFloorRulesFromURL(t *testing.T) { + mockHandler := func(mockResponse []byte, mockStatus int) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.Header().Add("Content-Length", "645") + w.Header().Add(MaxAge, "20") + w.WriteHeader(mockStatus) + w.Write(mockResponse) + }) + } + + type args struct { + configs config.AccountFloorFetch + } + tests := []struct { + name string + args args + response []byte + responseStatus int + want []byte + want1 int + wantErr bool + }{ + { + name: "Floor data is successfully returned", + args: args{ + configs: config.AccountFloorFetch{ + URL: "", + Timeout: 60, + Period: 300, + }, + }, + response: func() []byte { + data := `{"data":{"currency":"USD","modelgroups":[{"modelweight":40,"modelversion":"version1","default":5,"values":{"banner|300x600|www.website.com":3,"banner|728x90|www.website.com":5,"banner|300x600|*":4,"banner|300x250|*":2,"*|*|*":16,"*|300x250|*":10,"*|300x600|*":12,"*|300x600|www.website.com":11,"banner|*|*":8,"banner|300x250|www.website.com":1,"*|728x90|www.website.com":13,"*|300x250|www.website.com":9,"*|728x90|*":14,"banner|728x90|*":6,"banner|*|www.website.com":7,"*|*|www.website.com":15},"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"}}]},"enabled":true,"floormin":1,"enforcement":{"enforcepbs":false,"floordeals":true}}` + return []byte(data) + }(), + responseStatus: 200, + want: func() []byte { + data := `{"data":{"currency":"USD","modelgroups":[{"modelweight":40,"modelversion":"version1","default":5,"values":{"banner|300x600|www.website.com":3,"banner|728x90|www.website.com":5,"banner|300x600|*":4,"banner|300x250|*":2,"*|*|*":16,"*|300x250|*":10,"*|300x600|*":12,"*|300x600|www.website.com":11,"banner|*|*":8,"banner|300x250|www.website.com":1,"*|728x90|www.website.com":13,"*|300x250|www.website.com":9,"*|728x90|*":14,"banner|728x90|*":6,"banner|*|www.website.com":7,"*|*|www.website.com":15},"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"}}]},"enabled":true,"floormin":1,"enforcement":{"enforcepbs":false,"floordeals":true}}` + return []byte(data) + }(), + want1: 20, + wantErr: false, + }, + { + name: "Time out occured", + args: args{ + configs: config.AccountFloorFetch{ + URL: "", + Timeout: 0, + Period: 300, + }, + }, + want1: 0, + responseStatus: 200, + wantErr: true, + }, + { + name: "Invalid URL", + args: args{ + configs: config.AccountFloorFetch{ + URL: "%%", + Timeout: 10, + Period: 300, + }, + }, + want1: 0, + responseStatus: 200, + wantErr: true, + }, + { + name: "No response from server", + args: args{ + configs: config.AccountFloorFetch{ + URL: "", + Timeout: 10, + Period: 300, + }, + }, + want1: 0, + responseStatus: 500, + wantErr: true, + }, + { + name: "Invalid response", + args: args{ + configs: config.AccountFloorFetch{ + URL: "", + Timeout: 10, + Period: 300, + }, + }, + want1: 0, + response: []byte("1"), + responseStatus: 200, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockHttpServer := httptest.NewServer(mockHandler(tt.response, tt.responseStatus)) + defer mockHttpServer.Close() + + if tt.args.configs.URL == "" { + tt.args.configs.URL = mockHttpServer.URL + } + pff := PriceFloorFetcher{ + httpClient: mockHttpServer.Client(), + } + got, got1, err := pff.fetchFloorRulesFromURL(tt.args.configs) + if (err != nil) != tt.wantErr { + t.Errorf("fetchFloorRulesFromURL() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("fetchFloorRulesFromURL() got = %v, want %v", got, tt.want) + } + if got1 != tt.want1 { + t.Errorf("fetchFloorRulesFromURL() got1 = %v, want %v", got1, tt.want1) + } + }) + } +} + +func TestFetchFloorRulesFromURLInvalidMaxAge(t *testing.T) { + mockHandler := func(mockResponse []byte, mockStatus int) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.Header().Add("Content-Length", "645") + w.Header().Add(MaxAge, "abc") + w.WriteHeader(mockStatus) + w.Write(mockResponse) + }) + } + + type args struct { + configs config.AccountFloorFetch + } + tests := []struct { + name string + args args + response []byte + responseStatus int + want []byte + want1 int + wantErr bool + }{ + { + name: "Floor data is successfully returned", + args: args{ + configs: config.AccountFloorFetch{ + URL: "", + Timeout: 60, + Period: 300, + }, + }, + response: func() []byte { + data := `{"data":{"currency":"USD","modelgroups":[{"modelweight":40,"modelversion":"version1","default":5,"values":{"banner|300x600|www.website.com":3,"banner|728x90|www.website.com":5,"banner|300x600|*":4,"banner|300x250|*":2,"*|*|*":16,"*|300x250|*":10,"*|300x600|*":12,"*|300x600|www.website.com":11,"banner|*|*":8,"banner|300x250|www.website.com":1,"*|728x90|www.website.com":13,"*|300x250|www.website.com":9,"*|728x90|*":14,"banner|728x90|*":6,"banner|*|www.website.com":7,"*|*|www.website.com":15},"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"}}]},"enabled":true,"floormin":1,"enforcement":{"enforcepbs":false,"floordeals":true}}` + return []byte(data) + }(), + responseStatus: 200, + want: func() []byte { + data := `{"data":{"currency":"USD","modelgroups":[{"modelweight":40,"modelversion":"version1","default":5,"values":{"banner|300x600|www.website.com":3,"banner|728x90|www.website.com":5,"banner|300x600|*":4,"banner|300x250|*":2,"*|*|*":16,"*|300x250|*":10,"*|300x600|*":12,"*|300x600|www.website.com":11,"banner|*|*":8,"banner|300x250|www.website.com":1,"*|728x90|www.website.com":13,"*|300x250|www.website.com":9,"*|728x90|*":14,"banner|728x90|*":6,"banner|*|www.website.com":7,"*|*|www.website.com":15},"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"}}]},"enabled":true,"floormin":1,"enforcement":{"enforcepbs":false,"floordeals":true}}` + return []byte(data) + }(), + want1: 0, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockHttpServer := httptest.NewServer(mockHandler(tt.response, tt.responseStatus)) + defer mockHttpServer.Close() + + if tt.args.configs.URL == "" { + tt.args.configs.URL = mockHttpServer.URL + } + + ppf := PriceFloorFetcher{ + httpClient: mockHttpServer.Client(), + } + got, got1, err := ppf.fetchFloorRulesFromURL(tt.args.configs) + if (err != nil) != tt.wantErr { + t.Errorf("fetchFloorRulesFromURL() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("fetchFloorRulesFromURL() got = %v, want %v", got, tt.want) + } + if got1 != tt.want1 { + t.Errorf("fetchFloorRulesFromURL() got1 = %v, want %v", got1, tt.want1) + } + }) + } +} + +func TestFetchAndValidate(t *testing.T) { + mockHandler := func(mockResponse []byte, mockStatus int) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.Header().Add(MaxAge, "30") + w.WriteHeader(mockStatus) + w.Write(mockResponse) + }) + } + + type args struct { + configs config.AccountFloorFetch + } + tests := []struct { + name string + args args + response []byte + responseStatus int + want *openrtb_ext.PriceFloorRules + want1 int + }{ + { + name: "Recieved valid price floor rules response", + args: args{ + configs: config.AccountFloorFetch{ + Enabled: true, + Timeout: 30, + MaxFileSizeKB: 700, + MaxRules: 30, + MaxAge: 60, + Period: 40, + }, + }, + response: func() []byte { + data := `{"currency":"USD","modelgroups":[{"modelweight":40,"modelversion":"version1","default":5,"values":{"banner|300x600|www.website.com":3,"banner|728x90|www.website.com":5,"banner|300x600|*":4,"banner|300x250|*":2,"*|*|*":16,"*|300x250|*":10,"*|300x600|*":12,"*|300x600|www.website.com":11,"banner|*|*":8,"banner|300x250|www.website.com":1,"*|728x90|www.website.com":13,"*|300x250|www.website.com":9,"*|728x90|*":14,"banner|728x90|*":6,"banner|*|www.website.com":7,"*|*|www.website.com":15},"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"}}]}` + return []byte(data) + }(), + responseStatus: 200, + want: func() *openrtb_ext.PriceFloorRules { + var res openrtb_ext.PriceFloorRules + data := `{"currency":"USD","modelgroups":[{"modelweight":40,"modelversion":"version1","default":5,"values":{"banner|300x600|www.website.com":3,"banner|728x90|www.website.com":5,"banner|300x600|*":4,"banner|300x250|*":2,"*|*|*":16,"*|300x250|*":10,"*|300x600|*":12,"*|300x600|www.website.com":11,"banner|*|*":8,"banner|300x250|www.website.com":1,"*|728x90|www.website.com":13,"*|300x250|www.website.com":9,"*|728x90|*":14,"banner|728x90|*":6,"banner|*|www.website.com":7,"*|*|www.website.com":15},"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"}}]}` + _ = json.Unmarshal([]byte(data), &res.Data) + return &res + }(), + want1: 30, + }, + { + name: "No response from server", + args: args{ + configs: config.AccountFloorFetch{ + Enabled: true, + Timeout: 30, + MaxFileSizeKB: 700, + MaxRules: 30, + MaxAge: 60, + Period: 40, + }, + }, + response: []byte{}, + responseStatus: 500, + want: nil, + want1: 0, + }, + { + name: "File is greater than MaxFileSize", + args: args{ + configs: config.AccountFloorFetch{ + Enabled: true, + Timeout: 30, + MaxFileSizeKB: 1, + MaxRules: 30, + MaxAge: 60, + Period: 40, + }, + }, + response: func() []byte { + data := `{"currency":"USD","floorProvider":"PM","floorsSchemaVersion":2,"modelGroups":[{"modelVersion":"M_0","modelWeight":1,"schema":{"fields":["domain"]},"values":{"missyusa.com":0.85,"www.missyusa.com":0.7}},{"modelVersion":"M_1","modelWeight":1,"schema":{"fields":["domain"]},"values":{"missyusa.com":1,"www.missyusa.com":1.85}},{"modelVersion":"M_2","modelWeight":5,"schema":{"fields":["domain"]},"values":{"missyusa.com":1.6,"www.missyusa.com":0.7}},{"modelVersion":"M_3","modelWeight":2,"schema":{"fields":["domain"]},"values":{"missyusa.com":1.9,"www.missyusa.com":0.75}},{"modelVersion":"M_4","modelWeight":1,"schema":{"fields":["domain"]},"values":{"www.missyusa.com":1.35,"missyusa.com":1.75}},{"modelVersion":"M_5","modelWeight":2,"schema":{"fields":["domain"]},"values":{"missyusa.com":1.4,"www.missyusa.com":0.9}},{"modelVersion":"M_6","modelWeight":43,"schema":{"fields":["domain"]},"values":{"www.missyusa.com":2,"missyusa.com":2}},{"modelVersion":"M_7","modelWeight":1,"schema":{"fields":["domain"]},"values":{"missyusa.com":1.4,"www.missyusa.com":1.85}},{"modelVersion":"M_8","modelWeight":3,"schema":{"fields":["domain"]},"values":{"www.missyusa.com":1.7,"missyusa.com":0.1}},{"modelVersion":"M_9","modelWeight":7,"schema":{"fields":["domain"]},"values":{"missyusa.com":1.9,"www.missyusa.com":1.05}},{"modelVersion":"M_10","modelWeight":9,"schema":{"fields":["domain"]},"values":{"www.missyusa.com":2,"missyusa.com":0.1}},{"modelVersion":"M_11","modelWeight":1,"schema":{"fields":["domain"]},"values":{"missyusa.com":0.45,"www.missyusa.com":1.5}},{"modelVersion":"M_12","modelWeight":8,"schema":{"fields":["domain"]},"values":{"missyusa.com":1.2,"www.missyusa.com":1.7}},{"modelVersion":"M_13","modelWeight":8,"schema":{"fields":["domain"]},"values":{"missyusa.com":0.85,"www.missyusa.com":0.75}},{"modelVersion":"M_14","modelWeight":1,"schema":{"fields":["domain"]},"values":{"missyusa.com":1.8,"www.missyusa.com":1}},{"modelVersion":"M_15","modelWeight":1,"schema":{"fields":["domain"]},"values":{"www.missyusa.com":1.2,"missyusa.com":1.75}},{"modelVersion":"M_16","modelWeight":2,"schema":{"fields":["domain"]},"values":{"missyusa.com":1,"www.missyusa.com":0.7}},{"modelVersion":"M_17","modelWeight":1,"schema":{"fields":["domain"]},"values":{"missyusa.com":0.45,"www.missyusa.com":0.35}},{"modelVersion":"M_18","modelWeight":3,"schema":{"fields":["domain"]},"values":{"missyusa.com":1.2,"www.missyusa.com":1.05}}],"skipRate":10}` + return []byte(data) + }(), + responseStatus: 200, + want: nil, + want1: 0, + }, + { + name: "Malformed response : json unmarshalling failed", + args: args{ + configs: config.AccountFloorFetch{ + Enabled: true, + Timeout: 30, + MaxFileSizeKB: 800, + MaxRules: 30, + MaxAge: 60, + Period: 40, + }, + }, + response: func() []byte { + data := `{"data":nil?}` + return []byte(data) + }(), + responseStatus: 200, + want: nil, + want1: 0, + }, + { + name: "Validations failed for price floor rules response", + args: args{ + configs: config.AccountFloorFetch{ + Enabled: true, + Timeout: 30, + MaxFileSizeKB: 700, + MaxRules: 30, + MaxAge: 60, + Period: 40, + }, + }, + response: func() []byte { + data := `{"data":{"currency":"USD","modelgroups":[]},"enabled":true,"floormin":1,"enforcement":{"enforcepbs":false,"floordeals":true}}` + return []byte(data) + }(), + responseStatus: 200, + want: nil, + want1: 0, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockHttpServer := httptest.NewServer(mockHandler(tt.response, tt.responseStatus)) + defer mockHttpServer.Close() + ppf := PriceFloorFetcher{ + httpClient: mockHttpServer.Client(), + } + tt.args.configs.URL = mockHttpServer.URL + got, got1 := ppf.fetchAndValidate(tt.args.configs) + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("fetchAndValidate() got = %v, want %v", got, tt.want) + } + if got1 != tt.want1 { + t.Errorf("fetchAndValidate() got1 = %v, want %v", got1, tt.want1) + } + }) + } +} + +func mockFetcherInstance(config config.PriceFloors, httpClient *http.Client, metricEngine metrics.MetricsEngine) *PriceFloorFetcher { + if !config.Enabled { + return nil + } + + floorFetcher := PriceFloorFetcher{ + pool: pond.New(config.Fetcher.Worker, config.Fetcher.Capacity, pond.PanicHandler(workerPanicHandler)), + fetchQueue: make(FetchQueue, 0, 100), + fetchInProgress: make(map[string]bool), + configReceiver: make(chan fetchInfo, config.Fetcher.Capacity), + done: make(chan struct{}), + cache: freecache.NewCache(config.Fetcher.CacheSize * 1024 * 1024), + httpClient: httpClient, + time: &timeutil.RealTime{}, + metricEngine: metricEngine, + maxRetries: 10, + } + + go floorFetcher.Fetcher() + + return &floorFetcher +} + +func TestFetcherWhenRequestGetSameURLInrequest(t *testing.T) { + refetchCheckInterval = 1 + response := []byte(`{"currency":"USD","modelgroups":[{"modelweight":40,"modelversion":"version1","default":5,"values":{"banner|300x600|www.website.com":3,"banner|728x90|www.website.com":5,"banner|300x600|*":4,"banner|300x250|*":2,"*|*|*":16,"*|300x250|*":10,"*|300x600|*":12,"*|300x600|www.website.com":11,"banner|*|*":8,"banner|300x250|www.website.com":1,"*|728x90|www.website.com":13,"*|300x250|www.website.com":9,"*|728x90|*":14,"banner|728x90|*":6,"banner|*|www.website.com":7,"*|*|www.website.com":15},"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"}}]}`) + mockHandler := func(mockResponse []byte, mockStatus int) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(mockStatus) + w.Write(mockResponse) + }) + } + + mockHttpServer := httptest.NewServer(mockHandler(response, 200)) + defer mockHttpServer.Close() + + floorConfig := config.PriceFloors{ + Enabled: true, + Fetcher: config.PriceFloorFetcher{ + CacheSize: 1, + Worker: 5, + Capacity: 10, + }, + } + fetcherInstance := mockFetcherInstance(floorConfig, mockHttpServer.Client(), &metricsConf.NilMetricsEngine{}) + defer fetcherInstance.Stop() + + fetchConfig := config.AccountPriceFloors{ + Enabled: true, + UseDynamicData: true, + Fetcher: config.AccountFloorFetch{ + Enabled: true, + URL: mockHttpServer.URL, + Timeout: 100, + MaxFileSizeKB: 1000, + MaxRules: 100, + MaxAge: 20, + Period: 1, + }, + } + + for i := 0; i < 50; i++ { + fetcherInstance.Fetch(fetchConfig) + } + + assert.Never(t, func() bool { return len(fetcherInstance.fetchQueue) > 1 }, time.Duration(2*time.Second), 100*time.Millisecond, "Queue Got more than one entry") + assert.Never(t, func() bool { return len(fetcherInstance.fetchInProgress) > 1 }, time.Duration(2*time.Second), 100*time.Millisecond, "Map Got more than one entry") + +} + +func TestFetcherDataPresentInCache(t *testing.T) { + floorConfig := config.PriceFloors{ + Enabled: true, + Fetcher: config.PriceFloorFetcher{ + CacheSize: 1, + Worker: 2, + Capacity: 5, + }, + } + + fetcherInstance := mockFetcherInstance(floorConfig, http.DefaultClient, &metricsConf.NilMetricsEngine{}) + defer fetcherInstance.Stop() + + fetchConfig := config.AccountPriceFloors{ + Enabled: true, + UseDynamicData: true, + Fetcher: config.AccountFloorFetch{ + Enabled: true, + URL: "http://test.com/floor", + Timeout: 100, + MaxFileSizeKB: 1000, + MaxRules: 100, + MaxAge: 20, + Period: 5, + }, + } + var res *openrtb_ext.PriceFloorRules + data := `{"data":{"currency":"USD","modelgroups":[{"modelweight":40,"modelversion":"version1","default":5,"values":{"banner|300x600|www.website.com":3,"banner|728x90|www.website.com":5,"banner|300x600|*":4,"banner|300x250|*":2,"*|*|*":16,"*|300x250|*":10,"*|300x600|*":12,"*|300x600|www.website.com":11,"banner|*|*":8,"banner|300x250|www.website.com":1,"*|728x90|www.website.com":13,"*|300x250|www.website.com":9,"*|728x90|*":14,"banner|728x90|*":6,"banner|*|www.website.com":7,"*|*|www.website.com":15},"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"}}]},"enabled":true,"floormin":1,"enforcement":{"enforcepbs":false,"floordeals":true}}` + _ = json.Unmarshal([]byte(data), &res) + fetcherInstance.SetWithExpiry("http://test.com/floor", []byte(data), fetchConfig.Fetcher.MaxAge) + + val, status := fetcherInstance.Fetch(fetchConfig) + assert.Equal(t, res, val, "Invalid value in cache or cache is empty") + assert.Equal(t, "success", status, "Floor fetch should be success") +} + +func TestFetcherDataNotPresentInCache(t *testing.T) { + floorConfig := config.PriceFloors{ + Enabled: true, + Fetcher: config.PriceFloorFetcher{ + CacheSize: 1, + Worker: 2, + Capacity: 5, + }, + } + + fetcherInstance := mockFetcherInstance(floorConfig, http.DefaultClient, &metricsConf.NilMetricsEngine{}) + defer fetcherInstance.Stop() + + fetchConfig := config.AccountPriceFloors{ + Enabled: true, + UseDynamicData: true, + Fetcher: config.AccountFloorFetch{ + Enabled: true, + URL: "http://test.com/floor", + Timeout: 100, + MaxFileSizeKB: 1000, + MaxRules: 100, + MaxAge: 20, + Period: 5, + }, + } + fetcherInstance.SetWithExpiry("http://test.com/floor", nil, fetchConfig.Fetcher.MaxAge) + + val, status := fetcherInstance.Fetch(fetchConfig) + + assert.Equal(t, (*openrtb_ext.PriceFloorRules)(nil), val, "Floor data should be nil") + assert.Equal(t, "error", status, "Floor fetch should be error") +} + +func TestFetcherEntryNotPresentInCache(t *testing.T) { + floorConfig := config.PriceFloors{ + Enabled: true, + Fetcher: config.PriceFloorFetcher{ + CacheSize: 1, + Worker: 2, + Capacity: 5, + MaxRetries: 10, + }, + } + + fetcherInstance := NewPriceFloorFetcher(floorConfig, http.DefaultClient, &metricsConf.NilMetricsEngine{}) + defer fetcherInstance.Stop() + + fetchConfig := config.AccountPriceFloors{ + Enabled: true, + UseDynamicData: true, + Fetcher: config.AccountFloorFetch{ + Enabled: true, + URL: "http://test.com/floor", + Timeout: 100, + MaxFileSizeKB: 1000, + MaxRules: 100, + MaxAge: 20, + Period: 5, + }, + } + + val, status := fetcherInstance.Fetch(fetchConfig) + + assert.Equal(t, (*openrtb_ext.PriceFloorRules)(nil), val, "Floor data should be nil") + assert.Equal(t, openrtb_ext.FetchInprogress, status, "Floor fetch should be error") +} + +func TestFetcherDynamicFetchDisable(t *testing.T) { + floorConfig := config.PriceFloors{ + Enabled: true, + Fetcher: config.PriceFloorFetcher{ + CacheSize: 1, + Worker: 2, + Capacity: 5, + MaxRetries: 5, + }, + } + + fetcherInstance := NewPriceFloorFetcher(floorConfig, http.DefaultClient, &metricsConf.NilMetricsEngine{}) + defer fetcherInstance.Stop() + + fetchConfig := config.AccountPriceFloors{ + Enabled: true, + UseDynamicData: false, + Fetcher: config.AccountFloorFetch{ + Enabled: true, + URL: "http://test.com/floor", + Timeout: 100, + MaxFileSizeKB: 1000, + MaxRules: 100, + MaxAge: 20, + Period: 5, + }, + } + + val, status := fetcherInstance.Fetch(fetchConfig) + + assert.Equal(t, (*openrtb_ext.PriceFloorRules)(nil), val, "Floor data should be nil") + assert.Equal(t, openrtb_ext.FetchNone, status, "Floor fetch should be error") +} + +func TestPriceFloorFetcherWorker(t *testing.T) { + var floorData openrtb_ext.PriceFloorData + response := []byte(`{"currency":"USD","modelgroups":[{"modelweight":40,"modelversion":"version1","default":5,"values":{"banner|300x600|www.website.com":3,"banner|728x90|www.website.com":5,"banner|300x600|*":4,"banner|300x250|*":2,"*|*|*":16,"*|300x250|*":10,"*|300x600|*":12,"*|300x600|www.website.com":11,"banner|*|*":8,"banner|300x250|www.website.com":1,"*|728x90|www.website.com":13,"*|300x250|www.website.com":9,"*|728x90|*":14,"banner|728x90|*":6,"banner|*|www.website.com":7,"*|*|www.website.com":15},"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"}}]}`) + _ = json.Unmarshal(response, &floorData) + floorResp := &openrtb_ext.PriceFloorRules{ + Data: &floorData, + } + + mockHandler := func(mockResponse []byte, mockStatus int) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.Header().Add(MaxAge, "5") + w.WriteHeader(mockStatus) + w.Write(mockResponse) + }) + } + + mockHttpServer := httptest.NewServer(mockHandler(response, 200)) + defer mockHttpServer.Close() + + fetcherInstance := PriceFloorFetcher{ + pool: nil, + fetchQueue: nil, + fetchInProgress: nil, + configReceiver: make(chan fetchInfo, 1), + done: nil, + cache: freecache.NewCache(1 * 1024 * 1024), + httpClient: mockHttpServer.Client(), + time: &timeutil.RealTime{}, + metricEngine: &metricsConf.NilMetricsEngine{}, + maxRetries: 10, + } + defer close(fetcherInstance.configReceiver) + + fetchConfig := fetchInfo{ + AccountFloorFetch: config.AccountFloorFetch{ + Enabled: true, + URL: mockHttpServer.URL, + Timeout: 100, + MaxFileSizeKB: 1000, + MaxRules: 100, + MaxAge: 20, + Period: 1, + }, + } + + fetcherInstance.worker(fetchConfig) + dataInCache, _ := fetcherInstance.Get(mockHttpServer.URL) + var gotFloorData *openrtb_ext.PriceFloorRules + json.Unmarshal(dataInCache, &gotFloorData) + assert.Equal(t, floorResp, gotFloorData, "Data should be stored in cache") + + info := <-fetcherInstance.configReceiver + assert.Equal(t, true, info.refetchRequest, "Recieved request is not refetch request") + assert.Equal(t, mockHttpServer.URL, info.AccountFloorFetch.URL, "Recieved request with different url") + +} + +func TestPriceFloorFetcherWorkerRetry(t *testing.T) { + mockHandler := func(mockResponse []byte, mockStatus int) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(mockStatus) + w.Write(mockResponse) + }) + } + + mockHttpServer := httptest.NewServer(mockHandler(nil, 500)) + defer mockHttpServer.Close() + + fetcherInstance := PriceFloorFetcher{ + pool: nil, + fetchQueue: nil, + fetchInProgress: nil, + configReceiver: make(chan fetchInfo, 1), + done: nil, + cache: nil, + httpClient: mockHttpServer.Client(), + time: &timeutil.RealTime{}, + metricEngine: &metricsConf.NilMetricsEngine{}, + maxRetries: 5, + } + defer close(fetcherInstance.configReceiver) + + fetchConfig := fetchInfo{ + AccountFloorFetch: config.AccountFloorFetch{ + Enabled: true, + URL: mockHttpServer.URL, + Timeout: 100, + MaxFileSizeKB: 1000, + MaxRules: 100, + MaxAge: 20, + Period: 1, + }, + } + + fetcherInstance.worker(fetchConfig) + + info := <-fetcherInstance.configReceiver + assert.Equal(t, 1, info.retryCount, "Retry Count is not 1") +} + +func TestPriceFloorFetcherWorkerDefaultCacheExpiry(t *testing.T) { + var floorData openrtb_ext.PriceFloorData + response := []byte(`{"currency":"USD","modelgroups":[{"modelweight":40,"modelversion":"version1","default":5,"values":{"banner|300x600|www.website.com":3,"banner|728x90|www.website.com":5,"banner|300x600|*":4,"banner|300x250|*":2,"*|*|*":16,"*|300x250|*":10,"*|300x600|*":12,"*|300x600|www.website.com":11,"banner|*|*":8,"banner|300x250|www.website.com":1,"*|728x90|www.website.com":13,"*|300x250|www.website.com":9,"*|728x90|*":14,"banner|728x90|*":6,"banner|*|www.website.com":7,"*|*|www.website.com":15},"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"}}]}`) + _ = json.Unmarshal(response, &floorData) + floorResp := &openrtb_ext.PriceFloorRules{ + Data: &floorData, + } + + mockHandler := func(mockResponse []byte, mockStatus int) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(mockStatus) + w.Write(mockResponse) + }) + } + + mockHttpServer := httptest.NewServer(mockHandler(response, 200)) + defer mockHttpServer.Close() + + fetcherInstance := &PriceFloorFetcher{ + pool: nil, + fetchQueue: nil, + fetchInProgress: nil, + configReceiver: make(chan fetchInfo, 1), + done: nil, + cache: freecache.NewCache(1 * 1024 * 1024), + httpClient: mockHttpServer.Client(), + time: &timeutil.RealTime{}, + metricEngine: &metricsConf.NilMetricsEngine{}, + maxRetries: 5, + } + + fetchConfig := fetchInfo{ + AccountFloorFetch: config.AccountFloorFetch{ + Enabled: true, + URL: mockHttpServer.URL, + Timeout: 100, + MaxFileSizeKB: 1000, + MaxRules: 100, + MaxAge: 20, + Period: 1, + }, + } + + fetcherInstance.worker(fetchConfig) + dataInCache, _ := fetcherInstance.Get(mockHttpServer.URL) + var gotFloorData *openrtb_ext.PriceFloorRules + json.Unmarshal(dataInCache, &gotFloorData) + assert.Equal(t, floorResp, gotFloorData, "Data should be stored in cache") + + info := <-fetcherInstance.configReceiver + defer close(fetcherInstance.configReceiver) + assert.Equal(t, true, info.refetchRequest, "Recieved request is not refetch request") + assert.Equal(t, mockHttpServer.URL, info.AccountFloorFetch.URL, "Recieved request with different url") + +} + +func TestPriceFloorFetcherSubmit(t *testing.T) { + response := []byte(`{"currency":"USD","modelgroups":[{"modelweight":40,"modelversion":"version1","default":5,"values":{"banner|300x600|www.website.com":3,"banner|728x90|www.website.com":5,"banner|300x600|*":4,"banner|300x250|*":2,"*|*|*":16,"*|300x250|*":10,"*|300x600|*":12,"*|300x600|www.website.com":11,"banner|*|*":8,"banner|300x250|www.website.com":1,"*|728x90|www.website.com":13,"*|300x250|www.website.com":9,"*|728x90|*":14,"banner|728x90|*":6,"banner|*|www.website.com":7,"*|*|www.website.com":15},"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"}}]}`) + mockHandler := func(mockResponse []byte, mockStatus int) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(mockStatus) + w.Write(mockResponse) + }) + } + + mockHttpServer := httptest.NewServer(mockHandler(response, 200)) + defer mockHttpServer.Close() + + fetcherInstance := &PriceFloorFetcher{ + pool: pond.New(1, 1), + fetchQueue: make(FetchQueue, 0), + fetchInProgress: nil, + configReceiver: make(chan fetchInfo, 1), + done: make(chan struct{}), + cache: freecache.NewCache(1 * 1024 * 1024), + httpClient: mockHttpServer.Client(), + time: &timeutil.RealTime{}, + metricEngine: &metricsConf.NilMetricsEngine{}, + maxRetries: 5, + } + defer fetcherInstance.Stop() + + fetchInfo := fetchInfo{ + refetchRequest: false, + fetchTime: time.Now().Unix(), + AccountFloorFetch: config.AccountFloorFetch{ + Enabled: true, + URL: mockHttpServer.URL, + Timeout: 100, + MaxFileSizeKB: 1000, + MaxRules: 100, + MaxAge: 2, + Period: 1, + }, + } + + fetcherInstance.submit(&fetchInfo) + + info := <-fetcherInstance.configReceiver + assert.Equal(t, true, info.refetchRequest, "Recieved request is not refetch request") + assert.Equal(t, mockHttpServer.URL, info.AccountFloorFetch.URL, "Recieved request with different url") + +} + +type testPool struct{} + +func (t *testPool) TrySubmit(task func()) bool { + return false +} + +func (t *testPool) Stop() {} + +func TestPriceFloorFetcherSubmitFailed(t *testing.T) { + fetcherInstance := &PriceFloorFetcher{ + pool: &testPool{}, + fetchQueue: make(FetchQueue, 0), + fetchInProgress: nil, + configReceiver: nil, + done: nil, + cache: nil, + } + defer fetcherInstance.pool.Stop() + + fetchInfo := fetchInfo{ + refetchRequest: false, + fetchTime: time.Now().Unix(), + AccountFloorFetch: config.AccountFloorFetch{ + Enabled: true, + URL: "http://test.com", + Timeout: 100, + MaxFileSizeKB: 1000, + MaxRules: 100, + MaxAge: 2, + Period: 1, + }, + } + + fetcherInstance.submit(&fetchInfo) + assert.Equal(t, 1, len(fetcherInstance.fetchQueue), "Unable to submit the task") +} + +func getRandomNumber() int { + rand.Seed(time.Now().UnixNano()) + min := 1 + max := 10 + return rand.Intn(max-min+1) + min +} + +func TestFetcherWhenRequestGetDifferentURLInrequest(t *testing.T) { + refetchCheckInterval = 1 + response := []byte(`{"currency":"USD","modelgroups":[{"modelweight":40,"modelversion":"version1","default":5,"values":{"banner|300x600|www.website.com":3,"banner|728x90|www.website.com":5,"banner|300x600|*":4,"banner|300x250|*":2,"*|*|*":16,"*|300x250|*":10,"*|300x600|*":12,"*|300x600|www.website.com":11,"banner|*|*":8,"banner|300x250|www.website.com":1,"*|728x90|www.website.com":13,"*|300x250|www.website.com":9,"*|728x90|*":14,"banner|728x90|*":6,"banner|*|www.website.com":7,"*|*|www.website.com":15},"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"}}]}`) + mockHandler := func(mockResponse []byte, mockStatus int) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(mockStatus) + w.Write(mockResponse) + }) + } + + mockHttpServer := httptest.NewServer(mockHandler(response, 200)) + defer mockHttpServer.Close() + + floorConfig := config.PriceFloors{ + Enabled: true, + Fetcher: config.PriceFloorFetcher{ + CacheSize: 1, + Worker: 5, + Capacity: 10, + MaxRetries: 5, + }, + } + fetcherInstance := mockFetcherInstance(floorConfig, mockHttpServer.Client(), &metricsConf.NilMetricsEngine{}) + defer fetcherInstance.Stop() + + fetchConfig := config.AccountPriceFloors{ + Enabled: true, + UseDynamicData: true, + Fetcher: config.AccountFloorFetch{ + Enabled: true, + URL: mockHttpServer.URL, + Timeout: 100, + MaxFileSizeKB: 1000, + MaxRules: 100, + MaxAge: 5, + Period: 1, + }, + } + + for i := 0; i < 50; i++ { + fetchConfig.Fetcher.URL = fmt.Sprintf("%s?id=%d", mockHttpServer.URL, getRandomNumber()) + fetcherInstance.Fetch(fetchConfig) + } + + assert.Never(t, func() bool { return len(fetcherInstance.fetchQueue) > 10 }, time.Duration(2*time.Second), 100*time.Millisecond, "Queue Got more than one entry") + assert.Never(t, func() bool { return len(fetcherInstance.fetchInProgress) > 10 }, time.Duration(2*time.Second), 100*time.Millisecond, "Map Got more than one entry") +} + +func TestFetchWhenPriceFloorsDisabled(t *testing.T) { + floorConfig := config.PriceFloors{ + Enabled: false, + Fetcher: config.PriceFloorFetcher{ + CacheSize: 1, + Worker: 5, + Capacity: 10, + }, + } + fetcherInstance := NewPriceFloorFetcher(floorConfig, http.DefaultClient, &metricsConf.NilMetricsEngine{}) + defer fetcherInstance.Stop() + + fetchConfig := config.AccountPriceFloors{ + Enabled: true, + UseDynamicData: true, + Fetcher: config.AccountFloorFetch{ + Enabled: true, + URL: "http://test.com/floors", + Timeout: 100, + MaxFileSizeKB: 1000, + MaxRules: 100, + MaxAge: 5, + Period: 1, + }, + } + + data, status := fetcherInstance.Fetch(fetchConfig) + + assert.Equal(t, (*openrtb_ext.PriceFloorRules)(nil), data, "floor data should be nil as fetcher instance does not created") + assert.Equal(t, openrtb_ext.FetchNone, status, "floor status should be none as fetcher instance does not created") +} diff --git a/floors/floors.go b/floors/floors.go index c1e930298ac..3fdeb4c55ae 100644 --- a/floors/floors.go +++ b/floors/floors.go @@ -4,10 +4,12 @@ import ( "errors" "math" "math/rand" + "strings" "github.com/prebid/prebid-server/v2/config" "github.com/prebid/prebid-server/v2/currency" "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/ptrutil" ) type Price struct { @@ -30,8 +32,7 @@ const ( // EnrichWithPriceFloors checks for floors enabled in account and request and selects floors data from dynamic fetched if present // else selects floors data from req.ext.prebid.floors and update request with selected floors details -func EnrichWithPriceFloors(bidRequestWrapper *openrtb_ext.RequestWrapper, account config.Account, conversions currency.Conversions) []error { - +func EnrichWithPriceFloors(bidRequestWrapper *openrtb_ext.RequestWrapper, account config.Account, conversions currency.Conversions, priceFloorFetcher FloorFetcher) []error { if bidRequestWrapper == nil || bidRequestWrapper.BidRequest == nil { return []error{errors.New("Empty bidrequest")} } @@ -40,7 +41,7 @@ func EnrichWithPriceFloors(bidRequestWrapper *openrtb_ext.RequestWrapper, accoun return []error{errors.New("Floors feature is disabled at account or in the request")} } - floors, err := resolveFloors(account, bidRequestWrapper, conversions) + floors, err := resolveFloors(account, bidRequestWrapper, conversions, priceFloorFetcher) updateReqErrs := updateBidRequestWithFloors(floors, bidRequestWrapper, conversions) updateFloorsInRequest(bidRequestWrapper, floors) @@ -136,12 +137,26 @@ func isPriceFloorsEnabledForRequest(bidRequestWrapper *openrtb_ext.RequestWrappe } // resolveFloors does selection of floors fields from request data and dynamic fetched data if dynamic fetch is enabled -func resolveFloors(account config.Account, bidRequestWrapper *openrtb_ext.RequestWrapper, conversions currency.Conversions) (*openrtb_ext.PriceFloorRules, []error) { +func resolveFloors(account config.Account, bidRequestWrapper *openrtb_ext.RequestWrapper, conversions currency.Conversions, priceFloorFetcher FloorFetcher) (*openrtb_ext.PriceFloorRules, []error) { var errList []error var floorRules *openrtb_ext.PriceFloorRules reqFloor := extractFloorsFromRequest(bidRequestWrapper) - if reqFloor != nil { + if reqFloor != nil && reqFloor.Location != nil && len(reqFloor.Location.URL) > 0 { + account.PriceFloors.Fetcher.URL = reqFloor.Location.URL + } + account.PriceFloors.Fetcher.AccountID = account.ID + + var fetchResult *openrtb_ext.PriceFloorRules + var fetchStatus string + if priceFloorFetcher != nil && account.PriceFloors.UseDynamicData { + fetchResult, fetchStatus = priceFloorFetcher.Fetch(account.PriceFloors) + } + + if fetchResult != nil && fetchStatus == openrtb_ext.FetchSuccess { + mergedFloor := mergeFloors(reqFloor, fetchResult, conversions) + floorRules, errList = createFloorsFrom(mergedFloor, account, fetchStatus, openrtb_ext.FetchLocation) + } else if reqFloor != nil { floorRules, errList = createFloorsFrom(reqFloor, account, openrtb_ext.FetchNone, openrtb_ext.RequestLocation) } else { floorRules, errList = createFloorsFrom(nil, account, openrtb_ext.FetchNone, openrtb_ext.NoDataLocation) @@ -210,3 +225,83 @@ func updateFloorsInRequest(bidRequestWrapper *openrtb_ext.RequestWrapper, priceF bidRequestWrapper.RebuildRequest() } } + +// resolveFloorMin gets floorMin value from request and dynamic fetched data +func resolveFloorMin(reqFloors *openrtb_ext.PriceFloorRules, fetchFloors *openrtb_ext.PriceFloorRules, conversions currency.Conversions) Price { + var requestFloorMinCur, providerFloorMinCur string + var requestFloorMin, providerFloorMin float64 + + if reqFloors != nil { + requestFloorMin = reqFloors.FloorMin + requestFloorMinCur = reqFloors.FloorMinCur + if len(requestFloorMinCur) == 0 && reqFloors.Data != nil { + requestFloorMinCur = reqFloors.Data.Currency + } + } + + if fetchFloors != nil { + providerFloorMin = fetchFloors.FloorMin + providerFloorMinCur = fetchFloors.FloorMinCur + if len(providerFloorMinCur) == 0 && fetchFloors.Data != nil { + providerFloorMinCur = fetchFloors.Data.Currency + } + } + + if len(requestFloorMinCur) > 0 { + if requestFloorMin > 0 { + return Price{FloorMin: requestFloorMin, FloorMinCur: requestFloorMinCur} + } + + if providerFloorMin > 0 { + if strings.Compare(providerFloorMinCur, requestFloorMinCur) == 0 || len(providerFloorMinCur) == 0 { + return Price{FloorMin: providerFloorMin, FloorMinCur: requestFloorMinCur} + } + rate, err := conversions.GetRate(providerFloorMinCur, requestFloorMinCur) + if err != nil { + return Price{FloorMin: 0, FloorMinCur: requestFloorMinCur} + } + return Price{FloorMin: roundToFourDecimals(rate * providerFloorMin), FloorMinCur: requestFloorMinCur} + } + } + + if len(providerFloorMinCur) > 0 { + if providerFloorMin > 0 { + return Price{FloorMin: providerFloorMin, FloorMinCur: providerFloorMinCur} + } + if requestFloorMin > 0 { + return Price{FloorMin: requestFloorMin, FloorMinCur: providerFloorMinCur} + } + } + + return Price{FloorMin: requestFloorMin, FloorMinCur: requestFloorMinCur} + +} + +// mergeFloors does merging for floors data from request and dynamic fetch +func mergeFloors(reqFloors *openrtb_ext.PriceFloorRules, fetchFloors *openrtb_ext.PriceFloorRules, conversions currency.Conversions) *openrtb_ext.PriceFloorRules { + mergedFloors := fetchFloors.DeepCopy() + if mergedFloors.Enabled == nil { + mergedFloors.Enabled = new(bool) + } + *mergedFloors.Enabled = fetchFloors.GetEnabled() && reqFloors.GetEnabled() + + if reqFloors == nil { + return mergedFloors + } + + if reqFloors.Enforcement != nil { + mergedFloors.Enforcement = reqFloors.Enforcement.DeepCopy() + } + + floorMinPrice := resolveFloorMin(reqFloors, fetchFloors, conversions) + if floorMinPrice.FloorMin > 0 { + mergedFloors.FloorMin = floorMinPrice.FloorMin + mergedFloors.FloorMinCur = floorMinPrice.FloorMinCur + } + + if reqFloors != nil && reqFloors.Location != nil && reqFloors.Location.URL != "" { + mergedFloors.Location = ptrutil.Clone(reqFloors.Location) + } + + return mergedFloors +} diff --git a/floors/floors_test.go b/floors/floors_test.go index 56b21a1a209..047b6738cd3 100644 --- a/floors/floors_test.go +++ b/floors/floors_test.go @@ -3,6 +3,7 @@ package floors import ( "encoding/json" "errors" + "reflect" "testing" "github.com/prebid/openrtb/v19/openrtb2" @@ -50,6 +51,14 @@ func getCurrencyRates(rates map[string]map[string]float64) currency.Conversions return currency.NewRates(rates) } +type mockPriceFloorFetcher struct{} + +func (mpf *mockPriceFloorFetcher) Fetch(configs config.AccountPriceFloors) (*openrtb_ext.PriceFloorRules, string) { + return nil, openrtb_ext.FetchNone +} + +func (mpf *mockPriceFloorFetcher) Stop() {} + func TestEnrichWithPriceFloors(t *testing.T) { rates := map[string]map[string]float64{ "USD": { @@ -365,7 +374,7 @@ func TestEnrichWithPriceFloors(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - ErrList := EnrichWithPriceFloors(tc.bidRequestWrapper, tc.account, getCurrencyRates(rates)) + ErrList := EnrichWithPriceFloors(tc.bidRequestWrapper, tc.account, getCurrencyRates(rates), &mockPriceFloorFetcher{}) if tc.bidRequestWrapper != nil { assert.Equal(t, tc.bidRequestWrapper.Imp[0].BidFloor, tc.expFloorVal, tc.name) assert.Equal(t, tc.bidRequestWrapper.Imp[0].BidFloorCur, tc.expFloorCur, tc.name) @@ -393,6 +402,51 @@ func getTrue() *bool { return &trueFlag } +func getFalse() *bool { + falseFlag := false + return &falseFlag +} + +type MockFetch struct { + FakeFetch func(configs config.AccountPriceFloors) (*openrtb_ext.PriceFloorRules, string) +} + +func (m *MockFetch) Stop() {} + +func (m *MockFetch) Fetch(configs config.AccountPriceFloors) (*openrtb_ext.PriceFloorRules, string) { + + if !configs.UseDynamicData { + return nil, openrtb_ext.FetchNone + } + priceFloors := openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + PriceFloorLocation: openrtb_ext.RequestLocation, + Enforcement: &openrtb_ext.PriceFloorEnforcement{ + EnforcePBS: getTrue(), + EnforceRate: 100, + FloorDeals: getTrue(), + }, + Data: &openrtb_ext.PriceFloorData{ + Currency: "USD", + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "Version 101", + Currency: "USD", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 15, + "*|*|*": 25, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + } + return &priceFloors, openrtb_ext.FetchSuccess +} + func TestResolveFloors(t *testing.T) { rates := map[string]map[string]float64{ "USD": { @@ -407,9 +461,149 @@ func TestResolveFloors(t *testing.T) { bidRequestWrapper *openrtb_ext.RequestWrapper account config.Account conversions currency.Conversions + fetcher FloorFetcher expErr []error expFloors *openrtb_ext.PriceFloorRules }{ + { + name: "Dynamic fetch disabled, floors from request selected", + bidRequestWrapper: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Site: &openrtb2.Site{ + Publisher: &openrtb2.Publisher{Domain: "www.website.com"}, + }, + Imp: []openrtb2.Imp{{ID: "1234", Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}}}}}, + Ext: json.RawMessage(`{"prebid":{"floors":{"data":{"currency":"USD","modelgroups":[{"modelversion":"model 1 from req","currency":"USD","values":{"banner|300x600|www.website5.com":5,"*|*|*":7},"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"}}]},"enabled":true,"enforcement":{"enforcepbs":true,"floordeals":true,"enforcerate":100}}}}`), + }, + }, + account: config.Account{ + PriceFloors: config.AccountPriceFloors{ + Enabled: true, + UseDynamicData: false, + }, + }, + fetcher: &MockFetch{}, + expFloors: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + FetchStatus: openrtb_ext.FetchNone, + PriceFloorLocation: openrtb_ext.RequestLocation, + Enforcement: &openrtb_ext.PriceFloorEnforcement{ + EnforcePBS: getTrue(), + EnforceRate: 100, + FloorDeals: getTrue(), + }, + Data: &openrtb_ext.PriceFloorData{ + Currency: "USD", + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "model 1 from req", + Currency: "USD", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 5, + "*|*|*": 7, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + }, + }, + { + name: "Dynamic fetch enabled, floors from fetched selected", + bidRequestWrapper: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Site: &openrtb2.Site{ + Publisher: &openrtb2.Publisher{Domain: "www.website.com"}, + }, + Imp: []openrtb2.Imp{{ID: "1234", Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}}}}}, + }, + }, + account: config.Account{ + PriceFloors: config.AccountPriceFloors{ + Enabled: true, + UseDynamicData: true, + }, + }, + fetcher: &MockFetch{}, + expFloors: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + FetchStatus: openrtb_ext.FetchSuccess, + PriceFloorLocation: openrtb_ext.FetchLocation, + Enforcement: &openrtb_ext.PriceFloorEnforcement{ + EnforcePBS: getTrue(), + FloorDeals: getTrue(), + EnforceRate: 100, + }, + Data: &openrtb_ext.PriceFloorData{ + Currency: "USD", + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "Version 101", + Currency: "USD", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 15, + "*|*|*": 25, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + }, + }, + { + name: "Dynamic fetch enabled, floors formed after merging", + bidRequestWrapper: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Site: &openrtb2.Site{ + Publisher: &openrtb2.Publisher{Domain: "www.website.com"}, + }, + Imp: []openrtb2.Imp{{ID: "1234", Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}}}}}, + Ext: json.RawMessage(`{"prebid":{"floors":{"floormincur":"EUR","enabled":true,"data":{"currency":"USD","modelgroups":[{"modelversion":"model 1 from req","currency":"USD","values":{"banner|300x600|www.website5.com":5,"*|*|*":7},"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"}}]},"floormin":10.11,"enforcement":{"enforcepbs":true,"floordeals":true,"enforcerate":100}}}}`), + }, + }, + account: config.Account{ + PriceFloors: config.AccountPriceFloors{ + Enabled: true, + UseDynamicData: true, + }, + }, + fetcher: &MockFetch{}, + expFloors: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + FloorMin: 10.11, + FloorMinCur: "EUR", + FetchStatus: openrtb_ext.FetchSuccess, + PriceFloorLocation: openrtb_ext.FetchLocation, + Enforcement: &openrtb_ext.PriceFloorEnforcement{ + EnforcePBS: getTrue(), + EnforceRate: 100, + FloorDeals: getTrue(), + }, + Data: &openrtb_ext.PriceFloorData{ + Currency: "USD", + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "Version 101", + Currency: "USD", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 15, + "*|*|*": 25, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + }, + }, { name: "Dynamic fetch disabled, only enforcement object present in req.ext", bidRequestWrapper: &openrtb_ext.RequestWrapper{ @@ -427,6 +621,7 @@ func TestResolveFloors(t *testing.T) { UseDynamicData: false, }, }, + fetcher: &MockFetch{}, expFloors: &openrtb_ext.PriceFloorRules{ Enforcement: &openrtb_ext.PriceFloorEnforcement{ EnforcePBS: getTrue(), @@ -437,11 +632,129 @@ func TestResolveFloors(t *testing.T) { PriceFloorLocation: openrtb_ext.RequestLocation, }, }, + { + name: "Dynamic fetch enabled, floors from fetched selected and new URL is updated", + bidRequestWrapper: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Site: &openrtb2.Site{ + Publisher: &openrtb2.Publisher{Domain: "www.website.com"}, + }, + Imp: []openrtb2.Imp{{ID: "1234", Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}}}}}, + Ext: json.RawMessage(`{"prebid":{"floors":{"floorendpoint":{"url":"http://test.com/floor"},"enabled":true}}}`), + }, + }, + account: config.Account{ + PriceFloors: config.AccountPriceFloors{ + Enabled: true, + UseDynamicData: true, + }, + }, + fetcher: &MockFetch{}, + expFloors: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + FetchStatus: openrtb_ext.FetchSuccess, + PriceFloorLocation: openrtb_ext.FetchLocation, + Enforcement: &openrtb_ext.PriceFloorEnforcement{ + EnforcePBS: getTrue(), + FloorDeals: getTrue(), + EnforceRate: 100, + }, + Location: &openrtb_ext.PriceFloorEndpoint{ + URL: "http://test.com/floor", + }, + Data: &openrtb_ext.PriceFloorData{ + Currency: "USD", + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "Version 101", + Currency: "USD", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 15, + "*|*|*": 25, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + }, + }, + { + name: "Dynamic Fetch Enabled but price floor fetcher is nil, floors from request is selected", + bidRequestWrapper: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Site: &openrtb2.Site{ + Publisher: &openrtb2.Publisher{Domain: "www.website.com"}, + }, + Imp: []openrtb2.Imp{{ID: "1234", Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}}}}}, + Ext: json.RawMessage(`{"prebid":{"floors":{"data":{"currency":"USD","modelgroups":[{"modelversion":"model 1 from req","currency":"USD","values":{"banner|300x600|www.website5.com":5,"*|*|*":7},"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"}}]},"enabled":true,"enforcement":{"enforcepbs":true,"floordeals":true,"enforcerate":100}}}}`), + }, + }, + account: config.Account{ + PriceFloors: config.AccountPriceFloors{ + Enabled: true, + UseDynamicData: true, + }, + }, + fetcher: nil, + expFloors: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + FetchStatus: openrtb_ext.FetchNone, + PriceFloorLocation: openrtb_ext.RequestLocation, + Enforcement: &openrtb_ext.PriceFloorEnforcement{ + EnforcePBS: getTrue(), + EnforceRate: 100, + FloorDeals: getTrue(), + }, + Data: &openrtb_ext.PriceFloorData{ + Currency: "USD", + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "model 1 from req", + Currency: "USD", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 5, + "*|*|*": 7, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + }, + }, + { + name: "Dynamic Fetch Enabled but price floor fetcher is nil and request has no floors", + bidRequestWrapper: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Site: &openrtb2.Site{ + Publisher: &openrtb2.Publisher{Domain: "www.website.com"}, + }, + Imp: []openrtb2.Imp{{ID: "1234", Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}}}}}, + Ext: json.RawMessage(`{"prebid":{}}`), + }, + }, + account: config.Account{ + PriceFloors: config.AccountPriceFloors{ + Enabled: true, + UseDynamicData: true, + }, + }, + fetcher: nil, + expFloors: &openrtb_ext.PriceFloorRules{ + FetchStatus: openrtb_ext.FetchNone, + PriceFloorLocation: openrtb_ext.NoDataLocation, + }, + }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - resolvedFloors, _ := resolveFloors(tc.account, tc.bidRequestWrapper, getCurrencyRates(rates)) + resolvedFloors, _ := resolveFloors(tc.account, tc.bidRequestWrapper, getCurrencyRates(rates), tc.fetcher) assert.Equal(t, resolvedFloors, tc.expFloors, tc.name) }) } @@ -738,3 +1051,605 @@ func TestIsPriceFloorsEnabled(t *testing.T) { }) } } + +func TestResolveFloorMin(t *testing.T) { + rates := map[string]map[string]float64{ + "USD": { + "INR": 70, + "EUR": 0.9, + "JPY": 5.09, + }, + } + + tt := []struct { + name string + reqFloors openrtb_ext.PriceFloorRules + fetchFloors openrtb_ext.PriceFloorRules + conversions currency.Conversions + expPrice Price + }{ + { + name: "FloorsMin present in request Floors only", + reqFloors: openrtb_ext.PriceFloorRules{ + FloorMin: 10, + FloorMinCur: "JPY", + }, + fetchFloors: openrtb_ext.PriceFloorRules{}, + expPrice: Price{FloorMin: 10, FloorMinCur: "JPY"}, + }, + { + name: "FloorsMin, FloorMinCur and data currency present in request Floors", + reqFloors: openrtb_ext.PriceFloorRules{ + FloorMin: 10, + FloorMinCur: "JPY", + Data: &openrtb_ext.PriceFloorData{ + Currency: "USD", + }, + }, + fetchFloors: openrtb_ext.PriceFloorRules{}, + expPrice: Price{FloorMin: 10, FloorMinCur: "JPY"}, + }, + { + name: "FloorsMin and data currency present in request Floors", + reqFloors: openrtb_ext.PriceFloorRules{ + FloorMin: 10, + Data: &openrtb_ext.PriceFloorData{ + Currency: "USD", + }, + }, + fetchFloors: openrtb_ext.PriceFloorRules{}, + expPrice: Price{FloorMin: 10, FloorMinCur: "USD"}, + }, + { + name: "FloorsMin and FloorMinCur present in request Floors and fetched floors", + reqFloors: openrtb_ext.PriceFloorRules{ + FloorMin: 10, + FloorMinCur: "USD", + }, + fetchFloors: openrtb_ext.PriceFloorRules{ + FloorMin: 15, + FloorMinCur: "INR", + }, + expPrice: Price{FloorMin: 10, FloorMinCur: "USD"}, + }, + { + name: "FloorsMin present fetched floors only", + reqFloors: openrtb_ext.PriceFloorRules{}, + fetchFloors: openrtb_ext.PriceFloorRules{ + FloorMin: 15, + FloorMinCur: "EUR", + }, + expPrice: Price{FloorMin: 15, FloorMinCur: "EUR"}, + }, + { + name: "FloorMinCur present in reqFloors And FloorsMin, FloorMinCur present in fetched floors (Same Currency)", + reqFloors: openrtb_ext.PriceFloorRules{ + FloorMinCur: "EUR", + }, + fetchFloors: openrtb_ext.PriceFloorRules{ + FloorMin: 15, + FloorMinCur: "EUR", + }, + expPrice: Price{FloorMin: 15, FloorMinCur: "EUR"}, + }, + { + name: "FloorMinCur present in reqFloors And FloorsMin, FloorMinCur present in fetched floors (Different Currency)", + reqFloors: openrtb_ext.PriceFloorRules{ + FloorMinCur: "USD", + }, + fetchFloors: openrtb_ext.PriceFloorRules{ + FloorMin: 15, + FloorMinCur: "EUR", + }, + expPrice: Price{FloorMin: 16.6667, FloorMinCur: "USD"}, + }, + { + name: "FloorMin present in reqFloors And FloorMinCur present in fetched floors", + reqFloors: openrtb_ext.PriceFloorRules{ + FloorMin: 11, + }, + fetchFloors: openrtb_ext.PriceFloorRules{ + FloorMinCur: "EUR", + }, + expPrice: Price{FloorMin: 11, FloorMinCur: "EUR"}, + }, + { + name: "FloorMinCur present in reqFloors And FloorMin present in fetched floors", + reqFloors: openrtb_ext.PriceFloorRules{ + FloorMinCur: "INR", + }, + fetchFloors: openrtb_ext.PriceFloorRules{ + FloorMin: 12, + }, + expPrice: Price{FloorMin: 12, FloorMinCur: "INR"}, + }, + { + name: "FloorMinCur present in reqFloors And FloorMin, data currency present in fetched floors", + reqFloors: openrtb_ext.PriceFloorRules{ + FloorMinCur: "INR", + }, + fetchFloors: openrtb_ext.PriceFloorRules{ + FloorMin: 1, + Data: &openrtb_ext.PriceFloorData{Currency: "USD"}, + }, + expPrice: Price{FloorMin: 70, FloorMinCur: "INR"}, + }, + { + name: "FloorMinCur present in fetched Floors And data currency present in reqFloors", + reqFloors: openrtb_ext.PriceFloorRules{ + FloorMin: 2, + }, + fetchFloors: openrtb_ext.PriceFloorRules{ + Data: &openrtb_ext.PriceFloorData{Currency: "USD"}, + }, + expPrice: Price{FloorMin: 2, FloorMinCur: "USD"}, + }, + { + name: "Data currency and FloorMin present in fetched floors", + reqFloors: openrtb_ext.PriceFloorRules{}, + fetchFloors: openrtb_ext.PriceFloorRules{ + FloorMin: 12, + Data: &openrtb_ext.PriceFloorData{Currency: "USD"}, + }, + expPrice: Price{FloorMin: 12, FloorMinCur: "USD"}, + }, + { + name: "Empty reqFloors And Empty fetched floors", + reqFloors: openrtb_ext.PriceFloorRules{}, + fetchFloors: openrtb_ext.PriceFloorRules{}, + expPrice: Price{FloorMin: 0.0, FloorMinCur: ""}, + }, + } + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + price := resolveFloorMin(&tc.reqFloors, &tc.fetchFloors, getCurrencyRates(rates)) + if !reflect.DeepEqual(price.FloorMin, tc.expPrice.FloorMin) { + t.Errorf("Floor Value error: \nreturn:\t%v\nwant:\t%v", price.FloorMin, tc.expPrice.FloorMin) + } + if !reflect.DeepEqual(price.FloorMinCur, tc.expPrice.FloorMinCur) { + t.Errorf("Floor Currency error: \nreturn:\t%v\nwant:\t%v", price.FloorMinCur, tc.expPrice.FloorMinCur) + } + + }) + } +} + +func TestMergeFloors(t *testing.T) { + + rates := map[string]map[string]float64{ + "USD": { + "INR": 70, + "EUR": 0.9, + "JPY": 5.09, + }, + } + + type args struct { + reqFloors *openrtb_ext.PriceFloorRules + fetchFloors *openrtb_ext.PriceFloorRules + } + tests := []struct { + name string + args args + want *openrtb_ext.PriceFloorRules + }{ + { + name: "Fetched Floors are present and request Floors are empty", + args: args{ + reqFloors: nil, + fetchFloors: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + Data: &openrtb_ext.PriceFloorData{ + Currency: "INR", + SkipRate: 0, + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "Version 1", + Currency: "INR", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 20, + "*|*|*": 50, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + }, + }, + want: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + Data: &openrtb_ext.PriceFloorData{ + Currency: "INR", + SkipRate: 0, + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "Version 1", + Currency: "INR", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 20, + "*|*|*": 50, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + }, + }, + { + name: "Fetched Floors are present and request Floors has floors disabled", + args: args{ + reqFloors: &openrtb_ext.PriceFloorRules{ + Enabled: getFalse(), + }, + fetchFloors: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + Data: &openrtb_ext.PriceFloorData{ + Currency: "INR", + SkipRate: 0, + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "Version 1", + Currency: "INR", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 20, + "*|*|*": 50, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + }, + }, + want: &openrtb_ext.PriceFloorRules{ + Enabled: getFalse(), + Data: &openrtb_ext.PriceFloorData{ + Currency: "INR", + SkipRate: 0, + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "Version 1", + Currency: "INR", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 20, + "*|*|*": 50, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + }, + }, + { + name: "Fetched Floors are present and request Floors has enforcement (enforcepbs = true)", + args: args{ + reqFloors: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + Enforcement: &openrtb_ext.PriceFloorEnforcement{ + EnforceRate: 50, + EnforcePBS: getTrue(), + }, + }, + fetchFloors: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + Data: &openrtb_ext.PriceFloorData{ + Currency: "INR", + SkipRate: 0, + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "Version 1", + Currency: "INR", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 20, + "*|*|*": 50, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + }, + }, + want: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + Data: &openrtb_ext.PriceFloorData{ + Currency: "INR", + SkipRate: 0, + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "Version 1", + Currency: "INR", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 20, + "*|*|*": 50, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + Enforcement: &openrtb_ext.PriceFloorEnforcement{ + EnforceRate: 50, + EnforcePBS: getTrue(), + }, + }, + }, + { + name: "Fetched Floors are present and request Floors has enforcement (enforcepbs = false)", + args: args{ + reqFloors: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + Enforcement: &openrtb_ext.PriceFloorEnforcement{ + EnforceRate: 50, + EnforcePBS: getFalse(), + }, + }, + fetchFloors: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + Data: &openrtb_ext.PriceFloorData{ + Currency: "INR", + SkipRate: 0, + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "Version 1", + Currency: "INR", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 20, + "*|*|*": 50, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + }, + }, + want: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + Data: &openrtb_ext.PriceFloorData{ + Currency: "INR", + SkipRate: 0, + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "Version 1", + Currency: "INR", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 20, + "*|*|*": 50, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + Enforcement: &openrtb_ext.PriceFloorEnforcement{ + EnforceRate: 50, + EnforcePBS: getFalse(), + }, + }, + }, + { + name: "Fetched Floors are present and request Floors has Floormin", + args: args{ + reqFloors: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + Enforcement: &openrtb_ext.PriceFloorEnforcement{ + EnforceRate: 50, + EnforcePBS: getFalse(), + }, + FloorMin: 5, + FloorMinCur: "INR", + }, + fetchFloors: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + Data: &openrtb_ext.PriceFloorData{ + Currency: "INR", + SkipRate: 0, + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "Version 1", + Currency: "INR", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 20, + "*|*|*": 50, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + }, + }, + want: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + Data: &openrtb_ext.PriceFloorData{ + Currency: "INR", + SkipRate: 0, + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "Version 1", + Currency: "INR", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 20, + "*|*|*": 50, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + Enforcement: &openrtb_ext.PriceFloorEnforcement{ + EnforceRate: 50, + EnforcePBS: getFalse(), + }, + FloorMin: 5, + FloorMinCur: "INR", + }, + }, + { + name: "Fetched Floors are present and request Floors has URL", + args: args{ + reqFloors: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + Enforcement: &openrtb_ext.PriceFloorEnforcement{ + EnforceRate: 50, + EnforcePBS: getFalse(), + }, + FloorMin: 5, + FloorMinCur: "INR", + Location: &openrtb_ext.PriceFloorEndpoint{ + URL: "https://test.com/floors", + }, + }, + fetchFloors: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + Data: &openrtb_ext.PriceFloorData{ + Currency: "INR", + SkipRate: 0, + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "Version 1", + Currency: "INR", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 20, + "*|*|*": 50, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + }, + }, + want: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + Data: &openrtb_ext.PriceFloorData{ + Currency: "INR", + SkipRate: 0, + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "Version 1", + Currency: "INR", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 20, + "*|*|*": 50, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + Enforcement: &openrtb_ext.PriceFloorEnforcement{ + EnforceRate: 50, + EnforcePBS: getFalse(), + }, + FloorMin: 5, + FloorMinCur: "INR", + Location: &openrtb_ext.PriceFloorEndpoint{ + URL: "https://test.com/floors", + }, + }, + }, + { + name: "Fetched Floors has no enable atrribute are present and request Floors has URL", + args: args{ + reqFloors: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + Enforcement: &openrtb_ext.PriceFloorEnforcement{ + EnforceRate: 50, + EnforcePBS: getFalse(), + }, + FloorMin: 5, + FloorMinCur: "INR", + Location: &openrtb_ext.PriceFloorEndpoint{ + URL: "https://test.com/floors", + }, + }, + fetchFloors: &openrtb_ext.PriceFloorRules{ + Data: &openrtb_ext.PriceFloorData{ + Currency: "INR", + SkipRate: 0, + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "Version 1", + Currency: "INR", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 20, + "*|*|*": 50, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + }, + }, + want: &openrtb_ext.PriceFloorRules{ + Enabled: getTrue(), + Data: &openrtb_ext.PriceFloorData{ + Currency: "INR", + SkipRate: 0, + ModelGroups: []openrtb_ext.PriceFloorModelGroup{ + { + ModelVersion: "Version 1", + Currency: "INR", + Values: map[string]float64{ + "banner|300x600|www.website5.com": 20, + "*|*|*": 50, + }, + Schema: openrtb_ext.PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + Enforcement: &openrtb_ext.PriceFloorEnforcement{ + EnforceRate: 50, + EnforcePBS: getFalse(), + }, + FloorMin: 5, + FloorMinCur: "INR", + Location: &openrtb_ext.PriceFloorEndpoint{ + URL: "https://test.com/floors", + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := mergeFloors(tt.args.reqFloors, tt.args.fetchFloors, getCurrencyRates(rates)); !reflect.DeepEqual(got, tt.want) { + t.Errorf("mergeFloors() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/floors/rule.go b/floors/rule.go index db12719c337..50c12462d28 100644 --- a/floors/rule.go +++ b/floors/rule.go @@ -38,8 +38,7 @@ const ( // getFloorCurrency returns floors currency provided in floors JSON, // if currency is not provided then defaults to USD func getFloorCurrency(floorExt *openrtb_ext.PriceFloorRules) string { - var floorCur string - + floorCur := defaultCurrency if floorExt != nil && floorExt.Data != nil { if floorExt.Data.Currency != "" { floorCur = floorExt.Data.Currency @@ -50,10 +49,6 @@ func getFloorCurrency(floorExt *openrtb_ext.PriceFloorRules) string { } } - if len(floorCur) == 0 { - floorCur = defaultCurrency - } - return floorCur } diff --git a/go.mod b/go.mod index d152a3b6614..ac394a6742c 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/DATA-DOG/go-sqlmock v1.5.0 github.com/IABTechLab/adscert v0.34.0 github.com/NYTimes/gziphandler v1.1.1 + github.com/alitto/pond v1.8.3 github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d github.com/benbjohnson/clock v1.3.0 github.com/buger/jsonparser v1.1.1 diff --git a/go.sum b/go.sum index d05f428cef5..6331beb3287 100644 --- a/go.sum +++ b/go.sum @@ -64,6 +64,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alitto/pond v1.8.3 h1:ydIqygCLVPqIX/USe5EaV/aSRXTRXDEI9JwuDdu+/xs= +github.com/alitto/pond v1.8.3/go.mod h1:CmvIIGd5jKLasGI3D87qDkQxjzChdKMmnXMg3fG6M6Q= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= diff --git a/openrtb_ext/floors.go b/openrtb_ext/floors.go index 3553946cc2e..0e773c65899 100644 --- a/openrtb_ext/floors.go +++ b/openrtb_ext/floors.go @@ -1,5 +1,11 @@ package openrtb_ext +import ( + "github.com/prebid/prebid-server/v2/util/maputil" + "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v2/util/sliceutil" +) + // Defines strings for FetchStatus const ( FetchSuccess = "success" @@ -145,3 +151,59 @@ type ExtImp struct { type ImpExtPrebid struct { Floors Price `json:"floors,omitempty"` } + +func (pf *PriceFloorRules) DeepCopy() *PriceFloorRules { + if pf == nil { + return nil + } + + newRules := *pf + newRules.Enabled = ptrutil.Clone(pf.Enabled) + newRules.Skipped = ptrutil.Clone(pf.Skipped) + newRules.Location = ptrutil.Clone(pf.Location) + newRules.Data = pf.Data.DeepCopy() + newRules.Enforcement = pf.Enforcement.DeepCopy() + + return &newRules +} + +func (data *PriceFloorData) DeepCopy() *PriceFloorData { + if data == nil { + return nil + } + + newData := *data + newModelGroups := make([]PriceFloorModelGroup, len(data.ModelGroups)) + + for i := range data.ModelGroups { + var eachGroup PriceFloorModelGroup + eachGroup.Currency = data.ModelGroups[i].Currency + eachGroup.ModelWeight = ptrutil.Clone(data.ModelGroups[i].ModelWeight) + eachGroup.ModelVersion = data.ModelGroups[i].ModelVersion + eachGroup.SkipRate = data.ModelGroups[i].SkipRate + eachGroup.Values = maputil.Clone(data.ModelGroups[i].Values) + eachGroup.Default = data.ModelGroups[i].Default + eachGroup.Schema = PriceFloorSchema{ + Fields: sliceutil.Clone(data.ModelGroups[i].Schema.Fields), + Delimiter: data.ModelGroups[i].Schema.Delimiter, + } + newModelGroups[i] = eachGroup + } + newData.ModelGroups = newModelGroups + + return &newData +} + +func (enforcement *PriceFloorEnforcement) DeepCopy() *PriceFloorEnforcement { + if enforcement == nil { + return nil + } + + newEnforcement := *enforcement + newEnforcement.EnforceJS = ptrutil.Clone(enforcement.EnforceJS) + newEnforcement.EnforcePBS = ptrutil.Clone(enforcement.EnforcePBS) + newEnforcement.FloorDeals = ptrutil.Clone(enforcement.FloorDeals) + newEnforcement.BidAdjustment = ptrutil.Clone(enforcement.BidAdjustment) + + return &newEnforcement +} diff --git a/openrtb_ext/floors_test.go b/openrtb_ext/floors_test.go index 20247736768..d6c35b9f7ef 100644 --- a/openrtb_ext/floors_test.go +++ b/openrtb_ext/floors_test.go @@ -1,8 +1,10 @@ package openrtb_ext import ( + "reflect" "testing" + "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/stretchr/testify/assert" ) @@ -218,3 +220,263 @@ func TestPriceFloorRulesGetEnabled(t *testing.T) { }) } } + +func TestPriceFloorRulesDeepCopy(t *testing.T) { + type fields struct { + FloorMin float64 + FloorMinCur string + SkipRate int + Location *PriceFloorEndpoint + Data *PriceFloorData + Enforcement *PriceFloorEnforcement + Enabled *bool + Skipped *bool + FloorProvider string + FetchStatus string + PriceFloorLocation string + } + tests := []struct { + name string + fields fields + }{ + { + name: "DeepCopy does not share same reference", + fields: fields{ + FloorMin: 10, + FloorMinCur: "INR", + SkipRate: 0, + Location: &PriceFloorEndpoint{ + URL: "https://test/floors", + }, + Data: &PriceFloorData{ + Currency: "INR", + SkipRate: 0, + ModelGroups: []PriceFloorModelGroup{ + { + Currency: "INR", + ModelWeight: ptrutil.ToPtr(1), + SkipRate: 0, + Values: map[string]float64{ + "banner|300x600|www.website5.com": 20, + "*|*|*": 50, + }, + Schema: PriceFloorSchema{ + Fields: []string{"mediaType", "size", "domain"}, + Delimiter: "|", + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pf := &PriceFloorRules{ + FloorMin: tt.fields.FloorMin, + FloorMinCur: tt.fields.FloorMinCur, + SkipRate: tt.fields.SkipRate, + Location: tt.fields.Location, + Data: tt.fields.Data, + Enforcement: tt.fields.Enforcement, + Enabled: tt.fields.Enabled, + Skipped: tt.fields.Skipped, + FloorProvider: tt.fields.FloorProvider, + FetchStatus: tt.fields.FetchStatus, + PriceFloorLocation: tt.fields.PriceFloorLocation, + } + got := pf.DeepCopy() + if got == pf { + t.Errorf("Rules reference are same") + } + if got.Data == pf.Data { + t.Errorf("Floor data reference is same") + } + }) + } +} + +func TestFloorRulesDeepCopy(t *testing.T) { + type fields struct { + FloorMin float64 + FloorMinCur string + SkipRate int + Location *PriceFloorEndpoint + Data *PriceFloorData + Enforcement *PriceFloorEnforcement + Enabled *bool + Skipped *bool + FloorProvider string + FetchStatus string + PriceFloorLocation string + } + tests := []struct { + name string + fields fields + want *PriceFloorRules + }{ + { + name: "Copy entire floors object", + fields: fields{ + FloorMin: 10, + FloorMinCur: "INR", + SkipRate: 0, + Location: &PriceFloorEndpoint{ + URL: "http://prebid.com/floor", + }, + Data: &PriceFloorData{ + Currency: "INR", + SkipRate: 0, + FloorsSchemaVersion: "2", + ModelTimestamp: 123, + ModelGroups: []PriceFloorModelGroup{ + { + Currency: "INR", + ModelWeight: ptrutil.ToPtr(50), + ModelVersion: "version 1", + SkipRate: 0, + Schema: PriceFloorSchema{ + Fields: []string{"a", "b", "c"}, + Delimiter: "|", + }, + Values: map[string]float64{ + "*|*|*": 20, + }, + Default: 1, + }, + }, + FloorProvider: "prebid", + }, + Enforcement: &PriceFloorEnforcement{ + EnforceJS: ptrutil.ToPtr(true), + EnforcePBS: ptrutil.ToPtr(true), + FloorDeals: ptrutil.ToPtr(true), + BidAdjustment: ptrutil.ToPtr(true), + EnforceRate: 100, + }, + Enabled: ptrutil.ToPtr(true), + Skipped: ptrutil.ToPtr(false), + FloorProvider: "Prebid", + FetchStatus: "success", + PriceFloorLocation: "fetch", + }, + want: &PriceFloorRules{ + FloorMin: 10, + FloorMinCur: "INR", + SkipRate: 0, + Location: &PriceFloorEndpoint{ + URL: "http://prebid.com/floor", + }, + Data: &PriceFloorData{ + Currency: "INR", + SkipRate: 0, + FloorsSchemaVersion: "2", + ModelTimestamp: 123, + ModelGroups: []PriceFloorModelGroup{ + { + Currency: "INR", + ModelWeight: ptrutil.ToPtr(50), + ModelVersion: "version 1", + SkipRate: 0, + Schema: PriceFloorSchema{ + Fields: []string{"a", "b", "c"}, + Delimiter: "|", + }, + Values: map[string]float64{ + "*|*|*": 20, + }, + Default: 1, + }, + }, + FloorProvider: "prebid", + }, + Enforcement: &PriceFloorEnforcement{ + EnforceJS: ptrutil.ToPtr(true), + EnforcePBS: ptrutil.ToPtr(true), + FloorDeals: ptrutil.ToPtr(true), + BidAdjustment: ptrutil.ToPtr(true), + EnforceRate: 100, + }, + Enabled: ptrutil.ToPtr(true), + Skipped: ptrutil.ToPtr(false), + FloorProvider: "Prebid", + FetchStatus: "success", + PriceFloorLocation: "fetch", + }, + }, + { + name: "Copy entire floors object", + fields: fields{ + FloorMin: 10, + FloorMinCur: "INR", + SkipRate: 0, + Location: &PriceFloorEndpoint{ + URL: "http://prebid.com/floor", + }, + Data: nil, + Enforcement: &PriceFloorEnforcement{ + EnforceJS: ptrutil.ToPtr(true), + EnforcePBS: ptrutil.ToPtr(true), + FloorDeals: ptrutil.ToPtr(true), + BidAdjustment: ptrutil.ToPtr(true), + EnforceRate: 100, + }, + Enabled: ptrutil.ToPtr(true), + Skipped: ptrutil.ToPtr(false), + FloorProvider: "Prebid", + FetchStatus: "success", + PriceFloorLocation: "fetch", + }, + want: &PriceFloorRules{ + FloorMin: 10, + FloorMinCur: "INR", + SkipRate: 0, + Location: &PriceFloorEndpoint{ + URL: "http://prebid.com/floor", + }, + Data: nil, + Enforcement: &PriceFloorEnforcement{ + EnforceJS: ptrutil.ToPtr(true), + EnforcePBS: ptrutil.ToPtr(true), + FloorDeals: ptrutil.ToPtr(true), + BidAdjustment: ptrutil.ToPtr(true), + EnforceRate: 100, + }, + Enabled: ptrutil.ToPtr(true), + Skipped: ptrutil.ToPtr(false), + FloorProvider: "Prebid", + FetchStatus: "success", + PriceFloorLocation: "fetch", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pf := &PriceFloorRules{ + FloorMin: tt.fields.FloorMin, + FloorMinCur: tt.fields.FloorMinCur, + SkipRate: tt.fields.SkipRate, + Location: tt.fields.Location, + Data: tt.fields.Data, + Enforcement: tt.fields.Enforcement, + Enabled: tt.fields.Enabled, + Skipped: tt.fields.Skipped, + FloorProvider: tt.fields.FloorProvider, + FetchStatus: tt.fields.FetchStatus, + PriceFloorLocation: tt.fields.PriceFloorLocation, + } + if got := pf.DeepCopy(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("PriceFloorRules.DeepCopy() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestFloorRuleDeepCopyNil(t *testing.T) { + var priceFloorRule *PriceFloorRules + got := priceFloorRule.DeepCopy() + + if got != nil { + t.Errorf("PriceFloorRules.DeepCopy() = %v, want %v", got, nil) + } +} diff --git a/router/router.go b/router/router.go index 80d972a9f5b..99fe2e5da9e 100644 --- a/router/router.go +++ b/router/router.go @@ -20,6 +20,7 @@ import ( "github.com/prebid/prebid-server/v2/errortypes" "github.com/prebid/prebid-server/v2/exchange" "github.com/prebid/prebid-server/v2/experiment/adscert" + "github.com/prebid/prebid-server/v2/floors" "github.com/prebid/prebid-server/v2/gdpr" "github.com/prebid/prebid-server/v2/hooks" "github.com/prebid/prebid-server/v2/macros" @@ -162,6 +163,16 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R }, } + floorFechterHttpClient := &http.Client{ + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, + MaxConnsPerHost: cfg.PriceFloors.Fetcher.HttpClient.MaxConnsPerHost, + MaxIdleConns: cfg.PriceFloors.Fetcher.HttpClient.MaxIdleConns, + MaxIdleConnsPerHost: cfg.PriceFloors.Fetcher.HttpClient.MaxIdleConnsPerHost, + IdleConnTimeout: time.Duration(cfg.PriceFloors.Fetcher.HttpClient.IdleConnTimeout) * time.Second, + }, + } + if err := checkSupportedUserSyncEndpoints(cfg.BidderInfos); err != nil { return nil, err } @@ -224,10 +235,12 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R glog.Fatalf("Failed to create ads cert signer: %v", err) } + priceFloorFetcher := floors.NewPriceFloorFetcher(cfg.PriceFloors, floorFechterHttpClient, r.MetricsEngine) + tmaxAdjustments := exchange.ProcessTMaxAdjustments(cfg.TmaxAdjustments) planBuilder := hooks.NewExecutionPlanBuilder(cfg.Hooks, repo) macroReplacer := macros.NewStringIndexBasedReplacer() - theExchange := exchange.NewExchange(adapters, cacheClient, cfg, syncersByBidder, r.MetricsEngine, cfg.BidderInfos, gdprPermsBuilder, rateConvertor, categoriesFetcher, adsCertSigner, macroReplacer) + theExchange := exchange.NewExchange(adapters, cacheClient, cfg, syncersByBidder, r.MetricsEngine, cfg.BidderInfos, gdprPermsBuilder, rateConvertor, categoriesFetcher, adsCertSigner, macroReplacer, priceFloorFetcher) var uuidGenerator uuidutil.UUIDRandomGenerator openrtbEndpoint, err := openrtb2.NewEndpoint(uuidGenerator, theExchange, paramsValidator, fetcher, accounts, cfg, r.MetricsEngine, analyticsRunner, disabledBidders, defReqJSON, activeBidders, storedRespFetcher, planBuilder, tmaxAdjustments) if err != nil { From f9f5546542aa76672156d9220100e18dfc6996e0 Mon Sep 17 00:00:00 2001 From: Veronika Solovei Date: Thu, 16 Nov 2023 09:20:00 -0800 Subject: [PATCH 210/268] Modularity: Make request wrapper accessible in bidder request hook (#3096) --- exchange/bidder.go | 7 ++++++- exchange/exchange_test.go | 4 ++-- hooks/hookexecution/executor.go | 10 +++++----- hooks/hookexecution/executor_test.go | 4 ++-- hooks/hookexecution/mocks_test.go | 14 ++++++------- hooks/hookstage/bidderrequest.go | 7 +++---- hooks/hookstage/bidderrequest_mutations.go | 10 +++++----- hooks/hookstage/processedauctionrequest.go | 2 +- .../ortb2blocking/hook_bidderrequest.go | 20 +++++++++---------- modules/prebid/ortb2blocking/module_test.go | 9 ++++++--- 10 files changed, 47 insertions(+), 40 deletions(-) diff --git a/exchange/bidder.go b/exchange/bidder.go index 610122fbbf2..3cc55acb408 100644 --- a/exchange/bidder.go +++ b/exchange/bidder.go @@ -131,7 +131,8 @@ type bidderAdapterConfig struct { } func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes, hookExecutor hookexecution.StageExecutor, ruleToAdjustments openrtb_ext.AdjustmentsByDealID) ([]*entities.PbsOrtbSeatBid, extraBidderRespInfo, []error) { - reject := hookExecutor.ExecuteBidderRequestStage(bidderRequest.BidRequest, string(bidderRequest.BidderName)) + request := openrtb_ext.RequestWrapper{BidRequest: bidderRequest.BidRequest} + reject := hookExecutor.ExecuteBidderRequestStage(&request, string(bidderRequest.BidderName)) if reject != nil { return nil, extraBidderRespInfo{}, []error{reject} } @@ -143,6 +144,10 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest Bidde extraRespInfo extraBidderRespInfo ) + // rebuild request after modules execution + request.RebuildRequest() + bidderRequest.BidRequest = request.BidRequest + //check if real request exists for this bidder or it only has stored responses dataLen := 0 if len(bidderRequest.BidRequest.Imp) > 0 { diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go index a537054cbce..25925e83566 100644 --- a/exchange/exchange_test.go +++ b/exchange/exchange_test.go @@ -5630,12 +5630,12 @@ func (e mockUpdateBidRequestHook) HandleBidderRequestHook(_ context.Context, mct c := hookstage.ChangeSet[hookstage.BidderRequestPayload]{} c.AddMutation( func(payload hookstage.BidderRequestPayload) (hookstage.BidderRequestPayload, error) { - payload.BidRequest.Site.Name = "test" + payload.Request.Site.Name = "test" return payload, nil }, hookstage.MutationUpdate, "bidRequest", "site.name", ).AddMutation( func(payload hookstage.BidderRequestPayload) (hookstage.BidderRequestPayload, error) { - payload.BidRequest.Site.Domain = "test.com" + payload.Request.Site.Domain = "test.com" return payload, nil }, hookstage.MutationUpdate, "bidRequest", "site.domain", ) diff --git a/hooks/hookexecution/executor.go b/hooks/hookexecution/executor.go index dd6953fb73c..f820b79fdb2 100644 --- a/hooks/hookexecution/executor.go +++ b/hooks/hookexecution/executor.go @@ -34,7 +34,7 @@ type StageExecutor interface { ExecuteEntrypointStage(req *http.Request, body []byte) ([]byte, *RejectError) ExecuteRawAuctionStage(body []byte) ([]byte, *RejectError) ExecuteProcessedAuctionStage(req *openrtb_ext.RequestWrapper) error - ExecuteBidderRequestStage(req *openrtb2.BidRequest, bidder string) *RejectError + ExecuteBidderRequestStage(req *openrtb_ext.RequestWrapper, bidder string) *RejectError ExecuteRawBidderResponseStage(response *adapters.BidderResponse, bidder string) *RejectError ExecuteAllProcessedBidResponsesStage(adapterBids map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid) ExecuteAuctionResponseStage(response *openrtb2.BidResponse) @@ -160,7 +160,7 @@ func (e *hookExecutor) ExecuteProcessedAuctionStage(request *openrtb_ext.Request stageName := hooks.StageProcessedAuctionRequest.String() executionCtx := e.newContext(stageName) - payload := hookstage.ProcessedAuctionRequestPayload{RequestWrapper: request} + payload := hookstage.ProcessedAuctionRequestPayload{Request: request} outcome, _, contexts, reject := executeStage(executionCtx, plan, payload, handler, e.metricEngine) outcome.Entity = entityAuctionRequest @@ -177,7 +177,7 @@ func (e *hookExecutor) ExecuteProcessedAuctionStage(request *openrtb_ext.Request return reject } -func (e *hookExecutor) ExecuteBidderRequestStage(req *openrtb2.BidRequest, bidder string) *RejectError { +func (e *hookExecutor) ExecuteBidderRequestStage(req *openrtb_ext.RequestWrapper, bidder string) *RejectError { plan := e.planBuilder.PlanForBidderRequestStage(e.endpoint, e.account) if len(plan) == 0 { return nil @@ -194,7 +194,7 @@ func (e *hookExecutor) ExecuteBidderRequestStage(req *openrtb2.BidRequest, bidde stageName := hooks.StageBidderRequest.String() executionCtx := e.newContext(stageName) - payload := hookstage.BidderRequestPayload{BidRequest: req, Bidder: bidder} + payload := hookstage.BidderRequestPayload{Request: req, Bidder: bidder} outcome, payload, contexts, reject := executeStage(executionCtx, plan, payload, handler, e.metricEngine) outcome.Entity = entity(bidder) outcome.Stage = stageName @@ -332,7 +332,7 @@ func (executor EmptyHookExecutor) ExecuteProcessedAuctionStage(_ *openrtb_ext.Re return nil } -func (executor EmptyHookExecutor) ExecuteBidderRequestStage(_ *openrtb2.BidRequest, bidder string) *RejectError { +func (executor EmptyHookExecutor) ExecuteBidderRequestStage(_ *openrtb_ext.RequestWrapper, bidder string) *RejectError { return nil } diff --git a/hooks/hookexecution/executor_test.go b/hooks/hookexecution/executor_test.go index 6f50e089b40..90fa09e394f 100644 --- a/hooks/hookexecution/executor_test.go +++ b/hooks/hookexecution/executor_test.go @@ -37,7 +37,7 @@ func TestEmptyHookExecutor(t *testing.T) { entrypointBody, entrypointRejectErr := executor.ExecuteEntrypointStage(req, body) rawAuctionBody, rawAuctionRejectErr := executor.ExecuteRawAuctionStage(body) processedAuctionRejectErr := executor.ExecuteProcessedAuctionStage(&openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{}}) - bidderRequestRejectErr := executor.ExecuteBidderRequestStage(bidderRequest, "bidder-name") + bidderRequestRejectErr := executor.ExecuteBidderRequestStage(&openrtb_ext.RequestWrapper{BidRequest: bidderRequest}, "bidder-name") executor.ExecuteAuctionResponseStage(&openrtb2.BidResponse{}) outcomes := executor.GetOutcomes() @@ -1171,7 +1171,7 @@ func TestExecuteBidderRequestStage(t *testing.T) { exec := NewHookExecutor(test.givenPlanBuilder, EndpointAuction, &metricsConfig.NilMetricsEngine{}) exec.SetAccount(test.givenAccount) - reject := exec.ExecuteBidderRequestStage(test.givenBidderRequest, bidderName) + reject := exec.ExecuteBidderRequestStage(&openrtb_ext.RequestWrapper{BidRequest: test.givenBidderRequest}, bidderName) assert.Equal(t, test.expectedReject, reject, "Unexpected stage reject.") assert.Equal(t, test.expectedBidderRequest, test.givenBidderRequest, "Incorrect bidder request.") diff --git a/hooks/hookexecution/mocks_test.go b/hooks/hookexecution/mocks_test.go index 420a44e8fe9..c47e2892cc0 100644 --- a/hooks/hookexecution/mocks_test.go +++ b/hooks/hookexecution/mocks_test.go @@ -131,7 +131,7 @@ func (e mockTimeoutHook) HandleProcessedAuctionHook(_ context.Context, _ hooksta time.Sleep(20 * time.Millisecond) c := hookstage.ChangeSet[hookstage.ProcessedAuctionRequestPayload]{} c.AddMutation(func(payload hookstage.ProcessedAuctionRequestPayload) (hookstage.ProcessedAuctionRequestPayload, error) { - payload.RequestWrapper.User.CustomData = "some-custom-data" + payload.Request.User.CustomData = "some-custom-data" return payload, nil }, hookstage.MutationUpdate, "bidRequest", "user.customData") @@ -142,7 +142,7 @@ func (e mockTimeoutHook) HandleBidderRequestHook(_ context.Context, _ hookstage. time.Sleep(20 * time.Millisecond) c := hookstage.ChangeSet[hookstage.BidderRequestPayload]{} c.AddMutation(func(payload hookstage.BidderRequestPayload) (hookstage.BidderRequestPayload, error) { - payload.BidRequest.User.CustomData = "some-custom-data" + payload.Request.User.CustomData = "some-custom-data" return payload, nil }, hookstage.MutationUpdate, "bidRequest", "user.customData") @@ -305,8 +305,8 @@ func (e mockUpdateBidRequestHook) HandleProcessedAuctionHook(_ context.Context, c := hookstage.ChangeSet[hookstage.ProcessedAuctionRequestPayload]{} c.AddMutation( func(payload hookstage.ProcessedAuctionRequestPayload) (hookstage.ProcessedAuctionRequestPayload, error) { - payload.RequestWrapper.User.Yob = 2000 - userExt, err := payload.RequestWrapper.GetUserExt() + payload.Request.User.Yob = 2000 + userExt, err := payload.Request.GetUserExt() if err != nil { return payload, err } @@ -318,7 +318,7 @@ func (e mockUpdateBidRequestHook) HandleProcessedAuctionHook(_ context.Context, }, hookstage.MutationUpdate, "bidRequest", "user.yob", ).AddMutation( func(payload hookstage.ProcessedAuctionRequestPayload) (hookstage.ProcessedAuctionRequestPayload, error) { - payload.RequestWrapper.User.Consent = "true" + payload.Request.User.Consent = "true" return payload, nil }, hookstage.MutationUpdate, "bidRequest", "user.consent", ) @@ -330,12 +330,12 @@ func (e mockUpdateBidRequestHook) HandleBidderRequestHook(_ context.Context, _ h c := hookstage.ChangeSet[hookstage.BidderRequestPayload]{} c.AddMutation( func(payload hookstage.BidderRequestPayload) (hookstage.BidderRequestPayload, error) { - payload.BidRequest.User.Yob = 2000 + payload.Request.User.Yob = 2000 return payload, nil }, hookstage.MutationUpdate, "bidRequest", "user.yob", ).AddMutation( func(payload hookstage.BidderRequestPayload) (hookstage.BidderRequestPayload, error) { - payload.BidRequest.User.Consent = "true" + payload.Request.User.Consent = "true" return payload, nil }, hookstage.MutationUpdate, "bidRequest", "user.consent", ) diff --git a/hooks/hookstage/bidderrequest.go b/hooks/hookstage/bidderrequest.go index 6609a103279..af480c5410c 100644 --- a/hooks/hookstage/bidderrequest.go +++ b/hooks/hookstage/bidderrequest.go @@ -2,8 +2,7 @@ package hookstage import ( "context" - - "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) // BidderRequest hooks are invoked for each bidder participating in auction. @@ -25,6 +24,6 @@ type BidderRequest interface { // distilled for the particular bidder. // Hooks are allowed to modify openrtb2.BidRequest using mutations. type BidderRequestPayload struct { - BidRequest *openrtb2.BidRequest - Bidder string + Request *openrtb_ext.RequestWrapper + Bidder string } diff --git a/hooks/hookstage/bidderrequest_mutations.go b/hooks/hookstage/bidderrequest_mutations.go index 6dfd1c6438f..746878cb4a1 100644 --- a/hooks/hookstage/bidderrequest_mutations.go +++ b/hooks/hookstage/bidderrequest_mutations.go @@ -2,9 +2,9 @@ package hookstage import ( "errors" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/prebid/openrtb/v19/adcom1" - "github.com/prebid/openrtb/v19/openrtb2" ) func (c *ChangeSet[T]) BidderRequest() ChangeSetBidderRequest[T] { @@ -31,12 +31,12 @@ func (c ChangeSetBidderRequest[T]) BApp() ChangeSetBApp[T] { return ChangeSetBApp[T]{changeSetBidderRequest: c} } -func (c ChangeSetBidderRequest[T]) castPayload(p T) (*openrtb2.BidRequest, error) { +func (c ChangeSetBidderRequest[T]) castPayload(p T) (*openrtb_ext.RequestWrapper, error) { if payload, ok := any(p).(BidderRequestPayload); ok { - if payload.BidRequest == nil { - return nil, errors.New("empty BidRequest provided") + if payload.Request == nil || payload.Request.BidRequest == nil { + return nil, errors.New("payload contains a nil bid request") } - return payload.BidRequest, nil + return payload.Request, nil } return nil, errors.New("failed to cast BidderRequestPayload") } diff --git a/hooks/hookstage/processedauctionrequest.go b/hooks/hookstage/processedauctionrequest.go index 9ee06fabb2f..f420561310c 100644 --- a/hooks/hookstage/processedauctionrequest.go +++ b/hooks/hookstage/processedauctionrequest.go @@ -26,5 +26,5 @@ type ProcessedAuctionRequest interface { // ProcessedAuctionRequestPayload consists of the openrtb_ext.RequestWrapper object. // Hooks are allowed to modify openrtb_ext.RequestWrapper using mutations. type ProcessedAuctionRequestPayload struct { - RequestWrapper *openrtb_ext.RequestWrapper + Request *openrtb_ext.RequestWrapper } diff --git a/modules/prebid/ortb2blocking/hook_bidderrequest.go b/modules/prebid/ortb2blocking/hook_bidderrequest.go index 0bd990eb50c..602e75aec95 100644 --- a/modules/prebid/ortb2blocking/hook_bidderrequest.go +++ b/modules/prebid/ortb2blocking/hook_bidderrequest.go @@ -16,11 +16,11 @@ func handleBidderRequestHook( cfg config, payload hookstage.BidderRequestPayload, ) (result hookstage.HookResult[hookstage.BidderRequestPayload], err error) { - if payload.BidRequest == nil { - return result, hookexecution.NewFailure("empty BidRequest provided") + if payload.Request == nil || payload.Request.BidRequest == nil { + return result, hookexecution.NewFailure("payload contains a nil bid request") } - mediaTypes := mediaTypesFrom(payload.BidRequest) + mediaTypes := mediaTypesFrom(payload.Request.BidRequest) changeSet := hookstage.ChangeSet[hookstage.BidderRequestPayload]{} blockingAttributes := blockingAttributes{} @@ -60,7 +60,7 @@ func updateBAdv( result *hookstage.HookResult[hookstage.BidderRequestPayload], changeSet *hookstage.ChangeSet[hookstage.BidderRequestPayload], ) (err error) { - if len(payload.BidRequest.BAdv) > 0 { + if len(payload.Request.BAdv) > 0 { return nil } @@ -87,7 +87,7 @@ func updateBApp( result *hookstage.HookResult[hookstage.BidderRequestPayload], changeSet *hookstage.ChangeSet[hookstage.BidderRequestPayload], ) (err error) { - if len(payload.BidRequest.BApp) > 0 { + if len(payload.Request.BApp) > 0 { return nil } @@ -114,7 +114,7 @@ func updateBCat( result *hookstage.HookResult[hookstage.BidderRequestPayload], changeSet *hookstage.ChangeSet[hookstage.BidderRequestPayload], ) (err error) { - if len(payload.BidRequest.BCat) > 0 { + if len(payload.Request.BCat) > 0 { return nil } @@ -191,7 +191,7 @@ func updateCatTax( attributes *blockingAttributes, changeSet *hookstage.ChangeSet[hookstage.BidderRequestPayload], ) { - if payload.BidRequest.CatTax > 0 { + if payload.Request.CatTax > 0 { return } @@ -226,7 +226,7 @@ func mutationForImp( impUpdater impUpdateFunc, ) hookstage.MutationFunc[hookstage.BidderRequestPayload] { return func(payload hookstage.BidderRequestPayload) (hookstage.BidderRequestPayload, error) { - for i, imp := range payload.BidRequest.Imp { + for i, imp := range payload.Request.Imp { if values, ok := valuesByImp[imp.ID]; ok { if len(values) == 0 { continue @@ -236,7 +236,7 @@ func mutationForImp( imp.Banner = &openrtb2.Banner{} } - payload.BidRequest.Imp[i] = impUpdater(imp, values) + payload.Request.Imp[i] = impUpdater(imp, values) } } return payload, nil @@ -310,7 +310,7 @@ func findImpressionOverrides( overrides := map[string][]int{} messages := []string{} - for _, imp := range payload.BidRequest.Imp { + for _, imp := range payload.Request.Imp { // do not add override for attribute if it already exists in request if isAttrPresent(imp) { continue diff --git a/modules/prebid/ortb2blocking/module_test.go b/modules/prebid/ortb2blocking/module_test.go index b4499a4bbfb..fc5cdcc7af6 100644 --- a/modules/prebid/ortb2blocking/module_test.go +++ b/modules/prebid/ortb2blocking/module_test.go @@ -13,6 +13,7 @@ import ( "github.com/prebid/prebid-server/v2/hooks/hookexecution" "github.com/prebid/prebid-server/v2/hooks/hookstage" "github.com/prebid/prebid-server/v2/modules/moduledeps" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) @@ -497,7 +498,7 @@ func TestHandleBidderRequestHook(t *testing.T) { bidRequest: nil, expectedBidRequest: nil, expectedHookResult: hookstage.HookResult[hookstage.BidderRequestPayload]{}, - expectedError: hookexecution.NewFailure("empty BidRequest provided"), + expectedError: hookexecution.NewFailure("payload contains a nil bid request"), }, { description: "Expect baadv error if bidders and media_types not defined in config conditions", @@ -566,7 +567,8 @@ func TestHandleBidderRequestHook(t *testing.T) { for _, test := range testCases { t.Run(test.description, func(t *testing.T) { - payload := hookstage.BidderRequestPayload{Bidder: test.bidder, BidRequest: test.bidRequest} + brw := openrtb_ext.RequestWrapper{BidRequest: test.bidRequest} + payload := hookstage.BidderRequestPayload{Bidder: test.bidder, Request: &brw} result, err := Builder(nil, moduledeps.ModuleDeps{}) assert.NoError(t, err, "Failed to build module.") @@ -590,7 +592,8 @@ func TestHandleBidderRequestHook(t *testing.T) { _, err := mut.Apply(payload) assert.NoError(t, err) } - assert.Equal(t, test.expectedBidRequest, payload.BidRequest, "Invalid BidRequest after executing BidderRequestHook.") + + assert.Equal(t, test.expectedBidRequest, payload.Request.BidRequest, "Invalid BidRequest after executing BidderRequestHook.") // reset ChangeSet not to break hookResult assertion, we validated ChangeSet separately hookResult.ChangeSet = hookstage.ChangeSet[hookstage.BidderRequestPayload]{} From b904b530658aefa13739d6afd5acb38c04c09ed4 Mon Sep 17 00:00:00 2001 From: ccorbo Date: Thu, 16 Nov 2023 12:47:54 -0500 Subject: [PATCH 211/268] fix: pass through bid.prebid.meta, currently it is being dropped (#3100) Co-authored-by: Chris Corbo --- exchange/bidder.go | 4 -- exchange/bidder_test.go | 10 ----- exchange/exchange.go | 12 ++++-- exchange/exchange_test.go | 41 ++++++++++--------- .../exchangetest/alternate-bidder-codes.json | 4 +- .../exchangetest/append-bidder-names.json | 6 +++ .../exchangetest/bid-consolidation-test.json | 9 ++++ .../bid-ext-prebid-collision.json | 3 ++ exchange/exchangetest/bid-ext.json | 3 ++ exchange/exchangetest/bid-id-invalid.json | 3 ++ exchange/exchangetest/bid-id-valid.json | 3 ++ ...e_validation_enforce_one_bid_rejected.json | 3 ++ ...bid_response_validation_warn_creative.json | 6 +++ .../bid_response_validation_warn_secure.json | 6 +++ exchange/exchangetest/debuglog_disabled.json | 6 +++ exchange/exchangetest/debuglog_enabled.json | 6 +++ .../eidpermissions-allowed-alias.json | 3 ++ ...dpermissions-allowed-case-insensitive.json | 3 ++ .../exchangetest/eidpermissions-allowed.json | 3 ++ .../exchangetest/eidpermissions-denied.json | 3 ++ .../events-bid-account-off-request-off.json | 6 +++ .../events-bid-account-off-request-on.json | 6 +++ .../events-bid-account-on-request-off.json | 6 +++ .../events-vast-account-off-request-off.json | 9 ++++ .../events-vast-account-off-request-on.json | 9 ++++ .../events-vast-account-on-request-off.json | 9 ++++ .../extra-bids-with-aliases-adaptercode.json | 6 +-- exchange/exchangetest/extra-bids.json | 4 +- ...rtydata-amp-imp-ext-one-prebid-bidder.json | 3 ++ ...ydata-imp-ext-multiple-prebid-bidders.json | 6 +++ ...stpartydata-imp-ext-one-prebid-bidder.json | 3 ++ exchange/exchangetest/fledge-with-bids.json | 3 ++ exchange/exchangetest/floors_enforcement.json | 3 ++ .../exchangetest/include-brand-category.json | 6 +++ ...epricegranularity-banner-video-native.json | 9 ++++ .../mediatypepricegranularity-native.json | 6 +++ .../exchangetest/passthrough_imp_only.json | 6 +++ .../passthrough_root_and_imp.json | 3 ++ .../exchangetest/passthrough_root_only.json | 3 ++ .../request-ext-prebid-filtering.json | 3 ++ .../request-imp-ext-prebid-filtering.json | 3 ++ .../request-multi-bidders-debug-info.json | 3 ++ .../request-multi-bidders-one-no-resp.json | 3 ++ .../targeting-cache-vast-banner.json | 3 ++ .../exchangetest/targeting-cache-vast.json | 3 ++ .../exchangetest/targeting-cache-zero.json | 3 ++ exchange/exchangetest/targeting-mobile.json | 12 ++++++ .../exchangetest/targeting-no-winners.json | 12 ++++++ .../exchangetest/targeting-only-winners.json | 12 ++++++ .../exchangetest/targeting-with-winners.json | 12 ++++++ 50 files changed, 268 insertions(+), 44 deletions(-) diff --git a/exchange/bidder.go b/exchange/bidder.go index 3cc55acb408..ce502e53d84 100644 --- a/exchange/bidder.go +++ b/exchange/bidder.go @@ -332,10 +332,6 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest Bidde if err == nil { // Conversion rate found, using it for conversion for i := 0; i < len(bidResponse.Bids); i++ { - if bidResponse.Bids[i].BidMeta == nil { - bidResponse.Bids[i].BidMeta = &openrtb_ext.ExtBidPrebidMeta{} - } - bidResponse.Bids[i].BidMeta.AdapterCode = bidderRequest.BidderName.String() bidderName := bidderRequest.BidderName if bidResponse.Bids[i].Seat != "" { diff --git a/exchange/bidder_test.go b/exchange/bidder_test.go index 6db61d0d883..b2314c8c428 100644 --- a/exchange/bidder_test.go +++ b/exchange/bidder_test.go @@ -2520,7 +2520,6 @@ func TestExtraBid(t *testing.T) { DealPriority: 5, BidType: openrtb_ext.BidTypeVideo, OriginalBidCur: "USD", - BidMeta: &openrtb_ext.ExtBidPrebidMeta{AdapterCode: string(openrtb_ext.BidderPubmatic)}, }}, Seat: "groupm", Currency: "USD", @@ -2532,7 +2531,6 @@ func TestExtraBid(t *testing.T) { DealPriority: 4, BidType: openrtb_ext.BidTypeBanner, OriginalBidCur: "USD", - BidMeta: &openrtb_ext.ExtBidPrebidMeta{AdapterCode: string(openrtb_ext.BidderPubmatic)}, }}, Seat: string(openrtb_ext.BidderPubmatic), Currency: "USD", @@ -2630,7 +2628,6 @@ func TestExtraBidWithAlternateBidderCodeDisabled(t *testing.T) { DealPriority: 5, BidType: openrtb_ext.BidTypeVideo, OriginalBidCur: "USD", - BidMeta: &openrtb_ext.ExtBidPrebidMeta{AdapterCode: string(openrtb_ext.BidderPubmatic)}, }}, Seat: "groupm-allowed", Currency: "USD", @@ -2642,7 +2639,6 @@ func TestExtraBidWithAlternateBidderCodeDisabled(t *testing.T) { DealPriority: 4, BidType: openrtb_ext.BidTypeBanner, OriginalBidCur: "USD", - BidMeta: &openrtb_ext.ExtBidPrebidMeta{AdapterCode: string(openrtb_ext.BidderPubmatic)}, }}, Seat: string(openrtb_ext.BidderPubmatic), Currency: "USD", @@ -2740,7 +2736,6 @@ func TestExtraBidWithBidAdjustments(t *testing.T) { BidType: openrtb_ext.BidTypeVideo, OriginalBidCPM: 7, OriginalBidCur: "USD", - BidMeta: &openrtb_ext.ExtBidPrebidMeta{AdapterCode: "PUBMATIC"}, }}, Seat: "groupm", Currency: "USD", @@ -2756,7 +2751,6 @@ func TestExtraBidWithBidAdjustments(t *testing.T) { BidType: openrtb_ext.BidTypeBanner, OriginalBidCur: "USD", OriginalBidCPM: 3, - BidMeta: &openrtb_ext.ExtBidPrebidMeta{AdapterCode: "PUBMATIC"}, }}, Seat: "PUBMATIC", Currency: "USD", @@ -2855,7 +2849,6 @@ func TestExtraBidWithBidAdjustmentsUsingAdapterCode(t *testing.T) { BidType: openrtb_ext.BidTypeVideo, OriginalBidCPM: 7, OriginalBidCur: "USD", - BidMeta: &openrtb_ext.ExtBidPrebidMeta{AdapterCode: string(openrtb_ext.BidderPubmatic)}, }}, Seat: "groupm", Currency: "USD", @@ -2871,7 +2864,6 @@ func TestExtraBidWithBidAdjustmentsUsingAdapterCode(t *testing.T) { BidType: openrtb_ext.BidTypeBanner, OriginalBidCur: "USD", OriginalBidCPM: 3, - BidMeta: &openrtb_ext.ExtBidPrebidMeta{AdapterCode: string(openrtb_ext.BidderPubmatic)}, }}, Seat: string(openrtb_ext.BidderPubmatic), Currency: "USD", @@ -2969,7 +2961,6 @@ func TestExtraBidWithMultiCurrencies(t *testing.T) { BidType: openrtb_ext.BidTypeVideo, OriginalBidCPM: 7, OriginalBidCur: "USD", - BidMeta: &openrtb_ext.ExtBidPrebidMeta{AdapterCode: string(openrtb_ext.BidderPubmatic)}, }}, Seat: "groupm", Currency: "INR", @@ -2985,7 +2976,6 @@ func TestExtraBidWithMultiCurrencies(t *testing.T) { BidType: openrtb_ext.BidTypeBanner, OriginalBidCPM: 3, OriginalBidCur: "USD", - BidMeta: &openrtb_ext.ExtBidPrebidMeta{AdapterCode: string(openrtb_ext.BidderPubmatic)}, }}, Seat: string(openrtb_ext.BidderPubmatic), Currency: "INR", diff --git a/exchange/exchange.go b/exchange/exchange.go index bb59fe90d43..b7e26ee2a73 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -1277,7 +1277,7 @@ func (e *exchange) makeBid(bids []*entities.PbsOrtbBid, auc *auction, returnCrea } } - if bidExtJSON, err := makeBidExtJSON(bid.Bid.Ext, bidExtPrebid, impExtInfoMap, bid.Bid.ImpID, bid.OriginalBidCPM, bid.OriginalBidCur); err != nil { + if bidExtJSON, err := makeBidExtJSON(bid.Bid.Ext, bidExtPrebid, impExtInfoMap, bid.Bid.ImpID, bid.OriginalBidCPM, bid.OriginalBidCur, adapter); err != nil { errs = append(errs, err) } else { result = append(result, *bid.Bid) @@ -1291,7 +1291,7 @@ func (e *exchange) makeBid(bids []*entities.PbsOrtbBid, auc *auction, returnCrea return result, errs } -func makeBidExtJSON(ext json.RawMessage, prebid *openrtb_ext.ExtBidPrebid, impExtInfoMap map[string]ImpExtInfo, impId string, originalBidCpm float64, originalBidCur string) (json.RawMessage, error) { +func makeBidExtJSON(ext json.RawMessage, prebid *openrtb_ext.ExtBidPrebid, impExtInfoMap map[string]ImpExtInfo, impId string, originalBidCpm float64, originalBidCur string, adapter openrtb_ext.BidderName) (json.RawMessage, error) { var extMap map[string]interface{} if len(ext) != 0 { @@ -1320,11 +1320,17 @@ func makeBidExtJSON(ext json.RawMessage, prebid *openrtb_ext.ExtBidPrebid, impEx } `json:"prebid"` }{} if err := jsonutil.Unmarshal(ext, &metaContainer); err != nil { - return nil, fmt.Errorf("error validaing response from server, %s", err) + return nil, fmt.Errorf("error validating response from server, %s", err) } prebid.Meta = &metaContainer.Prebid.Meta } + if prebid.Meta == nil { + prebid.Meta = &openrtb_ext.ExtBidPrebidMeta{} + } + + prebid.Meta.AdapterCode = adapter.String() + // ext.prebid.storedrequestattributes and ext.prebid.passthrough if impExtInfo, ok := impExtInfoMap[impId]; ok { prebid.Passthrough = impExtInfoMap[impId].Passthrough diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go index 25925e83566..8f7ec30d30d 100644 --- a/exchange/exchange_test.go +++ b/exchange/exchange_test.go @@ -1836,7 +1836,7 @@ func TestBidResponseCurrency(t *testing.T) { Price: 9.517803, W: 300, H: 250, - Ext: json.RawMessage(`{"origbidcpm":9.517803,"prebid":{"type":"banner"}}`), + Ext: json.RawMessage(`{"origbidcpm":9.517803,"prebid":{"meta":{"adaptercode":"appnexus"},"type":"banner"}}`), }, }, }, @@ -1978,7 +1978,7 @@ func TestBidResponseImpExtInfo(t *testing.T) { []byte(`{"video":{"h":480,"mimes":["video/mp4"]}}`), json.RawMessage(`{"imp_passthrough_val":1}`)} - expectedBidResponseExt := `{"origbidcpm":0,"prebid":{"type":"video","passthrough":{"imp_passthrough_val":1}},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]}}` + expectedBidResponseExt := `{"origbidcpm":0,"prebid":{"meta":{"adaptercode":"appnexus"},"type":"video","passthrough":{"imp_passthrough_val":1}},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]}}` actualBidResp := e.buildBidResponse(context.Background(), liveAdapters, adapterBids, bidRequest, nil, nil, nil, true, impExtInfo, "", errList) @@ -4044,7 +4044,7 @@ func TestMakeBidExtJSON(t *testing.T) { impExtInfo: map[string]ImpExtInfo{"test_imp_id": {true, []byte(`{"video":{"h":480,"mimes":["video/mp4"]}}`), json.RawMessage(`{"imp_passthrough_val": 1}`)}}, origbidcpm: 10.0000, origbidcur: "USD", - expectedBidExt: `{"prebid":{"meta": {"brandName": "foo"}, "passthrough":{"imp_passthrough_val":1}, "type":"video"}, "storedrequestattributes":{"h":480,"mimes":["video/mp4"]},"video":{"h":100}, "origbidcpm": 10, "origbidcur": "USD"}`, + expectedBidExt: `{"prebid":{"meta": {"brandName": "foo","adaptercode": "adapter"}, "passthrough":{"imp_passthrough_val":1}, "type":"video"}, "storedrequestattributes":{"h":480,"mimes":["video/mp4"]},"video":{"h":100}, "origbidcpm": 10, "origbidcur": "USD"}`, expectedErrMessage: "", }, { @@ -4054,7 +4054,7 @@ func TestMakeBidExtJSON(t *testing.T) { impExtInfo: map[string]ImpExtInfo{"test_imp_id": {true, []byte(`{"video":{"h":480,"mimes":["video/mp4"]}}`), nil}}, origbidcpm: 10.0000, origbidcur: "USD", - expectedBidExt: `{"prebid":{"meta": {"brandName": "foo"}, "type":"video"},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]},"video":{"h":100}, "origbidcpm": 10, "origbidcur": "USD"}`, + expectedBidExt: `{"prebid":{"meta": {"brandName": "foo","adaptercode": "adapter"}, "type":"video"},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]},"video":{"h":100}, "origbidcpm": 10, "origbidcur": "USD"}`, expectedErrMessage: "", }, { @@ -4063,7 +4063,7 @@ func TestMakeBidExtJSON(t *testing.T) { extBidPrebid: openrtb_ext.ExtBidPrebid{Type: openrtb_ext.BidType("video")}, impExtInfo: map[string]ImpExtInfo{"test_imp_id": {true, []byte(`{"video":{"h":480,"mimes":["video/mp4"]}}`), json.RawMessage(`{"imp_passthrough_val": 1}`)}}, origbidcpm: 0, - expectedBidExt: `{"origbidcpm": 0,"prebid":{"passthrough":{"imp_passthrough_val":1}, "type":"video"},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]}}`, + expectedBidExt: `{"origbidcpm": 0,"prebid":{"meta":{"adaptercode": "adapter"},"passthrough":{"imp_passthrough_val":1}, "type":"video"},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]}}`, expectedErrMessage: "", }, { @@ -4073,7 +4073,7 @@ func TestMakeBidExtJSON(t *testing.T) { impExtInfo: map[string]ImpExtInfo{"another_imp_id": {true, []byte(`{"video":{"h":480,"mimes":["video/mp4"]}}`), json.RawMessage(`{"imp_passthrough_val": 1}`)}}, origbidcpm: 10.0000, origbidcur: "USD", - expectedBidExt: `{"prebid":{"type":"video"},"video":{"h":100}, "origbidcpm": 10, "origbidcur": "USD"}`, + expectedBidExt: `{"prebid":{"meta":{"adaptercode": "adapter"},"type":"video"},"video":{"h":100}, "origbidcpm": 10, "origbidcur": "USD"}`, expectedErrMessage: "", }, { @@ -4083,7 +4083,7 @@ func TestMakeBidExtJSON(t *testing.T) { origbidcpm: 10.0000, origbidcur: "USD", impExtInfo: map[string]ImpExtInfo{"test_imp_id": {true, []byte(`{"video":{"h":480,"mimes":["video/mp4"]}}`), json.RawMessage(`{"imp_passthrough_val": 1}`)}}, - expectedBidExt: `{"prebid":{"passthrough":{"imp_passthrough_val":1}},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]},"video":{"h":100}, "origbidcpm": 10, "origbidcur": "USD"}`, + expectedBidExt: `{"prebid":{"meta":{"adaptercode": "adapter"},"passthrough":{"imp_passthrough_val":1}},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]},"video":{"h":100}, "origbidcpm": 10, "origbidcur": "USD"}`, expectedErrMessage: "", }, { @@ -4093,7 +4093,7 @@ func TestMakeBidExtJSON(t *testing.T) { origbidcpm: 10.0000, origbidcur: "USD", impExtInfo: nil, - expectedBidExt: `{"prebid":{"type":"video"},"video":{"h":100}, "origbidcpm": 10, "origbidcur": "USD"}`, + expectedBidExt: `{"prebid":{"meta":{"adaptercode": "adapter"},"type":"video"},"video":{"h":100}, "origbidcpm": 10, "origbidcur": "USD"}`, expectedErrMessage: "", }, { @@ -4103,7 +4103,7 @@ func TestMakeBidExtJSON(t *testing.T) { origbidcpm: 10.0000, origbidcur: "USD", impExtInfo: map[string]ImpExtInfo{"test_imp_id": {true, []byte(`{"banner":{"h":480}}`), json.RawMessage(`{"imp_passthrough_val": 1}`)}}, - expectedBidExt: `{"prebid":{"passthrough":{"imp_passthrough_val":1}, "type":"video"},"video":{"h":100}, "origbidcpm": 10, "origbidcur": "USD"}`, + expectedBidExt: `{"prebid":{"meta":{"adaptercode": "adapter"},"passthrough":{"imp_passthrough_val":1}, "type":"video"},"video":{"h":100}, "origbidcpm": 10, "origbidcur": "USD"}`, expectedErrMessage: "", }, { @@ -4113,7 +4113,7 @@ func TestMakeBidExtJSON(t *testing.T) { origbidcpm: 10.0000, origbidcur: "USD", impExtInfo: map[string]ImpExtInfo{"test_imp_id": {true, []byte(`{"banner":{"h":480}}`), json.RawMessage(`{"imp_passthrough_val": 1}`)}}, - expectedBidExt: `{"prebid":{"passthrough":{"imp_passthrough_val":1}, "type":"video"}, "origbidcpm": 10, "origbidcur": "USD"}`, + expectedBidExt: `{"prebid":{"meta":{"adaptercode": "adapter"},"passthrough":{"imp_passthrough_val":1}, "type":"video"}, "origbidcpm": 10, "origbidcur": "USD"}`, expectedErrMessage: "", }, { @@ -4123,7 +4123,7 @@ func TestMakeBidExtJSON(t *testing.T) { origbidcpm: 10.0000, origbidcur: "USD", impExtInfo: map[string]ImpExtInfo{"test_imp_id": {true, []byte(`{"video":{"h":480,"mimes":["video/mp4"]}}`), json.RawMessage(`{"imp_passthrough_val": 1}`)}}, - expectedBidExt: `{"prebid":{"passthrough":{"imp_passthrough_val":1}, "type":"video"}, "storedrequestattributes":{"h":480,"mimes":["video/mp4"]}, "origbidcpm": 10, "origbidcur": "USD"}`, + expectedBidExt: `{"prebid":{"meta":{"adaptercode": "adapter"},"passthrough":{"imp_passthrough_val":1}, "type":"video"}, "storedrequestattributes":{"h":480,"mimes":["video/mp4"]}, "origbidcpm": 10, "origbidcur": "USD"}`, expectedErrMessage: "", }, { @@ -4133,7 +4133,7 @@ func TestMakeBidExtJSON(t *testing.T) { impExtInfo: map[string]ImpExtInfo{}, origbidcpm: 0, origbidcur: "USD", - expectedBidExt: `{"origbidcpm": 0,"prebid":{"meta":{"brandName":"foo"},"type":"banner"}, "origbidcur": "USD"}`, + expectedBidExt: `{"origbidcpm": 0,"prebid":{"meta":{"brandName":"foo","adaptercode": "adapter"},"type":"banner"}, "origbidcur": "USD"}`, expectedErrMessage: "", }, { @@ -4143,7 +4143,7 @@ func TestMakeBidExtJSON(t *testing.T) { impExtInfo: nil, origbidcpm: 0, origbidcur: "USD", - expectedBidExt: `{"origbidcpm": 0,"prebid":{"meta":{"brandName":"foo"},"type":"banner"}, "origbidcur": "USD"}`, + expectedBidExt: `{"origbidcpm": 0,"prebid":{"meta":{"brandName":"foo","adaptercode": "adapter"},"type":"banner"}, "origbidcur": "USD"}`, expectedErrMessage: "", }, { @@ -4153,7 +4153,7 @@ func TestMakeBidExtJSON(t *testing.T) { impExtInfo: nil, origbidcpm: 10.0000, origbidcur: "USD", - expectedBidExt: `{"prebid":{"meta":{"brandName":"foo"},"type":"banner"}, "origbidcpm": 10, "origbidcur": "USD"}`, + expectedBidExt: `{"prebid":{"meta":{"brandName":"foo","adaptercode": "adapter"},"type":"banner"}, "origbidcpm": 10, "origbidcur": "USD"}`, expectedErrMessage: "", }, { @@ -4163,7 +4163,7 @@ func TestMakeBidExtJSON(t *testing.T) { impExtInfo: nil, origbidcpm: 10.0000, origbidcur: "USD", - expectedBidExt: `{"prebid":{"meta":{"brandName":"foo"},"type":"banner"}, "origbidcpm": 10, "origbidcur": "USD"}`, + expectedBidExt: `{"prebid":{"meta":{"brandName":"foo","adaptercode": "adapter"},"type":"banner"}, "origbidcpm": 10, "origbidcur": "USD"}`, expectedErrMessage: "", }, { @@ -4173,7 +4173,7 @@ func TestMakeBidExtJSON(t *testing.T) { impExtInfo: nil, origbidcpm: -1, origbidcur: "USD", - expectedBidExt: `{"prebid":{"meta":{"brandName":"foo"},"type":"banner"}, "origbidcur": "USD"}`, + expectedBidExt: `{"prebid":{"meta":{"brandName":"foo","adaptercode":"adapter"},"type":"banner"}, "origbidcur": "USD"}`, expectedErrMessage: "", }, { @@ -4183,7 +4183,7 @@ func TestMakeBidExtJSON(t *testing.T) { impExtInfo: nil, origbidcpm: 0, origbidcur: "USD", - expectedBidExt: `{"origbidcpm": 0,"prebid":{"type":"banner"}, "origbidcur": "USD"}`, + expectedBidExt: `{"origbidcpm": 0,"prebid":{"type":"banner","meta":{"adaptercode":"adapter"}}, "origbidcur": "USD"}`, expectedErrMessage: "", }, //Error cases @@ -4199,13 +4199,14 @@ func TestMakeBidExtJSON(t *testing.T) { ext: json.RawMessage(`{"prebid":{"meta":{"brandId":"foo"}}}`), // brandId should be an int, but is a string in this test case extBidPrebid: openrtb_ext.ExtBidPrebid{Type: openrtb_ext.BidType("banner")}, impExtInfo: nil, - expectedErrMessage: "error validaing response from server, cannot unmarshal openrtb_ext.ExtBidPrebidMeta.BrandID: unexpected character: \xff", + expectedErrMessage: "error validating response from server, cannot unmarshal openrtb_ext.ExtBidPrebidMeta.BrandID: unexpected character: \xff", }, } for _, test := range testCases { t.Run(test.description, func(t *testing.T) { - result, err := makeBidExtJSON(test.ext, &test.extBidPrebid, test.impExtInfo, "test_imp_id", test.origbidcpm, test.origbidcur) + var adapter openrtb_ext.BidderName = "adapter" + result, err := makeBidExtJSON(test.ext, &test.extBidPrebid, test.impExtInfo, "test_imp_id", test.origbidcpm, test.origbidcur, adapter) if test.expectedErrMessage == "" { assert.JSONEq(t, test.expectedBidExt, string(result), "Incorrect result") @@ -4249,7 +4250,7 @@ func TestStoredAuctionResponses(t *testing.T) { SeatBid: []openrtb2.SeatBid{ { Bid: []openrtb2.Bid{ - {ID: "bid_id", ImpID: "impression-id", Ext: json.RawMessage(`{"origbidcpm":0,"prebid":{"type":"video"}}`)}, + {ID: "bid_id", ImpID: "impression-id", Ext: json.RawMessage(`{"origbidcpm":0,"prebid":{"meta":{"adaptercode":"appnexus"},"type":"video"}}`)}, }, Seat: "appnexus", }, diff --git a/exchange/exchangetest/alternate-bidder-codes.json b/exchange/exchangetest/alternate-bidder-codes.json index 26a7a05d4e1..c2e6f95a5a7 100644 --- a/exchange/exchangetest/alternate-bidder-codes.json +++ b/exchange/exchangetest/alternate-bidder-codes.json @@ -206,7 +206,7 @@ "origbidcpm": 0.51, "prebid": { "meta": { - "adaptercode": "pubmatic" + "adaptercode": "groupm" }, "type": "video" } @@ -220,7 +220,7 @@ "origbidcpm": 0.3, "prebid": { "meta": { - "adaptercode": "appnexus" + "adaptercode": "groupm" }, "type": "banner" } diff --git a/exchange/exchangetest/append-bidder-names.json b/exchange/exchangetest/append-bidder-names.json index 659045cd588..14f1181e96a 100644 --- a/exchange/exchangetest/append-bidder-names.json +++ b/exchange/exchangetest/append-bidder-names.json @@ -137,6 +137,9 @@ "origbidcpm": 0.3, "prebid": { "type": "video", + "meta": { + "adaptercode":"appnexus" + }, "targeting": { "hb_bidder": "appnexus", "hb_bidder_appnexus": "appnexus", @@ -162,6 +165,9 @@ "ext": { "origbidcpm": 0.6, "prebid": { + "meta": { + "adaptercode":"appnexus" + }, "targeting": { "hb_bidder": "appnexus", "hb_bidder_appnexus": "appnexus", diff --git a/exchange/exchangetest/bid-consolidation-test.json b/exchange/exchangetest/bid-consolidation-test.json index b38e9d69603..61dbae5e045 100644 --- a/exchange/exchangetest/bid-consolidation-test.json +++ b/exchange/exchangetest/bid-consolidation-test.json @@ -127,6 +127,9 @@ "ext": { "origbidcpm": 0.4, "prebid": { + "meta": { + "adaptercode":"rubicon" + }, "type": "video" } } @@ -146,6 +149,9 @@ "ext": { "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode":"appnexus" + }, "type": "video" } } @@ -160,6 +166,9 @@ "ext": { "origbidcpm": 0.6, "prebid": { + "meta": { + "adaptercode":"appnexus" + }, "type": "video" } } diff --git a/exchange/exchangetest/bid-ext-prebid-collision.json b/exchange/exchangetest/bid-ext-prebid-collision.json index 49e4f8a8f22..f6a2a065485 100644 --- a/exchange/exchangetest/bid-ext-prebid-collision.json +++ b/exchange/exchangetest/bid-ext-prebid-collision.json @@ -99,6 +99,9 @@ "someField": "someValue", "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode":"appnexus" + }, "type": "video" } } diff --git a/exchange/exchangetest/bid-ext.json b/exchange/exchangetest/bid-ext.json index 69e7aba9f0c..f2416d6f2de 100644 --- a/exchange/exchangetest/bid-ext.json +++ b/exchange/exchangetest/bid-ext.json @@ -96,6 +96,9 @@ "origbidcpm": 0.3, "someField": "someValue", "prebid": { + "meta": { + "adaptercode":"appnexus" + }, "type": "video" } } diff --git a/exchange/exchangetest/bid-id-invalid.json b/exchange/exchangetest/bid-id-invalid.json index 9c5cb84c310..9b3c5eee245 100644 --- a/exchange/exchangetest/bid-id-invalid.json +++ b/exchange/exchangetest/bid-id-invalid.json @@ -109,6 +109,9 @@ "ext": { "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode":"appnexus" + }, "type": "video", "targeting": { "hb_bidder": "appnexus", diff --git a/exchange/exchangetest/bid-id-valid.json b/exchange/exchangetest/bid-id-valid.json index b4a30640f77..caa02384025 100644 --- a/exchange/exchangetest/bid-id-valid.json +++ b/exchange/exchangetest/bid-id-valid.json @@ -109,6 +109,9 @@ "ext": { "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode":"appnexus" + }, "bidid": "mock_uuid", "type": "video", "targeting": { diff --git a/exchange/exchangetest/bid_response_validation_enforce_one_bid_rejected.json b/exchange/exchangetest/bid_response_validation_enforce_one_bid_rejected.json index ea48f3a966f..a6e0de460f7 100644 --- a/exchange/exchangetest/bid_response_validation_enforce_one_bid_rejected.json +++ b/exchange/exchangetest/bid_response_validation_enforce_one_bid_rejected.json @@ -173,6 +173,9 @@ "ext": { "origbidcpm": 0.4, "prebid": { + "meta": { + "adaptercode":"rubicon" + }, "type": "banner" } } diff --git a/exchange/exchangetest/bid_response_validation_warn_creative.json b/exchange/exchangetest/bid_response_validation_warn_creative.json index a170eac778e..47546683f05 100644 --- a/exchange/exchangetest/bid_response_validation_warn_creative.json +++ b/exchange/exchangetest/bid_response_validation_warn_creative.json @@ -169,6 +169,9 @@ "ext": { "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode":"appnexus" + }, "type": "banner" } } @@ -188,6 +191,9 @@ "ext": { "origbidcpm": 0.4, "prebid": { + "meta": { + "adaptercode":"rubicon" + }, "type": "banner" } } diff --git a/exchange/exchangetest/bid_response_validation_warn_secure.json b/exchange/exchangetest/bid_response_validation_warn_secure.json index a6b208d2f0d..3c06f695970 100644 --- a/exchange/exchangetest/bid_response_validation_warn_secure.json +++ b/exchange/exchangetest/bid_response_validation_warn_secure.json @@ -172,6 +172,9 @@ "ext": { "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode":"appnexus" + }, "type": "banner" } } @@ -192,6 +195,9 @@ "ext": { "origbidcpm": 0.4, "prebid": { + "meta": { + "adaptercode":"rubicon" + }, "type": "banner" } } diff --git a/exchange/exchangetest/debuglog_disabled.json b/exchange/exchangetest/debuglog_disabled.json index d803759d1d9..5c0e029c975 100644 --- a/exchange/exchangetest/debuglog_disabled.json +++ b/exchange/exchangetest/debuglog_disabled.json @@ -145,6 +145,9 @@ "ext": { "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video", "targeting": { "hb_bidder": "appnexus", @@ -171,6 +174,9 @@ "ext": { "origbidcpm": 0.6, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "targeting": { "hb_bidder": "appnexus", "hb_bidder_appnexus": "appnexus", diff --git a/exchange/exchangetest/debuglog_enabled.json b/exchange/exchangetest/debuglog_enabled.json index 054737e653e..11a63f5db2e 100644 --- a/exchange/exchangetest/debuglog_enabled.json +++ b/exchange/exchangetest/debuglog_enabled.json @@ -147,6 +147,9 @@ "ext": { "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video", "targeting": { "hb_bidder": "appnexus", @@ -173,6 +176,9 @@ "ext": { "origbidcpm": 0.6, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "targeting": { "hb_bidder": "appnexus", "hb_bidder_appnexus": "appnexus", diff --git a/exchange/exchangetest/eidpermissions-allowed-alias.json b/exchange/exchangetest/eidpermissions-allowed-alias.json index de3c0e1dca6..3dfe441567e 100644 --- a/exchange/exchangetest/eidpermissions-allowed-alias.json +++ b/exchange/exchangetest/eidpermissions-allowed-alias.json @@ -135,6 +135,9 @@ "ext": { "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode": "foo" + }, "type": "video" } } diff --git a/exchange/exchangetest/eidpermissions-allowed-case-insensitive.json b/exchange/exchangetest/eidpermissions-allowed-case-insensitive.json index 86797501495..459bb015e25 100644 --- a/exchange/exchangetest/eidpermissions-allowed-case-insensitive.json +++ b/exchange/exchangetest/eidpermissions-allowed-case-insensitive.json @@ -132,6 +132,9 @@ "ext": { "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video" } } diff --git a/exchange/exchangetest/eidpermissions-allowed.json b/exchange/exchangetest/eidpermissions-allowed.json index 9daee27a9b6..06b2d184bf1 100644 --- a/exchange/exchangetest/eidpermissions-allowed.json +++ b/exchange/exchangetest/eidpermissions-allowed.json @@ -132,6 +132,9 @@ "ext": { "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video" } } diff --git a/exchange/exchangetest/eidpermissions-denied.json b/exchange/exchangetest/eidpermissions-denied.json index 04eb51bb600..72431595fe3 100644 --- a/exchange/exchangetest/eidpermissions-denied.json +++ b/exchange/exchangetest/eidpermissions-denied.json @@ -119,6 +119,9 @@ "ext": { "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video" } } diff --git a/exchange/exchangetest/events-bid-account-off-request-off.json b/exchange/exchangetest/events-bid-account-off-request-off.json index b15b33a8653..4ae1881b865 100644 --- a/exchange/exchangetest/events-bid-account-off-request-off.json +++ b/exchange/exchangetest/events-bid-account-off-request-off.json @@ -79,6 +79,9 @@ "ext": { "origbidcpm": 0.71, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "banner" } } @@ -93,6 +96,9 @@ "ext": { "origbidcpm": 0.21, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "banner" } } diff --git a/exchange/exchangetest/events-bid-account-off-request-on.json b/exchange/exchangetest/events-bid-account-off-request-on.json index 8a6b8aa7e14..20606002619 100644 --- a/exchange/exchangetest/events-bid-account-off-request-on.json +++ b/exchange/exchangetest/events-bid-account-off-request-on.json @@ -82,6 +82,9 @@ "ext": { "origbidcpm": 0.71, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "banner", "events": { "imp": "http://localhost/event?t=imp&b=winning-bid&a=testaccount&bidder=appnexus&int=testIntegrationType&ts=1234567890", @@ -100,6 +103,9 @@ "ext": { "origbidcpm": 0.21, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "banner", "events": { "imp": "http://localhost/event?t=imp&b=losing-bid&a=testaccount&bidder=appnexus&int=testIntegrationType&ts=1234567890", diff --git a/exchange/exchangetest/events-bid-account-on-request-off.json b/exchange/exchangetest/events-bid-account-on-request-off.json index 5a2fa6ae4d2..0447a2240e3 100644 --- a/exchange/exchangetest/events-bid-account-on-request-off.json +++ b/exchange/exchangetest/events-bid-account-on-request-off.json @@ -81,6 +81,9 @@ "ext": { "origbidcpm": 0.71, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "banner", "events": { "imp": "http://localhost/event?t=imp&b=winning-bid&a=testaccount&bidder=appnexus&int=testIntegrationType&ts=1234567890", @@ -99,6 +102,9 @@ "ext": { "origbidcpm": 0.21, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "banner", "events": { "imp": "http://localhost/event?t=imp&b=losing-bid&a=testaccount&bidder=appnexus&int=testIntegrationType&ts=1234567890", diff --git a/exchange/exchangetest/events-vast-account-off-request-off.json b/exchange/exchangetest/events-vast-account-off-request-off.json index a94546d2aa0..3792c0ba95b 100644 --- a/exchange/exchangetest/events-vast-account-off-request-off.json +++ b/exchange/exchangetest/events-vast-account-off-request-off.json @@ -125,6 +125,9 @@ "ext": { "origbidcpm": 0.51, "prebid": { + "meta": { + "adaptercode": "audienceNetwork" + }, "type": "video" } } @@ -145,6 +148,9 @@ "ext": { "origbidcpm": 0.71, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video", "targeting": { "hb_bidder": "appnexus", @@ -168,6 +174,9 @@ "ext": { "origbidcpm": 0.21, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video" } } diff --git a/exchange/exchangetest/events-vast-account-off-request-on.json b/exchange/exchangetest/events-vast-account-off-request-on.json index 275b8aef2ce..1a5aea4217f 100644 --- a/exchange/exchangetest/events-vast-account-off-request-on.json +++ b/exchange/exchangetest/events-vast-account-off-request-on.json @@ -131,6 +131,9 @@ "ext": { "origbidcpm": 0.51, "prebid": { + "meta": { + "adaptercode": "audienceNetwork" + }, "bidid": "mock_uuid", "type": "video" } @@ -154,6 +157,9 @@ "origbidcpm": 0.71, "prebid": { "bidid": "mock_uuid", + "meta": { + "adaptercode": "appnexus" + }, "type": "video", "targeting": { "hb_bidder": "appnexus", @@ -178,6 +184,9 @@ "ext": { "origbidcpm": 0.21, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "bidid": "mock_uuid", "type": "video" } diff --git a/exchange/exchangetest/events-vast-account-on-request-off.json b/exchange/exchangetest/events-vast-account-on-request-off.json index e271ecf5c8f..38f407d559b 100644 --- a/exchange/exchangetest/events-vast-account-on-request-off.json +++ b/exchange/exchangetest/events-vast-account-on-request-off.json @@ -126,6 +126,9 @@ "ext": { "origbidcpm": 0.51, "prebid": { + "meta": { + "adaptercode": "audienceNetwork" + }, "type": "video" } } @@ -147,6 +150,9 @@ "ext": { "origbidcpm": 0.71, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video", "targeting": { "hb_bidder": "appnexus", @@ -171,6 +177,9 @@ "ext": { "origbidcpm": 0.21, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video" } } diff --git a/exchange/exchangetest/extra-bids-with-aliases-adaptercode.json b/exchange/exchangetest/extra-bids-with-aliases-adaptercode.json index b46f54c6408..8da9a29095a 100644 --- a/exchange/exchangetest/extra-bids-with-aliases-adaptercode.json +++ b/exchange/exchangetest/extra-bids-with-aliases-adaptercode.json @@ -185,7 +185,7 @@ "origbidcpm": 0.71, "prebid": { "meta": { - "adaptercode": "pmbidder" + "adaptercode": "groupm" }, "type": "video", "targeting": { @@ -214,7 +214,7 @@ "origbidcpm": 0.21, "prebid": { "meta": { - "adaptercode": "pmbidder" + "adaptercode": "groupm" }, "type": "video" } @@ -231,7 +231,7 @@ "origbidcpm": 0.61, "prebid": { "meta": { - "adaptercode": "pmbidder" + "adaptercode": "groupm" }, "type": "video", "targeting": { diff --git a/exchange/exchangetest/extra-bids.json b/exchange/exchangetest/extra-bids.json index 23e122593b5..edf2e60b124 100644 --- a/exchange/exchangetest/extra-bids.json +++ b/exchange/exchangetest/extra-bids.json @@ -309,7 +309,7 @@ "origbidcpm": 0.51, "prebid": { "meta": { - "adaptercode": "pubmatic" + "adaptercode": "groupm" }, "type": "video", "targeting": { @@ -333,7 +333,7 @@ "origbidcpm": 0.3, "prebid": { "meta": { - "adaptercode": "appnexus" + "adaptercode": "groupm" }, "type": "banner" } diff --git a/exchange/exchangetest/firstpartydata-amp-imp-ext-one-prebid-bidder.json b/exchange/exchangetest/firstpartydata-amp-imp-ext-one-prebid-bidder.json index 627c95f9d54..22e0fb8229f 100644 --- a/exchange/exchangetest/firstpartydata-amp-imp-ext-one-prebid-bidder.json +++ b/exchange/exchangetest/firstpartydata-amp-imp-ext-one-prebid-bidder.json @@ -121,6 +121,9 @@ "ext": { "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "banner" } } diff --git a/exchange/exchangetest/firstpartydata-imp-ext-multiple-prebid-bidders.json b/exchange/exchangetest/firstpartydata-imp-ext-multiple-prebid-bidders.json index f15fea59d87..37d5ade5c45 100644 --- a/exchange/exchangetest/firstpartydata-imp-ext-multiple-prebid-bidders.json +++ b/exchange/exchangetest/firstpartydata-imp-ext-multiple-prebid-bidders.json @@ -188,6 +188,9 @@ "ext": { "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "banner" } } @@ -207,6 +210,9 @@ "ext": { "origbidcpm": 0.4, "prebid": { + "meta": { + "adaptercode": "rubicon" + }, "type": "banner" } } diff --git a/exchange/exchangetest/firstpartydata-imp-ext-one-prebid-bidder.json b/exchange/exchangetest/firstpartydata-imp-ext-one-prebid-bidder.json index 9eb6a77eed5..1b6b2043d26 100644 --- a/exchange/exchangetest/firstpartydata-imp-ext-one-prebid-bidder.json +++ b/exchange/exchangetest/firstpartydata-imp-ext-one-prebid-bidder.json @@ -121,6 +121,9 @@ "ext": { "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "banner" } } diff --git a/exchange/exchangetest/fledge-with-bids.json b/exchange/exchangetest/fledge-with-bids.json index 0f998e69ee0..df59c0d28c7 100644 --- a/exchange/exchangetest/fledge-with-bids.json +++ b/exchange/exchangetest/fledge-with-bids.json @@ -114,6 +114,9 @@ "origbidcpm": 0.3, "someField": "someValue", "prebid": { + "meta": { + "adaptercode": "openx" + }, "type": "video" } } diff --git a/exchange/exchangetest/floors_enforcement.json b/exchange/exchangetest/floors_enforcement.json index 90d25301e65..2124bcf2aac 100644 --- a/exchange/exchangetest/floors_enforcement.json +++ b/exchange/exchangetest/floors_enforcement.json @@ -136,6 +136,9 @@ "ext": { "origbidcpm": 12, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "floors": { "floorCurrency": "USD", "floorRule": "*|*", diff --git a/exchange/exchangetest/include-brand-category.json b/exchange/exchangetest/include-brand-category.json index 9d537f74902..c0904448375 100644 --- a/exchange/exchangetest/include-brand-category.json +++ b/exchange/exchangetest/include-brand-category.json @@ -134,6 +134,9 @@ "ext": { "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video", "targeting": { "hb_bidder": "appnexus", @@ -160,6 +163,9 @@ "ext": { "origbidcpm": 0.6, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "targeting": { "hb_bidder": "appnexus", "hb_bidder_appnexus": "appnexus", diff --git a/exchange/exchangetest/mediatypepricegranularity-banner-video-native.json b/exchange/exchangetest/mediatypepricegranularity-banner-video-native.json index 7d119b23044..4e532d1e72f 100644 --- a/exchange/exchangetest/mediatypepricegranularity-banner-video-native.json +++ b/exchange/exchangetest/mediatypepricegranularity-banner-video-native.json @@ -196,6 +196,9 @@ "ext": { "origbidcpm": 15, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "banner", "targeting": { "hb_bidder": "appnexus", @@ -223,6 +226,9 @@ "ext": { "origbidcpm": 18, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "targeting": { "hb_bidder": "appnexus", "hb_bidder_appnexus": "appnexus", @@ -255,6 +261,9 @@ "ext": { "origbidcpm": 29, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "targeting": { "hb_bidder": "appnexus", "hb_bidder_appnexus": "appnexus", diff --git a/exchange/exchangetest/mediatypepricegranularity-native.json b/exchange/exchangetest/mediatypepricegranularity-native.json index 57a318e1fcf..e454b500722 100644 --- a/exchange/exchangetest/mediatypepricegranularity-native.json +++ b/exchange/exchangetest/mediatypepricegranularity-native.json @@ -164,6 +164,9 @@ "ext": { "origbidcpm": 24, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "native", "targeting": { "hb_bidder": "appnexus", @@ -191,6 +194,9 @@ "ext": { "origbidcpm": 29, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "targeting": { "hb_bidder": "appnexus", "hb_bidder_appnexus": "appnexus", diff --git a/exchange/exchangetest/passthrough_imp_only.json b/exchange/exchangetest/passthrough_imp_only.json index b7b2270270b..bc3d8dd22de 100644 --- a/exchange/exchangetest/passthrough_imp_only.json +++ b/exchange/exchangetest/passthrough_imp_only.json @@ -144,6 +144,9 @@ "someField": "someValue", "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video", "passthrough": { "imp_passthrough_val": 20 @@ -162,6 +165,9 @@ "someField": "someValue", "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video" } } diff --git a/exchange/exchangetest/passthrough_root_and_imp.json b/exchange/exchangetest/passthrough_root_and_imp.json index 7d4fe89b6d2..959b934f857 100644 --- a/exchange/exchangetest/passthrough_root_and_imp.json +++ b/exchange/exchangetest/passthrough_root_and_imp.json @@ -106,6 +106,9 @@ "someField": "someValue", "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video", "passthrough": { "imp_passthrough_val": 20 diff --git a/exchange/exchangetest/passthrough_root_only.json b/exchange/exchangetest/passthrough_root_only.json index 0b444535348..254b09adc0e 100644 --- a/exchange/exchangetest/passthrough_root_only.json +++ b/exchange/exchangetest/passthrough_root_only.json @@ -101,6 +101,9 @@ "crid": "creative-1", "ext": { "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video" }, "someField": "someValue", diff --git a/exchange/exchangetest/request-ext-prebid-filtering.json b/exchange/exchangetest/request-ext-prebid-filtering.json index 8e85d8edfdc..8a82f4cb8ab 100644 --- a/exchange/exchangetest/request-ext-prebid-filtering.json +++ b/exchange/exchangetest/request-ext-prebid-filtering.json @@ -174,6 +174,9 @@ "ext": { "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video" } } diff --git a/exchange/exchangetest/request-imp-ext-prebid-filtering.json b/exchange/exchangetest/request-imp-ext-prebid-filtering.json index fb8e0892aa5..94ac6ec057f 100644 --- a/exchange/exchangetest/request-imp-ext-prebid-filtering.json +++ b/exchange/exchangetest/request-imp-ext-prebid-filtering.json @@ -124,6 +124,9 @@ "ext": { "origbidcpm": 0.3, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video" } } diff --git a/exchange/exchangetest/request-multi-bidders-debug-info.json b/exchange/exchangetest/request-multi-bidders-debug-info.json index 8f41286b3eb..6eeaf58dba1 100644 --- a/exchange/exchangetest/request-multi-bidders-debug-info.json +++ b/exchange/exchangetest/request-multi-bidders-debug-info.json @@ -154,6 +154,9 @@ "ext": { "origbidcpm": 12.00, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "targeting": { "hb_bidder": "appnexus", "hb_bidder_appnexus": "appnexus", diff --git a/exchange/exchangetest/request-multi-bidders-one-no-resp.json b/exchange/exchangetest/request-multi-bidders-one-no-resp.json index c1fe595ad5f..fc55ebd369d 100644 --- a/exchange/exchangetest/request-multi-bidders-one-no-resp.json +++ b/exchange/exchangetest/request-multi-bidders-one-no-resp.json @@ -126,6 +126,9 @@ "ext": { "origbidcpm": 12.00, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "targeting": { "hb_bidder": "appnexus", "hb_bidder_appnexus": "appnexus", diff --git a/exchange/exchangetest/targeting-cache-vast-banner.json b/exchange/exchangetest/targeting-cache-vast-banner.json index 43b65e59c12..91fb5817c7a 100644 --- a/exchange/exchangetest/targeting-cache-vast-banner.json +++ b/exchange/exchangetest/targeting-cache-vast-banner.json @@ -87,6 +87,9 @@ "ext": { "origbidcpm": 0.01, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "banner", "targeting": { "hb_bidder": "appnexus", diff --git a/exchange/exchangetest/targeting-cache-vast.json b/exchange/exchangetest/targeting-cache-vast.json index 2f59ba30878..1c7cb636995 100644 --- a/exchange/exchangetest/targeting-cache-vast.json +++ b/exchange/exchangetest/targeting-cache-vast.json @@ -88,6 +88,9 @@ "ext": { "origbidcpm": 0.01, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "cache": { "bids": { "cacheId": "0", diff --git a/exchange/exchangetest/targeting-cache-zero.json b/exchange/exchangetest/targeting-cache-zero.json index ea062fbe277..7f94f73f52d 100644 --- a/exchange/exchangetest/targeting-cache-zero.json +++ b/exchange/exchangetest/targeting-cache-zero.json @@ -90,6 +90,9 @@ "ext": { "origbidcpm": 0.01, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "cache": { "bids": { "cacheId": "0", diff --git a/exchange/exchangetest/targeting-mobile.json b/exchange/exchangetest/targeting-mobile.json index 914a557bca9..9cc2b1ebbc0 100644 --- a/exchange/exchangetest/targeting-mobile.json +++ b/exchange/exchangetest/targeting-mobile.json @@ -152,6 +152,9 @@ "ext": { "origbidcpm": 0.51, "prebid": { + "meta": { + "adaptercode": "audienceNetwork" + }, "type": "video", "targeting": { "hb_bidder_audienceNe": "audienceNetwork", @@ -179,6 +182,9 @@ "ext": { "origbidcpm": 0.71, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video", "targeting": { "hb_bidder": "appnexus", @@ -207,6 +213,9 @@ "ext": { "origbidcpm": 0.21, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video" } } @@ -221,6 +230,9 @@ "ext": { "origbidcpm": 0.61, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video", "targeting": { "hb_bidder": "appnexus", diff --git a/exchange/exchangetest/targeting-no-winners.json b/exchange/exchangetest/targeting-no-winners.json index 6ab69fb4773..92526022f38 100644 --- a/exchange/exchangetest/targeting-no-winners.json +++ b/exchange/exchangetest/targeting-no-winners.json @@ -152,6 +152,9 @@ "ext": { "origbidcpm": 0.51, "prebid": { + "meta": { + "adaptercode": "audienceNetwork" + }, "type": "video", "targeting": { "hb_bidder_audienceNe": "audienceNetwork", @@ -178,6 +181,9 @@ "ext": { "origbidcpm": 0.71, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video", "targeting": { "hb_bidder_appnexus": "appnexus", @@ -199,6 +205,9 @@ "ext": { "origbidcpm": 0.21, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video" } } @@ -213,6 +222,9 @@ "ext": { "origbidcpm": 0.61, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video", "targeting": { "hb_bidder_appnexus": "appnexus", diff --git a/exchange/exchangetest/targeting-only-winners.json b/exchange/exchangetest/targeting-only-winners.json index f9f96515452..5e6d43ce236 100644 --- a/exchange/exchangetest/targeting-only-winners.json +++ b/exchange/exchangetest/targeting-only-winners.json @@ -152,6 +152,9 @@ "ext": { "origbidcpm": 0.51, "prebid": { + "meta": { + "adaptercode": "audienceNetwork" + }, "type": "video" } } @@ -171,6 +174,9 @@ "ext": { "origbidcpm": 0.71, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video", "targeting": { "hb_bidder": "appnexus", @@ -192,6 +198,9 @@ "ext": { "origbidcpm": 0.21, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video" } } @@ -206,6 +215,9 @@ "ext": { "origbidcpm": 0.61, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video", "targeting": { "hb_bidder": "appnexus", diff --git a/exchange/exchangetest/targeting-with-winners.json b/exchange/exchangetest/targeting-with-winners.json index d1a0f49f862..14ad8ef4b4e 100644 --- a/exchange/exchangetest/targeting-with-winners.json +++ b/exchange/exchangetest/targeting-with-winners.json @@ -152,6 +152,9 @@ "ext": { "origbidcpm": 0.51, "prebid": { + "meta": { + "adaptercode": "audienceNetwork" + }, "type": "video", "targeting": { "hb_bidder_audienceNe": "audienceNetwork", @@ -178,6 +181,9 @@ "ext": { "origbidcpm": 0.71, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video", "targeting": { "hb_bidder": "appnexus", @@ -204,6 +210,9 @@ "ext": { "origbidcpm": 0.21, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video" } } @@ -218,6 +227,9 @@ "ext": { "origbidcpm": 0.61, "prebid": { + "meta": { + "adaptercode": "appnexus" + }, "type": "video", "targeting": { "hb_bidder": "appnexus", From 905436f335c9cbb20a3a827adb64a87aa6a25627 Mon Sep 17 00:00:00 2001 From: AlexBVolcy <74930484+AlexBVolcy@users.noreply.github.com> Date: Thu, 16 Nov 2023 09:59:53 -0800 Subject: [PATCH 212/268] Add debug flag to cookie sync endpoint (#3107) --- endpoints/cookie_sync.go | 61 +++++++++++++++--- endpoints/cookie_sync_test.go | 69 ++++++++++++++++++-- usersync/chooser.go | 35 ++++++----- usersync/chooser_test.go | 114 ++++++++++++++++++++++++++-------- 4 files changed, 226 insertions(+), 53 deletions(-) diff --git a/endpoints/cookie_sync.go b/endpoints/cookie_sync.go index bbf91330be5..f2ffb2fb4d2 100644 --- a/endpoints/cookie_sync.go +++ b/endpoints/cookie_sync.go @@ -61,7 +61,7 @@ func NewCookieSyncEndpoint( } return &cookieSyncEndpoint{ - chooser: usersync.NewChooser(syncersByBidder), + chooser: usersync.NewChooser(syncersByBidder, bidderHashSet), config: config, privacyConfig: usersyncPrivacyConfig{ gdprConfig: config.GDPR, @@ -98,17 +98,18 @@ func (c *cookieSyncEndpoint) Handle(w http.ResponseWriter, r *http.Request, _ ht usersync.SyncHostCookie(r, cookie, &c.config.HostCookie) result := c.chooser.Choose(request, cookie) + switch result.Status { case usersync.StatusBlockedByUserOptOut: c.metrics.RecordCookieSync(metrics.CookieSyncOptOut) c.handleError(w, errCookieSyncOptOut, http.StatusUnauthorized) - case usersync.StatusBlockedByGDPR: + case usersync.StatusBlockedByPrivacy: c.metrics.RecordCookieSync(metrics.CookieSyncGDPRHostCookieBlocked) - c.handleResponse(w, request.SyncTypeFilter, cookie, privacyMacros, nil) + c.handleResponse(w, request.SyncTypeFilter, cookie, privacyMacros, nil, result.BiddersEvaluated, request.Debug) case usersync.StatusOK: c.metrics.RecordCookieSync(metrics.CookieSyncOK) c.writeSyncerMetrics(result.BiddersEvaluated) - c.handleResponse(w, request.SyncTypeFilter, cookie, privacyMacros, result.SyncersChosen) + c.handleResponse(w, request.SyncTypeFilter, cookie, privacyMacros, result.SyncersChosen, result.BiddersEvaluated, request.Debug) } } @@ -172,6 +173,7 @@ func (c *cookieSyncEndpoint) parseRequest(r *http.Request) (usersync.Request, ma Enabled: (request.CooperativeSync != nil && *request.CooperativeSync) || (request.CooperativeSync == nil && c.config.UserSync.Cooperative.EnabledByDefault), PriorityGroups: c.config.UserSync.PriorityGroups, }, + Debug: request.Debug, Limit: request.Limit, Privacy: usersyncPrivacy{ gdprPermissions: gdprPerms, @@ -387,9 +389,7 @@ func (c *cookieSyncEndpoint) writeSyncerMetrics(biddersEvaluated []usersync.Bidd switch bidder.Status { case usersync.StatusOK: c.metrics.RecordSyncerRequest(bidder.SyncerKey, metrics.SyncerCookieSyncOK) - case usersync.StatusBlockedByGDPR: - c.metrics.RecordSyncerRequest(bidder.SyncerKey, metrics.SyncerCookieSyncPrivacyBlocked) - case usersync.StatusBlockedByCCPA: + case usersync.StatusBlockedByPrivacy: c.metrics.RecordSyncerRequest(bidder.SyncerKey, metrics.SyncerCookieSyncPrivacyBlocked) case usersync.StatusAlreadySynced: c.metrics.RecordSyncerRequest(bidder.SyncerKey, metrics.SyncerCookieSyncAlreadySynced) @@ -399,7 +399,7 @@ func (c *cookieSyncEndpoint) writeSyncerMetrics(biddersEvaluated []usersync.Bidd } } -func (c *cookieSyncEndpoint) handleResponse(w http.ResponseWriter, tf usersync.SyncTypeFilter, co *usersync.Cookie, m macros.UserSyncPrivacy, s []usersync.SyncerChoice) { +func (c *cookieSyncEndpoint) handleResponse(w http.ResponseWriter, tf usersync.SyncTypeFilter, co *usersync.Cookie, m macros.UserSyncPrivacy, s []usersync.SyncerChoice, biddersEvaluated []usersync.BidderEvaluation, debug bool) { status := "no_cookie" if co.HasAnyLiveSyncs() { status = "ok" @@ -429,6 +429,24 @@ func (c *cookieSyncEndpoint) handleResponse(w http.ResponseWriter, tf usersync.S }) } + if debug { + biddersSeen := make(map[string]struct{}) + var debugInfo []cookieSyncResponseDebug + for _, bidderEval := range biddersEvaluated { + var debugResponse cookieSyncResponseDebug + debugResponse.Bidder = bidderEval.Bidder + if bidderEval.Status == usersync.StatusDuplicate && biddersSeen[bidderEval.Bidder] == struct{}{} { + debugResponse.Error = getDebugMessage(bidderEval.Status) + " synced as " + bidderEval.SyncerKey + debugInfo = append(debugInfo, debugResponse) + } else if bidderEval.Status != usersync.StatusOK { + debugResponse.Error = getDebugMessage(bidderEval.Status) + debugInfo = append(debugInfo, debugResponse) + } + biddersSeen[bidderEval.Bidder] = struct{}{} + } + response.Debug = debugInfo + } + c.pbsAnalytics.LogCookieSyncObject(&analytics.CookieSyncObject{ Status: http.StatusOK, BidderStatus: mapBidderStatusToAnalytics(response.BidderStatus), @@ -456,6 +474,26 @@ func mapBidderStatusToAnalytics(from []cookieSyncResponseBidder) []*analytics.Co return to } +func getDebugMessage(status usersync.Status) string { + switch status { + case usersync.StatusAlreadySynced: + return "Already in sync" + case usersync.StatusBlockedByPrivacy: + return "Rejected by privacy" + case usersync.StatusBlockedByUserOptOut: + return "Status blocked by user opt out" + case usersync.StatusDuplicate: + return "Duplicate bidder" + case usersync.StatusUnknownBidder: + return "Unsupported bidder" + case usersync.StatusUnconfiguredBidder: + return "No sync config" + case usersync.StatusTypeNotSupported: + return "Type not supported" + } + return "" +} + type cookieSyncRequest struct { Bidders []string `json:"bidders"` GDPR *int `json:"gdpr"` @@ -467,6 +505,7 @@ type cookieSyncRequest struct { CooperativeSync *bool `json:"coopSync"` FilterSettings *cookieSyncRequestFilterSettings `json:"filterSettings"` Account string `json:"account"` + Debug bool `json:"debug"` } type cookieSyncRequestFilterSettings struct { @@ -482,6 +521,7 @@ type cookieSyncRequestFilter struct { type cookieSyncResponse struct { Status string `json:"status"` BidderStatus []cookieSyncResponseBidder `json:"bidder_status"` + Debug []cookieSyncResponseDebug `json:"debug,omitempty"` } type cookieSyncResponseBidder struct { @@ -496,6 +536,11 @@ type cookieSyncResponseSync struct { SupportCORS bool `json:"supportCORS,omitempty"` } +type cookieSyncResponseDebug struct { + Bidder string `json:"bidder"` + Error string `json:"error,omitempty"` +} + type usersyncPrivacyConfig struct { gdprConfig config.GDPR gdprPermissionsBuilder gdpr.PermissionsBuilder diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go index 956123006ca..182a6666436 100644 --- a/endpoints/cookie_sync_test.go +++ b/endpoints/cookie_sync_test.go @@ -45,6 +45,7 @@ func TestNewCookieSyncEndpoint(t *testing.T) { analytics = MockAnalyticsRunner{} fetcher = FakeAccountsFetcher{} bidders = map[string]openrtb_ext.BidderName{"bidderA": openrtb_ext.BidderName("bidderA"), "bidderB": openrtb_ext.BidderName("bidderB")} + biddersKnown = map[string]struct{}{"bidderA": {}, "bidderB": {}} ) endpoint := NewCookieSyncEndpoint( @@ -65,7 +66,7 @@ func TestNewCookieSyncEndpoint(t *testing.T) { result := endpoint.(*cookieSyncEndpoint) expected := &cookieSyncEndpoint{ - chooser: usersync.NewChooser(syncersByBidder), + chooser: usersync.NewChooser(syncersByBidder, biddersKnown), config: &config.Configuration{ UserSync: configUserSync, HostCookie: configHostCookie, @@ -231,7 +232,7 @@ func TestCookieSyncHandle(t *testing.T) { givenCookie: cookieWithSyncs, givenBody: strings.NewReader(`{}`), givenChooserResult: usersync.Result{ - Status: usersync.StatusBlockedByGDPR, + Status: usersync.StatusBlockedByPrivacy, BiddersEvaluated: []usersync.BidderEvaluation{{Bidder: "a", SyncerKey: "aSyncer", Status: usersync.StatusOK}}, SyncersChosen: []usersync.SyncerChoice{{Bidder: "a", Syncer: &syncer}}, }, @@ -249,6 +250,38 @@ func TestCookieSyncHandle(t *testing.T) { a.On("LogCookieSyncObject", &expected).Once() }, }, + { + description: "Debug Check", + givenCookie: cookieWithSyncs, + givenBody: strings.NewReader(`{"debug": true}`), + givenChooserResult: usersync.Result{ + Status: usersync.StatusOK, + BiddersEvaluated: []usersync.BidderEvaluation{{Bidder: "a", SyncerKey: "aSyncer", Status: usersync.StatusAlreadySynced}}, + SyncersChosen: []usersync.SyncerChoice{{Bidder: "a", Syncer: &syncer}}, + }, + expectedStatusCode: 200, + expectedBody: `{"status":"ok","bidder_status":[` + + `{"bidder":"a","no_cookie":true,"usersync":{"url":"aURL","type":"redirect","supportCORS":true}}` + + `],"debug":[{"bidder":"a","error":"Already in sync"}]}` + "\n", + setMetricsExpectations: func(m *metrics.MetricsEngineMock) { + m.On("RecordCookieSync", metrics.CookieSyncOK).Once() + m.On("RecordSyncerRequest", "aSyncer", metrics.SyncerCookieSyncAlreadySynced).Once() + }, + setAnalyticsExpectations: func(a *MockAnalyticsRunner) { + expected := analytics.CookieSyncObject{ + Status: 200, + Errors: nil, + BidderStatus: []*analytics.CookieSyncBidder{ + { + BidderCode: "a", + NoCookie: true, + UsersyncInfo: &analytics.UsersyncInfo{URL: "aURL", Type: "redirect", SupportCORS: true}, + }, + }, + } + a.On("LogCookieSyncObject", &expected).Once() + }, + }, } for _, test := range testCases { @@ -1508,14 +1541,14 @@ func TestCookieSyncWriteBidderMetrics(t *testing.T) { }, { description: "One - Blocked By GDPR", - given: []usersync.BidderEvaluation{{Bidder: "a", SyncerKey: "aSyncer", Status: usersync.StatusBlockedByGDPR}}, + given: []usersync.BidderEvaluation{{Bidder: "a", SyncerKey: "aSyncer", Status: usersync.StatusBlockedByPrivacy}}, setExpectations: func(m *metrics.MetricsEngineMock) { m.On("RecordSyncerRequest", "aSyncer", metrics.SyncerCookieSyncPrivacyBlocked).Once() }, }, { description: "One - Blocked By CCPA", - given: []usersync.BidderEvaluation{{Bidder: "a", SyncerKey: "aSyncer", Status: usersync.StatusBlockedByCCPA}}, + given: []usersync.BidderEvaluation{{Bidder: "a", SyncerKey: "aSyncer", Status: usersync.StatusBlockedByPrivacy}}, setExpectations: func(m *metrics.MetricsEngineMock) { m.On("RecordSyncerRequest", "aSyncer", metrics.SyncerCookieSyncPrivacyBlocked).Once() }, @@ -1580,10 +1613,21 @@ func TestCookieSyncHandleResponse(t *testing.T) { syncerWithError := MockSyncer{} syncerWithError.On("GetSync", syncTypeExpected, privacyMacros).Return(syncWithError, errors.New("anyError")).Maybe() + bidderEvalForDebug := []usersync.BidderEvaluation{ + {Bidder: "Bidder1", Status: usersync.StatusAlreadySynced}, + {Bidder: "Bidder2", Status: usersync.StatusUnknownBidder}, + {Bidder: "Bidder3", Status: usersync.StatusUnconfiguredBidder}, + {Bidder: "Bidder4", Status: usersync.StatusBlockedByPrivacy}, + {Bidder: "Bidder5", Status: usersync.StatusTypeNotSupported}, + {Bidder: "Bidder6", Status: usersync.StatusBlockedByUserOptOut}, + {Bidder: "BidderA", Status: usersync.StatusDuplicate, SyncerKey: "syncerB"}, + } + testCases := []struct { description string givenCookieHasSyncs bool givenSyncersChosen []usersync.SyncerChoice + givenDebug bool expectedJSON string expectedAnalytics analytics.CookieSyncObject }{ @@ -1661,6 +1705,14 @@ func TestCookieSyncHandleResponse(t *testing.T) { expectedJSON: `{"status":"no_cookie","bidder_status":[]}` + "\n", expectedAnalytics: analytics.CookieSyncObject{Status: 200, BidderStatus: []*analytics.CookieSyncBidder{}}, }, + { + description: "Debug is true, should see all rejected bidder eval statuses in response", + givenCookieHasSyncs: true, + givenDebug: true, + givenSyncersChosen: []usersync.SyncerChoice{}, + expectedJSON: `{"status":"ok","bidder_status":[],"debug":[{"bidder":"Bidder1","error":"Already in sync"},{"bidder":"Bidder2","error":"Unsupported bidder"},{"bidder":"Bidder3","error":"No sync config"},{"bidder":"Bidder4","error":"Rejected by privacy"},{"bidder":"Bidder5","error":"Type not supported"},{"bidder":"Bidder6","error":"Status blocked by user opt out"},{"bidder":"BidderA","error":"Duplicate bidder synced as syncerB"}]}` + "\n", + expectedAnalytics: analytics.CookieSyncObject{Status: 200, BidderStatus: []*analytics.CookieSyncBidder{}}, + }, } for _, test := range testCases { @@ -1676,7 +1728,14 @@ func TestCookieSyncHandleResponse(t *testing.T) { writer := httptest.NewRecorder() endpoint := cookieSyncEndpoint{pbsAnalytics: &mockAnalytics} - endpoint.handleResponse(writer, syncTypeFilter, cookie, privacyMacros, test.givenSyncersChosen) + + var bidderEval []usersync.BidderEvaluation + if test.givenDebug { + bidderEval = bidderEvalForDebug + } else { + bidderEval = []usersync.BidderEvaluation{} + } + endpoint.handleResponse(writer, syncTypeFilter, cookie, privacyMacros, test.givenSyncersChosen, bidderEval, test.givenDebug) if assert.Equal(t, writer.Code, http.StatusOK, test.description+":http_status") { assert.Equal(t, writer.Header().Get("Content-Type"), "application/json; charset=utf-8", test.description+":http_header") diff --git a/usersync/chooser.go b/usersync/chooser.go index 3b97359e1ce..0615be56c3d 100644 --- a/usersync/chooser.go +++ b/usersync/chooser.go @@ -14,8 +14,9 @@ type Chooser interface { } // NewChooser returns a new instance of the standard chooser implementation. -func NewChooser(bidderSyncerLookup map[string]Syncer) Chooser { +func NewChooser(bidderSyncerLookup map[string]Syncer, biddersKnown map[string]struct{}) Chooser { bidders := make([]string, 0, len(bidderSyncerLookup)) + for k := range bidderSyncerLookup { bidders = append(bidders, k) } @@ -25,6 +26,7 @@ func NewChooser(bidderSyncerLookup map[string]Syncer) Chooser { biddersAvailable: bidders, bidderChooser: standardBidderChooser{shuffler: randomShuffler{}}, normalizeValidBidderName: openrtb_ext.NormalizeBidderName, + biddersKnown: biddersKnown, } } @@ -35,6 +37,7 @@ type Request struct { Limit int Privacy Privacy SyncTypeFilter SyncTypeFilter + Debug bool } // Cooperative specifies the settings for cooperative syncing for a given request, where bidders @@ -74,13 +77,6 @@ const ( // StatusBlockedByUserOptOut specifies a user's cookie explicitly signals an opt-out. StatusBlockedByUserOptOut - // StatusBlockedByGDPR specifies a user's GDPR TCF consent explicitly forbids host cookies - // or specific bidder syncing. - StatusBlockedByGDPR - - // StatusBlockedByCCPA specifies a user's CCPA consent explicitly forbids bidder syncing. - StatusBlockedByCCPA - // StatusAlreadySynced specifies a user's cookie has an existing non-expired sync for a specific bidder. StatusAlreadySynced @@ -95,6 +91,9 @@ const ( // StatusBlockedByPrivacy specifies a bidder sync url is not allowed by privacy activities StatusBlockedByPrivacy + + // StatusUnconfiguredBidder refers to a bidder who hasn't been configured to have a syncer key, but is known by Prebid Server + StatusUnconfiguredBidder ) // Privacy determines which privacy policies will be enforced for a user sync request. @@ -111,6 +110,7 @@ type standardChooser struct { biddersAvailable []string bidderChooser bidderChooser normalizeValidBidderName func(name string) (openrtb_ext.BidderName, bool) + biddersKnown map[string]struct{} } // Choose randomly selects user syncers which are permitted by the user's privacy settings and @@ -121,10 +121,11 @@ func (c standardChooser) Choose(request Request, cookie *Cookie) Result { } if !request.Privacy.GDPRAllowsHostCookie() { - return Result{Status: StatusBlockedByGDPR} + return Result{Status: StatusBlockedByPrivacy} } syncersSeen := make(map[string]struct{}) + biddersSeen := make(map[string]struct{}) limitDisabled := request.Limit <= 0 biddersEvaluated := make([]BidderEvaluation, 0) @@ -132,12 +133,16 @@ func (c standardChooser) Choose(request Request, cookie *Cookie) Result { bidders := c.bidderChooser.choose(request.Bidders, c.biddersAvailable, request.Cooperative) for i := 0; i < len(bidders) && (limitDisabled || len(syncersChosen) < request.Limit); i++ { + if _, ok := biddersSeen[bidders[i]]; ok { + continue + } syncer, evaluation := c.evaluate(bidders[i], syncersSeen, request.SyncTypeFilter, request.Privacy, cookie) biddersEvaluated = append(biddersEvaluated, evaluation) if evaluation.Status == StatusOK { syncersChosen = append(syncersChosen, SyncerChoice{Bidder: bidders[i], Syncer: syncer}) } + biddersSeen[bidders[i]] = struct{}{} } return Result{Status: StatusOK, BiddersEvaluated: biddersEvaluated, SyncersChosen: syncersChosen} @@ -151,7 +156,11 @@ func (c standardChooser) evaluate(bidder string, syncersSeen map[string]struct{} syncer, exists := c.bidderSyncerLookup[bidderNormalized.String()] if !exists { - return nil, BidderEvaluation{Status: StatusUnknownBidder, Bidder: bidder} + if _, ok := c.biddersKnown[bidder]; !ok { + return nil, BidderEvaluation{Status: StatusUnknownBidder, Bidder: bidder} + } else { + return nil, BidderEvaluation{Status: StatusUnconfiguredBidder, Bidder: bidder} + } } _, seen := syncersSeen[syncer.Key()] @@ -174,11 +183,7 @@ func (c standardChooser) evaluate(bidder string, syncersSeen map[string]struct{} } if !privacy.GDPRAllowsBidderSync(bidderNormalized.String()) { - return nil, BidderEvaluation{Status: StatusBlockedByGDPR, Bidder: bidder, SyncerKey: syncer.Key()} - } - - if !privacy.CCPAAllowsBidderSync(bidderNormalized.String()) { - return nil, BidderEvaluation{Status: StatusBlockedByCCPA, Bidder: bidder, SyncerKey: syncer.Key()} + return nil, BidderEvaluation{Status: StatusBlockedByPrivacy, Bidder: bidder, SyncerKey: syncer.Key()} } return syncer, BidderEvaluation{Status: StatusOK, Bidder: bidder, SyncerKey: syncer.Key()} diff --git a/usersync/chooser_test.go b/usersync/chooser_test.go index e73122b784a..4e5d4acdc9c 100644 --- a/usersync/chooser_test.go +++ b/usersync/chooser_test.go @@ -40,7 +40,7 @@ func TestNewChooser(t *testing.T) { } for _, test := range testCases { - chooser, _ := NewChooser(test.bidderSyncerLookup).(standardChooser) + chooser, _ := NewChooser(test.bidderSyncerLookup, make(map[string]struct{})).(standardChooser) assert.ElementsMatch(t, test.expectedBiddersAvailable, chooser.biddersAvailable, test.description) } } @@ -49,12 +49,18 @@ func TestChooserChoose(t *testing.T) { fakeSyncerA := fakeSyncer{key: "keyA", supportsIFrame: true} fakeSyncerB := fakeSyncer{key: "keyB", supportsIFrame: true} fakeSyncerC := fakeSyncer{key: "keyC", supportsIFrame: false} - bidderSyncerLookup := map[string]Syncer{"a": fakeSyncerA, "b": fakeSyncerB, "c": fakeSyncerC, "appnexus": fakeSyncerA} + + duplicateSyncer := fakeSyncer{key: "syncerForDuplicateTest", supportsIFrame: true} + bidderSyncerLookup := map[string]Syncer{"a": fakeSyncerA, "b": fakeSyncerB, "c": fakeSyncerC, "appnexus": fakeSyncerA, "d": duplicateSyncer, "e": duplicateSyncer} + biddersKnown := map[string]struct{}{"a": {}, "b": {}, "c": {}} + normalizedBidderNamesLookup := func(name string) (openrtb_ext.BidderName, bool) { return openrtb_ext.BidderName(name), true } + syncerChoiceA := SyncerChoice{Bidder: "a", Syncer: fakeSyncerA} syncerChoiceB := SyncerChoice{Bidder: "b", Syncer: fakeSyncerB} + syncTypeFilter := SyncTypeFilter{ IFrame: NewUniformBidderFilter(BidderFilterModeInclude), Redirect: NewUniformBidderFilter(BidderFilterModeExclude)} @@ -94,7 +100,7 @@ func TestChooserChoose(t *testing.T) { givenCookie: Cookie{}, bidderNamesLookup: normalizedBidderNamesLookup, expected: Result{ - Status: StatusBlockedByGDPR, + Status: StatusBlockedByPrivacy, BiddersEvaluated: nil, SyncersChosen: nil, }, @@ -144,6 +150,21 @@ func TestChooserChoose(t *testing.T) { SyncersChosen: []SyncerChoice{}, }, }, + { + description: "One Bidder - No Sync - Unknown", + givenRequest: Request{ + Privacy: &fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + Limit: 0, + }, + givenChosenBidders: []string{"unknown"}, + givenCookie: Cookie{}, + bidderNamesLookup: normalizedBidderNamesLookup, + expected: Result{ + Status: StatusOK, + BiddersEvaluated: []BidderEvaluation{{Bidder: "unknown", Status: StatusUnknownBidder}}, + SyncersChosen: []SyncerChoice{}, + }, + }, { description: "Many Bidders - All Sync - Limit Disabled With 0", givenRequest: Request{ @@ -219,6 +240,59 @@ func TestChooserChoose(t *testing.T) { SyncersChosen: []SyncerChoice{syncerChoiceA}, }, }, + { + description: "Chosen bidders have duplicate syncer keys, the one that comes first should be labled OK", + givenRequest: Request{ + Privacy: &fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + Limit: 0, + }, + givenChosenBidders: []string{"d", "e"}, + givenCookie: Cookie{}, + bidderNamesLookup: normalizedBidderNamesLookup, + expected: Result{ + Status: StatusOK, + BiddersEvaluated: []BidderEvaluation{ + {Bidder: "d", SyncerKey: "syncerForDuplicateTest", Status: StatusOK}, + {Bidder: "e", SyncerKey: "syncerForDuplicateTest", Status: StatusDuplicate}, + }, + SyncersChosen: []SyncerChoice{{Bidder: "d", Syncer: duplicateSyncer}}, + }, + }, + { + description: "Chosen bidders have duplicate syncer keys, the one that comes first should be labled OK (reverse)", + givenRequest: Request{ + Privacy: &fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + Limit: 0, + }, + givenChosenBidders: []string{"e", "d"}, + givenCookie: Cookie{}, + bidderNamesLookup: normalizedBidderNamesLookup, + expected: Result{ + Status: StatusOK, + BiddersEvaluated: []BidderEvaluation{ + {Bidder: "e", SyncerKey: "syncerForDuplicateTest", Status: StatusOK}, + {Bidder: "d", SyncerKey: "syncerForDuplicateTest", Status: StatusDuplicate}, + }, + SyncersChosen: []SyncerChoice{{Bidder: "e", Syncer: duplicateSyncer}}, + }, + }, + { + description: "Same bidder name, no duplicate warning", + givenRequest: Request{ + Privacy: &fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, + Limit: 0, + }, + givenChosenBidders: []string{"a", "a"}, + givenCookie: Cookie{}, + bidderNamesLookup: normalizedBidderNamesLookup, + expected: Result{ + Status: StatusOK, + BiddersEvaluated: []BidderEvaluation{ + {Bidder: "a", SyncerKey: fakeSyncerA.key, Status: StatusOK}, + }, + SyncersChosen: []SyncerChoice{{Bidder: "a", Syncer: fakeSyncerA}}, + }, + }, { description: "Unknown Bidder", givenRequest: Request{ @@ -286,6 +360,7 @@ func TestChooserChoose(t *testing.T) { biddersAvailable: biddersAvailable, bidderChooser: mockBidderChooser, normalizeValidBidderName: test.bidderNamesLookup, + biddersKnown: biddersKnown, } result := chooser.Choose(test.givenRequest, &test.givenCookie) @@ -296,7 +371,10 @@ func TestChooserChoose(t *testing.T) { func TestChooserEvaluate(t *testing.T) { fakeSyncerA := fakeSyncer{key: "keyA", supportsIFrame: true} fakeSyncerB := fakeSyncer{key: "keyB", supportsIFrame: false} + + biddersKnown := map[string]struct{}{"a": {}, "b": {}, "unconfigured": {}} bidderSyncerLookup := map[string]Syncer{"a": fakeSyncerA, "b": fakeSyncerB, "appnexus": fakeSyncerA, "suntContent": fakeSyncerA} + syncTypeFilter := SyncTypeFilter{ IFrame: NewUniformBidderFilter(BidderFilterModeInclude), Redirect: NewUniformBidderFilter(BidderFilterModeExclude)} @@ -401,19 +479,7 @@ func TestChooserEvaluate(t *testing.T) { givenSyncTypeFilter: syncTypeFilter, normalizedBidderNamesLookup: normalizedBidderNamesLookup, expectedSyncer: nil, - expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusBlockedByGDPR}, - }, - { - description: "Blocked By CCPA", - givenBidder: "a", - normalisedBidderName: "a", - givenSyncersSeen: map[string]struct{}{}, - givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: false, activityAllowUserSync: true}, - givenCookie: cookieNeedsSync, - givenSyncTypeFilter: syncTypeFilter, - normalizedBidderNamesLookup: normalizedBidderNamesLookup, - expectedSyncer: nil, - expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusBlockedByCCPA}, + expectedEvaluation: BidderEvaluation{Bidder: "a", SyncerKey: "keyA", Status: StatusBlockedByPrivacy}, }, { description: "Blocked By activity control", @@ -463,25 +529,23 @@ func TestChooserEvaluate(t *testing.T) { givenSyncTypeFilter: syncTypeFilter, normalizedBidderNamesLookup: openrtb_ext.NormalizeBidderName, expectedSyncer: nil, - expectedEvaluation: BidderEvaluation{Bidder: "AppNexus", SyncerKey: "keyA", Status: StatusBlockedByGDPR}, + expectedEvaluation: BidderEvaluation{Bidder: "AppNexus", SyncerKey: "keyA", Status: StatusBlockedByPrivacy}, }, { - description: "Case Insensitivity Check For Blocked By CCPA", - givenBidder: "AppNexus", - normalisedBidderName: "appnexus", + description: "Unconfigured Bidder", + givenBidder: "unconfigured", + normalizedBidderNamesLookup: normalizedBidderNamesLookup, givenSyncersSeen: map[string]struct{}{}, - givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: false, activityAllowUserSync: true}, + givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, givenCookie: cookieNeedsSync, - givenSyncTypeFilter: syncTypeFilter, - normalizedBidderNamesLookup: openrtb_ext.NormalizeBidderName, expectedSyncer: nil, - expectedEvaluation: BidderEvaluation{Bidder: "AppNexus", SyncerKey: "keyA", Status: StatusBlockedByCCPA}, + expectedEvaluation: BidderEvaluation{Bidder: "unconfigured", Status: StatusUnconfiguredBidder}, }, } for _, test := range testCases { t.Run(test.description, func(t *testing.T) { - chooser, _ := NewChooser(bidderSyncerLookup).(standardChooser) + chooser, _ := NewChooser(bidderSyncerLookup, biddersKnown).(standardChooser) chooser.normalizeValidBidderName = test.normalizedBidderNamesLookup sync, evaluation := chooser.evaluate(test.givenBidder, test.givenSyncersSeen, test.givenSyncTypeFilter, &test.givenPrivacy, &test.givenCookie) From 6a20c0e1945df1a46690a26aaf79183b321318fb Mon Sep 17 00:00:00 2001 From: Veronika Solovei Date: Thu, 16 Nov 2023 10:16:36 -0800 Subject: [PATCH 213/268] Privacy scrubber refactoring (#3108) --- exchange/utils.go | 82 ++-- exchange/utils_test.go | 324 +++++++++----- ortb/clone.go | 134 ++++++ ortb/clone_test.go | 378 ++++++++++++++++ privacy/enforcement.go | 92 ---- privacy/enforcement_test.go | 393 ----------------- privacy/scrubber.go | 315 +++++--------- privacy/scrubber_test.go | 840 +++++++++++++----------------------- 8 files changed, 1186 insertions(+), 1372 deletions(-) delete mode 100644 privacy/enforcement.go delete mode 100644 privacy/enforcement_test.go diff --git a/exchange/utils.go b/exchange/utils.go index 150fac3ca53..dfe1fe448ba 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -21,6 +21,7 @@ import ( "github.com/prebid/prebid-server/v2/gdpr" "github.com/prebid/prebid-server/v2/metrics" "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/ortb" "github.com/prebid/prebid-server/v2/privacy" "github.com/prebid/prebid-server/v2/privacy/ccpa" "github.com/prebid/prebid-server/v2/privacy/lmt" @@ -153,11 +154,6 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, // bidder level privacy policies for _, bidderRequest := range allBidderRequests { - privacyEnforcement := privacy.Enforcement{ - COPPA: coppa, - LMT: lmt, - } - // fetchBids activity scopedName := privacy.Component{Type: privacy.ComponentTypeBidder, Name: bidderRequest.BidderName.String()} fetchBidsActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityFetchBids, scopedName, privacy.NewRequestFromBidRequest(*req)) @@ -180,46 +176,56 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, } } + ipConf := privacy.IPConf{IPV6: auctionReq.Account.Privacy.IPv6Config, IPV4: auctionReq.Account.Privacy.IPv4Config} + + // FPD should be applied before policies, otherwise it overrides policies and activities restricted data + applyFPD(auctionReq.FirstPartyData, bidderRequest) + + reqWrapper := cloneBidderReq(bidderRequest.BidRequest) + passIDActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitUserFPD, scopedName, privacy.NewRequestFromBidRequest(*req)) if !passIDActivityAllowed { - privacyEnforcement.UFPD = true + //UFPD + privacy.ScrubUserFPD(reqWrapper) } else { // run existing policies (GDPR, CCPA, COPPA, LMT) // potentially block passing IDs based on GDPR - if gdprEnforced { - if gdprErr == nil { - privacyEnforcement.GDPRID = !auctionPermissions.PassID - } else { - privacyEnforcement.GDPRID = true - } + if gdprEnforced && (gdprErr != nil || !auctionPermissions.PassID) { + privacy.ScrubGdprID(reqWrapper) } // potentially block passing IDs based on CCPA - privacyEnforcement.CCPA = ccpaEnforcer.ShouldEnforce(bidderRequest.BidderName.String()) + if ccpaEnforcer.ShouldEnforce(bidderRequest.BidderName.String()) { + privacy.ScrubDeviceIDsIPsUserDemoExt(reqWrapper, ipConf, "eids", false) + } } passGeoActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitPreciseGeo, scopedName, privacy.NewRequestFromBidRequest(*req)) if !passGeoActivityAllowed { - privacyEnforcement.PreciseGeo = true + privacy.ScrubGeoAndDeviceIP(reqWrapper, ipConf) } else { // run existing policies (GDPR, CCPA, COPPA, LMT) // potentially block passing geo based on GDPR - if gdprEnforced { - if gdprErr == nil { - privacyEnforcement.GDPRGeo = !auctionPermissions.PassGeo - } else { - privacyEnforcement.GDPRGeo = true - } + if gdprEnforced && (gdprErr != nil || !auctionPermissions.PassGeo) { + privacy.ScrubGeoAndDeviceIP(reqWrapper, ipConf) } // potentially block passing geo based on CCPA - privacyEnforcement.CCPA = ccpaEnforcer.ShouldEnforce(bidderRequest.BidderName.String()) + if ccpaEnforcer.ShouldEnforce(bidderRequest.BidderName.String()) { + privacy.ScrubDeviceIDsIPsUserDemoExt(reqWrapper, ipConf, "eids", false) + } + } + if lmt || coppa { + privacy.ScrubDeviceIDsIPsUserDemoExt(reqWrapper, ipConf, "eids", coppa) } - applyFPD(auctionReq.FirstPartyData, bidderRequest) + passTIDAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitTIDs, scopedName, privacy.NewRequestFromBidRequest(*req)) + if !passTIDAllowed { + privacy.ScrubTID(reqWrapper) + } - privacyEnforcement.TID = !auctionReq.Activities.Allow(privacy.ActivityTransmitTIDs, scopedName, privacy.NewRequestFromBidRequest(*req)) + reqWrapper.RebuildRequest() + bidderRequest.BidRequest = reqWrapper.BidRequest - privacyEnforcement.Apply(bidderRequest.BidRequest, auctionReq.Account.Privacy) allowedBidderRequests = append(allowedBidderRequests, bidderRequest) // GPP downgrade: always downgrade unless we can confirm GPP is supported @@ -232,6 +238,34 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, return } +// cloneBidderReq - clones bidder request and replaces req.User and req.Device with new copies +func cloneBidderReq(req *openrtb2.BidRequest) *openrtb_ext.RequestWrapper { + + // bidder request may be modified differently per bidder based on privacy configs + // new request should be created for each bidder request + // pointer fields like User and Device should be cloned and set back to the request copy + var newReq *openrtb2.BidRequest + newReq = ptrutil.Clone(req) + + if req.User != nil { + userCopy := ortb.CloneUser(req.User) + newReq.User = userCopy + } + + if req.Device != nil { + deviceCopy := ortb.CloneDevice(req.Device) + newReq.Device = deviceCopy + } + + if req.Source != nil { + sourceCopy := ortb.CloneSource(req.Source) + newReq.Source = sourceCopy + } + + reqWrapper := &openrtb_ext.RequestWrapper{BidRequest: newReq} + return reqWrapper +} + func shouldSetLegacyPrivacy(bidderInfo config.BidderInfos, bidder string) bool { binfo, defined := bidderInfo[bidder] diff --git a/exchange/utils_test.go b/exchange/utils_test.go index 03184b7402d..1e5213ab0b1 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -26,6 +26,8 @@ import ( "github.com/stretchr/testify/mock" ) +const deviceUA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36" + // permissionsMock mocks the Permissions interface for tests type permissionsMock struct { allowAllBidders bool @@ -2279,6 +2281,7 @@ func TestCleanOpenRTBRequestsWithOpenRTBDowngrade(t *testing.T) { bidReq.User.ID = "" bidReq.User.BuyerUID = "" bidReq.User.Yob = 0 + bidReq.User.Gender = "" bidReq.User.Geo = &openrtb2.Geo{Lat: 123.46} downgradedRegs := *bidReq.Regs @@ -2536,7 +2539,7 @@ func newAdapterAliasBidRequest(t *testing.T) *openrtb2.BidRequest { }, Device: &openrtb2.Device{ DIDMD5: "some device ID hash", - UA: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36", + UA: deviceUA, IFA: "ifa", IP: "132.173.230.74", DNT: &dnt, @@ -2580,11 +2583,17 @@ func newBidRequest(t *testing.T) *openrtb2.BidRequest { }, }, Device: &openrtb2.Device{ - DIDMD5: "some device ID hash", - UA: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36", - IFA: "ifa", + UA: deviceUA, IP: "132.173.230.74", Language: "EN", + DIDMD5: "DIDMD5", + IFA: "IFA", + DIDSHA1: "DIDSHA1", + DPIDMD5: "DPIDMD5", + DPIDSHA1: "DPIDSHA1", + MACMD5: "MACMD5", + MACSHA1: "MACSHA1", + Geo: &openrtb2.Geo{Lat: 123.456, Lon: 11.278}, }, Source: &openrtb2.Source{ TID: "testTID", @@ -2593,8 +2602,13 @@ func newBidRequest(t *testing.T) *openrtb2.BidRequest { ID: "our-id", BuyerUID: "their-id", Yob: 1982, - Ext: json.RawMessage(`{}`), - Geo: &openrtb2.Geo{Lat: 123.456}, + Gender: "test", + Ext: json.RawMessage(`{"data": 1, "test": 2}`), + Geo: &openrtb2.Geo{Lat: 123.456, Lon: 11.278}, + EIDs: []openrtb2.EID{ + {Source: "eids-source"}, + }, + Data: []openrtb2.Data{{ID: "data-id"}}, }, Imp: []openrtb2.Imp{{ BidFloor: 100, @@ -2624,7 +2638,7 @@ func newBidRequestWithBidderParams(t *testing.T) *openrtb2.BidRequest { }, Device: &openrtb2.Device{ DIDMD5: "some device ID hash", - UA: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36", + UA: deviceUA, IFA: "ifa", IP: "132.173.230.74", Language: "EN", @@ -4466,126 +4480,210 @@ func TestGetMediaTypeForBid(t *testing.T) { } func TestCleanOpenRTBRequestsActivities(t *testing.T) { + expectedUserDefault := openrtb2.User{ + ID: "our-id", + BuyerUID: "their-id", + Yob: 1982, + Gender: "test", + Ext: json.RawMessage(`{"data": 1, "test": 2}`), + Geo: &openrtb2.Geo{Lat: 123.456, Lon: 11.278}, + EIDs: []openrtb2.EID{ + {Source: "eids-source"}, + }, + Data: []openrtb2.Data{{ID: "data-id"}}, + } + expectedDeviceDefault := openrtb2.Device{ + UA: deviceUA, + IP: "132.173.230.74", + Language: "EN", + DIDMD5: "DIDMD5", + IFA: "IFA", + DIDSHA1: "DIDSHA1", + DPIDMD5: "DPIDMD5", + DPIDSHA1: "DPIDSHA1", + MACMD5: "MACMD5", + MACSHA1: "MACSHA1", + Geo: &openrtb2.Geo{Lat: 123.456, Lon: 11.278}, + } + + expectedSourceDefault := openrtb2.Source{ + TID: "testTID", + } + testCases := []struct { - name string - req *openrtb2.BidRequest - privacyConfig config.AccountPrivacy - componentName string - allow bool - expectedReqNumber int - expectedUserYOB int64 - expectedUserLat float64 - expectedDeviceDIDMD5 string - expectedSourceTID string + name string + req *openrtb2.BidRequest + privacyConfig config.AccountPrivacy + componentName string + allow bool + expectedReqNumber int + expectedUser openrtb2.User + expectedDevice openrtb2.Device + expectedSource openrtb2.Source + expectedImpExt json.RawMessage }{ { - name: "fetch_bids_request_with_one_bidder_allowed", - req: newBidRequest(t), - privacyConfig: getFetchBidsActivityConfig("appnexus", true), - expectedReqNumber: 1, - expectedUserYOB: 1982, - expectedUserLat: 123.456, - expectedDeviceDIDMD5: "some device ID hash", - expectedSourceTID: "testTID", - }, - { - name: "fetch_bids_request_with_one_bidder_not_allowed", - req: newBidRequest(t), - privacyConfig: getFetchBidsActivityConfig("appnexus", false), - expectedReqNumber: 0, - expectedUserYOB: 1982, - expectedUserLat: 123.456, - expectedDeviceDIDMD5: "some device ID hash", - expectedSourceTID: "testTID", - }, - { - name: "transmit_ufpd_allowed", - req: newBidRequest(t), - privacyConfig: getTransmitUFPDActivityConfig("appnexus", true), - expectedReqNumber: 1, - expectedUserYOB: 1982, - expectedUserLat: 123.456, - expectedDeviceDIDMD5: "some device ID hash", - expectedSourceTID: "testTID", - }, - { - name: "transmit_ufpd_deny", - req: newBidRequest(t), - privacyConfig: getTransmitUFPDActivityConfig("appnexus", false), - expectedReqNumber: 1, - expectedUserYOB: 0, - expectedUserLat: 123.456, - expectedDeviceDIDMD5: "", - expectedSourceTID: "testTID", - }, - { - name: "transmit_precise_geo_allowed", - req: newBidRequest(t), - privacyConfig: getTransmitPreciseGeoActivityConfig("appnexus", true), - expectedReqNumber: 1, - expectedUserYOB: 1982, - expectedUserLat: 123.456, - expectedDeviceDIDMD5: "some device ID hash", - expectedSourceTID: "testTID", - }, - { - name: "transmit_precise_geo_deny", - req: newBidRequest(t), - privacyConfig: getTransmitPreciseGeoActivityConfig("appnexus", false), - expectedReqNumber: 1, - expectedUserYOB: 1982, - expectedUserLat: 123.46, - expectedDeviceDIDMD5: "some device ID hash", - expectedSourceTID: "testTID", - }, - { - name: "transmit_tid_allowed", - req: newBidRequest(t), - privacyConfig: getTransmitTIDActivityConfig("appnexus", true), - expectedReqNumber: 1, - expectedUserYOB: 1982, - expectedUserLat: 123.456, - expectedDeviceDIDMD5: "some device ID hash", - expectedSourceTID: "testTID", - }, - { - name: "transmit_tid_deny", - req: newBidRequest(t), - privacyConfig: getTransmitTIDActivityConfig("appnexus", false), - expectedReqNumber: 1, - expectedUserYOB: 1982, - expectedUserLat: 123.456, - expectedDeviceDIDMD5: "some device ID hash", - expectedSourceTID: "", + name: "fetch_bids_request_with_one_bidder_allowed", + req: newBidRequest(t), + privacyConfig: getFetchBidsActivityConfig("appnexus", true), + expectedReqNumber: 1, + expectedUser: expectedUserDefault, + expectedDevice: expectedDeviceDefault, + expectedSource: expectedSourceDefault, + }, + { + name: "fetch_bids_request_with_one_bidder_not_allowed", + req: newBidRequest(t), + privacyConfig: getFetchBidsActivityConfig("appnexus", false), + expectedReqNumber: 0, + expectedUser: expectedUserDefault, + expectedDevice: expectedDeviceDefault, + expectedSource: expectedSourceDefault, + }, + { + name: "transmit_ufpd_allowed", + req: newBidRequest(t), + privacyConfig: getTransmitUFPDActivityConfig("appnexus", true), + expectedReqNumber: 1, + expectedUser: expectedUserDefault, + expectedDevice: expectedDeviceDefault, + expectedSource: expectedSourceDefault, + }, + { + //remove user.eids, user.ext.data.*, user.data.*, user.{id, buyeruid, yob, gender} + //and device-specific IDs + name: "transmit_ufpd_deny", + req: newBidRequest(t), + privacyConfig: getTransmitUFPDActivityConfig("appnexus", false), + expectedReqNumber: 1, + expectedUser: openrtb2.User{ + ID: "", + BuyerUID: "", + Yob: 0, + Geo: &openrtb2.Geo{Lat: 123.456, Lon: 11.278}, + EIDs: nil, + Ext: json.RawMessage(`{"test":2}`), + Data: nil, + }, + expectedDevice: openrtb2.Device{ + UA: deviceUA, + Language: "EN", + IP: "132.173.230.74", + DIDMD5: "", + IFA: "", + DIDSHA1: "", + DPIDMD5: "", + DPIDSHA1: "", + MACMD5: "", + MACSHA1: "", + Geo: &openrtb2.Geo{Lat: 123.456, Lon: 11.278}, + }, + expectedSource: expectedSourceDefault, + }, + { + name: "transmit_precise_geo_allowed", + req: newBidRequest(t), + privacyConfig: getTransmitPreciseGeoActivityConfig("appnexus", true), + expectedReqNumber: 1, + expectedUser: expectedUserDefault, + expectedDevice: expectedDeviceDefault, + expectedSource: expectedSourceDefault, + }, + { + //round user's geographic location by rounding off IP address and lat/lng data. + //this applies to both device.geo and user.geo + name: "transmit_precise_geo_deny", + req: newBidRequest(t), + privacyConfig: getTransmitPreciseGeoActivityConfig("appnexus", false), + expectedReqNumber: 1, + expectedUser: openrtb2.User{ + ID: "our-id", + BuyerUID: "their-id", + Yob: 1982, + Geo: &openrtb2.Geo{Lat: 123.46, Lon: 11.28}, + Gender: "test", + Ext: json.RawMessage(`{"data": 1, "test": 2}`), + EIDs: []openrtb2.EID{ + {Source: "eids-source"}, + }, + Data: []openrtb2.Data{{ID: "data-id"}}, + }, + expectedDevice: openrtb2.Device{ + UA: deviceUA, + IP: "132.173.0.0", + Language: "EN", + DIDMD5: "DIDMD5", + IFA: "IFA", + DIDSHA1: "DIDSHA1", + DPIDMD5: "DPIDMD5", + DPIDSHA1: "DPIDSHA1", + MACMD5: "MACMD5", + MACSHA1: "MACSHA1", + Geo: &openrtb2.Geo{Lat: 123.46, Lon: 11.28}, + }, + expectedSource: expectedSourceDefault, + }, + { + name: "transmit_tid_allowed", + req: newBidRequest(t), + privacyConfig: getTransmitTIDActivityConfig("appnexus", true), + expectedReqNumber: 1, + expectedUser: expectedUserDefault, + expectedDevice: expectedDeviceDefault, + expectedSource: expectedSourceDefault, + }, + { + //remove source.tid and imp.ext.tid + name: "transmit_tid_deny", + req: newBidRequest(t), + privacyConfig: getTransmitTIDActivityConfig("appnexus", false), + expectedReqNumber: 1, + expectedUser: expectedUserDefault, + expectedDevice: expectedDeviceDefault, + expectedSource: openrtb2.Source{ + TID: "", + }, + expectedImpExt: json.RawMessage(`{"bidder": {"placementId": 1}}`), }, } for _, test := range testCases { - activities := privacy.NewActivityControl(&test.privacyConfig) - auctionReq := AuctionRequest{ - BidRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: test.req}, - UserSyncs: &emptyUsersync{}, - Activities: activities, - } + t.Run(test.name, func(t *testing.T) { + activities := privacy.NewActivityControl(&test.privacyConfig) + auctionReq := AuctionRequest{ + BidRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: test.req}, + UserSyncs: &emptyUsersync{}, + Activities: activities, + Account: config.Account{Privacy: config.AccountPrivacy{ + IPv6Config: config.IPv6{ + AnonKeepBits: 32, + }, + IPv4Config: config.IPv4{ + AnonKeepBits: 16, + }, + }}, + } - bidderToSyncerKey := map[string]string{} - reqSplitter := &requestSplitter{ - bidderToSyncerKey: bidderToSyncerKey, - me: &metrics.MetricsEngineMock{}, - hostSChainNode: nil, - bidderInfo: config.BidderInfos{}, - } + bidderToSyncerKey := map[string]string{} + reqSplitter := &requestSplitter{ + bidderToSyncerKey: bidderToSyncerKey, + me: &metrics.MetricsEngineMock{}, + hostSChainNode: nil, + bidderInfo: config.BidderInfos{}, + } - t.Run(test.name, func(t *testing.T) { bidderRequests, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, nil, gdpr.SignalNo, map[string]float64{}) assert.Empty(t, errs) assert.Len(t, bidderRequests, test.expectedReqNumber) if test.expectedReqNumber == 1 { - assert.Equal(t, test.expectedUserYOB, bidderRequests[0].BidRequest.User.Yob) - assert.Equal(t, test.expectedUserLat, bidderRequests[0].BidRequest.User.Geo.Lat) - assert.Equal(t, test.expectedDeviceDIDMD5, bidderRequests[0].BidRequest.Device.DIDMD5) - assert.Equal(t, test.expectedSourceTID, bidderRequests[0].BidRequest.Source.TID) + assert.Equal(t, &test.expectedUser, bidderRequests[0].BidRequest.User) + assert.Equal(t, &test.expectedDevice, bidderRequests[0].BidRequest.Device) + assert.Equal(t, &test.expectedSource, bidderRequests[0].BidRequest.Source) + + if len(test.expectedImpExt) > 0 { + assert.JSONEq(t, string(test.expectedImpExt), string(bidderRequests[0].BidRequest.Imp[0].Ext)) + } } }) } diff --git a/ortb/clone.go b/ortb/clone.go index 0dd210a986e..c831aae21b5 100644 --- a/ortb/clone.go +++ b/ortb/clone.go @@ -189,6 +189,140 @@ func CloneUser(s *openrtb2.User) *openrtb2.User { return &c } +func CloneDevice(s *openrtb2.Device) *openrtb2.Device { + if s == nil { + return nil + } + + // Shallow Copy (Value Fields) + c := *s + + // Deep Copy (Pointers) + c.Geo = CloneGeo(s.Geo) + + c.DNT = CloneInt8Pointer(s.DNT) + c.Lmt = CloneInt8Pointer(s.Lmt) + + c.SUA = CloneUserAgent(s.SUA) + if s.ConnectionType != nil { + connectionTypeCopy := s.ConnectionType.Val() + c.ConnectionType = &connectionTypeCopy + } + + c.Ext = sliceutil.Clone(s.Ext) + + return &c +} + +func CloneInt8Pointer(s *int8) *int8 { + if s == nil { + return nil + } + var dntCopy int8 + dntCopy = *s + return &dntCopy +} + +func CloneUserAgent(s *openrtb2.UserAgent) *openrtb2.UserAgent { + if s == nil { + return nil + } + + // Shallow Copy (Value Fields) + c := *s + + // Deep Copy (Pointers) + c.Browsers = CloneBrandVersionSlice(s.Browsers) + c.Platform = CloneBrandVersion(s.Platform) + + if s.Mobile != nil { + mobileCopy := *s.Mobile + c.Mobile = &mobileCopy + } + s.Ext = sliceutil.Clone(s.Ext) + + return &c +} + +func CloneBrandVersionSlice(s []openrtb2.BrandVersion) []openrtb2.BrandVersion { + if s == nil { + return nil + } + + c := make([]openrtb2.BrandVersion, len(s)) + for i, d := range s { + bv := CloneBrandVersion(&d) + c[i] = *bv + } + + return c +} + +func CloneBrandVersion(s *openrtb2.BrandVersion) *openrtb2.BrandVersion { + if s == nil { + return nil + } + c := *s + + // Deep Copy (Pointers) + c.Version = sliceutil.Clone(s.Version) + c.Ext = sliceutil.Clone(s.Ext) + + return &c +} + +func CloneSource(s *openrtb2.Source) *openrtb2.Source { + if s == nil { + return nil + } + + // Shallow Copy (Value Fields) + c := *s + + // Deep Copy (Pointers) + c.SChain = CloneSChain(s.SChain) + c.Ext = sliceutil.Clone(s.Ext) + + return &c +} + +func CloneSChain(s *openrtb2.SupplyChain) *openrtb2.SupplyChain { + if s == nil { + return nil + } + // Shallow Copy (Value Fields) + c := *s + + // Deep Copy (Pointers) + c.Nodes = CloneSupplyChainNodes(s.Nodes) + c.Ext = sliceutil.Clone(s.Ext) + + return &c +} + +func CloneSupplyChainNodes(s []openrtb2.SupplyChainNode) []openrtb2.SupplyChainNode { + if s == nil { + return nil + } + + c := make([]openrtb2.SupplyChainNode, len(s)) + for i, d := range s { + c[i] = CloneSupplyChainNode(d) + } + + return c +} + +func CloneSupplyChainNode(s openrtb2.SupplyChainNode) openrtb2.SupplyChainNode { + // Shallow Copy (Value Fields) Occurred By Passing Argument By Value + + // Deep Copy (Pointers) + s.HP = CloneInt8Pointer(s.HP) + s.Ext = sliceutil.Clone(s.Ext) + + return s +} + func CloneGeo(s *openrtb2.Geo) *openrtb2.Geo { if s == nil { return nil diff --git a/ortb/clone_test.go b/ortb/clone_test.go index 50dd94057ee..820c24397f4 100644 --- a/ortb/clone_test.go +++ b/ortb/clone_test.go @@ -536,6 +536,384 @@ func TestCloneUser(t *testing.T) { }) } +func TestCloneDevice(t *testing.T) { + t.Run("nil", func(t *testing.T) { + result := CloneDevice(nil) + assert.Nil(t, result) + }) + + t.Run("empty", func(t *testing.T) { + given := &openrtb2.Device{} + result := CloneDevice(given) + assert.Empty(t, result) + assert.NotSame(t, given, result) + }) + + t.Run("populated", func(t *testing.T) { + var n int8 = 1 + np := &n + ct := adcom1.ConnectionWIFI + + given := &openrtb2.Device{ + Geo: &openrtb2.Geo{Lat: 1.2, Lon: 2.3, Ext: json.RawMessage(`{"geo":1}`)}, + DNT: np, + Lmt: np, + UA: "UserAgent", + SUA: &openrtb2.UserAgent{Mobile: np, Model: "iPad"}, + IP: "127.0.0.1", + IPv6: "2001::", + DeviceType: adcom1.DeviceTablet, + Make: "Apple", + Model: "iPad", + OS: "macOS", + OSV: "1.2.3", + HWV: "mini", + H: 20, + W: 30, + PPI: 100, + PxRatio: 200, + JS: 2, + GeoFetch: 4, + FlashVer: "1.22.33", + Language: "En", + LangB: "ENG", + Carrier: "AT&T", + MCCMNC: "111-222", + ConnectionType: &ct, + IFA: "IFA", + DIDSHA1: "DIDSHA1", + DIDMD5: "DIDMD5", + DPIDSHA1: "DPIDSHA1", + DPIDMD5: "DPIDMD5", + MACSHA1: "MACSHA1", + MACMD5: "MACMD5", + Ext: json.RawMessage(`{"anyField":1}`), + } + result := CloneDevice(given) + assert.Equal(t, given, result, "equality") + assert.NotSame(t, given, result, "pointer") + assert.NotSame(t, given.Geo, result.Geo, "geo") + assert.NotSame(t, given.Geo.Ext, result.Geo.Ext, "geo-ext") + assert.NotSame(t, given.DNT, result.DNT, "dnt") + assert.NotSame(t, given.Lmt, result.Lmt, "lmt") + assert.NotSame(t, given.SUA, result.SUA, "sua") + assert.NotSame(t, given.ConnectionType, result.ConnectionType, "connectionType") + assert.NotSame(t, given.Ext, result.Ext, "ext") + }) + + t.Run("assumptions", func(t *testing.T) { + assert.ElementsMatch(t, discoverPointerFields(reflect.TypeOf(openrtb2.Device{})), + []string{ + "Geo", + "DNT", + "Lmt", + "SUA", + "ConnectionType", + "Ext", + }) + }) +} + +func TestCloneInt8Pointer(t *testing.T) { + + t.Run("nil", func(t *testing.T) { + result := CloneInt8Pointer(nil) + assert.Nil(t, result) + }) + + t.Run("empty", func(t *testing.T) { + var given *int8 + result := CloneInt8Pointer(given) + assert.Nil(t, result) + }) + + t.Run("populated", func(t *testing.T) { + var n int8 = 1 + given := &n + result := CloneInt8Pointer(given) + assert.Equal(t, given, result, "equality") + assert.NotSame(t, given, result, "pointer") + }) +} + +func TestCloneUserAgent(t *testing.T) { + t.Run("nil", func(t *testing.T) { + result := CloneUserAgent(nil) + assert.Nil(t, result) + }) + + t.Run("empty", func(t *testing.T) { + given := &openrtb2.UserAgent{} + result := CloneUserAgent(given) + assert.Empty(t, result) + assert.NotSame(t, given, result) + }) + + t.Run("populated", func(t *testing.T) { + var n int8 = 1 + np := &n + + given := &openrtb2.UserAgent{ + Browsers: []openrtb2.BrandVersion{{Brand: "Apple"}}, + Platform: &openrtb2.BrandVersion{Brand: "Apple"}, + Mobile: np, + Architecture: "X86", + Bitness: "64", + Model: "iPad", + Source: adcom1.UASourceLowEntropy, + Ext: json.RawMessage(`{"anyField":1}`), + } + result := CloneUserAgent(given) + assert.Equal(t, given, result, "equality") + assert.NotSame(t, given, result, "pointer") + assert.NotSame(t, given.Browsers, result.Browsers, "browsers") + assert.NotSame(t, given.Platform, result.Platform, "platform") + assert.NotSame(t, given.Mobile, result.Mobile, "mobile") + assert.NotSame(t, given.Architecture, result.Architecture, "architecture") + assert.NotSame(t, given.Ext, result.Ext, "ext") + }) + + t.Run("assumptions", func(t *testing.T) { + assert.ElementsMatch(t, discoverPointerFields(reflect.TypeOf(openrtb2.UserAgent{})), + []string{ + "Browsers", + "Platform", + "Mobile", + "Ext", + }) + }) +} + +func TestCloneBrandVersionSlice(t *testing.T) { + t.Run("nil", func(t *testing.T) { + result := CloneBrandVersionSlice(nil) + assert.Nil(t, result) + }) + + t.Run("empty", func(t *testing.T) { + given := []openrtb2.BrandVersion{} + result := CloneBrandVersionSlice(given) + assert.Empty(t, result) + assert.NotSame(t, given, result) + }) + + t.Run("one", func(t *testing.T) { + given := []openrtb2.BrandVersion{ + {Brand: "1", Version: []string{"s1", "s2"}, Ext: json.RawMessage(`{"anyField":1}`)}, + } + result := CloneBrandVersionSlice(given) + assert.Equal(t, given, result, "equality") + assert.NotSame(t, given[0], result[0], "item-pointer") + assert.NotSame(t, given[0].Ext, result[0].Ext, "item-pointer-ext") + }) + + t.Run("many", func(t *testing.T) { + given := []openrtb2.BrandVersion{ + {Brand: "1", Version: []string{"s1", "s2"}, Ext: json.RawMessage(`{"anyField":1}`)}, + {Brand: "2", Version: []string{"s3", "s4"}, Ext: json.RawMessage(`{"anyField":1}`)}, + {Brand: "3", Version: []string{"s5", "s6"}, Ext: json.RawMessage(`{"anyField":1}`)}, + } + result := CloneBrandVersionSlice(given) + assert.Equal(t, given, result, "equality") + assert.NotSame(t, given[0], result[0], "item0-pointer") + assert.NotSame(t, given[0].Ext, result[0].Ext, "item0-pointer-ext") + assert.NotSame(t, given[1], result[1], "item1-pointer") + assert.NotSame(t, given[1].Ext, result[1].Ext, "item1-pointer-ext") + assert.NotSame(t, given[2], result[2], "item1-pointer") + assert.NotSame(t, given[2].Ext, result[2].Ext, "item1-pointer-ext") + }) +} + +func TestCloneBrandVersion(t *testing.T) { + t.Run("nil", func(t *testing.T) { + result := CloneBrandVersion(nil) + assert.Nil(t, result) + }) + + t.Run("empty", func(t *testing.T) { + given := &openrtb2.BrandVersion{} + result := CloneBrandVersion(given) + assert.Empty(t, result) + assert.NotSame(t, given, result) + }) + + t.Run("populated", func(t *testing.T) { + given := &openrtb2.BrandVersion{ + Brand: "Apple", + Version: []string{"s1"}, + Ext: json.RawMessage(`{"anyField":1}`), + } + result := CloneBrandVersion(given) + assert.Equal(t, given, result, "equality") + assert.NotSame(t, given, result, "pointer") + assert.NotSame(t, given.Ext, result.Ext, "ext") + }) + + t.Run("assumptions", func(t *testing.T) { + assert.ElementsMatch(t, discoverPointerFields(reflect.TypeOf(openrtb2.BrandVersion{})), + []string{ + "Version", + "Ext", + }) + }) +} + +func TestCloneSource(t *testing.T) { + t.Run("nil", func(t *testing.T) { + result := CloneSource(nil) + assert.Nil(t, result) + }) + + t.Run("empty", func(t *testing.T) { + given := &openrtb2.Source{} + result := CloneSource(given) + assert.Empty(t, result) + assert.NotSame(t, given, result) + }) + + t.Run("populated", func(t *testing.T) { + + given := &openrtb2.Source{ + FD: 1, + TID: "Tid", + PChain: "PChain", + SChain: &openrtb2.SupplyChain{ + Complete: 1, + Nodes: []openrtb2.SupplyChainNode{ + {ASI: "asi", Ext: json.RawMessage(`{"anyField":1}`)}, + }, + Ext: json.RawMessage(`{"anyField":2}`), + }, + Ext: json.RawMessage(`{"anyField":1}`), + } + result := CloneSource(given) + assert.Equal(t, given, result, "equality") + assert.NotSame(t, given, result, "pointer") + assert.NotSame(t, given.SChain, result.SChain, "schain") + assert.NotSame(t, given.SChain.Ext, result.SChain.Ext, "schain.ext") + assert.NotSame(t, given.Ext, result.Ext, "ext") + assert.NotSame(t, given.SChain.Nodes[0].Ext, result.SChain.Nodes[0].Ext, "schain.nodes.ext") + }) + + t.Run("assumptions", func(t *testing.T) { + assert.ElementsMatch(t, discoverPointerFields(reflect.TypeOf(openrtb2.Source{})), + []string{ + "SChain", + "Ext", + }) + }) +} + +func TestCloneSChain(t *testing.T) { + t.Run("nil", func(t *testing.T) { + result := CloneSource(nil) + assert.Nil(t, result) + }) + + t.Run("empty", func(t *testing.T) { + given := &openrtb2.SupplyChain{} + result := CloneSChain(given) + assert.Empty(t, result) + assert.NotSame(t, given, result) + }) + + t.Run("populated", func(t *testing.T) { + given := &openrtb2.SupplyChain{ + Complete: 1, + Nodes: []openrtb2.SupplyChainNode{ + {ASI: "asi", Ext: json.RawMessage(`{"anyField":1}`)}, + }, + Ext: json.RawMessage(`{"anyField":1}`), + } + result := CloneSChain(given) + assert.Equal(t, given, result, "equality") + assert.NotSame(t, given, result, "pointer") + assert.NotSame(t, given.Nodes, result.Nodes, "nodes") + assert.NotSame(t, given.Nodes[0].Ext, result.Nodes[0].Ext, "nodes.ext") + assert.NotSame(t, given.Ext, result.Ext, "ext") + }) + + t.Run("assumptions", func(t *testing.T) { + assert.ElementsMatch(t, discoverPointerFields(reflect.TypeOf(openrtb2.SupplyChain{})), + []string{ + "Nodes", + "Ext", + }) + }) +} + +func TestCloneSupplyChainNodes(t *testing.T) { + var n int8 = 1 + np := &n + t.Run("nil", func(t *testing.T) { + result := CloneSupplyChainNodes(nil) + assert.Nil(t, result) + }) + + t.Run("empty", func(t *testing.T) { + given := []openrtb2.SupplyChainNode{} + result := CloneSupplyChainNodes(given) + assert.Empty(t, result) + assert.NotSame(t, given, result) + }) + + t.Run("one", func(t *testing.T) { + given := []openrtb2.SupplyChainNode{ + {ASI: "asi", HP: np, Ext: json.RawMessage(`{"anyField":1}`)}, + } + result := CloneSupplyChainNodes(given) + assert.Equal(t, given, result, "equality") + assert.NotSame(t, given[0], result[0], "item-pointer") + assert.NotSame(t, given[0].HP, result[0].HP, "item-pointer-hp") + assert.NotSame(t, given[0].Ext, result[0].Ext, "item-pointer-ext") + }) + + t.Run("many", func(t *testing.T) { + given := []openrtb2.SupplyChainNode{ + {ASI: "asi", HP: np, Ext: json.RawMessage(`{"anyField":1}`)}, + {ASI: "asi", HP: np, Ext: json.RawMessage(`{"anyField":1}`)}, + {ASI: "asi", HP: np, Ext: json.RawMessage(`{"anyField":1}`)}, + } + result := CloneSupplyChainNodes(given) + assert.Equal(t, given, result, "equality") + assert.NotSame(t, given[0], result[0], "item0-pointer") + assert.NotSame(t, given[0].Ext, result[0].Ext, "item0-pointer-ext") + assert.NotSame(t, given[0].HP, result[0].HP, "item0-pointer-hp") + assert.NotSame(t, given[1], result[1], "item1-pointer") + assert.NotSame(t, given[1].Ext, result[1].Ext, "item1-pointer-ext") + assert.NotSame(t, given[1].HP, result[1].HP, "item1-pointer-hp") + assert.NotSame(t, given[2], result[2], "item2-pointer") + assert.NotSame(t, given[2].Ext, result[2].Ext, "item2-pointer-ext") + assert.NotSame(t, given[2].HP, result[2].HP, "item2-pointer-hp") + }) +} + +func TestCloneSupplyChainNode(t *testing.T) { + t.Run("populated", func(t *testing.T) { + var n int8 = 1 + np := &n + + given := openrtb2.SupplyChainNode{ + ASI: "asi", + HP: np, + Ext: json.RawMessage(`{"anyField":1}`), + } + result := CloneSupplyChainNode(given) + assert.Equal(t, given, result, "equality") + assert.NotSame(t, given, result, "pointer") + assert.NotSame(t, given.Ext, result.Ext, "ext") + assert.NotSame(t, given.HP, result.HP, "hp") + }) + + t.Run("assumptions", func(t *testing.T) { + assert.ElementsMatch(t, discoverPointerFields(reflect.TypeOf(openrtb2.SupplyChainNode{})), + []string{ + "HP", + "Ext", + }) + }) +} + func TestCloneGeo(t *testing.T) { t.Run("nil", func(t *testing.T) { result := CloneGeo(nil) diff --git a/privacy/enforcement.go b/privacy/enforcement.go deleted file mode 100644 index 901c062ea4e..00000000000 --- a/privacy/enforcement.go +++ /dev/null @@ -1,92 +0,0 @@ -package privacy - -import ( - "github.com/prebid/openrtb/v19/openrtb2" - "github.com/prebid/prebid-server/v2/config" -) - -// Enforcement represents the privacy policies to enforce for an OpenRTB bid request. -type Enforcement struct { - CCPA bool - COPPA bool - GDPRGeo bool - GDPRID bool - LMT bool - - // activities - UFPD bool - Eids bool - PreciseGeo bool - TID bool -} - -// Any returns true if at least one privacy policy requires enforcement. -func (e Enforcement) AnyLegacy() bool { - return e.CCPA || e.COPPA || e.GDPRGeo || e.GDPRID || e.LMT -} - -func (e Enforcement) AnyActivities() bool { - return e.UFPD || e.PreciseGeo || e.Eids || e.TID -} - -// Apply cleans personally identifiable information from an OpenRTB bid request. -func (e Enforcement) Apply(bidRequest *openrtb2.BidRequest, privacy config.AccountPrivacy) { - e.apply(bidRequest, NewScrubber(privacy.IPv6Config, privacy.IPv4Config)) -} - -func (e Enforcement) apply(bidRequest *openrtb2.BidRequest, scrubber Scrubber) { - if bidRequest != nil { - if e.AnyActivities() { - bidRequest = scrubber.ScrubRequest(bidRequest, e) - } - if e.AnyLegacy() && !(e.UFPD && e.PreciseGeo && e.Eids) { - bidRequest.User = scrubber.ScrubUser(bidRequest.User, e.getUserScrubStrategy(), e.getGeoScrubStrategy()) - } - if e.AnyLegacy() && !(e.UFPD && e.PreciseGeo) { - bidRequest.Device = scrubber.ScrubDevice(bidRequest.Device, e.getDeviceIDScrubStrategy(), e.getIPv4ScrubStrategy(), e.getIPv6ScrubStrategy(), e.getGeoScrubStrategy()) - } - } -} - -func (e Enforcement) getDeviceIDScrubStrategy() ScrubStrategyDeviceID { - if e.COPPA || e.GDPRID || e.CCPA || e.LMT { - return ScrubStrategyDeviceIDAll - } - - return ScrubStrategyDeviceIDNone -} - -func (e Enforcement) getIPv4ScrubStrategy() ScrubStrategyIPV4 { - if e.COPPA || e.GDPRGeo || e.CCPA || e.LMT { - return ScrubStrategyIPV4Subnet - } - - return ScrubStrategyIPV4None -} - -func (e Enforcement) getIPv6ScrubStrategy() ScrubStrategyIPV6 { - if e.GDPRGeo || e.CCPA || e.LMT || e.COPPA { - return ScrubStrategyIPV6Subnet - } - return ScrubStrategyIPV6None -} - -func (e Enforcement) getGeoScrubStrategy() ScrubStrategyGeo { - if e.COPPA { - return ScrubStrategyGeoFull - } - - if e.GDPRGeo || e.CCPA || e.LMT { - return ScrubStrategyGeoReducedPrecision - } - - return ScrubStrategyGeoNone -} - -func (e Enforcement) getUserScrubStrategy() ScrubStrategyUser { - if e.COPPA || e.CCPA || e.LMT || e.GDPRID { - return ScrubStrategyUserIDAndDemographic - } - - return ScrubStrategyUserNone -} diff --git a/privacy/enforcement_test.go b/privacy/enforcement_test.go deleted file mode 100644 index a97779eb903..00000000000 --- a/privacy/enforcement_test.go +++ /dev/null @@ -1,393 +0,0 @@ -package privacy - -import ( - "testing" - - "github.com/prebid/openrtb/v19/openrtb2" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" -) - -func TestAnyLegacy(t *testing.T) { - testCases := []struct { - enforcement Enforcement - expected bool - description string - }{ - { - description: "All False", - enforcement: Enforcement{ - CCPA: false, - COPPA: false, - GDPRGeo: false, - GDPRID: false, - LMT: false, - }, - expected: false, - }, - { - description: "All True", - enforcement: Enforcement{ - CCPA: true, - COPPA: true, - GDPRGeo: true, - GDPRID: true, - LMT: true, - }, - expected: true, - }, - { - description: "Mixed", - enforcement: Enforcement{ - CCPA: false, - COPPA: true, - GDPRGeo: false, - GDPRID: false, - LMT: true, - }, - expected: true, - }, - } - - for _, test := range testCases { - result := test.enforcement.AnyLegacy() - assert.Equal(t, test.expected, result, test.description) - } -} - -func TestApplyGDPR(t *testing.T) { - testCases := []struct { - description string - enforcement Enforcement - expectedDeviceID ScrubStrategyDeviceID - expectedDeviceIPv4 ScrubStrategyIPV4 - expectedDeviceIPv6 ScrubStrategyIPV6 - expectedDeviceGeo ScrubStrategyGeo - expectedUser ScrubStrategyUser - expectedUserGeo ScrubStrategyGeo - }{ - { - description: "All Enforced", - enforcement: Enforcement{ - CCPA: true, - COPPA: true, - GDPRGeo: true, - GDPRID: true, - LMT: true, - }, - expectedDeviceID: ScrubStrategyDeviceIDAll, - expectedDeviceIPv4: ScrubStrategyIPV4Subnet, - expectedDeviceIPv6: ScrubStrategyIPV6Subnet, - expectedDeviceGeo: ScrubStrategyGeoFull, - expectedUser: ScrubStrategyUserIDAndDemographic, - expectedUserGeo: ScrubStrategyGeoFull, - }, - { - description: "CCPA Only", - enforcement: Enforcement{ - CCPA: true, - COPPA: false, - GDPRGeo: false, - GDPRID: false, - LMT: false, - }, - expectedDeviceID: ScrubStrategyDeviceIDAll, - expectedDeviceIPv4: ScrubStrategyIPV4Subnet, - expectedDeviceIPv6: ScrubStrategyIPV6Subnet, - expectedDeviceGeo: ScrubStrategyGeoReducedPrecision, - expectedUser: ScrubStrategyUserIDAndDemographic, - expectedUserGeo: ScrubStrategyGeoReducedPrecision, - }, - { - description: "COPPA Only", - enforcement: Enforcement{ - CCPA: false, - COPPA: true, - GDPRGeo: false, - GDPRID: false, - LMT: false, - }, - expectedDeviceID: ScrubStrategyDeviceIDAll, - expectedDeviceIPv4: ScrubStrategyIPV4Subnet, - expectedDeviceIPv6: ScrubStrategyIPV6Subnet, - expectedDeviceGeo: ScrubStrategyGeoFull, - expectedUser: ScrubStrategyUserIDAndDemographic, - expectedUserGeo: ScrubStrategyGeoFull, - }, - { - description: "GDPR Only - Full", - enforcement: Enforcement{ - CCPA: false, - COPPA: false, - GDPRGeo: true, - GDPRID: true, - LMT: false, - }, - expectedDeviceID: ScrubStrategyDeviceIDAll, - expectedDeviceIPv4: ScrubStrategyIPV4Subnet, - expectedDeviceIPv6: ScrubStrategyIPV6Subnet, - expectedDeviceGeo: ScrubStrategyGeoReducedPrecision, - expectedUser: ScrubStrategyUserIDAndDemographic, - expectedUserGeo: ScrubStrategyGeoReducedPrecision, - }, - { - description: "GDPR Only - ID Only", - enforcement: Enforcement{ - CCPA: false, - COPPA: false, - GDPRGeo: false, - GDPRID: true, - LMT: false, - }, - expectedDeviceID: ScrubStrategyDeviceIDAll, - expectedDeviceIPv4: ScrubStrategyIPV4None, - expectedDeviceIPv6: ScrubStrategyIPV6None, - expectedDeviceGeo: ScrubStrategyGeoNone, - expectedUser: ScrubStrategyUserIDAndDemographic, - expectedUserGeo: ScrubStrategyGeoNone, - }, - { - description: "GDPR Only - Geo Only", - enforcement: Enforcement{ - CCPA: false, - COPPA: false, - GDPRGeo: true, - GDPRID: false, - LMT: false, - }, - expectedDeviceID: ScrubStrategyDeviceIDNone, - expectedDeviceIPv4: ScrubStrategyIPV4Subnet, - expectedDeviceIPv6: ScrubStrategyIPV6Subnet, - expectedDeviceGeo: ScrubStrategyGeoReducedPrecision, - expectedUser: ScrubStrategyUserNone, - expectedUserGeo: ScrubStrategyGeoReducedPrecision, - }, - { - description: "LMT Only", - enforcement: Enforcement{ - CCPA: false, - COPPA: false, - GDPRGeo: false, - GDPRID: false, - LMT: true, - }, - expectedDeviceID: ScrubStrategyDeviceIDAll, - expectedDeviceIPv4: ScrubStrategyIPV4Subnet, - expectedDeviceIPv6: ScrubStrategyIPV6Subnet, - expectedDeviceGeo: ScrubStrategyGeoReducedPrecision, - expectedUser: ScrubStrategyUserIDAndDemographic, - expectedUserGeo: ScrubStrategyGeoReducedPrecision, - }, - { - description: "Interactions: COPPA + GDPR Full", - enforcement: Enforcement{ - CCPA: false, - COPPA: true, - GDPRGeo: true, - GDPRID: true, - LMT: false, - }, - expectedDeviceID: ScrubStrategyDeviceIDAll, - expectedDeviceIPv4: ScrubStrategyIPV4Subnet, - expectedDeviceIPv6: ScrubStrategyIPV6Subnet, - expectedDeviceGeo: ScrubStrategyGeoFull, - expectedUser: ScrubStrategyUserIDAndDemographic, - expectedUserGeo: ScrubStrategyGeoFull, - }, - } - - for _, test := range testCases { - req := &openrtb2.BidRequest{ - Device: &openrtb2.Device{}, - User: &openrtb2.User{}, - } - replacedDevice := &openrtb2.Device{} - replacedUser := &openrtb2.User{} - - m := &mockScrubber{} - m.On("ScrubDevice", req.Device, test.expectedDeviceID, test.expectedDeviceIPv4, test.expectedDeviceIPv6, test.expectedDeviceGeo).Return(replacedDevice).Once() - m.On("ScrubUser", req.User, test.expectedUser, test.expectedUserGeo).Return(replacedUser).Once() - - test.enforcement.apply(req, m) - - m.AssertExpectations(t) - assert.Same(t, replacedDevice, req.Device, "Device") - assert.Same(t, replacedUser, req.User, "User") - } -} - -func TestApplyToggle(t *testing.T) { - testCases := []struct { - description string - enforcement Enforcement - expectedScrubRequestExecuted bool - expectedScrubUserExecuted bool - expectedScrubDeviceExecuted bool - }{ - { - description: "All enforced - only ScrubRequest execution expected", - enforcement: Enforcement{ - CCPA: true, - COPPA: true, - GDPRGeo: true, - GDPRID: true, - LMT: true, - UFPD: true, - Eids: true, - PreciseGeo: true, - TID: true, - }, - expectedScrubRequestExecuted: true, - expectedScrubUserExecuted: false, - expectedScrubDeviceExecuted: false, - }, - { - description: "All Legacy and no activities - ScrubUser and ScrubDevice execution expected", - enforcement: Enforcement{ - CCPA: true, - COPPA: true, - GDPRGeo: true, - GDPRID: true, - LMT: true, - UFPD: false, - Eids: false, - PreciseGeo: false, - TID: false, - }, - expectedScrubRequestExecuted: false, - expectedScrubUserExecuted: true, - expectedScrubDeviceExecuted: true, - }, - { - description: "Some Legacy and some activities - ScrubRequest, ScrubUser and ScrubDevice execution expected", - enforcement: Enforcement{ - CCPA: true, - COPPA: true, - GDPRGeo: true, - GDPRID: true, - LMT: true, - UFPD: true, - Eids: false, - PreciseGeo: false, - TID: false, - }, - expectedScrubRequestExecuted: true, - expectedScrubUserExecuted: true, - expectedScrubDeviceExecuted: true, - }, - { - description: "Some Legacy and some activities - ScrubRequest execution expected", - enforcement: Enforcement{ - CCPA: true, - COPPA: true, - GDPRGeo: true, - GDPRID: true, - LMT: true, - UFPD: true, - Eids: true, - PreciseGeo: true, - TID: false, - }, - expectedScrubRequestExecuted: true, - expectedScrubUserExecuted: false, - expectedScrubDeviceExecuted: false, - }, - { - description: "Some Legacy and some activities overlap - ScrubRequest and ScrubUser execution expected", - enforcement: Enforcement{ - CCPA: true, - COPPA: true, - GDPRGeo: true, - GDPRID: true, - LMT: true, - UFPD: true, - Eids: false, - PreciseGeo: true, - TID: false, - }, - expectedScrubRequestExecuted: true, - expectedScrubUserExecuted: true, - expectedScrubDeviceExecuted: false, - }, - } - - for _, test := range testCases { - t.Run(test.description, func(t *testing.T) { - req := &openrtb2.BidRequest{ - Device: &openrtb2.Device{}, - User: &openrtb2.User{}, - } - replacedDevice := &openrtb2.Device{} - replacedUser := &openrtb2.User{} - - m := &mockScrubber{} - - if test.expectedScrubRequestExecuted { - m.On("ScrubRequest", req, test.enforcement).Return(req).Once() - } - if test.expectedScrubUserExecuted { - m.On("ScrubUser", req.User, ScrubStrategyUserIDAndDemographic, ScrubStrategyGeoFull).Return(replacedUser).Once() - } - if test.expectedScrubDeviceExecuted { - m.On("ScrubDevice", req.Device, ScrubStrategyDeviceIDAll, ScrubStrategyIPV4Subnet, ScrubStrategyIPV6Subnet, ScrubStrategyGeoFull).Return(replacedDevice).Once() - } - - test.enforcement.apply(req, m) - - m.AssertExpectations(t) - - }) - } -} - -func TestApplyNoneApplicable(t *testing.T) { - req := &openrtb2.BidRequest{} - - m := &mockScrubber{} - - enforcement := Enforcement{ - CCPA: false, - COPPA: false, - GDPRGeo: false, - GDPRID: false, - LMT: false, - - UFPD: false, - PreciseGeo: false, - TID: false, - Eids: false, - } - enforcement.apply(req, m) - - m.AssertNotCalled(t, "ScrubDevice") - m.AssertNotCalled(t, "ScrubUser") -} - -func TestApplyNil(t *testing.T) { - m := &mockScrubber{} - - enforcement := Enforcement{} - enforcement.apply(nil, m) - - m.AssertNotCalled(t, "ScrubDevice") - m.AssertNotCalled(t, "ScrubUser") -} - -type mockScrubber struct { - mock.Mock -} - -func (m *mockScrubber) ScrubRequest(bidRequest *openrtb2.BidRequest, enforcement Enforcement) *openrtb2.BidRequest { - args := m.Called(bidRequest, enforcement) - return args.Get(0).(*openrtb2.BidRequest) -} - -func (m *mockScrubber) ScrubDevice(device *openrtb2.Device, id ScrubStrategyDeviceID, ipv4 ScrubStrategyIPV4, ipv6 ScrubStrategyIPV6, geo ScrubStrategyGeo) *openrtb2.Device { - args := m.Called(device, id, ipv4, ipv6, geo) - return args.Get(0).(*openrtb2.Device) -} - -func (m *mockScrubber) ScrubUser(user *openrtb2.User, strategy ScrubStrategyUser, geo ScrubStrategyGeo) *openrtb2.User { - args := m.Called(user, strategy, geo) - return args.Get(0).(*openrtb2.User) -} diff --git a/privacy/scrubber.go b/privacy/scrubber.go index 54941669ab9..ba1f8a9478b 100644 --- a/privacy/scrubber.go +++ b/privacy/scrubber.go @@ -2,252 +2,147 @@ package privacy import ( "encoding/json" + "github.com/prebid/prebid-server/v2/util/jsonutil" "net" + "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/prebid/prebid-server/v2/util/iputil" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/ptrutil" - - "github.com/prebid/openrtb/v19/openrtb2" -) - -// ScrubStrategyIPV4 defines the approach to scrub PII from an IPV4 address. -type ScrubStrategyIPV4 int - -const ( - // ScrubStrategyIPV4None does not remove any part of an IPV4 address. - ScrubStrategyIPV4None ScrubStrategyIPV4 = iota - - // ScrubStrategyIPV4Subnet zeroes out the last 8 bits of an IPV4 address. - ScrubStrategyIPV4Subnet -) - -// ScrubStrategyIPV6 defines the approach to scrub PII from an IPV6 address. -type ScrubStrategyIPV6 int - -const ( - // ScrubStrategyIPV6None does not remove any part of an IPV6 address. - ScrubStrategyIPV6None ScrubStrategyIPV6 = iota - - // ScrubStrategyIPV6Subnet zeroes out the last 16 bits of an IPV6 sub net address. - ScrubStrategyIPV6Subnet -) - -// ScrubStrategyGeo defines the approach to scrub PII from geographical data. -type ScrubStrategyGeo int - -const ( - // ScrubStrategyGeoNone does not remove any geographical data. - ScrubStrategyGeoNone ScrubStrategyGeo = iota - - // ScrubStrategyGeoFull removes all geographical data. - ScrubStrategyGeoFull - - // ScrubStrategyGeoReducedPrecision anonymizes geographical data with rounding. - ScrubStrategyGeoReducedPrecision -) - -// ScrubStrategyUser defines the approach to scrub PII from user data. -type ScrubStrategyUser int - -const ( - // ScrubStrategyUserNone does not remove non-location data. - ScrubStrategyUserNone ScrubStrategyUser = iota - - // ScrubStrategyUserIDAndDemographic removes the user's buyer id, exchange id year of birth, and gender. - ScrubStrategyUserIDAndDemographic -) - -// ScrubStrategyDeviceID defines the approach to remove hardware id and device id data. -type ScrubStrategyDeviceID int - -const ( - // ScrubStrategyDeviceIDNone does not remove hardware id and device id data. - ScrubStrategyDeviceIDNone ScrubStrategyDeviceID = iota - - // ScrubStrategyDeviceIDAll removes all hardware and device id data (ifa, mac hashes device id hashes) - ScrubStrategyDeviceIDAll ) -// Scrubber removes PII from parts of an OpenRTB request. -type Scrubber interface { - ScrubRequest(bidRequest *openrtb2.BidRequest, enforcement Enforcement) *openrtb2.BidRequest - ScrubDevice(device *openrtb2.Device, id ScrubStrategyDeviceID, ipv4 ScrubStrategyIPV4, ipv6 ScrubStrategyIPV6, geo ScrubStrategyGeo) *openrtb2.Device - ScrubUser(user *openrtb2.User, strategy ScrubStrategyUser, geo ScrubStrategyGeo) *openrtb2.User +type IPConf struct { + IPV6 config.IPv6 + IPV4 config.IPv4 } -type scrubber struct { - ipV6 config.IPv6 - ipV4 config.IPv4 +func scrubDeviceIDs(reqWrapper *openrtb_ext.RequestWrapper) { + if reqWrapper.Device != nil { + reqWrapper.Device.DIDMD5 = "" + reqWrapper.Device.DIDSHA1 = "" + reqWrapper.Device.DPIDMD5 = "" + reqWrapper.Device.DPIDSHA1 = "" + reqWrapper.Device.IFA = "" + reqWrapper.Device.MACMD5 = "" + reqWrapper.Device.MACSHA1 = "" + } } -// NewScrubber returns an OpenRTB scrubber. -func NewScrubber(ipV6 config.IPv6, ipV4 config.IPv4) Scrubber { - return scrubber{ - ipV6: ipV6, - ipV4: ipV4, +func scrubUserIDs(reqWrapper *openrtb_ext.RequestWrapper) { + if reqWrapper.User != nil { + reqWrapper.User.Data = nil + reqWrapper.User.ID = "" + reqWrapper.User.BuyerUID = "" + reqWrapper.User.Yob = 0 + reqWrapper.User.Gender = "" + reqWrapper.User.Keywords = "" + reqWrapper.User.KwArray = nil } } -func (s scrubber) ScrubRequest(bidRequest *openrtb2.BidRequest, enforcement Enforcement) *openrtb2.BidRequest { - var userExtParsed map[string]json.RawMessage - userExtModified := false - - // expressed in two lines because IntelliJ cannot infer the generic type - var userCopy *openrtb2.User - userCopy = ptrutil.Clone(bidRequest.User) - - // expressed in two lines because IntelliJ cannot infer the generic type - var deviceCopy *openrtb2.Device - deviceCopy = ptrutil.Clone(bidRequest.Device) - - if userCopy != nil && (enforcement.UFPD || enforcement.Eids) { - if len(userCopy.Ext) != 0 { - jsonutil.Unmarshal(userCopy.Ext, &userExtParsed) - } +func scrubUserDemographics(reqWrapper *openrtb_ext.RequestWrapper) { + if reqWrapper.User != nil { + reqWrapper.User.BuyerUID = "" + reqWrapper.User.ID = "" + reqWrapper.User.Yob = 0 + reqWrapper.User.Gender = "" } +} - if enforcement.UFPD { - // transmitUfpd covers user.ext.data, user.data, user.id, user.buyeruid, user.yob, user.gender, user.keywords, user.kwarray - // and device.{ifa, macsha1, macmd5, dpidsha1, dpidmd5, didsha1, didmd5} - if deviceCopy != nil { - deviceCopy.DIDMD5 = "" - deviceCopy.DIDSHA1 = "" - deviceCopy.DPIDMD5 = "" - deviceCopy.DPIDSHA1 = "" - deviceCopy.IFA = "" - deviceCopy.MACMD5 = "" - deviceCopy.MACSHA1 = "" - } - if userCopy != nil { - userCopy.Data = nil - userCopy.ID = "" - userCopy.BuyerUID = "" - userCopy.Yob = 0 - userCopy.Gender = "" - userCopy.Keywords = "" - userCopy.KwArray = nil - - _, hasField := userExtParsed["data"] - if hasField { - delete(userExtParsed, "data") - userExtModified = true - } +func scrubUserExt(reqWrapper *openrtb_ext.RequestWrapper, fieldName string) error { + if reqWrapper.User != nil { + userExt, err := reqWrapper.GetUserExt() + if err != nil { + return err } - } - if enforcement.Eids { - //transmitEids covers user.eids and user.ext.eids - if userCopy != nil { - userCopy.EIDs = nil - _, hasField := userExtParsed["eids"] - if hasField { - delete(userExtParsed, "eids") - userExtModified = true - } + ext := userExt.GetExt() + _, hasField := ext[fieldName] + if hasField { + delete(ext, fieldName) + userExt.SetExt(ext) } } + return nil +} - if userExtModified { - userExt, _ := jsonutil.Marshal(userExtParsed) - userCopy.Ext = userExt +func ScrubEIDs(reqWrapper *openrtb_ext.RequestWrapper) error { + //transmitEids removes user.eids and user.ext.eids + if reqWrapper.User != nil { + reqWrapper.User.EIDs = nil } + return scrubUserExt(reqWrapper, "eids") +} - if enforcement.TID { - //remove source.tid and imp.ext.tid - if bidRequest.Source != nil { - sourceCopy := ptrutil.Clone(bidRequest.Source) - sourceCopy.TID = "" - bidRequest.Source = sourceCopy - } - for ind, imp := range bidRequest.Imp { - impExt := scrubExtIDs(imp.Ext, "tid") - bidRequest.Imp[ind].Ext = impExt - } +func ScrubTID(reqWrapper *openrtb_ext.RequestWrapper) { + if reqWrapper.Source != nil { + reqWrapper.Source.TID = "" } - - if enforcement.PreciseGeo { - //round user's geographic location by rounding off IP address and lat/lng data. - //this applies to both device.geo and user.geo - if userCopy != nil && userCopy.Geo != nil { - userCopy.Geo = scrubGeoPrecision(userCopy.Geo) - } - - if deviceCopy != nil { - if deviceCopy.Geo != nil { - deviceCopy.Geo = scrubGeoPrecision(deviceCopy.Geo) - } - deviceCopy.IP = scrubIP(deviceCopy.IP, s.ipV4.AnonKeepBits, iputil.IPv4BitSize) - deviceCopy.IPv6 = scrubIP(deviceCopy.IPv6, s.ipV6.AnonKeepBits, iputil.IPv6BitSize) - } + impWrapper := reqWrapper.GetImp() + for ind, imp := range impWrapper { + impExt := scrubExtIDs(imp.Ext, "tid") + impWrapper[ind].Ext = impExt } - - bidRequest.Device = deviceCopy - bidRequest.User = userCopy - return bidRequest + reqWrapper.SetImp(impWrapper) } -func (s scrubber) ScrubDevice(device *openrtb2.Device, id ScrubStrategyDeviceID, ipv4 ScrubStrategyIPV4, ipv6 ScrubStrategyIPV6, geo ScrubStrategyGeo) *openrtb2.Device { - if device == nil { - return nil - } - - deviceCopy := *device - - switch id { - case ScrubStrategyDeviceIDAll: - deviceCopy.DIDMD5 = "" - deviceCopy.DIDSHA1 = "" - deviceCopy.DPIDMD5 = "" - deviceCopy.DPIDSHA1 = "" - deviceCopy.IFA = "" - deviceCopy.MACMD5 = "" - deviceCopy.MACSHA1 = "" +func scrubGEO(reqWrapper *openrtb_ext.RequestWrapper) { + //round user's geographic location by rounding off IP address and lat/lng data. + //this applies to both device.geo and user.geo + if reqWrapper.User != nil && reqWrapper.User.Geo != nil { + reqWrapper.User.Geo = scrubGeoPrecision(reqWrapper.User.Geo) } - switch ipv4 { - case ScrubStrategyIPV4Subnet: - deviceCopy.IP = scrubIP(device.IP, s.ipV4.AnonKeepBits, iputil.IPv4BitSize) + if reqWrapper.Device != nil && reqWrapper.Device.Geo != nil { + reqWrapper.Device.Geo = scrubGeoPrecision(reqWrapper.Device.Geo) } +} - switch ipv6 { - case ScrubStrategyIPV6Subnet: - deviceCopy.IPv6 = scrubIP(device.IPv6, s.ipV6.AnonKeepBits, iputil.IPv6BitSize) +func scrubGeoFull(reqWrapper *openrtb_ext.RequestWrapper) { + if reqWrapper.User != nil && reqWrapper.User.Geo != nil { + reqWrapper.User.Geo = &openrtb2.Geo{} } - - switch geo { - case ScrubStrategyGeoFull: - deviceCopy.Geo = scrubGeoFull(device.Geo) - case ScrubStrategyGeoReducedPrecision: - deviceCopy.Geo = scrubGeoPrecision(device.Geo) + if reqWrapper.Device != nil && reqWrapper.Device.Geo != nil { + reqWrapper.Device.Geo = &openrtb2.Geo{} } - return &deviceCopy } -func (scrubber) ScrubUser(user *openrtb2.User, strategy ScrubStrategyUser, geo ScrubStrategyGeo) *openrtb2.User { - if user == nil { - return nil +func scrubDeviceIP(reqWrapper *openrtb_ext.RequestWrapper, ipConf IPConf) { + if reqWrapper.Device != nil { + reqWrapper.Device.IP = scrubIP(reqWrapper.Device.IP, ipConf.IPV4.AnonKeepBits, iputil.IPv4BitSize) + reqWrapper.Device.IPv6 = scrubIP(reqWrapper.Device.IPv6, ipConf.IPV6.AnonKeepBits, iputil.IPv6BitSize) } +} - userCopy := *user +func ScrubDeviceIDsIPsUserDemoExt(reqWrapper *openrtb_ext.RequestWrapper, ipConf IPConf, fieldName string, scrubFullGeo bool) { + scrubDeviceIDs(reqWrapper) + scrubDeviceIP(reqWrapper, ipConf) + scrubUserDemographics(reqWrapper) + scrubUserExt(reqWrapper, fieldName) - if strategy == ScrubStrategyUserIDAndDemographic { - userCopy.BuyerUID = "" - userCopy.ID = "" - userCopy.Ext = scrubExtIDs(userCopy.Ext, "eids") - userCopy.Yob = 0 - userCopy.Gender = "" + if scrubFullGeo { + scrubGeoFull(reqWrapper) + } else { + scrubGEO(reqWrapper) } +} - switch geo { - case ScrubStrategyGeoFull: - userCopy.Geo = scrubGeoFull(user.Geo) - case ScrubStrategyGeoReducedPrecision: - userCopy.Geo = scrubGeoPrecision(user.Geo) - } +func ScrubUserFPD(reqWrapper *openrtb_ext.RequestWrapper) { + scrubDeviceIDs(reqWrapper) + scrubUserIDs(reqWrapper) + scrubUserExt(reqWrapper, "data") + reqWrapper.User.EIDs = nil +} - return &userCopy +func ScrubGdprID(reqWrapper *openrtb_ext.RequestWrapper) { + scrubDeviceIDs(reqWrapper) + scrubUserDemographics(reqWrapper) + scrubUserExt(reqWrapper, "eids") +} + +func ScrubGeoAndDeviceIP(reqWrapper *openrtb_ext.RequestWrapper, ipConf IPConf) { + scrubDeviceIP(reqWrapper, ipConf) + scrubGEO(reqWrapper) } func scrubIP(ip string, ones, bits int) string { @@ -259,14 +154,6 @@ func scrubIP(ip string, ones, bits int) string { return ipMasked.String() } -func scrubGeoFull(geo *openrtb2.Geo) *openrtb2.Geo { - if geo == nil { - return nil - } - - return &openrtb2.Geo{} -} - func scrubGeoPrecision(geo *openrtb2.Geo) *openrtb2.Geo { if geo == nil { return nil diff --git a/privacy/scrubber_test.go b/privacy/scrubber_test.go index 299acd9eba3..1fb88874d43 100644 --- a/privacy/scrubber_test.go +++ b/privacy/scrubber_test.go @@ -4,453 +4,347 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/stretchr/testify/assert" ) -func TestScrubDevice(t *testing.T) { - device := getTestDevice() - +func TestScrubDeviceIDs(t *testing.T) { testCases := []struct { - description string - expected *openrtb2.Device - id ScrubStrategyDeviceID - ipv4 ScrubStrategyIPV4 - ipv6 ScrubStrategyIPV6 - geo ScrubStrategyGeo + name string + deviceIn *openrtb2.Device + expectedDevice *openrtb2.Device }{ { - description: "All Strategies - None", - expected: device, - id: ScrubStrategyDeviceIDNone, - ipv4: ScrubStrategyIPV4None, - ipv6: ScrubStrategyIPV6None, - geo: ScrubStrategyGeoNone, - }, - { - description: "All Strategies - Strictest", - expected: &openrtb2.Device{ - DIDMD5: "", - DIDSHA1: "", - DPIDMD5: "", - DPIDSHA1: "", - MACSHA1: "", - MACMD5: "", - IFA: "", - IP: "1.2.3.0", - IPv6: "2001:1db8:2233:4400::", - Geo: &openrtb2.Geo{}, - }, - id: ScrubStrategyDeviceIDAll, - ipv4: ScrubStrategyIPV4Subnet, - ipv6: ScrubStrategyIPV6Subnet, - geo: ScrubStrategyGeoFull, - }, - { - description: "Isolated - ID - All", - expected: &openrtb2.Device{ - DIDMD5: "", - DIDSHA1: "", - DPIDMD5: "", - DPIDSHA1: "", - MACSHA1: "", - MACMD5: "", - IFA: "", - IP: "1.2.3.4", - IPv6: "2001:1db8:2233:4455:6677:ff00:0042:8329", - Geo: device.Geo, - }, - id: ScrubStrategyDeviceIDAll, - ipv4: ScrubStrategyIPV4None, - ipv6: ScrubStrategyIPV6None, - geo: ScrubStrategyGeoNone, - }, - { - description: "Isolated - IPv4 - Lowest 8", - expected: &openrtb2.Device{ - DIDMD5: "anyDIDMD5", - DIDSHA1: "anyDIDSHA1", - DPIDMD5: "anyDPIDMD5", - DPIDSHA1: "anyDPIDSHA1", - MACSHA1: "anyMACSHA1", - MACMD5: "anyMACMD5", - IFA: "anyIFA", - IP: "1.2.3.0", - IPv6: "2001:1db8:2233:4455:6677:ff00:0042:8329", - Geo: device.Geo, - }, - id: ScrubStrategyDeviceIDNone, - ipv4: ScrubStrategyIPV4Subnet, - ipv6: ScrubStrategyIPV6None, - geo: ScrubStrategyGeoNone, - }, - { - description: "Isolated - IPv6", - expected: &openrtb2.Device{ - DIDMD5: "anyDIDMD5", - DIDSHA1: "anyDIDSHA1", - DPIDMD5: "anyDPIDMD5", - DPIDSHA1: "anyDPIDSHA1", - MACSHA1: "anyMACSHA1", - MACMD5: "anyMACMD5", - IFA: "anyIFA", - IP: "1.2.3.4", - IPv6: "2001:1db8:2233:4400::", - Geo: device.Geo, - }, - id: ScrubStrategyDeviceIDNone, - ipv4: ScrubStrategyIPV4None, - ipv6: ScrubStrategyIPV6Subnet, - geo: ScrubStrategyGeoNone, - }, - { - description: "Isolated - Geo - Reduced Precision", - expected: &openrtb2.Device{ - DIDMD5: "anyDIDMD5", - DIDSHA1: "anyDIDSHA1", - DPIDMD5: "anyDPIDMD5", - DPIDSHA1: "anyDPIDSHA1", - MACSHA1: "anyMACSHA1", - MACMD5: "anyMACMD5", - IFA: "anyIFA", - IP: "1.2.3.4", - IPv6: "2001:1db8:2233:4455:6677:ff00:0042:8329", - Geo: &openrtb2.Geo{ - Lat: 123.46, - Lon: 678.89, - Metro: "some metro", - City: "some city", - ZIP: "some zip", - }, - }, - id: ScrubStrategyDeviceIDNone, - ipv4: ScrubStrategyIPV4None, - ipv6: ScrubStrategyIPV6None, - geo: ScrubStrategyGeoReducedPrecision, - }, - { - description: "Isolated - Geo - Full", - expected: &openrtb2.Device{ - DIDMD5: "anyDIDMD5", - DIDSHA1: "anyDIDSHA1", - DPIDMD5: "anyDPIDMD5", - DPIDSHA1: "anyDPIDSHA1", - MACSHA1: "anyMACSHA1", - MACMD5: "anyMACMD5", - IFA: "anyIFA", - IP: "1.2.3.4", - IPv6: "2001:1db8:2233:4455:6677:ff00:0042:8329", - Geo: &openrtb2.Geo{}, - }, - id: ScrubStrategyDeviceIDNone, - ipv4: ScrubStrategyIPV4None, - ipv6: ScrubStrategyIPV6None, - geo: ScrubStrategyGeoFull, + name: "all", + deviceIn: &openrtb2.Device{DIDMD5: "MD5", DIDSHA1: "SHA1", DPIDMD5: "MD5", DPIDSHA1: "SHA1", IFA: "IFA", MACMD5: "MD5", MACSHA1: "SHA1"}, + expectedDevice: &openrtb2.Device{DIDMD5: "", DIDSHA1: "", DPIDMD5: "", DPIDSHA1: "", IFA: "", MACMD5: "", MACSHA1: ""}, + }, + { + name: "nil", + deviceIn: nil, + expectedDevice: nil, }, } - testIPMasking := getTestIPMasking() for _, test := range testCases { - result := NewScrubber(testIPMasking.IPv6Config, testIPMasking.IPv4Config).ScrubDevice(device, test.id, test.ipv4, test.ipv6, test.geo) - assert.Equal(t, test.expected, result, test.description) + t.Run(test.name, func(t *testing.T) { + brw := &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{Device: test.deviceIn}} + scrubDeviceIDs(brw) + brw.RebuildRequest() + assert.Equal(t, test.expectedDevice, brw.Device) + }) } } -func TestScrubDeviceNil(t *testing.T) { - testIPMasking := getTestIPMasking() - result := NewScrubber(testIPMasking.IPv6Config, testIPMasking.IPv4Config).ScrubDevice(nil, ScrubStrategyDeviceIDNone, ScrubStrategyIPV4None, ScrubStrategyIPV6None, ScrubStrategyGeoNone) - assert.Nil(t, result) +func TestScrubUserIDs(t *testing.T) { + testCases := []struct { + name string + userIn *openrtb2.User + expectedUser *openrtb2.User + }{ + { + name: "all", + userIn: &openrtb2.User{Data: []openrtb2.Data{}, ID: "ID", BuyerUID: "bID", Yob: 2000, Gender: "M", Keywords: "keywords", KwArray: nil}, + expectedUser: &openrtb2.User{Data: nil, ID: "", BuyerUID: "", Yob: 0, Gender: "", Keywords: "", KwArray: nil}, + }, + { + name: "nil", + userIn: nil, + expectedUser: nil, + }, + } + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + brw := &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{User: test.userIn}} + scrubUserIDs(brw) + brw.RebuildRequest() + assert.Equal(t, test.expectedUser, brw.User) + }) + } } -func TestScrubUser(t *testing.T) { - user := getTestUser() - +func TestScrubUserDemographics(t *testing.T) { testCases := []struct { - description string - expected *openrtb2.User - scrubUser ScrubStrategyUser - scrubGeo ScrubStrategyGeo + name string + userIn *openrtb2.User + expectedUser *openrtb2.User }{ { - description: "User ID And Demographic & Geo Full", - expected: &openrtb2.User{ - ID: "", - BuyerUID: "", - Yob: 0, - Gender: "", - Ext: json.RawMessage(`{}`), - Geo: &openrtb2.Geo{}, - }, - scrubUser: ScrubStrategyUserIDAndDemographic, - scrubGeo: ScrubStrategyGeoFull, - }, - { - description: "User ID And Demographic & Geo Reduced", - expected: &openrtb2.User{ - ID: "", - BuyerUID: "", - Yob: 0, - Gender: "", - Ext: json.RawMessage(`{}`), - Geo: &openrtb2.Geo{ - Lat: 123.46, - Lon: 678.89, - Metro: "some metro", - City: "some city", - ZIP: "some zip", - }, - }, - scrubUser: ScrubStrategyUserIDAndDemographic, - scrubGeo: ScrubStrategyGeoReducedPrecision, - }, - { - description: "User ID And Demographic & Geo None", - expected: &openrtb2.User{ - ID: "", - BuyerUID: "", - Yob: 0, - Gender: "", - Ext: json.RawMessage(`{}`), - Geo: &openrtb2.Geo{ - Lat: 123.456, - Lon: 678.89, - Metro: "some metro", - City: "some city", - ZIP: "some zip", - }, - }, - scrubUser: ScrubStrategyUserIDAndDemographic, - scrubGeo: ScrubStrategyGeoNone, - }, - { - description: "User None & Geo Full", - expected: &openrtb2.User{ - ID: "anyID", - BuyerUID: "anyBuyerUID", - Yob: 42, - Gender: "anyGender", - Ext: json.RawMessage(`{}`), - Geo: &openrtb2.Geo{}, - }, - scrubUser: ScrubStrategyUserNone, - scrubGeo: ScrubStrategyGeoFull, - }, - { - description: "User None & Geo Reduced", - expected: &openrtb2.User{ - ID: "anyID", - BuyerUID: "anyBuyerUID", - Yob: 42, - Gender: "anyGender", - Ext: json.RawMessage(`{}`), - Geo: &openrtb2.Geo{ - Lat: 123.46, - Lon: 678.89, - Metro: "some metro", - City: "some city", - ZIP: "some zip", - }, - }, - scrubUser: ScrubStrategyUserNone, - scrubGeo: ScrubStrategyGeoReducedPrecision, - }, - { - description: "User None & Geo None", - expected: &openrtb2.User{ - ID: "anyID", - BuyerUID: "anyBuyerUID", - Yob: 42, - Gender: "anyGender", - Ext: json.RawMessage(`{}`), - Geo: &openrtb2.Geo{ - Lat: 123.456, - Lon: 678.89, - Metro: "some metro", - City: "some city", - ZIP: "some zip", - }, - }, - scrubUser: ScrubStrategyUserNone, - scrubGeo: ScrubStrategyGeoNone, + name: "all", + userIn: &openrtb2.User{ID: "ID", BuyerUID: "bID", Yob: 2000, Gender: "M"}, + expectedUser: &openrtb2.User{ID: "", BuyerUID: "", Yob: 0, Gender: ""}, + }, + { + name: "nil", + userIn: nil, + expectedUser: nil, }, } - - testIPMasking := getTestIPMasking() for _, test := range testCases { - result := NewScrubber(testIPMasking.IPv6Config, testIPMasking.IPv4Config).ScrubUser(user, test.scrubUser, test.scrubGeo) - assert.Equal(t, test.expected, result, test.description) + t.Run(test.name, func(t *testing.T) { + brw := &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{User: test.userIn}} + scrubUserDemographics(brw) + brw.RebuildRequest() + assert.Equal(t, test.expectedUser, brw.User) + }) } } -func TestScrubUserNil(t *testing.T) { - testIPMasking := getTestIPMasking() - result := NewScrubber(testIPMasking.IPv6Config, testIPMasking.IPv4Config).ScrubUser(nil, ScrubStrategyUserNone, ScrubStrategyGeoNone) - assert.Nil(t, result) +func TestScrubUserExt(t *testing.T) { + testCases := []struct { + name string + userIn *openrtb2.User + fieldName string + expectedUser *openrtb2.User + }{ + { + name: "nil_user", + userIn: nil, + expectedUser: nil, + }, + { + name: "nil_ext", + userIn: &openrtb2.User{ID: "ID", Ext: nil}, + expectedUser: &openrtb2.User{ID: "ID", Ext: nil}, + }, + { + name: "empty_ext", + userIn: &openrtb2.User{ID: "ID", Ext: json.RawMessage(`{}`)}, + expectedUser: &openrtb2.User{ID: "ID", Ext: json.RawMessage(`{}`)}, + }, + { + name: "ext_with_field", + userIn: &openrtb2.User{ID: "ID", Ext: json.RawMessage(`{"data":"123","test":1}`)}, + fieldName: "data", + expectedUser: &openrtb2.User{ID: "ID", Ext: json.RawMessage(`{"test":1}`)}, + }, + { + name: "ext_without_field", + userIn: &openrtb2.User{ID: "ID", Ext: json.RawMessage(`{"data":"123","test":1}`)}, + fieldName: "noData", + expectedUser: &openrtb2.User{ID: "ID", Ext: json.RawMessage(`{"data":"123","test":1}`)}, + }, + { + name: "nil", + userIn: nil, + expectedUser: nil, + }, + } + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + brw := &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{User: test.userIn}} + scrubUserExt(brw, test.fieldName) + brw.RebuildRequest() + assert.Equal(t, test.expectedUser, brw.User) + }) + } } -func TestScrubRequest(t *testing.T) { - - imps := []openrtb2.Imp{ - {ID: "testId", Ext: json.RawMessage(`{"test": 1, "tid": 2}`)}, +func TestScrubEids(t *testing.T) { + testCases := []struct { + name string + userIn *openrtb2.User + expectedUser *openrtb2.User + }{ + { + name: "eids", + userIn: &openrtb2.User{ID: "ID", EIDs: []openrtb2.EID{}}, + expectedUser: &openrtb2.User{ID: "ID", EIDs: nil}, + }, + { + name: "nil_eids", + userIn: &openrtb2.User{ID: "ID", EIDs: nil}, + expectedUser: &openrtb2.User{ID: "ID", EIDs: nil}, + }, + { + name: "nil", + userIn: nil, + expectedUser: nil, + }, } - source := &openrtb2.Source{ - TID: "testTid", + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + brw := &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{User: test.userIn}} + ScrubEIDs(brw) + brw.RebuildRequest() + assert.Equal(t, test.expectedUser, brw.User) + }) } - device := getTestDevice() - user := getTestUser() - user.Ext = json.RawMessage(`{"data": 1, "eids": 2}`) - user.EIDs = []openrtb2.EID{{Source: "test"}} +} +func TestScrubTID(t *testing.T) { testCases := []struct { - description string - enforcement Enforcement - userExtPresent bool - expected *openrtb2.BidRequest + name string + sourceIn *openrtb2.Source + impIn []openrtb2.Imp + expectedSource *openrtb2.Source + expectedImp []openrtb2.Imp }{ { - description: "enforce transmitUFPD with user.ext", - enforcement: Enforcement{UFPD: true}, - userExtPresent: true, - expected: &openrtb2.BidRequest{ - Imp: imps, - Source: source, - User: &openrtb2.User{ - EIDs: []openrtb2.EID{{Source: "test"}}, - Geo: user.Geo, - Ext: json.RawMessage(`{"eids":2}`), - }, - Device: &openrtb2.Device{ - IP: "1.2.3.4", - IPv6: "2001:1db8:2233:4455:6677:ff00:0042:8329", - Geo: device.Geo, - }, - }, - }, - { - description: "enforce transmitUFPD without user.ext", - enforcement: Enforcement{UFPD: true}, - userExtPresent: false, - expected: &openrtb2.BidRequest{ - Imp: imps, - Source: source, - User: &openrtb2.User{ - EIDs: []openrtb2.EID{{Source: "test"}}, - Geo: user.Geo, - }, - Device: &openrtb2.Device{ - IP: "1.2.3.4", - IPv6: "2001:1db8:2233:4455:6677:ff00:0042:8329", - Geo: device.Geo, - }, - }, - }, - { - description: "enforce transmitEids", - enforcement: Enforcement{Eids: true}, - userExtPresent: true, - expected: &openrtb2.BidRequest{ - Imp: imps, - Source: source, - Device: device, - User: &openrtb2.User{ - ID: "anyID", - BuyerUID: "anyBuyerUID", - Yob: 42, - Gender: "anyGender", - Geo: user.Geo, - EIDs: nil, - Ext: json.RawMessage(`{"data":1}`), - }, - }, - }, - { - description: "enforce transmitTid", - enforcement: Enforcement{TID: true}, - userExtPresent: true, - expected: &openrtb2.BidRequest{ - Imp: []openrtb2.Imp{ - {ID: "testId", Ext: json.RawMessage(`{"test":1}`)}, - }, - Source: &openrtb2.Source{ - TID: "", - }, - Device: device, - User: &openrtb2.User{ - ID: "anyID", - BuyerUID: "anyBuyerUID", - Yob: 42, - Gender: "anyGender", - Geo: user.Geo, - EIDs: []openrtb2.EID{{Source: "test"}}, - Ext: json.RawMessage(`{"data": 1, "eids": 2}`), - }, - }, - }, - { - description: "enforce precise Geo", - enforcement: Enforcement{PreciseGeo: true}, - userExtPresent: true, - expected: &openrtb2.BidRequest{ - Imp: imps, - Source: source, - User: &openrtb2.User{ - ID: "anyID", - BuyerUID: "anyBuyerUID", - Yob: 42, - Gender: "anyGender", - Geo: &openrtb2.Geo{ - Lat: 123.46, Lon: 678.89, - Metro: "some metro", - City: "some city", - ZIP: "some zip", - }, - EIDs: []openrtb2.EID{{Source: "test"}}, - Ext: json.RawMessage(`{"data": 1, "eids": 2}`), - }, - Device: &openrtb2.Device{ - IFA: "anyIFA", - DIDSHA1: "anyDIDSHA1", - DIDMD5: "anyDIDMD5", - DPIDSHA1: "anyDPIDSHA1", - DPIDMD5: "anyDPIDMD5", - MACSHA1: "anyMACSHA1", - MACMD5: "anyMACMD5", - IP: "1.2.3.0", - IPv6: "2001:1db8:2233:4400::", - Geo: &openrtb2.Geo{ - Lat: 123.46, Lon: 678.89, - Metro: "some metro", - City: "some city", - ZIP: "some zip", - }, - }, - }, + name: "nil", + sourceIn: nil, + expectedSource: nil, + }, + { + name: "nil_imp_ext", + sourceIn: &openrtb2.Source{TID: "tid"}, + impIn: []openrtb2.Imp{{ID: "impID", Ext: nil}}, + expectedSource: &openrtb2.Source{TID: ""}, + expectedImp: []openrtb2.Imp{{ID: "impID", Ext: nil}}, + }, + { + name: "empty_imp_ext", + sourceIn: &openrtb2.Source{TID: "tid"}, + impIn: []openrtb2.Imp{{ID: "impID", Ext: json.RawMessage(`{}`)}}, + expectedSource: &openrtb2.Source{TID: ""}, + expectedImp: []openrtb2.Imp{{ID: "impID", Ext: json.RawMessage(`{}`)}}, + }, + { + name: "ext_with_tid", + sourceIn: &openrtb2.Source{TID: "tid"}, + impIn: []openrtb2.Imp{{ID: "impID", Ext: json.RawMessage(`{"tid":"123","test":1}`)}}, + expectedSource: &openrtb2.Source{TID: ""}, + expectedImp: []openrtb2.Imp{{ID: "impID", Ext: json.RawMessage(`{"test":1}`)}}, + }, + { + name: "ext_without_tid", + sourceIn: &openrtb2.Source{TID: "tid"}, + impIn: []openrtb2.Imp{{ID: "impID", Ext: json.RawMessage(`{"data":"123","test":1}`)}}, + expectedSource: &openrtb2.Source{TID: ""}, + expectedImp: []openrtb2.Imp{{ID: "impID", Ext: json.RawMessage(`{"data":"123","test":1}`)}}, }, } + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + brw := &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{Source: test.sourceIn, Imp: test.impIn}} + ScrubTID(brw) + brw.RebuildRequest() + assert.Equal(t, test.expectedSource, brw.Source) + assert.Equal(t, test.expectedImp, brw.Imp) + }) + } +} - testIPMasking := getTestIPMasking() +func TestScrubGEO(t *testing.T) { + testCases := []struct { + name string + userIn *openrtb2.User + expectedUser *openrtb2.User + deviceIn *openrtb2.Device + expectedDevice *openrtb2.Device + }{ + { + name: "nil", + userIn: nil, + expectedUser: nil, + deviceIn: nil, + expectedDevice: nil, + }, + { + name: "nil_user_geo", + userIn: &openrtb2.User{ID: "ID", Geo: nil}, + expectedUser: &openrtb2.User{ID: "ID", Geo: nil}, + deviceIn: &openrtb2.Device{Geo: &openrtb2.Geo{Lat: 123.123}}, + expectedDevice: &openrtb2.Device{Geo: &openrtb2.Geo{Lat: 123.12}}, + }, + { + name: "with_user_geo", + userIn: &openrtb2.User{ID: "ID", Geo: &openrtb2.Geo{Lat: 123.123}}, + expectedUser: &openrtb2.User{ID: "ID", Geo: &openrtb2.Geo{Lat: 123.12}}, + deviceIn: &openrtb2.Device{}, + expectedDevice: &openrtb2.Device{}, + }, + { + name: "nil_device_geo", + userIn: &openrtb2.User{}, + expectedUser: &openrtb2.User{}, + deviceIn: &openrtb2.Device{Geo: nil}, + expectedDevice: &openrtb2.Device{Geo: nil}, + }, + { + name: "with_device_geo", + userIn: &openrtb2.User{}, + expectedUser: &openrtb2.User{}, + deviceIn: &openrtb2.Device{Geo: &openrtb2.Geo{Lat: 123.123}}, + expectedDevice: &openrtb2.Device{Geo: &openrtb2.Geo{Lat: 123.12}}, + }, + { + name: "with_user_and_device_geo", + userIn: &openrtb2.User{ID: "ID", Geo: &openrtb2.Geo{Lat: 123.123}}, + expectedUser: &openrtb2.User{ID: "ID", Geo: &openrtb2.Geo{Lat: 123.12}}, + deviceIn: &openrtb2.Device{Geo: &openrtb2.Geo{Lat: 123.123}}, + expectedDevice: &openrtb2.Device{Geo: &openrtb2.Geo{Lat: 123.12}}, + }, + } for _, test := range testCases { - t.Run(test.description, func(t *testing.T) { - bidRequest := &openrtb2.BidRequest{ - Imp: []openrtb2.Imp{ - {ID: "testId", Ext: json.RawMessage(`{"test": 1, "tid": 2}`)}, - }, - Source: &openrtb2.Source{ - TID: "testTid", - }, - User: getTestUser(), - Device: getTestDevice(), - } - if test.userExtPresent { - bidRequest.User.Ext = json.RawMessage(`{"data": 1, "eids": 2}`) - } else { - bidRequest.User.Ext = nil - } - bidRequest.User.EIDs = []openrtb2.EID{{Source: "test"}} + t.Run(test.name, func(t *testing.T) { + brw := &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{User: test.userIn, Device: test.deviceIn}} + scrubGEO(brw) + brw.RebuildRequest() + assert.Equal(t, test.expectedUser, brw.User) + assert.Equal(t, test.expectedDevice, brw.Device) + }) + } +} - result := NewScrubber(testIPMasking.IPv6Config, testIPMasking.IPv4Config).ScrubRequest(bidRequest, test.enforcement) - assert.Equal(t, test.expected, result, test.description) +func TestScrubGeoFull(t *testing.T) { + testCases := []struct { + name string + userIn *openrtb2.User + expectedUser *openrtb2.User + deviceIn *openrtb2.Device + expectedDevice *openrtb2.Device + }{ + { + name: "nil", + userIn: nil, + expectedUser: nil, + deviceIn: nil, + expectedDevice: nil, + }, + { + name: "nil_user_geo", + userIn: &openrtb2.User{ID: "ID", Geo: nil}, + expectedUser: &openrtb2.User{ID: "ID", Geo: nil}, + deviceIn: &openrtb2.Device{}, + expectedDevice: &openrtb2.Device{}, + }, + { + name: "with_user_geo", + userIn: &openrtb2.User{ID: "ID", Geo: &openrtb2.Geo{Lat: 123.123}}, + expectedUser: &openrtb2.User{ID: "ID", Geo: &openrtb2.Geo{}}, + deviceIn: &openrtb2.Device{}, + expectedDevice: &openrtb2.Device{}, + }, + { + name: "nil_device_geo", + userIn: &openrtb2.User{}, + expectedUser: &openrtb2.User{}, + deviceIn: &openrtb2.Device{Geo: nil}, + expectedDevice: &openrtb2.Device{Geo: nil}, + }, + { + name: "with_device_geo", + userIn: &openrtb2.User{}, + expectedUser: &openrtb2.User{}, + deviceIn: &openrtb2.Device{Geo: &openrtb2.Geo{Lat: 123.123}}, + expectedDevice: &openrtb2.Device{Geo: &openrtb2.Geo{}}, + }, + { + name: "with_user_and_device_geo", + userIn: &openrtb2.User{ID: "ID", Geo: &openrtb2.Geo{Lat: 123.123}}, + expectedUser: &openrtb2.User{ID: "ID", Geo: &openrtb2.Geo{}}, + deviceIn: &openrtb2.Device{Geo: &openrtb2.Geo{Lat: 123.123}}, + expectedDevice: &openrtb2.Device{Geo: &openrtb2.Geo{}}, + }, + } + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + brw := &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{User: test.userIn, Device: test.deviceIn}} + scrubGeoFull(brw) + brw.RebuildRequest() + assert.Equal(t, test.expectedUser, brw.User) + assert.Equal(t, test.expectedDevice, brw.Device) }) } } @@ -510,42 +404,6 @@ func TestScrubIP(t *testing.T) { bits: 128, maskBits: 96, }, - { - IP: "2001:1db8:0000:0000:0000:ff00:0042:8329", - cleanedIP: "2001:1db8::ff00:42:0", - bits: 128, - maskBits: 112, - }, - { - IP: "2001:1db8:0000:0000:0000:ff00:0042:0", - cleanedIP: "2001:1db8::ff00:42:0", - bits: 128, - maskBits: 112, - }, - { - IP: "127.0.0.1", - cleanedIP: "127.0.0.0", - bits: 32, - maskBits: 24, - }, - { - IP: "0.0.0.0", - cleanedIP: "0.0.0.0", - bits: 32, - maskBits: 24, - }, - { - IP: "192.127.111.134", - cleanedIP: "192.127.111.0", - bits: 32, - maskBits: 24, - }, - { - IP: "192.127.111.0", - cleanedIP: "192.127.111.0", - bits: 32, - maskBits: 24, - }, } for _, test := range testCases { t.Run(test.IP, func(t *testing.T) { @@ -556,32 +414,6 @@ func TestScrubIP(t *testing.T) { } } -func TestScrubGeoFull(t *testing.T) { - geo := &openrtb2.Geo{ - Lat: 123.456, - Lon: 678.89, - Metro: "some metro", - City: "some city", - ZIP: "some zip", - } - geoExpected := &openrtb2.Geo{ - Lat: 0, - Lon: 0, - Metro: "", - City: "", - ZIP: "", - } - - result := scrubGeoFull(geo) - - assert.Equal(t, geoExpected, result) -} - -func TestScrubGeoFullWhenNil(t *testing.T) { - result := scrubGeoFull(nil) - assert.Nil(t, result) -} - func TestScrubGeoPrecision(t *testing.T) { geo := &openrtb2.Geo{ Lat: 123.456, @@ -654,26 +486,11 @@ func TestScrubUserExtIDs(t *testing.T) { userExt: json.RawMessage(`{"anyExisting":{"existing":42},"eids":[{"source":"anySource","id":"anyId","uids":[{"id":"anyId","ext":{"id":42}}],"ext":{"id":42}}]}`), expected: json.RawMessage(`{"anyExisting":{"existing":42}}`), }, - { - description: "Remove eids Only", - userExt: json.RawMessage(`{"eids":[{"source":"anySource","id":"anyId","uids":[{"id":"anyId","ext":{"id":42}}],"ext":{"id":42}}]}`), - expected: json.RawMessage(`{}`), - }, { description: "Remove eids Only - Empty Array", userExt: json.RawMessage(`{"eids":[]}`), expected: json.RawMessage(`{}`), }, - { - description: "Remove eids Only - With Other Data", - userExt: json.RawMessage(`{"anyExisting":42,"eids":[{"source":"anySource","id":"anyId","uids":[{"id":"anyId","ext":{"id":42}}],"ext":{"id":42}}]}`), - expected: json.RawMessage(`{"anyExisting":42}`), - }, - { - description: "Remove eids Only - With Other Nested Data", - userExt: json.RawMessage(`{"anyExisting":{"existing":42},"eids":[{"source":"anySource","id":"anyId","uids":[{"id":"anyId","ext":{"id":42}}],"ext":{"id":42}}]}`), - expected: json.RawMessage(`{"anyExisting":{"existing":42}}`), - }, } for _, test := range testCases { @@ -681,52 +498,3 @@ func TestScrubUserExtIDs(t *testing.T) { assert.Equal(t, test.expected, result, test.description) } } - -func getTestUser() *openrtb2.User { - return &openrtb2.User{ - ID: "anyID", - BuyerUID: "anyBuyerUID", - Yob: 42, - Gender: "anyGender", - Ext: json.RawMessage(`{}`), - Geo: &openrtb2.Geo{ - Lat: 123.456, - Lon: 678.89, - Metro: "some metro", - City: "some city", - ZIP: "some zip", - }, - } -} - -func getTestDevice() *openrtb2.Device { - return &openrtb2.Device{ - DIDMD5: "anyDIDMD5", - DIDSHA1: "anyDIDSHA1", - DPIDMD5: "anyDPIDMD5", - DPIDSHA1: "anyDPIDSHA1", - MACSHA1: "anyMACSHA1", - MACMD5: "anyMACMD5", - IFA: "anyIFA", - IP: "1.2.3.4", - IPv6: "2001:1db8:2233:4455:6677:ff00:0042:8329", - Geo: &openrtb2.Geo{ - Lat: 123.456, - Lon: 678.89, - Metro: "some metro", - City: "some city", - ZIP: "some zip", - }, - } -} - -func getTestIPMasking() config.AccountPrivacy { - return config.AccountPrivacy{ - IPv6Config: config.IPv6{ - 54, - }, - IPv4Config: config.IPv4{ - 24, - }, - } -} From 79d2f27870c928c410c8159947a596a6bd2550e6 Mon Sep 17 00:00:00 2001 From: abermanov-zeta <95416296+abermanov-zeta@users.noreply.github.com> Date: Thu, 16 Nov 2023 19:24:06 +0100 Subject: [PATCH 214/268] Zeta Global SSP: Update endpoints (#3201) --- .../zeta_global_ssp-test/exemplary/banner.json | 2 +- .../zeta_global_ssp-test/exemplary/no-bid.json | 2 +- .../zeta_global_ssp/zeta_global_ssp-test/exemplary/video.json | 2 +- .../zeta_global_ssp-test/supplemental/bad-request.json | 2 +- .../zeta_global_ssp-test/supplemental/invalid-bid-type.json | 2 +- .../zeta_global_ssp-test/supplemental/no-bid-type.json.json | 2 +- .../zeta_global_ssp-test/supplemental/server-error.json | 2 +- adapters/zeta_global_ssp/zeta_global_ssp_test.go | 2 +- static/bidder-info/zeta_global_ssp.yaml | 4 ++-- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/adapters/zeta_global_ssp/zeta_global_ssp-test/exemplary/banner.json b/adapters/zeta_global_ssp/zeta_global_ssp-test/exemplary/banner.json index cdfaf37e45d..8e04138937c 100644 --- a/adapters/zeta_global_ssp/zeta_global_ssp-test/exemplary/banner.json +++ b/adapters/zeta_global_ssp/zeta_global_ssp-test/exemplary/banner.json @@ -44,7 +44,7 @@ "application/json;charset=utf-8" ] }, - "uri": "http://whatever.url", + "uri": "https://ssp.disqus.com/bid/prebid-server?sid=11", "body": { "id": "some-request-id", "imp": [ diff --git a/adapters/zeta_global_ssp/zeta_global_ssp-test/exemplary/no-bid.json b/adapters/zeta_global_ssp/zeta_global_ssp-test/exemplary/no-bid.json index 68aabbed257..3e1ee805552 100644 --- a/adapters/zeta_global_ssp/zeta_global_ssp-test/exemplary/no-bid.json +++ b/adapters/zeta_global_ssp/zeta_global_ssp-test/exemplary/no-bid.json @@ -44,7 +44,7 @@ "application/json;charset=utf-8" ] }, - "uri": "http://whatever.url", + "uri": "https://ssp.disqus.com/bid/prebid-server?sid=11", "body": { "id": "some-request-id", "imp": [ diff --git a/adapters/zeta_global_ssp/zeta_global_ssp-test/exemplary/video.json b/adapters/zeta_global_ssp/zeta_global_ssp-test/exemplary/video.json index 248f4b0487a..bc1e496cb27 100644 --- a/adapters/zeta_global_ssp/zeta_global_ssp-test/exemplary/video.json +++ b/adapters/zeta_global_ssp/zeta_global_ssp-test/exemplary/video.json @@ -34,7 +34,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://whatever.url", + "uri": "https://ssp.disqus.com/bid/prebid-server?sid=11", "headers": { "Content-Type": [ "application/json;charset=utf-8" diff --git a/adapters/zeta_global_ssp/zeta_global_ssp-test/supplemental/bad-request.json b/adapters/zeta_global_ssp/zeta_global_ssp-test/supplemental/bad-request.json index 38f3bd326d0..bf2af3bf25b 100644 --- a/adapters/zeta_global_ssp/zeta_global_ssp-test/supplemental/bad-request.json +++ b/adapters/zeta_global_ssp/zeta_global_ssp-test/supplemental/bad-request.json @@ -44,7 +44,7 @@ "application/json;charset=utf-8" ] }, - "uri": "http://whatever.url", + "uri": "https://ssp.disqus.com/bid/prebid-server?sid=11", "body": { "id": "some-request-id", "imp": [ diff --git a/adapters/zeta_global_ssp/zeta_global_ssp-test/supplemental/invalid-bid-type.json b/adapters/zeta_global_ssp/zeta_global_ssp-test/supplemental/invalid-bid-type.json index 4a55670720d..0aba5f2ca36 100644 --- a/adapters/zeta_global_ssp/zeta_global_ssp-test/supplemental/invalid-bid-type.json +++ b/adapters/zeta_global_ssp/zeta_global_ssp-test/supplemental/invalid-bid-type.json @@ -44,7 +44,7 @@ "application/json;charset=utf-8" ] }, - "uri": "http://whatever.url", + "uri": "https://ssp.disqus.com/bid/prebid-server?sid=11", "body": { "id": "some-request-id", "imp": [ diff --git a/adapters/zeta_global_ssp/zeta_global_ssp-test/supplemental/no-bid-type.json.json b/adapters/zeta_global_ssp/zeta_global_ssp-test/supplemental/no-bid-type.json.json index 1992586435f..1f5a92c4fdf 100644 --- a/adapters/zeta_global_ssp/zeta_global_ssp-test/supplemental/no-bid-type.json.json +++ b/adapters/zeta_global_ssp/zeta_global_ssp-test/supplemental/no-bid-type.json.json @@ -44,7 +44,7 @@ "application/json;charset=utf-8" ] }, - "uri": "http://whatever.url", + "uri": "https://ssp.disqus.com/bid/prebid-server?sid=11", "body": { "id": "some-request-id", "imp": [ diff --git a/adapters/zeta_global_ssp/zeta_global_ssp-test/supplemental/server-error.json b/adapters/zeta_global_ssp/zeta_global_ssp-test/supplemental/server-error.json index 037c7307889..27e71c31255 100644 --- a/adapters/zeta_global_ssp/zeta_global_ssp-test/supplemental/server-error.json +++ b/adapters/zeta_global_ssp/zeta_global_ssp-test/supplemental/server-error.json @@ -44,7 +44,7 @@ "application/json;charset=utf-8" ] }, - "uri": "http://whatever.url", + "uri": "https://ssp.disqus.com/bid/prebid-server?sid=11", "body": { "id": "some-request-id", "imp": [ diff --git a/adapters/zeta_global_ssp/zeta_global_ssp_test.go b/adapters/zeta_global_ssp/zeta_global_ssp_test.go index f5384cdec0f..fabfa5efed8 100644 --- a/adapters/zeta_global_ssp/zeta_global_ssp_test.go +++ b/adapters/zeta_global_ssp/zeta_global_ssp_test.go @@ -10,7 +10,7 @@ import ( func TestJsonSamples(t *testing.T) { bidder, buildErr := Builder(openrtb_ext.BidderZetaGlobalSsp, config.Adapter{ - Endpoint: "http://whatever.url"}, + Endpoint: "https://ssp.disqus.com/bid/prebid-server?sid=11"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) if buildErr != nil { diff --git a/static/bidder-info/zeta_global_ssp.yaml b/static/bidder-info/zeta_global_ssp.yaml index 3cc2ecb5297..479f024c1b7 100644 --- a/static/bidder-info/zeta_global_ssp.yaml +++ b/static/bidder-info/zeta_global_ssp.yaml @@ -1,4 +1,4 @@ -endpoint: https://ssp.disqus.com/bid/prebid-server?sid=GET_SID_FROM_ZETA&shortname=GET_SHORTNAME_FROM_ZETA +endpoint: https://ssp.disqus.com/bid/prebid-server?sid=GET_SID_FROM_ZETA endpointCompression: gzip maintainer: email: DL-Zeta-SSP@zetaglobal.com @@ -15,6 +15,6 @@ capabilities: - video userSync: redirect: - url: https://ssp.disqus.com/redirectuser?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}&partner=GET_SHORTNAME_FROM_ZETA + url: https://ssp.disqus.com/redirectuser?sid=GET_SID_FROM_ZETA&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}} userMacro: 'BUYERUID' From 832fbf2d7c3f207d0e86807536045369b79b30d1 Mon Sep 17 00:00:00 2001 From: Nilesh Chate <97721111+pm-nilesh-chate@users.noreply.github.com> Date: Fri, 17 Nov 2023 00:23:11 +0530 Subject: [PATCH 215/268] PubMatic: Support hardcoded alias (#3224) --- adapters/pubmatic/pubmatic.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/adapters/pubmatic/pubmatic.go b/adapters/pubmatic/pubmatic.go index 17f43ea0f0a..7ab0248b937 100644 --- a/adapters/pubmatic/pubmatic.go +++ b/adapters/pubmatic/pubmatic.go @@ -22,7 +22,8 @@ const MAX_IMPRESSIONS_PUBMATIC = 30 const ae = "ae" type PubmaticAdapter struct { - URI string + URI string + bidderName string } type pubmaticBidExt struct { @@ -640,7 +641,8 @@ func getBidType(bidExt *pubmaticBidExt) openrtb_ext.BidType { // Builder builds a new instance of the Pubmatic adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { bidder := &PubmaticAdapter{ - URI: config.Endpoint, + URI: config.Endpoint, + bidderName: string(bidderName), } return bidder, nil } From 9693797b3d0eb81c71e86c967b5604d202b9a269 Mon Sep 17 00:00:00 2001 From: gg-natalia <148577437+gg-natalia@users.noreply.github.com> Date: Thu, 16 Nov 2023 15:59:47 -0300 Subject: [PATCH 216/268] GumGum: Add product parameter (#3253) --- adapters/gumgum/gumgum.go | 18 ++- .../banner-with-pubId-product-params.json | 104 ++++++++++++++++++ adapters/gumgum/params_test.go | 4 + openrtb_ext/imp_gumgum.go | 9 +- static/bidder-params/gumgum.json | 6 +- 5 files changed, 131 insertions(+), 10 deletions(-) create mode 100644 adapters/gumgum/gumgumtest/supplemental/banner-with-pubId-product-params.json diff --git a/adapters/gumgum/gumgum.go b/adapters/gumgum/gumgum.go index 3b954bf5837..ea9624c73c7 100644 --- a/adapters/gumgum/gumgum.go +++ b/adapters/gumgum/gumgum.go @@ -14,13 +14,13 @@ import ( "github.com/prebid/prebid-server/v2/openrtb_ext" ) -// GumGumAdapter implements Bidder interface. -type GumGumAdapter struct { +// adapter implements Bidder interface. +type adapter struct { URI string } // MakeRequests makes the HTTP requests which should be made to fetch bids. -func (g *GumGumAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { +func (g *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { var validImps []openrtb2.Imp var siteCopy openrtb2.Site if request.Site != nil { @@ -80,7 +80,7 @@ func (g *GumGumAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adap } // MakeBids unpacks the server's response into Bids. -func (g *GumGumAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { +func (g *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { if response.StatusCode == http.StatusNoContent { return nil, nil } @@ -176,6 +176,14 @@ func preprocess(imp *openrtb2.Imp) (*openrtb_ext.ExtImpGumGum, error) { } } + if gumgumExt.Product != "" { + var err error + imp.Ext, err = json.Marshal(map[string]string{"product": gumgumExt.Product}) + if err != nil { + return nil, err + } + } + return &gumgumExt, nil } @@ -223,7 +231,7 @@ func validateVideoParams(video *openrtb2.Video) (err error) { // Builder builds a new instance of the GumGum adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { - bidder := &GumGumAdapter{ + bidder := &adapter{ URI: config.Endpoint, } return bidder, nil diff --git a/adapters/gumgum/gumgumtest/supplemental/banner-with-pubId-product-params.json b/adapters/gumgum/gumgumtest/supplemental/banner-with-pubId-product-params.json new file mode 100644 index 00000000000..6e2793658d3 --- /dev/null +++ b/adapters/gumgum/gumgumtest/supplemental/banner-with-pubId-product-params.json @@ -0,0 +1,104 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 300 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pubId": 12345678 + }, + "product": "skins" + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://g2.gumgum.com/providers/prbds2s/bid", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 300 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pubId": 12345678 + }, + "product": "skins" + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "seatbid": [ + { + "bid": [ + { + "crid": "2068416", + "adm": "some-test-ad", + "adid": "2068416", + "price": 5, + "id": "5736a50b-6b05-42a8-aa6d-b0a4649dcd05", + "impid": "test-imp-id", + "cid": "4747" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "crid": "2068416", + "adm": "some-test-ad", + "adid": "2068416", + "price": 5, + "id": "5736a50b-6b05-42a8-aa6d-b0a4649dcd05", + "impid": "test-imp-id", + "cid": "4747" + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/gumgum/params_test.go b/adapters/gumgum/params_test.go index afee017be03..11874cdbd61 100644 --- a/adapters/gumgum/params_test.go +++ b/adapters/gumgum/params_test.go @@ -37,11 +37,13 @@ var validParams = []string{ `{"zone":"dc9d6be1"}`, `{"pubId":12345678}`, `{"zone":"dc9d6be1", "pubId":12345678}`, + `{"zone":"dc9d6be1", "pubId":12345678, "product": "skins"}`, `{"zone":"dc9d6be1", "slot":1234567}`, `{"pubId":12345678, "slot":1234567}`, `{"pubId":12345678, "irisid": "iris_6f9285823a48bne5"}`, `{"zone":"dc9d6be1", "irisid": "iris_6f9285823a48bne5"}`, `{"zone":"dc9d6be1", "pubId":12345678, "irisid": "iris_6f9285823a48bne5"}`, + `{"zone":"dc9d6be1", "pubId":12345678, "irisid": "iris_6f9285823a48bne5", "product": "skins"}`, } var invalidParams = []string{ @@ -62,4 +64,6 @@ var invalidParams = []string{ `{"zone":"1234567", "irisid": ""}`, `{"zone":"1234567", "irisid": 1234}`, `{"irisid": "iris_6f9285823a48bne5"}`, + `{"product": "test"}`, + `{"product": 12345678}`, } diff --git a/openrtb_ext/imp_gumgum.go b/openrtb_ext/imp_gumgum.go index 96a1308d663..f54234fa394 100644 --- a/openrtb_ext/imp_gumgum.go +++ b/openrtb_ext/imp_gumgum.go @@ -3,10 +3,11 @@ package openrtb_ext // ExtImpGumGum defines the contract for bidrequest.imp[i].ext.prebid.bidder.gumgum // Either Zone or PubId must be present, others are optional parameters type ExtImpGumGum struct { - Zone string `json:"zone,omitempty"` - PubID float64 `json:"pubId,omitempty"` - IrisID string `json:"irisid,omitempty"` - Slot float64 `json:"slot,omitempty"` + Zone string `json:"zone,omitempty"` + PubID float64 `json:"pubId,omitempty"` + IrisID string `json:"irisid,omitempty"` + Slot float64 `json:"slot,omitempty"` + Product string `json:"product,omitempty"` } // ExtImpGumGumVideo defines the contract for bidresponse.seatbid.bid[i].ext.prebid.bidder.gumgum.video diff --git a/static/bidder-params/gumgum.json b/static/bidder-params/gumgum.json index 95f05e7d517..c9972713f87 100644 --- a/static/bidder-params/gumgum.json +++ b/static/bidder-params/gumgum.json @@ -20,6 +20,10 @@ "slot": { "type": "integer", "description": "A slot id used to identify a slot placement mapped to a GumGum zone or publisher" + }, + "product": { + "type": "string", + "description": "Product param that allow support for Desktop Skins - display and video" } }, "anyOf": [ @@ -34,4 +38,4 @@ ] } ] -} +} \ No newline at end of file From 738884f7cc4182f712d679df800f13e847f1ccac Mon Sep 17 00:00:00 2001 From: Sonali-More-Xandr <87759626+Sonali-More-Xandr@users.noreply.github.com> Date: Sat, 18 Nov 2023 02:36:36 +0530 Subject: [PATCH 217/268] Migrate yahooAdvertising alias of yahooAds to use new pattern (#3203) --- exchange/adapter_builders.go | 1 - openrtb_ext/bidders.go | 2 -- openrtb_ext/bidders_validate_test.go | 2 +- static/bidder-info/yahooAdvertising.yaml | 14 +------------- static/bidder-params/yahooAdvertising.json | 19 ------------------- 5 files changed, 2 insertions(+), 36 deletions(-) delete mode 100644 static/bidder-params/yahooAdvertising.json diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index a5179f75d53..2f422ede534 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -382,7 +382,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderVrtcal: vrtcal.Builder, openrtb_ext.BidderXeworks: xeworks.Builder, openrtb_ext.BidderYahooAds: yahooAds.Builder, - openrtb_ext.BidderYahooAdvertising: yahooAds.Builder, openrtb_ext.BidderYahooSSP: yahooAds.Builder, openrtb_ext.BidderYeahmobi: yeahmobi.Builder, openrtb_ext.BidderYieldlab: yieldlab.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index fbd5bb9f787..77113bf5bda 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -204,7 +204,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderVrtcal, BidderXeworks, BidderYahooAds, - BidderYahooAdvertising, BidderYahooSSP, BidderYeahmobi, BidderYieldlab, @@ -486,7 +485,6 @@ const ( BidderVrtcal BidderName = "vrtcal" BidderXeworks BidderName = "xeworks" BidderYahooAds BidderName = "yahooAds" - BidderYahooAdvertising BidderName = "yahooAdvertising" BidderYahooSSP BidderName = "yahoossp" BidderYeahmobi BidderName = "yeahmobi" BidderYieldlab BidderName = "yieldlab" diff --git a/openrtb_ext/bidders_validate_test.go b/openrtb_ext/bidders_validate_test.go index 33148d1ed41..fed606ea439 100644 --- a/openrtb_ext/bidders_validate_test.go +++ b/openrtb_ext/bidders_validate_test.go @@ -50,7 +50,7 @@ func TestBidderUniquenessGatekeeping(t *testing.T) { // - Exclude duplicates of adapters for the same bidder, as it's unlikely a publisher will use both. var bidders []string for _, bidder := range CoreBidderNames() { - if bidder != BidderSilverPush && bidder != BidderTripleliftNative && bidder != BidderAdkernelAdn && bidder != BidderFreewheelSSPOld && bidder != BidderYahooAdvertising { + if bidder != BidderSilverPush && bidder != BidderTripleliftNative && bidder != BidderAdkernelAdn && bidder != BidderFreewheelSSPOld && bidder != "yahooAdvertising" { bidders = append(bidders, string(bidder)) } } diff --git a/static/bidder-info/yahooAdvertising.yaml b/static/bidder-info/yahooAdvertising.yaml index 3798adf7ca2..f9f34fbfbd0 100644 --- a/static/bidder-info/yahooAdvertising.yaml +++ b/static/bidder-info/yahooAdvertising.yaml @@ -1,16 +1,4 @@ -endpoint: "https://s2shb.ssp.yahoo.com/admax/bid/partners/PBS" -maintainer: - email: "hb-fe-tech@yahooinc.com" -gvlVendorID: 25 -capabilities: - app: - mediaTypes: - - banner - - video - site: - mediaTypes: - - banner - - video +aliasOf: yahooAds userSync: # yahooAdvertising supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. diff --git a/static/bidder-params/yahooAdvertising.json b/static/bidder-params/yahooAdvertising.json deleted file mode 100644 index 4778f0778c7..00000000000 --- a/static/bidder-params/yahooAdvertising.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "YahooAdvertising Adapter Params", - "description": "A schema which validates params accepted by the YahooAdvertising adapter", - "type": "object", - "properties": { - "dcn": { - "type": "string", - "minLength": 1, - "description": "Site ID provided by One Mobile" - }, - "pos": { - "type": "string", - "minLength": 1, - "description": "Placement ID" - } - }, - "required": ["dcn", "pos"] -} From 21ee27b948dc501184ea666847de14cbeb1e9de3 Mon Sep 17 00:00:00 2001 From: Sonali-More-Xandr <87759626+Sonali-More-Xandr@users.noreply.github.com> Date: Sat, 18 Nov 2023 02:49:54 +0530 Subject: [PATCH 218/268] Migrate synacormedia alias of imds to use new pattern (#3205) --- exchange/adapter_builders.go | 1 - openrtb_ext/bidders.go | 2 -- static/bidder-info/synacormedia.yaml | 14 +------------- static/bidder-params/synacormedia.json | 19 ------------------- 4 files changed, 1 insertion(+), 35 deletions(-) delete mode 100644 static/bidder-params/synacormedia.json diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 2f422ede534..594833401ba 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -359,7 +359,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderSspBC: sspBC.Builder, openrtb_ext.BidderSuntContent: suntContent.Builder, openrtb_ext.BidderStroeerCore: stroeerCore.Builder, - openrtb_ext.BidderSynacormedia: imds.Builder, openrtb_ext.BidderTaboola: taboola.Builder, openrtb_ext.BidderTappx: tappx.Builder, openrtb_ext.BidderTeads: teads.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 77113bf5bda..77e58fcd8b1 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -181,7 +181,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderSspBC, BidderStroeerCore, BidderSuntContent, - BidderSynacormedia, BidderTaboola, BidderTappx, BidderTeads, @@ -462,7 +461,6 @@ const ( BidderSspBC BidderName = "sspBC" BidderStroeerCore BidderName = "stroeerCore" BidderSuntContent BidderName = "suntContent" - BidderSynacormedia BidderName = "synacormedia" BidderTaboola BidderName = "taboola" BidderTappx BidderName = "tappx" BidderTeads BidderName = "teads" diff --git a/static/bidder-info/synacormedia.yaml b/static/bidder-info/synacormedia.yaml index 2a796ae839f..ccbba0700a4 100644 --- a/static/bidder-info/synacormedia.yaml +++ b/static/bidder-info/synacormedia.yaml @@ -1,15 +1,3 @@ # DEPRECATED: Use imds bidder instead +aliasOf: imds endpoint: "https://pbs.technoratimedia.com/openrtb/bids/{{.AccountID}}?src={{.SourceId}}&adapter=synacormedia" -maintainer: - email: "eng-demand@imds.tv" -capabilities: - app: - mediaTypes: - - banner - - video - site: - mediaTypes: - - banner - - video -userSync: - key: "imds" diff --git a/static/bidder-params/synacormedia.json b/static/bidder-params/synacormedia.json deleted file mode 100644 index 21eb06cc7ce..00000000000 --- a/static/bidder-params/synacormedia.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Synacormedia Adapter Params", - "description": "DEPRECATED: Use imds bidder instead. A schema which validates params accepted by the Synacormedia adapter", - - "type": "object", - "properties": { - "seatId": { - "type": "string", - "description": "The seat id." - }, - "tagId": { - "type": "string", - "description": "The tag id." - } - }, - - "required": ["seatId"] -} From 7e06aae947489da90eb3020e4cd36a62bb9485ca Mon Sep 17 00:00:00 2001 From: Sonali-More-Xandr <87759626+Sonali-More-Xandr@users.noreply.github.com> Date: Sat, 18 Nov 2023 03:37:05 +0530 Subject: [PATCH 219/268] Migrate epsilon alias of conversant to use new pattern (#3207) --- exchange/adapter_builders.go | 1 - openrtb_ext/bidders.go | 2 -- static/bidder-info/epsilon.yaml | 14 +------- static/bidder-params/epsilon.json | 54 ------------------------------- 4 files changed, 1 insertion(+), 70 deletions(-) delete mode 100644 static/bidder-params/epsilon.json diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 594833401ba..b859af01148 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -274,7 +274,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderEmxDigital: cadentaperturemx.Builder, openrtb_ext.BidderEPlanning: eplanning.Builder, openrtb_ext.BidderEpom: epom.Builder, - openrtb_ext.BidderEpsilon: conversant.Builder, openrtb_ext.BidderEVolution: evolution.Builder, openrtb_ext.BidderFlipp: flipp.Builder, openrtb_ext.BidderFreewheelSSP: freewheelssp.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 77e58fcd8b1..a921f981aee 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -96,7 +96,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderEmxDigital, BidderEPlanning, BidderEpom, - BidderEpsilon, BidderEVolution, BidderFlipp, BidderFreewheelSSP, @@ -375,7 +374,6 @@ const ( BidderEmtv BidderName = "emtv" BidderEmxDigital BidderName = "emx_digital" BidderEPlanning BidderName = "eplanning" - BidderEpsilon BidderName = "epsilon" BidderEpom BidderName = "epom" BidderEVolution BidderName = "e_volution" BidderFlipp BidderName = "flipp" diff --git a/static/bidder-info/epsilon.yaml b/static/bidder-info/epsilon.yaml index 856d82a6f3f..828bac6cfc4 100644 --- a/static/bidder-info/epsilon.yaml +++ b/static/bidder-info/epsilon.yaml @@ -1,16 +1,4 @@ -endpoint: "http://api.hb.ad.cpe.dotomi.com/cvx/server/hb/ortb/25" -maintainer: - email: "PublisherIntegration@epsilon.com" -gvlVendorID: 24 -capabilities: - app: - mediaTypes: - - banner - - video - site: - mediaTypes: - - banner - - video +aliasOf: conversant userSync: redirect: url: "https://prebid-match.dotomi.com/match/bounce/current?version=1&networkId=72582&rurl={{.RedirectURL}}" diff --git a/static/bidder-params/epsilon.json b/static/bidder-params/epsilon.json deleted file mode 100644 index a33a68325e4..00000000000 --- a/static/bidder-params/epsilon.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Epsilon Adapter Params", - "description": "A schema which validates params accepted by the Epsilon adapter.", - "type": "object", - "properties": { - "site_id": { - "type": "string", - "description": "An Epsilon specific ID which identifies the site." - }, - "secure": { - "type": "integer", - "description": "Override http/https context on ad markup." - }, - "bidfloor" : { - "type": "number", - "description": "Minimum bid price that will be considered." - }, - "tag_id": { - "type": "string", - "description": "Identifies specific ad placement." - }, - "position": { - "type": "integer", - "description": "Ad position on screen." - }, - "mimes": { - "type": "array", - "description": "Array of content MIME types. For videos only.", - "items": { - "type": "string" - } - }, - "maxduration": { - "type": "integer", - "description": "Maximum duration in seconds. For videos only." - }, - "api": { - "type": "array", - "description": "Array of supported API frameworks. For videos only.", - "items": { - "type": "integer" - } - }, - "protocols": { - "type": "array", - "description": "Array of supported video protocols. For videos only.", - "items": { - "type": "integer" - } - } - }, - "required": ["site_id"] -} \ No newline at end of file From f5f1e072180de52d1f17d9f51cc5e7c38785ca99 Mon Sep 17 00:00:00 2001 From: BrightMountainMedia <69471268+BrightMountainMediaInc@users.noreply.github.com> Date: Sat, 18 Nov 2023 03:45:53 +0530 Subject: [PATCH 220/268] BMTM: app support (#3280) --- .../exemplary/app-banner.json | 105 ++++++++++++++++ .../exemplary/app-video.json | 115 ++++++++++++++++++ static/bidder-info/bmtm.yaml | 4 + 3 files changed, 224 insertions(+) create mode 100644 adapters/bmtm/brightmountainmediatest/exemplary/app-banner.json create mode 100644 adapters/bmtm/brightmountainmediatest/exemplary/app-video.json diff --git a/adapters/bmtm/brightmountainmediatest/exemplary/app-banner.json b/adapters/bmtm/brightmountainmediatest/exemplary/app-banner.json new file mode 100644 index 00000000000..8a02ad8d5ea --- /dev/null +++ b/adapters/bmtm/brightmountainmediatest/exemplary/app-banner.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "placement_id": 329 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com/api/pbs", + "body": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "tagid": "329" + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "bmtm", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 728, + "h": 90 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/bmtm/brightmountainmediatest/exemplary/app-video.json b/adapters/bmtm/brightmountainmediatest/exemplary/app-video.json new file mode 100644 index 00000000000..1dc1a4752f5 --- /dev/null +++ b/adapters/bmtm/brightmountainmediatest/exemplary/app-video.json @@ -0,0 +1,115 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "placement_id": 329 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com/api/pbs", + "body": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "tagid": "329" + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "bmtm", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 728, + "h": 90 + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/static/bidder-info/bmtm.yaml b/static/bidder-info/bmtm.yaml index 2992d0fbc7b..3d3f2ca6e22 100644 --- a/static/bidder-info/bmtm.yaml +++ b/static/bidder-info/bmtm.yaml @@ -3,6 +3,10 @@ maintainer: email: dev@brightmountainmedia.com modifyingVastXmlAllowed: false capabilities: + app: + mediaTypes: + - banner + - video site: mediaTypes: - banner From 515b9372f850f856c8c2f8875c624aa9b9816512 Mon Sep 17 00:00:00 2001 From: Ahmet Faruk Karakus <65093478+ahmetfaruk59@users.noreply.github.com> Date: Mon, 20 Nov 2023 09:06:20 +0300 Subject: [PATCH 221/268] HuaweiAds: Increase fill rate for native ads (#3279) co-authored by @ahmetfaruk59 --- adapters/huaweiads/huaweiads.go | 87 +++-- .../exemplary/nativeIncludeVideo.json | 114 ++++--- .../exemplary/nativeMultiSizesByRange.json | 305 ++++++++++++++++++ .../exemplary/nativeMultiSizesByRatio.json | 305 ++++++++++++++++++ .../exemplary/nativeSingleImage.json | 67 +++- .../exemplary/nativeThreeImage.json | 21 +- .../nativeThreeImageIncludeIcon.json | 71 +++- .../supplemental/bad_response_not_native.json | 67 +++- 8 files changed, 951 insertions(+), 86 deletions(-) create mode 100644 adapters/huaweiads/huaweiadstest/exemplary/nativeMultiSizesByRange.json create mode 100644 adapters/huaweiads/huaweiadstest/exemplary/nativeMultiSizesByRatio.json diff --git a/adapters/huaweiads/huaweiads.go b/adapters/huaweiads/huaweiads.go index 68622bf9f9e..ac4e2446bdc 100644 --- a/adapters/huaweiads/huaweiads.go +++ b/adapters/huaweiads/huaweiads.go @@ -8,6 +8,7 @@ import ( "encoding/json" "errors" "fmt" + "math" "net/http" "net/url" "regexp" @@ -533,11 +534,27 @@ func getNativeFormat(adslot30 *adslot30, openRTBImp *openrtb2.Imp) error { return err } + //popular size for native ads + popularSizes := []map[string]int64{{"w": 225, "h": 150}, {"w": 300, "h": 250}, {"w": 320, "h": 250}, {"w": 640, "h": 360}, {"w": 720, "h": 1280}, {"w": 1080, "h": 170}, {"w": 1080, "h": 430}, {"w": 1080, "h": 432}, {"w": 1080, "h": 504}, {"w": 1080, "h": 607}, {"w": 1080, "h": 1620}, {"w": 1200, "h": 627}, {"w": 1280, "h": 720}, {"w": 1312, "h": 768}, {"w": 1920, "h": 1080}} + // only compute the main image number, type = native1.ImageAssetTypeMain var numMainImage = 0 var numVideo = 0 - var width int64 - var height int64 + var formats = make([]format, 0) + var numFormat = 0 + var detailedCreativeTypeList = make([]string, 0, 2) + + //number of the requested image size + for _, asset := range nativePayload.Assets { + if numFormat > 1 { + break + } + if asset.Img != nil { + if asset.Img.Type == native1.ImageAssetTypeMain { + numFormat++ + } + } + } for _, asset := range nativePayload.Assets { // Only one of the {title,img,video,data} objects should be present in each object. if asset.Video != nil { @@ -548,34 +565,52 @@ func getNativeFormat(adslot30 *adslot30, openRTBImp *openrtb2.Imp) error { if asset.Img != nil { if asset.Img.Type == native1.ImageAssetTypeMain { numMainImage++ - if asset.Img.H != 0 && asset.Img.W != 0 { - width = asset.Img.W - height = asset.Img.H - } else if asset.Img.WMin != 0 && asset.Img.HMin != 0 { - width = asset.Img.WMin - height = asset.Img.HMin + if numFormat > 1 && asset.Img.H != 0 && asset.Img.W != 0 && asset.Img.WMin != 0 && asset.Img.HMin != 0 { + formats = append(formats, format{asset.Img.W, asset.Img.H}) + } + if numFormat == 1 && asset.Img.H != 0 && asset.Img.W != 0 && asset.Img.WMin != 0 && asset.Img.HMin != 0 { + result := filterPopularSizes(popularSizes, asset.Img.W, asset.Img.H, "ratio") + for i := 0; i < len(result); i++ { + formats = append(formats, format{result[i]["w"], result[i]["h"]}) + } + } + if numFormat == 1 && asset.Img.H == 0 && asset.Img.W == 0 && asset.Img.WMin != 0 && asset.Img.HMin != 0 { + result := filterPopularSizes(popularSizes, asset.Img.W, asset.Img.H, "range") + for i := 0; i < len(result); i++ { + formats = append(formats, format{result[i]["w"], result[i]["h"]}) + } } } - continue } + adslot30.Format = formats } - adslot30.W = width - adslot30.H = height - - var detailedCreativeTypeList = make([]string, 0, 2) - if numVideo >= 1 { - detailedCreativeTypeList = append(detailedCreativeTypeList, "903") - } else if numMainImage > 1 { - detailedCreativeTypeList = append(detailedCreativeTypeList, "904") - } else if numMainImage == 1 { - detailedCreativeTypeList = append(detailedCreativeTypeList, "901") - } else { - detailedCreativeTypeList = append(detailedCreativeTypeList, "913", "914") - } + detailedCreativeTypeList = append(detailedCreativeTypeList, "901", "905") adslot30.DetailedCreativeTypeList = detailedCreativeTypeList return nil } +// filter popular size by range or ratio to append format array +func filterPopularSizes(sizes []map[string]int64, width int64, height int64, byWhat string) []map[string]int64 { + + filtered := []map[string]int64{} + for _, size := range sizes { + w := size["w"] + h := size["h"] + + if byWhat == "ratio" { + ratio := float64(width) / float64(height) + diff := math.Abs(float64(w)/float64(h) - ratio) + if diff <= 0.3 { + filtered = append(filtered, size) + } + } + if byWhat == "range" && w > width && h > height { + filtered = append(filtered, size) + } + } + return filtered +} + // roll ad need TotalDuration func getVideoFormat(adslot30 *adslot30, adtype int32, openRTBImp *openrtb2.Imp) error { adslot30.W = openRTBImp.Video.W @@ -960,10 +995,14 @@ func checkRespStatusCode(response *adapters.ResponseData) error { } func checkHuaweiAdsResponseRetcode(response huaweiAdsResponse) error { - if response.Retcode == 200 || response.Retcode == 204 || response.Retcode == 206 { + if response.Retcode == 200 || response.Retcode == 206 { return nil } - + if response.Retcode == 204 { + return &errortypes.BadInput{ + Message: fmt.Sprintf("HuaweiAdsResponse retcode: %d , reason: The request packet is correct, but no advertisement was found for this request.", response.Retcode), + } + } if (response.Retcode < 600 && response.Retcode >= 400) || (response.Retcode < 300 && response.Retcode > 200) { return &errortypes.BadInput{ Message: fmt.Sprintf("HuaweiAdsResponse retcode: %d , reason: %s", response.Retcode, response.Reason), diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json index 673d6a39a99..49562dacc80 100644 --- a/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json +++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json @@ -5,7 +5,7 @@ { "id": "test-imp-id", "native": { - "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"aurlsupport\":0,\"durlsupport\":0,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"privacy\":0,\"assets\":[{\"id\":100,\"title\":{\"len\":90},\"required\":1},{\"id\":101,\"img\":{\"type\":3,\"wmin\":200,\"hmin\":200},\"required\":1},{\"id\":107,\"video\":{\"mimes\":[\"mp4\"],\"minduration\":100,\"maxduration\":100,\"protocols\":[1,2]},\"required\":1},{\"id\":105,\"data\":{\"type\":2,\"len\":90},\"required\":1}],\"ver\":\"1.2\"}", + "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"aurlsupport\":0,\"durlsupport\":0,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"privacy\":0,\"assets\":[{\"id\":100,\"title\":{\"len\":90},\"required\":1},{\"id\":101,\"img\":{\"type\":3,\"w\":200,\"h\":300,\"wmin\":300,\"hmin\":200},\"required\":1},{\"id\":102,\"img\":{\"type\":3,\"w\":400,\"h\":500,\"wmin\":400,\"hmin\":500},\"required\":1},{\"id\":103,\"img\":{\"type\":3,\"w\":300,\"h\":250,\"wmin\":300,\"hmin\":250},\"required\":1},{\"id\":105,\"data\":{\"type\":2,\"len\":90},\"required\":1}],\"ver\":\"1.2\"}", "ver": "1.2" }, "ext": { @@ -21,15 +21,14 @@ } ], "app": { - "bundle": "com.huawei.browser", + "bundle": "com.huawei.p11", "name": "Huawei Browser", "ver": "9.1.0.301" }, "device": { "ua": "useragent", "h": 1920, - "language": "zh", - "geoCountry": "CH", + "language": "en", "model": "COL-TEST", "os": "android", "osv": "10.0.0", @@ -39,12 +38,10 @@ "ip": "152.193.6.74", "pxratio": 23.01, "geo": { - "country": "" + "country": "ARG" } }, "user": { - "id": "db089de9-a62e-4861-a881-0ff15e052516", - "buyeruid": "v4_bidder_token", "ext": { "data": { "gaid": [ @@ -83,9 +80,9 @@ "body": { "app": { "lang": "en", - "country": "ZA", + "country": "AR", "name": "Huawei Browser", - "pkgname": "com.huawei.browser", + "pkgname": "com.example.pkgname2", "version": "9.1.0.301" }, "multislot": [ @@ -93,21 +90,34 @@ "adtype": 3, "slotid": "u42ohmaufh", "detailedCreativeTypeList": [ - "903" + "901", + "905" ], - "h": 200, - "w": 200, + "format": [ + { + "w": 200, + "h": 300 + }, + { + "w": 400, + "h": 500 + }, + { + "w": 300, + "h": 250 + } + ], "test": 1 } ], "device": { "height": 1920, - "language": "zh", + "language": "en", "oaid": "oaid", "os": "android", "type": 4, "ip": "152.193.6.74", - "localeCountry": "ZA", + "localeCountry": "AR", "pxratio": 23.01, "model": "COL-TEST", "width": 1080, @@ -116,7 +126,7 @@ "useragent": "useragent", "version": "10.0.0", "maker": "huawei", - "belongCountry": "ZA" + "belongCountry": "AR" }, "geo": { }, @@ -146,7 +156,7 @@ "metaData": { "adSign": "2", "apkInfo": { - "appIcon": "https://pps-icon.png", + "appIcon": "https://icon.png", "appName": "%E6%89%8B%E6%9C%BA%E6%B7%98%E5%AE%9D", "fileSize": 118902470, "packageName": "com.demo.package", @@ -171,7 +181,16 @@ "height": 160, "imageType": "img", "sha256": "042479eccbda9a8d7d3aa3da73c42486854407835623a30ffff875cb578242d0", - "url": "https://pps-icon.png", + "url": "https://icon1.png", + "width": 160 + }, + { + "checkSha256Flag": 1, + "fileSize": 10797, + "height": 320, + "imageType": "img", + "sha256": "042479eccbda9a8d7d3aa3da73c42486854407835623a30ffff875cb578242d0", + "url": "https://icon2.png", "width": 160 } ], @@ -191,49 +210,51 @@ "sha256": "8baa56fdb2702b9fb044d95b328936160cd245764375cdb25a4ab504f4ae2e19", "url": "http://image2.jpg", "width": 400 + }, + { + "checkSha256Flag": 0, + "height": 300, + "imageType": "img", + "sha256": "8baa56fdb2702b9fb044d95b328936160cd245764375cdb25a4ab504f4ae2e19", + "url": "http://image3.jpg", + "width": 400 } ], "label": "%E6%89%8B%E6%9C%BA%E6%B7%98%E5%AE%9D", "landingPageType": "3", "marketAppId": "C101219405", "title": "%2Ftest%2F", - "description": "this is a test ad", - "videoInfo": { - "autoPlayAreaRatio": 100, - "autoStopPlayAreaRatio": 10, - "checkSha256Flag": 1, - "sha256": "aa08c8ffce82bbcd37cabefd6c8972b407de48f0b4e332e06d4cc18d25377d77", - "timeBeforeVideoAutoPlay": 50, - "videoAutoPlayOnWifi": "y", - "videoAutoPlayWithSound": "n", - "videoDownloadUrl": "https://video.mp4", - "videoDuration": 6038, - "videoFileSize": 949951, - "videoPlayMode": 2, - "videoRatio": 0.5625, - "width": 600, - "height": 500 - } + "description": "this is a test ad" }, "monitor": [ { - "eventType": "vastError", + "eventType": "click", "url": [ - "http://test/vastError" + "http://test/click" ] }, { - "eventType": "click", + "eventType": "imp", "url": [ - "http://test/click", - "http://test/dspclick" + "http://test/imp" ] }, { - "eventType": "imp", + "eventType": "download", + "url": [ + "http://test/download" + ] + }, + { + "eventType": "install", + "url": [ + "http://test/install" + ] + }, + { + "eventType": "downloadstart", "url": [ - "http://test/imp", - "http://test/dspimp" + "http://test/downloadstart" ] }, { @@ -251,8 +272,7 @@ { "eventType": "playEnd", "url": [ - "http://test/playEnd1", - "http://test/playEnd2" + "http://test/playEnd" ] }, { @@ -312,12 +332,12 @@ "huaweiads" ], "crid": "58022259", - "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":100,\"title\":{\"text\":\"/test/\",\"len\":6}},{\"id\":101,\"img\":{\"type\":3,\"url\":\"http://image1.jpg\",\"w\":400,\"h\":350}},{\"id\":107,\"video\":{\"vasttag\":\"HuaweiAds/test/00:00:06.038 \"}},{\"id\":105,\"data\":{\"label\":\"desc\",\"value\":\"this is a test ad\"}}],\"link\":{\"url\":\"https://ads.huawei.com/usermgtportal/home/index.html#/\",\"clicktrackers\":[\"http://test/click\",\"http://test/dspclick\"]},\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"http://test/imp\"},{\"event\":1,\"method\":1,\"url\":\"http://test/dspimp\"}]}", + "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":100,\"title\":{\"text\":\"/test/\",\"len\":6}},{\"id\":101,\"img\":{\"type\":3,\"url\":\"http://image1.jpg\",\"w\":400,\"h\":350}},{\"id\":102,\"img\":{\"type\":3,\"url\":\"http://image2.jpg\",\"w\":400,\"h\":300}},{\"id\":103,\"img\":{\"type\":3,\"url\":\"http://image3.jpg\",\"w\":400,\"h\":300}},{\"id\":105,\"data\":{\"label\":\"desc\",\"value\":\"this is a test ad\"}}],\"link\":{\"url\":\"https://ads.huawei.com/usermgtportal/home/index.html#/\",\"clicktrackers\":[\"http://test/click\"]},\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"http://test/imp\"}]}", "id": "test-imp-id", "impid": "test-imp-id", "price": 2.8, - "h": 500, - "w": 600 + "h": 350, + "w": 400 }, "type": "native" } diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeMultiSizesByRange.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeMultiSizesByRange.json new file mode 100644 index 00000000000..e9128ce1619 --- /dev/null +++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeMultiSizesByRange.json @@ -0,0 +1,305 @@ +{ + "mockBidRequest": { + "id": "test-req-id", + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"aurlsupport\":0,\"durlsupport\":0,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"privacy\":0,\"assets\":[{\"id\":101,\"title\":{\"len\":90},\"required\":1},{\"id\":102,\"img\":{\"type\":3,\"wmin\":225,\"hmin\":150},\"required\":1},{\"id\":103,\"data\":{\"type\":2,\"len\":90},\"required\":1}],\"ver\":\"1.2\"}", + "ver": "1.2" + }, + "ext": { + "bidder": { + "slotid": "u42ohmaufh", + "adtype": "native", + "publisherid": "123", + "signkey": "signkey", + "keyid": "41", + "isTestAuthorization": "true" + } + } + } + ], + "app": { + "bundle": "com.huawei.browser", + "name": "Huawei Browser", + "ver": "9.1.0.301" + }, + "device": { + "ua": "useragent", + "h": 1920, + "language": "en", + "model": "COL-TEST", + "os": "android", + "osv": "10.0.0", + "devicetype": 4, + "make": "huawei", + "w": 1080, + "ip": "ip", + "dnt": 0, + "pxratio": 23.01, + "geo": { + "country": "DEU" + } + }, + "user": { + "ext": { + "data": { + "gaid": [ + "gaid" + ], + "oaid": [ + "oaid" + ], + "clientTime": [ + "2018-11-02 16:34:07.981+1300" + ] + } + } + }, + "ext": { + } + }, + "httpcalls": [ + { + "expectedRequest": { + "uri": "https://adx-dre.op.hicloud.com/ppsadx/getResult", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "User-Agent": [ + "useragent" + ], + "Authorization": [ + "Digest username=123,realm=ppsadx/getResult,nonce=1629473330823,response=d1d61a13a83e1468aa4dff5c8a6cee0b8b381173ca3eb6fa9b313937684d87c0,algorithm=HmacSHA256,usertype=1,keyid=41" + ] + }, + "body": { + "app": { + "lang": "en", + "country": "DE", + "name": "Huawei Browser", + "pkgname": "com.huawei.browser", + "version": "9.1.0.301" + }, + "multislot": [ + { + "adtype": 3, + "slotid": "u42ohmaufh", + "detailedCreativeTypeList": [ + "901", + "905" + ], + "format":[{"w":225,"h":150},{"w":300,"h":250},{"w":320,"h":250},{"w":640,"h":360},{"w":720,"h":1280},{"w":1080,"h":170},{"w":1080,"h":430},{"w":1080,"h":432},{"w":1080,"h":504},{"w":1080,"h":607},{"w":1080,"h":1620},{"w":1200,"h":627},{"w":1280,"h":720},{"w":1312,"h":768},{"w":1920,"h":1080}], + "test": 1 + } + ], + "device": { + "height": 1920, + "language": "en", + "oaid": "oaid", + "os": "android", + "type": 4, + "ip": "ip", + "localeCountry": "DE", + "pxratio": 23.01, + "model": "COL-TEST", + "width": 1080, + "clientTime": "2018-11-02 16:34:07.981+1300", + "gaid": "gaid", + "gaidTrackingEnabled": "1", + "isTrackingEnabled": "1", + "useragent": "useragent", + "version": "10.0.0", + "maker": "huawei", + "belongCountry": "DE" + }, + "geo": { + }, + "network": { + "type": 0 + }, + "regs": { + }, + "version": "3.4", + "clientAdRequestId": "test-req-id" + } + }, + "mockResponse": { + "status": 200, + "body": { + "ctrlSwitchs": "0", + "dsp1cost": 28, + "dspcost": 59, + "multiad": [ + { + "adtype": 3, + "content": [ + { + "contentid": "58022259", + "creativetype": 106, + "ctrlSwitchs": "001011101001010212", + "endtime": 1621344684645, + "interactiontype": 1, + "landingTitle": 1, + "metaData": { + "adSign": "2", + "apkInfo": { + "appDesc": "43+%E4%BA%BF%E6%AC%A1%E5%AE%89%E8%A3%85", + "appIcon": "https://icon.png", + "appName": "demo", + "fileSize": 118902470, + "packageName": "com.demo.package", + "permPromptForCard": "0", + "popNotify": 1, + "popUpAfterInstallNew": 1, + "priorInstallWay": "2", + "sha256": "sha256", + "url": "http://test/url", + "versionCode": "284", + "versionName": "9.6.1.9" + }, + "appId": "101219405", + "appPromotionChannel": "401721412", + "clickUrl": "https://ads.huawei.com/usermgtportal/home/index.html#/", + "cta": "install", + "duration": 6038, + "description": "", + "imageInfo": [ + { + "checkSha256Flag": 0, + "height": 607, + "imageType": "img", + "sha256": "8baa56fdb2702b9fb044d95b328936160cd245764375cdb25a4ab504f4ae2e19", + "url": "http://image.jpg", + "width": 1080 + } + ], + "label": "%E6%89%8B%E6%9C%BA%E6%B7%98%E5%AE%9D", + "landingPageType": "3", + "marketAppId": "C101219405", + "title": "%2Ftest%2F" + }, + "monitor": [ + { + "eventType": "click", + "url": [ + "http://test/click" + ] + }, + { + "eventType": "imp", + "url": [ + "http://test/imp" + ] + }, + { + "eventType": "download", + "url": [ + "http://test/download" + ] + }, + { + "eventType": "install", + "url": [ + "http://test/install" + ] + }, + { + "eventType": "downloadstart", + "url": [ + "http://test/downloadstart" + ] + }, + { + "eventType": "userclose", + "url": [ + "http://test/userclose" + ] + }, + { + "eventType": "playStart", + "url": [ + "http://test/playStart" + ] + }, + { + "eventType": "playEnd", + "url": [ + "http://test/playEnd" + ] + }, + { + "eventType": "playResume", + "url": [ + "http://test/playResume" + ] + }, + { + "eventType": "playPause", + "url": [ + "http://test/playPause" + ] + }, + { + "eventType": "appOpen", + "url": [ + "http://test/appOpen" + ] + } + ], + "paramfromserver": { + "a": "1||test", + "sig": "", + "t": "99990101235959" + }, + "price": 2.8, + "starttime": 1620230400000, + "taskid": "48016632" + } + ], + "retcode30": 200, + "slotid": "u42ohmaufh" + } + ], + "noReportAdTypeEventList": [ + { + "adType": 3, + "eventTypeList": [ + "installFail" + ] + } + ], + "retcode": 200, + "totalCacheSize": 300 + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "adomain": [ + "huaweiads" + ], + "crid": "58022259", + "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":101,\"title\":{\"text\":\"/test/\",\"len\":6}},{\"id\":102,\"img\":{\"type\":3,\"url\":\"http://image.jpg\",\"w\":1080,\"h\":607}},{\"id\":103,\"data\":{\"label\":\"desc\",\"value\":\"\"}}],\"link\":{\"url\":\"https://ads.huawei.com/usermgtportal/home/index.html#/\",\"clicktrackers\":[\"http://test/click\"]},\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"http://test/imp\"}]}", + "id": "test-imp-id", + "impid": "test-imp-id", + "price": 2.8, + "h": 607, + "w": 1080 + }, + "type": "native" + } + ] + } + ] + } \ No newline at end of file diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeMultiSizesByRatio.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeMultiSizesByRatio.json new file mode 100644 index 00000000000..cd21f40ee69 --- /dev/null +++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeMultiSizesByRatio.json @@ -0,0 +1,305 @@ +{ + "mockBidRequest": { + "id": "test-req-id", + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"aurlsupport\":0,\"durlsupport\":0,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"privacy\":0,\"assets\":[{\"id\":101,\"title\":{\"len\":90},\"required\":1},{\"id\":102,\"img\":{\"type\":3,\"w\":225,\"wmin\":225,\"h\":150,\"hmin\":150},\"required\":1},{\"id\":103,\"data\":{\"type\":2,\"len\":90},\"required\":1},{\"id\":104,\"data\":{\"type\":12,\"len\":90},\"required\":1}],\"ver\":\"1.2\"}", + "ver": "1.2" + }, + "ext": { + "bidder": { + "slotid": "u42ohmaufh", + "adtype": "native", + "publisherid": "123", + "signkey": "signkey", + "keyid": "41", + "isTestAuthorization": "true" + } + } + } + ], + "app": { + "bundle": "com.huawei.browser", + "name": "Huawei Browser", + "ver": "9.1.0.301" + }, + "device": { + "ua": "useragent", + "h": 1920, + "language": "en", + "model": "COL-TEST", + "os": "android", + "osv": "10.0.0", + "devicetype": 4, + "make": "huawei", + "w": 1080, + "ip": "ip", + "dnt": 0, + "pxratio": 23.01, + "geo": { + "country": "DEU" + } + }, + "user": { + "ext": { + "data": { + "gaid": [ + "gaid" + ], + "oaid": [ + "oaid" + ], + "clientTime": [ + "2018-11-02 16:34:07.981+1300" + ] + } + } + }, + "ext": { + } + }, + "httpcalls": [ + { + "expectedRequest": { + "uri": "https://adx-dre.op.hicloud.com/ppsadx/getResult", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "User-Agent": [ + "useragent" + ], + "Authorization": [ + "Digest username=123,realm=ppsadx/getResult,nonce=1629473330823,response=d1d61a13a83e1468aa4dff5c8a6cee0b8b381173ca3eb6fa9b313937684d87c0,algorithm=HmacSHA256,usertype=1,keyid=41" + ] + }, + "body": { + "app": { + "lang": "en", + "country": "DE", + "name": "Huawei Browser", + "pkgname": "com.huawei.browser", + "version": "9.1.0.301" + }, + "multislot": [ + { + "adtype": 3, + "slotid": "u42ohmaufh", + "detailedCreativeTypeList": [ + "901", + "905" + ], + "format": [{"w":225,"h":150},{"w":320,"h":250},{"w":640,"h":360},{"w":1080,"h":607},{"w":1280,"h":720},{"w":1312,"h":768},{"w":1920,"h":1080}], + "test": 1 + } + ], + "device": { + "height": 1920, + "language": "en", + "oaid": "oaid", + "os": "android", + "type": 4, + "ip": "ip", + "localeCountry": "DE", + "pxratio": 23.01, + "model": "COL-TEST", + "width": 1080, + "clientTime": "2018-11-02 16:34:07.981+1300", + "gaid": "gaid", + "gaidTrackingEnabled": "1", + "isTrackingEnabled": "1", + "useragent": "useragent", + "version": "10.0.0", + "maker": "huawei", + "belongCountry": "DE" + }, + "geo": { + }, + "network": { + "type": 0 + }, + "regs": { + }, + "version": "3.4", + "clientAdRequestId": "test-req-id" + } + }, + "mockResponse": { + "status": 200, + "body": { + "ctrlSwitchs": "0", + "dsp1cost": 28, + "dspcost": 59, + "multiad": [ + { + "adtype": 3, + "content": [ + { + "contentid": "58022259", + "creativetype": 106, + "ctrlSwitchs": "001011101001010212", + "endtime": 1621344684645, + "interactiontype": 1, + "landingTitle": 1, + "metaData": { + "adSign": "2", + "apkInfo": { + "appDesc": "43+%E4%BA%BF%E6%AC%A1%E5%AE%89%E8%A3%85", + "appIcon": "https://icon.png", + "appName": "demo", + "fileSize": 118902470, + "packageName": "com.demo.package", + "permPromptForCard": "0", + "popNotify": 1, + "popUpAfterInstallNew": 1, + "priorInstallWay": "2", + "sha256": "sha256", + "url": "http://test/url", + "versionCode": "284", + "versionName": "9.6.1.9" + }, + "appId": "101219405", + "appPromotionChannel": "401721412", + "clickUrl": "https://ads.huawei.com/usermgtportal/home/index.html#/", + "cta": "install", + "duration": 6038, + "description": "", + "imageInfo": [ + { + "checkSha256Flag": 0, + "height": 607, + "imageType": "img", + "sha256": "8baa56fdb2702b9fb044d95b328936160cd245764375cdb25a4ab504f4ae2e19", + "url": "http://image.jpg", + "width": 1080 + } + ], + "label": "%E6%89%8B%E6%9C%BA%E6%B7%98%E5%AE%9D", + "landingPageType": "3", + "marketAppId": "C101219405", + "title": "%2Ftest%2F" + }, + "monitor": [ + { + "eventType": "click", + "url": [ + "http://test/click" + ] + }, + { + "eventType": "imp", + "url": [ + "http://test/imp" + ] + }, + { + "eventType": "download", + "url": [ + "http://test/download" + ] + }, + { + "eventType": "install", + "url": [ + "http://test/install" + ] + }, + { + "eventType": "downloadstart", + "url": [ + "http://test/downloadstart" + ] + }, + { + "eventType": "userclose", + "url": [ + "http://test/userclose" + ] + }, + { + "eventType": "playStart", + "url": [ + "http://test/playStart" + ] + }, + { + "eventType": "playEnd", + "url": [ + "http://test/playEnd" + ] + }, + { + "eventType": "playResume", + "url": [ + "http://test/playResume" + ] + }, + { + "eventType": "playPause", + "url": [ + "http://test/playPause" + ] + }, + { + "eventType": "appOpen", + "url": [ + "http://test/appOpen" + ] + } + ], + "paramfromserver": { + "a": "1||test", + "sig": "", + "t": "99990101235959" + }, + "price": 2.8, + "starttime": 1620230400000, + "taskid": "48016632" + } + ], + "retcode30": 200, + "slotid": "u42ohmaufh" + } + ], + "noReportAdTypeEventList": [ + { + "adType": 3, + "eventTypeList": [ + "installFail" + ] + } + ], + "retcode": 200, + "totalCacheSize": 300 + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "adomain": [ + "huaweiads" + ], + "crid": "58022259", + "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":101,\"title\":{\"text\":\"/test/\",\"len\":6}},{\"id\":102,\"img\":{\"type\":3,\"url\":\"http://image.jpg\",\"w\":1080,\"h\":607}},{\"id\":103,\"data\":{\"label\":\"desc\",\"value\":\"\"}},{\"id\":104,\"data\":{\"type\":12,\"value\":\"install\"}}],\"link\":{\"url\":\"https://ads.huawei.com/usermgtportal/home/index.html#/\",\"clicktrackers\":[\"http://test/click\"]},\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"http://test/imp\"}]}", + "id": "test-imp-id", + "impid": "test-imp-id", + "price": 2.8, + "h": 607, + "w": 1080 + }, + "type": "native" + } + ] + } + ] + } \ No newline at end of file diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json index d296010cc77..c422f92b23d 100644 --- a/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json +++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json @@ -91,10 +91,71 @@ "adtype": 3, "slotid": "u42ohmaufh", "detailedCreativeTypeList": [ - "901" + "901", + "905" ], - "h": 200, - "w": 200, + "format": [ + { + "w": 225, + "h": 150 + }, + { + "w": 300, + "h": 250 + }, + { + "w": 320, + "h": 250 + }, + { + "w": 640, + "h": 360 + }, + { + "w": 720, + "h": 1280 + }, + { + "w": 1080, + "h": 170 + }, + { + "w": 1080, + "h": 430 + }, + { + "w": 1080, + "h": 432 + }, + { + "w": 1080, + "h": 504 + }, + { + "w": 1080, + "h": 607 + }, + { + "w": 1080, + "h": 1620 + }, + { + "w": 1200, + "h": 627 + }, + { + "w": 1280, + "h": 720 + }, + { + "w": 1312, + "h": 768 + }, + { + "w": 1920, + "h": 1080 + } + ], "test": 1 } ], diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json index 16313a5588a..49562dacc80 100644 --- a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json +++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json @@ -5,7 +5,7 @@ { "id": "test-imp-id", "native": { - "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"aurlsupport\":0,\"durlsupport\":0,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"privacy\":0,\"assets\":[{\"id\":100,\"title\":{\"len\":90},\"required\":1},{\"id\":101,\"img\":{\"type\":3,\"wmin\":200,\"hmin\":200},\"required\":1},{\"id\":102,\"img\":{\"type\":3,\"w\":200,\"h\":200},\"required\":1},{\"id\":103,\"img\":{\"type\":3,\"wmin\":200,\"hmin\":200},\"required\":1},{\"id\":105,\"data\":{\"type\":2,\"len\":90},\"required\":1}],\"ver\":\"1.2\"}", + "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"aurlsupport\":0,\"durlsupport\":0,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"privacy\":0,\"assets\":[{\"id\":100,\"title\":{\"len\":90},\"required\":1},{\"id\":101,\"img\":{\"type\":3,\"w\":200,\"h\":300,\"wmin\":300,\"hmin\":200},\"required\":1},{\"id\":102,\"img\":{\"type\":3,\"w\":400,\"h\":500,\"wmin\":400,\"hmin\":500},\"required\":1},{\"id\":103,\"img\":{\"type\":3,\"w\":300,\"h\":250,\"wmin\":300,\"hmin\":250},\"required\":1},{\"id\":105,\"data\":{\"type\":2,\"len\":90},\"required\":1}],\"ver\":\"1.2\"}", "ver": "1.2" }, "ext": { @@ -90,10 +90,23 @@ "adtype": 3, "slotid": "u42ohmaufh", "detailedCreativeTypeList": [ - "904" + "901", + "905" ], - "h": 200, - "w": 200, + "format": [ + { + "w": 200, + "h": 300 + }, + { + "w": 400, + "h": 500 + }, + { + "w": 300, + "h": 250 + } + ], "test": 1 } ], diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json index 6122af732c2..a11f2ca89c8 100644 --- a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json +++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json @@ -5,7 +5,7 @@ { "id": "test-imp-id", "native": { - "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"aurlsupport\":0,\"durlsupport\":0,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"privacy\":0,\"assets\":[{\"id\":100,\"title\":{\"len\":90},\"required\":1},{\"id\":101,\"img\":{\"type\":3,\"wmin\":200,\"hmin\":200},\"required\":1},{\"id\":102,\"img\":{\"type\":1,\"w\":20,\"h\":20},\"required\":1},{\"id\":103,\"img\":{\"type\":3,\"wmin\":200,\"hmin\":200},\"required\":1},{\"id\":105,\"data\":{\"type\":2,\"len\":90},\"required\":1}],\"ver\":\"1.2\"}", + "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"aurlsupport\":0,\"durlsupport\":0,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"privacy\":0,\"assets\":[{\"id\":100,\"title\":{\"len\":90},\"required\":1},{\"id\":101,\"img\":{\"type\":3,\"wmin\":200,\"hmin\":200},\"required\":1},{\"id\":102,\"img\":{\"type\":1,\"w\":20,\"h\":20},\"required\":1},{\"id\":105,\"data\":{\"type\":2,\"len\":90},\"required\":1}],\"ver\":\"1.2\"}", "ver": "1.2" }, "ext": { @@ -91,10 +91,71 @@ "adtype": 3, "slotid": "u42ohmaufh", "detailedCreativeTypeList": [ - "904" + "901", + "905" ], - "h": 200, - "w": 200, + "format": [ + { + "w": 225, + "h": 150 + }, + { + "w": 300, + "h": 250 + }, + { + "w": 320, + "h": 250 + }, + { + "w": 640, + "h": 360 + }, + { + "w": 720, + "h": 1280 + }, + { + "w": 1080, + "h": 170 + }, + { + "w": 1080, + "h": 430 + }, + { + "w": 1080, + "h": 432 + }, + { + "w": 1080, + "h": 504 + }, + { + "w": 1080, + "h": 607 + }, + { + "w": 1080, + "h": 1620 + }, + { + "w": 1200, + "h": 627 + }, + { + "w": 1280, + "h": 720 + }, + { + "w": 1312, + "h": 768 + }, + { + "w": 1920, + "h": 1080 + } + ], "test": 1 } ], @@ -320,7 +381,7 @@ "huaweiads" ], "crid": "58022259", - "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":100,\"title\":{\"text\":\"/test/\",\"len\":6}},{\"id\":101,\"img\":{\"type\":3,\"url\":\"http://image1.jpg\",\"w\":400,\"h\":350}},{\"id\":102,\"img\":{\"type\":1,\"url\":\"https://icon1.png\",\"w\":160,\"h\":160}},{\"id\":103,\"img\":{\"type\":3,\"url\":\"http://image2.jpg\",\"w\":400,\"h\":300}},{\"id\":105,\"data\":{\"label\":\"desc\",\"value\":\"this is a test ad\"}}],\"link\":{\"url\":\"https://ads.huawei.com/usermgtportal/home/index.html#/\",\"clicktrackers\":[\"http://test/click\"]},\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"http://test/imp\"}]}", + "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":100,\"title\":{\"text\":\"/test/\",\"len\":6}},{\"id\":101,\"img\":{\"type\":3,\"url\":\"http://image1.jpg\",\"w\":400,\"h\":350}},{\"id\":102,\"img\":{\"type\":1,\"url\":\"https://icon1.png\",\"w\":160,\"h\":160}},{\"id\":105,\"data\":{\"label\":\"desc\",\"value\":\"this is a test ad\"}}],\"link\":{\"url\":\"https://ads.huawei.com/usermgtportal/home/index.html#/\",\"clicktrackers\":[\"http://test/click\"]},\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"http://test/imp\"}]}", "id": "test-imp-id", "impid": "test-imp-id", "price": 2.8, diff --git a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json index c38bc9f69b9..20cfb2b82f5 100644 --- a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json +++ b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json @@ -92,10 +92,71 @@ "slotid": "m8x9x3rzff", "test": 1, "detailedCreativeTypeList": [ - "903" + "901", + "905" ], - "h": 200, - "w": 200 + "format": [ + { + "w": 225, + "h": 150 + }, + { + "w": 300, + "h": 250 + }, + { + "w": 320, + "h": 250 + }, + { + "w": 640, + "h": 360 + }, + { + "w": 720, + "h": 1280 + }, + { + "w": 1080, + "h": 170 + }, + { + "w": 1080, + "h": 430 + }, + { + "w": 1080, + "h": 432 + }, + { + "w": 1080, + "h": 504 + }, + { + "w": 1080, + "h": 607 + }, + { + "w": 1080, + "h": 1620 + }, + { + "w": 1200, + "h": 627 + }, + { + "w": 1280, + "h": 720 + }, + { + "w": 1312, + "h": 768 + }, + { + "w": 1920, + "h": 1080 + } + ] } ], "device": { From cad9097fd5731c5042a13747eb5220152e6a7a5d Mon Sep 17 00:00:00 2001 From: Hasan Kanjee <55110940+hasan-kanjee@users.noreply.github.com> Date: Mon, 20 Nov 2023 01:27:55 -0500 Subject: [PATCH 222/268] Flipp: abide by privacy concerns when using flippExt userKey (#3250) --- adapters/flipp/flipp.go | 50 ++++- adapters/flipp/flipp_test.go | 54 ++++++ ...ple-banner-native-param-transmit-eids.json | 181 ++++++++++++++++++ ...simple-banner-native-param-user-coppa.json | 177 +++++++++++++++++ .../simple-banner-native-param-user-gdpr.json | 177 +++++++++++++++++ .../simple-banner-native-param-user.json | 5 + 6 files changed, 640 insertions(+), 4 deletions(-) create mode 100644 adapters/flipp/flipptest/exemplary/simple-banner-native-param-transmit-eids.json create mode 100644 adapters/flipp/flipptest/exemplary/simple-banner-native-param-user-coppa.json create mode 100644 adapters/flipp/flipptest/exemplary/simple-banner-native-param-user-gdpr.json diff --git a/adapters/flipp/flipp.go b/adapters/flipp/flipp.go index c119ec078cc..e758ec741b2 100644 --- a/adapters/flipp/flipp.go +++ b/adapters/flipp/flipp.go @@ -1,6 +1,7 @@ package flipp import ( + "encoding/base64" "encoding/json" "fmt" "net/http" @@ -8,11 +9,13 @@ import ( "strings" "github.com/buger/jsonparser" - "github.com/gofrs/uuid" + "github.com/prebid/go-gdpr/consentconstants" + "github.com/prebid/go-gdpr/vendorconsent" "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/v2/adapters" "github.com/prebid/prebid-server/v2/config" "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/util/uuidutil" ) const ( @@ -22,6 +25,8 @@ const ( defaultCurrency = "USD" ) +var uuidGenerator uuidutil.UUIDGenerator + var ( count int64 = 1 adTypes = []int64{4309, 641} @@ -34,6 +39,7 @@ type adapter struct { // Builder builds a new instance of the Flipp adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + uuidGenerator = uuidutil.UUIDRandomGenerator{} bidder := &adapter{ endpoint: config.Endpoint, } @@ -123,14 +129,15 @@ func (a *adapter) processImp(request *openrtb2.BidRequest, imp openrtb2.Imp) (*a var userKey string if request.User != nil && request.User.ID != "" { userKey = request.User.ID - } else if flippExtParams.UserKey != "" { + } else if flippExtParams.UserKey != "" && paramsUserKeyPermitted(request) { userKey = flippExtParams.UserKey } else { - uid, err := uuid.NewV4() + + uid, err := uuidGenerator.Generate() if err != nil { return nil, fmt.Errorf("unable to generate user uuid. %v", err) } - userKey = uid.String() + userKey = uid } keywordsArray := strings.Split(request.Site.Keywords, ",") @@ -223,3 +230,38 @@ func buildBid(decision *InlineModel, impId string) *openrtb2.Bid { } return bid } + +func paramsUserKeyPermitted(request *openrtb2.BidRequest) bool { + if request.Regs != nil { + if request.Regs.COPPA == 1 { + return false + } + if request.Regs.GDPR != nil && *request.Regs.GDPR == 1 { + return false + } + } + if request.Ext != nil { + var extData struct { + TransmitEids *bool `json:"transmitEids,omitempty"` + } + if err := json.Unmarshal(request.Ext, &extData); err == nil { + if extData.TransmitEids != nil && !*extData.TransmitEids { + return false + } + } + } + if request.User != nil && request.User.Consent != "" { + data, err := base64.RawURLEncoding.DecodeString(request.User.Consent) + if err != nil { + return true + } + consent, err := vendorconsent.Parse(data) + if err != nil { + return true + } + if !consent.PurposeAllowed(consentconstants.ContentSelectionDeliveryReporting) { + return false + } + } + return true +} diff --git a/adapters/flipp/flipp_test.go b/adapters/flipp/flipp_test.go index e9ba0d138fd..310b7e145d9 100644 --- a/adapters/flipp/flipp_test.go +++ b/adapters/flipp/flipp_test.go @@ -1,17 +1,29 @@ package flipp import ( + "encoding/json" "testing" + "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/v2/adapters/adapterstest" "github.com/prebid/prebid-server/v2/config" "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/stretchr/testify/assert" ) +const fakeUuid = "30470a14-2949-4110-abce-b62d57304ad5" + +type TestUUIDGenerator struct{} + +func (TestUUIDGenerator) Generate() (string, error) { + return fakeUuid, nil +} + func TestJsonSamples(t *testing.T) { bidder, buildErr := Builder(openrtb_ext.BidderFlipp, config.Adapter{ Endpoint: "http://example.com/pserver"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + uuidGenerator = TestUUIDGenerator{} if buildErr != nil { t.Fatalf("Builder returned unexpected error %v", buildErr) @@ -19,3 +31,45 @@ func TestJsonSamples(t *testing.T) { adapterstest.RunJSONBidderTest(t, "flipptest", bidder) } + +func TestParamsUserKeyPermitted(t *testing.T) { + + t.Run("Coppa is in effect", func(t *testing.T) { + request := &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + COPPA: 1, + }, + } + result := paramsUserKeyPermitted(request) + assert.New(t) + assert.False(t, result, "param user key not permitted because coppa is in effect") + }) + t.Run("The Global Privacy Control is set", func(t *testing.T) { + request := &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GDPR: openrtb2.Int8Ptr(1), + }, + } + result := paramsUserKeyPermitted(request) + assert.New(t) + assert.False(t, result, "param user key not permitted because Global Privacy Control is set") + }) + t.Run("The Prebid transmitEids activity is disallowed", func(t *testing.T) { + extData := struct { + TransmitEids bool `json:"transmitEids"` + }{ + TransmitEids: false, + } + ext, err := json.Marshal(extData) + if err != nil { + t.Fatalf("failed to marshal ext data: %v", err) + } + request := &openrtb2.BidRequest{ + Ext: ext, + } + + result := paramsUserKeyPermitted(request) + assert.New(t) + assert.False(t, result, "param user key not permitted because Prebid transmitEids activity is disallowed") + }) +} diff --git a/adapters/flipp/flipptest/exemplary/simple-banner-native-param-transmit-eids.json b/adapters/flipp/flipptest/exemplary/simple-banner-native-param-transmit-eids.json new file mode 100644 index 00000000000..77ba527b5cf --- /dev/null +++ b/adapters/flipp/flipptest/exemplary/simple-banner-native-param-transmit-eids.json @@ -0,0 +1,181 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "test": 1, + "device": { + "ip": "123.123.123.123" + }, + "site": { + "id": "1243066", + "page": "http://www.example.com/test?flipp-content-code=publisher-test" + }, + "user": { + }, + "ext": { + "transmitEids": false + }, + "regs": { + "coppa": 0, + "gdpr": 0 + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 1800 + } + ] + }, + "ext": { + "bidder": { + "publisherNameIdentifier": "wishabi-test-publisher", + "creativeType": "NativeX", + "siteId": 1243066, + "zoneIds": [285431], + "options": { + "startCompact": true + }, + "userKey": "abc123" + } + } + } + + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://example.com/pserver", + "body": { + "ip":"123.123.123.123", + "keywords":[ + "" + ], + "placements":[ + { + "adTypes":[ + 4309, + 641 + ], + "count":1, + "divName":"inline", + "prebid":{ + "creativeType":"NativeX", + "height":1800, + "publisherNameIdentifier":"wishabi-test-publisher", + "requestId":"test-imp-id", + "width":300 + }, + "properties":{ + "contentCode":"publisher-test" + }, + "siteId":1243066, + "zoneIds":[ + 285431 + ], + "options": { + "startCompact": true + } + } + ], + "url":"http://www.example.com/test?flipp-content-code=publisher-test", + "user":{ + "key":"30470a14-2949-4110-abce-b62d57304ad5" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "decisions": { + "inline": [ + { + "adId": 183599115, + "advertiserId": 1988027, + "campaignId": 63285392, + "clickUrl": "https://e-11090.adzerk.net/r?e=eyJ2IjoiMS4xMSIsImF2IjoxOTg4MDI3LCJhdCI6NDMwOSwiYnQiOjAsImNtIjo2MzI4NTM5MiwiY2giOjU4MDgxLCJjayI6e30sImNyIjo4MTMyNTY5MCwiZGkiOiJiOTg3MGNkYTA5MTU0NDlmOTkwZGNkZTNmNjYyNGNhMyIsImRqIjowLCJpaSI6IjJmNjYwMjMyODBmYjQ4NTRiYTY0YzFlYzA1ZDU5MTNiIiwiZG0iOjMsImZjIjoxODM1OTkxMTUsImZsIjoxNzU0MjE3OTUsImlwIjoiMTQyLjE4MS41OC41MiIsIm53IjoxMDkyMiwicGMiOjAsIm9wIjowLCJlYyI6MCwiZ20iOjAsImVwIjpudWxsLCJwciI6MjMyNjk5LCJydCI6MywicnMiOjUwMCwic2EiOiIzNCIsInNiIjoiaS0wNDZjMWNlNWRjYmExMTVjNSIsInNwIjozNzIzMDU1LCJzdCI6MTI0MzA2NiwidWsiOiJkOTU1N2Q2NS1kNWI5LTQyOTItYjg2My0xNGEyOTcyNTk3ZjQiLCJ6biI6Mjg1NDMxLCJ0cyI6MTY4MDU1NTc4MzkyMiwicG4iOiJpbmxpbmUiLCJnYyI6dHJ1ZSwiZ0MiOnRydWUsImdzIjoibm9uZSIsInR6IjoiQW1lcmljYS9OZXdfWW9yayIsInVyIjoiaHR0cDovL3d3dy5mbGlwcC5jb20ifQ&s=Mnss8P1kc37Eftik5RJvLJb4S9Y", + "contents": [ + { + "data": { + "customData": { + "campaignConfigUrl": "https://campaign-config.flipp.com/dist-campaign-admin/215", + "campaignNameIdentifier": "US Grocery Demo (Kroger)" + }, + "height": 1800, + "width": 300 + }, + "type": "raw" + } + ], + "creativeId": 81325690, + "flightId": 175421795, + "height": 1800, + "impressionUrl": "https://e-11090.adzerk.net/i.gif?e=eyJ2IjoiMS4xMSIsImF2IjoxOTg4MDI3LCJhdCI6NDMwOSwiYnQiOjAsImNtIjo2MzI4NTM5MiwiY2giOjU4MDgxLCJjayI6e30sImNyIjo4MTMyNTY5MCwiZGkiOiJiOTg3MGNkYTA5MTU0NDlmOTkwZGNkZTNmNjYyNGNhMyIsImRqIjowLCJpaSI6IjJmNjYwMjMyODBmYjQ4NTRiYTY0YzFlYzA1ZDU5MTNiIiwiZG0iOjMsImZjIjoxODM1OTkxMTUsImZsIjoxNzU0MjE3OTUsImlwIjoiMTQyLjE4MS41OC41MiIsIm53IjoxMDkyMiwicGMiOjAsIm9wIjowLCJlYyI6MCwiZ20iOjAsImVwIjpudWxsLCJwciI6MjMyNjk5LCJydCI6MywicnMiOjUwMCwic2EiOiIzNCIsInNiIjoiaS0wNDZjMWNlNWRjYmExMTVjNSIsInNwIjozNzIzMDU1LCJzdCI6MTI0MzA2NiwidWsiOiJkOTU1N2Q2NS1kNWI5LTQyOTItYjg2My0xNGEyOTcyNTk3ZjQiLCJ6biI6Mjg1NDMxLCJ0cyI6MTY4MDU1NTc4MzkyMywicG4iOiJpbmxpbmUiLCJnYyI6dHJ1ZSwiZ0MiOnRydWUsImdzIjoibm9uZSIsInR6IjoiQW1lcmljYS9OZXdfWW9yayIsImJhIjoxLCJmcSI6MH0&s=Qce4_IohtESeNA_sB71Qjb4TouY", + "prebid": { + "cpm": 12.34, + "creative":"creativeContent", + "creativeType": "NativeX", + "requestId": "test-imp-id" + }, + "priorityId": 232699, + "storefront": { + "campaignConfig": { + "fallbackImageUrl": "https://f.wishabi.net/arbitrary_files/115856/1666018811/115856_Featured Local Savings - Flipp Fallback - US (1).png", + "fallbackLinkUrl": "https://flipp.com/flyers/", + "tags": { + "advertiser": { + "engagement": "https://f.wishabi.net/creative/happyfruits/_itemlevelv2/apple.png?cb=[[random]]" + } + } + }, + "flyer_id": 5554080, + "flyer_run_id": 873256, + "flyer_type_id": 2826, + "is_fallback": true, + "merchant": "Kroger", + "merchant_id": 2778, + "name": "Weekly Ad", + "storefront_logo_url": "https://images.wishabi.net/merchants/qX1/BGIzc9sFcA==/RackMultipart20210421-1-e3k5rx.jpeg", + "storefront_payload_url": "https://cdn-gateflipp.flippback.com/storefront-payload/v2/873256/5554080/ff14f675705934507c269b5750e124a323bc9bf60e8a6f210f422f4528b233ff?merchant_id=2778", + "valid_from": "2023-03-29 04:00:00 +0000 UTC", + "valid_to": "2023-04-05 03:59:59 +0000 UTC" + }, + "width": 300 + } + ] + }, + "location": { + "accuracy_radius": 5, + "city": "Toronto", + "country": "CA", + "ip": "123.123.123.123", + "postal_code": "M4S", + "region": "ON", + "region_name": "Ontario" + } + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "183599115", + "impid": "test-imp-id", + "price": 12.34, + "adm": "creativeContent", + "crid": "81325690", + "w": 300 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/flipp/flipptest/exemplary/simple-banner-native-param-user-coppa.json b/adapters/flipp/flipptest/exemplary/simple-banner-native-param-user-coppa.json new file mode 100644 index 00000000000..f61f6d9d710 --- /dev/null +++ b/adapters/flipp/flipptest/exemplary/simple-banner-native-param-user-coppa.json @@ -0,0 +1,177 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "test": 1, + "device": { + "ip": "123.123.123.123" + }, + "site": { + "id": "1243066", + "page": "http://www.example.com/test?flipp-content-code=publisher-test" + }, + "regs": { + "coppa": 1 + }, + "user": { + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 1800 + } + ] + }, + "ext": { + "bidder": { + "publisherNameIdentifier": "wishabi-test-publisher", + "creativeType": "NativeX", + "siteId": 1243066, + "zoneIds": [285431], + "options": { + "startCompact": true + }, + "userKey": "abc123" + } + } + } + + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://example.com/pserver", + "body": { + "ip":"123.123.123.123", + "keywords":[ + "" + ], + "placements":[ + { + "adTypes":[ + 4309, + 641 + ], + "count":1, + "divName":"inline", + "prebid":{ + "creativeType":"NativeX", + "height":1800, + "publisherNameIdentifier":"wishabi-test-publisher", + "requestId":"test-imp-id", + "width":300 + }, + "properties":{ + "contentCode":"publisher-test" + }, + "siteId":1243066, + "zoneIds":[ + 285431 + ], + "options": { + "startCompact": true + } + } + ], + "url":"http://www.example.com/test?flipp-content-code=publisher-test", + "user":{ + "key":"30470a14-2949-4110-abce-b62d57304ad5" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "decisions": { + "inline": [ + { + "adId": 183599115, + "advertiserId": 1988027, + "campaignId": 63285392, + "clickUrl": "https://e-11090.adzerk.net/r?e=eyJ2IjoiMS4xMSIsImF2IjoxOTg4MDI3LCJhdCI6NDMwOSwiYnQiOjAsImNtIjo2MzI4NTM5MiwiY2giOjU4MDgxLCJjayI6e30sImNyIjo4MTMyNTY5MCwiZGkiOiJiOTg3MGNkYTA5MTU0NDlmOTkwZGNkZTNmNjYyNGNhMyIsImRqIjowLCJpaSI6IjJmNjYwMjMyODBmYjQ4NTRiYTY0YzFlYzA1ZDU5MTNiIiwiZG0iOjMsImZjIjoxODM1OTkxMTUsImZsIjoxNzU0MjE3OTUsImlwIjoiMTQyLjE4MS41OC41MiIsIm53IjoxMDkyMiwicGMiOjAsIm9wIjowLCJlYyI6MCwiZ20iOjAsImVwIjpudWxsLCJwciI6MjMyNjk5LCJydCI6MywicnMiOjUwMCwic2EiOiIzNCIsInNiIjoiaS0wNDZjMWNlNWRjYmExMTVjNSIsInNwIjozNzIzMDU1LCJzdCI6MTI0MzA2NiwidWsiOiJkOTU1N2Q2NS1kNWI5LTQyOTItYjg2My0xNGEyOTcyNTk3ZjQiLCJ6biI6Mjg1NDMxLCJ0cyI6MTY4MDU1NTc4MzkyMiwicG4iOiJpbmxpbmUiLCJnYyI6dHJ1ZSwiZ0MiOnRydWUsImdzIjoibm9uZSIsInR6IjoiQW1lcmljYS9OZXdfWW9yayIsInVyIjoiaHR0cDovL3d3dy5mbGlwcC5jb20ifQ&s=Mnss8P1kc37Eftik5RJvLJb4S9Y", + "contents": [ + { + "data": { + "customData": { + "campaignConfigUrl": "https://campaign-config.flipp.com/dist-campaign-admin/215", + "campaignNameIdentifier": "US Grocery Demo (Kroger)" + }, + "height": 1800, + "width": 300 + }, + "type": "raw" + } + ], + "creativeId": 81325690, + "flightId": 175421795, + "height": 1800, + "impressionUrl": "https://e-11090.adzerk.net/i.gif?e=eyJ2IjoiMS4xMSIsImF2IjoxOTg4MDI3LCJhdCI6NDMwOSwiYnQiOjAsImNtIjo2MzI4NTM5MiwiY2giOjU4MDgxLCJjayI6e30sImNyIjo4MTMyNTY5MCwiZGkiOiJiOTg3MGNkYTA5MTU0NDlmOTkwZGNkZTNmNjYyNGNhMyIsImRqIjowLCJpaSI6IjJmNjYwMjMyODBmYjQ4NTRiYTY0YzFlYzA1ZDU5MTNiIiwiZG0iOjMsImZjIjoxODM1OTkxMTUsImZsIjoxNzU0MjE3OTUsImlwIjoiMTQyLjE4MS41OC41MiIsIm53IjoxMDkyMiwicGMiOjAsIm9wIjowLCJlYyI6MCwiZ20iOjAsImVwIjpudWxsLCJwciI6MjMyNjk5LCJydCI6MywicnMiOjUwMCwic2EiOiIzNCIsInNiIjoiaS0wNDZjMWNlNWRjYmExMTVjNSIsInNwIjozNzIzMDU1LCJzdCI6MTI0MzA2NiwidWsiOiJkOTU1N2Q2NS1kNWI5LTQyOTItYjg2My0xNGEyOTcyNTk3ZjQiLCJ6biI6Mjg1NDMxLCJ0cyI6MTY4MDU1NTc4MzkyMywicG4iOiJpbmxpbmUiLCJnYyI6dHJ1ZSwiZ0MiOnRydWUsImdzIjoibm9uZSIsInR6IjoiQW1lcmljYS9OZXdfWW9yayIsImJhIjoxLCJmcSI6MH0&s=Qce4_IohtESeNA_sB71Qjb4TouY", + "prebid": { + "cpm": 12.34, + "creative":"creativeContent", + "creativeType": "NativeX", + "requestId": "test-imp-id" + }, + "priorityId": 232699, + "storefront": { + "campaignConfig": { + "fallbackImageUrl": "https://f.wishabi.net/arbitrary_files/115856/1666018811/115856_Featured Local Savings - Flipp Fallback - US (1).png", + "fallbackLinkUrl": "https://flipp.com/flyers/", + "tags": { + "advertiser": { + "engagement": "https://f.wishabi.net/creative/happyfruits/_itemlevelv2/apple.png?cb=[[random]]" + } + } + }, + "flyer_id": 5554080, + "flyer_run_id": 873256, + "flyer_type_id": 2826, + "is_fallback": true, + "merchant": "Kroger", + "merchant_id": 2778, + "name": "Weekly Ad", + "storefront_logo_url": "https://images.wishabi.net/merchants/qX1/BGIzc9sFcA==/RackMultipart20210421-1-e3k5rx.jpeg", + "storefront_payload_url": "https://cdn-gateflipp.flippback.com/storefront-payload/v2/873256/5554080/ff14f675705934507c269b5750e124a323bc9bf60e8a6f210f422f4528b233ff?merchant_id=2778", + "valid_from": "2023-03-29 04:00:00 +0000 UTC", + "valid_to": "2023-04-05 03:59:59 +0000 UTC" + }, + "width": 300 + } + ] + }, + "location": { + "accuracy_radius": 5, + "city": "Toronto", + "country": "CA", + "ip": "123.123.123.123", + "postal_code": "M4S", + "region": "ON", + "region_name": "Ontario" + } + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "183599115", + "impid": "test-imp-id", + "price": 12.34, + "adm": "creativeContent", + "crid": "81325690", + "w": 300 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/flipp/flipptest/exemplary/simple-banner-native-param-user-gdpr.json b/adapters/flipp/flipptest/exemplary/simple-banner-native-param-user-gdpr.json new file mode 100644 index 00000000000..446ecd7d3f1 --- /dev/null +++ b/adapters/flipp/flipptest/exemplary/simple-banner-native-param-user-gdpr.json @@ -0,0 +1,177 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "test": 1, + "device": { + "ip": "123.123.123.123" + }, + "site": { + "id": "1243066", + "page": "http://www.example.com/test?flipp-content-code=publisher-test" + }, + "user": { + }, + "regs": { + "gdpr": 1 + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 1800 + } + ] + }, + "ext": { + "bidder": { + "publisherNameIdentifier": "wishabi-test-publisher", + "creativeType": "NativeX", + "siteId": 1243066, + "zoneIds": [285431], + "options": { + "startCompact": true + }, + "userKey": "abc123" + } + } + } + + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://example.com/pserver", + "body": { + "ip":"123.123.123.123", + "keywords":[ + "" + ], + "placements":[ + { + "adTypes":[ + 4309, + 641 + ], + "count":1, + "divName":"inline", + "prebid":{ + "creativeType":"NativeX", + "height":1800, + "publisherNameIdentifier":"wishabi-test-publisher", + "requestId":"test-imp-id", + "width":300 + }, + "properties":{ + "contentCode":"publisher-test" + }, + "siteId":1243066, + "zoneIds":[ + 285431 + ], + "options": { + "startCompact": true + } + } + ], + "url":"http://www.example.com/test?flipp-content-code=publisher-test", + "user":{ + "key":"30470a14-2949-4110-abce-b62d57304ad5" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "decisions": { + "inline": [ + { + "adId": 183599115, + "advertiserId": 1988027, + "campaignId": 63285392, + "clickUrl": "https://e-11090.adzerk.net/r?e=eyJ2IjoiMS4xMSIsImF2IjoxOTg4MDI3LCJhdCI6NDMwOSwiYnQiOjAsImNtIjo2MzI4NTM5MiwiY2giOjU4MDgxLCJjayI6e30sImNyIjo4MTMyNTY5MCwiZGkiOiJiOTg3MGNkYTA5MTU0NDlmOTkwZGNkZTNmNjYyNGNhMyIsImRqIjowLCJpaSI6IjJmNjYwMjMyODBmYjQ4NTRiYTY0YzFlYzA1ZDU5MTNiIiwiZG0iOjMsImZjIjoxODM1OTkxMTUsImZsIjoxNzU0MjE3OTUsImlwIjoiMTQyLjE4MS41OC41MiIsIm53IjoxMDkyMiwicGMiOjAsIm9wIjowLCJlYyI6MCwiZ20iOjAsImVwIjpudWxsLCJwciI6MjMyNjk5LCJydCI6MywicnMiOjUwMCwic2EiOiIzNCIsInNiIjoiaS0wNDZjMWNlNWRjYmExMTVjNSIsInNwIjozNzIzMDU1LCJzdCI6MTI0MzA2NiwidWsiOiJkOTU1N2Q2NS1kNWI5LTQyOTItYjg2My0xNGEyOTcyNTk3ZjQiLCJ6biI6Mjg1NDMxLCJ0cyI6MTY4MDU1NTc4MzkyMiwicG4iOiJpbmxpbmUiLCJnYyI6dHJ1ZSwiZ0MiOnRydWUsImdzIjoibm9uZSIsInR6IjoiQW1lcmljYS9OZXdfWW9yayIsInVyIjoiaHR0cDovL3d3dy5mbGlwcC5jb20ifQ&s=Mnss8P1kc37Eftik5RJvLJb4S9Y", + "contents": [ + { + "data": { + "customData": { + "campaignConfigUrl": "https://campaign-config.flipp.com/dist-campaign-admin/215", + "campaignNameIdentifier": "US Grocery Demo (Kroger)" + }, + "height": 1800, + "width": 300 + }, + "type": "raw" + } + ], + "creativeId": 81325690, + "flightId": 175421795, + "height": 1800, + "impressionUrl": "https://e-11090.adzerk.net/i.gif?e=eyJ2IjoiMS4xMSIsImF2IjoxOTg4MDI3LCJhdCI6NDMwOSwiYnQiOjAsImNtIjo2MzI4NTM5MiwiY2giOjU4MDgxLCJjayI6e30sImNyIjo4MTMyNTY5MCwiZGkiOiJiOTg3MGNkYTA5MTU0NDlmOTkwZGNkZTNmNjYyNGNhMyIsImRqIjowLCJpaSI6IjJmNjYwMjMyODBmYjQ4NTRiYTY0YzFlYzA1ZDU5MTNiIiwiZG0iOjMsImZjIjoxODM1OTkxMTUsImZsIjoxNzU0MjE3OTUsImlwIjoiMTQyLjE4MS41OC41MiIsIm53IjoxMDkyMiwicGMiOjAsIm9wIjowLCJlYyI6MCwiZ20iOjAsImVwIjpudWxsLCJwciI6MjMyNjk5LCJydCI6MywicnMiOjUwMCwic2EiOiIzNCIsInNiIjoiaS0wNDZjMWNlNWRjYmExMTVjNSIsInNwIjozNzIzMDU1LCJzdCI6MTI0MzA2NiwidWsiOiJkOTU1N2Q2NS1kNWI5LTQyOTItYjg2My0xNGEyOTcyNTk3ZjQiLCJ6biI6Mjg1NDMxLCJ0cyI6MTY4MDU1NTc4MzkyMywicG4iOiJpbmxpbmUiLCJnYyI6dHJ1ZSwiZ0MiOnRydWUsImdzIjoibm9uZSIsInR6IjoiQW1lcmljYS9OZXdfWW9yayIsImJhIjoxLCJmcSI6MH0&s=Qce4_IohtESeNA_sB71Qjb4TouY", + "prebid": { + "cpm": 12.34, + "creative":"creativeContent", + "creativeType": "NativeX", + "requestId": "test-imp-id" + }, + "priorityId": 232699, + "storefront": { + "campaignConfig": { + "fallbackImageUrl": "https://f.wishabi.net/arbitrary_files/115856/1666018811/115856_Featured Local Savings - Flipp Fallback - US (1).png", + "fallbackLinkUrl": "https://flipp.com/flyers/", + "tags": { + "advertiser": { + "engagement": "https://f.wishabi.net/creative/happyfruits/_itemlevelv2/apple.png?cb=[[random]]" + } + } + }, + "flyer_id": 5554080, + "flyer_run_id": 873256, + "flyer_type_id": 2826, + "is_fallback": true, + "merchant": "Kroger", + "merchant_id": 2778, + "name": "Weekly Ad", + "storefront_logo_url": "https://images.wishabi.net/merchants/qX1/BGIzc9sFcA==/RackMultipart20210421-1-e3k5rx.jpeg", + "storefront_payload_url": "https://cdn-gateflipp.flippback.com/storefront-payload/v2/873256/5554080/ff14f675705934507c269b5750e124a323bc9bf60e8a6f210f422f4528b233ff?merchant_id=2778", + "valid_from": "2023-03-29 04:00:00 +0000 UTC", + "valid_to": "2023-04-05 03:59:59 +0000 UTC" + }, + "width": 300 + } + ] + }, + "location": { + "accuracy_radius": 5, + "city": "Toronto", + "country": "CA", + "ip": "123.123.123.123", + "postal_code": "M4S", + "region": "ON", + "region_name": "Ontario" + } + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "183599115", + "impid": "test-imp-id", + "price": 12.34, + "adm": "creativeContent", + "crid": "81325690", + "w": 300 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/flipp/flipptest/exemplary/simple-banner-native-param-user.json b/adapters/flipp/flipptest/exemplary/simple-banner-native-param-user.json index 272bcd744ab..21957ae7096 100644 --- a/adapters/flipp/flipptest/exemplary/simple-banner-native-param-user.json +++ b/adapters/flipp/flipptest/exemplary/simple-banner-native-param-user.json @@ -10,6 +10,11 @@ "page": "http://www.example.com/test?flipp-content-code=publisher-test" }, "user": { + "consent": "CP0xeHPP0xeHPBcABBENAgCAAPAAAAAAAGcgAAAAAAAA" + }, + "regs": { + "coppa": 0, + "gdpr": 0 }, "imp": [ { From 01f3320e4ea1a6c794418817ae80ad9d107835a6 Mon Sep 17 00:00:00 2001 From: Simple Magic Software Date: Mon, 20 Nov 2023 02:30:36 -0500 Subject: [PATCH 223/268] New Adapter: oms (#3264) Co-authored-by: yfcr --- adapters/oms/oms.go | 80 +++++++ adapters/oms/oms_test.go | 20 ++ .../exemplary/simple-banner-cookie-uid.json | 128 +++++++++++ .../simple-banner-multiple-bids.json | 216 ++++++++++++++++++ .../omstest/exemplary/simple-banner-uid.json | 149 ++++++++++++ .../exemplary/simple-multi-type-banner.json | 161 +++++++++++++ .../204-response-from-target.json | 85 +++++++ .../400-response-from-target.json | 90 ++++++++ .../500-response-from-target.json | 90 ++++++++ .../supplemental/simple-banner-with-ipv6.json | 142 ++++++++++++ adapters/oms/params_test.go | 56 +++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_oms.go | 6 + static/bidder-info/oms.yaml | 11 + static/bidder-params/oms.json | 14 ++ 16 files changed, 1252 insertions(+) create mode 100644 adapters/oms/oms.go create mode 100644 adapters/oms/oms_test.go create mode 100755 adapters/oms/omstest/exemplary/simple-banner-cookie-uid.json create mode 100644 adapters/oms/omstest/exemplary/simple-banner-multiple-bids.json create mode 100755 adapters/oms/omstest/exemplary/simple-banner-uid.json create mode 100644 adapters/oms/omstest/exemplary/simple-multi-type-banner.json create mode 100755 adapters/oms/omstest/supplemental/204-response-from-target.json create mode 100755 adapters/oms/omstest/supplemental/400-response-from-target.json create mode 100755 adapters/oms/omstest/supplemental/500-response-from-target.json create mode 100755 adapters/oms/omstest/supplemental/simple-banner-with-ipv6.json create mode 100644 adapters/oms/params_test.go create mode 100644 openrtb_ext/imp_oms.go create mode 100644 static/bidder-info/oms.yaml create mode 100644 static/bidder-params/oms.json diff --git a/adapters/oms/oms.go b/adapters/oms/oms.go new file mode 100644 index 00000000000..af16cc78ace --- /dev/null +++ b/adapters/oms/oms.go @@ -0,0 +1,80 @@ +package oms + +import ( + "encoding/json" + "fmt" + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "net/http" +) + +type adapter struct { + endpoint string +} + +// Builder builds a new instance of the OMS adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + requestJSON, err := json.Marshal(request) + if err != nil { + return nil, []error{err} + } + + requestData := &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: requestJSON, + } + + return []*adapters.RequestData{requestData}, nil +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + + if responseData.StatusCode == http.StatusNoContent { + return nil, nil + } + + if responseData.StatusCode == http.StatusBadRequest { + err := &errortypes.BadInput{ + Message: "Unexpected status code: 400. Bad request from publisher. Run with request.debug = 1 for more info.", + } + return nil, []error{err} + } + + if responseData.StatusCode != http.StatusOK { + err := &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info.", responseData.StatusCode), + } + return nil, []error{err} + } + + var response openrtb2.BidResponse + if err := json.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + if len(response.Cur) == 0 { + bidResponse.Currency = response.Cur + } + for _, seatBid := range response.SeatBid { + for i := range seatBid.Bid { + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: openrtb_ext.BidTypeBanner, + }) + } + } + + return bidResponse, nil +} diff --git a/adapters/oms/oms_test.go b/adapters/oms/oms_test.go new file mode 100644 index 00000000000..9c3c4119f10 --- /dev/null +++ b/adapters/oms/oms_test.go @@ -0,0 +1,20 @@ +package oms + +import ( + "testing" + + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderOms, config.Adapter{ + Endpoint: "http://rt.marphezis.com/pbs"}, config.Server{ExternalUrl: "http://hosturl.com"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "omstest", bidder) +} diff --git a/adapters/oms/omstest/exemplary/simple-banner-cookie-uid.json b/adapters/oms/omstest/exemplary/simple-banner-cookie-uid.json new file mode 100755 index 00000000000..576173b548c --- /dev/null +++ b/adapters/oms/omstest/exemplary/simple-banner-cookie-uid.json @@ -0,0 +1,128 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "oms.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "buyeruid": "oms-user-id" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "pid": "12345" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rt.marphezis.com/pbs", + "headers": {}, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "oms.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "buyeruid": "oms-user-id" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "pid": "12345" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} + diff --git a/adapters/oms/omstest/exemplary/simple-banner-multiple-bids.json b/adapters/oms/omstest/exemplary/simple-banner-multiple-bids.json new file mode 100644 index 00000000000..6b292b27a53 --- /dev/null +++ b/adapters/oms/omstest/exemplary/simple-banner-multiple-bids.json @@ -0,0 +1,216 @@ +{ + "mockBidRequest": { + "id": "test-request-id-multiple-bids", + "site": { + "id": "site-id", + "page": "oms.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "oms.com", + "uids": [ + { + "id": "oms-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "pid": "12345" + } + } + }, + { + "id": "test-imp-id2", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "pid": "12345" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rt.marphezis.com/pbs", + "headers": {}, + "body": { + "id": "test-request-id-multiple-bids", + "site": { + "id": "site-id", + "page": "oms.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "oms.com", + "uids": [ + { + "id": "oms-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "pid": "12345" + } + } + }, + { + "id": "test-imp-id2", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "pid": "12345" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + }, + { + "bid": [ + { + "id": "test-slot-id2", + "impid": "test-imp-id2", + "price": 0.5, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + }, + { + "bid": { + "id": "test-slot-id2", + "impid": "test-imp-id2", + "price": 0.5, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} + diff --git a/adapters/oms/omstest/exemplary/simple-banner-uid.json b/adapters/oms/omstest/exemplary/simple-banner-uid.json new file mode 100755 index 00000000000..077c5562448 --- /dev/null +++ b/adapters/oms/omstest/exemplary/simple-banner-uid.json @@ -0,0 +1,149 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "oms.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "oms.com", + "uids": [ + { + "id": "oms-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "pid": "12345" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rt.marphezis.com/pbs", + "headers": {}, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "oms.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "oms.com", + "uids": [ + { + "id": "oms-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "pid": "12345" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} + diff --git a/adapters/oms/omstest/exemplary/simple-multi-type-banner.json b/adapters/oms/omstest/exemplary/simple-multi-type-banner.json new file mode 100644 index 00000000000..7e96dbfcc7e --- /dev/null +++ b/adapters/oms/omstest/exemplary/simple-multi-type-banner.json @@ -0,0 +1,161 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "oms.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "oms.com", + "uids": [ + { + "id": "oms-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 300, + "h": 250 + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "pid": "12345" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rt.marphezis.com/pbs", + "headers": {}, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "oms.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "oms.com", + "uids": [ + { + "id": "oms-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 300, + "h": 250 + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "pid": "12345" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "h": 250, + "w": 300, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "h": 250, + "w": 300, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} + diff --git a/adapters/oms/omstest/supplemental/204-response-from-target.json b/adapters/oms/omstest/supplemental/204-response-from-target.json new file mode 100755 index 00000000000..63a0829d9f3 --- /dev/null +++ b/adapters/oms/omstest/supplemental/204-response-from-target.json @@ -0,0 +1,85 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle" + }, + "device": { + "ifa": "test-ifa-123456", + "ip": "91.199.242.236", + "ua": "random user agent", + "os": "android" + }, + "regs": { + "ext": { + "us_privacy": "1YYY" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "pid": "12345" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rt.marphezis.com/pbs", + "headers": {}, + "body": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle" + }, + "device": { + "ifa": "test-ifa-123456", + "ip": "91.199.242.236", + "ua": "random user agent", + "os": "android" + }, + "regs": { + "ext": { + "us_privacy": "1YYY" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "pid": "12345" + } + } + } + ] + } + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedMakeBidsErrors": [] + } + \ No newline at end of file diff --git a/adapters/oms/omstest/supplemental/400-response-from-target.json b/adapters/oms/omstest/supplemental/400-response-from-target.json new file mode 100755 index 00000000000..831788f229d --- /dev/null +++ b/adapters/oms/omstest/supplemental/400-response-from-target.json @@ -0,0 +1,90 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle" + }, + "device": { + "ifa": "test-ifa-123456", + "ip": "91.199.242.236", + "ua": "random user agent", + "os": "android" + }, + "regs": { + "ext": { + "us_privacy": "1YYY" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "pid": "12345" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rt.marphezis.com/pbs", + "headers": {}, + "body": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle" + }, + "device": { + "ifa": "test-ifa-123456", + "ip": "91.199.242.236", + "ua": "random user agent", + "os": "android" + }, + "regs": { + "ext": { + "us_privacy": "1YYY" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "pid": "12345" + } + } + } + ] + } + }, + "mockResponse": { + "status": 400 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Bad request from publisher. Run with request.debug = 1 for more info.", + "comparison": "literal" + } + ] + } + \ No newline at end of file diff --git a/adapters/oms/omstest/supplemental/500-response-from-target.json b/adapters/oms/omstest/supplemental/500-response-from-target.json new file mode 100755 index 00000000000..9e4e48e2f2b --- /dev/null +++ b/adapters/oms/omstest/supplemental/500-response-from-target.json @@ -0,0 +1,90 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle" + }, + "device": { + "ifa": "test-ifa-123456", + "ip": "91.199.242.236", + "ua": "random user agent", + "os": "android" + }, + "regs": { + "ext": { + "us_privacy": "1YYY" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "pid": "12345" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rt.marphezis.com/pbs", + "headers": {}, + "body": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle" + }, + "device": { + "ifa": "test-ifa-123456", + "ip": "91.199.242.236", + "ua": "random user agent", + "os": "android" + }, + "regs": { + "ext": { + "us_privacy": "1YYY" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "pid": "12345" + } + } + } + ] + } + }, + "mockResponse": { + "status": 500 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info.", + "comparison": "literal" + } + ] + } + \ No newline at end of file diff --git a/adapters/oms/omstest/supplemental/simple-banner-with-ipv6.json b/adapters/oms/omstest/supplemental/simple-banner-with-ipv6.json new file mode 100755 index 00000000000..f473ecd6f21 --- /dev/null +++ b/adapters/oms/omstest/supplemental/simple-banner-with-ipv6.json @@ -0,0 +1,142 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "oms.com" + }, + "device": { + "os": "android", + "ipv6": "fd36:ce97:0fa1:dec0:0000:0000:0000:0000", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "oms.com", + "uids": [ + { + "id": "oms-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pid": "12345" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rt.marphezis.com/pbs", + "headers": {}, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "oms.com" + }, + "device": { + "os": "android", + "ipv6": "fd36:ce97:0fa1:dec0:0000:0000:0000:0000", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "oms.com", + "uids": [ + { + "id": "oms-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pid": "12345" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} + diff --git a/adapters/oms/params_test.go b/adapters/oms/params_test.go new file mode 100644 index 00000000000..daa78fe7ddf --- /dev/null +++ b/adapters/oms/params_test.go @@ -0,0 +1,56 @@ +package oms + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" +) + +// This file actually intends to test static/bidder-params/oms.json +// +// These also validate the format of the external API: request.imp[i].ext.prebid.bidder.oms + +// TestValidParams makes sure that the oms schema accepts all imp.ext fields which we intend to support. +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderOms, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected oms params: %s", validParam) + } + } +} + +// TestInvalidParams makes sure that the oms schema rejects all the imp.ext fields we don't support. +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderOms, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{"pid": "12345"}`, + `{"pid": "123456"}`, +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `4.2`, + `[]`, + `{}`, + `{"pid": "0"}`, +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index b859af01148..ca3fa778f0d 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -125,6 +125,7 @@ import ( "github.com/prebid/prebid-server/v2/adapters/motorik" "github.com/prebid/prebid-server/v2/adapters/nextmillennium" "github.com/prebid/prebid-server/v2/adapters/nobid" + "github.com/prebid/prebid-server/v2/adapters/oms" "github.com/prebid/prebid-server/v2/adapters/onetag" "github.com/prebid/prebid-server/v2/adapters/openweb" "github.com/prebid/prebid-server/v2/adapters/openx" @@ -322,6 +323,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderMotorik: motorik.Builder, openrtb_ext.BidderNextMillennium: nextmillennium.Builder, openrtb_ext.BidderNoBid: nobid.Builder, + openrtb_ext.BidderOms: oms.Builder, openrtb_ext.BidderOneTag: onetag.Builder, openrtb_ext.BidderOpenWeb: openweb.Builder, openrtb_ext.BidderOpenx: openx.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index a921f981aee..172d030ba31 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -144,6 +144,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderMotorik, BidderNextMillennium, BidderNoBid, + BidderOms, BidderOneTag, BidderOpenWeb, BidderOpenx, @@ -423,6 +424,7 @@ const ( BidderMotorik BidderName = "motorik" BidderNextMillennium BidderName = "nextmillennium" BidderNoBid BidderName = "nobid" + BidderOms BidderName = "oms" BidderOneTag BidderName = "onetag" BidderOpenWeb BidderName = "openweb" BidderOpenx BidderName = "openx" diff --git a/openrtb_ext/imp_oms.go b/openrtb_ext/imp_oms.go new file mode 100644 index 00000000000..4e12da86264 --- /dev/null +++ b/openrtb_ext/imp_oms.go @@ -0,0 +1,6 @@ +package openrtb_ext + +// ExtImpOms defines the contract for bidrequest.imp[i].ext.prebid.bidder.oms +type ExtImpOms struct { + PublisherID string `json:"pid"` +} diff --git a/static/bidder-info/oms.yaml b/static/bidder-info/oms.yaml new file mode 100644 index 00000000000..8bb9299d6e9 --- /dev/null +++ b/static/bidder-info/oms.yaml @@ -0,0 +1,11 @@ +endpoint: "http://rt.marphezis.com/pbs" +maintainer: + email: "prebid@onlinemediasolutions.com" +capabilities: + app: + mediaTypes: + - banner + site: + mediaTypes: + - banner + diff --git a/static/bidder-params/oms.json b/static/bidder-params/oms.json new file mode 100644 index 00000000000..f33286d10d9 --- /dev/null +++ b/static/bidder-params/oms.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Online Media Solutions Adapter Params", + "description": "A schema which validates params accepted by the OMS adapter", + "type": "object", + "properties": { + "pid": { + "type": "string", + "description": "An id used to identify OMS publisher.", + "minLength": 5 + } + }, + "required": ["pid"] +} From 94d86825acf52c25ea9ca648d9a4fc5b09e72c03 Mon Sep 17 00:00:00 2001 From: Witek Galecki <49022890+wgalecki@users.noreply.github.com> Date: Mon, 20 Nov 2023 09:07:54 +0100 Subject: [PATCH 224/268] adquery: added device ip and ua to bidder request (#1) (#3288) --- adapters/adquery/adquery.go | 33 ++++- adapters/adquery/adquery_test.go | 2 +- .../adquery/adquerytest/exemplary/empty.json | 9 +- .../adquerytest/exemplary/many-imps.json | 55 +++++--- .../adquerytest/exemplary/no-currency.json | 37 +++-- .../adquery/adquerytest/exemplary/ok.json | 38 +++-- .../exemplary/single-imp-banner-format.json | 29 ++-- .../adquerytest/supplemental/data-null.json | 15 +- .../invalid-numerical-values.json | 51 +++---- .../supplemental/malformed-resp.json | 37 ++--- .../supplemental/mediatype-unknown.json | 37 ++--- .../supplemental/mediatype-video.json | 37 ++--- .../adquerytest/supplemental/no-device.json | 128 +++++++++++++++++ .../supplemental/no-imp-banner-measures.json | 15 +- .../supplemental/no-imp-banner.json | 15 +- .../adquerytest/supplemental/no-site.json | 130 ++++++++++++++++++ .../supplemental/resp-bad-request.json | 33 +++-- .../supplemental/resp-no-content.json | 26 ++-- .../supplemental/resp-server-error.json | 33 +++-- adapters/adquery/types.go | 3 + static/bidder-info/adquery.yaml | 13 +- 21 files changed, 570 insertions(+), 206 deletions(-) create mode 100644 adapters/adquery/adquerytest/supplemental/no-device.json create mode 100644 adapters/adquery/adquerytest/supplemental/no-site.json diff --git a/adapters/adquery/adquery.go b/adapters/adquery/adquery.go index 92a1733dae6..a1e8f638d7f 100644 --- a/adapters/adquery/adquery.go +++ b/adapters/adquery/adquery.go @@ -34,10 +34,7 @@ func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) ( } func (a *adapter) MakeRequests(request *openrtb2.BidRequest, _ *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - headers := http.Header{} - headers.Add("Content-Type", "application/json;charset=utf-8") - headers.Add("Accept", "application/json") - headers.Add("x-openrtb-version", "2.5") + headers := buildHeaders(request) var result []*adapters.RequestData var errs []error @@ -112,13 +109,27 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData return bidResponse, nil } +func buildHeaders(bidReq *openrtb2.BidRequest) http.Header { + headers := http.Header{} + + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + headers.Add("X-Openrtb-Version", "2.5") + + if bidReq.Device != nil && len(bidReq.Device.IP) > 0 { + headers.Add("X-Forwarded-For", bidReq.Device.IP) + } + + return headers +} + func buildRequest(bidReq *openrtb2.BidRequest, imp *openrtb2.Imp, ext *openrtb_ext.ImpExtAdQuery) *BidderRequest { userId := "" if bidReq.User != nil { userId = bidReq.User.ID } - return &BidderRequest{ + bidderRequest := &BidderRequest{ V: prebidVersion, PlacementCode: ext.PlacementID, AuctionId: "", @@ -132,6 +143,18 @@ func buildRequest(bidReq *openrtb2.BidRequest, imp *openrtb2.Imp, ext *openrtb_e BidderRequestsCount: 1, Sizes: getImpSizes(imp), } + + if bidReq.Device != nil { + bidderRequest.BidIp = bidReq.Device.IP + bidderRequest.BidIpv6 = bidReq.Device.IPv6 + bidderRequest.BidUa = bidReq.Device.UA + } + + if bidReq.Site != nil { + bidderRequest.BidPageUrl = bidReq.Site.Page + } + + return bidderRequest } func parseExt(ext json.RawMessage) (*openrtb_ext.ImpExtAdQuery, error) { diff --git a/adapters/adquery/adquery_test.go b/adapters/adquery/adquery_test.go index 2b88c3b82c7..792e7c553a8 100644 --- a/adapters/adquery/adquery_test.go +++ b/adapters/adquery/adquery_test.go @@ -10,7 +10,7 @@ import ( func TestJsonSamples(t *testing.T) { bidder, buildErr := Builder(openrtb_ext.BidderAdquery, config.Adapter{ - Endpoint: "https://bidder.adquery.io/prebid/bid"}, + Endpoint: "https://bidder2.adquery.io/prebid/bid"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 902, DataCenter: "2"}) if buildErr != nil { diff --git a/adapters/adquery/adquerytest/exemplary/empty.json b/adapters/adquery/adquerytest/exemplary/empty.json index 04f1d21bcab..055d9829e63 100644 --- a/adapters/adquery/adquerytest/exemplary/empty.json +++ b/adapters/adquery/adquerytest/exemplary/empty.json @@ -4,9 +4,16 @@ "user": { "id": "xyz" }, + "site": { + "page": "https://www.example.com" + }, + "device": { + "ip": "104.28.131.104", + "ua": "PostmanRuntime/7.26.8" + }, "imp": [], "bidder": "adquery" }, "httpCalls": [], "expectedBidResponses": [] -} \ No newline at end of file +} diff --git a/adapters/adquery/adquerytest/exemplary/many-imps.json b/adapters/adquery/adquerytest/exemplary/many-imps.json index a3985c87dc1..b3f5f8c9a78 100644 --- a/adapters/adquery/adquerytest/exemplary/many-imps.json +++ b/adapters/adquery/adquerytest/exemplary/many-imps.json @@ -4,6 +4,13 @@ "user": { "id": "d93f2a0e5f0fe2cc3a6e" }, + "site": { + "page": "https://www.example.com" + }, + "device": { + "ip": "104.28.131.104", + "ua": "PostmanRuntime/7.26.8" + }, "imp": [ { "id": "1", @@ -27,7 +34,8 @@ "type": "banner" } } - },{ + }, + { "id": "2", "tagid": "test-banner-imp-id-2", "bidder": "adquery", @@ -52,21 +60,25 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bidder.adquery.io/prebid/bid", + "uri": "https://bidder2.adquery.io/prebid/bid", "headers": { "Accept": ["application/json"], "Content-Type": ["application/json;charset=utf-8"], - "X-Openrtb-Version": ["2.5"] + "X-Openrtb-Version": ["2.5"], + "X-Forwarded-For": ["104.28.131.104"] }, "body": { "adUnitCode": "test-banner-imp-id", - "bidId": "22e26bd9a702bc1", - "bidQid": "d93f2a0e5f0fe2cc3a6e", - "bidPageUrl": "", "bidder": "adquery", "bidderRequestId": "22e26bd9a702bc", - "bidRequestsCount": 1, "bidderRequestsCount": 1, + "bidId": "22e26bd9a702bc1", + "bidIp": "104.28.131.104", + "bidIpv6": "", + "bidPageUrl": "https://www.example.com", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidRequestsCount": 1, + "bidUa": "PostmanRuntime/7.26.8", "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", "sizes": "320x100,300x250", "type": "banner", @@ -98,9 +110,7 @@ "urlAdq": "https://adquery.io", "creationId": 7211, "currency": "EUR", - "adDomains": [ - "https://s1.adquery.io" - ], + "adDomains": ["https://s1.adquery.io"], "tag": " ", "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", "mediaType": { @@ -117,23 +127,28 @@ } } } - },{ + }, + { "expectedRequest": { - "uri": "https://bidder.adquery.io/prebid/bid", + "uri": "https://bidder2.adquery.io/prebid/bid", "headers": { "Accept": ["application/json"], "Content-Type": ["application/json;charset=utf-8"], - "X-Openrtb-Version": ["2.5"] + "X-Openrtb-Version": ["2.5"], + "X-Forwarded-For": ["104.28.131.104"] }, "body": { "adUnitCode": "test-banner-imp-id-2", - "bidId": "22e26bd9a702bc2", - "bidQid": "d93f2a0e5f0fe2cc3a6e", - "bidPageUrl": "", "bidder": "adquery", "bidderRequestId": "22e26bd9a702bc", - "bidRequestsCount": 1, "bidderRequestsCount": 1, + "bidId": "22e26bd9a702bc2", + "bidIp": "104.28.131.104", + "bidIpv6": "", + "bidPageUrl": "https://www.example.com", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidRequestsCount": 1, + "bidUa": "PostmanRuntime/7.26.8", "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f898", "sizes": "300x250", "type": "banner", @@ -165,9 +180,7 @@ "urlAdq": "https://adquery.io", "creationId": 7211, "currency": "EUR", - "adDomains": [ - "https://s1.adquery.io" - ], + "adDomains": ["https://s1.adquery.io"], "tag": " ", "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", "mediaType": { @@ -224,4 +237,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/adapters/adquery/adquerytest/exemplary/no-currency.json b/adapters/adquery/adquerytest/exemplary/no-currency.json index e97e4b9beaa..301eec783fa 100644 --- a/adapters/adquery/adquerytest/exemplary/no-currency.json +++ b/adapters/adquery/adquerytest/exemplary/no-currency.json @@ -4,6 +4,13 @@ "user": { "id": "d93f2a0e5f0fe2cc3a6e" }, + "site": { + "page": "https://www.example.com" + }, + "device": { + "ip": "104.28.131.104", + "ua": "PostmanRuntime/7.26.8" + }, "imp": [ { "id": "1", @@ -22,10 +29,10 @@ ] }, "ext": { - "bidder": { - "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", - "type": "banner" - } + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } } } ], @@ -34,21 +41,25 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bidder.adquery.io/prebid/bid", + "uri": "https://bidder2.adquery.io/prebid/bid", "headers": { "Accept": ["application/json"], "Content-Type": ["application/json;charset=utf-8"], - "X-Openrtb-Version": ["2.5"] + "X-Openrtb-Version": ["2.5"], + "X-Forwarded-For": ["104.28.131.104"] }, "body": { "adUnitCode": "test-banner-imp-id", - "bidId": "22e26bd9a702bc1", - "bidQid": "d93f2a0e5f0fe2cc3a6e", - "bidPageUrl": "", "bidder": "adquery", "bidderRequestId": "22e26bd9a702bc", - "bidRequestsCount": 1, "bidderRequestsCount": 1, + "bidId": "22e26bd9a702bc1", + "bidIp": "104.28.131.104", + "bidIpv6": "", + "bidPageUrl": "https://www.example.com", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidRequestsCount": 1, + "bidUa": "PostmanRuntime/7.26.8", "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", "sizes": "320x100,300x250", "type": "banner", @@ -79,9 +90,7 @@ "domain": "https://bidder.adquery.io", "urlAdq": "https://adquery.io", "creationId": 7211, - "adDomains": [ - "https://s1.adquery.io" - ], + "adDomains": ["https://s1.adquery.io"], "tag": " ", "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", "mediaType": { @@ -120,4 +129,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/adapters/adquery/adquerytest/exemplary/ok.json b/adapters/adquery/adquerytest/exemplary/ok.json index e725e055293..573fb2336e6 100644 --- a/adapters/adquery/adquerytest/exemplary/ok.json +++ b/adapters/adquery/adquerytest/exemplary/ok.json @@ -4,6 +4,14 @@ "user": { "id": "d93f2a0e5f0fe2cc3a6e" }, + "site": { + "page": "https://www.example.com" + }, + "device": { + "ip": "104.28.131.104", + "ipv6": "2001:4860:4860::8888", + "ua": "PostmanRuntime/7.26.8" + }, "imp": [ { "id": "1", @@ -22,10 +30,10 @@ ] }, "ext": { - "bidder": { - "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", - "type": "banner" - } + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } } } ], @@ -34,21 +42,25 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bidder.adquery.io/prebid/bid", + "uri": "https://bidder2.adquery.io/prebid/bid", "headers": { "Accept": ["application/json"], "Content-Type": ["application/json;charset=utf-8"], - "X-Openrtb-Version": ["2.5"] + "X-Openrtb-Version": ["2.5"], + "X-Forwarded-For": ["104.28.131.104"] }, "body": { "adUnitCode": "test-banner-imp-id", - "bidId": "22e26bd9a702bc1", - "bidQid": "d93f2a0e5f0fe2cc3a6e", - "bidPageUrl": "", "bidder": "adquery", "bidderRequestId": "22e26bd9a702bc", - "bidRequestsCount": 1, "bidderRequestsCount": 1, + "bidId": "22e26bd9a702bc1", + "bidIp": "104.28.131.104", + "bidIpv6": "2001:4860:4860::8888", + "bidPageUrl": "https://www.example.com", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidRequestsCount": 1, + "bidUa": "PostmanRuntime/7.26.8", "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", "sizes": "320x100,300x250", "type": "banner", @@ -80,9 +92,7 @@ "urlAdq": "https://adquery.io", "creationId": 7211, "currency": "EUR", - "adDomains": [ - "https://s1.adquery.io" - ], + "adDomains": ["https://s1.adquery.io"], "tag": " ", "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", "mediaType": { @@ -121,4 +131,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/adapters/adquery/adquerytest/exemplary/single-imp-banner-format.json b/adapters/adquery/adquerytest/exemplary/single-imp-banner-format.json index 7a0092d5f5a..5b2a54a70d3 100644 --- a/adapters/adquery/adquerytest/exemplary/single-imp-banner-format.json +++ b/adapters/adquery/adquerytest/exemplary/single-imp-banner-format.json @@ -4,6 +4,13 @@ "user": { "id": "d93f2a0e5f0fe2cc3a6e" }, + "site": { + "page": "https://www.example.com" + }, + "device": { + "ip": "104.28.131.104", + "ua": "PostmanRuntime/7.26.8" + }, "imp": [ { "id": "1", @@ -26,21 +33,25 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bidder.adquery.io/prebid/bid", + "uri": "https://bidder2.adquery.io/prebid/bid", "headers": { "Accept": ["application/json"], "Content-Type": ["application/json;charset=utf-8"], - "X-Openrtb-Version": ["2.5"] + "X-Openrtb-Version": ["2.5"], + "X-Forwarded-For": ["104.28.131.104"] }, "body": { "adUnitCode": "test-banner-imp-id", - "bidId": "22e26bd9a702bc1", - "bidQid": "d93f2a0e5f0fe2cc3a6e", - "bidPageUrl": "", "bidder": "adquery", "bidderRequestId": "22e26bd9a702bc", - "bidRequestsCount": 1, "bidderRequestsCount": 1, + "bidId": "22e26bd9a702bc1", + "bidIp": "104.28.131.104", + "bidIpv6": "", + "bidPageUrl": "https://www.example.com", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidRequestsCount": 1, + "bidUa": "PostmanRuntime/7.26.8", "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", "sizes": "320x100", "type": "banner", @@ -72,9 +83,7 @@ "urlAdq": "https://adquery.io", "creationId": 7211, "currency": "PLN", - "adDomains": [ - "https://s1.adquery.io" - ], + "adDomains": ["https://s1.adquery.io"], "tag": " ", "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", "mediaType": { @@ -112,4 +121,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/adapters/adquery/adquerytest/supplemental/data-null.json b/adapters/adquery/adquerytest/supplemental/data-null.json index 0d21a2bd9f7..8bbe8dc501f 100644 --- a/adapters/adquery/adquerytest/supplemental/data-null.json +++ b/adapters/adquery/adquerytest/supplemental/data-null.json @@ -34,7 +34,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bidder.adquery.io/prebid/bid", + "uri": "https://bidder2.adquery.io/prebid/bid", "headers": { "Accept": ["application/json"], "Content-Type": ["application/json;charset=utf-8"], @@ -42,13 +42,16 @@ }, "body": { "adUnitCode": "test-banner-imp-id", - "bidId": "22e26bd9a702bc1", - "bidQid": "d93f2a0e5f0fe2cc3a6e", - "bidPageUrl": "", "bidder": "adquery", "bidderRequestId": "22e26bd9a702bc", - "bidRequestsCount": 1, "bidderRequestsCount": 1, + "bidId": "22e26bd9a702bc1", + "bidIp": "", + "bidIpv6": "", + "bidPageUrl": "", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidRequestsCount": 1, + "bidUa": "", "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", "sizes": "320x100,300x250", "type": "banner", @@ -69,4 +72,4 @@ "bids": [] } ] -} \ No newline at end of file +} diff --git a/adapters/adquery/adquerytest/supplemental/invalid-numerical-values.json b/adapters/adquery/adquerytest/supplemental/invalid-numerical-values.json index daff3d0828c..a9664e5232e 100644 --- a/adapters/adquery/adquerytest/supplemental/invalid-numerical-values.json +++ b/adapters/adquery/adquerytest/supplemental/invalid-numerical-values.json @@ -22,10 +22,10 @@ ] }, "ext": { - "bidder": { - "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", - "type": "banner" - } + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } } } ], @@ -34,7 +34,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bidder.adquery.io/prebid/bid", + "uri": "https://bidder2.adquery.io/prebid/bid", "headers": { "Accept": ["application/json"], "Content-Type": ["application/json;charset=utf-8"], @@ -42,13 +42,16 @@ }, "body": { "adUnitCode": "test-banner-imp-id", - "bidId": "22e26bd9a702bc1", - "bidQid": "d93f2a0e5f0fe2cc3a6e", - "bidPageUrl": "", "bidder": "adquery", "bidderRequestId": "22e26bd9a702bc", - "bidRequestsCount": 1, "bidderRequestsCount": 1, + "bidId": "22e26bd9a702bc1", + "bidIp": "", + "bidIpv6": "", + "bidPageUrl": "", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidRequestsCount": 1, + "bidUa": "", "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", "sizes": "320x100,300x250", "type": "banner", @@ -80,9 +83,7 @@ "urlAdq": "https://adquery.io", "creationId": 7211, "currency": "PLN", - "adDomains": [ - "https://s1.adquery.io" - ], + "adDomains": ["https://s1.adquery.io"], "tag": " ", "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", "mediaType": { @@ -101,14 +102,18 @@ } } ], - "expectedMakeBidsErrors": [{ - "value": "strconv.ParseFloat: parsing \"$4.14\": invalid syntax", - "comparison": "literal" - },{ - "value": "strconv.ParseInt: parsing \"320px\": invalid syntax", - "comparison": "literal" - },{ - "value": "strconv.ParseInt: parsing \"50px\": invalid syntax", - "comparison": "literal" - }] -} \ No newline at end of file + "expectedMakeBidsErrors": [ + { + "value": "strconv.ParseFloat: parsing \"$4.14\": invalid syntax", + "comparison": "literal" + }, + { + "value": "strconv.ParseInt: parsing \"320px\": invalid syntax", + "comparison": "literal" + }, + { + "value": "strconv.ParseInt: parsing \"50px\": invalid syntax", + "comparison": "literal" + } + ] +} diff --git a/adapters/adquery/adquerytest/supplemental/malformed-resp.json b/adapters/adquery/adquerytest/supplemental/malformed-resp.json index f7aa271e6fe..8ab1763c0be 100644 --- a/adapters/adquery/adquerytest/supplemental/malformed-resp.json +++ b/adapters/adquery/adquerytest/supplemental/malformed-resp.json @@ -22,10 +22,10 @@ ] }, "ext": { - "bidder": { - "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", - "type": "banner" - } + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } } } ], @@ -34,7 +34,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bidder.adquery.io/prebid/bid", + "uri": "https://bidder2.adquery.io/prebid/bid", "headers": { "Accept": ["application/json"], "Content-Type": ["application/json;charset=utf-8"], @@ -42,13 +42,16 @@ }, "body": { "adUnitCode": "test-banner-imp-id", - "bidId": "22e26bd9a702bc1", - "bidQid": "d93f2a0e5f0fe2cc3a6e", - "bidPageUrl": "", "bidder": "adquery", "bidderRequestId": "22e26bd9a702bc", - "bidRequestsCount": 1, "bidderRequestsCount": 1, + "bidId": "22e26bd9a702bc1", + "bidIp": "", + "bidIpv6": "", + "bidPageUrl": "", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidRequestsCount": 1, + "bidUa": "", "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", "sizes": "320x100,300x250", "type": "banner", @@ -80,9 +83,7 @@ "urlAdq": "https://adquery.io", "creationId": "string-identifier", "currency": "PLN", - "adDomains": [ - "https://s1.adquery.io" - ], + "adDomains": ["https://s1.adquery.io"], "tag": " ", "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", "mediaType": { @@ -101,8 +102,10 @@ } } ], - "expectedMakeBidsErrors": [{ - "value": "json: cannot unmarshal string into Go struct field ResponseData.data.creationId of type int64", - "comparison": "literal" - }] -} \ No newline at end of file + "expectedMakeBidsErrors": [ + { + "value": "json: cannot unmarshal string into Go struct field ResponseData.data.creationId of type int64", + "comparison": "literal" + } + ] +} diff --git a/adapters/adquery/adquerytest/supplemental/mediatype-unknown.json b/adapters/adquery/adquerytest/supplemental/mediatype-unknown.json index bf3cdc63f45..47b05d836f9 100644 --- a/adapters/adquery/adquerytest/supplemental/mediatype-unknown.json +++ b/adapters/adquery/adquerytest/supplemental/mediatype-unknown.json @@ -22,10 +22,10 @@ ] }, "ext": { - "bidder": { - "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", - "type": "banner" - } + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } } } ], @@ -34,7 +34,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bidder.adquery.io/prebid/bid", + "uri": "https://bidder2.adquery.io/prebid/bid", "headers": { "Accept": ["application/json"], "Content-Type": ["application/json;charset=utf-8"], @@ -42,13 +42,16 @@ }, "body": { "adUnitCode": "test-banner-imp-id", - "bidId": "22e26bd9a702bc1", - "bidQid": "d93f2a0e5f0fe2cc3a6e", - "bidPageUrl": "", "bidder": "adquery", "bidderRequestId": "22e26bd9a702bc", - "bidRequestsCount": 1, "bidderRequestsCount": 1, + "bidId": "22e26bd9a702bc1", + "bidIp": "", + "bidIpv6": "", + "bidPageUrl": "", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidRequestsCount": 1, + "bidUa": "", "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", "sizes": "320x100,300x250", "type": "banner", @@ -80,9 +83,7 @@ "urlAdq": "https://adquery.io", "creationId": 7211, "currency": "PLN", - "adDomains": [ - "https://s1.adquery.io" - ], + "adDomains": ["https://s1.adquery.io"], "tag": " ", "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", "mediaType": { @@ -101,8 +102,10 @@ } } ], - "expectedMakeBidsErrors": [{ - "value": "unsupported MediaType: unknown", - "comparison": "literal" - }] -} \ No newline at end of file + "expectedMakeBidsErrors": [ + { + "value": "unsupported MediaType: unknown", + "comparison": "literal" + } + ] +} diff --git a/adapters/adquery/adquerytest/supplemental/mediatype-video.json b/adapters/adquery/adquerytest/supplemental/mediatype-video.json index 7becebab291..a6d19e7fc5a 100644 --- a/adapters/adquery/adquerytest/supplemental/mediatype-video.json +++ b/adapters/adquery/adquerytest/supplemental/mediatype-video.json @@ -22,10 +22,10 @@ ] }, "ext": { - "bidder": { - "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", - "type": "banner" - } + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } } } ], @@ -34,7 +34,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bidder.adquery.io/prebid/bid", + "uri": "https://bidder2.adquery.io/prebid/bid", "headers": { "Accept": ["application/json"], "Content-Type": ["application/json;charset=utf-8"], @@ -42,13 +42,16 @@ }, "body": { "adUnitCode": "test-banner-imp-id", - "bidId": "22e26bd9a702bc1", - "bidQid": "d93f2a0e5f0fe2cc3a6e", - "bidPageUrl": "", "bidder": "adquery", "bidderRequestId": "22e26bd9a702bc", - "bidRequestsCount": 1, "bidderRequestsCount": 1, + "bidId": "22e26bd9a702bc1", + "bidIp": "", + "bidIpv6": "", + "bidPageUrl": "", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidRequestsCount": 1, + "bidUa": "", "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", "sizes": "320x100,300x250", "type": "banner", @@ -80,9 +83,7 @@ "urlAdq": "https://adquery.io", "creationId": 7211, "currency": "PLN", - "adDomains": [ - "https://s1.adquery.io" - ], + "adDomains": ["https://s1.adquery.io"], "tag": " ", "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", "mediaType": { @@ -101,8 +102,10 @@ } } ], - "expectedMakeBidsErrors": [{ - "value": "unsupported MediaType: video", - "comparison": "literal" - }] -} \ No newline at end of file + "expectedMakeBidsErrors": [ + { + "value": "unsupported MediaType: video", + "comparison": "literal" + } + ] +} diff --git a/adapters/adquery/adquerytest/supplemental/no-device.json b/adapters/adquery/adquerytest/supplemental/no-device.json new file mode 100644 index 00000000000..9876cd57c88 --- /dev/null +++ b/adapters/adquery/adquerytest/supplemental/no-device.json @@ -0,0 +1,128 @@ +{ + "mockBidRequest": { + "id": "22e26bd9a702bc", + "user": { + "id": "d93f2a0e5f0fe2cc3a6e" + }, + "site": { + "page": "http://www.example.com" + }, + "imp": [ + { + "id": "1", + "tagid": "test-banner-imp-id", + "bidder": "adquery", + "banner": { + "format": [ + { + "w": 320, + "h": 100 + }, + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } + } + } + ], + "bidder": "adquery" + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bidder2.adquery.io/prebid/bid", + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"], + "X-Openrtb-Version": ["2.5"] + }, + "body": { + "adUnitCode": "test-banner-imp-id", + "bidder": "adquery", + "bidderRequestId": "22e26bd9a702bc", + "bidderRequestsCount": 1, + "bidId": "22e26bd9a702bc1", + "bidIp": "", + "bidIpv6": "", + "bidPageUrl": "http://www.example.com", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidRequestsCount": 1, + "bidUa": "", + "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "sizes": "320x100,300x250", + "type": "banner", + "v": "server" + } + }, + "mockResponse": { + "status": 200, + "headers": {}, + "body": { + "data": { + "requestId": "22e26bd9a702bc1", + "emission_id": "22e26bd9a702bc1", + "eventTracker": "https://bidder.adquery.io/prebid/ev/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "externalEmissionCodes": "", + "impressionTracker": "https://bidder.adquery.io/prebid/im/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "viewabilityTracker": "https://bidder.adquery.io/prebid/vi/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "clickTracker": "https://bidder.adquery.io/prebid/cl/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?url=https%3A%2F%2Fbrodacid.pl%2F%3Futm_source%3Dmobile_open%26utm_medium%3Dcpc%26utm_campaign%3Dhi2023", + "link": "https://brodacid.pl/?utm_source=mobile_open&utm_medium=cpc&utm_campaign=hi2023", + "logo": "https://api.adquery.io/img/adquery.png", + "medias": [ + { + "src": "banner/2023-06-05/17591", + "ext": "zip", + "type": 3 + } + ], + "domain": "https://bidder.adquery.io", + "urlAdq": "https://adquery.io", + "creationId": 7211, + "currency": "EUR", + "adDomains": ["https://s1.adquery.io"], + "tag": " ", + "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", + "mediaType": { + "width": "320", + "height": "50", + "name": "banner", + "type": "banner320x50" + }, + "cpm": "4.14", + "qid": "fc08aacb07eac44421ed", + "width": "320", + "height": "50", + "isExpand": false + } + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "22e26bd9a702bc1", + "impid": "1", + "price": 4.14, + "adm": " ", + "adomain": ["https://s1.adquery.io"], + "crid": "7211", + "w": 320, + "h": 50 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/adquery/adquerytest/supplemental/no-imp-banner-measures.json b/adapters/adquery/adquerytest/supplemental/no-imp-banner-measures.json index 953d6de5d8d..c745c9a7c30 100644 --- a/adapters/adquery/adquerytest/supplemental/no-imp-banner-measures.json +++ b/adapters/adquery/adquerytest/supplemental/no-imp-banner-measures.json @@ -23,7 +23,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bidder.adquery.io/prebid/bid", + "uri": "https://bidder2.adquery.io/prebid/bid", "headers": { "Accept": ["application/json"], "Content-Type": ["application/json;charset=utf-8"], @@ -31,13 +31,16 @@ }, "body": { "adUnitCode": "test-banner-imp-id", - "bidId": "22e26bd9a702bc1", - "bidQid": "d93f2a0e5f0fe2cc3a6e", - "bidPageUrl": "", "bidder": "adquery", "bidderRequestId": "22e26bd9a702bc", - "bidRequestsCount": 1, "bidderRequestsCount": 1, + "bidId": "22e26bd9a702bc1", + "bidIp": "", + "bidIpv6": "", + "bidPageUrl": "", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidRequestsCount": 1, + "bidUa": "", "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", "sizes": "", "type": "banner", @@ -58,4 +61,4 @@ "bids": [] } ] -} \ No newline at end of file +} diff --git a/adapters/adquery/adquerytest/supplemental/no-imp-banner.json b/adapters/adquery/adquerytest/supplemental/no-imp-banner.json index 8589d97f606..f7de622587f 100644 --- a/adapters/adquery/adquerytest/supplemental/no-imp-banner.json +++ b/adapters/adquery/adquerytest/supplemental/no-imp-banner.json @@ -22,7 +22,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bidder.adquery.io/prebid/bid", + "uri": "https://bidder2.adquery.io/prebid/bid", "headers": { "Accept": ["application/json"], "Content-Type": ["application/json;charset=utf-8"], @@ -30,13 +30,16 @@ }, "body": { "adUnitCode": "test-banner-imp-id", - "bidId": "22e26bd9a702bc1", - "bidQid": "d93f2a0e5f0fe2cc3a6e", - "bidPageUrl": "", "bidder": "adquery", "bidderRequestId": "22e26bd9a702bc", - "bidRequestsCount": 1, "bidderRequestsCount": 1, + "bidId": "22e26bd9a702bc1", + "bidIp": "", + "bidIpv6": "", + "bidPageUrl": "", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidRequestsCount": 1, + "bidUa": "", "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", "sizes": "", "type": "banner", @@ -57,4 +60,4 @@ "bids": [] } ] -} \ No newline at end of file +} diff --git a/adapters/adquery/adquerytest/supplemental/no-site.json b/adapters/adquery/adquerytest/supplemental/no-site.json new file mode 100644 index 00000000000..20305f52b11 --- /dev/null +++ b/adapters/adquery/adquerytest/supplemental/no-site.json @@ -0,0 +1,130 @@ +{ + "mockBidRequest": { + "id": "22e26bd9a702bc", + "user": { + "id": "d93f2a0e5f0fe2cc3a6e" + }, + "device": { + "ip": "104.28.131.104", + "ua": "PostmanRuntime/7.26.8" + }, + "imp": [ + { + "id": "1", + "tagid": "test-banner-imp-id", + "bidder": "adquery", + "banner": { + "format": [ + { + "w": 320, + "h": 100 + }, + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } + } + } + ], + "bidder": "adquery" + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bidder2.adquery.io/prebid/bid", + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"], + "X-Openrtb-Version": ["2.5"], + "X-Forwarded-For": ["104.28.131.104"] + }, + "body": { + "adUnitCode": "test-banner-imp-id", + "bidder": "adquery", + "bidderRequestId": "22e26bd9a702bc", + "bidderRequestsCount": 1, + "bidId": "22e26bd9a702bc1", + "bidIp": "104.28.131.104", + "bidIpv6": "", + "bidPageUrl": "", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidRequestsCount": 1, + "bidUa": "PostmanRuntime/7.26.8", + "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "sizes": "320x100,300x250", + "type": "banner", + "v": "server" + } + }, + "mockResponse": { + "status": 200, + "headers": {}, + "body": { + "data": { + "requestId": "22e26bd9a702bc1", + "emission_id": "22e26bd9a702bc1", + "eventTracker": "https://bidder.adquery.io/prebid/ev/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "externalEmissionCodes": "", + "impressionTracker": "https://bidder.adquery.io/prebid/im/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "viewabilityTracker": "https://bidder.adquery.io/prebid/vi/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?ad=1", + "clickTracker": "https://bidder.adquery.io/prebid/cl/d30f79cf7fef47bd7a5611719f936539bec0d2e9/22e26bd9a702bc?url=https%3A%2F%2Fbrodacid.pl%2F%3Futm_source%3Dmobile_open%26utm_medium%3Dcpc%26utm_campaign%3Dhi2023", + "link": "https://brodacid.pl/?utm_source=mobile_open&utm_medium=cpc&utm_campaign=hi2023", + "logo": "https://api.adquery.io/img/adquery.png", + "medias": [ + { + "src": "banner/2023-06-05/17591", + "ext": "zip", + "type": 3 + } + ], + "domain": "https://bidder.adquery.io", + "urlAdq": "https://adquery.io", + "creationId": 7211, + "currency": "EUR", + "adDomains": ["https://s1.adquery.io"], + "tag": " ", + "adqLib": "https://api.adquery.io/js/adquery-0.1.js?time=10", + "mediaType": { + "width": "320", + "height": "50", + "name": "banner", + "type": "banner320x50" + }, + "cpm": "4.14", + "qid": "fc08aacb07eac44421ed", + "width": "320", + "height": "50", + "isExpand": false + } + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "22e26bd9a702bc1", + "impid": "1", + "price": 4.14, + "adm": " ", + "adomain": ["https://s1.adquery.io"], + "crid": "7211", + "w": 320, + "h": 50 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/adquery/adquerytest/supplemental/resp-bad-request.json b/adapters/adquery/adquerytest/supplemental/resp-bad-request.json index cb869625720..f5e807ebad5 100644 --- a/adapters/adquery/adquerytest/supplemental/resp-bad-request.json +++ b/adapters/adquery/adquerytest/supplemental/resp-bad-request.json @@ -22,10 +22,10 @@ ] }, "ext": { - "bidder": { - "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", - "type": "banner" - } + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } } } ], @@ -34,7 +34,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bidder.adquery.io/prebid/bid", + "uri": "https://bidder2.adquery.io/prebid/bid", "headers": { "Accept": ["application/json"], "Content-Type": ["application/json;charset=utf-8"], @@ -42,13 +42,16 @@ }, "body": { "adUnitCode": "test-banner-imp-id", - "bidId": "22e26bd9a702bc1", - "bidQid": "d93f2a0e5f0fe2cc3a6e", - "bidPageUrl": "", "bidder": "adquery", "bidderRequestId": "22e26bd9a702bc", - "bidRequestsCount": 1, "bidderRequestsCount": 1, + "bidId": "22e26bd9a702bc1", + "bidIp": "", + "bidIpv6": "", + "bidPageUrl": "", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidRequestsCount": 1, + "bidUa": "", "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", "sizes": "320x100,300x250", "type": "banner", @@ -61,8 +64,10 @@ } } ], - "expectedMakeBidsErrors": [{ - "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", - "comparison": "literal" - }] -} \ No newline at end of file + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/adquery/adquerytest/supplemental/resp-no-content.json b/adapters/adquery/adquerytest/supplemental/resp-no-content.json index 5817e15a533..1ce24c17081 100644 --- a/adapters/adquery/adquerytest/supplemental/resp-no-content.json +++ b/adapters/adquery/adquerytest/supplemental/resp-no-content.json @@ -22,10 +22,10 @@ ] }, "ext": { - "bidder": { - "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", - "type": "banner" - } + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } } } ], @@ -34,7 +34,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bidder.adquery.io/prebid/bid", + "uri": "https://bidder2.adquery.io/prebid/bid", "headers": { "Accept": ["application/json"], "Content-Type": ["application/json;charset=utf-8"], @@ -42,13 +42,16 @@ }, "body": { "adUnitCode": "test-banner-imp-id", - "bidId": "22e26bd9a702bc1", - "bidQid": "d93f2a0e5f0fe2cc3a6e", - "bidPageUrl": "", "bidder": "adquery", "bidderRequestId": "22e26bd9a702bc", - "bidRequestsCount": 1, "bidderRequestsCount": 1, + "bidId": "22e26bd9a702bc1", + "bidIp": "", + "bidIpv6": "", + "bidPageUrl": "", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidRequestsCount": 1, + "bidUa": "", "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", "sizes": "320x100,300x250", "type": "banner", @@ -61,6 +64,5 @@ } } ], - "expectedBidResponses": [ - ] -} \ No newline at end of file + "expectedBidResponses": [] +} diff --git a/adapters/adquery/adquerytest/supplemental/resp-server-error.json b/adapters/adquery/adquerytest/supplemental/resp-server-error.json index 05c1cae8488..2e8e42ba927 100644 --- a/adapters/adquery/adquerytest/supplemental/resp-server-error.json +++ b/adapters/adquery/adquerytest/supplemental/resp-server-error.json @@ -22,10 +22,10 @@ ] }, "ext": { - "bidder": { - "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", - "type": "banner" - } + "bidder": { + "placementId": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", + "type": "banner" + } } } ], @@ -34,7 +34,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://bidder.adquery.io/prebid/bid", + "uri": "https://bidder2.adquery.io/prebid/bid", "headers": { "Accept": ["application/json"], "Content-Type": ["application/json;charset=utf-8"], @@ -42,13 +42,16 @@ }, "body": { "adUnitCode": "test-banner-imp-id", - "bidId": "22e26bd9a702bc1", - "bidQid": "d93f2a0e5f0fe2cc3a6e", - "bidPageUrl": "", "bidder": "adquery", "bidderRequestId": "22e26bd9a702bc", - "bidRequestsCount": 1, "bidderRequestsCount": 1, + "bidId": "22e26bd9a702bc1", + "bidIp": "", + "bidIpv6": "", + "bidPageUrl": "", + "bidQid": "d93f2a0e5f0fe2cc3a6e", + "bidRequestsCount": 1, + "bidUa": "", "placementCode": "6d93f2a0e5f0fe2cc3a6e9e3ade964b43b07f897", "sizes": "320x100,300x250", "type": "banner", @@ -61,8 +64,10 @@ } } ], - "expectedMakeBidsErrors": [{ - "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", - "comparison": "literal" - }] -} \ No newline at end of file + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/adquery/types.go b/adapters/adquery/types.go index 5013ecf488a..dab9619a7f5 100644 --- a/adapters/adquery/types.go +++ b/adapters/adquery/types.go @@ -10,6 +10,9 @@ type BidderRequest struct { AdUnitCode string `json:"adUnitCode"` BidQid string `json:"bidQid"` BidId string `json:"bidId"` + BidIp string `json:"bidIp"` + BidIpv6 string `json:"bidIpv6"` + BidUa string `json:"bidUa"` Bidder string `json:"bidder"` BidPageUrl string `json:"bidPageUrl"` BidderRequestId string `json:"bidderRequestId"` diff --git a/static/bidder-info/adquery.yaml b/static/bidder-info/adquery.yaml index 98b6b0ea432..035bd6fc1cb 100644 --- a/static/bidder-info/adquery.yaml +++ b/static/bidder-info/adquery.yaml @@ -1,16 +1,13 @@ -endpoint: "https://bidder.adquery.io/prebid/bid" +endpoint: https://bidder2.adquery.io/prebid/bid maintainer: email: prebid@adquery.io -#endpointCompression: gzip # disabled because otherwise bidder responds with {data:null} gvlVendorID: 902 capabilities: -# app: # disabled because currently it's only a site, not an app (?) -# mediaTypes: -# - banner site: mediaTypes: - banner userSync: - redirect: - url: https://bidder.adquery.io/prebid/userSync?1=1&gdpr={{.GDPR}}&consent={{.GDPRConsent}}&ccpa_consent={{.USPrivacy}}&redirect={{.RedirectURL}} - userMacro: $UID \ No newline at end of file + iframe: + url: https://api.adquery.io/storage?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&ccpa_consent={{.USPrivacy}}&redirect={{.RedirectURL}} + userMacro: $UID + \ No newline at end of file From ea01ccff4100235f8af425011785ad7adfdb4a9d Mon Sep 17 00:00:00 2001 From: Vungle-GordonTian <115982294+Vungle-GordonTian@users.noreply.github.com> Date: Mon, 20 Nov 2023 17:01:24 +0800 Subject: [PATCH 225/268] update contact email address (#3298) --- static/bidder-info/liftoff.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/bidder-info/liftoff.yaml b/static/bidder-info/liftoff.yaml index 577439dbb97..43ffd1a7b18 100644 --- a/static/bidder-info/liftoff.yaml +++ b/static/bidder-info/liftoff.yaml @@ -1,6 +1,6 @@ endpoint: "https://rtb.ads.vungle.com/bid/t/c770f32" maintainer: - email: platform-ssp@liftoff.io + email: vxssp@liftoff.io endpointCompression: gzip modifyingVastXmlAllowed: true capabilities: From 1e89053b4780a81fe99242daf153875d4e509fbb Mon Sep 17 00:00:00 2001 From: Maxime Liege <56251840+github-maxime-liege@users.noreply.github.com> Date: Mon, 20 Nov 2023 10:02:09 +0100 Subject: [PATCH 226/268] Change endpoint for Teads adapter (#3303) --- adapters/teads/teads_test.go | 4 ++-- .../teads/teadstest/exemplary/simple-banner-with-format.json | 2 +- adapters/teads/teadstest/exemplary/simple-banner.json | 2 +- adapters/teads/teadstest/exemplary/simple-video.json | 2 +- .../teads/teadstest/supplemental/bid-id-does-not-match.json | 2 +- .../teads/teadstest/supplemental/currency-empty-string.json | 2 +- .../teads/teadstest/supplemental/no-impression-response.json | 2 +- .../teads/teadstest/supplemental/renderer-name-empty.json | 2 +- .../teads/teadstest/supplemental/renderer-version-empty.json | 2 +- adapters/teads/teadstest/supplemental/status-400.json | 2 +- adapters/teads/teadstest/supplemental/status-500.json | 2 +- static/bidder-info/teads.yaml | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/adapters/teads/teads_test.go b/adapters/teads/teads_test.go index 4f492b66b1e..c9f807ace21 100644 --- a/adapters/teads/teads_test.go +++ b/adapters/teads/teads_test.go @@ -11,7 +11,7 @@ import ( func TestJsonSamples(t *testing.T) { bidder, buildErr := Builder(openrtb_ext.BidderTeads, config.Adapter{ - Endpoint: "https://a.teads.tv/prebid-server/bid-request"}, config.Server{ExternalUrl: "https://a.teads.tv/prebid-server/bid-request", GvlID: 1, DataCenter: "2"}) + Endpoint: "https://psrv.teads.tv/prebid-server/bid-request"}, config.Server{ExternalUrl: "https://psrv.teads.tv/prebid-server/bid-request", GvlID: 1, DataCenter: "2"}) if buildErr != nil { t.Fatalf("Builder returned unexpected error %v", buildErr) @@ -22,7 +22,7 @@ func TestJsonSamples(t *testing.T) { func TestEndpointTemplateMalformed(t *testing.T) { _, buildErr := Builder(openrtb_ext.BidderTeads, config.Adapter{ - Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "https://a.teads.tv/prebid-server/bid-request", GvlID: 1, DataCenter: "2"}) + Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "https://psrv.teads.tv/prebid-server/bid-request", GvlID: 1, DataCenter: "2"}) assert.Error(t, buildErr) } diff --git a/adapters/teads/teadstest/exemplary/simple-banner-with-format.json b/adapters/teads/teadstest/exemplary/simple-banner-with-format.json index b2677e6faba..ffaf849bfd8 100644 --- a/adapters/teads/teadstest/exemplary/simple-banner-with-format.json +++ b/adapters/teads/teadstest/exemplary/simple-banner-with-format.json @@ -39,7 +39,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://a.teads.tv/prebid-server/bid-request", + "uri": "https://psrv.teads.tv/prebid-server/bid-request", "body": { "id": "test-request-id", "imp": [ diff --git a/adapters/teads/teadstest/exemplary/simple-banner.json b/adapters/teads/teadstest/exemplary/simple-banner.json index 2d9be7c7368..43a28614f9c 100644 --- a/adapters/teads/teadstest/exemplary/simple-banner.json +++ b/adapters/teads/teadstest/exemplary/simple-banner.json @@ -35,7 +35,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://a.teads.tv/prebid-server/bid-request", + "uri": "https://psrv.teads.tv/prebid-server/bid-request", "body": { "id": "test-request-id", "imp": [ diff --git a/adapters/teads/teadstest/exemplary/simple-video.json b/adapters/teads/teadstest/exemplary/simple-video.json index 814569a47e1..de273aba904 100644 --- a/adapters/teads/teadstest/exemplary/simple-video.json +++ b/adapters/teads/teadstest/exemplary/simple-video.json @@ -48,7 +48,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://a.teads.tv/prebid-server/bid-request", + "uri": "https://psrv.teads.tv/prebid-server/bid-request", "body": { "id": "test-request-id", "imp": [ diff --git a/adapters/teads/teadstest/supplemental/bid-id-does-not-match.json b/adapters/teads/teadstest/supplemental/bid-id-does-not-match.json index 384e72fb537..b2e5c9e7aba 100644 --- a/adapters/teads/teadstest/supplemental/bid-id-does-not-match.json +++ b/adapters/teads/teadstest/supplemental/bid-id-does-not-match.json @@ -48,7 +48,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://a.teads.tv/prebid-server/bid-request", + "uri": "https://psrv.teads.tv/prebid-server/bid-request", "body": { "id": "test-request-id", "imp": [ diff --git a/adapters/teads/teadstest/supplemental/currency-empty-string.json b/adapters/teads/teadstest/supplemental/currency-empty-string.json index 5f0d700b14b..9168f265cae 100644 --- a/adapters/teads/teadstest/supplemental/currency-empty-string.json +++ b/adapters/teads/teadstest/supplemental/currency-empty-string.json @@ -48,7 +48,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://a.teads.tv/prebid-server/bid-request", + "uri": "https://psrv.teads.tv/prebid-server/bid-request", "body": { "id": "test-request-id", "imp": [ diff --git a/adapters/teads/teadstest/supplemental/no-impression-response.json b/adapters/teads/teadstest/supplemental/no-impression-response.json index 814569a47e1..de273aba904 100644 --- a/adapters/teads/teadstest/supplemental/no-impression-response.json +++ b/adapters/teads/teadstest/supplemental/no-impression-response.json @@ -48,7 +48,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://a.teads.tv/prebid-server/bid-request", + "uri": "https://psrv.teads.tv/prebid-server/bid-request", "body": { "id": "test-request-id", "imp": [ diff --git a/adapters/teads/teadstest/supplemental/renderer-name-empty.json b/adapters/teads/teadstest/supplemental/renderer-name-empty.json index da4ee9a5094..9d35cf2fe71 100644 --- a/adapters/teads/teadstest/supplemental/renderer-name-empty.json +++ b/adapters/teads/teadstest/supplemental/renderer-name-empty.json @@ -44,7 +44,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://a.teads.tv/prebid-server/bid-request", + "uri": "https://psrv.teads.tv/prebid-server/bid-request", "body": { "id": "test-request-id", "imp": [ diff --git a/adapters/teads/teadstest/supplemental/renderer-version-empty.json b/adapters/teads/teadstest/supplemental/renderer-version-empty.json index e9e7b278dcb..cb1a47d6fbe 100644 --- a/adapters/teads/teadstest/supplemental/renderer-version-empty.json +++ b/adapters/teads/teadstest/supplemental/renderer-version-empty.json @@ -44,7 +44,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://a.teads.tv/prebid-server/bid-request", + "uri": "https://psrv.teads.tv/prebid-server/bid-request", "body": { "id": "test-request-id", "imp": [ diff --git a/adapters/teads/teadstest/supplemental/status-400.json b/adapters/teads/teadstest/supplemental/status-400.json index cd9fafff0a1..98b1875402c 100644 --- a/adapters/teads/teadstest/supplemental/status-400.json +++ b/adapters/teads/teadstest/supplemental/status-400.json @@ -24,7 +24,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://a.teads.tv/prebid-server/bid-request", + "uri": "https://psrv.teads.tv/prebid-server/bid-request", "body": { "id": "test-request-id", "imp": [ diff --git a/adapters/teads/teadstest/supplemental/status-500.json b/adapters/teads/teadstest/supplemental/status-500.json index 337d4754006..4db6eed0ec8 100644 --- a/adapters/teads/teadstest/supplemental/status-500.json +++ b/adapters/teads/teadstest/supplemental/status-500.json @@ -24,7 +24,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://a.teads.tv/prebid-server/bid-request", + "uri": "https://psrv.teads.tv/prebid-server/bid-request", "body": { "id": "test-request-id", "imp": [ diff --git a/static/bidder-info/teads.yaml b/static/bidder-info/teads.yaml index 5dc428ddf7b..47686977673 100644 --- a/static/bidder-info/teads.yaml +++ b/static/bidder-info/teads.yaml @@ -1,4 +1,4 @@ -endpoint: "https://a.teads.tv/prebid-server/bid-request" +endpoint: "https://psrv.teads.tv/prebid-server/bid-request" maintainer: email: "support-sdk@teads.com" gvlVendorID: 132 From 06e1145971c81c66c884a77b1fe2cf0752d1d2f0 Mon Sep 17 00:00:00 2001 From: kalidas-alkimi <92875788+kalidas-alkimi@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:38:58 +0000 Subject: [PATCH 227/268] New Adapter: Alkimi (#3247) co-authored by @kalidas-alkimi @pro-nsk --- adapters/alkimi/alkimi.go | 192 ++++++++++++++++++ adapters/alkimi/alkimi_test.go | 57 ++++++ .../alkimitest/exemplary/simple-audio.json | 143 +++++++++++++ .../alkimitest/exemplary/simple-banner.json | 150 ++++++++++++++ .../alkimitest/exemplary/simple-video.json | 147 ++++++++++++++ .../supplemental/bad_media_type.json | 108 ++++++++++ .../alkimitest/supplemental/bad_response.json | 101 +++++++++ .../alkimitest/supplemental/status-204.json | 96 +++++++++ .../supplemental/status-not-200.json | 101 +++++++++ adapters/alkimi/params_test.go | 48 +++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_alkimi.go | 9 + static/bidder-info/alkimi.yaml | 15 ++ static/bidder-params/alkimi.json | 28 +++ 15 files changed, 1199 insertions(+) create mode 100644 adapters/alkimi/alkimi.go create mode 100644 adapters/alkimi/alkimi_test.go create mode 100644 adapters/alkimi/alkimitest/exemplary/simple-audio.json create mode 100644 adapters/alkimi/alkimitest/exemplary/simple-banner.json create mode 100644 adapters/alkimi/alkimitest/exemplary/simple-video.json create mode 100644 adapters/alkimi/alkimitest/supplemental/bad_media_type.json create mode 100644 adapters/alkimi/alkimitest/supplemental/bad_response.json create mode 100644 adapters/alkimi/alkimitest/supplemental/status-204.json create mode 100644 adapters/alkimi/alkimitest/supplemental/status-not-200.json create mode 100644 adapters/alkimi/params_test.go create mode 100644 openrtb_ext/imp_alkimi.go create mode 100644 static/bidder-info/alkimi.yaml create mode 100644 static/bidder-params/alkimi.json diff --git a/adapters/alkimi/alkimi.go b/adapters/alkimi/alkimi.go new file mode 100644 index 00000000000..f0979c3a809 --- /dev/null +++ b/adapters/alkimi/alkimi.go @@ -0,0 +1,192 @@ +package alkimi + +import ( + "encoding/json" + "fmt" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/floors" + "net/http" + "net/url" + "strconv" + "strings" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" +) + +const price_macro = "${AUCTION_PRICE}" + +type adapter struct { + endpoint string +} + +type extObj struct { + AlkimiBidderExt openrtb_ext.ExtImpAlkimi `json:"bidder"` +} + +// Builder builds a new instance of the Alkimi adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + endpointURL, err := url.Parse(config.Endpoint) + if err != nil || len(endpointURL.String()) == 0 { + return nil, fmt.Errorf("invalid endpoint: %v", err) + } + + bidder := &adapter{ + endpoint: endpointURL.String(), + } + return bidder, nil +} + +// MakeRequests creates Alkimi adapter requests +func (adapter *adapter) MakeRequests(request *openrtb2.BidRequest, req *adapters.ExtraRequestInfo) (reqsBidder []*adapters.RequestData, errs []error) { + reqCopy := *request + + updated, errs := updateImps(reqCopy) + if len(errs) > 0 || len(reqCopy.Imp) != len(updated) { + return nil, errs + } + + reqCopy.Imp = updated + encoded, err := json.Marshal(reqCopy) + if err != nil { + errs = append(errs, err) + } else { + reqBidder := buildBidderRequest(adapter, encoded) + reqsBidder = append(reqsBidder, reqBidder) + } + return +} + +func updateImps(bidRequest openrtb2.BidRequest) ([]openrtb2.Imp, []error) { + var errs []error + + updatedImps := make([]openrtb2.Imp, 0, len(bidRequest.Imp)) + for _, imp := range bidRequest.Imp { + + var bidderExt adapters.ExtImpBidder + var extImpAlkimi openrtb_ext.ExtImpAlkimi + + if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + errs = append(errs, err) + continue + } + + if err := json.Unmarshal(bidderExt.Bidder, &extImpAlkimi); err != nil { + errs = append(errs, err) + continue + } + + var bidFloorPrice floors.Price + bidFloorPrice.FloorMinCur = imp.BidFloorCur + bidFloorPrice.FloorMin = imp.BidFloor + + if len(bidFloorPrice.FloorMinCur) > 0 && bidFloorPrice.FloorMin > 0 { + imp.BidFloor = bidFloorPrice.FloorMin + } else { + imp.BidFloor = extImpAlkimi.BidFloor + } + imp.Instl = extImpAlkimi.Instl + imp.Exp = extImpAlkimi.Exp + + temp := extObj{AlkimiBidderExt: extImpAlkimi} + temp.AlkimiBidderExt.AdUnitCode = imp.ID + + extJson, err := json.Marshal(temp) + if err != nil { + errs = append(errs, err) + continue + } + imp.Ext = extJson + updatedImps = append(updatedImps, imp) + } + + return updatedImps, errs +} + +func buildBidderRequest(adapter *adapter, encoded []byte) *adapters.RequestData { + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + + reqBidder := &adapters.RequestData{ + Method: "POST", + Uri: adapter.endpoint, + Body: encoded, + Headers: headers, + } + return reqBidder +} + +// MakeBids will parse the bids from the Alkimi server +func (adapter *adapter) MakeBids(request *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + var errs []error + + if adapters.IsResponseStatusCodeNoContent(response) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(response); err != nil { + return nil, []error{err} + } + + var bidResp openrtb2.BidResponse + err := json.Unmarshal(response.Body, &bidResp) + if err != nil { + return nil, []error{err} + } + + seatBidCount := len(bidResp.SeatBid) + if seatBidCount == 0 { + return nil, []error{&errortypes.BadServerResponse{ + Message: "Empty SeatBid array", + }} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + for _, seatBid := range bidResp.SeatBid { + for _, bid := range seatBid.Bid { + copyBid := bid + resolveMacros(©Bid) + impId := copyBid.ImpID + imp := request.Imp + bidType, err := getMediaTypeForImp(impId, imp) + if err != nil { + errs = append(errs, err) + continue + } + bidderBid := &adapters.TypedBid{ + Bid: ©Bid, + BidType: bidType, + } + bidResponse.Bids = append(bidResponse.Bids, bidderBid) + } + } + return bidResponse, errs +} + +func resolveMacros(bid *openrtb2.Bid) { + strPrice := strconv.FormatFloat(bid.Price, 'f', -1, 64) + bid.NURL = strings.Replace(bid.NURL, price_macro, strPrice, -1) + bid.AdM = strings.Replace(bid.AdM, price_macro, strPrice, -1) +} + +func getMediaTypeForImp(impId string, imps []openrtb2.Imp) (openrtb_ext.BidType, error) { + for _, imp := range imps { + if imp.ID == impId { + if imp.Banner != nil { + return openrtb_ext.BidTypeBanner, nil + } + if imp.Video != nil { + return openrtb_ext.BidTypeVideo, nil + } + if imp.Audio != nil { + return openrtb_ext.BidTypeAudio, nil + } + } + } + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("Failed to find imp \"%s\"", impId), + } +} diff --git a/adapters/alkimi/alkimi_test.go b/adapters/alkimi/alkimi_test.go new file mode 100644 index 00000000000..b745f0feb95 --- /dev/null +++ b/adapters/alkimi/alkimi_test.go @@ -0,0 +1,57 @@ +package alkimi + +import ( + "testing" + + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +const ( + alkimiTestEndpoint = "https://exchange.alkimi-onboarding.com/server/bid" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder( + openrtb_ext.BidderAlkimi, + config.Adapter{Endpoint: alkimiTestEndpoint}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}, + ) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "alkimitest", bidder) +} + +func TestEndpointEmpty(t *testing.T) { + _, buildErr := Builder(openrtb_ext.BidderAlkimi, config.Adapter{ + Endpoint: ""}, config.Server{ExternalUrl: alkimiTestEndpoint, GvlID: 1, DataCenter: "2"}) + assert.Error(t, buildErr) +} + +func TestEndpointMalformed(t *testing.T) { + _, buildErr := Builder(openrtb_ext.BidderAlkimi, config.Adapter{ + Endpoint: " http://leading.space.is.invalid"}, config.Server{ExternalUrl: alkimiTestEndpoint, GvlID: 1, DataCenter: "2"}) + assert.Error(t, buildErr) +} + +func TestBuilder(t *testing.T) { + bidder, buildErr := buildBidder() + if buildErr != nil { + t.Fatalf("Failed to build bidder: %v", buildErr) + } + assert.NotNil(t, bidder) +} + +func buildBidder() (adapters.Bidder, error) { + return Builder( + openrtb_ext.BidderAlkimi, + config.Adapter{Endpoint: alkimiTestEndpoint}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}, + ) +} diff --git a/adapters/alkimi/alkimitest/exemplary/simple-audio.json b/adapters/alkimi/alkimitest/exemplary/simple-audio.json new file mode 100644 index 00000000000..09ac2131a12 --- /dev/null +++ b/adapters/alkimi/alkimitest/exemplary/simple-audio.json @@ -0,0 +1,143 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "site": { + "domain": "www.example.com", + "page": "http://www.example.com", + "publisher": { + "domain": "example.com" + }, + "ext": { + "amp": 0 + } + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "audio": { + "mimes": [ + "audio/mpeg", + "audio/mp3" + ], + "minduration": 5, + "maxduration": 30, + "minbitrate": 32, + "maxbitrate": 128 + }, + "bidfloor": 0.7, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "token": "XXX", + "bidFloor": 0.5 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://exchange.alkimi-onboarding.com/server/bid", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "audio": { + "mimes": [ + "audio/mpeg", + "audio/mp3" + ], + "minduration": 5, + "maxduration": 30, + "minbitrate": 32, + "maxbitrate": 128 + }, + "bidfloor": 0.7, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "token": "XXX", + "bidFloor": 0.5, + "adUnitCode": "test-imp-id", + "exp": 0, + "instl": 0 + } + } + } + ], + "site": { + "domain": "www.example.com", + "page": "http://www.example.com", + "publisher": { + "domain": "example.com" + }, + "ext": { + "amp": 0 + } + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.9, + "adm": "<\/Error><\/Impression>00:00:15<\/Duration><\/Tracking><\/TrackingEvents><\/ClickThrough><\/VideoClicks><\/MediaFile><\/MediaFiles><\/Linear><\/Creative><\/Creatives><\/InLine><\/Ad><\/VAST>", + "cid": "test_cid", + "crid": "test_crid", + "ext": { + "prebid": { + "type": "audio" + } + } + } + ], + "seat": "alkimi" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.9, + "adm": "<\/Error><\/Impression>00:00:15<\/Duration><\/Tracking><\/TrackingEvents><\/ClickThrough><\/VideoClicks><\/MediaFile><\/MediaFiles><\/Linear><\/Creative><\/Creatives><\/InLine><\/Ad><\/VAST>", + "cid": "test_cid", + "crid": "test_crid", + "ext": { + "prebid": { + "type": "audio" + } + } + }, + "type": "audio" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/alkimi/alkimitest/exemplary/simple-banner.json b/adapters/alkimi/alkimitest/exemplary/simple-banner.json new file mode 100644 index 00000000000..96512989596 --- /dev/null +++ b/adapters/alkimi/alkimitest/exemplary/simple-banner.json @@ -0,0 +1,150 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "site": { + "domain": "www.example.com", + "page": "http://www.example.com", + "publisher": { + "domain": "example.com" + }, + "ext": { + "amp": 0 + } + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "token": "XXX", + "bidFloor": 0.5 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://exchange.alkimi-onboarding.com/server/bid", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "bidfloor": 0.5, + "ext": { + "bidder": { + "token": "XXX", + "bidFloor": 0.5, + "adUnitCode": "test-imp-id", + "exp": 0, + "instl": 0 + } + } + } + ], + "site": { + "domain": "www.example.com", + "page": "http://www.example.com", + "publisher": { + "domain": "example.com" + }, + "ext": { + "amp": 0 + } + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.9, + "adm": "
<\/a><\/div>\"}", - "ext": { - "prebid": { - "type": "native" - } - } - } - ], - "seat": "123" - } - ], - "bidid": "8141327771600527856", - "cur": "EUR" - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "EUR", - "bids": [ - { - "bid": { - "id": "some-id", - "impid": "test-imp-id", - "price": 1, - "adid": "69595837", - "adm": "{\"assets\":[{\"id\": 2,\"img\":{\"url\":\"http://example.com/p/creative-image/5e/b6/de/c3/5eb6dec3-4854-4dcd-980a-347f36ab502e.jpg\",\"w\": 3000,\"h\": 2250}},{\"id\": 1,\"title\":{\"text\":\"This is an example Prebid Native creative\"}},{\"id\": 3,\"data\":{\"value\":\"Prebid.org\"}},{\"id\": 4,\"data\":{\"value\":\"This is a Prebid Native Creative. There are many like it, but this one is mine.\"}}],\"link\":{\"url\":\"http://example.com/click?AAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAA8D8AAAAAAADwPwhdYz3ZyNFNG3fXpZUyLXNZ0o5aAAAAACrElgC-AwAAvgMAAAIAAAC98iUEeP4QAAAAAABVU0QAVVNEAAEAAQARIAAAAAABAgQCAAAAAAEAhBaSXgAAAAA./pp=1/cnd=%21OwwGAQiGmooHEL3llyEY-PxDIAQoADoRZGVmYXVsdCNOWU0yOjQwMjM./bn=75922/test=1/referrer=prebid.org/clickenc=http%3A%2F%2Fprebid.org%2Fdev-docs%2Fshow-native-ads.html\"},\"imptrackers\":[\"http://example.com/openrtb_win?e=wqT_3QLFBqBFAwAAAwDWAAUBCNmku9QFEIi6jeuTm_LoTRib7t2u2tLMlnMqNgkAAAECCPA_EQEHEAAA8D8ZCQkIAAAhCQkI8D8pEQkAMQkJqAAAMKqI2wQ4vgdAvgdIAlC95ZchWPj8Q2AAaJFAeJLRBIABAYoBA1VTRJIFBvBQmAEBoAEBqAEBsAEAuAECwAEEyAEC0AEJ2AEA4AEB8AEAigI7dWYoJ2EnLCAxMzc2ODYwLCAxNTE5MzA5NDAxKTt1ZigncicsIDY5NTk1ODM3Nh4A8IqSAvUBIXRETkdfUWlHbW9vSEVMM2xseUVZQUNENF9FTXdBRGdBUUFSSXZnZFFxb2piQkZnQVlMTURhQUJ3QUhnQWdBRUFpQUVBa0FFQm1BRUJvQUVCcUFFRHNBRUF1UUVwaTRpREFBRHdQOEVCS1l1SWd3QUE4RF9KQVhfelYzek1zXzBfMlFFQUFBAQMkRHdQLUFCQVBVQgEOLEFKZ0NBS0FDQUxVQwUQBEwwCQjwTE1BQ0FNZ0NBT0FDQU9nQ0FQZ0NBSUFEQVpBREFKZ0RBYWdEaHBxS0I3b0RFV1JsWm1GMWJIUWpUbGxOTWpvME1ESXqaAjkhT3d3R0FRNvgA8E4tUHhESUFRb0FEb1JaR1ZtWVhWc2RDTk9XVTB5T2pRd01qTS7YAugH4ALH0wHqAgpwcmViaWQub3Jn8gIRCgZBRFZfSUQSBzEzNzY4NjDyARQMQ1BHXwEUNDM1MDMwOTjyAhEKBUNQARPwmQgxNDg0NzIzOIADAYgDAZADAJgDFKADAaoDAMADkBzIAwDYAwDgAwDoAwD4AwOABACSBAkvb3BlbnJ0YjKYBACiBAwxNTIuMTkzLjYuNzSoBJrMI7IEDAgAEAAYACAAMAA4ALgEAMAEAMgEANIEEWRlZmF1bHQjTllNMjo0MDIz2gQCCADgBADwBL3llyGIBQGYBQCgBf____8FA1ABqgULc29tZS1yZXEtaWTABQDJBQAFARTwP9IFCQkFC2QAAADYBQHgBQHwBd4C-gUECAAQAJAGAZgGAA..&s=08b1535744639c904684afe46e3c6c0e4786089f&test=1&referrer=prebid.org&pp=1\"],\"jstracker\":\"\"}", - "ext": { - "prebid": { - "type": "native" - } - } - }, - "type": "native" - } - ] - } - ] -} \ No newline at end of file diff --git a/adapters/suntContent/suntContenttest/supplemental/invalid_tag_id.json b/adapters/suntContent/suntContenttest/supplemental/invalid_tag_id.json deleted file mode 100644 index 1493d336f9d..00000000000 --- a/adapters/suntContent/suntContenttest/supplemental/invalid_tag_id.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "expectedMakeRequestsErrors": [ - { - "value": "could not unmarshal openrtb_ext.ImpExtSuntContent: json: cannot unmarshal number into Go struct field ImpExtSuntContent.adUnitID of type string", - "comparison": "literal" - } - ], - "mockBidRequest": { - "id": "test-request-id", - "site": { - "publisher": { - "id": "foo", - "name": "foo" - } - }, - "imp": [ - { - "id": "test-imp-id", - "native": { - "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" - }, - "ext": { - "bidder": { - "adUnitId": 1234 - } - } - } - ] - } -} \ No newline at end of file diff --git a/adapters/suntContent/suntContenttest/supplemental/status_bad_request.json b/adapters/suntContent/suntContenttest/supplemental/status_bad_request.json deleted file mode 100644 index d7e62bb90cb..00000000000 --- a/adapters/suntContent/suntContenttest/supplemental/status_bad_request.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "ext": { - "bidder": { - "adUnitId": "example-tag-id" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://mockup.suntcontent.com/", - "body": { - "cur": [ - "EUR" - ], - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "tagid": "example-tag-id", - "ext": { - "bidder": { - "adUnitId": "example-tag-id" - } - } - } - ] - } - }, - "mockResponse": { - "status": 400 - } - } - ], - "expectedMakeBidsErrors": [ - { - "value": "Unexpected status code: 400. Bad request from publisher. Run with request.debug = 1 for more info.", - "comparison": "literal" - } - ] -} \ No newline at end of file diff --git a/adapters/suntContent/suntContenttest/supplemental/status_no_content.json b/adapters/suntContent/suntContenttest/supplemental/status_no_content.json deleted file mode 100644 index 8eda774c657..00000000000 --- a/adapters/suntContent/suntContenttest/supplemental/status_no_content.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "ext": { - "bidder": { - "adUnitId": "example-tag-id" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://mockup.suntcontent.com/", - "body": { - "cur": [ - "EUR" - ], - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "tagid": "example-tag-id", - "ext": { - "bidder": { - "adUnitId": "example-tag-id" - } - } - } - ] - } - }, - "mockResponse": { - "status": 204 - } - } - ] -} \ No newline at end of file diff --git a/adapters/suntContent/suntContenttest/supplemental/status_not_ok.json b/adapters/suntContent/suntContenttest/supplemental/status_not_ok.json deleted file mode 100644 index 07618aed7fa..00000000000 --- a/adapters/suntContent/suntContenttest/supplemental/status_not_ok.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "ext": { - "bidder": { - "adUnitId": "example-tag-id" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://mockup.suntcontent.com/", - "body": { - "cur": [ - "EUR" - ], - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "tagid": "example-tag-id", - "ext": { - "bidder": { - "adUnitId": "example-tag-id" - } - } - } - ] - } - }, - "mockResponse": { - "status": 404 - } - } - ], - "expectedMakeBidsErrors": [ - { - "value": "Unexpected status code: 404. Run with request.debug = 1 for more info.", - "comparison": "literal" - } - ] -} \ No newline at end of file diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index d8fd57c3187..5de2d78362e 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -163,7 +163,6 @@ import ( "github.com/prebid/prebid-server/v2/adapters/sovrn" "github.com/prebid/prebid-server/v2/adapters/sspBC" "github.com/prebid/prebid-server/v2/adapters/stroeerCore" - "github.com/prebid/prebid-server/v2/adapters/suntContent" "github.com/prebid/prebid-server/v2/adapters/taboola" "github.com/prebid/prebid-server/v2/adapters/tappx" "github.com/prebid/prebid-server/v2/adapters/teads" @@ -361,7 +360,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderSonobi: sonobi.Builder, openrtb_ext.BidderSovrn: sovrn.Builder, openrtb_ext.BidderSspBC: sspBC.Builder, - openrtb_ext.BidderSuntContent: suntContent.Builder, openrtb_ext.BidderStroeerCore: stroeerCore.Builder, openrtb_ext.BidderTaboola: taboola.Builder, openrtb_ext.BidderTappx: tappx.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 9c2afdae13e..cc4e095a93e 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -181,7 +181,6 @@ var coreBidderNames []BidderName = []BidderName{ BidderSovrn, BidderSspBC, BidderStroeerCore, - BidderSuntContent, BidderTaboola, BidderTappx, BidderTeads, @@ -460,7 +459,6 @@ const ( BidderSovrn BidderName = "sovrn" BidderSspBC BidderName = "sspBC" BidderStroeerCore BidderName = "stroeerCore" - BidderSuntContent BidderName = "suntContent" BidderTaboola BidderName = "taboola" BidderTappx BidderName = "tappx" BidderTeads BidderName = "teads" @@ -625,7 +623,7 @@ func NewBidderParamsValidator(schemaDirectory string) (BidderParamValidator, err schemaContents[BidderName(bidderName)] = string(fileBytes) } - //set alias bidder params schema to its parent + // set alias bidder params schema to its parent for alias, parent := range aliasBidderToParent { parentSchema := schemas[parent] schemas[alias] = parentSchema diff --git a/openrtb_ext/imp_seedingAlliance.go b/openrtb_ext/imp_seedingAlliance.go index 759683ad6b3..0f594d3c933 100644 --- a/openrtb_ext/imp_seedingAlliance.go +++ b/openrtb_ext/imp_seedingAlliance.go @@ -1,5 +1,6 @@ package openrtb_ext type ImpExtSeedingAlliance struct { - AdUnitID string `json:"adUnitID"` + AdUnitID string `json:"adUnitId"` + SeatID string `json:"seatId"` } diff --git a/openrtb_ext/imp_suntContent.go b/openrtb_ext/imp_suntContent.go deleted file mode 100644 index 5040df7e3b6..00000000000 --- a/openrtb_ext/imp_suntContent.go +++ /dev/null @@ -1,5 +0,0 @@ -package openrtb_ext - -type ImpExtSuntContent struct { - AdUnitID string `json:"adUnitID"` -} diff --git a/static/bidder-info/finative.yaml b/static/bidder-info/finative.yaml new file mode 100644 index 00000000000..e1136c3220d --- /dev/null +++ b/static/bidder-info/finative.yaml @@ -0,0 +1,2 @@ +endpoint: "https://b.finative.cloud/cds/rtb/bid?ssp={{.AccountID}}" +aliasOf: "seedingAlliance" \ No newline at end of file diff --git a/static/bidder-info/seedingAlliance.yaml b/static/bidder-info/seedingAlliance.yaml index dee9fcd6026..9dcb7701b34 100644 --- a/static/bidder-info/seedingAlliance.yaml +++ b/static/bidder-info/seedingAlliance.yaml @@ -1,4 +1,4 @@ -endpoint: "https://b.nativendo.de/cds/rtb/bid?ssp=pbs" +endpoint: "https://b.nativendo.de/cds/rtb/bid?ssp={{.AccountID}}" maintainer: email: tech@seeding-alliance.de gvlVendorID: 371 diff --git a/static/bidder-info/suntContent.yaml b/static/bidder-info/suntContent.yaml index e46cc4086e0..bb5eb2ee977 100644 --- a/static/bidder-info/suntContent.yaml +++ b/static/bidder-info/suntContent.yaml @@ -1,13 +1,7 @@ -endpoint: "https://b.suntcontent.se/cds/rtb/bid?ssp=pbs" -maintainer: - email: tech@seeding-alliance.de +endpoint: "https://b.suntcontent.se/cds/rtb/bid?ssp={{.AccountID}}" +aliasOf: "seedingAlliance" gvlVendorID: 1097 -capabilities: - site: - mediaTypes: - - native - - banner userSync: redirect: url: "https://dmp.suntcontent.se/set-uuid?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirect_url={{.RedirectURL}}" - userMacro: "$UID" + userMacro: "$UID" \ No newline at end of file diff --git a/static/bidder-params/seedingAlliance.json b/static/bidder-params/seedingAlliance.json index cf9aa375eb4..5fe463b6803 100644 --- a/static/bidder-params/seedingAlliance.json +++ b/static/bidder-params/seedingAlliance.json @@ -8,6 +8,10 @@ "type": "string", "description": "Ad Unit ID", "minLength": 1 + }, + "seatId": { + "type": "string", + "description": "Seat ID" } }, "required": [ diff --git a/static/bidder-params/suntContent.json b/static/bidder-params/suntContent.json deleted file mode 100644 index e85ad3f5de5..00000000000 --- a/static/bidder-params/suntContent.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "SUNT Content Adapter Params", - "description": "A schema which validates params accepted by the SUNT Content adapter", - "type": "object", - "properties": { - "adUnitId": { - "type": "string", - "description": "Ad Unit ID", - "minLength": 1 - } - }, - "required": [ - "adUnitId" - ] -} \ No newline at end of file diff --git a/usersync/chooser_test.go b/usersync/chooser_test.go index abf49b7f7c2..9bc06100e81 100644 --- a/usersync/chooser_test.go +++ b/usersync/chooser_test.go @@ -66,7 +66,8 @@ func TestChooserChoose(t *testing.T) { syncTypeFilter := SyncTypeFilter{ IFrame: NewUniformBidderFilter(BidderFilterModeInclude), - Redirect: NewUniformBidderFilter(BidderFilterModeExclude)} + Redirect: NewUniformBidderFilter(BidderFilterModeExclude), + } cooperativeConfig := Cooperative{Enabled: true} @@ -455,11 +456,12 @@ func TestChooserEvaluate(t *testing.T) { fakeSyncerB := fakeSyncer{key: "keyB", supportsIFrame: false} biddersKnown := map[string]struct{}{"a": {}, "b": {}, "unconfigured": {}} - bidderSyncerLookup := map[string]Syncer{"a": fakeSyncerA, "b": fakeSyncerB, "appnexus": fakeSyncerA, "suntContent": fakeSyncerA} + bidderSyncerLookup := map[string]Syncer{"a": fakeSyncerA, "b": fakeSyncerB, "appnexus": fakeSyncerA, "seedingAlliance": fakeSyncerA} syncTypeFilter := SyncTypeFilter{ IFrame: NewUniformBidderFilter(BidderFilterModeInclude), - Redirect: NewUniformBidderFilter(BidderFilterModeExclude)} + Redirect: NewUniformBidderFilter(BidderFilterModeExclude), + } normalizedBidderNamesLookup := func(name string) (openrtb_ext.BidderName, bool) { return openrtb_ext.BidderName(name), true } @@ -593,17 +595,18 @@ func TestChooserEvaluate(t *testing.T) { }, { description: "Case insensitivity check for sync type filter", - givenBidder: "SuntContent", - normalisedBidderName: "suntContent", + givenBidder: "SeedingAlliance", + normalisedBidderName: "seedingAlliance", givenSyncersSeen: map[string]struct{}{}, givenPrivacy: fakePrivacy{gdprAllowsHostCookie: true, gdprAllowsBidderSync: true, ccpaAllowsBidderSync: true, activityAllowUserSync: true}, givenCookie: cookieNeedsSync, givenSyncTypeFilter: SyncTypeFilter{ - IFrame: NewSpecificBidderFilter([]string{"SuntContent"}, BidderFilterModeInclude), - Redirect: NewSpecificBidderFilter([]string{"SuntContent"}, BidderFilterModeExclude)}, + IFrame: NewSpecificBidderFilter([]string{"SeedingAlliance"}, BidderFilterModeInclude), + Redirect: NewSpecificBidderFilter([]string{"SeedingAlliance"}, BidderFilterModeExclude), + }, normalizedBidderNamesLookup: openrtb_ext.NormalizeBidderName, expectedSyncer: fakeSyncerA, - expectedEvaluation: BidderEvaluation{Bidder: "SuntContent", SyncerKey: "keyA", Status: StatusOK}, + expectedEvaluation: BidderEvaluation{Bidder: "SeedingAlliance", SyncerKey: "keyA", Status: StatusOK}, }, { description: "Case Insensitivity Check For Blocked By GDPR", From ec873dcc87a93c380733c5cd96a75d1b12f920d8 Mon Sep 17 00:00:00 2001 From: Veronika Solovei Date: Mon, 11 Dec 2023 13:38:33 -0800 Subject: [PATCH 252/268] Modules activities (#3057) --- endpoints/openrtb2/amp_auction.go | 2 + endpoints/openrtb2/auction.go | 2 + exchange/utils.go | 32 +---- hooks/hookexecution/context.go | 12 +- hooks/hookexecution/execution.go | 33 ++++- hooks/hookexecution/execution_test.go | 151 +++++++++++++++++++++ hooks/hookexecution/executor.go | 34 +++-- hooks/hookexecution/executor_test.go | 50 ++++++- hooks/hookstage/bidderrequest.go | 14 ++ hooks/hookstage/processedauctionrequest.go | 9 +- ortb/clone.go | 31 +++++ ortb/clone_test.go | 52 +++++++ 12 files changed, 371 insertions(+), 51 deletions(-) create mode 100644 hooks/hookexecution/execution_test.go diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index 8f8d32c8fb9..db427f380ed 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -234,6 +234,8 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h activityControl = privacy.NewActivityControl(&account.Privacy) + hookExecutor.SetActivityControl(activityControl) + secGPC := r.Header.Get("Sec-GPC") auctionRequest := &exchange.AuctionRequest{ diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 72382f36b04..eb3f5c02ccb 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -205,6 +205,8 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http activityControl = privacy.NewActivityControl(&account.Privacy) + hookExecutor.SetActivityControl(activityControl) + ctx := context.Background() timeout := deps.cfg.AuctionTimeouts.LimitAuctionTimeout(time.Duration(req.TMax) * time.Millisecond) diff --git a/exchange/utils.go b/exchange/utils.go index dfe1fe448ba..53890718a1d 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "github.com/prebid/prebid-server/v2/ortb" "math/rand" "strings" @@ -21,7 +22,6 @@ import ( "github.com/prebid/prebid-server/v2/gdpr" "github.com/prebid/prebid-server/v2/metrics" "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/ortb" "github.com/prebid/prebid-server/v2/privacy" "github.com/prebid/prebid-server/v2/privacy/ccpa" "github.com/prebid/prebid-server/v2/privacy/lmt" @@ -181,7 +181,7 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, // FPD should be applied before policies, otherwise it overrides policies and activities restricted data applyFPD(auctionReq.FirstPartyData, bidderRequest) - reqWrapper := cloneBidderReq(bidderRequest.BidRequest) + reqWrapper := ortb.CloneBidderReq(bidderRequest.BidRequest) passIDActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitUserFPD, scopedName, privacy.NewRequestFromBidRequest(*req)) if !passIDActivityAllowed { @@ -238,34 +238,6 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, return } -// cloneBidderReq - clones bidder request and replaces req.User and req.Device with new copies -func cloneBidderReq(req *openrtb2.BidRequest) *openrtb_ext.RequestWrapper { - - // bidder request may be modified differently per bidder based on privacy configs - // new request should be created for each bidder request - // pointer fields like User and Device should be cloned and set back to the request copy - var newReq *openrtb2.BidRequest - newReq = ptrutil.Clone(req) - - if req.User != nil { - userCopy := ortb.CloneUser(req.User) - newReq.User = userCopy - } - - if req.Device != nil { - deviceCopy := ortb.CloneDevice(req.Device) - newReq.Device = deviceCopy - } - - if req.Source != nil { - sourceCopy := ortb.CloneSource(req.Source) - newReq.Source = sourceCopy - } - - reqWrapper := &openrtb_ext.RequestWrapper{BidRequest: newReq} - return reqWrapper -} - func shouldSetLegacyPrivacy(bidderInfo config.BidderInfos, bidder string) bool { binfo, defined := bidderInfo[bidder] diff --git a/hooks/hookexecution/context.go b/hooks/hookexecution/context.go index 0817078137f..f7b6a9d32e1 100644 --- a/hooks/hookexecution/context.go +++ b/hooks/hookexecution/context.go @@ -6,15 +6,17 @@ import ( "github.com/golang/glog" "github.com/prebid/prebid-server/v2/config" "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v2/privacy" ) // executionContext holds information passed to module's hook during hook execution. type executionContext struct { - endpoint string - stage string - accountId string - account *config.Account - moduleContexts *moduleContexts + endpoint string + stage string + accountID string + account *config.Account + moduleContexts *moduleContexts + activityControl privacy.ActivityControl } func (ctx executionContext) getModuleContext(moduleName string) hookstage.ModuleInvocationContext { diff --git a/hooks/hookexecution/execution.go b/hooks/hookexecution/execution.go index 90ee9b46a9c..05cc5fb5943 100644 --- a/hooks/hookexecution/execution.go +++ b/hooks/hookexecution/execution.go @@ -3,6 +3,7 @@ package hookexecution import ( "context" "fmt" + "github.com/prebid/prebid-server/v2/ortb" "strings" "sync" "time" @@ -10,6 +11,7 @@ import ( "github.com/prebid/prebid-server/v2/hooks" "github.com/prebid/prebid-server/v2/hooks/hookstage" "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v2/privacy" ) type hookResponse[T any] struct { @@ -66,10 +68,11 @@ func executeGroup[H any, P any]( for _, hook := range group.Hooks { mCtx := executionCtx.getModuleContext(hook.Module) + newPayload := handleModuleActivities(hook.Code, executionCtx.activityControl, payload) wg.Add(1) go func(hw hooks.HookWrapper[H], moduleCtx hookstage.ModuleInvocationContext) { defer wg.Done() - executeHook(moduleCtx, hw, payload, hookHandler, group.Timeout, resp, rejected) + executeHook(moduleCtx, hw, newPayload, hookHandler, group.Timeout, resp, rejected) }(hook, mCtx) } @@ -176,7 +179,7 @@ func handleHookResponse[P any]( metricEngine metrics.MetricsEngine, ) (P, HookOutcome, *RejectError) { var rejectErr *RejectError - labels := metrics.ModuleLabels{Module: moduleReplacer.Replace(hr.HookID.ModuleCode), Stage: ctx.stage, AccountID: ctx.accountId} + labels := metrics.ModuleLabels{Module: moduleReplacer.Replace(hr.HookID.ModuleCode), Stage: ctx.stage, AccountID: ctx.accountID} metricEngine.RecordModuleCalled(labels, hr.ExecutionTime) hookOutcome := HookOutcome{ @@ -311,3 +314,29 @@ func handleHookMutations[P any]( return payload } + +func handleModuleActivities[P any](hookCode string, activityControl privacy.ActivityControl, payload P) P { + payloadData, ok := any(&payload).(hookstage.RequestUpdater) + if !ok { + return payload + } + + scopeGeneral := privacy.Component{Type: privacy.ComponentTypeGeneral, Name: hookCode} + transmitUserFPDActivityAllowed := activityControl.Allow(privacy.ActivityTransmitUserFPD, scopeGeneral, privacy.ActivityRequest{}) + + if !transmitUserFPDActivityAllowed { + // changes need to be applied to new payload and leave original payload unchanged + bidderReq := payloadData.GetBidderRequestPayload() + + bidderReqCopy := ortb.CloneBidderReq(bidderReq.BidRequest) + + privacy.ScrubUserFPD(bidderReqCopy) + + var newPayload = payload + var np = any(&newPayload).(hookstage.RequestUpdater) + np.SetBidderRequestPayload(bidderReqCopy) + return newPayload + } + + return payload +} diff --git a/hooks/hookexecution/execution_test.go b/hooks/hookexecution/execution_test.go new file mode 100644 index 00000000000..a12175e30a0 --- /dev/null +++ b/hooks/hookexecution/execution_test.go @@ -0,0 +1,151 @@ +package hookexecution + +import ( + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/privacy" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestHandleModuleActivitiesBidderRequestPayload(t *testing.T) { + + testCases := []struct { + description string + hookCode string + privacyConfig *config.AccountPrivacy + inPayloadData hookstage.BidderRequestPayload + expectedPayloadData hookstage.BidderRequestPayload + }{ + { + description: "payload should change when userFPD is blocked by activity", + hookCode: "foo", + inPayloadData: hookstage.BidderRequestPayload{ + Request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + User: &openrtb2.User{ID: "test_user_id"}, + }}, + }, + privacyConfig: getTransmitUFPDActivityConfig("foo", false), + expectedPayloadData: hookstage.BidderRequestPayload{ + Request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + User: &openrtb2.User{ID: ""}, + }, + }}, + }, + { + description: "payload should not change when userFPD is not blocked by activity", + hookCode: "foo", + inPayloadData: hookstage.BidderRequestPayload{ + Request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + User: &openrtb2.User{ID: "test_user_id"}, + }}, + }, + privacyConfig: getTransmitUFPDActivityConfig("foo", true), + expectedPayloadData: hookstage.BidderRequestPayload{ + Request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + User: &openrtb2.User{ID: "test_user_id"}, + }}, + }, + }, + } + for _, test := range testCases { + t.Run(test.description, func(t *testing.T) { + //check input payload didn't change + origInPayloadData := test.inPayloadData + activityControl := privacy.NewActivityControl(test.privacyConfig) + newPayload := handleModuleActivities(test.hookCode, activityControl, test.inPayloadData) + assert.Equal(t, test.expectedPayloadData.Request.BidRequest, newPayload.Request.BidRequest) + assert.Equal(t, origInPayloadData, test.inPayloadData) + }) + } +} + +func TestHandleModuleActivitiesProcessedAuctionRequestPayload(t *testing.T) { + + testCases := []struct { + description string + hookCode string + privacyConfig *config.AccountPrivacy + inPayloadData hookstage.ProcessedAuctionRequestPayload + expectedPayloadData hookstage.ProcessedAuctionRequestPayload + }{ + { + description: "payload should change when userFPD is blocked by activity", + hookCode: "foo", + inPayloadData: hookstage.ProcessedAuctionRequestPayload{ + Request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + User: &openrtb2.User{ID: "test_user_id"}, + }}, + }, + privacyConfig: getTransmitUFPDActivityConfig("foo", false), + expectedPayloadData: hookstage.ProcessedAuctionRequestPayload{ + Request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + User: &openrtb2.User{ID: ""}, + }}, + }, + }, + { + description: "payload should not change when userFPD is not blocked by activity", + hookCode: "foo", + inPayloadData: hookstage.ProcessedAuctionRequestPayload{ + Request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + User: &openrtb2.User{ID: "test_user_id"}, + }}, + }, + privacyConfig: getTransmitUFPDActivityConfig("foo", true), + expectedPayloadData: hookstage.ProcessedAuctionRequestPayload{ + Request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{ + User: &openrtb2.User{ID: "test_user_id"}, + }}, + }, + }, + } + for _, test := range testCases { + t.Run(test.description, func(t *testing.T) { + //check input payload didn't change + origInPayloadData := test.inPayloadData + activityControl := privacy.NewActivityControl(test.privacyConfig) + newPayload := handleModuleActivities(test.hookCode, activityControl, test.inPayloadData) + assert.Equal(t, test.expectedPayloadData.Request.BidRequest, newPayload.Request.BidRequest) + assert.Equal(t, origInPayloadData, test.inPayloadData) + }) + } +} + +func TestHandleModuleActivitiesNoBidderRequestPayload(t *testing.T) { + + testCases := []struct { + description string + hookCode string + privacyConfig *config.AccountPrivacy + inPayloadData hookstage.RawAuctionRequestPayload + expectedPayloadData hookstage.RawAuctionRequestPayload + }{ + { + description: "payload should change when userFPD is blocked by activity", + hookCode: "foo", + inPayloadData: hookstage.RawAuctionRequestPayload{}, + privacyConfig: getTransmitUFPDActivityConfig("foo", false), + expectedPayloadData: hookstage.RawAuctionRequestPayload{}, + }, + { + description: "payload should not change when userFPD is not blocked by activity", + hookCode: "foo", + inPayloadData: hookstage.RawAuctionRequestPayload{}, + privacyConfig: getTransmitUFPDActivityConfig("foo", true), + expectedPayloadData: hookstage.RawAuctionRequestPayload{}, + }, + } + for _, test := range testCases { + t.Run(test.description, func(t *testing.T) { + //check input payload didn't change + origInPayloadData := test.inPayloadData + activityControl := privacy.NewActivityControl(test.privacyConfig) + newPayload := handleModuleActivities(test.hookCode, activityControl, test.inPayloadData) + assert.Equal(t, test.expectedPayloadData, newPayload) + assert.Equal(t, origInPayloadData, test.inPayloadData) + }) + } +} diff --git a/hooks/hookexecution/executor.go b/hooks/hookexecution/executor.go index f820b79fdb2..518a0c628a6 100644 --- a/hooks/hookexecution/executor.go +++ b/hooks/hookexecution/executor.go @@ -13,6 +13,7 @@ import ( "github.com/prebid/prebid-server/v2/hooks/hookstage" "github.com/prebid/prebid-server/v2/metrics" "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/privacy" ) const ( @@ -43,17 +44,19 @@ type StageExecutor interface { type HookStageExecutor interface { StageExecutor SetAccount(account *config.Account) + SetActivityControl(activityControl privacy.ActivityControl) GetOutcomes() []StageOutcome } type hookExecutor struct { - account *config.Account - accountID string - endpoint string - planBuilder hooks.ExecutionPlanBuilder - stageOutcomes []StageOutcome - moduleContexts *moduleContexts - metricEngine metrics.MetricsEngine + account *config.Account + accountID string + endpoint string + planBuilder hooks.ExecutionPlanBuilder + stageOutcomes []StageOutcome + moduleContexts *moduleContexts + metricEngine metrics.MetricsEngine + activityControl privacy.ActivityControl // Mutex needed for BidderRequest and RawBidderResponse Stages as they are run in several goroutines sync.Mutex } @@ -77,6 +80,10 @@ func (e *hookExecutor) SetAccount(account *config.Account) { e.accountID = account.ID } +func (e *hookExecutor) SetActivityControl(activityControl privacy.ActivityControl) { + e.activityControl = activityControl +} + func (e *hookExecutor) GetOutcomes() []StageOutcome { return e.stageOutcomes } @@ -290,11 +297,12 @@ func (e *hookExecutor) ExecuteAuctionResponseStage(response *openrtb2.BidRespons func (e *hookExecutor) newContext(stage string) executionContext { return executionContext{ - account: e.account, - accountId: e.accountID, - endpoint: e.endpoint, - moduleContexts: e.moduleContexts, - stage: stage, + account: e.account, + accountID: e.accountID, + endpoint: e.endpoint, + moduleContexts: e.moduleContexts, + stage: stage, + activityControl: e.activityControl, } } @@ -316,6 +324,8 @@ type EmptyHookExecutor struct{} func (executor EmptyHookExecutor) SetAccount(_ *config.Account) {} +func (executor EmptyHookExecutor) SetActivityControl(_ privacy.ActivityControl) {} + func (executor EmptyHookExecutor) GetOutcomes() []StageOutcome { return []StageOutcome{} } diff --git a/hooks/hookexecution/executor_test.go b/hooks/hookexecution/executor_test.go index 90fa09e394f..1fb299204ec 100644 --- a/hooks/hookexecution/executor_test.go +++ b/hooks/hookexecution/executor_test.go @@ -18,6 +18,8 @@ import ( "github.com/prebid/prebid-server/v2/metrics" metricsConfig "github.com/prebid/prebid-server/v2/metrics/config" "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) @@ -674,8 +676,11 @@ func TestExecuteRawAuctionStage(t *testing.T) { for _, test := range testCases { t.Run(test.description, func(t *testing.T) { exec := NewHookExecutor(test.givenPlanBuilder, EndpointAuction, &metricsConfig.NilMetricsEngine{}) - exec.SetAccount(test.givenAccount) + privacyConfig := getTransmitUFPDActivityConfig("foo", false) + ac := privacy.NewActivityControl(privacyConfig) + exec.SetActivityControl(ac) + exec.SetAccount(test.givenAccount) newBody, reject := exec.ExecuteRawAuctionStage([]byte(test.givenBody)) assert.Equal(t, test.expectedReject, reject, "Unexpected stage reject.") @@ -896,6 +901,10 @@ func TestExecuteProcessedAuctionStage(t *testing.T) { for _, test := range testCases { t.Run(test.description, func(ti *testing.T) { exec := NewHookExecutor(test.givenPlanBuilder, EndpointAuction, &metricsConfig.NilMetricsEngine{}) + + privacyConfig := getTransmitUFPDActivityConfig("foo", false) + ac := privacy.NewActivityControl(privacyConfig) + exec.SetActivityControl(ac) exec.SetAccount(test.givenAccount) err := exec.ExecuteProcessedAuctionStage(&test.givenRequest) @@ -938,6 +947,7 @@ func TestExecuteBidderRequestStage(t *testing.T) { expectedReject *RejectError expectedModuleContexts *moduleContexts expectedStageOutcomes []StageOutcome + privacyConfig *config.AccountPrivacy }{ { description: "Payload not changed if hook execution plan empty", @@ -1169,6 +1179,9 @@ func TestExecuteBidderRequestStage(t *testing.T) { for _, test := range testCases { t.Run(test.description, func(t *testing.T) { exec := NewHookExecutor(test.givenPlanBuilder, EndpointAuction, &metricsConfig.NilMetricsEngine{}) + privacyConfig := getTransmitUFPDActivityConfig("foo", false) + ac := privacy.NewActivityControl(privacyConfig) + exec.SetActivityControl(ac) exec.SetAccount(test.givenAccount) reject := exec.ExecuteBidderRequestStage(&openrtb_ext.RequestWrapper{BidRequest: test.givenBidderRequest}, bidderName) @@ -1187,6 +1200,29 @@ func TestExecuteBidderRequestStage(t *testing.T) { } } +func getTransmitUFPDActivityConfig(componentName string, allow bool) *config.AccountPrivacy { + return &config.AccountPrivacy{ + AllowActivities: &config.AllowActivities{ + TransmitUserFPD: buildDefaultActivityConfig(componentName, allow), + }, + } +} + +func buildDefaultActivityConfig(componentName string, allow bool) config.Activity { + return config.Activity{ + Default: ptrutil.ToPtr(true), + Rules: []config.ActivityRule{ + { + Allow: allow, + Condition: config.ActivityCondition{ + ComponentName: []string{componentName}, + ComponentType: []string{"general"}, + }, + }, + }, + } +} + func TestExecuteRawBidderResponseStage(t *testing.T) { foobarModuleCtx := &moduleContexts{ctxs: map[string]hookstage.ModuleContext{"foobar": nil}} account := &config.Account{} @@ -1390,6 +1426,10 @@ func TestExecuteRawBidderResponseStage(t *testing.T) { for _, test := range testCases { t.Run(test.description, func(ti *testing.T) { exec := NewHookExecutor(test.givenPlanBuilder, EndpointAuction, &metricsConfig.NilMetricsEngine{}) + + privacyConfig := getTransmitUFPDActivityConfig("foo", false) + ac := privacy.NewActivityControl(privacyConfig) + exec.SetActivityControl(ac) exec.SetAccount(test.givenAccount) reject := exec.ExecuteRawBidderResponseStage(&test.givenBidderResponse, "the-bidder") @@ -1669,6 +1709,10 @@ func TestExecuteAllProcessedBidResponsesStage(t *testing.T) { for _, test := range testCases { t.Run(test.description, func(t *testing.T) { exec := NewHookExecutor(test.givenPlanBuilder, EndpointAuction, &metricsConfig.NilMetricsEngine{}) + + privacyConfig := getTransmitUFPDActivityConfig("foo", false) + ac := privacy.NewActivityControl(privacyConfig) + exec.SetActivityControl(ac) exec.SetAccount(test.givenAccount) exec.ExecuteAllProcessedBidResponsesStage(test.givenBiddersResponse) @@ -1918,6 +1962,10 @@ func TestExecuteAuctionResponseStage(t *testing.T) { for _, test := range testCases { t.Run(test.description, func(t *testing.T) { exec := NewHookExecutor(test.givenPlanBuilder, EndpointAuction, &metricsConfig.NilMetricsEngine{}) + + privacyConfig := getTransmitUFPDActivityConfig("foo", false) + ac := privacy.NewActivityControl(privacyConfig) + exec.SetActivityControl(ac) exec.SetAccount(test.givenAccount) exec.ExecuteAuctionResponseStage(test.givenResponse) diff --git a/hooks/hookstage/bidderrequest.go b/hooks/hookstage/bidderrequest.go index af480c5410c..05f3574c8bf 100644 --- a/hooks/hookstage/bidderrequest.go +++ b/hooks/hookstage/bidderrequest.go @@ -27,3 +27,17 @@ type BidderRequestPayload struct { Request *openrtb_ext.RequestWrapper Bidder string } + +func (brp *BidderRequestPayload) GetBidderRequestPayload() *openrtb_ext.RequestWrapper { + return brp.Request +} + +func (brp *BidderRequestPayload) SetBidderRequestPayload(br *openrtb_ext.RequestWrapper) { + brp.Request = br +} + +// RequestUpdater allows reading and writing a bid request +type RequestUpdater interface { + GetBidderRequestPayload() *openrtb_ext.RequestWrapper + SetBidderRequestPayload(br *openrtb_ext.RequestWrapper) +} diff --git a/hooks/hookstage/processedauctionrequest.go b/hooks/hookstage/processedauctionrequest.go index f420561310c..02638dccc20 100644 --- a/hooks/hookstage/processedauctionrequest.go +++ b/hooks/hookstage/processedauctionrequest.go @@ -2,7 +2,6 @@ package hookstage import ( "context" - "github.com/prebid/prebid-server/v2/openrtb_ext" ) @@ -28,3 +27,11 @@ type ProcessedAuctionRequest interface { type ProcessedAuctionRequestPayload struct { Request *openrtb_ext.RequestWrapper } + +func (parp *ProcessedAuctionRequestPayload) GetBidderRequestPayload() *openrtb_ext.RequestWrapper { + return parp.Request +} + +func (parp *ProcessedAuctionRequestPayload) SetBidderRequestPayload(br *openrtb_ext.RequestWrapper) { + parp.Request = br +} diff --git a/ortb/clone.go b/ortb/clone.go index c831aae21b5..2fe9be68f74 100644 --- a/ortb/clone.go +++ b/ortb/clone.go @@ -2,6 +2,7 @@ package ortb import ( "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/v2/openrtb_ext" "github.com/prebid/prebid-server/v2/util/ptrutil" "github.com/prebid/prebid-server/v2/util/sliceutil" ) @@ -399,3 +400,33 @@ func CloneDOOH(s *openrtb2.DOOH) *openrtb2.DOOH { return &c } + +// cloneBidderReq - clones bidder request and replaces req.User and req.Device and req.Source with new copies +func CloneBidderReq(req *openrtb2.BidRequest) *openrtb_ext.RequestWrapper { + if req == nil { + return nil + } + + // bidder request may be modified differently per bidder based on privacy configs + // new request should be created for each bidder request + // pointer fields like User and Device should be cloned and set back to the request copy + newReq := ptrutil.Clone(req) + + if req.User != nil { + userCopy := CloneUser(req.User) + newReq.User = userCopy + } + + if req.Device != nil { + deviceCopy := CloneDevice(req.Device) + newReq.Device = deviceCopy + } + + if req.Source != nil { + sourceCopy := CloneSource(req.Source) + newReq.Source = sourceCopy + } + + reqWrapper := &openrtb_ext.RequestWrapper{BidRequest: newReq} + return reqWrapper +} diff --git a/ortb/clone_test.go b/ortb/clone_test.go index 820c24397f4..1afc269240b 100644 --- a/ortb/clone_test.go +++ b/ortb/clone_test.go @@ -1127,6 +1127,58 @@ func TestCloneDOOH(t *testing.T) { }) } +func TestCloneBidderReq(t *testing.T) { + t.Run("nil", func(t *testing.T) { + result := CloneBidderReq(nil) + assert.Nil(t, result) + }) + + t.Run("empty", func(t *testing.T) { + given := &openrtb2.BidRequest{} + result := CloneBidderReq(given) + assert.Equal(t, given, result.BidRequest) + assert.NotSame(t, given, result) + }) + + t.Run("populated", func(t *testing.T) { + given := &openrtb2.BidRequest{ + ID: "anyID", + User: &openrtb2.User{ID: "testUserId"}, + Device: &openrtb2.Device{Carrier: "testCarrier"}, + Source: &openrtb2.Source{TID: "testTID"}, + } + result := CloneBidderReq(given) + assert.Equal(t, given, result.BidRequest) + assert.NotSame(t, given, result.BidRequest, "pointer") + assert.NotSame(t, given.User, result.User, "user") + assert.NotSame(t, given.Device, result.Device, "device") + assert.NotSame(t, given.Source, result.Source, "source") + }) + + t.Run("assumptions", func(t *testing.T) { + assert.ElementsMatch(t, discoverPointerFields(reflect.TypeOf(openrtb2.BidRequest{})), + []string{ + "Device", + "User", + "Source", + "Imp", + "Site", + "App", + "DOOH", + "WSeat", + "BSeat", + "Cur", + "WLang", + "WLangB", + "BCat", + "BAdv", + "BApp", + "Regs", + "Ext", + }) + }) +} + // discoverPointerFields returns the names of all fields of an object that are // pointers and would need to be cloned. This method is specific to types which can // appear within an OpenRTB data model object. From 869a3e599253ef181f8eca99c6cc7eef51b91436 Mon Sep 17 00:00:00 2001 From: Anton Babak <76536883+AntoxaAntoxic@users.noreply.github.com> Date: Mon, 18 Dec 2023 07:54:48 +0100 Subject: [PATCH 253/268] Add Magnite Alias for Rubicon Bidder (#3354) --- static/bidder-info/magnite.yaml | 1 + 1 file changed, 1 insertion(+) create mode 100644 static/bidder-info/magnite.yaml diff --git a/static/bidder-info/magnite.yaml b/static/bidder-info/magnite.yaml new file mode 100644 index 00000000000..109c20d03bf --- /dev/null +++ b/static/bidder-info/magnite.yaml @@ -0,0 +1 @@ +aliasOf: "rubicon" \ No newline at end of file From 91a495f961ebc5066ae175539a4f99a8ead9a309 Mon Sep 17 00:00:00 2001 From: bretg Date: Mon, 18 Dec 2023 01:55:18 -0500 Subject: [PATCH 254/268] Rubicon adapter: enable endpoint compression (#3346) --- static/bidder-info/rubicon.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/static/bidder-info/rubicon.yaml b/static/bidder-info/rubicon.yaml index b3de838c9fd..be2acdc8355 100644 --- a/static/bidder-info/rubicon.yaml +++ b/static/bidder-info/rubicon.yaml @@ -1,4 +1,5 @@ endpoint: "http://exapi-us-east.rubiconproject.com/a/api/exchange.json" +endpointCompression: GZIP disabled: true maintainer: email: "header-bidding@rubiconproject.com" From b0daa14b98bbb6bb602c4343ad1fa6f01ec581d8 Mon Sep 17 00:00:00 2001 From: JuanM <96113351+juanmartinengo@users.noreply.github.com> Date: Mon, 18 Dec 2023 07:56:00 +0100 Subject: [PATCH 255/268] Stroeercore: Support video (#3314) Co-authored-by: juanm Co-authored-by: docech --- adapters/stroeerCore/stroeercore.go | 23 ++- .../exemplary/mobile-banner-single.json | 6 +- .../exemplary/site-banner-multi.json | 12 +- .../exemplary/site-banner-single.json | 6 +- .../exemplary/site-multi-format-single.json | 146 +++++++++++++ .../exemplary/site-multi-types.json | 186 +++++++++++++++++ .../exemplary/site-video-single.json | 116 +++++++++++ .../supplemental/unknown-bid-media-type.json | 193 ++++++++++++++++++ static/bidder-info/stroeerCore.yaml | 2 + 9 files changed, 681 insertions(+), 9 deletions(-) create mode 100644 adapters/stroeerCore/stroeercoretest/exemplary/site-multi-format-single.json create mode 100644 adapters/stroeerCore/stroeercoretest/exemplary/site-multi-types.json create mode 100644 adapters/stroeerCore/stroeercoretest/exemplary/site-video-single.json create mode 100644 adapters/stroeerCore/stroeercoretest/supplemental/unknown-bid-media-type.json diff --git a/adapters/stroeerCore/stroeercore.go b/adapters/stroeerCore/stroeercore.go index 5f0194061a8..590e641ff1f 100644 --- a/adapters/stroeerCore/stroeercore.go +++ b/adapters/stroeerCore/stroeercore.go @@ -30,6 +30,18 @@ type bidResponse struct { Height int64 `json:"height"` Ad string `json:"ad"` CrID string `json:"crid"` + Mtype string `json:"mtype"` +} + +func (b bidResponse) resolveMediaType() (mt openrtb2.MarkupType, bt openrtb_ext.BidType, err error) { + switch b.Mtype { + case "banner": + return openrtb2.MarkupBanner, openrtb_ext.BidTypeBanner, nil + case "video": + return openrtb2.MarkupVideo, openrtb_ext.BidTypeVideo, nil + default: + return mt, bt, fmt.Errorf("unable to determine media type for bid with id \"%s\"", b.BidID) + } } func (a *adapter) MakeBids(bidRequest *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { @@ -51,6 +63,14 @@ func (a *adapter) MakeBids(bidRequest *openrtb2.BidRequest, requestData *adapter bidderResponse.Currency = "EUR" for _, bid := range stroeerResponse.Bids { + markupType, bidType, err := bid.resolveMediaType() + if err != nil { + errors = append(errors, &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Bid media type error: %s", err.Error()), + }) + continue + } + openRtbBid := openrtb2.Bid{ ID: bid.ID, ImpID: bid.BidID, @@ -59,11 +79,12 @@ func (a *adapter) MakeBids(bidRequest *openrtb2.BidRequest, requestData *adapter Price: bid.CPM, AdM: bid.Ad, CrID: bid.CrID, + MType: markupType, } bidderResponse.Bids = append(bidderResponse.Bids, &adapters.TypedBid{ Bid: &openRtbBid, - BidType: openrtb_ext.BidTypeBanner, + BidType: bidType, }) } diff --git a/adapters/stroeerCore/stroeercoretest/exemplary/mobile-banner-single.json b/adapters/stroeerCore/stroeercoretest/exemplary/mobile-banner-single.json index 0abdbc8b499..b91cc72fbde 100644 --- a/adapters/stroeerCore/stroeercoretest/exemplary/mobile-banner-single.json +++ b/adapters/stroeerCore/stroeercoretest/exemplary/mobile-banner-single.json @@ -161,7 +161,8 @@ "width": 468, "height": 60, "ad": "advert", - "crid": "XYZijk" + "crid": "XYZijk", + "mtype": "banner" } ] } @@ -179,7 +180,8 @@ "adm": "advert", "w": 468, "h": 60, - "crid": "XYZijk" + "crid": "XYZijk", + "mtype": 1 }, "type": "banner" }] diff --git a/adapters/stroeerCore/stroeercoretest/exemplary/site-banner-multi.json b/adapters/stroeerCore/stroeercoretest/exemplary/site-banner-multi.json index 091f244c6ef..03d6f10214e 100644 --- a/adapters/stroeerCore/stroeercoretest/exemplary/site-banner-multi.json +++ b/adapters/stroeerCore/stroeercoretest/exemplary/site-banner-multi.json @@ -138,7 +138,8 @@ "width": 468, "height": 60, "ad": "advert", - "crid": "qwert" + "crid": "qwert", + "mtype": "banner" }, { "id": "3929239282-02", @@ -147,7 +148,8 @@ "width": 770, "height": 250, "ad": "another advert", - "crid": "wasd" + "crid": "wasd", + "mtype": "banner" } ] } @@ -166,7 +168,8 @@ "adm": "advert", "w": 468, "h": 60, - "crid": "qwert" + "crid": "qwert", + "mtype": 1 }, "type": "banner" }, @@ -178,7 +181,8 @@ "adm": "another advert", "w": 770, "h": 250, - "crid": "wasd" + "crid": "wasd", + "mtype": 1 }, "type": "banner" } diff --git a/adapters/stroeerCore/stroeercoretest/exemplary/site-banner-single.json b/adapters/stroeerCore/stroeercoretest/exemplary/site-banner-single.json index ca6ea0c26ea..7dd860a72ba 100644 --- a/adapters/stroeerCore/stroeercoretest/exemplary/site-banner-single.json +++ b/adapters/stroeerCore/stroeercoretest/exemplary/site-banner-single.json @@ -105,7 +105,8 @@ "width": 468, "height": 60, "ad": "advert", - "crid": "wasd" + "crid": "wasd", + "mtype": "banner" } ] } @@ -123,7 +124,8 @@ "adm": "advert", "w": 468, "h": 60, - "crid": "wasd" + "crid": "wasd", + "mtype": 1 }, "type": "banner" }] diff --git a/adapters/stroeerCore/stroeercoretest/exemplary/site-multi-format-single.json b/adapters/stroeerCore/stroeercoretest/exemplary/site-multi-format-single.json new file mode 100644 index 00000000000..57a6e39bc6e --- /dev/null +++ b/adapters/stroeerCore/stroeercoretest/exemplary/site-multi-format-single.json @@ -0,0 +1,146 @@ +{ + "mockBidRequest": { + "id": "auction-id", + "cur": ["EUR"], + "imp": [ + { + "id": "3", + "banner": { + "format": [ + { + "w": 468, + "h": 60 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "video": { + "mimes": ["video/mp4"], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "sid": "123456" + } + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path", + "ext": { + "amp": 1 + } + }, + "user": { + "buyeruid": "test-buyer-user-id" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"] + }, + "uri": "http://localhost/s2sdsh", + "body": { + "id": "auction-id", + "cur": ["EUR"], + "imp": [ + { + "id": "3", + "tagid": "123456", + "banner": { + "format": [ + { + "w": 468, + "h": 60 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "video": { + "mimes": ["video/mp4"], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "sid": "123456" + } + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path", + "ext": { + "amp": 1 + } + }, + "user": { + "buyeruid": "test-buyer-user-id" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "bids": [ + { + "id": "3929239282-01", + "bidId": "3", + "cpm": 2, + "width": 468, + "height": 60, + "ad": "banner ad", + "crid": "qwert", + "mtype": "banner" + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "3929239282-01", + "impid": "3", + "price": 2, + "adm": "banner ad", + "w": 468, + "h": 60, + "crid": "qwert", + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/stroeerCore/stroeercoretest/exemplary/site-multi-types.json b/adapters/stroeerCore/stroeercoretest/exemplary/site-multi-types.json new file mode 100644 index 00000000000..27cd32ba1d0 --- /dev/null +++ b/adapters/stroeerCore/stroeercoretest/exemplary/site-multi-types.json @@ -0,0 +1,186 @@ +{ + "mockBidRequest": { + "id": "auction-id", + "cur": ["EUR"], + "imp": [ + { + "id": "3", + "banner": { + "format": [ + { + "w": 468, + "h": 60 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "sid": "123456" + } + } + }, + { + "id": "9", + "video": { + "mimes": ["video/mp4"], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "sid": "85310" + } + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path", + "ext": { + "amp": 1 + } + }, + "user": { + "buyeruid": "test-buyer-user-id" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"] + }, + "uri": "http://localhost/s2sdsh", + "body": { + "id": "auction-id", + "cur": ["EUR"], + "imp": [ + { + "id": "3", + "tagid": "123456", + "banner": { + "format": [ + { + "w": 468, + "h": 60 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "sid": "123456" + } + } + }, + { + "id": "9", + "tagid": "85310", + "video": { + "mimes": ["video/mp4"], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "sid": "85310" + } + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path", + "ext": { + "amp": 1 + } + }, + "user": { + "buyeruid": "test-buyer-user-id" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "bids": [ + { + "id": "3929239282-01", + "bidId": "3", + "cpm": 2, + "width": 468, + "height": 60, + "ad": "banner ad", + "crid": "qwert", + "mtype": "banner" + }, + { + "id": "3929239282-02", + "bidId": "9", + "cpm": 7.21, + "width": 770, + "height": 250, + "ad": "video ad", + "crid": "wasd", + "mtype": "video" + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "3929239282-01", + "impid": "3", + "price": 2, + "adm": "banner ad", + "w": 468, + "h": 60, + "crid": "qwert", + "mtype": 1 + }, + "type": "banner" + }, + { + "bid": { + "id": "3929239282-02", + "impid": "9", + "price": 7.21, + "adm": "video ad", + "w": 770, + "h": 250, + "crid": "wasd", + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/stroeerCore/stroeercoretest/exemplary/site-video-single.json b/adapters/stroeerCore/stroeercoretest/exemplary/site-video-single.json new file mode 100644 index 00000000000..65b2da804ea --- /dev/null +++ b/adapters/stroeerCore/stroeercoretest/exemplary/site-video-single.json @@ -0,0 +1,116 @@ +{ + "mockBidRequest": { + "id": "auction-id", + "cur": ["EUR"], + "imp": [ + { + "id": "3", + "video": { + "mimes": ["video/mp4"], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "sid": "123456" + } + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path", + "ext": { + "amp": 0 + } + }, + "user": { + "buyeruid": "test-buyer-user-id" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"] + }, + "uri": "http://localhost/s2sdsh", + "body": { + "id": "auction-id", + "cur": ["EUR"], + "imp": [ + { + "id": "3", + "tagid": "123456", + "video": { + "mimes": ["video/mp4"], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "sid": "123456" + } + } + } + ], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "site": { + "domain": "www.publisher.com", + "page": "http://www.publisher.com/some/path", + "ext": { + "amp": 0 + } + }, + "user": { + "buyeruid": "test-buyer-user-id" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "bids": [ + { + "id": "8923356982838-09", + "bidId": "3", + "cpm": 2, + "ad": "
video
", + "crid": "wasd", + "mtype": "video" + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids" : [{ + "bid": { + "id": "8923356982838-09", + "impid": "3", + "price": 2, + "adm": "
video
", + "crid": "wasd", + "mtype": 2 + }, + "type": "video" + }] + } + ] +} diff --git a/adapters/stroeerCore/stroeercoretest/supplemental/unknown-bid-media-type.json b/adapters/stroeerCore/stroeercoretest/supplemental/unknown-bid-media-type.json new file mode 100644 index 00000000000..0cb74cd47a6 --- /dev/null +++ b/adapters/stroeerCore/stroeercoretest/supplemental/unknown-bid-media-type.json @@ -0,0 +1,193 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "banner-1", + "banner": { + "format": [ + { + "w": 300, + "h": 200 + } + ] + }, + "ext": { + "bidder": { + "sid": "tagid" + } + } + }, + { + "id": "banner-2", + "banner": { + "format": [ + { + "w": 300, + "h": 200 + } + ] + }, + "ext": { + "bidder": { + "sid": "tagid" + } + } + }, + { + "id": "banner-3", + "banner": { + "format": [ + { + "w": 300, + "h": 200 + } + ] + }, + "ext": { + "bidder": { + "sid": "tagid" + } + } + } + ], + "user": { + "buyeruid": "test-buyer-user-id" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": ["application/json"], + "Content-Type": ["application/json;charset=utf-8"] + }, + "uri": "http://localhost/s2sdsh", + "body": { + "id": "id", + "imp": [ + { + "id": "banner-1", + "tagid": "tagid", + "banner": { + "format": [ + { + "w": 300, + "h": 200 + } + ] + }, + "ext": { + "bidder": { + "sid": "tagid" + } + } + }, + { + "id": "banner-2", + "tagid": "tagid", + "banner": { + "format": [ + { + "w": 300, + "h": 200 + } + ] + }, + "ext": { + "bidder": { + "sid": "tagid" + } + } + }, + { + "id": "banner-3", + "tagid": "tagid", + "banner": { + "format": [ + { + "w": 300, + "h": 200 + } + ] + }, + "ext": { + "bidder": { + "sid": "tagid" + } + } + } + ], + "user": { + "buyeruid": "test-buyer-user-id" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "bids": [ + { + "id": "3929239282-01", + "bidId": "banner-1", + "cpm": 2, + "width": 300, + "height": 200, + "ad": "banner ad 1", + "crid": "qwert", + "mtype": "unknown" + }, + { + "id": "3929239282-02", + "bidId": "banner-2", + "cpm": 2, + "width": 300, + "height": 200, + "ad": "banner ad 2", + "crid": "qwert" + }, + { + "id": "3929239282-03", + "bidId": "banner-3", + "cpm": 2, + "width": 300, + "height": 200, + "ad": "banner ad 3", + "crid": "qwert", + "mtype": "banner" + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids" : [{ + "bid": { + "id": "3929239282-03", + "impid": "banner-3", + "price": 2, + "adm": "banner ad 3", + "w": 300, + "h": 200, + "crid": "qwert", + "mtype": 1 + }, + "type": "banner" + }] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bid media type error: unable to determine media type for bid with id \"banner-1\"", + "comparison": "literal" + }, + { + "value": "Bid media type error: unable to determine media type for bid with id \"banner-2\"", + "comparison": "literal" + } + ] +} diff --git a/static/bidder-info/stroeerCore.yaml b/static/bidder-info/stroeerCore.yaml index 32c78590bb8..9c0904508ac 100644 --- a/static/bidder-info/stroeerCore.yaml +++ b/static/bidder-info/stroeerCore.yaml @@ -7,9 +7,11 @@ capabilities: app: mediaTypes: - banner + - video site: mediaTypes: - banner + - video userSync: # for both user syncs, stroeerCore appends the user id to end of the redirect url and does not utilize a macro iframe: From 37f0f46de34c9b52b1a8e61cd8ecb0569bb09d2f Mon Sep 17 00:00:00 2001 From: kmdevops <126434358+kmdevops@users.noreply.github.com> Date: Tue, 19 Dec 2023 19:25:28 +0100 Subject: [PATCH 256/268] DXKulture: Change domain (#3345) --- adapters/dxkulture/dxkulture_test.go | 2 +- adapters/dxkulture/dxkulturetest/exemplary/banner.json | 2 +- .../dxkulturetest/exemplary/empty-site-domain-ref.json | 2 +- adapters/dxkulture/dxkulturetest/exemplary/ipv6.json | 2 +- .../dxkulturetest/exemplary/video-test-request.json | 2 +- adapters/dxkulture/dxkulturetest/exemplary/video.json | 2 +- .../dxkulturetest/supplemental/invalid-response.json | 2 +- adapters/dxkulture/dxkulturetest/supplemental/no-mtype.json | 2 +- .../dxkulturetest/supplemental/status-code-bad-request.json | 2 +- .../dxkulturetest/supplemental/status-code-no-content.json | 2 +- .../dxkulturetest/supplemental/status-code-other-error.json | 2 +- static/bidder-info/dxkulture.yaml | 6 +++--- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/adapters/dxkulture/dxkulture_test.go b/adapters/dxkulture/dxkulture_test.go index fb14c2b3c6a..7344d5a9d51 100644 --- a/adapters/dxkulture/dxkulture_test.go +++ b/adapters/dxkulture/dxkulture_test.go @@ -9,7 +9,7 @@ import ( ) func TestJsonSamples(t *testing.T) { - bidder, buildErr := Builder("dxkulture", config.Adapter{Endpoint: "https://ads.kulture.media/pbs"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + bidder, buildErr := Builder("dxkulture", config.Adapter{Endpoint: "https://ads.dxkulture.com/pbs"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) if buildErr != nil { t.Fatalf("Builder returned unexpected error %v", buildErr) } diff --git a/adapters/dxkulture/dxkulturetest/exemplary/banner.json b/adapters/dxkulture/dxkulturetest/exemplary/banner.json index 3b84881fc67..86b0e928c67 100644 --- a/adapters/dxkulture/dxkulturetest/exemplary/banner.json +++ b/adapters/dxkulture/dxkulturetest/exemplary/banner.json @@ -57,7 +57,7 @@ "2.5" ] }, - "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=pub123", + "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=pub123", "body": { "id": "test-request-id", "user": { diff --git a/adapters/dxkulture/dxkulturetest/exemplary/empty-site-domain-ref.json b/adapters/dxkulture/dxkulturetest/exemplary/empty-site-domain-ref.json index 630467ce96b..7460153f5ab 100644 --- a/adapters/dxkulture/dxkulturetest/exemplary/empty-site-domain-ref.json +++ b/adapters/dxkulture/dxkulturetest/exemplary/empty-site-domain-ref.json @@ -53,7 +53,7 @@ "2.5" ] }, - "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=pub123", + "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=pub123", "body": { "id": "test-request-id", "user": { diff --git a/adapters/dxkulture/dxkulturetest/exemplary/ipv6.json b/adapters/dxkulture/dxkulturetest/exemplary/ipv6.json index 58f7e7fdf2c..20841500d58 100644 --- a/adapters/dxkulture/dxkulturetest/exemplary/ipv6.json +++ b/adapters/dxkulture/dxkulturetest/exemplary/ipv6.json @@ -53,7 +53,7 @@ "2.5" ] }, - "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=pub123", + "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=pub123", "body": { "id": "test-request-id", "user": { diff --git a/adapters/dxkulture/dxkulturetest/exemplary/video-test-request.json b/adapters/dxkulture/dxkulturetest/exemplary/video-test-request.json index 6a0746ad258..f1d0a840ba0 100644 --- a/adapters/dxkulture/dxkulturetest/exemplary/video-test-request.json +++ b/adapters/dxkulture/dxkulturetest/exemplary/video-test-request.json @@ -62,7 +62,7 @@ "2.5" ] }, - "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=test", + "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=test", "body": { "id": "test-request-id", "test": 1, diff --git a/adapters/dxkulture/dxkulturetest/exemplary/video.json b/adapters/dxkulture/dxkulturetest/exemplary/video.json index 017dd5ea2bc..37f4b9e8236 100644 --- a/adapters/dxkulture/dxkulturetest/exemplary/video.json +++ b/adapters/dxkulture/dxkulturetest/exemplary/video.json @@ -61,7 +61,7 @@ "2.5" ] }, - "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=pub123", + "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=pub123", "body": { "id": "test-request-id", "user": { diff --git a/adapters/dxkulture/dxkulturetest/supplemental/invalid-response.json b/adapters/dxkulture/dxkulturetest/supplemental/invalid-response.json index 8fff1bb0375..4ef0539c69b 100644 --- a/adapters/dxkulture/dxkulturetest/supplemental/invalid-response.json +++ b/adapters/dxkulture/dxkulturetest/supplemental/invalid-response.json @@ -61,7 +61,7 @@ "2.5" ] }, - "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=pub123", + "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=pub123", "body": { "id": "test-request-id", "user": { diff --git a/adapters/dxkulture/dxkulturetest/supplemental/no-mtype.json b/adapters/dxkulture/dxkulturetest/supplemental/no-mtype.json index a56200fad50..a65a46ef0ee 100644 --- a/adapters/dxkulture/dxkulturetest/supplemental/no-mtype.json +++ b/adapters/dxkulture/dxkulturetest/supplemental/no-mtype.json @@ -61,7 +61,7 @@ "2.5" ] }, - "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=pub123", + "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=pub123", "body": { "id": "test-request-id", "user": { diff --git a/adapters/dxkulture/dxkulturetest/supplemental/status-code-bad-request.json b/adapters/dxkulture/dxkulturetest/supplemental/status-code-bad-request.json index f0f2ce2c47b..0338be9f811 100644 --- a/adapters/dxkulture/dxkulturetest/supplemental/status-code-bad-request.json +++ b/adapters/dxkulture/dxkulturetest/supplemental/status-code-bad-request.json @@ -61,7 +61,7 @@ "2.5" ] }, - "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=pub123", + "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=pub123", "body": { "id": "test-request-id", "user": { diff --git a/adapters/dxkulture/dxkulturetest/supplemental/status-code-no-content.json b/adapters/dxkulture/dxkulturetest/supplemental/status-code-no-content.json index 43c53f3d64c..4363b998cf7 100644 --- a/adapters/dxkulture/dxkulturetest/supplemental/status-code-no-content.json +++ b/adapters/dxkulture/dxkulturetest/supplemental/status-code-no-content.json @@ -61,7 +61,7 @@ "2.5" ] }, - "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=pub123", + "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=pub123", "body": { "id": "test-request-id", "user": { diff --git a/adapters/dxkulture/dxkulturetest/supplemental/status-code-other-error.json b/adapters/dxkulture/dxkulturetest/supplemental/status-code-other-error.json index 3e1b0b33c1e..608521b42a0 100644 --- a/adapters/dxkulture/dxkulturetest/supplemental/status-code-other-error.json +++ b/adapters/dxkulture/dxkulturetest/supplemental/status-code-other-error.json @@ -61,7 +61,7 @@ "2.5" ] }, - "uri": "https://ads.kulture.media/pbs?placement_id=placement123&publisher_id=pub123", + "uri": "https://ads.dxkulture.com/pbs?placement_id=placement123&publisher_id=pub123", "body": { "id": "test-request-id", "user": { diff --git a/static/bidder-info/dxkulture.yaml b/static/bidder-info/dxkulture.yaml index 1af72e9fc33..d6f03044fda 100644 --- a/static/bidder-info/dxkulture.yaml +++ b/static/bidder-info/dxkulture.yaml @@ -1,6 +1,6 @@ -endpoint: "https://ads.kulture.media/pbs" +endpoint: "https://ads.dxkulture.com/pbs" maintainer: - email: "devops@kulture.media" + email: "devops@dxkulture.com" capabilities: app: mediaTypes: @@ -12,5 +12,5 @@ capabilities: - video userSync: redirect: - url: "https://ads.kulture.media/usync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&cb={{.RedirectURL}}" + url: "https://ads.dxkulture.com/usync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&cb={{.RedirectURL}}" userMacro: "$UID" From 0c444d0408cddc6e6a11156f9e60ca9cfdb5ad23 Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 20 Dec 2023 07:40:48 -0500 Subject: [PATCH 257/268] Rise allows vast modification (#3369) --- static/bidder-info/rise.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/bidder-info/rise.yaml b/static/bidder-info/rise.yaml index d429e8780a7..72e56c334c8 100644 --- a/static/bidder-info/rise.yaml +++ b/static/bidder-info/rise.yaml @@ -2,7 +2,7 @@ endpoint: "https://pbs.yellowblue.io/pbs" maintainer: email: rise-prog-dev@risecodes.com gvlVendorID: 1043 -modifyingVastXmlAllowed: false +modifyingVastXmlAllowed: true capabilities: app: mediaTypes: From c773b0f1a0c282d12ba46a0b6be2a98be107cd3e Mon Sep 17 00:00:00 2001 From: JacobKlein26 <42449375+JacobKlein26@users.noreply.github.com> Date: Thu, 21 Dec 2023 08:58:24 -0500 Subject: [PATCH 258/268] Nextmillennium: add extra_info support (#3351) --- adapters/nextmillennium/nextmillennium.go | 20 ++++++++++++++++--- .../nextmillennium/nextmillennium_test.go | 13 ++++++++++++ .../exemplary/banner-empty-group-id.json | 2 ++ .../exemplary/banner-with-group-id.json | 2 ++ .../exemplary/banner-with-group-id_app.json | 2 ++ .../exemplary/banner-with-only-width.json | 2 ++ .../exemplary/banner-with-wh.json | 2 ++ .../exemplary/banner-wo-domain.json | 2 ++ .../exemplary/banner-wo-size.json | 2 ++ .../nextmillenniumtest/exemplary/banner.json | 2 ++ .../exemplary/empty-banner-obj.json | 2 ++ .../supplemental/empty-seatbid.json | 2 ++ .../supplemental/error-response.json | 2 ++ .../supplemental/no-content.json | 2 ++ 14 files changed, 54 insertions(+), 3 deletions(-) diff --git a/adapters/nextmillennium/nextmillennium.go b/adapters/nextmillennium/nextmillennium.go index 5d10cac2d9e..966f96de47a 100644 --- a/adapters/nextmillennium/nextmillennium.go +++ b/adapters/nextmillennium/nextmillennium.go @@ -14,6 +14,7 @@ import ( type adapter struct { endpoint string + nmmFlags []string } type nmExtPrebidStoredRequest struct { @@ -22,8 +23,12 @@ type nmExtPrebidStoredRequest struct { type nmExtPrebid struct { StoredRequest nmExtPrebidStoredRequest `json:"storedrequest"` } +type nmExtNMM struct { + NmmFlags []string `json:"nmmFlags,omitempty"` +} type nextMillJsonExt struct { - Prebid nmExtPrebid `json:"prebid"` + Prebid nmExtPrebid `json:"prebid"` + NextMillennium nmExtNMM `json:"nextMillennium,omitempty"` } // MakeRequests prepares request information for prebid-server core @@ -77,7 +82,7 @@ func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ImpExtNextMillennium, err } func (adapter *adapter) buildAdapterRequest(prebidBidRequest *openrtb2.BidRequest, params *openrtb_ext.ImpExtNextMillennium) (*adapters.RequestData, error) { - newBidRequest := createBidRequest(prebidBidRequest, params) + newBidRequest := createBidRequest(prebidBidRequest, params, adapter.nmmFlags) reqJSON, err := json.Marshal(newBidRequest) if err != nil { @@ -96,7 +101,7 @@ func (adapter *adapter) buildAdapterRequest(prebidBidRequest *openrtb2.BidReques Headers: headers}, nil } -func createBidRequest(prebidBidRequest *openrtb2.BidRequest, params *openrtb_ext.ImpExtNextMillennium) *openrtb2.BidRequest { +func createBidRequest(prebidBidRequest *openrtb2.BidRequest, params *openrtb_ext.ImpExtNextMillennium, flags []string) *openrtb2.BidRequest { placementID := params.PlacementID if params.GroupID != "" { @@ -122,6 +127,7 @@ func createBidRequest(prebidBidRequest *openrtb2.BidRequest, params *openrtb_ext } ext := nextMillJsonExt{} ext.Prebid.StoredRequest.ID = placementID + ext.NextMillennium.NmmFlags = flags jsonExt, err := json.Marshal(ext) if err != nil { return prebidBidRequest @@ -169,7 +175,15 @@ func (adapter *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalR // Builder builds a new instance of the NextMillennium adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + var info nmExtNMM + if config.ExtraAdapterInfo != "" { + if err := json.Unmarshal([]byte(config.ExtraAdapterInfo), &info); err != nil { + return nil, fmt.Errorf("invalid extra info: %v", err) + } + } + return &adapter{ endpoint: config.Endpoint, + nmmFlags: info.NmmFlags, }, nil } diff --git a/adapters/nextmillennium/nextmillennium_test.go b/adapters/nextmillennium/nextmillennium_test.go index ec813ba2412..6e51edc5e17 100644 --- a/adapters/nextmillennium/nextmillennium_test.go +++ b/adapters/nextmillennium/nextmillennium_test.go @@ -6,6 +6,7 @@ import ( "github.com/prebid/prebid-server/v2/adapters/adapterstest" "github.com/prebid/prebid-server/v2/config" "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/stretchr/testify/assert" ) func TestJsonSamples(t *testing.T) { @@ -18,3 +19,15 @@ func TestJsonSamples(t *testing.T) { adapterstest.RunJSONBidderTest(t, "nextmillenniumtest", bidder) } +func TestWithExtraInfo(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderNextMillennium, config.Adapter{ + Endpoint: "https://pbs.nextmillmedia.com/openrtb2/auction", + ExtraAdapterInfo: "{\"nmmFlags\":[\"flag1\",\"flag2\"]}", + }, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + bidderNextMillennium, _ := bidder.(*adapter) + assert.Equal(t, bidderNextMillennium.nmmFlags, []string{"flag1", "flag2"}) +} diff --git a/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-empty-group-id.json b/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-empty-group-id.json index 7a628d0fd91..19212134463 100644 --- a/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-empty-group-id.json +++ b/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-empty-group-id.json @@ -33,6 +33,7 @@ "body":{ "id": "testid", "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "7819" @@ -54,6 +55,7 @@ ] }, "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "7819" diff --git a/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-with-group-id.json b/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-with-group-id.json index 3538113014d..129c025e1da 100644 --- a/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-with-group-id.json +++ b/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-with-group-id.json @@ -44,6 +44,7 @@ "body":{ "id": "testid", "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "g7819;320x250;www.example.com" @@ -67,6 +68,7 @@ "w": 320 }, "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "g7819;320x250;www.example.com" diff --git a/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-with-group-id_app.json b/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-with-group-id_app.json index 25c1f36deff..2ddf9bee948 100644 --- a/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-with-group-id_app.json +++ b/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-with-group-id_app.json @@ -40,6 +40,7 @@ "domain": "www.example.com" }, "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "g7819;320x250;www.example.com" @@ -63,6 +64,7 @@ "w": 320 }, "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "g7819;320x250;www.example.com" diff --git a/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-with-only-width.json b/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-with-only-width.json index 79c9894f424..4db65ec46cd 100644 --- a/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-with-only-width.json +++ b/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-with-only-width.json @@ -29,6 +29,7 @@ "domain": "www.example.com" }, "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "g7819;;www.example.com" @@ -41,6 +42,7 @@ "w": 320 }, "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "g7819;;www.example.com" diff --git a/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-with-wh.json b/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-with-wh.json index 6af7816eb21..f7da0784728 100644 --- a/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-with-wh.json +++ b/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-with-wh.json @@ -30,6 +30,7 @@ "domain": "www.example.com" }, "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "g7819;320x250;www.example.com" @@ -43,6 +44,7 @@ "w": 320 }, "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "g7819;320x250;www.example.com" diff --git a/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-wo-domain.json b/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-wo-domain.json index 181dab3548b..d27dffafaf1 100644 --- a/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-wo-domain.json +++ b/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-wo-domain.json @@ -34,6 +34,7 @@ "body":{ "id": "testid", "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "g7819;320x250;" @@ -57,6 +58,7 @@ "w": 320 }, "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "g7819;320x250;" diff --git a/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-wo-size.json b/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-wo-size.json index f2422033b81..c5b9276700d 100644 --- a/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-wo-size.json +++ b/adapters/nextmillennium/nextmillenniumtest/exemplary/banner-wo-size.json @@ -32,6 +32,7 @@ "body":{ "id": "testid", "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "g7819;320x250;" @@ -53,6 +54,7 @@ ] }, "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "g7819;320x250;" diff --git a/adapters/nextmillennium/nextmillenniumtest/exemplary/banner.json b/adapters/nextmillennium/nextmillenniumtest/exemplary/banner.json index fa8834fa998..df736d79757 100644 --- a/adapters/nextmillennium/nextmillenniumtest/exemplary/banner.json +++ b/adapters/nextmillennium/nextmillenniumtest/exemplary/banner.json @@ -34,6 +34,7 @@ "body":{ "id": "testid", "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "7819" @@ -57,6 +58,7 @@ "w": 320 }, "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "7819" diff --git a/adapters/nextmillennium/nextmillenniumtest/exemplary/empty-banner-obj.json b/adapters/nextmillennium/nextmillenniumtest/exemplary/empty-banner-obj.json index cc9f9eb980b..2d357ffb99c 100644 --- a/adapters/nextmillennium/nextmillenniumtest/exemplary/empty-banner-obj.json +++ b/adapters/nextmillennium/nextmillenniumtest/exemplary/empty-banner-obj.json @@ -21,6 +21,7 @@ "body":{ "id": "testid", "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "g7819;;" @@ -31,6 +32,7 @@ { "banner": {}, "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "g7819;;" diff --git a/adapters/nextmillennium/nextmillenniumtest/supplemental/empty-seatbid.json b/adapters/nextmillennium/nextmillenniumtest/supplemental/empty-seatbid.json index dd070d62427..8f3588de144 100644 --- a/adapters/nextmillennium/nextmillenniumtest/supplemental/empty-seatbid.json +++ b/adapters/nextmillennium/nextmillenniumtest/supplemental/empty-seatbid.json @@ -33,6 +33,7 @@ "body": { "id": "testid", "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "7819" @@ -56,6 +57,7 @@ "w": 320 }, "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "7819" diff --git a/adapters/nextmillennium/nextmillenniumtest/supplemental/error-response.json b/adapters/nextmillennium/nextmillenniumtest/supplemental/error-response.json index 3e8047fae54..f7b23ac9bcf 100644 --- a/adapters/nextmillennium/nextmillenniumtest/supplemental/error-response.json +++ b/adapters/nextmillennium/nextmillenniumtest/supplemental/error-response.json @@ -29,6 +29,7 @@ "body": { "id": "testid", "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "7819" @@ -48,6 +49,7 @@ "w": 320 }, "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "7819" diff --git a/adapters/nextmillennium/nextmillenniumtest/supplemental/no-content.json b/adapters/nextmillennium/nextmillenniumtest/supplemental/no-content.json index c4710a376d0..699be4e9aad 100644 --- a/adapters/nextmillennium/nextmillenniumtest/supplemental/no-content.json +++ b/adapters/nextmillennium/nextmillenniumtest/supplemental/no-content.json @@ -29,6 +29,7 @@ "body": { "id": "testid", "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "7819" @@ -48,6 +49,7 @@ "w": 320 }, "ext": { + "nextMillennium": {}, "prebid": { "storedrequest": { "id": "7819" From 71f20302f7436cd2c707b58f0cc237c2f8d56677 Mon Sep 17 00:00:00 2001 From: Bryan DeLong Date: Wed, 27 Dec 2023 06:29:21 -0500 Subject: [PATCH 259/268] Consumable: App video and audio support (#3338) --- adapters/consumable/adtypes.go | 64 --- adapters/consumable/consumable.go | 383 +++++------------- .../consumable/exemplary/app-audio.json | 113 ++++++ .../consumable/exemplary/app-banner.json | 111 +++++ .../consumable/exemplary/app-video.json | 126 ++++++ .../consumable/exemplary/simple-banner.json | 133 +++--- .../supplemental/app-audio-bad-params.json | 37 ++ .../supplemental/app-banner-no-ad.json | 75 ++++ .../supplemental/app-video-no-media-type.json | 110 +++++ .../supplemental/bad-dsp-request-example.json | 78 ++++ .../dsp-server-internal-error-example.json | 78 ++++ .../simple-banner-content-meta.json | 117 +++--- .../supplemental/simple-banner-coppa.json | 110 +++-- .../supplemental/simple-banner-eids.json | 163 ++++---- .../supplemental/simple-banner-gdpr-2.json | 112 +++-- .../supplemental/simple-banner-gdpr-3.json | 119 +++--- .../supplemental/simple-banner-gdpr.json | 126 +++--- .../supplemental/simple-banner-gpp.json | 125 +++--- .../supplemental/simple-banner-meta.json | 114 +++--- .../simple-banner-no-impressionUrl.json | 130 +++--- .../supplemental/simple-banner-no-params.json | 43 ++ .../supplemental/simple-banner-schain.json | 132 +++--- .../simple-banner-us-privacy.json | 119 +++--- .../unknown-status-code-example.json | 78 ++++ adapters/consumable/consumable_test.go | 85 +++- adapters/consumable/instant.go | 21 - adapters/consumable/params_test.go | 2 + adapters/consumable/retrieveAd.go | 10 - openrtb_ext/imp_consumable.go | 3 +- static/bidder-info/consumable.yaml | 3 + static/bidder-params/consumable.json | 10 +- 31 files changed, 1750 insertions(+), 1180 deletions(-) delete mode 100644 adapters/consumable/adtypes.go create mode 100644 adapters/consumable/consumable/exemplary/app-audio.json create mode 100644 adapters/consumable/consumable/exemplary/app-banner.json create mode 100644 adapters/consumable/consumable/exemplary/app-video.json create mode 100644 adapters/consumable/consumable/supplemental/app-audio-bad-params.json create mode 100644 adapters/consumable/consumable/supplemental/app-banner-no-ad.json create mode 100644 adapters/consumable/consumable/supplemental/app-video-no-media-type.json create mode 100644 adapters/consumable/consumable/supplemental/bad-dsp-request-example.json create mode 100644 adapters/consumable/consumable/supplemental/dsp-server-internal-error-example.json create mode 100644 adapters/consumable/consumable/supplemental/simple-banner-no-params.json create mode 100644 adapters/consumable/consumable/supplemental/unknown-status-code-example.json delete mode 100644 adapters/consumable/instant.go delete mode 100644 adapters/consumable/retrieveAd.go diff --git a/adapters/consumable/adtypes.go b/adapters/consumable/adtypes.go deleted file mode 100644 index 9974a4f26d6..00000000000 --- a/adapters/consumable/adtypes.go +++ /dev/null @@ -1,64 +0,0 @@ -package consumable - -import ( - "strconv" - - "github.com/prebid/openrtb/v19/openrtb2" -) - -/* Turn array of openrtb formats into consumable's code*/ -func getSizeCodes(Formats []openrtb2.Format) []int { - - codes := make([]int, 0) - for _, format := range Formats { - str := strconv.FormatInt(format.W, 10) + "x" + strconv.FormatInt(format.H, 10) - if code, ok := sizeMap[str]; ok { - codes = append(codes, code) - } - } - return codes -} - -var sizeMap = map[string]int{ - "120x90": 1, - // 120x90 is in twice in prebid.js implementation - probably as spacer - "468x60": 3, - "728x90": 4, - "300x250": 5, - "160x600": 6, - "120x600": 7, - "300x100": 8, - "180x150": 9, - "336x280": 10, - "240x400": 11, - "234x60": 12, - "88x31": 13, - "120x60": 14, - "120x240": 15, - "125x125": 16, - "220x250": 17, - "250x250": 18, - "250x90": 19, - "0x0": 20, // TODO: can this be removed - I suspect it's padding in prebid.js impl - "200x90": 21, - "300x50": 22, - "320x50": 23, - "320x480": 24, - "185x185": 25, - "620x45": 26, - "300x125": 27, - "800x250": 28, - // below order is preserved from prebid.js implementation for easy comparison - "970x90": 77, - "970x250": 123, - "300x600": 43, - "970x66": 286, - "970x280": 3230, - "486x60": 429, - "700x500": 374, - "300x1050": 934, - "320x100": 1578, - "320x250": 331, - "320x267": 3301, - "728x250": 2730, -} diff --git a/adapters/consumable/consumable.go b/adapters/consumable/consumable.go index 635bc7058ed..932a58b5679 100644 --- a/adapters/consumable/consumable.go +++ b/adapters/consumable/consumable.go @@ -3,319 +3,144 @@ package consumable import ( "encoding/json" "fmt" - "net/http" - "net/url" - "strconv" - "strings" - "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/v2/adapters" "github.com/prebid/prebid-server/v2/config" "github.com/prebid/prebid-server/v2/errortypes" "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/privacy/ccpa" + "net/http" ) -type ConsumableAdapter struct { - clock instant +type adapter struct { endpoint string } -type bidRequest struct { - Placements []placement `json:"placements"` - Time int64 `json:"time"` - NetworkId int `json:"networkId,omitempty"` - SiteId int `json:"siteId"` - UnitId int `json:"unitId"` - UnitName string `json:"unitName,omitempty"` - IncludePricingData bool `json:"includePricingData"` - User user `json:"user,omitempty"` - Referrer string `json:"referrer,omitempty"` - Ip string `json:"ip,omitempty"` - Url string `json:"url,omitempty"` - EnableBotFiltering bool `json:"enableBotFiltering,omitempty"` - Parallel bool `json:"parallel"` - CCPA string `json:"ccpa,omitempty"` - GDPR *bidGdpr `json:"gdpr,omitempty"` - Coppa bool `json:"coppa,omitempty"` - SChain openrtb2.SupplyChain `json:"schain"` - Content *openrtb2.Content `json:"content,omitempty"` - GPP string `json:"gpp,omitempty"` - GPPSID []int8 `json:"gpp_sid,omitempty"` -} - -type placement struct { - DivName string `json:"divName"` - NetworkId int `json:"networkId,omitempty"` - SiteId int `json:"siteId"` - UnitId int `json:"unitId"` - UnitName string `json:"unitName,omitempty"` - AdTypes []int `json:"adTypes"` -} - -type user struct { - Key string `json:"key,omitempty"` - Eids []openrtb2.EID `json:"eids,omitempty"` -} - -type bidGdpr struct { - Applies *bool `json:"applies,omitempty"` - Consent string `json:"consent,omitempty"` -} - -type bidResponse struct { - Decisions map[string]decision `json:"decisions"` // map by bidId -} - -/** - * See https://dev.adzerk.com/v1.0/reference/response - */ -type decision struct { - Pricing *pricing `json:"pricing"` - AdID int64 `json:"adId"` - BidderName string `json:"bidderName,omitempty"` - CreativeID string `json:"creativeId,omitempty"` - Contents []contents `json:"contents"` - ImpressionUrl *string `json:"impressionUrl,omitempty"` - Width uint64 `json:"width,omitempty"` // Consumable extension, not defined by Adzerk - Height uint64 `json:"height,omitempty"` // Consumable extension, not defined by Adzerk - Adomain []string `json:"adomain,omitempty"` - Cats []string `json:"cats,omitempty"` -} - -type contents struct { - Body string `json:"body"` -} - -type pricing struct { - ClearPrice *float64 `json:"clearPrice"` -} - -func (a *ConsumableAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { var errs []error - headers := http.Header{ "Content-Type": {"application/json"}, "Accept": {"application/json"}, } - - if request.Device != nil { - if request.Device.UA != "" { - headers.Set("User-Agent", request.Device.UA) - } - - if request.Device.IP != "" { - headers.Set("Forwarded", "for="+request.Device.IP) - headers.Set("X-Forwarded-For", request.Device.IP) - } - } - - // Set azk cookie to one we got via sync - if request.User != nil { - userID := strings.TrimSpace(request.User.BuyerUID) - if len(userID) > 0 { - headers.Add("Cookie", fmt.Sprintf("%s=%s", "azk", userID)) - } - } - - if request.Site != nil && request.Site.Page != "" { - headers.Set("Referer", request.Site.Page) - - pageUrl, err := url.Parse(request.Site.Page) - if err != nil { - errs = append(errs, err) - } else { - origin := url.URL{ - Scheme: pageUrl.Scheme, - Opaque: pageUrl.Opaque, - Host: pageUrl.Host, - } - headers.Set("Origin", origin.String()) - } - } - - body := bidRequest{ - Placements: make([]placement, len(request.Imp)), - Time: a.clock.Now().Unix(), - IncludePricingData: true, - EnableBotFiltering: true, - Parallel: true, - } - - if request.Site != nil { - body.Referrer = request.Site.Ref // Effectively the previous page to the page where the ad will be shown - body.Url = request.Site.Page // where the impression will be made - } - - gdpr := bidGdpr{} - - ccpaPolicy, err := ccpa.ReadFromRequest(request) + bodyBytes, err := json.Marshal(request) if err != nil { - errs = append(errs, err) - } else { - body.CCPA = ccpaPolicy.Consent + return nil, []error{err} } - if request.Regs != nil && request.Regs.Ext != nil { - var extRegs openrtb_ext.ExtRegs - if err := json.Unmarshal(request.Regs.Ext, &extRegs); err != nil { - errs = append(errs, err) - } else { - if extRegs.GDPR != nil { - applies := *extRegs.GDPR != 0 - gdpr.Applies = &applies - body.GDPR = &gdpr - } + if request.Site != nil { + _, consumableExt, err := extractExtensions(request.Imp[0]) + if err != nil { + return nil, err } - } - - if request.User != nil && request.User.Ext != nil { - var extUser openrtb_ext.ExtUser - if err := json.Unmarshal(request.User.Ext, &extUser); err != nil { - errs = append(errs, err) - } else { - gdpr.Consent = extUser.Consent - body.GDPR = &gdpr - - if hasEids(extUser.Eids) { - body.User.Eids = extUser.Eids - } + if consumableExt.SiteId == 0 && consumableExt.NetworkId == 0 && consumableExt.UnitId == 0 { + return nil, []error{&errortypes.FailedToRequestBids{ + Message: "SiteId, NetworkId and UnitId are all required for site requests", + }} } - } - - if request.Source != nil && request.Source.Ext != nil { - var extSChain openrtb_ext.ExtRequestPrebidSChain - if err := json.Unmarshal(request.Source.Ext, &extSChain); err != nil { - errs = append(errs, err) - } else { - body.SChain = extSChain.SChain + requests := []*adapters.RequestData{ + { + Method: "POST", + Uri: "https://e.serverbid.com/sb/rtb", + Body: bodyBytes, + Headers: headers, + }, } - } - - body.Coppa = request.Regs != nil && request.Regs.COPPA > 0 - - if request.Regs != nil && request.Regs.GPP != "" { - body.GPP = request.Regs.GPP - } - - if request.Regs != nil && request.Regs.GPPSID != nil { - body.GPPSID = request.Regs.GPPSID - } - - if request.Site != nil && request.Site.Content != nil { - body.Content = request.Site.Content - } else if request.App != nil && request.App.Content != nil { - body.Content = request.App.Content - } - - for i, impression := range request.Imp { - - _, consumableExt, err := extractExtensions(impression) + return requests, errs + } else { + _, consumableExt, err := extractExtensions(request.Imp[0]) if err != nil { return nil, err } - // These get set on the first one in observed working requests - if i == 0 { - body.NetworkId = consumableExt.NetworkId - body.SiteId = consumableExt.SiteId - body.UnitId = consumableExt.UnitId - body.UnitName = consumableExt.UnitName + if consumableExt.PlacementId == "" { + return nil, []error{&errortypes.FailedToRequestBids{ + Message: "PlacementId is required for non-site requests", + }} } - - body.Placements[i] = placement{ - DivName: impression.ID, - NetworkId: consumableExt.NetworkId, - SiteId: consumableExt.SiteId, - UnitId: consumableExt.UnitId, - UnitName: consumableExt.UnitName, - AdTypes: getSizeCodes(impression.Banner.Format), // was adTypes: bid.adTypes || getSize(bid.sizes) in prebid.js + requests := []*adapters.RequestData{ + { + Method: "POST", + Uri: "https://e.serverbid.com/rtb/bid?s=" + consumableExt.PlacementId, + Body: bodyBytes, + Headers: headers, + }, } + return requests, errs } - bodyBytes, err := json.Marshal(body) - if err != nil { - return nil, []error{err} - } - - requests := []*adapters.RequestData{ - { - Method: "POST", - Uri: "https://e.serverbid.com/api/v2", - Body: bodyBytes, - Headers: headers, - }, - } - - return requests, errs } - -/* -internal original request in OpenRTB, external = result of us having converted it (what comes out of MakeRequests) -*/ -func (a *ConsumableAdapter) MakeBids( - internalRequest *openrtb2.BidRequest, - externalRequest *adapters.RequestData, - response *adapters.ResponseData, -) (*adapters.BidderResponse, []error) { - - if response.StatusCode == http.StatusNoContent { +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { return nil, nil } - if response.StatusCode == http.StatusBadRequest { - return nil, []error{&errortypes.BadInput{ - Message: fmt.Sprintf("unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), - }} - } - - if response.StatusCode != http.StatusOK { - return nil, []error{&errortypes.BadServerResponse{ - Message: fmt.Sprintf("unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), - }} + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} } - var serverResponse bidResponse // response from Consumable - if err := json.Unmarshal(response.Body, &serverResponse); err != nil { - return nil, []error{&errortypes.BadServerResponse{ - Message: fmt.Sprintf("error while decoding response, err: %s", err), - }} + var response openrtb2.BidResponse + if err := json.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} } - bidderResponse := adapters.NewBidderResponse() + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + bidResponse.Currency = response.Cur var errors []error + for _, seatBid := range response.SeatBid { + for i, bid := range seatBid.Bid { + bidType, err := getMediaTypeForBid(bid) + if err != nil { + errors = append(errors, err) + continue + } + var bidVideo *openrtb_ext.ExtBidPrebidVideo + if bidType == openrtb_ext.BidTypeVideo { + bidVideo = &openrtb_ext.ExtBidPrebidVideo{Duration: int(bid.Dur)} + } + switch bidType { + case openrtb_ext.BidTypeAudio: + seatBid.Bid[i].MType = openrtb2.MarkupAudio + break + case openrtb_ext.BidTypeVideo: + seatBid.Bid[i].MType = openrtb2.MarkupVideo + break + case openrtb_ext.BidTypeBanner: + seatBid.Bid[i].MType = openrtb2.MarkupBanner + break + } + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + BidVideo: bidVideo, + }) + } + } + return bidResponse, nil +} - for impID, decision := range serverResponse.Decisions { +func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + if bid.MType != 0 { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupAudio: + return openrtb_ext.BidTypeAudio, nil + } + } - if decision.Pricing != nil && decision.Pricing.ClearPrice != nil { - bid := openrtb2.Bid{} - bid.ID = internalRequest.ID - bid.ImpID = impID - bid.Price = *decision.Pricing.ClearPrice - bid.AdM = retrieveAd(decision) - bid.W = int64(decision.Width) - bid.H = int64(decision.Height) - bid.CrID = strconv.FormatInt(decision.AdID, 10) - bid.Exp = 30 // TODO: Check this is intention of TTL - bid.ADomain = decision.Adomain - bid.Cat = decision.Cats - // not yet ported from prebid.js adapter - //bid.requestId = bidId; - //bid.currency = 'USD'; - //bid.netRevenue = true; - //bid.referrer = utils.getTopWindowUrl(); + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Failed to parse impression \"%s\" mediatype", bid.ImpID), + } +} - bidderResponse.Bids = append(bidderResponse.Bids, &adapters.TypedBid{ - Bid: &bid, - // Consumable units are always HTML, never VAST. - // From Prebid's point of view, this means that Consumable units - // are always "banners". - BidType: openrtb_ext.BidTypeBanner, - }) - } +// Builder builds a new instance of the Consumable adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, } - return bidderResponse, errors + return bidder, nil } func extractExtensions(impression openrtb2.Imp) (*adapters.ExtImpBidder, *openrtb_ext.ExtImpConsumable, []error) { @@ -335,21 +160,3 @@ func extractExtensions(impression openrtb2.Imp) (*adapters.ExtImpBidder, *openrt return &bidderExt, &consumableExt, nil } - -// Builder builds a new instance of the Consumable adapter for the given bidder with the given config. -func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { - bidder := &ConsumableAdapter{ - clock: realInstant{}, - endpoint: config.Endpoint, - } - return bidder, nil -} - -func hasEids(eids []openrtb2.EID) bool { - for i := 0; i < len(eids); i++ { - if len(eids[i].UIDs) > 0 && eids[i].UIDs[0].ID != "" { - return true - } - } - return false -} diff --git a/adapters/consumable/consumable/exemplary/app-audio.json b/adapters/consumable/consumable/exemplary/app-audio.json new file mode 100644 index 00000000000..589842c8876 --- /dev/null +++ b/adapters/consumable/consumable/exemplary/app-audio.json @@ -0,0 +1,113 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "audio": { + "mimes": [ + "audio/mp3" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ] + }, + "ext": { + "bidder": { + "placementId": "0421008445828ceb46f496700a5fa65e" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://e.serverbid.com/rtb/bid?s=0421008445828ceb46f496700a5fa65e", + "body": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "audio": { + "mimes": [ + "audio/mp3" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ] + }, + "ext": { + "bidder": { + "placementId": "0421008445828ceb46f496700a5fa65e" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "bmtm", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "mtype": 3 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "mtype": 3 + }, + "type": "audio" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/consumable/consumable/exemplary/app-banner.json b/adapters/consumable/consumable/exemplary/app-banner.json new file mode 100644 index 00000000000..688ccb74c05 --- /dev/null +++ b/adapters/consumable/consumable/exemplary/app-banner.json @@ -0,0 +1,111 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "placementId": "0421008445828ceb46f496700a5fa65e" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://e.serverbid.com/rtb/bid?s=0421008445828ceb46f496700a5fa65e", + "body": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "placementId": "0421008445828ceb46f496700a5fa65e" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "bmtm", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 728, + "h": 90, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/consumable/consumable/exemplary/app-video.json b/adapters/consumable/consumable/exemplary/app-video.json new file mode 100644 index 00000000000..a3772933aba --- /dev/null +++ b/adapters/consumable/consumable/exemplary/app-video.json @@ -0,0 +1,126 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "placementId": "0421008445828ceb46f496700a5fa65e" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://e.serverbid.com/rtb/bid?s=0421008445828ceb46f496700a5fa65e", + "body": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "placementId": "0421008445828ceb46f496700a5fa65e" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "bmtm", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "cat": ["IAB15"], + "dur": 30, + "mtype": 2 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 728, + "h": 90, + "cat": ["IAB15"], + "dur": 30, + "mtype": 2 + }, + "type": "video", + "BidType": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/consumable/consumable/exemplary/simple-banner.json b/adapters/consumable/consumable/exemplary/simple-banner.json index 173104ee9ad..2e401b88087 100644 --- a/adapters/consumable/consumable/exemplary/simple-banner.json +++ b/adapters/consumable/consumable/exemplary/simple-banner.json @@ -5,20 +5,32 @@ { "id": "test-imp-id", "banner": { - "format": [{"w": 728, "h": 250}] + "format": [ + { + "w": 728, + "h": 250 + } + ] }, "ext": { "bidder": { "networkId": 11, "siteId": 32, - "unitId": 42 + "unitId": 42, + "unitName": "cnsmbl-audio-728x90-slider" } } } ], "device": { "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36", - "ip": "123.123.123.123" + "ip": "123.123.123.123", + "geo": { + "country": "USA", + "region": "IL", + "city": "Elgin", + "zip": "60123" + } }, "site": { "domain": "www.some.com", @@ -28,75 +40,68 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://e.serverbid.com/api/v2", - "headers": { - "Accept": [ - "application/json" - ], - "Content-Type": [ - "application/json" - ], - "User-Agent": [ - "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" - ], - "X-Forwarded-For": [ - "123.123.123.123" - ], - "Forwarded": [ - "for=123.123.123.123" - ], - "Origin": [ - "http://www.some.com" - ], - "Referer": [ - "http://www.some.com/page-where-ad-will-be-shown" - ] - }, + "uri": "https://e.serverbid.com/sb/rtb", "body": { - "placements": [ + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36", + "geo": { + "country": "USA", + "region": "IL", + "city": "Elgin", + "zip": "60123" + } + }, + "id": "test-request-id", + "imp": [ { - "adTypes": [2730], - "divName": "test-imp-id", - "networkId": 11, - "siteId": 32, - "unitId": 42 + "banner": { + "format": [ + { + "h": 250, + "w": 728 + } + ] + }, + "ext": { + "bidder": { + "networkId": 11, + "siteId": 32, + "unitId": 42, + "unitName": "cnsmbl-audio-728x90-slider" + } + }, + "id": "test-imp-id" } ], - "schain": { - "complete": 0, - "nodes": null, - "ver": "" - }, - "networkId": 11, - "siteId": 32, - "unitId": 42, - "time": 1451651415, - "url": "http://www.some.com/page-where-ad-will-be-shown", - "includePricingData": true, - "user":{}, - "enableBotFiltering": true, - "parallel": true + "site": { + "domain": "www.some.com", + "page": "http://www.some.com/page-where-ad-will-be-shown" + } } }, "mockResponse": { "status": 200, "body": { - "decisions": { - "test-imp-id": { - "adId": 1234567890, - "pricing": { - "clearPrice": 0.5 - }, - "width": 728, - "height": 250, - "impressionUrl": "http://localhost:8080/shown", - "contents" : [ + "id": "test-request-id", + "seatbid": [ + { + "seat": "bmtm", + "bid": [ { - "body": "Remember this: https://www.google.com/search?q=blink+tag ?" + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "mtype": 1 } ] } - } + ], + "cur": "USD" } } } @@ -107,14 +112,14 @@ "bids": [ { "bid": { - "id": "test-request-id", + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", "price": 0.5, - "adm": "Remember this: https://www.google.com/search?q=blink+tag ?", - "crid": "1234567890", - "exp": 30, + "adm": "some-test-ad", + "crid": "crid_10", "w": 728, - "h": 250 + "h": 90, + "mtype": 1 }, "type": "banner" } diff --git a/adapters/consumable/consumable/supplemental/app-audio-bad-params.json b/adapters/consumable/consumable/supplemental/app-audio-bad-params.json new file mode 100644 index 00000000000..2dadc39c111 --- /dev/null +++ b/adapters/consumable/consumable/supplemental/app-audio-bad-params.json @@ -0,0 +1,37 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + + } + } + } + ] + }, + "expectedMakeRequestsErrors": [ + { + "value": "PlacementId is required for non-site requests", + "comparison": "literal" + } + ] +} diff --git a/adapters/consumable/consumable/supplemental/app-banner-no-ad.json b/adapters/consumable/consumable/supplemental/app-banner-no-ad.json new file mode 100644 index 00000000000..c3d7238e104 --- /dev/null +++ b/adapters/consumable/consumable/supplemental/app-banner-no-ad.json @@ -0,0 +1,75 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "placementId": "0421008445828ceb46f496700a5fa65e" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://e.serverbid.com/rtb/bid?s=0421008445828ceb46f496700a5fa65e", + "body": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "placementId": "0421008445828ceb46f496700a5fa65e" + } + } + } + ] + } + }, + "mockResponse": { + "status": 204, + "body": { + } + } + } + ], + "expectedBidResponses": [ + + ] +} \ No newline at end of file diff --git a/adapters/consumable/consumable/supplemental/app-video-no-media-type.json b/adapters/consumable/consumable/supplemental/app-video-no-media-type.json new file mode 100644 index 00000000000..3cba39bb5b5 --- /dev/null +++ b/adapters/consumable/consumable/supplemental/app-video-no-media-type.json @@ -0,0 +1,110 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "placementId": "0421008445828ceb46f496700a5fa65e" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://e.serverbid.com/rtb/bid?s=0421008445828ceb46f496700a5fa65e", + "body": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "placementId": "0421008445828ceb46f496700a5fa65e" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "bmtm", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "cat": ["IAB15"], + "dur": 30 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + + ] + } + ] +} \ No newline at end of file diff --git a/adapters/consumable/consumable/supplemental/bad-dsp-request-example.json b/adapters/consumable/consumable/supplemental/bad-dsp-request-example.json new file mode 100644 index 00000000000..c66bb9ab5de --- /dev/null +++ b/adapters/consumable/consumable/supplemental/bad-dsp-request-example.json @@ -0,0 +1,78 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "placementId": "0421008445828ceb46f496700a5fa65e" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://e.serverbid.com/rtb/bid?s=0421008445828ceb46f496700a5fa65e", + "body": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "placementId": "0421008445828ceb46f496700a5fa65e" + } + } + } + ] + } + }, + "mockResponse": { + "status": 400, + "body": { + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/consumable/consumable/supplemental/dsp-server-internal-error-example.json b/adapters/consumable/consumable/supplemental/dsp-server-internal-error-example.json new file mode 100644 index 00000000000..07ad8e2358a --- /dev/null +++ b/adapters/consumable/consumable/supplemental/dsp-server-internal-error-example.json @@ -0,0 +1,78 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "placementId": "0421008445828ceb46f496700a5fa65e" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://e.serverbid.com/rtb/bid?s=0421008445828ceb46f496700a5fa65e", + "body": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "placementId": "0421008445828ceb46f496700a5fa65e" + } + } + } + ] + } + }, + "mockResponse": { + "status": 500, + "body": { + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/consumable/consumable/supplemental/simple-banner-content-meta.json b/adapters/consumable/consumable/supplemental/simple-banner-content-meta.json index 56d24166fec..220c8ab2069 100644 --- a/adapters/consumable/consumable/supplemental/simple-banner-content-meta.json +++ b/adapters/consumable/consumable/supplemental/simple-banner-content-meta.json @@ -5,7 +5,12 @@ { "id": "test-imp-id", "banner": { - "format": [{ "w": 728, "h": 250 }] + "format": [ + { + "w": 728, + "h": 250 + } + ] }, "ext": { "bidder": { @@ -36,71 +41,69 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://e.serverbid.com/api/v2", - "headers": { - "Accept": ["application/json"], - "Content-Type": ["application/json"], - "User-Agent": [ - "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" - ], - "X-Forwarded-For": ["123.123.123.123"], - "Forwarded": ["for=123.123.123.123"], - "Origin": ["http://www.some.com"], - "Referer": ["http://www.some.com/page-where-ad-will-be-shown"] - }, + "uri": "https://e.serverbid.com/sb/rtb", "body": { - "content": { - "id": "1009680902", - "title": "What You Know Bout Love", - "context": 3, - "url": "https://www.deezer.com/track/1009680902", - "artist": "Pop Smoke", - "album": "Shoot For The Stars Aim For The Moon" + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" }, - "placements": [ + "id": "test-request-id", + "imp": [ { - "adTypes": [2730], - "divName": "test-imp-id", - "networkId": 11, - "siteId": 32, - "unitId": 42 + "banner": { + "format": [ + { + "h": 250, + "w": 728 + } + ] + }, + "ext": { + "bidder": { + "networkId": 11, + "siteId": 32, + "unitId": 42 + } + }, + "id": "test-imp-id" } ], - "schain": { - "complete": 0, - "nodes": null, - "ver": "" - }, - "networkId": 11, - "siteId": 32, - "unitId": 42, - "time": 1451651415, - "url": "http://www.some.com/page-where-ad-will-be-shown", - "includePricingData": true, - "user": {}, - "enableBotFiltering": true, - "parallel": true + "site": { + "content": { + "album": "Shoot For The Stars Aim For The Moon", + "artist": "Pop Smoke", + "context": 3, + "id": "1009680902", + "title": "What You Know Bout Love", + "url": "https://www.deezer.com/track/1009680902" + }, + "domain": "www.some.com", + "page": "http://www.some.com/page-where-ad-will-be-shown" + } } }, "mockResponse": { "status": 200, "body": { - "decisions": { - "test-imp-id": { - "adId": 1234567890, - "pricing": { - "clearPrice": 0.5 - }, - "width": 728, - "height": 250, - "impressionUrl": "http://localhost:8080/shown", - "contents": [ + "id": "test-request-id", + "seatbid": [ + { + "seat": "bmtm", + "bid": [ { - "body": "Remember this: https://www.google.com/search?q=blink+tag ?" + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "mtype": 1 } ] } - } + ], + "cur": "USD" } } } @@ -111,14 +114,14 @@ "bids": [ { "bid": { - "id": "test-request-id", + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", "price": 0.5, - "adm": "Remember this: https://www.google.com/search?q=blink+tag ?", - "crid": "1234567890", - "exp": 30, + "adm": "some-test-ad", + "crid": "crid_10", "w": 728, - "h": 250 + "h": 90, + "mtype": 1 }, "type": "banner" } diff --git a/adapters/consumable/consumable/supplemental/simple-banner-coppa.json b/adapters/consumable/consumable/supplemental/simple-banner-coppa.json index d1551c92e7c..25b732a21ce 100644 --- a/adapters/consumable/consumable/supplemental/simple-banner-coppa.json +++ b/adapters/consumable/consumable/supplemental/simple-banner-coppa.json @@ -31,76 +31,64 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://e.serverbid.com/api/v2", - "headers": { - "Accept": [ - "application/json" - ], - "Content-Type": [ - "application/json" - ], - "User-Agent": [ - "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" - ], - "X-Forwarded-For": [ - "123.123.123.123" - ], - "Forwarded": [ - "for=123.123.123.123" - ], - "Origin": [ - "http://www.some.com" - ], - "Referer": [ - "http://www.some.com/page-where-ad-will-be-shown" - ] - }, + "uri": "https://e.serverbid.com/sb/rtb", "body": { - "placements": [ + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" + }, + "id": "test-request-id", + "imp": [ { - "adTypes": [2730], - "divName": "test-imp-id", - "networkId": 11, - "siteId": 32, - "unitId": 42 + "banner": { + "format": [ + { + "h": 250, + "w": 728 + } + ] + }, + "ext": { + "bidder": { + "networkId": 11, + "siteId": 32, + "unitId": 42 + } + }, + "id": "test-imp-id" } ], - "schain": { - "complete": 0, - "nodes": null, - "ver": "" + "regs": { + "coppa": 1 }, - "networkId": 11, - "siteId": 32, - "unitId": 42, - "time": 1451651415, - "url": "http://www.some.com/page-where-ad-will-be-shown", - "includePricingData": true, - "user":{}, - "enableBotFiltering": true, - "parallel": true, - "coppa": true + "site": { + "domain": "www.some.com", + "page": "http://www.some.com/page-where-ad-will-be-shown" + } } }, "mockResponse": { "status": 200, "body": { - "decisions": { - "test-imp-id": { - "adId": 1234567890, - "pricing": { - "clearPrice": 0.5 - }, - "width": 728, - "height": 250, - "impressionUrl": "http://localhost:8080/shown", - "contents" : [ + "id": "test-request-id", + "seatbid": [ + { + "seat": "bmtm", + "bid": [ { - "body": "Remember this: https://www.google.com/search?q=blink+tag ?" + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "mtype": 1 } ] } - } + ], + "cur": "USD" } } } @@ -111,14 +99,14 @@ "bids": [ { "bid": { - "id": "test-request-id", + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", "price": 0.5, - "adm": "Remember this: https://www.google.com/search?q=blink+tag ?", - "crid": "1234567890", - "exp": 30, + "adm": "some-test-ad", + "crid": "crid_10", "w": 728, - "h": 250 + "h": 90, + "mtype": 1 }, "type": "banner" } diff --git a/adapters/consumable/consumable/supplemental/simple-banner-eids.json b/adapters/consumable/consumable/supplemental/simple-banner-eids.json index 106796e21c0..d273117b1ae 100644 --- a/adapters/consumable/consumable/supplemental/simple-banner-eids.json +++ b/adapters/consumable/consumable/supplemental/simple-banner-eids.json @@ -5,7 +5,12 @@ { "id": "test-imp-id", "banner": { - "format": [{"w": 728, "h": 250}] + "format": [ + { + "w": 728, + "h": 250 + } + ] }, "ext": { "bidder": { @@ -26,103 +31,99 @@ }, "user": { "ext": { - "eids": [{ - "source": "adserver.org", - "uids": [{ - "id": "TTD_ID", - "atype": 1, - "ext": { - "rtiPartner": "TDID" - } - }] - }] + "eids": [ + { + "source": "adserver.org", + "uids": [ + { + "id": "TTD_ID", + "atype": 1, + "ext": { + "rtiPartner": "TDID" + } + } + ] + } + ] } } }, "httpCalls": [ { "expectedRequest": { - "uri": "https://e.serverbid.com/api/v2", - "headers": { - "Accept": [ - "application/json" - ], - "Content-Type": [ - "application/json" - ], - "User-Agent": [ - "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" - ], - "X-Forwarded-For": [ - "123.123.123.123" - ], - "Forwarded": [ - "for=123.123.123.123" - ], - "Origin": [ - "http://www.some.com" - ], - "Referer": [ - "http://www.some.com/page-where-ad-will-be-shown" - ] - }, + "uri": "https://e.serverbid.com/sb/rtb", "body": { - "placements": [ + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" + }, + "id": "test-request-id", + "imp": [ { - "adTypes": [2730], - "divName": "test-imp-id", - "networkId": 11, - "siteId": 32, - "unitId": 42 + "banner": { + "format": [ + { + "h": 250, + "w": 728 + } + ] + }, + "ext": { + "bidder": { + "networkId": 11, + "siteId": 32, + "unitId": 42 + } + }, + "id": "test-imp-id" } ], - "schain": { - "complete": 0, - "nodes": null, - "ver": "" + "site": { + "domain": "www.some.com", + "page": "http://www.some.com/page-where-ad-will-be-shown" }, - "networkId": 11, - "siteId": 32, - "unitId": 42, - "time": 1451651415, - "url": "http://www.some.com/page-where-ad-will-be-shown", - "includePricingData": true, "user": { - "eids": [{ - "source": "adserver.org", - "uids": [{ - "id": "TTD_ID", - "atype": 1, - "ext": { - "rtiPartner": "TDID" + "ext": { + "eids": [ + { + "source": "adserver.org", + "uids": [ + { + "atype": 1, + "ext": { + "rtiPartner": "TDID" + }, + "id": "TTD_ID" + } + ] } - }] - }] - }, - "enableBotFiltering": true, - "gdpr": {}, - "parallel": true + ] + } + } } }, "mockResponse": { "status": 200, "body": { - "decisions": { - "test-imp-id": { - "adId": 1234567890, - "pricing": { - "clearPrice": 0.5 - }, - "width": 728, - "height": 250, - "impressionUrl": "http://localhost:8080/shown", - "contents" : [ + "id": "test-request-id", + "seatbid": [ + { + "seat": "bmtm", + "bid": [ { - "body": "Remember this: https://www.google.com/search?q=blink+tag ?" + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "mtype": 1 } ] } - } + ], + "cur": "USD" } } } @@ -133,14 +134,14 @@ "bids": [ { "bid": { - "id": "test-request-id", + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", "price": 0.5, - "adm": "Remember this: https://www.google.com/search?q=blink+tag ?", - "crid": "1234567890", - "exp": 30, + "adm": "some-test-ad", + "crid": "crid_10", "w": 728, - "h": 250 + "h": 90, + "mtype": 1 }, "type": "banner" } diff --git a/adapters/consumable/consumable/supplemental/simple-banner-gdpr-2.json b/adapters/consumable/consumable/supplemental/simple-banner-gdpr-2.json index 2e2d8588326..b2dbc9bdfbf 100644 --- a/adapters/consumable/consumable/supplemental/simple-banner-gdpr-2.json +++ b/adapters/consumable/consumable/supplemental/simple-banner-gdpr-2.json @@ -33,78 +33,66 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://e.serverbid.com/api/v2", - "headers": { - "Accept": [ - "application/json" - ], - "Content-Type": [ - "application/json" - ], - "User-Agent": [ - "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" - ], - "X-Forwarded-For": [ - "123.123.123.123" - ], - "Forwarded": [ - "for=123.123.123.123" - ], - "Origin": [ - "http://www.some.com" - ], - "Referer": [ - "http://www.some.com/page-where-ad-will-be-shown" - ] - }, + "uri": "https://e.serverbid.com/sb/rtb", "body": { - "placements": [ + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" + }, + "id": "test-request-id", + "imp": [ { - "adTypes": [2730], - "divName": "test-imp-id", - "networkId": 11, - "siteId": 32, - "unitId": 42 + "banner": { + "format": [ + { + "h": 250, + "w": 728 + } + ] + }, + "ext": { + "bidder": { + "networkId": 11, + "siteId": 32, + "unitId": 42 + } + }, + "id": "test-imp-id" } ], - "schain": { - "complete": 0, - "nodes": null, - "ver": "" + "regs": { + "ext": { + "gdpr": 0 + } }, - "networkId": 11, - "siteId": 32, - "unitId": 42, - "time": 1451651415, - "url": "http://www.some.com/page-where-ad-will-be-shown", - "includePricingData": true, - "user":{}, - "enableBotFiltering": true, - "parallel": true, - "gdpr": { - "applies": false + "site": { + "domain": "www.some.com", + "page": "http://www.some.com/page-where-ad-will-be-shown" } } }, "mockResponse": { "status": 200, "body": { - "decisions": { - "test-imp-id": { - "adId": 1234567890, - "pricing": { - "clearPrice": 0.5 - }, - "width": 728, - "height": 250, - "impressionUrl": "http://localhost:8080/shown", - "contents" : [ + "id": "test-request-id", + "seatbid": [ + { + "seat": "bmtm", + "bid": [ { - "body": "Remember this: https://www.google.com/search?q=blink+tag ?" + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "mtype": 1 } ] } - } + ], + "cur": "USD" } } } @@ -115,14 +103,14 @@ "bids": [ { "bid": { - "id": "test-request-id", + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", "price": 0.5, - "adm": "Remember this: https://www.google.com/search?q=blink+tag ?", - "crid": "1234567890", - "exp": 30, + "adm": "some-test-ad", + "crid": "crid_10", "w": 728, - "h": 250 + "h": 90, + "mtype": 1 }, "type": "banner" } diff --git a/adapters/consumable/consumable/supplemental/simple-banner-gdpr-3.json b/adapters/consumable/consumable/supplemental/simple-banner-gdpr-3.json index ea7be2342b2..fccc96ed6df 100644 --- a/adapters/consumable/consumable/supplemental/simple-banner-gdpr-3.json +++ b/adapters/consumable/consumable/supplemental/simple-banner-gdpr-3.json @@ -5,7 +5,12 @@ { "id": "test-imp-id", "banner": { - "format": [{"w": 728, "h": 250}] + "format": [ + { + "w": 728, + "h": 250 + } + ] }, "ext": { "bidder": { @@ -33,78 +38,66 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://e.serverbid.com/api/v2", - "headers": { - "Accept": [ - "application/json" - ], - "Content-Type": [ - "application/json" - ], - "User-Agent": [ - "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" - ], - "X-Forwarded-For": [ - "123.123.123.123" - ], - "Forwarded": [ - "for=123.123.123.123" - ], - "Origin": [ - "http://www.some.com" - ], - "Referer": [ - "http://www.some.com/page-where-ad-will-be-shown" - ] - }, + "uri": "https://e.serverbid.com/sb/rtb", "body": { - "placements": [ + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" + }, + "id": "test-request-id", + "imp": [ { - "adTypes": [2730], - "divName": "test-imp-id", - "networkId": 11, - "siteId": 32, - "unitId": 42 + "banner": { + "format": [ + { + "h": 250, + "w": 728 + } + ] + }, + "ext": { + "bidder": { + "networkId": 11, + "siteId": 32, + "unitId": 42 + } + }, + "id": "test-imp-id" } ], - "schain": { - "complete": 0, - "nodes": null, - "ver": "" + "site": { + "domain": "www.some.com", + "page": "http://www.some.com/page-where-ad-will-be-shown" }, - "networkId": 11, - "siteId": 32, - "unitId": 42, - "time": 1451651415, - "url": "http://www.some.com/page-where-ad-will-be-shown", - "includePricingData": true, - "user":{}, - "enableBotFiltering": true, - "parallel": true, - "gdpr": { - "consent": "abcdefghijklm" + "user": { + "ext": { + "consent": "abcdefghijklm" + } } } }, "mockResponse": { "status": 200, "body": { - "decisions": { - "test-imp-id": { - "adId": 1234567890, - "pricing": { - "clearPrice": 0.5 - }, - "width": 728, - "height": 250, - "impressionUrl": "http://localhost:8080/shown", - "contents" : [ + "id": "test-request-id", + "seatbid": [ + { + "seat": "bmtm", + "bid": [ { - "body": "Remember this: https://www.google.com/search?q=blink+tag ?" + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "mtype": 1 } ] } - } + ], + "cur": "USD" } } } @@ -115,14 +108,14 @@ "bids": [ { "bid": { - "id": "test-request-id", + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", "price": 0.5, - "adm": "Remember this: https://www.google.com/search?q=blink+tag ?", - "crid": "1234567890", - "exp": 30, + "adm": "some-test-ad", + "crid": "crid_10", "w": 728, - "h": 250 + "h": 90, + "mtype": 1 }, "type": "banner" } diff --git a/adapters/consumable/consumable/supplemental/simple-banner-gdpr.json b/adapters/consumable/consumable/supplemental/simple-banner-gdpr.json index 3f6a953efa8..99105a77325 100644 --- a/adapters/consumable/consumable/supplemental/simple-banner-gdpr.json +++ b/adapters/consumable/consumable/supplemental/simple-banner-gdpr.json @@ -5,7 +5,12 @@ { "id": "test-imp-id", "banner": { - "format": [{"w": 728, "h": 250}] + "format": [ + { + "w": 728, + "h": 250 + } + ] }, "ext": { "bidder": { @@ -38,79 +43,71 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://e.serverbid.com/api/v2", - "headers": { - "Accept": [ - "application/json" - ], - "Content-Type": [ - "application/json" - ], - "User-Agent": [ - "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" - ], - "X-Forwarded-For": [ - "123.123.123.123" - ], - "Forwarded": [ - "for=123.123.123.123" - ], - "Origin": [ - "http://www.some.com" - ], - "Referer": [ - "http://www.some.com/page-where-ad-will-be-shown" - ] - }, + "uri": "https://e.serverbid.com/sb/rtb", "body": { - "placements": [ + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" + }, + "id": "test-request-id", + "imp": [ { - "adTypes": [2730], - "divName": "test-imp-id", - "networkId": 11, - "siteId": 32, - "unitId": 42 + "banner": { + "format": [ + { + "h": 250, + "w": 728 + } + ] + }, + "ext": { + "bidder": { + "networkId": 11, + "siteId": 32, + "unitId": 42 + } + }, + "id": "test-imp-id" } ], - "schain": { - "complete": 0, - "nodes": null, - "ver": "" + "regs": { + "ext": { + "gdpr": 1 + } + }, + "site": { + "domain": "www.some.com", + "page": "http://www.some.com/page-where-ad-will-be-shown" }, - "networkId": 11, - "siteId": 32, - "unitId": 42, - "time": 1451651415, - "url": "http://www.some.com/page-where-ad-will-be-shown", - "includePricingData": true, - "user":{}, - "enableBotFiltering": true, - "parallel": true, - "gdpr": { - "applies": true, - "consent": "abcdefghijklm" + "user": { + "ext": { + "consent": "abcdefghijklm" + } } } }, "mockResponse": { "status": 200, "body": { - "decisions": { - "test-imp-id": { - "adId": 1234567890, - "pricing": { - "clearPrice": 0.5 - }, - "width": 728, - "height": 250, - "impressionUrl": "http://localhost:8080/shown", - "contents" : [ + "id": "test-request-id", + "seatbid": [ + { + "seat": "bmtm", + "bid": [ { - "body": "Remember this: https://www.google.com/search?q=blink+tag ?" + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "mtype": 1 } ] } - } + ], + "cur": "USD" } } } @@ -121,14 +118,15 @@ "bids": [ { "bid": { - "id": "test-request-id", + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", "price": 0.5, - "adm": "Remember this: https://www.google.com/search?q=blink+tag ?", - "crid": "1234567890", - "exp": 30, + "adm": "some-test-ad", + "crid": "crid_10", "w": 728, - "h": 250 + "h": 90, + "mtype": 1 + }, "type": "banner" } diff --git a/adapters/consumable/consumable/supplemental/simple-banner-gpp.json b/adapters/consumable/consumable/supplemental/simple-banner-gpp.json index 9b2e3d75031..eae291c1c61 100644 --- a/adapters/consumable/consumable/supplemental/simple-banner-gpp.json +++ b/adapters/consumable/consumable/supplemental/simple-banner-gpp.json @@ -5,7 +5,12 @@ { "id": "test-imp-id", "banner": { - "format": [{"w": 728, "h": 250}] + "format": [ + { + "w": 728, + "h": 250 + } + ] }, "ext": { "bidder": { @@ -26,83 +31,75 @@ }, "regs": { "gpp": "gppString", - "gpp_sid": [7] + "gpp_sid": [ + 7 + ] } }, "httpCalls": [ { "expectedRequest": { - "uri": "https://e.serverbid.com/api/v2", - "headers": { - "Accept": [ - "application/json" - ], - "Content-Type": [ - "application/json" - ], - "User-Agent": [ - "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" - ], - "X-Forwarded-For": [ - "123.123.123.123" - ], - "Forwarded": [ - "for=123.123.123.123" - ], - "Origin": [ - "http://www.some.com" - ], - "Referer": [ - "http://www.some.com/page-where-ad-will-be-shown" - ] - }, + "uri": "https://e.serverbid.com/sb/rtb", "body": { - "placements": [ + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" + }, + "id": "test-request-id", + "imp": [ { - "adTypes": [2730], - "divName": "test-imp-id", - "networkId": 11, - "siteId": 32, - "unitId": 42 + "banner": { + "format": [ + { + "h": 250, + "w": 728 + } + ] + }, + "ext": { + "bidder": { + "networkId": 11, + "siteId": 32, + "unitId": 42 + } + }, + "id": "test-imp-id" } ], - "schain": { - "complete": 0, - "nodes": null, - "ver": "" + "regs": { + "gpp": "gppString", + "gpp_sid": [ + 7 + ] }, - "networkId": 11, - "siteId": 32, - "unitId": 42, - "time": 1451651415, - "url": "http://www.some.com/page-where-ad-will-be-shown", - "includePricingData": true, - "user":{}, - "enableBotFiltering": true, - "parallel": true, - "gpp": "gppString", - "gpp_sid": [7] + "site": { + "domain": "www.some.com", + "page": "http://www.some.com/page-where-ad-will-be-shown" + } } }, "mockResponse": { "status": 200, "body": { - "decisions": { - "test-imp-id": { - "adId": 1234567890, - "pricing": { - "clearPrice": 0.5 - }, - "width": 728, - "height": 250, - "impressionUrl": "http://localhost:8080/shown", - "contents" : [ + "id": "test-request-id", + "seatbid": [ + { + "seat": "bmtm", + "bid": [ { - "body": "Remember this: https://www.google.com/search?q=blink+tag ?" + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "mtype": 1 } ] } - } + ], + "cur": "USD" } } } @@ -113,14 +110,14 @@ "bids": [ { "bid": { - "id": "test-request-id", + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", "price": 0.5, - "adm": "Remember this: https://www.google.com/search?q=blink+tag ?", - "crid": "1234567890", - "exp": 30, + "adm": "some-test-ad", + "crid": "crid_10", "w": 728, - "h": 250 + "h": 90, + "mtype": 1 }, "type": "banner" } diff --git a/adapters/consumable/consumable/supplemental/simple-banner-meta.json b/adapters/consumable/consumable/supplemental/simple-banner-meta.json index 6c94c835aab..782ddc7bbe7 100644 --- a/adapters/consumable/consumable/supplemental/simple-banner-meta.json +++ b/adapters/consumable/consumable/supplemental/simple-banner-meta.json @@ -28,77 +28,61 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://e.serverbid.com/api/v2", - "headers": { - "Accept": [ - "application/json" - ], - "Content-Type": [ - "application/json" - ], - "User-Agent": [ - "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" - ], - "X-Forwarded-For": [ - "123.123.123.123" - ], - "Forwarded": [ - "for=123.123.123.123" - ], - "Origin": [ - "http://www.some.com" - ], - "Referer": [ - "http://www.some.com/page-where-ad-will-be-shown" - ] - }, + "uri": "https://e.serverbid.com/sb/rtb", "body": { - "placements": [ + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" + }, + "id": "test-request-id", + "imp": [ { - "adTypes": [2730], - "divName": "test-imp-id", - "networkId": 11, - "siteId": 32, - "unitId": 42 + "banner": { + "format": [ + { + "h": 250, + "w": 728 + } + ] + }, + "ext": { + "bidder": { + "networkId": 11, + "siteId": 32, + "unitId": 42 + } + }, + "id": "test-imp-id" } ], - "schain": { - "complete": 0, - "nodes": null, - "ver": "" - }, - "networkId": 11, - "siteId": 32, - "unitId": 42, - "time": 1451651415, - "url": "http://www.some.com/page-where-ad-will-be-shown", - "includePricingData": true, - "user":{}, - "enableBotFiltering": true, - "parallel": true + "site": { + "domain": "www.some.com", + "page": "http://www.some.com/page-where-ad-will-be-shown" + } } }, "mockResponse": { "status": 200, "body": { - "decisions": { - "test-imp-id": { - "adId": 1234567890, - "pricing": { - "clearPrice": 0.5 - }, - "width": 728, - "height": 250, - "impressionUrl": "http://localhost:8080/shown", - "contents" : [ + "id": "test-request-id", + "seatbid": [ + { + "seat": "bmtm", + "bid": [ { - "body": "Remember this: https://www.google.com/search?q=blink+tag ?" + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "mtype": 1 } - ], - "adomain": ["consumabletv.com"], - "cats": ["IAB1", "IAB2"] + ] } - } + ], + "cur": "USD" } } } @@ -109,16 +93,14 @@ "bids": [ { "bid": { - "id": "test-request-id", + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", "price": 0.5, - "adm": "Remember this: https://www.google.com/search?q=blink+tag ?", - "crid": "1234567890", - "exp": 30, + "adm": "some-test-ad", + "crid": "crid_10", "w": 728, - "h": 250, - "adomain": ["consumabletv.com"], - "cat": ["IAB1", "IAB2"] + "h": 90, + "mtype": 1 }, "type": "banner" } diff --git a/adapters/consumable/consumable/supplemental/simple-banner-no-impressionUrl.json b/adapters/consumable/consumable/supplemental/simple-banner-no-impressionUrl.json index 6e9787ee163..fddf160a548 100644 --- a/adapters/consumable/consumable/supplemental/simple-banner-no-impressionUrl.json +++ b/adapters/consumable/consumable/supplemental/simple-banner-no-impressionUrl.json @@ -5,7 +5,12 @@ { "id": "test-no-impUrl-id", "banner": { - "format": [{"w": 300, "h": 250}] + "format": [ + { + "w": 300, + "h": 250 + } + ] }, "ext": { "bidder": { @@ -30,104 +35,87 @@ "buyeruid": "azk-user-id" } }, - "httpCalls": [ { "expectedRequest": { - "headers": { - "Accept": [ - "application/json" - ], - "Content-Type": [ - "application/json" - ], - "Cookie": [ - "azk=azk-user-id" - ], - "User-Agent": [ - "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" - ], - "X-Forwarded-For": [ - "123.123.123.123" - ], - "Forwarded": [ - "for=123.123.123.123" - ], - "Origin": [ - "http://www.some.com" - ], - "Referer": [ - "http://www.some.com/page-where-ad-will-be-shown" - ] - }, - "uri": "https://e.serverbid.com/api/v2", + "uri": "https://e.serverbid.com/sb/rtb", "body": { - "placements": [ + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" + }, + "id": "test-request-id", + "imp": [ { - "adTypes": [5], - "divName": "test-no-impUrl-id", - "networkId": 11, - "siteId": 32, - "unitId": 42, - "unitName": "the-answer" + "banner": { + "format": [ + { + "h": 250, + "w": 300 + } + ] + }, + "ext": { + "bidder": { + "networkId": 11, + "siteId": 32, + "unitId": 42, + "unitName": "the-answer" + } + }, + "id": "test-no-impUrl-id" } ], - "schain": { - "complete": 0, - "nodes": null, - "ver": "" + "site": { + "domain": "www.some.com", + "page": "http://www.some.com/page-where-ad-will-be-shown", + "ref": "http://www.some.com/page-before-the-ad-if-any" }, - "networkId": 11, - "siteId": 32, - "unitId": 42, - "unitName": "the-answer", - "time": 1451651415, - "includePricingData": true, - "user":{}, - "enableBotFiltering": true, - "parallel": true, - "url": "http://www.some.com/page-where-ad-will-be-shown", - "referrer": "http://www.some.com/page-before-the-ad-if-any" + "user": { + "buyeruid": "azk-user-id" + } } }, "mockResponse": { "status": 200, "body": { - "decisions": { - "test-no-impUrl-id": { - "adId": 1234567890, - "bidderName": "aol", - "pricing": { - "clearPrice": 0.5 - }, - "width": 300, - "height": 250, - "contents" : [ + "id": "test-request-id", + "seatbid": [ + { + "seat": "bmtm", + "bid": [ { - "body": "Remember this: https://www.google.com/search?q=blink+tag ?" + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "mtype": 1 } ] } - } + ], + "cur": "USD" } } } ], - "expectedBidResponses": [ { "currency": "USD", "bids": [ { "bid": { - "id": "test-request-id", - "crid": "1234567890", - "impid": "test-no-impUrl-id", + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", "price": 0.5, - "adm": "Remember this: https://www.google.com/search?q=blink+tag ?", - "exp": 30, - "w": 300, - "h": 250 + "adm": "some-test-ad", + "crid": "crid_10", + "w": 728, + "h": 90, + "mtype": 1 }, "type": "banner" } diff --git a/adapters/consumable/consumable/supplemental/simple-banner-no-params.json b/adapters/consumable/consumable/supplemental/simple-banner-no-params.json new file mode 100644 index 00000000000..03d1ca9ce3e --- /dev/null +++ b/adapters/consumable/consumable/supplemental/simple-banner-no-params.json @@ -0,0 +1,43 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + + } + } + } + ], + "device": { + "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36", + "ip": "123.123.123.123", + "geo": { + "country": "USA", + "region": "IL", + "city": "Elgin", + "zip": "60123" + } + }, + "site": { + "domain": "www.some.com", + "page": "http://www.some.com/page-where-ad-will-be-shown" + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "SiteId, NetworkId and UnitId are all required for site requests", + "comparison": "literal" + } + ] +} diff --git a/adapters/consumable/consumable/supplemental/simple-banner-schain.json b/adapters/consumable/consumable/supplemental/simple-banner-schain.json index 0b963a507e7..c3491e6d1e0 100644 --- a/adapters/consumable/consumable/supplemental/simple-banner-schain.json +++ b/adapters/consumable/consumable/supplemental/simple-banner-schain.json @@ -5,7 +5,12 @@ { "id": "test-imp-id", "banner": { - "format": [{"w": 728, "h": 250}] + "format": [ + { + "w": 728, + "h": 250 + } + ] }, "ext": { "bidder": { @@ -43,81 +48,76 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://e.serverbid.com/api/v2", - "headers": { - "Accept": [ - "application/json" - ], - "Content-Type": [ - "application/json" - ], - "User-Agent": [ - "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" - ], - "X-Forwarded-For": [ - "123.123.123.123" - ], - "Forwarded": [ - "for=123.123.123.123" - ], - "Origin": [ - "http://www.some.com" - ], - "Referer": [ - "http://www.some.com/page-where-ad-will-be-shown" - ] - }, + "uri": "https://e.serverbid.com/sb/rtb", "body": { - "placements": [ + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" + }, + "id": "test-request-id", + "imp": [ { - "adTypes": [2730], - "divName": "test-imp-id", - "networkId": 11, - "siteId": 32, - "unitId": 42 + "banner": { + "format": [ + { + "h": 250, + "w": 728 + } + ] + }, + "ext": { + "bidder": { + "networkId": 11, + "siteId": 32, + "unitId": 42 + } + }, + "id": "test-imp-id" } ], - "networkId": 11, - "siteId": 32, - "unitId": 42, - "time": 1451651415, - "url": "http://www.some.com/page-where-ad-will-be-shown", - "includePricingData": true, - "user":{}, - "enableBotFiltering": true, - "parallel": true, - "schain": { - "complete": 1, - "nodes": [ - { - "asi": "indirectseller.com", - "hp": 1, - "sid": "00001" + "site": { + "domain": "www.some.com", + "page": "http://www.some.com/page-where-ad-will-be-shown" + }, + "source": { + "ext": { + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "indirectseller.com", + "hp": 1, + "sid": "00001" + } + ], + "ver": "1.0" } - ], - "ver": "1.0" + } } } }, "mockResponse": { "status": 200, "body": { - "decisions": { - "test-imp-id": { - "adId": 1234567890, - "pricing": { - "clearPrice": 0.5 - }, - "width": 728, - "height": 250, - "impressionUrl": "http://localhost:8080/shown", - "contents" : [ + "id": "test-request-id", + "seatbid": [ + { + "seat": "bmtm", + "bid": [ { - "body": "Remember this: https://www.google.com/search?q=blink+tag ?" + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "mtype": 1 } ] } - } + ], + "cur": "USD" } } } @@ -128,14 +128,14 @@ "bids": [ { "bid": { - "id": "test-request-id", + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", "price": 0.5, - "adm": "Remember this: https://www.google.com/search?q=blink+tag ?", - "crid": "1234567890", - "exp": 30, + "adm": "some-test-ad", + "crid": "crid_10", "w": 728, - "h": 250 + "h": 90, + "mtype": 1 }, "type": "banner" } diff --git a/adapters/consumable/consumable/supplemental/simple-banner-us-privacy.json b/adapters/consumable/consumable/supplemental/simple-banner-us-privacy.json index c09200c4bd3..bf27672805c 100644 --- a/adapters/consumable/consumable/supplemental/simple-banner-us-privacy.json +++ b/adapters/consumable/consumable/supplemental/simple-banner-us-privacy.json @@ -5,7 +5,12 @@ { "id": "test-imp-id", "banner": { - "format": [{"w": 728, "h": 250}] + "format": [ + { + "w": 728, + "h": 250 + } + ] }, "ext": { "bidder": { @@ -33,76 +38,66 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://e.serverbid.com/api/v2", - "headers": { - "Accept": [ - "application/json" - ], - "Content-Type": [ - "application/json" - ], - "User-Agent": [ - "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" - ], - "X-Forwarded-For": [ - "123.123.123.123" - ], - "Forwarded": [ - "for=123.123.123.123" - ], - "Origin": [ - "http://www.some.com" - ], - "Referer": [ - "http://www.some.com/page-where-ad-will-be-shown" - ] - }, + "uri": "https://e.serverbid.com/sb/rtb", "body": { - "placements": [ + "device": { + "ip": "123.123.123.123", + "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36" + }, + "id": "test-request-id", + "imp": [ { - "adTypes": [2730], - "divName": "test-imp-id", - "networkId": 11, - "siteId": 32, - "unitId": 42 + "banner": { + "format": [ + { + "h": 250, + "w": 728 + } + ] + }, + "ext": { + "bidder": { + "networkId": 11, + "siteId": 32, + "unitId": 42 + } + }, + "id": "test-imp-id" } ], - "schain": { - "complete": 0, - "nodes": null, - "ver": "" + "site": { + "domain": "www.some.com", + "page": "http://www.some.com/page-where-ad-will-be-shown" }, - "networkId": 11, - "siteId": 32, - "unitId": 42, - "time": 1451651415, - "url": "http://www.some.com/page-where-ad-will-be-shown", - "includePricingData": true, - "user":{}, - "enableBotFiltering": true, - "parallel": true, - "ccpa": "1NYN" + "regs": { + "ext": { + "us_privacy": "1NYN" + } + } } }, "mockResponse": { "status": 200, "body": { - "decisions": { - "test-imp-id": { - "adId": 1234567890, - "pricing": { - "clearPrice": 0.5 - }, - "width": 728, - "height": 250, - "impressionUrl": "http://localhost:8080/shown", - "contents" : [ + "id": "test-request-id", + "seatbid": [ + { + "seat": "bmtm", + "bid": [ { - "body": "Remember this: https://www.google.com/search?q=blink+tag ?" + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "mtype": 1 } ] } - } + ], + "cur": "USD" } } } @@ -113,14 +108,14 @@ "bids": [ { "bid": { - "id": "test-request-id", + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", "price": 0.5, - "adm": "Remember this: https://www.google.com/search?q=blink+tag ?", - "crid": "1234567890", - "exp": 30, + "adm": "some-test-ad", + "crid": "crid_10", "w": 728, - "h": 250 + "h": 90, + "mtype": 1 }, "type": "banner" } diff --git a/adapters/consumable/consumable/supplemental/unknown-status-code-example.json b/adapters/consumable/consumable/supplemental/unknown-status-code-example.json new file mode 100644 index 00000000000..58fafcff6b2 --- /dev/null +++ b/adapters/consumable/consumable/supplemental/unknown-status-code-example.json @@ -0,0 +1,78 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "placementId": "0421008445828ceb46f496700a5fa65e" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://e.serverbid.com/rtb/bid?s=0421008445828ceb46f496700a5fa65e", + "body": { + "id": "test-request-id", + "app": { + "id": "1", + "bundle": "com.foo.bar" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36", + "ip": "73.55.27.72" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "placementId": "0421008445828ceb46f496700a5fa65e" + } + } + } + ] + } + }, + "mockResponse": { + "status": 301, + "body": { + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 301. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/consumable/consumable_test.go b/adapters/consumable/consumable_test.go index e3bedce5e2f..75e69535f20 100644 --- a/adapters/consumable/consumable_test.go +++ b/adapters/consumable/consumable_test.go @@ -1,14 +1,14 @@ package consumable import ( - "testing" - "time" - + "encoding/json" + "github.com/prebid/openrtb/v19/adcom1" + "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/v2/adapters" "github.com/prebid/prebid-server/v2/adapters/adapterstest" "github.com/prebid/prebid-server/v2/config" "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/stretchr/testify/assert" + "testing" ) func TestJsonSamples(t *testing.T) { @@ -19,18 +19,75 @@ func TestJsonSamples(t *testing.T) { t.Fatalf("Builder returned unexpected error %v", buildErr) } - assertClock(t, bidder) - replaceClockWithKnownTime(bidder) - adapterstest.RunJSONBidderTest(t, "consumable", bidder) } -func assertClock(t *testing.T, bidder adapters.Bidder) { - bidderConsumable, _ := bidder.(*ConsumableAdapter) - assert.NotNil(t, bidderConsumable.clock) -} +func TestConsumableMakeBidsWithCategoryDuration(t *testing.T) { + bidder := &adapter{} + + mockedReq := &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{ + ID: "1_1", + Video: &openrtb2.Video{ + W: 640, + H: 360, + MIMEs: []string{"video/mp4"}, + MaxDuration: 60, + Protocols: []adcom1.MediaCreativeSubtype{2, 3, 5, 6}, + }, + Ext: json.RawMessage( + `{ + "prebid": {}, + "bidder": { + "placementId": "123456" + } + }`, + )}, + }, + } + mockedExtReq := &adapters.RequestData{} + mockedBidResponse := &openrtb2.BidResponse{ + ID: "test-1", + SeatBid: []openrtb2.SeatBid{{ + Seat: "Buyer", + Bid: []openrtb2.Bid{{ + ID: "1", + ImpID: "1_1", + Price: 1.23, + AdID: "123", + Cat: []string{"IAB18-1"}, + Dur: 30, + MType: openrtb2.MarkupVideo, + }}, + }}, + } + body, _ := json.Marshal(mockedBidResponse) + mockedRes := &adapters.ResponseData{ + StatusCode: 200, + Body: body, + } + + expectedBidCount := 1 + expectedBidType := openrtb_ext.BidTypeVideo + expectedBidDuration := 30 + expectedBidCategory := "IAB18-1" + expectedErrorCount := 0 -func replaceClockWithKnownTime(bidder adapters.Bidder) { - bidderConsumable, _ := bidder.(*ConsumableAdapter) - bidderConsumable.clock = knownInstant(time.Date(2016, 1, 1, 12, 30, 15, 0, time.UTC)) + bidResponse, errors := bidder.MakeBids(mockedReq, mockedExtReq, mockedRes) + + if len(bidResponse.Bids) != expectedBidCount { + t.Errorf("should have 1 bid, bids=%v", bidResponse.Bids) + } + if bidResponse.Bids[0].BidType != expectedBidType { + t.Errorf("bid type should be video, bidType=%s", bidResponse.Bids[0].BidType) + } + if bidResponse.Bids[0].BidVideo.Duration != expectedBidDuration { + t.Errorf("video duration should be set") + } + if bidResponse.Bids[0].Bid.Cat[0] != expectedBidCategory { + t.Errorf("bid category should be set") + } + if len(errors) != expectedErrorCount { + t.Errorf("should not have any errors, errors=%v", errors) + } } diff --git a/adapters/consumable/instant.go b/adapters/consumable/instant.go deleted file mode 100644 index a6162d44e22..00000000000 --- a/adapters/consumable/instant.go +++ /dev/null @@ -1,21 +0,0 @@ -package consumable - -import "time" - -type instant interface { - Now() time.Time -} - -// Send a real instance when you construct it in adapter_map.go -type realInstant struct{} - -func (realInstant) Now() time.Time { - return time.Now() -} - -// Use this for tests e.g. knownInstant(time.Date(y, m, ..., time.UTC)) -type knownInstant time.Time - -func (i knownInstant) Now() time.Time { - return time.Time(i) -} diff --git a/adapters/consumable/params_test.go b/adapters/consumable/params_test.go index fdb3edec41b..99a993e9752 100644 --- a/adapters/consumable/params_test.go +++ b/adapters/consumable/params_test.go @@ -43,6 +43,7 @@ var validParams = []string{ `{"networkId": 22, "siteId": 1, "unitId": 101, "unitName": "unit-1"}`, `{"networkId": 22, "siteId": 1, "unitId": 101, "unitName": "-unit-1"}`, // unitName can start with a dash `{"networkId": 22, "siteId": 1, "unitId": 101}`, // unitName can be omitted (although prebid.js doesn't allow that) + `{"placementId": "abcdjk232"}`, } var invalidParams = []string{ @@ -56,4 +57,5 @@ var invalidParams = []string{ `{"siteId": 1, "unitId": 101, "unitName": 11}`, // networkId must be present `{"networkId": 22, "unitId": 101, "unitName": 11}`, // siteId must be present `{"siteId": 1, "networkId": 22, "unitName": 11}`, // unitId must be present + `{"placementId": "---abjk;jkewj;k;jwejklfs}`, // placementId must be alphanumeric } diff --git a/adapters/consumable/retrieveAd.go b/adapters/consumable/retrieveAd.go deleted file mode 100644 index 7f69a1bbc23..00000000000 --- a/adapters/consumable/retrieveAd.go +++ /dev/null @@ -1,10 +0,0 @@ -package consumable - -func retrieveAd(decision decision) string { - - if decision.Contents != nil && len(decision.Contents) > 0 { - return decision.Contents[0].Body - } - - return "" -} diff --git a/openrtb_ext/imp_consumable.go b/openrtb_ext/imp_consumable.go index fe916b09972..8158b41d2cc 100644 --- a/openrtb_ext/imp_consumable.go +++ b/openrtb_ext/imp_consumable.go @@ -6,5 +6,6 @@ type ExtImpConsumable struct { SiteId int `json:"siteId,omitempty"` UnitId int `json:"unitId,omitempty"` /* UnitName gets used as a classname and in the URL when building the ad markup */ - UnitName string `json:"unitName,omitempty"` + UnitName string `json:"unitName,omitempty"` + PlacementId string `json:"placementid,omitempty"` } diff --git a/static/bidder-info/consumable.yaml b/static/bidder-info/consumable.yaml index cc290149be2..0f240e87942 100644 --- a/static/bidder-info/consumable.yaml +++ b/static/bidder-info/consumable.yaml @@ -2,10 +2,13 @@ endpoint: "https://e.serverbid.com/api/v2" maintainer: email: "prebid@consumable.com" gvlVendorID: 591 +endpointCompression: gzip capabilities: app: mediaTypes: - banner + - video + - audio site: mediaTypes: - banner diff --git a/static/bidder-params/consumable.json b/static/bidder-params/consumable.json index b1db53568b9..7709ab09d37 100644 --- a/static/bidder-params/consumable.json +++ b/static/bidder-params/consumable.json @@ -24,7 +24,15 @@ "type": "string", "description": "The unit name from Consumable (expected to be a valid CSS class name)", "pattern": "^-?[_a-zA-Z]+[_a-zA-Z0-9-]*$" + }, + "placementId": { + "type": "string", + "description": "The placementID from Consumable, Required for non-site requests", + "pattern": "^[a-zA-Z0-9]+$" } }, - "required": ["siteId", "networkId","unitId"] + "oneOf": [ + {"required": ["siteId", "networkId","unitId"] }, + {"required": ["placementId"] } + ] } From 2e7f73a566622ad1cea970100e348029d838866d Mon Sep 17 00:00:00 2001 From: Brian Sardo <1168933+bsardo@users.noreply.github.com> Date: Wed, 3 Jan 2024 13:29:38 -0500 Subject: [PATCH 260/268] Fix: increase tmax in flakey modularity test (#3370) --- .../openrtb2/sample-requests/hooks/auction_bidder_reject.json | 2 +- .../sample-requests/hooks/auction_bidder_response_reject.json | 2 +- .../sample-requests/hooks/auction_entrypoint_reject.json | 2 +- .../hooks/auction_processed_auction_request_reject.json | 2 +- .../hooks/auction_raw_auction_request_reject.json | 2 +- endpoints/openrtb2/test_utils.go | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/endpoints/openrtb2/sample-requests/hooks/auction_bidder_reject.json b/endpoints/openrtb2/sample-requests/hooks/auction_bidder_reject.json index 94769e4f6cd..0bc86e4c4a5 100644 --- a/endpoints/openrtb2/sample-requests/hooks/auction_bidder_reject.json +++ b/endpoints/openrtb2/sample-requests/hooks/auction_bidder_reject.json @@ -32,7 +32,7 @@ } } ], - "tmax": 50, + "tmax": 500, "test": 1, "ext": { "prebid": { diff --git a/endpoints/openrtb2/sample-requests/hooks/auction_bidder_response_reject.json b/endpoints/openrtb2/sample-requests/hooks/auction_bidder_response_reject.json index 6198e3e23bc..16a7f43c87a 100644 --- a/endpoints/openrtb2/sample-requests/hooks/auction_bidder_response_reject.json +++ b/endpoints/openrtb2/sample-requests/hooks/auction_bidder_response_reject.json @@ -32,7 +32,7 @@ } } ], - "tmax": 50, + "tmax": 500, "test": 1, "ext": { "prebid": { diff --git a/endpoints/openrtb2/sample-requests/hooks/auction_entrypoint_reject.json b/endpoints/openrtb2/sample-requests/hooks/auction_entrypoint_reject.json index c67b8d4b490..3481b986bc3 100644 --- a/endpoints/openrtb2/sample-requests/hooks/auction_entrypoint_reject.json +++ b/endpoints/openrtb2/sample-requests/hooks/auction_entrypoint_reject.json @@ -28,7 +28,7 @@ } } ], - "tmax": 50, + "tmax": 500, "ext": { "prebid": { "trace": "verbose" diff --git a/endpoints/openrtb2/sample-requests/hooks/auction_processed_auction_request_reject.json b/endpoints/openrtb2/sample-requests/hooks/auction_processed_auction_request_reject.json index eca136cf75f..4c160dec007 100644 --- a/endpoints/openrtb2/sample-requests/hooks/auction_processed_auction_request_reject.json +++ b/endpoints/openrtb2/sample-requests/hooks/auction_processed_auction_request_reject.json @@ -28,7 +28,7 @@ } } ], - "tmax": 50, + "tmax": 500, "ext": { "prebid": { "trace": "verbose" diff --git a/endpoints/openrtb2/sample-requests/hooks/auction_raw_auction_request_reject.json b/endpoints/openrtb2/sample-requests/hooks/auction_raw_auction_request_reject.json index dc192baffee..ed284e6687d 100644 --- a/endpoints/openrtb2/sample-requests/hooks/auction_raw_auction_request_reject.json +++ b/endpoints/openrtb2/sample-requests/hooks/auction_raw_auction_request_reject.json @@ -28,7 +28,7 @@ } } ], - "tmax": 50, + "tmax": 500, "ext": { "prebid": { "trace": "verbose" diff --git a/endpoints/openrtb2/test_utils.go b/endpoints/openrtb2/test_utils.go index e3e7803e551..a0ac836e30e 100644 --- a/endpoints/openrtb2/test_utils.go +++ b/endpoints/openrtb2/test_utils.go @@ -1579,7 +1579,7 @@ var entryPointHookUpdate = hooks.HookWrapper[hookstage.Entrypoint]{ ch := hookstage.ChangeSet[hookstage.EntrypointPayload]{} ch.AddMutation(func(payload hookstage.EntrypointPayload) (hookstage.EntrypointPayload, error) { - body, err := jsonpatch.MergePatch(payload.Body, []byte(`{"tmax":50}`)) + body, err := jsonpatch.MergePatch(payload.Body, []byte(`{"tmax":600}`)) if err == nil { payload.Body = body } From bd483bb8f838593566463bb1a418cbe75df23d05 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Jan 2024 13:41:32 -0500 Subject: [PATCH 261/268] Bump golang.org/x/crypto from 0.14.0 to 0.17.0 (#3361) --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index ac394a6742c..9a55cddb00a 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/xeipuuv/gojsonschema v1.2.0 github.com/yudai/gojsondiff v1.0.0 golang.org/x/net v0.17.0 - golang.org/x/text v0.13.0 + golang.org/x/text v0.14.0 google.golang.org/grpc v1.56.3 gopkg.in/evanphx/json-patch.v4 v4.12.0 gopkg.in/yaml.v3 v3.0.1 @@ -70,8 +70,8 @@ require ( github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect github.com/yudai/pp v2.0.1+incompatible // indirect - golang.org/x/crypto v0.14.0 // indirect - golang.org/x/sys v0.13.0 // indirect + golang.org/x/crypto v0.17.0 // indirect + golang.org/x/sys v0.15.0 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/ini.v1 v1.66.4 // indirect diff --git a/go.sum b/go.sum index 6331beb3287..ad2d5ba94b8 100644 --- a/go.sum +++ b/go.sum @@ -530,8 +530,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -728,8 +728,8 @@ golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -742,8 +742,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 98b0f349dba1d77b8b8d38e1366deca4a106d942 Mon Sep 17 00:00:00 2001 From: Eugene <73837230+orlov-e@users.noreply.github.com> Date: Thu, 4 Jan 2024 13:11:23 +0200 Subject: [PATCH 262/268] smartyads: added vendor id to spec (#3383) --- static/bidder-info/smartyads.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/static/bidder-info/smartyads.yaml b/static/bidder-info/smartyads.yaml index b36983bc7b1..21b8a0a11d6 100644 --- a/static/bidder-info/smartyads.yaml +++ b/static/bidder-info/smartyads.yaml @@ -1,6 +1,7 @@ endpoint: "http://{{.Host}}.smartyads.com/bid?rtb_seat_id={{.SourceId}}&secret_key={{.AccountID}}" maintainer: email: "support@smartyads.com" +gvlVendorID: 534 capabilities: app: mediaTypes: From 0f89ed6dd370f42e7a72aa584f4b48a26789c877 Mon Sep 17 00:00:00 2001 From: svamiftah <125688973+svamiftah@users.noreply.github.com> Date: Thu, 4 Jan 2024 11:15:48 +0000 Subject: [PATCH 263/268] New Adapter: SovrnXSP (#3312) --- adapters/sovrnXsp/params_test.go | 56 ++++++ adapters/sovrnXsp/sovrnXsp.go | 172 ++++++++++++++++++ adapters/sovrnXsp/sovrnXsp_test.go | 20 ++ .../sovrnXsptest/exemplary/banner.json | 119 ++++++++++++ .../sovrnXsptest/exemplary/native.json | 109 +++++++++++ .../sovrnXsptest/exemplary/video.json | 121 ++++++++++++ .../supplemental/request-no-matching-imp.json | 30 +++ .../supplemental/response-empty-seat.json | 82 +++++++++ .../supplemental/response-http-error.json | 84 +++++++++ .../supplemental/response-invalid-crtype.json | 103 +++++++++++ .../supplemental/response-nobid.json | 79 ++++++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_sovrnXsp.go | 8 + static/bidder-info/sovrnXsp.yaml | 12 ++ static/bidder-params/sovrnXsp.json | 27 +++ 16 files changed, 1026 insertions(+) create mode 100644 adapters/sovrnXsp/params_test.go create mode 100644 adapters/sovrnXsp/sovrnXsp.go create mode 100644 adapters/sovrnXsp/sovrnXsp_test.go create mode 100644 adapters/sovrnXsp/sovrnXsptest/exemplary/banner.json create mode 100644 adapters/sovrnXsp/sovrnXsptest/exemplary/native.json create mode 100644 adapters/sovrnXsp/sovrnXsptest/exemplary/video.json create mode 100644 adapters/sovrnXsp/sovrnXsptest/supplemental/request-no-matching-imp.json create mode 100644 adapters/sovrnXsp/sovrnXsptest/supplemental/response-empty-seat.json create mode 100644 adapters/sovrnXsp/sovrnXsptest/supplemental/response-http-error.json create mode 100644 adapters/sovrnXsp/sovrnXsptest/supplemental/response-invalid-crtype.json create mode 100644 adapters/sovrnXsp/sovrnXsptest/supplemental/response-nobid.json create mode 100644 openrtb_ext/imp_sovrnXsp.go create mode 100644 static/bidder-info/sovrnXsp.yaml create mode 100644 static/bidder-params/sovrnXsp.json diff --git a/adapters/sovrnXsp/params_test.go b/adapters/sovrnXsp/params_test.go new file mode 100644 index 00000000000..cca8b22cf51 --- /dev/null +++ b/adapters/sovrnXsp/params_test.go @@ -0,0 +1,56 @@ +package sovrnXsp + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + + if err != nil { + t.Fatalf("Failed to fetch json-schemas. %v", err) + } + + for _, param := range validParams { + if err := validator.Validate(openrtb_ext.BidderSovrnXsp, json.RawMessage(param)); err != nil { + t.Errorf("Schema rejected sovrnXsp params: %s", param) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + + if err != nil { + t.Fatalf("Failed to fetch json-schemas. %v", err) + } + + for _, param := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderSovrnXsp, json.RawMessage(param)); err == nil { + t.Errorf("Schema allowed sovrnXsp params: %s", param) + } + } +} + +var validParams = []string{ + `{"pub_id":"1234"}`, + `{"pub_id":"1234","med_id":"1234"}`, + `{"pub_id":"1234","med_id":"1234","zone_id":"abcdefghijklmnopqrstuvwxyz"}`, + `{"pub_id":"1234","med_id":"1234","zone_id":"abcdefghijklmnopqrstuvwxyz","force_bid":true}`, + `{"pub_id":"1234","med_id":"1234","zone_id":"abcdefghijklmnopqrstuvwxyz","force_bid":false}`, +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `0`, + `[]`, + `{}`, + `{"pub_id":""}`, + `{"pub_id":"123"}`, + `{"pub_id":"1234","zone_id":"123"}`, +} diff --git a/adapters/sovrnXsp/sovrnXsp.go b/adapters/sovrnXsp/sovrnXsp.go new file mode 100644 index 00000000000..a026f888c72 --- /dev/null +++ b/adapters/sovrnXsp/sovrnXsp.go @@ -0,0 +1,172 @@ +package sovrnXsp + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" + + "github.com/prebid/openrtb/v19/openrtb2" +) + +type adapter struct { + Endpoint string +} + +// bidExt.CreativeType values. +const ( + creativeTypeBanner int = 0 + creativeTypeVideo = 1 + creativeTypeNative = 2 + creativeTypeAudio = 3 +) + +// Bid response extension from XSP. +type bidExt struct { + CreativeType int `json:"creative_type"` +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + appCopy := *request.App + if appCopy.Publisher == nil { + appCopy.Publisher = &openrtb2.Publisher{} + } else { + publisherCopy := *appCopy.Publisher + appCopy.Publisher = &publisherCopy + } + request.App = &appCopy + + var errors []error + var imps []openrtb2.Imp + + for idx, imp := range request.Imp { + if imp.Banner == nil && imp.Video == nil && imp.Native == nil { + continue + } + + var bidderExt adapters.ExtImpBidder + if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + err = &errortypes.BadInput{ + Message: fmt.Sprintf("imp #%d: ext.bidder not provided", idx), + } + errors = append(errors, err) + continue + } + + var xspExt openrtb_ext.ExtImpSovrnXsp + if err := json.Unmarshal(bidderExt.Bidder, &xspExt); err != nil { + err = &errortypes.BadInput{ + Message: fmt.Sprintf("imp #%d: %s", idx, err.Error()), + } + errors = append(errors, err) + continue + } + + request.App.Publisher.ID = xspExt.PubID + if xspExt.MedID != "" { + request.App.ID = xspExt.MedID + } + if xspExt.ZoneID != "" { + imp.TagID = xspExt.ZoneID + } + imps = append(imps, imp) + } + + if len(imps) == 0 { + return nil, append(errors, &errortypes.BadInput{ + Message: "no matching impression with ad format", + }) + } + + request.Imp = imps + requestJson, err := json.Marshal(request) + if err != nil { + return nil, append(errors, err) + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + headers.Add("x-openrtb-version", "2.5") + + return []*adapters.RequestData{{ + Method: "POST", + Uri: a.Endpoint, + Body: requestJson, + Headers: headers, + }}, errors +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} + } + + var response openrtb2.BidResponse + if err := json.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + var errors []error + result := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + + for _, seatBid := range response.SeatBid { + for _, bid := range seatBid.Bid { + bid := bid + var ext bidExt + if err := json.Unmarshal(bid.Ext, &ext); err != nil { + errors = append(errors, err) + continue + } + + var bidType openrtb_ext.BidType + var mkupType openrtb2.MarkupType + switch ext.CreativeType { + case creativeTypeBanner: + bidType = openrtb_ext.BidTypeBanner + mkupType = openrtb2.MarkupBanner + case creativeTypeVideo: + bidType = openrtb_ext.BidTypeVideo + mkupType = openrtb2.MarkupVideo + case creativeTypeNative: + bidType = openrtb_ext.BidTypeNative + mkupType = openrtb2.MarkupNative + default: + errors = append(errors, &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unsupported creative type: %d", ext.CreativeType), + }) + continue + } + + if bid.MType == 0 { + bid.MType = mkupType + } + + result.Bids = append(result.Bids, &adapters.TypedBid{ + Bid: &bid, + BidType: bidType, + }) + } + } + + if len(result.Bids) == 0 { + // it's possible an empty seat array was sent as a response + return nil, errors + } + return result, errors +} + +// Builder builds a new instance of the SovrnXSP adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + Endpoint: config.Endpoint, + } + return bidder, nil +} diff --git a/adapters/sovrnXsp/sovrnXsp_test.go b/adapters/sovrnXsp/sovrnXsp_test.go new file mode 100644 index 00000000000..4c93fc39fa8 --- /dev/null +++ b/adapters/sovrnXsp/sovrnXsp_test.go @@ -0,0 +1,20 @@ +package sovrnXsp + +import ( + "testing" + + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderSovrnXsp, config.Adapter{ + Endpoint: "http://xsp.lijit.com/json/rtb/prebid/server"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "sovrnXsptest", bidder) +} diff --git a/adapters/sovrnXsp/sovrnXsptest/exemplary/banner.json b/adapters/sovrnXsp/sovrnXsptest/exemplary/banner.json new file mode 100644 index 00000000000..08f36adb91b --- /dev/null +++ b/adapters/sovrnXsp/sovrnXsptest/exemplary/banner.json @@ -0,0 +1,119 @@ +{ + "mockBidRequest": { + "id": "abc", + "app": { + "id": "0jqCuiqHfPDHAHrdFfGG", + "bundle": "test", + "publisher": { + "id": "sovrn" + } + }, + "imp": [ + { + "id": "imp123", + "bidfloor": 1.0, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pub_id": "sovrn", + "med_id": "0jqCuiqHfPDHAHrdFfGG", + "zone_id": "FgUtQqop18uf1I2fwDie" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://xsp.lijit.com/json/rtb/prebid/server", + "body":{ + "id": "abc", + "app": { + "id": "0jqCuiqHfPDHAHrdFfGG", + "bundle": "test", + "publisher": { + "id": "sovrn" + } + }, + "imp": [{ + "id": "imp123", + "tagid": "FgUtQqop18uf1I2fwDie", + "bidfloor": 1.0, + "banner": { + "format": [{ + "w": 300, + "h": 250 + }], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pub_id": "sovrn", + "med_id": "0jqCuiqHfPDHAHrdFfGG", + "zone_id": "FgUtQqop18uf1I2fwDie" + } + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "abc", + "seatbid": [ + { + "bid": [ + { + "adm": "
", + "crid": "test_banner_crid", + "cid": "test_cid", + "impid": "imp123", + "id": "1", + "price": 1.0, + "ext": { + "creative_type": 0 + } + } + ] + } + ] + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "adm": "", + "crid": "test_banner_crid", + "cid": "test_cid", + "impid": "imp123", + "price": 1.0, + "id": "1", + "mtype": 1, + "ext": { + "creative_type": 0 + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/sovrnXsp/sovrnXsptest/exemplary/native.json b/adapters/sovrnXsp/sovrnXsptest/exemplary/native.json new file mode 100644 index 00000000000..f82297e3bb2 --- /dev/null +++ b/adapters/sovrnXsp/sovrnXsptest/exemplary/native.json @@ -0,0 +1,109 @@ +{ + "mockBidRequest": { + "id": "abc", + "app": { + "id": "0jqCuiqHfPDHAHrdFfGG", + "bundle": "test", + "publisher": { + "id": "sovrn" + } + }, + "imp": [ + { + "id": "imp123", + "bidfloor": 1.0, + "native": { + "ver": "1.2", + "request": "{\"context\":1,\"plcmttype\":1,\"assets\":[{\"id\":0,\"required\":1,\"img\":{\"type\":3,\"w\":300,\"h\":250}},{\"id\":1,\"required\":1,\"title\":{\"len\":140}},{\"id\":2,\"data\":{\"type\":1}}],\"eventtrackers\":[{\"event\":1,\"methods\":[1]}]}" + }, + "ext": { + "bidder": { + "pub_id": "sovrn", + "med_id": "0jqCuiqHfPDHAHrdFfGG", + "zone_id": "FgUtQqop18uf1I2fwDie" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://xsp.lijit.com/json/rtb/prebid/server", + "body":{ + "id": "abc", + "app": { + "id": "0jqCuiqHfPDHAHrdFfGG", + "bundle": "test", + "publisher": { + "id": "sovrn" + } + }, + "imp": [{ + "id": "imp123", + "tagid": "FgUtQqop18uf1I2fwDie", + "bidfloor": 1.0, + "native": { + "ver": "1.2", + "request": "{\"context\":1,\"plcmttype\":1,\"assets\":[{\"id\":0,\"required\":1,\"img\":{\"type\":3,\"w\":300,\"h\":250}},{\"id\":1,\"required\":1,\"title\":{\"len\":140}},{\"id\":2,\"data\":{\"type\":1}}],\"eventtrackers\":[{\"event\":1,\"methods\":[1]}]}" + }, + "ext": { + "bidder": { + "pub_id": "sovrn", + "med_id": "0jqCuiqHfPDHAHrdFfGG", + "zone_id": "FgUtQqop18uf1I2fwDie" + } + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "abc", + "seatbid": [ + { + "bid": [ + { + "adm": "{\"ver\":\"1.2\",\"link\":{\"url\":\"https://sovrn.com\"},\"assets\":[{\"id\":0,\"img\":{\"w\":300,\"h\":250,\"url\":\"https://ads.smrtb.com/demo/ads/300x250.png\"}},{\"id\":1,\"title\":{\"text\":\"Test Ad\",\"len\":7}},{\"id\":2,\"data\":{\"value\":\"0\",\"len\":1}}]}", + "crid": "test_native_crid", + "cid": "test_cid", + "impid": "imp123", + "id": "1", + "price": 1.0, + "ext": { + "creative_type": 2 + } + } + ] + } + ] + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "adm": "{\"ver\":\"1.2\",\"link\":{\"url\":\"https://sovrn.com\"},\"assets\":[{\"id\":0,\"img\":{\"w\":300,\"h\":250,\"url\":\"https://ads.smrtb.com/demo/ads/300x250.png\"}},{\"id\":1,\"title\":{\"text\":\"Test Ad\",\"len\":7}},{\"id\":2,\"data\":{\"value\":\"0\",\"len\":1}}]}", + "crid": "test_native_crid", + "cid": "test_cid", + "impid": "imp123", + "price": 1.0, + "id": "1", + "mtype": 4, + "ext": { + "creative_type": 2 + } + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/sovrnXsp/sovrnXsptest/exemplary/video.json b/adapters/sovrnXsp/sovrnXsptest/exemplary/video.json new file mode 100644 index 00000000000..5ba8259f063 --- /dev/null +++ b/adapters/sovrnXsp/sovrnXsptest/exemplary/video.json @@ -0,0 +1,121 @@ +{ + "mockBidRequest": { + "id": "abc", + "app": { + "id": "0jqCuiqHfPDHAHrdFfGG", + "bundle": "test", + "publisher": { + "id": "sovrn" + } + }, + "imp": [ + { + "id": "imp123", + "bidfloor": 1.0, + "video": { + "w": 300, + "h": 250, + "protocols": [1,2,3,4,5,6,7,8], + "playbackmethod": [1], + "mimes": ["video/mp4"], + "skip": 1, + "api": [2], + "maxbitrate": 3000 + }, + "ext": { + "bidder": { + "pub_id": "sovrn", + "med_id": "0jqCuiqHfPDHAHrdFfGG", + "zone_id": "FgUtQqop18uf1I2fwDie" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://xsp.lijit.com/json/rtb/prebid/server", + "body":{ + "id": "abc", + "app": { + "id": "0jqCuiqHfPDHAHrdFfGG", + "bundle": "test", + "publisher": { + "id": "sovrn" + } + }, + "imp": [{ + "id": "imp123", + "bidfloor": 1.0, + "tagid": "FgUtQqop18uf1I2fwDie", + "video": { + "w": 300, + "h": 250, + "protocols": [1,2,3,4,5,6,7,8], + "playbackmethod": [1], + "mimes": ["video/mp4"], + "skip": 1, + "api": [2], + "maxbitrate": 3000 + }, + "ext": { + "bidder": { + "pub_id": "sovrn", + "med_id": "0jqCuiqHfPDHAHrdFfGG", + "zone_id": "FgUtQqop18uf1I2fwDie" + } + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "abc", + "seatbid": [ + { + "bid": [ + { + "adm": "Mc0Sovrn PSA00:00:30", + "crid": "sovrn_psa_crid_1", + "cid": "sovrn_psa", + "impid": "imp123", + "id": "1", + "price": 1.0, + "ext": { + "creative_type": 1 + } + } + ] + } + ] + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "adm": "Mc0Sovrn PSA00:00:30", + "crid": "sovrn_psa_crid_1", + "cid": "sovrn_psa", + "impid": "imp123", + "price": 1.0, + "id": "1", + "mtype": 2, + "ext": { + "creative_type": 1 + } + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/sovrnXsp/sovrnXsptest/supplemental/request-no-matching-imp.json b/adapters/sovrnXsp/sovrnXsptest/supplemental/request-no-matching-imp.json new file mode 100644 index 00000000000..d9719d0a2e1 --- /dev/null +++ b/adapters/sovrnXsp/sovrnXsptest/supplemental/request-no-matching-imp.json @@ -0,0 +1,30 @@ +{ + "mockBidRequest": { + "id": "abc", + "app": { + "id": "0jqCuiqHfPDHAHrdFfGG", + "bundle": "test", + "publisher": { + "id": "sovrn" + } + }, + "imp": [ + { + "id": "imp123", + "bidfloor": 1.0, + "ext": { + "bidder": { + "pub_id": "sovrn", + "med_id": "0jqCuiqHfPDHAHrdFfGG", + "zone_id": "FgUtQqop18uf1I2fwDie" + } + } + } + ] + }, + + "expectedMakeRequestsErrors": [{ + "value": "no matching impression with ad format", + "comparison": "literal" + }] +} diff --git a/adapters/sovrnXsp/sovrnXsptest/supplemental/response-empty-seat.json b/adapters/sovrnXsp/sovrnXsptest/supplemental/response-empty-seat.json new file mode 100644 index 00000000000..0de8fa072f8 --- /dev/null +++ b/adapters/sovrnXsp/sovrnXsptest/supplemental/response-empty-seat.json @@ -0,0 +1,82 @@ +{ + "mockBidRequest": { + "id": "abc", + "app": { + "id": "0jqCuiqHfPDHAHrdFfGG", + "bundle": "test", + "publisher": { + "id": "sovrn" + } + }, + "imp": [ + { + "id": "imp123", + "bidfloor": 1.0, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pub_id": "sovrn", + "med_id": "0jqCuiqHfPDHAHrdFfGG", + "zone_id": "FgUtQqop18uf1I2fwDie" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://xsp.lijit.com/json/rtb/prebid/server", + "body":{ + "id": "abc", + "app": { + "id": "0jqCuiqHfPDHAHrdFfGG", + "bundle": "test", + "publisher": { + "id": "sovrn" + } + }, + "imp": [{ + "id": "imp123", + "tagid": "FgUtQqop18uf1I2fwDie", + "bidfloor": 1.0, + "banner": { + "format": [{ + "w": 300, + "h": 250 + }], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pub_id": "sovrn", + "med_id": "0jqCuiqHfPDHAHrdFfGG", + "zone_id": "FgUtQqop18uf1I2fwDie" + } + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "abc", + "seatbid": [{}] + } + } + } + ], + + "expectedBidResponses": [] +} diff --git a/adapters/sovrnXsp/sovrnXsptest/supplemental/response-http-error.json b/adapters/sovrnXsp/sovrnXsptest/supplemental/response-http-error.json new file mode 100644 index 00000000000..10f647186fd --- /dev/null +++ b/adapters/sovrnXsp/sovrnXsptest/supplemental/response-http-error.json @@ -0,0 +1,84 @@ +{ + "mockBidRequest": { + "id": "abc", + "app": { + "id": "0jqCuiqHfPDHAHrdFfGG", + "bundle": "test", + "publisher": { + "id": "sovrn" + } + }, + "imp": [ + { + "id": "imp123", + "bidfloor": 1.0, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pub_id": "sovrn", + "med_id": "0jqCuiqHfPDHAHrdFfGG", + "zone_id": "FgUtQqop18uf1I2fwDie" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://xsp.lijit.com/json/rtb/prebid/server", + "body":{ + "id": "abc", + "app": { + "id": "0jqCuiqHfPDHAHrdFfGG", + "bundle": "test", + "publisher": { + "id": "sovrn" + } + }, + "imp": [{ + "id": "imp123", + "tagid": "FgUtQqop18uf1I2fwDie", + "bidfloor": 1.0, + "banner": { + "format": [{ + "w": 300, + "h": 250 + }], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pub_id": "sovrn", + "med_id": "0jqCuiqHfPDHAHrdFfGG", + "zone_id": "FgUtQqop18uf1I2fwDie" + } + } + }] + } + }, + "mockResponse": { + "status": 500, + "body": {} + } + } + ], + + "expectedBidResponses": [], + + "expectedMakeBidsErrors": [{ + "value": "Unexpected status code: 500", + "comparison": "regex" + }] +} diff --git a/adapters/sovrnXsp/sovrnXsptest/supplemental/response-invalid-crtype.json b/adapters/sovrnXsp/sovrnXsptest/supplemental/response-invalid-crtype.json new file mode 100644 index 00000000000..73bc7d87a53 --- /dev/null +++ b/adapters/sovrnXsp/sovrnXsptest/supplemental/response-invalid-crtype.json @@ -0,0 +1,103 @@ +{ + "mockBidRequest": { + "id": "abc", + "app": { + "id": "0jqCuiqHfPDHAHrdFfGG", + "bundle": "test", + "publisher": { + "id": "sovrn" + } + }, + "imp": [ + { + "id": "imp123", + "bidfloor": 1.0, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pub_id": "sovrn", + "med_id": "0jqCuiqHfPDHAHrdFfGG", + "zone_id": "FgUtQqop18uf1I2fwDie" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://xsp.lijit.com/json/rtb/prebid/server", + "body":{ + "id": "abc", + "app": { + "id": "0jqCuiqHfPDHAHrdFfGG", + "bundle": "test", + "publisher": { + "id": "sovrn" + } + }, + "imp": [{ + "id": "imp123", + "tagid": "FgUtQqop18uf1I2fwDie", + "bidfloor": 1.0, + "banner": { + "format": [{ + "w": 300, + "h": 250 + }], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pub_id": "sovrn", + "med_id": "0jqCuiqHfPDHAHrdFfGG", + "zone_id": "FgUtQqop18uf1I2fwDie" + } + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "abc", + "seatbid": [ + { + "bid": [ + { + "adm": "", + "crid": "test_banner_crid", + "cid": "test_cid", + "impid": "imp123", + "id": "1", + "price": 1.0, + "ext": { + "creative_type": 100 + } + } + ] + } + ] + } + } + } + ], + + "expectedBidResponses": [], + + "expectedMakeBidsErrors": [{ + "value": "Unsupported creative type: 100", + "comparison": "literal" + }] +} diff --git a/adapters/sovrnXsp/sovrnXsptest/supplemental/response-nobid.json b/adapters/sovrnXsp/sovrnXsptest/supplemental/response-nobid.json new file mode 100644 index 00000000000..bb0e04a50fc --- /dev/null +++ b/adapters/sovrnXsp/sovrnXsptest/supplemental/response-nobid.json @@ -0,0 +1,79 @@ +{ + "mockBidRequest": { + "id": "abc", + "app": { + "id": "0jqCuiqHfPDHAHrdFfGG", + "bundle": "test", + "publisher": { + "id": "sovrn" + } + }, + "imp": [ + { + "id": "imp123", + "bidfloor": 1.0, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pub_id": "sovrn", + "med_id": "0jqCuiqHfPDHAHrdFfGG", + "zone_id": "FgUtQqop18uf1I2fwDie" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://xsp.lijit.com/json/rtb/prebid/server", + "body":{ + "id": "abc", + "app": { + "id": "0jqCuiqHfPDHAHrdFfGG", + "bundle": "test", + "publisher": { + "id": "sovrn" + } + }, + "imp": [{ + "id": "imp123", + "tagid": "FgUtQqop18uf1I2fwDie", + "bidfloor": 1.0, + "banner": { + "format": [{ + "w": 300, + "h": 250 + }], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pub_id": "sovrn", + "med_id": "0jqCuiqHfPDHAHrdFfGG", + "zone_id": "FgUtQqop18uf1I2fwDie" + } + } + }] + } + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + + "expectedBidResponses": [] +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 5de2d78362e..0e85a39a314 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -161,6 +161,7 @@ import ( "github.com/prebid/prebid-server/v2/adapters/smilewanted" "github.com/prebid/prebid-server/v2/adapters/sonobi" "github.com/prebid/prebid-server/v2/adapters/sovrn" + "github.com/prebid/prebid-server/v2/adapters/sovrnXsp" "github.com/prebid/prebid-server/v2/adapters/sspBC" "github.com/prebid/prebid-server/v2/adapters/stroeerCore" "github.com/prebid/prebid-server/v2/adapters/taboola" @@ -359,6 +360,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderSmileWanted: smilewanted.Builder, openrtb_ext.BidderSonobi: sonobi.Builder, openrtb_ext.BidderSovrn: sovrn.Builder, + openrtb_ext.BidderSovrnXsp: sovrnXsp.Builder, openrtb_ext.BidderSspBC: sspBC.Builder, openrtb_ext.BidderStroeerCore: stroeerCore.Builder, openrtb_ext.BidderTaboola: taboola.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index cc4e095a93e..4f5aaebab94 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -179,6 +179,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderSmileWanted, BidderSonobi, BidderSovrn, + BidderSovrnXsp, BidderSspBC, BidderStroeerCore, BidderTaboola, @@ -457,6 +458,7 @@ const ( BidderSmileWanted BidderName = "smilewanted" BidderSonobi BidderName = "sonobi" BidderSovrn BidderName = "sovrn" + BidderSovrnXsp BidderName = "sovrnXsp" BidderSspBC BidderName = "sspBC" BidderStroeerCore BidderName = "stroeerCore" BidderTaboola BidderName = "taboola" diff --git a/openrtb_ext/imp_sovrnXsp.go b/openrtb_ext/imp_sovrnXsp.go new file mode 100644 index 00000000000..90c78d707e4 --- /dev/null +++ b/openrtb_ext/imp_sovrnXsp.go @@ -0,0 +1,8 @@ +package openrtb_ext + +type ExtImpSovrnXsp struct { + PubID string `json:"pub_id,omitempty"` + MedID string `json:"med_id,omitempty"` + ZoneID string `json:"zone_id,omitempty"` + ForceBid bool `json:"force_bid,omitempty"` +} diff --git a/static/bidder-info/sovrnXsp.yaml b/static/bidder-info/sovrnXsp.yaml new file mode 100644 index 00000000000..3cce11a551c --- /dev/null +++ b/static/bidder-info/sovrnXsp.yaml @@ -0,0 +1,12 @@ +endpoint: "http://xsp.lijit.com/json/rtb/prebid/server" +maintainer: + email: "sovrnoss@sovrn.com" +endpointCompression: gzip +gvlVendorID: 13 +modifyingVastXmlAllowed: true +capabilities: + app: + mediaTypes: + - banner + - video + - native diff --git a/static/bidder-params/sovrnXsp.json b/static/bidder-params/sovrnXsp.json new file mode 100644 index 00000000000..beea3f588df --- /dev/null +++ b/static/bidder-params/sovrnXsp.json @@ -0,0 +1,27 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Sovrn XSP Adapter Params", + "description": "Schema validating params accepted by the Sovrn XSP adapter", + "type": "object", + "properties": { + "pub_id": { + "type": "string", + "description": "Assigned publisher ID", + "minLength": 4 + }, + "med_id": { + "type": "string", + "description": "Property ID not zone ID not provided" + }, + "zone_id": { + "type": "string", + "description": "Specific zone ID for this placement, belonging to app/site", + "minLength": 20 + }, + "force_bid": { + "type": "boolean", + "description": "Force bids with a test creative" + } + }, + "required": [ "pub_id" ] + } From c49e8eac6289f27db32bb23a7f9803bd46904009 Mon Sep 17 00:00:00 2001 From: bretg Date: Mon, 8 Jan 2024 16:37:24 -0500 Subject: [PATCH 264/268] Bidder geo scope in-line documentation (#3311) --- static/bidder-info/33across.yaml | 5 ++++- static/bidder-info/imds.yaml | 4 ++++ static/bidder-info/lockerdome.yaml | 3 +++ static/bidder-info/lunamedia.yaml | 2 ++ static/bidder-info/mobilefuse.yaml | 6 +++++- static/bidder-info/rubicon.yaml | 14 +++++++++++--- static/bidder-info/smaato.yaml | 2 ++ 7 files changed, 31 insertions(+), 5 deletions(-) diff --git a/static/bidder-info/33across.yaml b/static/bidder-info/33across.yaml index 902db6b362b..cbbdedb2193 100644 --- a/static/bidder-info/33across.yaml +++ b/static/bidder-info/33across.yaml @@ -1,4 +1,7 @@ endpoint: "https://ssc.33across.com/api/v1/s2s" +# This bidder does not operate globally. Please consider setting "disabled: true" in European datacenters. +geoscope: + - "!EEA" maintainer: email: "headerbidding@33across.com" gvlVendorID: 58 @@ -10,4 +13,4 @@ capabilities: userSync: iframe: url: "https://ssc-cms.33across.com/ps/?m=xch&rt=html&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&ru={{.RedirectURL}}&id=zzz000000000002zzz" - userMacro: "33XUSERID33X" \ No newline at end of file + userMacro: "33XUSERID33X" diff --git a/static/bidder-info/imds.yaml b/static/bidder-info/imds.yaml index 491a5bd0ac6..135b67fc1f9 100644 --- a/static/bidder-info/imds.yaml +++ b/static/bidder-info/imds.yaml @@ -1,4 +1,8 @@ endpoint: "https://pbs.technoratimedia.com/openrtb/bids/{{.AccountID}}?src={{.SourceId}}&adapter=imds" +# This bidder does not operate globally. Please consider setting "disabled: true" outside of the following regions: +geoscope: + - USA + - CAN maintainer: email: "eng-demand@imds.tv" capabilities: diff --git a/static/bidder-info/lockerdome.yaml b/static/bidder-info/lockerdome.yaml index cfefb2f995b..530c54eaaff 100644 --- a/static/bidder-info/lockerdome.yaml +++ b/static/bidder-info/lockerdome.yaml @@ -1,4 +1,7 @@ endpoint: "https://lockerdome.com/ladbid/prebidserver/openrtb2" +# This bidder does not operate globally. Please consider setting "disabled: true" outside of the following regions: +geoscope: + - USA maintainer: email: "bidding@lockerdome.com" capabilities: diff --git a/static/bidder-info/lunamedia.yaml b/static/bidder-info/lunamedia.yaml index 4064a566040..6f450382c0e 100644 --- a/static/bidder-info/lunamedia.yaml +++ b/static/bidder-info/lunamedia.yaml @@ -1,4 +1,6 @@ endpoint: "http://rtb.lunamedia.live/?pid={{.PublisherID}}" +geoscope: + - USA maintainer: email: "cs@lunamedia.io" capabilities: diff --git a/static/bidder-info/mobilefuse.yaml b/static/bidder-info/mobilefuse.yaml index e1474f775fc..1d6b323c3a6 100644 --- a/static/bidder-info/mobilefuse.yaml +++ b/static/bidder-info/mobilefuse.yaml @@ -1,4 +1,8 @@ endpoint: "http://mfx.mobilefuse.com/openrtb?pub_id={{.PublisherID}}" +# This bidder does not operate globally. Please consider setting "disabled: true" outside of the following regions: +geoscope: + - USA + - CAN maintainer: email: prebid@mobilefuse.com gvlVendorID: 909 @@ -8,4 +12,4 @@ capabilities: - banner - video - native -endpointCompression: "GZIP" \ No newline at end of file +endpointCompression: "GZIP" diff --git a/static/bidder-info/rubicon.yaml b/static/bidder-info/rubicon.yaml index be2acdc8355..c3943058511 100644 --- a/static/bidder-info/rubicon.yaml +++ b/static/bidder-info/rubicon.yaml @@ -1,6 +1,15 @@ -endpoint: "http://exapi-us-east.rubiconproject.com/a/api/exchange.json" +# Contact global-support@magnite.com to ask about enabling a connection to the Magnite (formerly Rubicon) exchange. +# We have the following regional endpoint domains: exapi-us-east, exapi-us-west, exapi-apac, exapi-eu +# Please deploy this config in each of your datacenters with the appropriate regional subdomain +endpoint: "https://REGION.rubiconproject.com/a/api/exchange" endpointCompression: GZIP +geoscope: + - global disabled: true +xapi: + username: GET_FROM_MAGNITE + password: GET_FROM_MAGNITE + tracker: SAME_AS_USERNAME maintainer: email: "header-bidding@rubiconproject.com" gvlVendorID: 52 @@ -16,7 +25,6 @@ capabilities: - video - native userSync: - # rubicon supports user syncing, but requires configuration by the host. contact this - # bidder directly at the email address in this file to ask about enabling user sync. + # rubicon supports user syncing, but requires configuration. Please contact global-support@magnite.com. supports: - redirect diff --git a/static/bidder-info/smaato.yaml b/static/bidder-info/smaato.yaml index 59a734c90fd..2b1b5c3fe17 100644 --- a/static/bidder-info/smaato.yaml +++ b/static/bidder-info/smaato.yaml @@ -15,6 +15,8 @@ capabilities: - video - native userSync: + # This bidder does not sync when GDPR is in-scope. Please consider removing the usersync + # block when deploying to European datacenters redirect: url: "https://s.ad.smaato.net/c/?adExInit=p&redir={{.RedirectURL}}&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}" userMacro: "$UID" From f347436dc33023e08914a51dc28331f75025c908 Mon Sep 17 00:00:00 2001 From: Maxime Liege <56251840+github-maxime-liege@users.noreply.github.com> Date: Thu, 11 Jan 2024 08:04:45 +0100 Subject: [PATCH 265/268] Change email support for Teads adapter (#3386) authored by: @github-maxime-liege --- static/bidder-info/teads.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/bidder-info/teads.yaml b/static/bidder-info/teads.yaml index 47686977673..307b631efb4 100644 --- a/static/bidder-info/teads.yaml +++ b/static/bidder-info/teads.yaml @@ -1,6 +1,6 @@ endpoint: "https://psrv.teads.tv/prebid-server/bid-request" maintainer: - email: "support-sdk@teads.com" + email: "innov-ssp@teads.tv" gvlVendorID: 132 capabilities: app: From 967b88241f930eb6f1fdf3d64ce35c200c30feed Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 11 Jan 2024 02:05:25 -0500 Subject: [PATCH 266/268] Update contact info for iqx (#3365) authored by: @minaguib --- static/bidder-info/iqx.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/bidder-info/iqx.yaml b/static/bidder-info/iqx.yaml index ab10ad96289..3569c3accf8 100644 --- a/static/bidder-info/iqx.yaml +++ b/static/bidder-info/iqx.yaml @@ -1,6 +1,6 @@ endpoint: "http://rtb.iqzone.com?pid={{.SourceId}}&host={{.Host}}&pbs=1" maintainer: - email: "it@iqzone.com" + email: "adops@iqzone.com" capabilities: app: mediaTypes: @@ -16,4 +16,4 @@ userSync: # IQX supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. supports: - - redirect \ No newline at end of file + - redirect From 03314e14fc36db4544276ceb2048bc44ba55d5aa Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 11 Jan 2024 02:06:01 -0500 Subject: [PATCH 267/268] Update contact info for iqzone (#3360) authored by @bretg --- static/bidder-info/iqzone.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/bidder-info/iqzone.yaml b/static/bidder-info/iqzone.yaml index 3465cfabcb0..620ea01e43c 100644 --- a/static/bidder-info/iqzone.yaml +++ b/static/bidder-info/iqzone.yaml @@ -1,6 +1,6 @@ endpoint: "http://smartssp-us-east.iqzone.com/pserver" maintainer: - email: "smartssp@iqzone.com" + email: "adops@iqzone.com" capabilities: site: mediaTypes: From 3789cf91b8e9906d8716000b68817d51971d1559 Mon Sep 17 00:00:00 2001 From: AlexBVolcy <74930484+AlexBVolcy@users.noreply.github.com> Date: Thu, 11 Jan 2024 22:06:27 -0800 Subject: [PATCH 268/268] Allow Bidder to Override Callback Type in /setuid (#3301) --- config/bidderinfo.go | 12 +++++++ config/bidderinfo_test.go | 35 ++++++++++++++++++++ endpoints/cookie_sync_test.go | 2 +- endpoints/setuid.go | 2 +- endpoints/setuid_test.go | 60 ++++++++++++++++++++++++++++++----- usersync/chooser_test.go | 3 +- usersync/syncer.go | 32 ++++++++++++------- usersync/syncer_test.go | 34 ++++++++++++++++++-- 8 files changed, 155 insertions(+), 25 deletions(-) diff --git a/config/bidderinfo.go b/config/bidderinfo.go index d3c874f706b..d78f5722552 100644 --- a/config/bidderinfo.go +++ b/config/bidderinfo.go @@ -125,6 +125,9 @@ type Syncer struct { // SupportCORS identifies if CORS is supported for the user syncing endpoints. SupportCORS *bool `yaml:"supportCors" mapstructure:"support_cors"` + // FormatOverride allows a bidder to override their callback type "b" for iframe, "i" for redirect + FormatOverride string `yaml:"formatOverride" mapstructure:"format_override"` + // Enabled signifies whether a bidder is enabled/disabled for user sync Enabled *bool `yaml:"enabled" mapstructure:"enabled"` @@ -206,6 +209,11 @@ type InfoReaderFromDisk struct { Path string } +const ( + SyncResponseFormatIFrame = "b" // b = blank HTML response + SyncResponseFormatRedirect = "i" // i = image response +) + func (r InfoReaderFromDisk) Read() (map[string][]byte, error) { bidderConfigs, err := os.ReadDir(r.Path) if err != nil { @@ -562,6 +570,10 @@ func validateSyncer(bidderInfo BidderInfo) error { return nil } + if bidderInfo.Syncer.FormatOverride != SyncResponseFormatIFrame && bidderInfo.Syncer.FormatOverride != SyncResponseFormatRedirect && bidderInfo.Syncer.FormatOverride != "" { + return fmt.Errorf("syncer could not be created, invalid format override value: %s", bidderInfo.Syncer.FormatOverride) + } + for _, supports := range bidderInfo.Syncer.Supports { if !strings.EqualFold(supports, "iframe") && !strings.EqualFold(supports, "redirect") { return fmt.Errorf("syncer could not be created, invalid supported endpoint: %s", supports) diff --git a/config/bidderinfo_test.go b/config/bidderinfo_test.go index ee1b35d4994..3305e34e88a 100644 --- a/config/bidderinfo_test.go +++ b/config/bidderinfo_test.go @@ -593,6 +593,7 @@ func TestBidderInfoValidationPositive(t *testing.T) { URL: "http://bidderB.com/usersync", UserMacro: "UID", }, + FormatOverride: SyncResponseFormatRedirect, }, }, "bidderC": BidderInfo{ @@ -627,6 +628,9 @@ func TestBidderInfoValidationPositive(t *testing.T) { }, }, }, + Syncer: &Syncer{ + FormatOverride: SyncResponseFormatIFrame, + }, }, } errs := bidderInfos.validate(make([]error, 0)) @@ -1318,6 +1322,37 @@ func TestBidderInfoValidationNegative(t *testing.T) { errors.New("parent bidder: bidderC not found for an alias: bidderB"), }, }, + { + "Invalid format override value", + BidderInfos{ + "bidderB": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeBanner, + openrtb_ext.BidTypeNative, + }, + }, + Site: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeBanner, + openrtb_ext.BidTypeNative, + }, + }, + }, + Syncer: &Syncer{ + FormatOverride: "x", + }, + }, + }, + []error{ + errors.New("syncer could not be created, invalid format override value: x"), + }, + }, } for _, test := range testCases { diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go index 401c6796237..adfdcb22fab 100644 --- a/endpoints/cookie_sync_test.go +++ b/endpoints/cookie_sync_test.go @@ -2094,7 +2094,7 @@ func (m *MockSyncer) Key() string { return args.String(0) } -func (m *MockSyncer) DefaultSyncType() usersync.SyncType { +func (m *MockSyncer) DefaultResponseFormat() usersync.SyncType { args := m.Called() return args.Get(0).(usersync.SyncType) } diff --git a/endpoints/setuid.go b/endpoints/setuid.go index aae31f10e2e..0f4d36d35ac 100644 --- a/endpoints/setuid.go +++ b/endpoints/setuid.go @@ -362,7 +362,7 @@ func getResponseFormat(query url.Values, syncer usersync.Syncer) (string, error) formatEmpty := len(format) == 0 || format[0] == "" if !formatProvided || formatEmpty { - switch syncer.DefaultSyncType() { + switch syncer.DefaultResponseFormat() { case usersync.SyncTypeIFrame: return "b", nil case usersync.SyncTypeRedirect: diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go index 145be3d3d13..ded528abeb3 100644 --- a/endpoints/setuid_test.go +++ b/endpoints/setuid_test.go @@ -34,6 +34,7 @@ func TestSetUIDEndpoint(t *testing.T) { gdprAllowsHostCookies bool gdprReturnsError bool gdprMalformed bool + formatOverride string expectedSyncs map[string]string expectedBody string expectedStatusCode int @@ -346,6 +347,17 @@ func TestSetUIDEndpoint(t *testing.T) { expectedStatusCode: http.StatusBadRequest, expectedBody: "invalid gpp_sid encoding, must be a csv list of integers", }, + { + uri: "/setuid?bidder=pubmatic&uid=123", + syncersBidderNameToKey: map[string]string{"pubmatic": "pubmatic"}, + existingSyncs: nil, + gdprAllowsHostCookies: true, + formatOverride: "i", + expectedSyncs: map[string]string{"pubmatic": "123"}, + expectedStatusCode: http.StatusOK, + expectedHeaders: map[string]string{"Content-Length": "86", "Content-Type": "image/png"}, + description: "Format not provided in URL, but formatOverride is defined", + }, } analytics := analyticsBuild.New(&config.Analytics{}) @@ -353,7 +365,7 @@ func TestSetUIDEndpoint(t *testing.T) { for _, test := range testCases { response := doRequest(makeRequest(test.uri, test.existingSyncs), analytics, metrics, - test.syncersBidderNameToKey, test.gdprAllowsHostCookies, test.gdprReturnsError, test.gdprMalformed, false, 0, nil) + test.syncersBidderNameToKey, test.gdprAllowsHostCookies, test.gdprReturnsError, test.gdprMalformed, false, 0, nil, test.formatOverride) assert.Equal(t, test.expectedStatusCode, response.Code, "Test Case: %s. /setuid returned unexpected error code", test.description) if test.expectedSyncs != nil { @@ -477,7 +489,7 @@ func TestSetUIDPriorityEjection(t *testing.T) { request.AddCookie(httpCookie) // Make Request to /setuid - response := doRequest(request, analytics, &metricsConf.NilMetricsEngine{}, syncersByBidder, true, false, false, false, test.givenMaxCookieSize, test.givenPriorityGroups) + response := doRequest(request, analytics, &metricsConf.NilMetricsEngine{}, syncersByBidder, true, false, false, false, test.givenMaxCookieSize, test.givenPriorityGroups, "") if test.expectedWarning != "" { assert.Equal(t, test.expectedWarning, response.Body.String(), test.description) @@ -1343,7 +1355,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { for _, v := range test.cookies { addCookie(req, v) } - response := doRequest(req, analyticsEngine, metricsEngine, test.syncersBidderNameToKey, test.gdprAllowsHostCookies, false, false, test.cfgAccountRequired, 0, nil) + response := doRequest(req, analyticsEngine, metricsEngine, test.syncersBidderNameToKey, test.gdprAllowsHostCookies, false, false, test.cfgAccountRequired, 0, nil, "") assert.Equal(t, test.expectedResponseCode, response.Code, test.description) analyticsEngine.AssertExpectations(t) @@ -1359,7 +1371,7 @@ func TestOptedOut(t *testing.T) { syncersBidderNameToKey := map[string]string{"pubmatic": "pubmatic"} analytics := analyticsBuild.New(&config.Analytics{}) metrics := &metricsConf.NilMetricsEngine{} - response := doRequest(request, analytics, metrics, syncersBidderNameToKey, true, false, false, false, 0, nil) + response := doRequest(request, analytics, metrics, syncersBidderNameToKey, true, false, false, false, 0, nil, "") assert.Equal(t, http.StatusUnauthorized, response.Code) } @@ -1455,6 +1467,30 @@ func TestGetResponseFormat(t *testing.T) { expectedFormat: "i", description: "parameter given is empty (by empty item), use default sync type redirect", }, + { + urlValues: url.Values{"f": []string{""}}, + syncer: fakeSyncer{key: "a", defaultSyncType: usersync.SyncTypeRedirect}, + expectedFormat: "i", + description: "parameter given is empty (by empty item), use default sync type redirect", + }, + { + urlValues: url.Values{"f": []string{}}, + syncer: fakeSyncer{key: "a", formatOverride: "i"}, + expectedFormat: "i", + description: "format not provided, but formatOverride is defined, expect i", + }, + { + urlValues: url.Values{"f": []string{}}, + syncer: fakeSyncer{key: "a", formatOverride: "b"}, + expectedFormat: "b", + description: "format not provided, but formatOverride is defined, expect b", + }, + { + urlValues: url.Values{"f": []string{}}, + syncer: fakeSyncer{key: "a", formatOverride: "b", defaultSyncType: usersync.SyncTypeRedirect}, + expectedFormat: "b", + description: "format not provided, default is defined but formatOverride is defined as well, expect b", + }, } for _, test := range testCases { @@ -1554,7 +1590,7 @@ func makeRequest(uri string, existingSyncs map[string]string) *http.Request { return request } -func doRequest(req *http.Request, analytics analytics.Runner, metrics metrics.MetricsEngine, syncersBidderNameToKey map[string]string, gdprAllowsHostCookies, gdprReturnsError, gdprReturnsMalformedError, cfgAccountRequired bool, maxCookieSize int, priorityGroups [][]string) *httptest.ResponseRecorder { +func doRequest(req *http.Request, analytics analytics.Runner, metrics metrics.MetricsEngine, syncersBidderNameToKey map[string]string, gdprAllowsHostCookies, gdprReturnsError, gdprReturnsMalformedError, cfgAccountRequired bool, maxCookieSize int, priorityGroups [][]string, formatOverride string) *httptest.ResponseRecorder { cfg := config.Configuration{ AccountRequired: cfgAccountRequired, AccountDefaults: config.Account{}, @@ -1585,7 +1621,7 @@ func doRequest(req *http.Request, analytics analytics.Runner, metrics metrics.Me syncersByBidder := make(map[string]usersync.Syncer) for bidderName, syncerKey := range syncersBidderNameToKey { - syncersByBidder[bidderName] = fakeSyncer{key: syncerKey, defaultSyncType: usersync.SyncTypeIFrame} + syncersByBidder[bidderName] = fakeSyncer{key: syncerKey, defaultSyncType: usersync.SyncTypeIFrame, formatOverride: formatOverride} if priorityGroups == nil { cfg.UserSync.PriorityGroups = [][]string{{}} cfg.UserSync.PriorityGroups[0] = append(cfg.UserSync.PriorityGroups[0], bidderName) @@ -1676,14 +1712,22 @@ func (g *fakePermsSetUID) AuctionActivitiesAllowed(ctx context.Context, bidderCo type fakeSyncer struct { key string defaultSyncType usersync.SyncType + formatOverride string } func (s fakeSyncer) Key() string { return s.key } -func (s fakeSyncer) DefaultSyncType() usersync.SyncType { - return s.defaultSyncType +func (s fakeSyncer) DefaultResponseFormat() usersync.SyncType { + switch s.formatOverride { + case "b": + return usersync.SyncTypeIFrame + case "i": + return usersync.SyncTypeRedirect + default: + return s.defaultSyncType + } } func (s fakeSyncer) SupportsType(syncTypes []usersync.SyncType) bool { diff --git a/usersync/chooser_test.go b/usersync/chooser_test.go index 9bc06100e81..f48dbeff9f1 100644 --- a/usersync/chooser_test.go +++ b/usersync/chooser_test.go @@ -720,13 +720,14 @@ type fakeSyncer struct { key string supportsIFrame bool supportsRedirect bool + formatOverride string } func (s fakeSyncer) Key() string { return s.key } -func (s fakeSyncer) DefaultSyncType() SyncType { +func (s fakeSyncer) DefaultResponseFormat() SyncType { return SyncTypeIFrame } diff --git a/usersync/syncer.go b/usersync/syncer.go index 3add47e5873..50985eca5be 100644 --- a/usersync/syncer.go +++ b/usersync/syncer.go @@ -26,8 +26,8 @@ type Syncer interface { // necessarily, a one-to-one mapping with a bidder. Key() string - // DefaultSyncType is the default SyncType for this syncer. - DefaultSyncType() SyncType + // DefaultResponseFormat is the default SyncType for this syncer. + DefaultResponseFormat() SyncType // SupportsType returns true if the syncer supports at least one of the specified sync types. SupportsType(syncTypes []SyncType) bool @@ -50,13 +50,9 @@ type standardSyncer struct { iframe *template.Template redirect *template.Template supportCORS bool + formatOverride string } -const ( - setuidSyncTypeIFrame = "b" // b = blank HTML response - setuidSyncTypeRedirect = "i" // i = image response -) - // NewSyncer creates a new Syncer from the provided configuration, or return an error if macro substition // fails or an endpoint url is invalid. func NewSyncer(hostConfig config.UserSync, syncerConfig config.Syncer, bidder string) (Syncer, error) { @@ -72,11 +68,12 @@ func NewSyncer(hostConfig config.UserSync, syncerConfig config.Syncer, bidder st key: syncerConfig.Key, defaultSyncType: resolveDefaultSyncType(syncerConfig), supportCORS: syncerConfig.SupportCORS != nil && *syncerConfig.SupportCORS, + formatOverride: syncerConfig.FormatOverride, } if syncerConfig.IFrame != nil { var err error - syncer.iframe, err = buildTemplate(bidder, setuidSyncTypeIFrame, hostConfig, syncerConfig.ExternalURL, *syncerConfig.IFrame) + syncer.iframe, err = buildTemplate(bidder, config.SyncResponseFormatIFrame, hostConfig, syncerConfig.ExternalURL, *syncerConfig.IFrame, syncerConfig.FormatOverride) if err != nil { return nil, fmt.Errorf("iframe %v", err) } @@ -87,7 +84,7 @@ func NewSyncer(hostConfig config.UserSync, syncerConfig config.Syncer, bidder st if syncerConfig.Redirect != nil { var err error - syncer.redirect, err = buildTemplate(bidder, setuidSyncTypeRedirect, hostConfig, syncerConfig.ExternalURL, *syncerConfig.Redirect) + syncer.redirect, err = buildTemplate(bidder, config.SyncResponseFormatRedirect, hostConfig, syncerConfig.ExternalURL, *syncerConfig.Redirect, syncerConfig.FormatOverride) if err != nil { return nil, fmt.Errorf("redirect %v", err) } @@ -117,12 +114,16 @@ var ( macroRegex = regexp.MustCompile(`{{\s*\..*?\s*}}`) ) -func buildTemplate(bidderName, syncTypeValue string, hostConfig config.UserSync, syncerExternalURL string, syncerEndpoint config.SyncerEndpoint) (*template.Template, error) { +func buildTemplate(bidderName, syncTypeValue string, hostConfig config.UserSync, syncerExternalURL string, syncerEndpoint config.SyncerEndpoint, formatOverride string) (*template.Template, error) { redirectTemplate := syncerEndpoint.RedirectURL if redirectTemplate == "" { redirectTemplate = hostConfig.RedirectURL } + if formatOverride != "" { + syncTypeValue = formatOverride + } + externalURL := chooseExternalURL(syncerEndpoint.ExternalURL, syncerExternalURL, hostConfig.ExternalURL) redirectURL := macroRegexSyncerKey.ReplaceAllLiteralString(redirectTemplate, bidderName) @@ -189,8 +190,15 @@ func (s standardSyncer) Key() string { return s.key } -func (s standardSyncer) DefaultSyncType() SyncType { - return s.defaultSyncType +func (s standardSyncer) DefaultResponseFormat() SyncType { + switch s.formatOverride { + case config.SyncResponseFormatIFrame: + return SyncTypeIFrame + case config.SyncResponseFormatRedirect: + return SyncTypeRedirect + default: + return s.defaultSyncType + } } func (s standardSyncer) SupportsType(syncTypes []SyncType) bool { diff --git a/usersync/syncer_test.go b/usersync/syncer_test.go index 6aa3103211e..c9c568e299a 100644 --- a/usersync/syncer_test.go +++ b/usersync/syncer_test.go @@ -27,6 +27,7 @@ func TestNewSyncer(t *testing.T) { givenIFrameConfig *config.SyncerEndpoint givenRedirectConfig *config.SyncerEndpoint givenExternalURL string + givenForceType string expectedError string expectedDefault SyncType expectedIFrame string @@ -322,7 +323,7 @@ func TestBuildTemplate(t *testing.T) { } for _, test := range testCases { - result, err := buildTemplate(key, syncTypeValue, hostConfig, test.givenSyncerExternalURL, test.givenSyncerEndpoint) + result, err := buildTemplate(key, syncTypeValue, hostConfig, test.givenSyncerExternalURL, test.givenSyncerEndpoint, "") if test.expectedError == "" { assert.NoError(t, err, test.description+":err") @@ -480,7 +481,36 @@ func TestSyncerKey(t *testing.T) { func TestSyncerDefaultSyncType(t *testing.T) { syncer := standardSyncer{defaultSyncType: SyncTypeRedirect} - assert.Equal(t, SyncTypeRedirect, syncer.DefaultSyncType()) + assert.Equal(t, SyncTypeRedirect, syncer.DefaultResponseFormat()) +} + +func TestSyncerDefaultResponseFormat(t *testing.T) { + testCases := []struct { + description string + givenSyncer standardSyncer + expectedSyncType SyncType + }{ + { + description: "IFrame", + givenSyncer: standardSyncer{formatOverride: config.SyncResponseFormatIFrame}, + expectedSyncType: SyncTypeIFrame, + }, + { + description: "Default with Redirect Override", + givenSyncer: standardSyncer{defaultSyncType: SyncTypeIFrame, formatOverride: config.SyncResponseFormatRedirect}, + expectedSyncType: SyncTypeRedirect, + }, + { + description: "Default with no override", + givenSyncer: standardSyncer{defaultSyncType: SyncTypeRedirect}, + expectedSyncType: SyncTypeRedirect, + }, + } + + for _, test := range testCases { + syncType := test.givenSyncer.DefaultResponseFormat() + assert.Equal(t, test.expectedSyncType, syncType, test.description) + } } func TestSyncerSupportsType(t *testing.T) {