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

New Adapter: ResetDigital #3766

Open
wants to merge 82 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
70de190
New Adapter: ResetDigital
bruno-siira Feb 5, 2024
dd48470
Fix to have the a bid forced on testing
bruno-siira Feb 7, 2024
32551fc
Merge branch 'prebid:master' into master
bruno-siira Feb 7, 2024
125124b
Merge branch 'prebid:master' into master
bruno-siira Feb 9, 2024
5c56e12
Test changes
bruno-siira Feb 9, 2024
fe4ff39
Merge branch 'prebid:master' into master
bruno-siira Feb 13, 2024
664614f
Merge branch 'master' of https://github.com/bruno-siira/prebid-server
bruno-siira Feb 13, 2024
0b44384
Merge branch 'prebid:master' into master
bruno-siira Feb 21, 2024
0775c72
Merge branch 'master' of https://github.com/bruno-siira/prebid-server
bruno-siira Feb 26, 2024
20fa856
Add file
bruno-siira Feb 28, 2024
33f4603
Added schema for adapter
bruno-siira Feb 28, 2024
e468217
Merge branch 'prebid:master' into master
bruno-siira Mar 17, 2024
b8ca566
Unused builder removed
bruno-siira Mar 18, 2024
2de7781
Fix to lack of builder
bruno-siira Mar 24, 2024
eb067f7
Change of data on export
bruno-siira Mar 26, 2024
86206d7
no need to include `required` if its empty
bruno-siira Apr 14, 2024
3fc5455
Resolving https://github.com/prebid/prebid-server/pull/3452
BrunoJacinto May 14, 2024
3762676
Merge branch 'prebid:master' into master
bruno-siira Jun 20, 2024
989c565
New Adapter: ResetDigital #3766
bruno-siira Jul 3, 2024
39905ed
Fix naming
bruno-siira Jul 5, 2024
4482bc9
Fix naming of Var
bruno-siira Jul 5, 2024
d426e8a
Fix PR New Adapter: ResetDigital #3766
bruno-siira Jul 9, 2024
ac2fc01
Fix New Adapter: ResetDigital #3766
bruno-siira Jul 9, 2024
52a6794
Fix multiple comments
bruno-siira Jul 16, 2024
9626103
New tests
bruno-siira Jul 18, 2024
dea6cf7
Fix http.StatusBadRequest and non http.StatusOK codes should not be e…
bruno-siira Jul 24, 2024
5cfe0ae
Not running tests at this momment
bruno-siira Aug 16, 2024
ece8152
Update with help of Xandr Team
bruno-siira Aug 29, 2024
baa553c
Simplify Tests
bruno-siira Aug 29, 2024
ecc90bb
PR of functioning version
bruno-siira Sep 10, 2024
0d54a8d
Added Video and removed unwanted data
bruno-siira Sep 29, 2024
660dba7
created mock test
ogbonnaEmmanuel Oct 25, 2024
5f70f11
delete fake_test.json
ogbonnaEmmanuel Oct 31, 2024
613317a
Merge pull request #1 from ogbonnaEmmanuel/master
dirk-rd Oct 31, 2024
a083c03
Adding support for audio media type and a corresponding simple-audio.…
dirk-rd Nov 3, 2024
bc7caaf
Fix slice append syntax.
dirk-rd Nov 4, 2024
4569e97
Removed zero check for bid response and moved HTTP headers into separ…
dirk-rd Nov 4, 2024
0bc2aeb
Adding test case for missing currency to improve test coverage percen…
dirk-rd Nov 4, 2024
d212d91
Merge pull request #2 from bruno-siira/add-audio
bruno-siira Nov 4, 2024
cff2442
New Adapter: ResetDigital
bruno-siira Feb 5, 2024
44bee69
Fix to have the a bid forced on testing
bruno-siira Feb 7, 2024
96fde76
Test changes
bruno-siira Feb 9, 2024
6e08b5d
Add file
bruno-siira Feb 28, 2024
ec4005d
Added schema for adapter
bruno-siira Feb 28, 2024
fd3ec0d
Unused builder removed
bruno-siira Mar 18, 2024
8bca6ad
Fix to lack of builder
bruno-siira Mar 24, 2024
278be3f
Change of data on export
bruno-siira Mar 26, 2024
56a77a0
no need to include `required` if its empty
bruno-siira Apr 14, 2024
f0e2574
Resolving https://github.com/prebid/prebid-server/pull/3452
BrunoJacinto May 14, 2024
0e365ce
New Adapter: ResetDigital #3766
bruno-siira Jul 3, 2024
f2d3afc
Fix naming
bruno-siira Jul 5, 2024
d6e24d0
Fix naming of Var
bruno-siira Jul 5, 2024
eceef87
Fix PR New Adapter: ResetDigital #3766
bruno-siira Jul 9, 2024
e86d017
Fix New Adapter: ResetDigital #3766
bruno-siira Jul 9, 2024
baa974f
Fix multiple comments
bruno-siira Jul 16, 2024
73c3fe0
New tests
bruno-siira Jul 18, 2024
246010f
Fix http.StatusBadRequest and non http.StatusOK codes should not be e…
bruno-siira Jul 24, 2024
cff5817
Not running tests at this momment
bruno-siira Aug 16, 2024
5ab5517
Update with help of Xandr Team
bruno-siira Aug 29, 2024
d3df8f2
Simplify Tests
bruno-siira Aug 29, 2024
c1795b8
PR of functioning version
bruno-siira Sep 10, 2024
1665bc9
Added Video and removed unwanted data
bruno-siira Sep 29, 2024
0f6f5b1
created mock test
ogbonnaEmmanuel Oct 25, 2024
27863db
delete fake_test.json
ogbonnaEmmanuel Oct 31, 2024
f0da5d7
Adding support for audio media type and a corresponding simple-audio.…
dirk-rd Nov 3, 2024
6c745fb
Fix slice append syntax.
dirk-rd Nov 4, 2024
56b03f1
Removed zero check for bid response and moved HTTP headers into separ…
dirk-rd Nov 4, 2024
21eecdd
Adding test case for missing currency to improve test coverage percen…
dirk-rd Nov 4, 2024
dcd9dad
COmmit
bruno-siira Nov 4, 2024
2584c6b
Changing the version to V3
bruno-siira Nov 4, 2024
123cb13
Renaming test JSON files
dirk-rd Nov 21, 2024
4950da1
Deleting errant -vv file
dirk-rd Nov 21, 2024
cc06d05
Simplying HTML test markup.
dirk-rd Nov 21, 2024
330d84f
Reverting unnecessary changes.
dirk-rd Nov 25, 2024
17cf6c8
Adding test cases via JSON to increase coverage.
dirk-rd Dec 1, 2024
5b44280
Removing keys with null values.
dirk-rd Dec 1, 2024
ee3546c
Removing unnecessary keys and fixing redirect URL.
dirk-rd Dec 1, 2024
2ecc9a8
Ignore test coverage output.
dirk-rd Dec 1, 2024
0a4d9bc
Remove unnecessary test case.
dirk-rd Dec 1, 2024
b93dca3
Formattting; removed comments; simplified GetMediaTypeForImp.
dirk-rd Dec 1, 2024
ef65f7b
Merge branch 'prebid:master' into master
dirk-rd Dec 2, 2024
6bac6cd
Merge pull request #3 from bruno-siira/pr-review-comments-11-13-24
dirk-rd Dec 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions adapters/resetdigital/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Ignore test coverage output
cover.out
307 changes: 307 additions & 0 deletions adapters/resetdigital/resetdigital.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,307 @@
package resetdigital

import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"text/template"

"github.com/prebid/openrtb/v20/openrtb2"
"github.com/prebid/prebid-server/v3/adapters"
"github.com/prebid/prebid-server/v3/config"
"github.com/prebid/prebid-server/v3/openrtb_ext"
)

type adapter struct {
endpoint *template.Template
endpointUri string
}

type resetDigitalRequest struct {
Site resetDigitalSite `json:"site"`
Imps []resetDigitalImp `json:"imps"`
}
type resetDigitalSite struct {
Domain string `json:"domain"`
Referrer string `json:"referrer"`
}
type resetDigitalImp struct {
ZoneID resetDigitalImpZone `json:"zone_id"`
BidID string `json:"bid_id"`
ImpID string `json:"imp_id"`
Ext resetDigitalImpExt `json:"ext"`
MediaTypes resetDigitalMediaTypes `json:"media_types"`
}
type resetDigitalImpZone struct {
PlacementID string `json:"placementId"`
}
type resetDigitalImpExt struct {
Gpid string `json:"gpid"`
}
type resetDigitalMediaTypes struct {
Banner resetDigitalMediaType `json:"banner,omitempty"`
Video resetDigitalMediaType `json:"video,omitempty"`
Audio resetDigitalMediaType `json:"audio,omitempty"`
}
type resetDigitalMediaType struct {
Sizes [][]int64 `json:"sizes,omitempty"`
Mimes []string `json:"mimes,omitempty"`
}
type resetDigitalBidResponse struct {
Bids []resetDigitalBid `json:"bids"`
}
type resetDigitalBid struct {
BidID string `json:"bid_id"`
ImpID string `json:"imp_id"`
CPM float64 `json:"cpm"`
CID string `json:"cid,omitempty"`
CrID string `json:"crid,omitempty"`
AdID string `json:"adid"`
W string `json:"w,omitempty"`
H string `json:"h,omitempty"`
Seat string `json:"seat"`
HTML string `json:"html"`
}

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{}

addNonEmptyHeaders(&headers, map[string]string{
"Content-Type": "application/json;charset=utf-8",
"Accept": "application/json",
})

if request != nil && request.Device != nil {
addNonEmptyHeaders(&headers, map[string]string{
"Accept-Language": request.Device.Language,
"User-Agent": request.Device.UA,
"X-Forwarded-For": request.Device.IP,
"X-Real-Ip": request.Device.IP,
})
}
if request != nil && request.Site != nil {
addNonEmptyHeaders(&headers, map[string]string{
"Referer": request.Site.Page,
})
}

return headers
}

func addNonEmptyHeaders(headers *http.Header, headerValues map[string]string) {
for key, value := range headerValues {
if len(value) > 0 {
headers.Add(key, value)
}
}
}

func (a *adapter) MakeRequests(requestData *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
var (
requests []*adapters.RequestData
errors []error
)

for _, imp := range requestData.Imp {
bidType, err := getBidType(imp)
if err != nil {
errors = append(errors, err)
continue
Comment on lines +120 to +121
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code path is not covered. should add json tests to improve coverage

}

splittedRequestData, err := processDataFromRequest(requestData, imp, bidType)
if err != nil {
errors = append(errors, err)
continue
Comment on lines +126 to +127
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code path is not covered. should add json tests to improve coverage

}

requestBody, err := json.Marshal(splittedRequestData)

if err != nil {
errors = append(errors, err)
continue
}

requests = append(requests, &adapters.RequestData{
Method: "POST",
Uri: a.endpointUri,
Body: requestBody,
Headers: getHeaders(requestData),
ImpIDs: []string{imp.ID},
})
}

return requests, errors
}

func processDataFromRequest(requestData *openrtb2.BidRequest, imp openrtb2.Imp, bidType openrtb_ext.BidType) (resetDigitalRequest, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's a suggestion to make this function a bit easier to read:

func processDataFromRequest(requestData *openrtb2.BidRequest, imp openrtb2.Imp, bidType openrtb_ext.BidType) (resetDigitalRequest, error) {
	var reqData resetDigitalRequest

	if requestData.Site != nil {
		reqData.Site.Domain = requestData.Site.Domain
		reqData.Site.Referrer = requestData.Site.Page
	}

	rdImp := resetDigitalImp{
		BidID: requestData.ID,
		ImpID: imp.ID,
	}

	if bidType == openrtb_ext.BidTypeBanner && imp.Banner != nil {
		var tempH, tempW int64
		if imp.Banner.H != nil {
			tempH = *imp.Banner.H
		}
		if imp.Banner.W != nil {
			tempW = *imp.Banner.W
		}
		if tempH > 0 && tempW > 0 {
			rdImp.MediaTypes.Banner.Sizes = append(rdImp.MediaTypes.Banner.Sizes, []int64{tempW, tempH})
		}
	}
	if bidType == openrtb_ext.BidTypeVideo && imp.Video != nil {
		var tempH, tempW int64
		if imp.Video.H != nil {
			tempH = *imp.Video.H
		}
		if imp.Video.W != nil {
			tempW = *imp.Video.W
		}
		if tempH > 0 && tempW > 0 {
			rdImp.MediaTypes.Video.Sizes = append(rdImp.MediaTypes.Video.Sizes, []int64{tempW, tempH})
		}
		if imp.Video.MIMEs != nil {
			rdImp.MediaTypes.Video.Mimes = append(rdImp.MediaTypes.Video.Mimes, imp.Video.MIMEs...)
		}
	}
	if bidType == openrtb_ext.BidTypeAudio && imp.Audio != nil && imp.Audio.MIMEs != nil {
		rdImp.MediaTypes.Audio.Mimes = append(rdImp.MediaTypes.Audio.Mimes, imp.Audio.MIMEs...)
	}

	var bidderExt adapters.ExtImpBidder
	var resetDigitalExt openrtb_ext.ImpExtResetDigital

	if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
		return resetDigitalRequest{}, err
	}
	if err := json.Unmarshal(bidderExt.Bidder, &resetDigitalExt); err != nil {
		return resetDigitalRequest{}, err
	}
	rdImp.ZoneID.PlacementID = resetDigitalExt.PlacementID

	reqData.Imps = append(reqData.Imps, rdImp)

	return reqData, nil
}

var reqData resetDigitalRequest

if requestData.Site != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need to handle App data?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed offline. We do not need to handle app data.

reqData.Site.Domain = requestData.Site.Domain
reqData.Site.Referrer = requestData.Site.Page
}

rdImp := resetDigitalImp{
BidID: requestData.ID,
ImpID: imp.ID,
}

if bidType == openrtb_ext.BidTypeBanner && imp.Banner != nil {
var tempH, tempW int64
if imp.Banner.H != nil {
tempH = *imp.Banner.H
}
if imp.Banner.W != nil {
tempW = *imp.Banner.W
}
if tempH > 0 && tempW > 0 {
rdImp.MediaTypes.Banner.Sizes = append(rdImp.MediaTypes.Banner.Sizes, []int64{tempW, tempH})
}
}
if bidType == openrtb_ext.BidTypeVideo && imp.Video != nil {
var tempH, tempW int64
if imp.Video.H != nil {
tempH = *imp.Video.H
}
if imp.Video.W != nil {
tempW = *imp.Video.W
}
if tempH > 0 && tempW > 0 {
rdImp.MediaTypes.Video.Sizes = append(rdImp.MediaTypes.Video.Sizes, []int64{tempW, tempH})
}
if imp.Video.MIMEs != nil {
rdImp.MediaTypes.Video.Mimes = append(rdImp.MediaTypes.Video.Mimes, imp.Video.MIMEs...)
}
}
if bidType == openrtb_ext.BidTypeAudio && imp.Audio != nil && imp.Audio.MIMEs != nil {
rdImp.MediaTypes.Audio.Mimes = append(rdImp.MediaTypes.Audio.Mimes, imp.Audio.MIMEs...)
}

var bidderExt adapters.ExtImpBidder
var resetDigitalExt openrtb_ext.ImpExtResetDigital

if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
return resetDigitalRequest{}, err
}
if err := json.Unmarshal(bidderExt.Bidder, &resetDigitalExt); err != nil {
return resetDigitalRequest{}, err
}
rdImp.ZoneID.PlacementID = resetDigitalExt.PlacementID

reqData.Imps = append(reqData.Imps, rdImp)

return reqData, 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 resetDigitalBidResponse
if err := json.Unmarshal(responseData.Body, &response); err != nil {
return nil, []error{err}
}

bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp))

var errs []error
requestImps := make(map[string]openrtb2.Imp)
for _, imp := range request.Imp {
requestImps[imp.ID] = imp
}

for i := range response.Bids {
resetDigitalBid := &response.Bids[i]

bid, err := getBidFromResponse(resetDigitalBid)
if bid == nil {
errs = append(errs, err)
continue
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code path is not covered. should add json tests to improve coverage

}

bidType, err := GetMediaTypeForImp(requestImps[bid.ImpID])
if err != nil {
errs = append(errs, err)
continue
}

b := &adapters.TypedBid{
Bid: bid,
BidType: bidType,
Seat: openrtb_ext.BidderName(resetDigitalBid.Seat),
}
bidResponse.Bids = append(bidResponse.Bids, b)
}

if len(request.Cur) == 0 {
bidResponse.Currency = "USD"
}

return bidResponse, errs
}

func getBidFromResponse(bidResponse *resetDigitalBid) (*openrtb2.Bid, error) {

bid := &openrtb2.Bid{
ID: bidResponse.BidID,
Price: bidResponse.CPM,
ImpID: bidResponse.ImpID,
CID: bidResponse.CID,
CrID: bidResponse.CrID,
AdM: bidResponse.HTML,
}

w, err := strconv.ParseInt(bidResponse.W, 10, 64)
if err != nil {
return nil, err
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add test coverage for this line by adding a supplemental JSON test invalid-bid-width.json.

}
bid.W = w

h, err := strconv.ParseInt(bidResponse.H, 10, 64)
if err != nil {
return nil, err
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add test coverage for this line by adding a supplemental JSON test invalid-bid-height.json.

}
bid.H = h
return bid, nil
}

func getBidType(imp openrtb2.Imp) (openrtb_ext.BidType, error) {
if imp.Banner != nil {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider this as a suggestion. The current implementation follows an anti-pattern, assumes that if there is a multi-format request, the media type defaults to openrtb_ext.BidTypeBanner, nil. 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 field in the response to accurately determine the media type for the impression.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented as suggested

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented as suggested

could you point out or link where MType changes are implemented?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, it was addressed on the point that we support only single format bids, so we could assume the anti pattern. Anyway, it would be more advisable to change to the normal pattern?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway, it would be more advisable to change to the normal pattern?

Prebid team recommends using MType field. But if it's not doable then current change suffices single format bid. @bruno-siira should mention in Bidder docs that adapter expects only single format bids in the incoming request

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we're talking about the Bidder Docs what is this file exacly @onkarvhanumante

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return openrtb_ext.BidTypeBanner, nil
} else if imp.Video != nil {
bruno-siira marked this conversation as resolved.
Show resolved Hide resolved
return openrtb_ext.BidTypeVideo, nil
} else if imp.Audio != nil {
bruno-siira marked this conversation as resolved.
Show resolved Hide resolved
return openrtb_ext.BidTypeAudio, nil
}

return "", fmt.Errorf("failed to find matching imp for bid %s", imp.ID)
Comment on lines +290 to +295
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code path is not covered. should add json tests to improve coverage

}

func GetMediaTypeForImp(reqImp openrtb2.Imp) (openrtb_ext.BidType, error) {

if reqImp.Video != nil {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider this as a suggestion. The current implementation follows an anti-pattern, assumes that if there is a multi-format request, the media type defaults to openrtb_ext.BidTypeVideo, nil. 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 field in the response to accurately determine the media type for the impression.

return openrtb_ext.BidTypeVideo, nil
}
if reqImp.Audio != nil {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider this as a suggestion. The current implementation follows an anti-pattern, assumes that if there is a multi-format request, the media type defaults to openrtb_ext.BidTypeAudio, nil. 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 field in the response to accurately determine the media type for the impression.

return openrtb_ext.BidTypeAudio, nil
}
return openrtb_ext.BidTypeBanner, nil
}
21 changes: 21 additions & 0 deletions adapters/resetdigital/resetdigital_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package resetdigital

import (
"testing"

"github.com/prebid/prebid-server/v3/adapters/adapterstest"
"github.com/prebid/prebid-server/v3/config"
"github.com/prebid/prebid-server/v3/openrtb_ext"
)

func TestJsonSamples(t *testing.T) {

bidder, buildErr := Builder(openrtb_ext.BidderResetDigital, config.Adapter{
Endpoint: "https://test.com"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})

if buildErr != nil {
t.Fatalf("Builder returned unexpected error %v", buildErr)
}

adapterstest.RunJSONBidderTest(t, "resetdigitaltest", bidder)
}
Loading
Loading