Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modularity: Make request wrapper accessible in bidder request hook #3096

Merged
merged 9 commits into from
Nov 16, 2023
7 changes: 6 additions & 1 deletion exchange/bidder.go
Original file line number Diff line number Diff line change
Expand Up @@ -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}
}
Expand All @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions exchange/exchange_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5620,12 +5620,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",
)
Expand Down
10 changes: 5 additions & 5 deletions hooks/hookexecution/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
}

Expand Down
4 changes: 2 additions & 2 deletions hooks/hookexecution/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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.")
Expand Down
14 changes: 7 additions & 7 deletions hooks/hookexecution/mocks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")

Expand All @@ -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")

Expand Down Expand Up @@ -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
}
Expand All @@ -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",
)
Expand All @@ -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",
)
Expand Down
7 changes: 3 additions & 4 deletions hooks/hookstage/bidderrequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
}
10 changes: 5 additions & 5 deletions hooks/hookstage/bidderrequest_mutations.go
Original file line number Diff line number Diff line change
Expand Up @@ -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] {
Expand All @@ -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")
}
Expand Down
2 changes: 1 addition & 1 deletion hooks/hookstage/processedauctionrequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
20 changes: 10 additions & 10 deletions modules/prebid/ortb2blocking/hook_bidderrequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}

Expand Down Expand Up @@ -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
}

Expand All @@ -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
}

Expand All @@ -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
}

Expand Down Expand Up @@ -191,7 +191,7 @@ func updateCatTax(
attributes *blockingAttributes,
changeSet *hookstage.ChangeSet[hookstage.BidderRequestPayload],
) {
if payload.BidRequest.CatTax > 0 {
if payload.Request.CatTax > 0 {
return
}

Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
9 changes: 6 additions & 3 deletions modules/prebid/ortb2blocking/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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.")
Expand All @@ -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]{}
Expand Down
Loading