From ab26a907dda7af431861f181e922c5c76e564a1e Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Wed, 18 Nov 2020 16:30:52 -0500 Subject: [PATCH] Refactored HoldAuction Arguments (#1570) --- endpoints/openrtb2/amp_auction.go | 12 ++- endpoints/openrtb2/amp_auction_test.go | 22 +---- endpoints/openrtb2/auction.go | 14 ++- endpoints/openrtb2/auction_benchmark_test.go | 2 +- endpoints/openrtb2/auction_test.go | 48 ++++------ endpoints/openrtb2/video_auction.go | 15 +++- endpoints/openrtb2/video_auction_test.go | 17 ++-- exchange/exchange.go | 43 +++++---- exchange/exchange_test.go | 92 ++++++++++++++++---- exchange/targeting_test.go | 23 ++--- router/router.go | 11 +-- 11 files changed, 178 insertions(+), 121 deletions(-) diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index 5536c4e6603..486b5cfc638 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -48,7 +48,6 @@ func NewAmpEndpoint( validator openrtb_ext.BidderParamValidator, requestsById stored_requests.Fetcher, accounts stored_requests.AccountFetcher, - categories stored_requests.CategoryFetcher, cfg *config.Configuration, met pbsmetrics.MetricsEngine, pbsAnalytics analytics.PBSAnalyticsModule, @@ -74,7 +73,6 @@ func NewAmpEndpoint( requestsById, empty_fetcher.EmptyFetcher{}, accounts, - categories, cfg, met, pbsAnalytics, @@ -185,7 +183,15 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h return } - response, err := deps.ex.HoldAuction(ctx, req, usersyncs, labels, account, &deps.categories, nil) + auctionRequest := exchange.AuctionRequest{ + BidRequest: req, + Account: *account, + UserSyncs: usersyncs, + RequestType: labels.RType, + LegacyLabels: labels, + } + + response, err := deps.ex.HoldAuction(ctx, auctionRequest, nil) ao.AuctionResponse = response if err != nil { diff --git a/endpoints/openrtb2/amp_auction_test.go b/endpoints/openrtb2/amp_auction_test.go index b8dd75b2dc0..80a48754bae 100644 --- a/endpoints/openrtb2/amp_auction_test.go +++ b/endpoints/openrtb2/amp_auction_test.go @@ -12,7 +12,6 @@ import ( "testing" "github.com/prebid/prebid-server/analytics" - "github.com/prebid/prebid-server/stored_requests" "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" "github.com/mxmCherry/openrtb" @@ -48,7 +47,6 @@ func TestGoodAmpRequests(t *testing.T) { newParamsValidator(t), &mockAmpStoredReqFetcher{goodRequests}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, theMetrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -102,7 +100,6 @@ func TestAMPPageInfo(t *testing.T) { newParamsValidator(t), &mockAmpStoredReqFetcher{stored}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, theMetrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -208,7 +205,6 @@ func TestGDPRConsent(t *testing.T) { newParamsValidator(t), &mockAmpStoredReqFetcher{stored}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, metrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -362,7 +358,6 @@ func TestCCPAConsent(t *testing.T) { newParamsValidator(t), &mockAmpStoredReqFetcher{stored}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, metrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -422,7 +417,6 @@ func TestNoConsent(t *testing.T) { newParamsValidator(t), &mockAmpStoredReqFetcher{stored}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, metrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -469,7 +463,6 @@ func TestInvalidConsent(t *testing.T) { newParamsValidator(t), &mockAmpStoredReqFetcher{stored}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, metrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -554,7 +547,6 @@ func TestNewAndLegacyConsentBothProvided(t *testing.T) { newParamsValidator(t), &mockAmpStoredReqFetcher{stored}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, metrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -607,7 +599,6 @@ func TestAMPSiteExt(t *testing.T) { newParamsValidator(t), &mockAmpStoredReqFetcher{stored}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, theMetrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -648,7 +639,6 @@ func TestAmpBadRequests(t *testing.T) { newParamsValidator(t), &mockAmpStoredReqFetcher{badRequests}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, theMetrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -680,7 +670,6 @@ func TestAmpDebug(t *testing.T) { newParamsValidator(t), &mockAmpStoredReqFetcher{requests}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, theMetrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -754,7 +743,6 @@ func TestQueryParamOverrides(t *testing.T) { newParamsValidator(t), &mockAmpStoredReqFetcher{requests}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, theMetrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -907,7 +895,6 @@ func (s formatOverrideSpec) execute(t *testing.T) { newParamsValidator(t), &mockAmpStoredReqFetcher{requests}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, theMetrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -965,8 +952,8 @@ var expectedErrorsFromHoldAuction map[openrtb_ext.BidderName][]openrtb_ext.ExtBi }, } -func (m *mockAmpExchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, ids exchange.IdFetcher, labels pbsmetrics.Labels, account *config.Account, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) { - m.lastRequest = bidRequest +func (m *mockAmpExchange) HoldAuction(ctx context.Context, r exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) { + m.lastRequest = r.BidRequest response := &openrtb.BidResponse{ SeatBid: []openrtb.SeatBid{{ @@ -978,8 +965,8 @@ func (m *mockAmpExchange) HoldAuction(ctx context.Context, bidRequest *openrtb.B Ext: json.RawMessage(`{ "errors": {"openx":[ { "code": 1, "message": "The request exceeded the timeout allocated" } ] } }`), } - if bidRequest.Test == 1 { - resolvedRequest, err := json.Marshal(bidRequest) + if r.BidRequest.Test == 1 { + resolvedRequest, err := json.Marshal(r.BidRequest) if err != nil { resolvedRequest = json.RawMessage("{}") } @@ -1275,7 +1262,6 @@ func TestBuildAmpObject(t *testing.T) { newParamsValidator(t), mockAmpFetcher, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), logger, diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index b02b57861bd..839ae975611 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -47,7 +47,7 @@ var ( dntEnabled int8 = 1 ) -func NewEndpoint(ex exchange.Exchange, validator openrtb_ext.BidderParamValidator, requestsById stored_requests.Fetcher, accounts stored_requests.AccountFetcher, categories stored_requests.CategoryFetcher, cfg *config.Configuration, met pbsmetrics.MetricsEngine, pbsAnalytics analytics.PBSAnalyticsModule, disabledBidders map[string]string, defReqJSON []byte, bidderMap map[string]openrtb_ext.BidderName) (httprouter.Handle, error) { +func NewEndpoint(ex exchange.Exchange, validator openrtb_ext.BidderParamValidator, requestsById stored_requests.Fetcher, accounts stored_requests.AccountFetcher, cfg *config.Configuration, met pbsmetrics.MetricsEngine, pbsAnalytics analytics.PBSAnalyticsModule, disabledBidders map[string]string, defReqJSON []byte, bidderMap map[string]openrtb_ext.BidderName) (httprouter.Handle, error) { if ex == nil || validator == nil || requestsById == nil || accounts == nil || cfg == nil || met == nil { return nil, errors.New("NewEndpoint requires non-nil arguments.") @@ -66,7 +66,6 @@ func NewEndpoint(ex exchange.Exchange, validator openrtb_ext.BidderParamValidato requestsById, empty_fetcher.EmptyFetcher{}, accounts, - categories, cfg, met, pbsAnalytics, @@ -85,7 +84,6 @@ type endpointDeps struct { storedReqFetcher stored_requests.Fetcher videoFetcher stored_requests.Fetcher accounts stored_requests.AccountFetcher - categories stored_requests.CategoryFetcher cfg *config.Configuration metricsEngine pbsmetrics.MetricsEngine analytics analytics.PBSAnalyticsModule @@ -164,7 +162,15 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http return } - response, err := deps.ex.HoldAuction(ctx, req, usersyncs, labels, account, &deps.categories, nil) + auctionRequest := exchange.AuctionRequest{ + BidRequest: req, + Account: *account, + UserSyncs: usersyncs, + RequestType: labels.RType, + LegacyLabels: labels, + } + + response, err := deps.ex.HoldAuction(ctx, auctionRequest, nil) ao.Request = req ao.Response = response ao.Account = account diff --git a/endpoints/openrtb2/auction_benchmark_test.go b/endpoints/openrtb2/auction_benchmark_test.go index 09af23af103..c5b7eb2b37c 100644 --- a/endpoints/openrtb2/auction_benchmark_test.go +++ b/endpoints/openrtb2/auction_benchmark_test.go @@ -79,11 +79,11 @@ func BenchmarkOpenrtbEndpoint(b *testing.B) { infos, gdpr.AlwaysAllow{}, currencies.NewRateConverter(&http.Client{}, "", time.Duration(0)), + empty_fetcher.EmptyFetcher{}, ), paramValidator, empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, theMetrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index 02a41f52169..9cdeff7bb49 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -406,8 +406,8 @@ func TestExplicitUserId(t *testing.T) { }) // NewMetrics() will create a new go_metrics MetricsEngine, bypassing the need for a crafted configuration set to support it. // As a side effect this gives us some coverage of the go_metrics piece of the metrics engine. - metrics := pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}) - endpoint, _ := NewEndpoint(ex, newParamsValidator(t), empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, cfg, metrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BidderMap) + theMetrics := pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}) + endpoint, _ := NewEndpoint(ex, newParamsValidator(t), empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, cfg, theMetrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BidderMap) endpoint(httptest.NewRecorder(), request, nil) @@ -437,7 +437,6 @@ func doRequest(t *testing.T, test testCase) (int, string) { newParamsValidator(t), &mockStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{ MaxRequestSize: maxSize, BlacklistedApps: test.Config.BlacklistedApps, @@ -504,7 +503,7 @@ func doBadAliasRequest(t *testing.T, filename string, expectMsg string) { // NewMetrics() will create a new go_metrics MetricsEngine, bypassing the need for a crafted configuration set to support it. // As a side effect this gives us some coverage of the go_metrics piece of the metrics engine. metrics := pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}) - endpoint, _ := NewEndpoint(&nobidExchange{}, newParamsValidator(t), &mockStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, metrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), disabledBidders, aliasJSON, bidderMap) + endpoint, _ := NewEndpoint(&nobidExchange{}, newParamsValidator(t), &mockStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, metrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), disabledBidders, aliasJSON, bidderMap) request := httptest.NewRequest("POST", "/openrtb2/auction", bytes.NewReader(testBidRequest)) recorder := httptest.NewRecorder() @@ -545,7 +544,7 @@ func TestNilExchange(t *testing.T) { // NewMetrics() will create a new go_metrics MetricsEngine, bypassing the need for a crafted configuration set to support it. // As a side effect this gives us some coverage of the go_metrics piece of the metrics engine. metrics := pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}) - _, err := NewEndpoint(nil, newParamsValidator(t), empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, metrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BidderMap) + _, err := NewEndpoint(nil, newParamsValidator(t), empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, metrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BidderMap) if err == nil { t.Errorf("NewEndpoint should return an error when given a nil Exchange.") } @@ -556,7 +555,7 @@ func TestNilValidator(t *testing.T) { // NewMetrics() will create a new go_metrics MetricsEngine, bypassing the need for a crafted configuration set to support it. // As a side effect this gives us some coverage of the go_metrics piece of the metrics engine. metrics := pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}) - _, err := NewEndpoint(&nobidExchange{}, nil, empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, metrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BidderMap) + _, err := NewEndpoint(&nobidExchange{}, nil, empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, metrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BidderMap) if err == nil { t.Errorf("NewEndpoint should return an error when given a nil BidderParamValidator.") } @@ -567,7 +566,7 @@ func TestExchangeError(t *testing.T) { // NewMetrics() will create a new go_metrics MetricsEngine, bypassing the need for a crafted configuration set to support it. // As a side effect this gives us some coverage of the go_metrics piece of the metrics engine. metrics := pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}) - endpoint, _ := NewEndpoint(&brokenExchange{}, newParamsValidator(t), empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, metrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BidderMap) + endpoint, _ := NewEndpoint(&brokenExchange{}, newParamsValidator(t), empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, metrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BidderMap) request := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(validRequest(t, "site.json"))) recorder := httptest.NewRecorder() endpoint(recorder, request, nil) @@ -679,7 +678,7 @@ func TestImplicitIPsEndToEnd(t *testing.T) { IPv6PrivateNetworksParsed: test.privateNetworksIPv6, }, } - endpoint, _ := NewEndpoint(exchange, newParamsValidator(t), &mockStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, cfg, metrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BidderMap) + endpoint, _ := NewEndpoint(exchange, newParamsValidator(t), &mockStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, cfg, metrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BidderMap) httpReq := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(validRequest(t, test.reqJSONFile))) httpReq.Header.Set("X-Forwarded-For", test.xForwardedForHeader) @@ -864,7 +863,7 @@ func TestImplicitDNTEndToEnd(t *testing.T) { metrics := pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}) for _, test := range testCases { exchange := &nobidExchange{} - endpoint, _ := NewEndpoint(exchange, newParamsValidator(t), &mockStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, metrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BidderMap) + endpoint, _ := NewEndpoint(exchange, newParamsValidator(t), &mockStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, metrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BidderMap) httpReq := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(validRequest(t, test.reqJSONFile))) httpReq.Header.Set("DNT", test.dntHeader) @@ -924,7 +923,6 @@ func TestStoredRequests(t *testing.T) { &mockStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, metrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -964,7 +962,6 @@ func TestOversizedRequest(t *testing.T) { &mockStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(len(reqBody) - 1)}, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -1000,7 +997,6 @@ func TestRequestSizeEdgeCase(t *testing.T) { &mockStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(len(reqBody))}, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -1034,7 +1030,6 @@ func TestNoEncoding(t *testing.T) { newParamsValidator(t), &mockStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -1110,7 +1105,6 @@ func TestContentType(t *testing.T) { newParamsValidator(t), &mockStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -1200,7 +1194,6 @@ func TestValidateImpExt(t *testing.T) { &mockStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(8096)}, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -1245,7 +1238,6 @@ func TestCurrencyTrunc(t *testing.T) { &mockStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{}, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -1290,7 +1282,6 @@ func TestCCPAInvalid(t *testing.T) { &mockStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{}, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -1339,7 +1330,6 @@ func TestNoSaleInvalid(t *testing.T) { &mockStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{}, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -1391,7 +1381,6 @@ func TestValidateSourceTID(t *testing.T) { &mockStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, cfg, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -1436,7 +1425,6 @@ func TestSChainInvalid(t *testing.T) { &mockStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{}, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -1657,10 +1645,10 @@ type nobidExchange struct { gotRequest *openrtb.BidRequest } -func (e *nobidExchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, ids exchange.IdFetcher, labels pbsmetrics.Labels, account *config.Account, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) { - e.gotRequest = bidRequest +func (e *nobidExchange) HoldAuction(ctx context.Context, r exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) { + e.gotRequest = r.BidRequest return &openrtb.BidResponse{ - ID: bidRequest.ID, + ID: r.BidRequest.ID, BidID: "test bid id", NBR: openrtb.NoBidReasonCodeUnknownError.Ptr(), }, nil @@ -1672,15 +1660,15 @@ type mockBidExchange struct { // mockBidExchange is a well-behaved exchange that lists the bidders found in every bidRequest.Imp[i].Ext // into the bidResponse.Ext to assert the bidder adapters that were not filtered out in the validation process -func (e *mockBidExchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, ids exchange.IdFetcher, labels pbsmetrics.Labels, account *config.Account, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) { +func (e *mockBidExchange) HoldAuction(ctx context.Context, r exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) { bidResponse := &openrtb.BidResponse{ - ID: bidRequest.ID, + ID: r.BidRequest.ID, BidID: "test bid id", NBR: openrtb.NoBidReasonCodeUnknownError.Ptr(), } - if len(bidRequest.Imp) > 0 { + if len(r.BidRequest.Imp) > 0 { var SeatBidMap = make(map[string]openrtb.SeatBid, 0) - for _, imp := range bidRequest.Imp { + for _, imp := range r.BidRequest.Imp { var bidderExts map[string]json.RawMessage if err := json.Unmarshal(imp.Ext, &bidderExts); err != nil { return nil, err @@ -1704,7 +1692,7 @@ func (e *mockBidExchange) HoldAuction(ctx context.Context, bidRequest *openrtb.B type brokenExchange struct{} -func (e *brokenExchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, ids exchange.IdFetcher, labels pbsmetrics.Labels, account *config.Account, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) { +func (e *brokenExchange) HoldAuction(ctx context.Context, r exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) { return nil, errors.New("Critical, unrecoverable error.") } @@ -2070,8 +2058,8 @@ type mockExchange struct { lastRequest *openrtb.BidRequest } -func (m *mockExchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, ids exchange.IdFetcher, labels pbsmetrics.Labels, account *config.Account, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) { - m.lastRequest = bidRequest +func (m *mockExchange) HoldAuction(ctx context.Context, r exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) { + m.lastRequest = r.BidRequest return &openrtb.BidResponse{ SeatBid: []openrtb.SeatBid{{ Bid: []openrtb.Bid{{ diff --git a/endpoints/openrtb2/video_auction.go b/endpoints/openrtb2/video_auction.go index e277e362a28..d1fcda0ab89 100644 --- a/endpoints/openrtb2/video_auction.go +++ b/endpoints/openrtb2/video_auction.go @@ -36,7 +36,7 @@ import ( var defaultRequestTimeout int64 = 5000 -func NewVideoEndpoint(ex exchange.Exchange, validator openrtb_ext.BidderParamValidator, requestsById stored_requests.Fetcher, videoFetcher stored_requests.Fetcher, accounts stored_requests.AccountFetcher, categories stored_requests.CategoryFetcher, cfg *config.Configuration, met pbsmetrics.MetricsEngine, pbsAnalytics analytics.PBSAnalyticsModule, disabledBidders map[string]string, defReqJSON []byte, bidderMap map[string]openrtb_ext.BidderName, cache prebid_cache_client.Client) (httprouter.Handle, error) { +func NewVideoEndpoint(ex exchange.Exchange, validator openrtb_ext.BidderParamValidator, requestsById stored_requests.Fetcher, videoFetcher stored_requests.Fetcher, accounts stored_requests.AccountFetcher, cfg *config.Configuration, met pbsmetrics.MetricsEngine, pbsAnalytics analytics.PBSAnalyticsModule, disabledBidders map[string]string, defReqJSON []byte, bidderMap map[string]openrtb_ext.BidderName, cache prebid_cache_client.Client) (httprouter.Handle, error) { if ex == nil || validator == nil || requestsById == nil || accounts == nil || cfg == nil || met == nil { return nil, errors.New("NewVideoEndpoint requires non-nil arguments.") @@ -57,7 +57,6 @@ func NewVideoEndpoint(ex exchange.Exchange, validator openrtb_ext.BidderParamVal requestsById, videoFetcher, accounts, - categories, cfg, met, pbsAnalytics, @@ -261,8 +260,16 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re handleError(&labels, w, acctIDErrs, &vo, &debugLog) return } - //execute auction logic - response, err := deps.ex.HoldAuction(ctx, bidReq, usersyncs, labels, account, &deps.categories, &debugLog) + + auctionRequest := exchange.AuctionRequest{ + BidRequest: bidReq, + Account: *account, + UserSyncs: usersyncs, + RequestType: labels.RType, + LegacyLabels: labels, + } + + response, err := deps.ex.HoldAuction(ctx, auctionRequest, &debugLog) vo.Request = bidReq vo.Response = response if err != nil { diff --git a/endpoints/openrtb2/video_auction_test.go b/endpoints/openrtb2/video_auction_test.go index 66a3bd6775b..2b6c478e7ff 100644 --- a/endpoints/openrtb2/video_auction_test.go +++ b/endpoints/openrtb2/video_auction_test.go @@ -20,7 +20,6 @@ import ( "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/pbsmetrics" "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" metrics "github.com/rcrowley/go-metrics" "github.com/stretchr/testify/assert" @@ -1210,7 +1209,6 @@ func mockDepsWithMetrics(t *testing.T, ex *mockExchangeVideo) (*endpointDeps, *p &mockVideoStoredReqFetcher{}, &mockVideoStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, theMetrics, mockModule, @@ -1255,7 +1253,6 @@ func mockDeps(t *testing.T, ex *mockExchangeVideo) *endpointDeps { &mockVideoStoredReqFetcher{}, &mockVideoStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, theMetrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -1279,7 +1276,6 @@ func mockDepsAppendBidderNames(t *testing.T, ex *mockExchangeAppendBidderNames) &mockVideoStoredReqFetcher{}, &mockVideoStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, theMetrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -1303,7 +1299,6 @@ func mockDepsNoBids(t *testing.T, ex *mockExchangeVideoNoBids) *endpointDeps { &mockVideoStoredReqFetcher{}, &mockVideoStoredReqFetcher{}, empty_fetcher.EmptyFetcher{}, - empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, theMetrics, analyticsConf.NewPBSAnalytics(&config.Analytics{}), @@ -1346,8 +1341,8 @@ type mockExchangeVideo struct { cache *mockCacheClient } -func (m *mockExchangeVideo) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, ids exchange.IdFetcher, labels pbsmetrics.Labels, account *config.Account, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) { - m.lastRequest = bidRequest +func (m *mockExchangeVideo) HoldAuction(ctx context.Context, r exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) { + m.lastRequest = r.BidRequest if debugLog != nil && debugLog.Enabled { m.cache.called = true } @@ -1382,8 +1377,8 @@ type mockExchangeAppendBidderNames struct { cache *mockCacheClient } -func (m *mockExchangeAppendBidderNames) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, ids exchange.IdFetcher, labels pbsmetrics.Labels, account *config.Account, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) { - m.lastRequest = bidRequest +func (m *mockExchangeAppendBidderNames) HoldAuction(ctx context.Context, r exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) { + m.lastRequest = r.BidRequest if debugLog != nil && debugLog.Enabled { m.cache.called = true } @@ -1418,8 +1413,8 @@ type mockExchangeVideoNoBids struct { cache *mockCacheClient } -func (m *mockExchangeVideoNoBids) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, ids exchange.IdFetcher, labels pbsmetrics.Labels, account *config.Account, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) { - m.lastRequest = bidRequest +func (m *mockExchangeVideoNoBids) HoldAuction(ctx context.Context, r exchange.AuctionRequest, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) { + m.lastRequest = r.BidRequest return &openrtb.BidResponse{ SeatBid: []openrtb.SeatBid{{}}, }, nil diff --git a/exchange/exchange.go b/exchange/exchange.go index 3a5f785bbc8..9056caf8d0a 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -41,13 +41,14 @@ type extCacheInstructions struct { // Exchange runs Auctions. Implementations must be threadsafe, and will be shared across many goroutines. type Exchange interface { // HoldAuction executes an OpenRTB v2.5 Auction. - HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, usersyncs IdFetcher, labels pbsmetrics.Labels, account *config.Account, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *DebugLog) (*openrtb.BidResponse, error) + HoldAuction(ctx context.Context, r AuctionRequest, debugLog *DebugLog) (*openrtb.BidResponse, error) } // IdFetcher can find the user's ID for a specific Bidder. type IdFetcher interface { // GetId returns the ID for the bidder. The boolean will be true if the ID exists, and false otherwise. GetId(bidder openrtb_ext.BidderName) (string, bool) + LiveSyncCount() int } type exchange struct { @@ -59,6 +60,7 @@ type exchange struct { currencyConverter *currencies.RateConverter UsersyncIfAmbiguous bool privacyConfig config.Privacy + categoriesFetcher stored_requests.CategoryFetcher } // Container to pass out response ext data from the GetAllBids goroutines back into the main thread @@ -76,7 +78,7 @@ type bidResponseWrapper struct { bidder openrtb_ext.BidderName } -func NewExchange(client *http.Client, cache prebid_cache_client.Client, cfg *config.Configuration, metricsEngine pbsmetrics.MetricsEngine, infos adapters.BidderInfos, gDPR gdpr.Permissions, currencyConverter *currencies.RateConverter) Exchange { +func NewExchange(client *http.Client, cache prebid_cache_client.Client, cfg *config.Configuration, metricsEngine pbsmetrics.MetricsEngine, infos adapters.BidderInfos, gDPR gdpr.Permissions, currencyConverter *currencies.RateConverter, categoriesFetcher stored_requests.CategoryFetcher) Exchange { e := new(exchange) e.adapterMap = newAdapterMap(client, cfg, infos, metricsEngine) @@ -91,13 +93,24 @@ func NewExchange(client *http.Client, cache prebid_cache_client.Client, cfg *con GDPR: cfg.GDPR, LMT: cfg.LMT, } + e.categoriesFetcher = categoriesFetcher return e } -func (e *exchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, usersyncs IdFetcher, labels pbsmetrics.Labels, account *config.Account, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *DebugLog) (*openrtb.BidResponse, error) { +type AuctionRequest struct { + BidRequest *openrtb.BidRequest + Account config.Account + UserSyncs IdFetcher + RequestType pbsmetrics.RequestType + // LegacyLabels is included here for temporary compatability with cleanOpenRTBRequests + // in HoldAuction until we get to factoring it away. Do not use for anything new. + LegacyLabels pbsmetrics.Labels +} + +func (e *exchange) HoldAuction(ctx context.Context, r AuctionRequest, debugLog *DebugLog) (*openrtb.BidResponse, error) { var err error - requestExt, err := extractBidRequestExt(bidRequest) + requestExt, err := extractBidRequestExt(r.BidRequest) if err != nil { return nil, err } @@ -108,21 +121,21 @@ func (e *exchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidReque _, targData.cacheHost, targData.cachePath = e.cache.GetExtCacheData() } - debugInfo := getDebugInfo(bidRequest, requestExt) + debugInfo := getDebugInfo(r.BidRequest, requestExt) if debugInfo { ctx = e.makeDebugContext(ctx, debugInfo) } bidAdjustmentFactors := getExtBidAdjustmentFactors(requestExt) - recordImpMetrics(bidRequest, e.me) + recordImpMetrics(r.BidRequest, e.me) // Make our best guess if GDPR applies - usersyncIfAmbiguous := e.parseUsersyncIfAmbiguous(bidRequest) + usersyncIfAmbiguous := e.parseUsersyncIfAmbiguous(r.BidRequest) // Slice of BidRequests, each a copy of the original cleaned to only contain bidder data for the named bidder blabels := make(map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels) - cleanRequests, aliases, privacyLabels, errs := cleanOpenRTBRequests(ctx, bidRequest, requestExt, usersyncs, blabels, labels, e.gDPR, usersyncIfAmbiguous, e.privacyConfig, account) + cleanRequests, aliases, privacyLabels, errs := cleanOpenRTBRequests(ctx, r.BidRequest, requestExt, r.UserSyncs, blabels, r.LegacyLabels, e.gDPR, usersyncIfAmbiguous, e.privacyConfig, &r.Account) e.me.RecordRequestPrivacy(privacyLabels) @@ -147,7 +160,7 @@ func (e *exchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidReque //If includebrandcategory is present in ext then CE feature is on. if requestExt.Prebid.Targeting != nil && requestExt.Prebid.Targeting.IncludeBrandCategory != nil { var rejections []string - bidCategory, adapterBids, rejections, err = applyCategoryMapping(ctx, requestExt, adapterBids, *categoriesFetcher, targData) + bidCategory, adapterBids, rejections, err = applyCategoryMapping(ctx, requestExt, adapterBids, e.categoriesFetcher, targData) if err != nil { return nil, fmt.Errorf("Error in category mapping : %s", err.Error()) } @@ -158,24 +171,24 @@ func (e *exchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidReque if targData != nil { // A non-nil auction is only needed if targeting is active. (It is used below this block to extract cache keys) - auc = newAuction(adapterBids, len(bidRequest.Imp), targData.preferDeals) + auc = newAuction(adapterBids, len(r.BidRequest.Imp), targData.preferDeals) auc.setRoundedPrices(targData.priceGranularity) if requestExt.Prebid.SupportDeals { - dealErrs := applyDealSupport(bidRequest, auc, bidCategory) + dealErrs := applyDealSupport(r.BidRequest, auc, bidCategory) errs = append(errs, dealErrs...) } - cacheErrs := auc.doCache(ctx, e.cache, targData, bidRequest, 60, &account.CacheTTL, bidCategory, debugLog) + cacheErrs := auc.doCache(ctx, e.cache, targData, r.BidRequest, 60, &r.Account.CacheTTL, bidCategory, debugLog) if len(cacheErrs) > 0 { errs = append(errs, cacheErrs...) } - targData.setTargeting(auc, bidRequest.App != nil, bidCategory) + targData.setTargeting(auc, r.BidRequest.App != nil, bidCategory) } } - bidResponseExt := e.makeExtBidResponse(adapterBids, adapterExtra, bidRequest, debugInfo, errs) + bidResponseExt := e.makeExtBidResponse(adapterBids, adapterExtra, r.BidRequest, debugInfo, errs) // Ensure caching errors are added in case auc.doCache was called and errors were returned if len(cacheErrs) > 0 { @@ -200,7 +213,7 @@ func (e *exchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidReque } // Build the response - return e.buildBidResponse(ctx, liveAdapters, adapterBids, bidRequest, adapterExtra, auc, bidResponseExt, cacheInstructions.returnCreative, errs) + return e.buildBidResponse(ctx, liveAdapters, adapterBids, r.BidRequest, adapterExtra, auc, bidResponseExt, cacheInstructions.returnCreative, errs) } func (e *exchange) parseUsersyncIfAmbiguous(bidRequest *openrtb.BidRequest) bool { diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go index bd2fa1147ef..d22acf0f04e 100644 --- a/exchange/exchange_test.go +++ b/exchange/exchange_test.go @@ -54,7 +54,7 @@ func TestNewExchange(t *testing.T) { } currencyConverter := currencies.NewRateConverter(&http.Client{}, "", time.Duration(0)) - e := NewExchange(server.Client(), nil, cfg, pbsmetrics.NewMetrics(metrics.NewRegistry(), knownAdapters, config.DisabledMetrics{}), adapters.ParseBidderInfos(cfg.Adapters, "../static/bidder-info", openrtb_ext.BidderList()), gdpr.AlwaysAllow{}, currencyConverter).(*exchange) + e := NewExchange(server.Client(), nil, cfg, pbsmetrics.NewMetrics(metrics.NewRegistry(), knownAdapters, config.DisabledMetrics{}), adapters.ParseBidderInfos(cfg.Adapters, "../static/bidder-info", openrtb_ext.BidderList()), gdpr.AlwaysAllow{}, currencyConverter, nilCategoryFetcher{}).(*exchange) for _, bidderName := range knownAdapters { if _, ok := e.adapterMap[bidderName]; !ok { t.Errorf("NewExchange produced an Exchange without bidder %s", bidderName) @@ -92,7 +92,7 @@ func TestCharacterEscape(t *testing.T) { defer server.Close() currencyConverter := currencies.NewRateConverter(&http.Client{}, "", time.Duration(0)) - e := NewExchange(server.Client(), nil, cfg, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), adapters.ParseBidderInfos(cfg.Adapters, "../static/bidder-info", openrtb_ext.BidderList()), gdpr.AlwaysAllow{}, currencyConverter).(*exchange) + e := NewExchange(server.Client(), nil, cfg, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), adapters.ParseBidderInfos(cfg.Adapters, "../static/bidder-info", openrtb_ext.BidderList()), gdpr.AlwaysAllow{}, currencyConverter, nilCategoryFetcher{}).(*exchange) /* 3) Build all the parameters e.buildBidResponse(ctx.Background(), liveA... ) needs */ //liveAdapters []openrtb_ext.BidderName, @@ -236,6 +236,7 @@ func TestDebugBehaviour(t *testing.T) { e.me = &metricsConf.DummyMetricsEngine{} e.gDPR = gdpr.AlwaysAllow{} e.currencyConverter = currencies.NewRateConverter(&http.Client{}, "", time.Duration(0)) + e.categoriesFetcher = categoriesFetcher // Run tests for _, test := range testCases { @@ -247,8 +248,14 @@ func TestDebugBehaviour(t *testing.T) { bidRequest.Ext = nil } + auctionRequest := AuctionRequest{ + BidRequest: bidRequest, + Account: config.Account{}, + UserSyncs: &emptyUsersync{}, + } + // Run test - outBidResponse, err := e.HoldAuction(context.Background(), bidRequest, &emptyUsersync{}, pbsmetrics.Labels{}, &config.Account{}, &categoriesFetcher, nil) + outBidResponse, err := e.HoldAuction(context.Background(), auctionRequest, nil) // Assert no HoldAuction error assert.NoErrorf(t, err, "%s. ex.HoldAuction returned an error: %v \n", test.desc, err) @@ -418,6 +425,7 @@ func TestReturnCreativeEndToEnd(t *testing.T) { e.me = &metricsConf.DummyMetricsEngine{} e.gDPR = gdpr.AlwaysAllow{} e.currencyConverter = currencies.NewRateConverter(&http.Client{}, "", time.Duration(0)) + e.categoriesFetcher = categoriesFetcher // Define mock incoming bid requeset mockBidRequest := &openrtb.BidRequest{ @@ -435,8 +443,14 @@ func TestReturnCreativeEndToEnd(t *testing.T) { for _, test := range testGroup.testCases { mockBidRequest.Ext = test.inExt + auctionRequest := AuctionRequest{ + BidRequest: mockBidRequest, + Account: config.Account{}, + UserSyncs: &emptyUsersync{}, + } + // Run test - outBidResponse, err := e.HoldAuction(context.Background(), mockBidRequest, &emptyUsersync{}, pbsmetrics.Labels{}, &config.Account{}, &categoriesFetcher, nil) + outBidResponse, err := e.HoldAuction(context.Background(), auctionRequest, nil) // Assert return error, if any if testGroup.expectError { @@ -494,7 +508,7 @@ func TestGetBidCacheInfoEndToEnd(t *testing.T) { defer server.Close() currencyConverter := currencies.NewRateConverter(&http.Client{}, "", time.Duration(0)) - e := NewExchange(server.Client(), pbc.NewClient(&http.Client{}, &cfg.CacheURL, &cfg.ExtCacheURL, testEngine), cfg, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), adapters.ParseBidderInfos(cfg.Adapters, "../static/bidder-info", openrtb_ext.BidderList()), gdpr.AlwaysAllow{}, currencyConverter).(*exchange) + e := NewExchange(server.Client(), pbc.NewClient(&http.Client{}, &cfg.CacheURL, &cfg.ExtCacheURL, testEngine), cfg, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), adapters.ParseBidderInfos(cfg.Adapters, "../static/bidder-info", openrtb_ext.BidderList()), gdpr.AlwaysAllow{}, currencyConverter, nilCategoryFetcher{}).(*exchange) /* 3) Build all the parameters e.buildBidResponse(ctx.Background(), liveA... ) needs */ liveAdapters := []openrtb_ext.BidderName{bidderName} @@ -838,7 +852,7 @@ func TestBidResponseCurrency(t *testing.T) { defer server.Close() currencyConverter := currencies.NewRateConverter(&http.Client{}, "", time.Duration(0)) - e := NewExchange(server.Client(), nil, cfg, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), adapters.ParseBidderInfos(cfg.Adapters, "../static/bidder-info", openrtb_ext.BidderList()), gdpr.AlwaysAllow{}, currencyConverter).(*exchange) + e := NewExchange(server.Client(), nil, cfg, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), adapters.ParseBidderInfos(cfg.Adapters, "../static/bidder-info", openrtb_ext.BidderList()), gdpr.AlwaysAllow{}, currencyConverter, nilCategoryFetcher{}).(*exchange) liveAdapters := make([]openrtb_ext.BidderName, 1) liveAdapters[0] = "appnexus" @@ -1010,8 +1024,15 @@ func TestRaceIntegration(t *testing.T) { } theMetrics := pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}) currencyConverter := currencies.NewRateConverter(&http.Client{}, "", time.Duration(0)) - ex := NewExchange(server.Client(), &wellBehavedCache{}, cfg, theMetrics, adapters.ParseBidderInfos(cfg.Adapters, "../static/bidder-info", openrtb_ext.BidderList()), gdpr.AlwaysAllow{}, currencyConverter) - _, err := ex.HoldAuction(context.Background(), newRaceCheckingRequest(t), &emptyUsersync{}, pbsmetrics.Labels{}, &config.Account{}, &categoriesFetcher, nil) + + auctionRequest := AuctionRequest{ + BidRequest: newRaceCheckingRequest(t), + Account: config.Account{}, + UserSyncs: &emptyUsersync{}, + } + + ex := NewExchange(server.Client(), &wellBehavedCache{}, cfg, theMetrics, adapters.ParseBidderInfos(cfg.Adapters, "../static/bidder-info", openrtb_ext.BidderList()), gdpr.AlwaysAllow{}, currencyConverter, categoriesFetcher) + _, err := ex.HoldAuction(context.Background(), auctionRequest, nil) if err != nil { t.Errorf("HoldAuction returned unexpected error: %v", err) } @@ -1095,7 +1116,7 @@ func TestPanicRecovery(t *testing.T) { theMetrics := pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}) currencyConverter := currencies.NewRateConverter(&http.Client{}, "", time.Duration(0)) - e := NewExchange(&http.Client{}, nil, cfg, theMetrics, adapters.ParseBidderInfos(cfg.Adapters, "../static/bidder-info", openrtb_ext.BidderList()), gdpr.AlwaysAllow{}, currencyConverter).(*exchange) + e := NewExchange(&http.Client{}, nil, cfg, theMetrics, adapters.ParseBidderInfos(cfg.Adapters, "../static/bidder-info", openrtb_ext.BidderList()), gdpr.AlwaysAllow{}, currencyConverter, nilCategoryFetcher{}).(*exchange) chBids := make(chan *bidResponseWrapper, 1) panicker := func(aName openrtb_ext.BidderName, coreBidder openrtb_ext.BidderName, request *openrtb.BidRequest, bidlabels *pbsmetrics.AdapterLabels, conversions currencies.Conversions) { panic("panic!") @@ -1160,8 +1181,12 @@ func TestPanicRecoveryHighLevel(t *testing.T) { Endpoint: server.URL, } } + categoriesFetcher, error := newCategoryFetcher("./test/category-mapping") + if error != nil { + t.Errorf("Failed to create a category Fetcher: %v", error) + } currencyConverter := currencies.NewRateConverter(&http.Client{}, "", time.Duration(0)) - e := NewExchange(server.Client(), &mockCache{}, cfg, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), adapters.ParseBidderInfos(cfg.Adapters, "../static/bidder-info", openrtb_ext.BidderList()), gdpr.AlwaysAllow{}, currencyConverter).(*exchange) + e := NewExchange(server.Client(), &mockCache{}, cfg, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), adapters.ParseBidderInfos(cfg.Adapters, "../static/bidder-info", openrtb_ext.BidderList()), gdpr.AlwaysAllow{}, currencyConverter, categoriesFetcher).(*exchange) e.adapterMap[openrtb_ext.BidderBeachfront] = panicingAdapter{} e.adapterMap[openrtb_ext.BidderAppnexus] = panicingAdapter{} @@ -1194,11 +1219,13 @@ func TestPanicRecoveryHighLevel(t *testing.T) { }}, } - categoriesFetcher, error := newCategoryFetcher("./test/category-mapping") - if error != nil { - t.Errorf("Failed to create a category Fetcher: %v", error) + auctionRequest := AuctionRequest{ + BidRequest: request, + Account: config.Account{}, + UserSyncs: &emptyUsersync{}, } - _, err := e.HoldAuction(context.Background(), request, &emptyUsersync{}, pbsmetrics.Labels{}, &config.Account{}, &categoriesFetcher, nil) + + _, err := e.HoldAuction(context.Background(), auctionRequest, nil) if err != nil { t.Errorf("HoldAuction returned unexpected error: %v", err) } @@ -1313,16 +1340,19 @@ func runSpec(t *testing.T, filename string, spec *exchangeSpec) { ex := newExchangeForTests(t, filename, spec.OutgoingRequests, aliases, privacyConfig) biddersInAuction := findBiddersInAuction(t, filename, &spec.IncomingRequest.OrtbRequest) - categoriesFetcher, error := newCategoryFetcher("./test/category-mapping") - if error != nil { - t.Errorf("Failed to create a category Fetcher: %v", error) - } debugLog := &DebugLog{} if spec.DebugLog != nil { *debugLog = *spec.DebugLog debugLog.Regexp = regexp.MustCompile(`[<>]`) } - bid, err := ex.HoldAuction(context.Background(), &spec.IncomingRequest.OrtbRequest, mockIdFetcher(spec.IncomingRequest.Usersyncs), pbsmetrics.Labels{}, &config.Account{}, &categoriesFetcher, debugLog) + + auctionRequest := AuctionRequest{ + BidRequest: &spec.IncomingRequest.OrtbRequest, + Account: config.Account{}, + UserSyncs: mockIdFetcher(spec.IncomingRequest.Usersyncs), + } + + bid, err := ex.HoldAuction(context.Background(), auctionRequest, debugLog) responseTimes := extractResponseTimes(t, filename, bid) for _, bidderName := range biddersInAuction { if _, ok := responseTimes[bidderName]; !ok { @@ -1426,6 +1456,11 @@ func newExchangeForTests(t *testing.T, filename string, expectations map[string] } } + categoriesFetcher, error := newCategoryFetcher("./test/category-mapping") + if error != nil { + t.Fatalf("Failed to create a category Fetcher: %v", error) + } + return &exchange{ adapterMap: adapters, me: metricsConf.NewMetricsEngine(&config.Configuration{}, openrtb_ext.BidderList()), @@ -1435,6 +1470,7 @@ func newExchangeForTests(t *testing.T, filename string, expectations map[string] currencyConverter: currencies.NewRateConverter(&http.Client{}, "", time.Duration(0)), UsersyncIfAmbiguous: privacyConfig.GDPR.UsersyncIfAmbiguous, privacyConfig: privacyConfig, + categoriesFetcher: categoriesFetcher, } } @@ -2503,6 +2539,10 @@ func (f mockIdFetcher) GetId(bidder openrtb_ext.BidderName) (id string, ok bool) return } +func (f mockIdFetcher) LiveSyncCount() int { + return len(f) +} + type validatingBidder struct { t *testing.T fileName string @@ -2673,6 +2713,10 @@ func (e *emptyUsersync) GetId(bidder openrtb_ext.BidderName) (string, bool) { return "", false } +func (e *emptyUsersync) LiveSyncCount() int { + return 0 +} + type mockUsersync struct { syncs map[string]string } @@ -2682,8 +2726,18 @@ func (e *mockUsersync) GetId(bidder openrtb_ext.BidderName) (id string, exists b return } +func (e *mockUsersync) LiveSyncCount() int { + return len(e.syncs) +} + type panicingAdapter struct{} func (panicingAdapter) requestBid(ctx context.Context, request *openrtb.BidRequest, name openrtb_ext.BidderName, bidAdjustment float64, conversions currencies.Conversions, reqInfo *adapters.ExtraRequestInfo) (posb *pbsOrtbSeatBid, errs []error) { panic("Panic! Panic! The world is ending!") } + +type nilCategoryFetcher struct{} + +func (nilCategoryFetcher) FetchCategories(ctx context.Context, primaryAdServer, publisherId, iabCategory string) (string, error) { + return "", nil +} diff --git a/exchange/targeting_test.go b/exchange/targeting_test.go index aaa75411ee4..23a24facd16 100644 --- a/exchange/targeting_test.go +++ b/exchange/targeting_test.go @@ -13,7 +13,6 @@ import ( "github.com/prebid/prebid-server/gdpr" - "github.com/prebid/prebid-server/pbsmetrics" metricsConf "github.com/prebid/prebid-server/pbsmetrics/config" metricsConfig "github.com/prebid/prebid-server/pbsmetrics/config" @@ -82,6 +81,11 @@ func runTargetingAuction(t *testing.T, mockBids map[openrtb_ext.BidderName][]*op server := httptest.NewServer(http.HandlerFunc(mockServer)) defer server.Close() + categoriesFetcher, error := newCategoryFetcher("./test/category-mapping") + if error != nil { + t.Errorf("Failed to create a category Fetcher: %v", error) + } + ex := &exchange{ adapterMap: buildAdapterMap(mockBids, server.URL, server.Client()), me: &metricsConf.DummyMetricsEngine{}, @@ -90,6 +94,7 @@ func runTargetingAuction(t *testing.T, mockBids map[openrtb_ext.BidderName][]*op gDPR: gdpr.AlwaysAllow{}, currencyConverter: currencies.NewRateConverter(&http.Client{}, "", time.Duration(0)), UsersyncIfAmbiguous: false, + categoriesFetcher: categoriesFetcher, } imps := buildImps(t, mockBids) @@ -104,11 +109,13 @@ func runTargetingAuction(t *testing.T, mockBids map[openrtb_ext.BidderName][]*op req.Site = &openrtb.Site{} } - categoriesFetcher, error := newCategoryFetcher("./test/category-mapping") - if error != nil { - t.Errorf("Failed to create a category Fetcher: %v", error) + auctionRequest := AuctionRequest{ + BidRequest: req, + Account: config.Account{}, + UserSyncs: &emptyUsersync{}, } - bidResp, err := ex.HoldAuction(context.Background(), req, &mockFetcher{}, pbsmetrics.Labels{}, &config.Account{}, &categoriesFetcher, nil) + + bidResp, err := ex.HoldAuction(context.Background(), auctionRequest, nil) if err != nil { t.Fatalf("Unexpected errors running auction: %v", err) @@ -238,12 +245,6 @@ func (m *mockTargetingBidder) MakeBids(internalRequest *openrtb.BidRequest, exte return bidResponse, nil } -type mockFetcher struct{} - -func (f *mockFetcher) GetId(bidder openrtb_ext.BidderName) (string, bool) { - return "", false -} - func mockServer(w http.ResponseWriter, req *http.Request) { w.Write([]byte("{}")) } diff --git a/router/router.go b/router/router.go index 919781f7e30..07021481ebf 100644 --- a/router/router.go +++ b/router/router.go @@ -6,13 +6,14 @@ import ( "database/sql" "encoding/json" "fmt" - "github.com/prebid/prebid-server/endpoints/events" "io/ioutil" "net/http" "path/filepath" "strings" "time" + "github.com/prebid/prebid-server/endpoints/events" + "github.com/prebid/prebid-server/pbsmetrics" "github.com/prebid/prebid-server/adapters" @@ -242,21 +243,21 @@ func New(cfg *config.Configuration, rateConvertor *currencies.RateConverter) (r exchanges = newExchangeMap(cfg) cacheClient := pbc.NewClient(cacheHttpClient, &cfg.CacheURL, &cfg.ExtCacheURL, r.MetricsEngine) - theExchange := exchange.NewExchange(generalHttpClient, cacheClient, cfg, r.MetricsEngine, bidderInfos, gdprPerms, rateConvertor) + theExchange := exchange.NewExchange(generalHttpClient, cacheClient, cfg, r.MetricsEngine, bidderInfos, gdprPerms, rateConvertor, categoriesFetcher) - openrtbEndpoint, err := openrtb2.NewEndpoint(theExchange, paramsValidator, fetcher, accounts, categoriesFetcher, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBiddersMap) + openrtbEndpoint, err := openrtb2.NewEndpoint(theExchange, paramsValidator, fetcher, accounts, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBiddersMap) if err != nil { glog.Fatalf("Failed to create the openrtb endpoint handler. %v", err) } - ampEndpoint, err := openrtb2.NewAmpEndpoint(theExchange, paramsValidator, ampFetcher, accounts, categoriesFetcher, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBiddersMap) + ampEndpoint, err := openrtb2.NewAmpEndpoint(theExchange, paramsValidator, ampFetcher, accounts, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBiddersMap) if err != nil { glog.Fatalf("Failed to create the amp endpoint handler. %v", err) } - videoEndpoint, err := openrtb2.NewVideoEndpoint(theExchange, paramsValidator, fetcher, videoFetcher, accounts, categoriesFetcher, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBiddersMap, cacheClient) + videoEndpoint, err := openrtb2.NewVideoEndpoint(theExchange, paramsValidator, fetcher, videoFetcher, accounts, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBiddersMap, cacheClient) if err != nil { glog.Fatalf("Failed to create the video endpoint handler. %v", err) }