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: AdUp Tech #4076

Merged
merged 11 commits into from
Jan 30, 2025
Merged

Conversation

danygielow
Copy link
Contributor

@danygielow danygielow commented Nov 26, 2024

Hello,

We as AdUp Technology want to add our own Prebid Server Adapter.
We already have a PrebidJS Adapter.

Docs: prebid/prebid.github.io#5728

}

func getBidType(markupType openrtb2.MarkupType) (openrtb_ext.BidType, error) {
switch markupType {

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. 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.

}

func getBidType(markupType openrtb2.MarkupType) (openrtb_ext.BidType, error) {
switch markupType {

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.BidTypeNative. 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

Code coverage summary

Note:

  • Prebid team doesn't anticipate tests covering code paths that might result in marshal and unmarshal errors
  • Coverage summary encompasses all commits leading up to the latest one, 74112fe

aduptech

Refer here for heat map coverage report

github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:23:	Builder		100.0%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:32:	MakeRequests	53.8%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:63:	convertCurrency	0.0%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:90:	MakeBids	63.6%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:136:	getBidType	75.0%
total:									(statements)	49.1%

}

func getBidType(markupType openrtb2.MarkupType) (openrtb_ext.BidType, error) {
switch markupType {

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. 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.

}

func getBidType(markupType openrtb2.MarkupType) (openrtb_ext.BidType, error) {
switch markupType {

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.BidTypeNative. 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
Contributor Author

Choose a reason for hiding this comment

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

What should be changed here? I assume this check is wrong, because we do exactly what the comment suggests.

Copy link
Contributor

Choose a reason for hiding this comment

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

💯 this suggestion (x3?) is not very helpful

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure why this is triggering but you can ignore it.

Copy link

Code coverage summary

Note:

  • Prebid team doesn't anticipate tests covering code paths that might result in marshal and unmarshal errors
  • Coverage summary encompasses all commits leading up to the latest one, 8e94b4b

aduptech

Refer here for heat map coverage report

github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:23:	Builder		100.0%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:32:	MakeRequests	84.6%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:63:	convertCurrency	75.0%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:90:	MakeBids	63.6%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:136:	getBidType	75.0%
total:									(statements)	73.6%

@bsardo bsardo added the adapter label Jan 6, 2025
@bsardo
Copy link
Collaborator

bsardo commented Jan 6, 2025

@scr-oath can you please review?

@bsardo
Copy link
Collaborator

bsardo commented Jan 7, 2025

@pm-isha-bharti can you please review?

func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
bidder := &adapter{
endpoint: config.Endpoint,
target_currency: "EUR",
Copy link
Contributor

Choose a reason for hiding this comment

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

question: Can this go into ExtraAdapterInfo (either directly or as json that's parsed or inspected maybe with gjson.Get) rather than being hard coded?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to use ExtraAdapterInfo.


convertedValue, err := a.convertCurrency(imp.BidFloor, imp.BidFloorCur, reqInfo)
if err != nil {
return nil, err
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: This return doesn't seem right - as it should be []error - perhaps, if convertCurrency returns a []error, it should be named errs rather than err which suggests a single error as the type.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

convertCurrency doesn't have to return []error. Refactored to just return a single error.

}

requestData := &adapters.RequestData{
Method: "POST",
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Method: "POST",
Method: http.MethodPost,


// try again by first converting to USD
// then convert to target_currency
convertedValue, err = reqInfo.ConvertCurrency(value, cur, "USD")
Copy link
Contributor

Choose a reason for hiding this comment

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

observation we should have constants or an enum of valid currencies… you can ignore for this PR but just making the note; filed #4134

Comment on lines 91 to 115
if responseData.StatusCode == http.StatusNoContent {
return nil, nil
}

if responseData.StatusCode == http.StatusBadRequest {
err := &errortypes.BadInput{
Message: "Unexpected status code: 400. Run with request.debug = 1 for more info.",
}
return nil, []error{err}
}

if responseData.StatusCode != http.StatusOK {
err := &errortypes.BadServerResponse{
Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info.", responseData.StatusCode),
}
return nil, []error{err}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

question: would a switch on the statusCode (with empty for ok and default clause for this everything-else case) be more readable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refactored into a switch

Comment on lines 118 to 140
for _, seatBid := range response.SeatBid {
for i, bid := range seatBid.Bid {
bidType, err := getBidType(bid.MType)
if err != nil {
errs = append(errs, err)
continue
}

bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
Bid: &seatBid.Bid[i],
BidType: bidType,
})
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: I don't like making copies of the seatbid and bid in a loop

Suggested change
for _, seatBid := range response.SeatBid {
for i, bid := range seatBid.Bid {
bidType, err := getBidType(bid.MType)
if err != nil {
errs = append(errs, err)
continue
}
bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
Bid: &seatBid.Bid[i],
BidType: bidType,
})
}
}
for i := range response.SeatBid {
seatBid = &response.SeatBid[i]
for j := range seatBid.Bid {
bid := &seatBid.Bid[j]
bidType, err := getBidType(bid.MType)
if err != nil {
errs = append(errs, err)
continue
}
bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
Bid: bid,
BidType: bidType,
})
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Used your suggestion

}

func getBidType(markupType openrtb2.MarkupType) (openrtb_ext.BidType, error) {
switch markupType {
Copy link
Contributor

Choose a reason for hiding this comment

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

💯 this suggestion (x3?) is not very helpful

Comment on lines 15 to 17
if buildErr != nil {
t.Fatalf("Builder returned unexpected error %v", buildErr)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, good to know. This is our first time working in Go.

Copy link
Contributor

@scr-oath scr-oath Jan 8, 2025

Choose a reason for hiding this comment

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

suggestion: Change assert to require

For what it's worth, I realize you were calling fatal before so I realize you need the require.NoError - assertions from the assert module continue but the test fails whereas those from require halt immediately. This is kind of like google's gtest with its two variants for each assertion so when you can continue you report more/all things that fail but when you can't, you don't.

Comment on lines 59 to 61
if err := validator.Validate(openrtb_ext.BidderAdUpTech, json.RawMessage(invalidParam)); err == nil {
t.Errorf("Schema allowed unexpected params: %s", invalidParam)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if err := validator.Validate(openrtb_ext.BidderAdUpTech, json.RawMessage(invalidParam)); err == nil {
t.Errorf("Schema allowed unexpected params: %s", invalidParam)
}
assert.NoErrorf(t, validator.Validate(openrtb_ext.BidderAdUpTech, json.RawMessage(invalidParam)), "Schema allowed unexpected params: %s", invalidParam)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

using assert.Errorf here, but otherwise used the suggestion.

Copy link
Contributor

@scr-oath scr-oath left a comment

Choose a reason for hiding this comment

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

I didn't mean to approve before… I thought I had ticked request changes…

@derfryday derfryday force-pushed the feat/add-aduptech-adapter branch from 8e94b4b to 2ad858d Compare January 8, 2025 07:54
}

func getBidType(markupType openrtb2.MarkupType) (openrtb_ext.BidType, error) {
switch markupType {
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.BidTypeBanner. 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.

}

func getBidType(markupType openrtb2.MarkupType) (openrtb_ext.BidType, error) {
switch markupType {
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.BidTypeNative. 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

github-actions bot commented Jan 8, 2025

Code coverage summary

Note:

  • Prebid team doesn't anticipate tests covering code paths that might result in marshal and unmarshal errors
  • Coverage summary encompasses all commits leading up to the latest one, 2ad858d

aduptech

Refer here for heat map coverage report

github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:27:	Builder		80.0%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:41:	MakeRequests	84.6%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:72:	convertCurrency	75.0%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:99:	MakeBids	71.4%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:145:	getBidType	75.0%
total:									(statements)	76.4%

- banner
- native
userSync:
redirect:
Copy link
Contributor

@pm-isha-bharti pm-isha-bharti Jan 8, 2025

Choose a reason for hiding this comment

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

@danygielow The usersync URL returned by the /cookie_sync for aduptech is currently throwing 404. Can you please check if the URLs added for userSync are correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed sync Endpoint.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Verified redirect works with id set in cookie:
Screenshot 2025-01-21 at 12 32 36 PM

func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
switch responseData.StatusCode {
case http.StatusNoContent:
return nil, nil
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add a supplemental JSON test where your mock response returns a 204 status code.


var response openrtb2.BidResponse
if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil {
return nil, []error{err}
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add a supplemental JSON test where your mock response returns a bid response that fails to unmarshal successfully. This can be achieved by setting one of the fields to an incorrect data type.

switch responseData.StatusCode {
case http.StatusNoContent:
return nil, nil
case http.StatusBadRequest:
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add a supplemental JSON test where your mock response returns a 400 status code.

func (a *adapter) convertCurrency(value float64, cur string, reqInfo *adapters.ExtraRequestInfo) (float64, error) {
convertedValue, err := reqInfo.ConvertCurrency(value, cur, a.extraInfo.TargetCurrency)

if err != nil {
Copy link
Contributor

@pm-isha-bharti pm-isha-bharti Jan 8, 2025

Choose a reason for hiding this comment

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

Please add supplemental JSONs for currency conversion failures

bidder, buildErr := Builder(openrtb_ext.BidderAdUpTech, config.Adapter{
Endpoint: "https://example.com/rtb/bid", ExtraAdapterInfo: "{\"target_currency\": \"EUR\"}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})

assert.NoError(t, buildErr, "Builder returned unexpected error")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
assert.NoError(t, buildErr, "Builder returned unexpected error")
require.NoError(t, buildErr, "Builder returned unexpected error")

package aduptech

import (
"github.com/stretchr/testify/assert"
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

}

for _, validParam := range validParams {
assert.NoErrorf(t, validator.Validate(openrtb_ext.BidderAdUpTech, json.RawMessage(validParam)), "Schema rejected Aduptech params: %s", validParam)
Copy link
Contributor

Choose a reason for hiding this comment

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

FWIW, assert seems correct here as you want all failing assertions reported

@bsardo
Copy link
Collaborator

bsardo commented Jan 8, 2025

Hi @danygielow, @derfryday, now that the review process has begun, can you please push new commits when making changes instead of rebasing and force pushing? It will save reviewers a lot of time when performing delta reviews. All of the commits will be squashed when we merge. Thanks!

func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
var extraInfo ExtraInfo
if err := jsonutil.Unmarshal([]byte(config.ExtraAdapterInfo), &extraInfo); err != nil {
return nil, fmt.Errorf("invalid extra info: %v", err)
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: Use %w instead - see https://pkg.go.dev/fmt#Errorf

Suggested change
return nil, fmt.Errorf("invalid extra info: %v", err)
return nil, fmt.Errorf("invalid extra info: %w", err)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to %w

return nil, []error{err}
}

imp.BidFloorCur = a.extraInfo.TargetCurrency
Copy link
Contributor

@scr-oath scr-oath Jan 9, 2025

Choose a reason for hiding this comment

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

bug?: There seems like a bug in here somewhere… the convertCurrency has a path that can handle errors and, instead, convert to "USD" - how is that choice made here if you always set the BidFloorCur to a.extraInfo.TargetCurrency - should you pass in a pointer to the extraInfo and set the chosen currency in the convertCurrency method maybe? or return the choice back and set to that? Style is your choice, but I think that's an unhandled case and might deserve some unit tests to prove it works as intended.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi, we try to be ready for the eventuality of conversion rates to EUR not being there for every currency.

The process is:

  • first try to convert directly to EUR
  • if there is an error, check if it is a conversion rate error
  • if it is, try converting to USD first and then from USD to EUR
  • So if convertCurrency is successful, then the BidFloorCur is EUR.

There are already special currency conversion JSON tests. See exemplary/simple-banner-convert-currency.json and exemplary/simple-banner-convert-currency-intermediate.json.

Copy link
Contributor

Choose a reason for hiding this comment

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

oh… so it won't convert to USD and return no error - it would try to go from USD to EUR and return that result - therefore, the err != nil would save setting blindly to TargetCurrency even if USD were chosen; thanks


if err != nil {
var convErr currency.ConversionNotFoundError
if errors.As(err, &convErr) {
Copy link
Contributor

@scr-oath scr-oath Jan 9, 2025

Choose a reason for hiding this comment

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

nitpick/suggestion: In go, there's a pattern that you try to take the "terminal" case first - return/break/panic/exit so that you don't need an else clause - it saves "cognitive overload" because you can just reason that everything after is the "happy path" (not having your brain full with remembering what the condition was when you get to the else way down the screen or having to scroll back up to understand it) - and also saves precious indentation 😄

(so make this !errors.As and pull the else clause into the block and remove the curly braces {} (keeping and unindenting this code))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed, to have the terminal case first.

Copy link

Code coverage summary

Note:

  • Prebid team doesn't anticipate tests covering code paths that might result in marshal and unmarshal errors
  • Coverage summary encompasses all commits leading up to the latest one, 1dc4b16

aduptech

Refer here for heat map coverage report

github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:27:	Builder		85.7%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:45:	MakeRequests	92.3%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:80:	convertCurrency	83.3%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:106:	MakeBids	100.0%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:152:	getBidType	100.0%
total:									(statements)	93.0%

Comment on lines 15 to 16
bidder, buildErr := Builder(openrtb_ext.BidderAdUpTech, config.Adapter{
Endpoint: "https://example.com/rtb/bid", ExtraAdapterInfo: "{\"target_currency\": \"EUR\"}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
Copy link
Contributor

@scr-oath scr-oath Jan 13, 2025

Choose a reason for hiding this comment

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

suggestion: json can be easier to read/maintain if using the backtick string literal as long as the data doesn't contain backtick, which should be uncommon. (See https://go.dev/ref/spec#String_literals). Also… a few newlines couldn't hurt here to line up the fields so you can tell what goes with what at a glance:

Suggested change
bidder, buildErr := Builder(openrtb_ext.BidderAdUpTech, config.Adapter{
Endpoint: "https://example.com/rtb/bid", ExtraAdapterInfo: "{\"target_currency\": \"EUR\"}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
bidder, buildErr := Builder(
openrtb_ext.BidderAdUpTech,
config.Adapter{
Endpoint: "https://example.com/rtb/bid",
ExtraAdapterInfo: `{"target_currency": "EUR"}`,
},
config.Server{
ExternalUrl: "http://hosturl.com",
GvlID: 1,
DataCenter: "2",
},
)

Copy link
Contributor

Choose a reason for hiding this comment

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

There are other places where this pattern can improve readability; I've only exemplified this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, sorry, i thought gofmt takes care of everything. I didn't even try to format anything.
I come from Python where black or now ruff-format will also take care of line breaks and indentations in appropriate places to improve readability. And they reference gofmt as an inspiration.

Copy link

Code coverage summary

Note:

  • Prebid team doesn't anticipate tests covering code paths that might result in marshal and unmarshal errors
  • Coverage summary encompasses all commits leading up to the latest one, ec665c1

aduptech

Refer here for heat map coverage report

github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:27:	Builder		85.7%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:45:	MakeRequests	92.3%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:80:	convertCurrency	83.3%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:106:	MakeBids	100.0%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:152:	getBidType	100.0%
total:									(statements)	93.0%

@danygielow
Copy link
Contributor Author

danygielow commented Jan 21, 2025

@scr-oath The checks seem to have problems. Can you please take a look.

@scr-oath
Copy link
Contributor

scr-oath commented Jan 21, 2025

@scr-oath The checks seem to have problems. Can you please take a look.

Hmm… I still see checks running and none of the completed ones have failed - will check back when those finish Seems ok to me:

image

}

if extraInfo.TargetCurrency == "" {
return nil, fmt.Errorf("invalid extra info: TargetCurrency is empty, pls check")
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick (not-blocking) while a little pedantic, I prefer errors.New for errors that are just string literals.

Suggested change
return nil, fmt.Errorf("invalid extra info: TargetCurrency is empty, pls check")
return nil, errors.New("invalid extra info: TargetCurrency is empty, pls check")

Copy link
Collaborator

Choose a reason for hiding this comment

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

Good catch, agreed @scr-oath.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

makes sense, changed it

Publisher string `json:"publisher"`
Placement string `json:"placement"`
Query string `json:"query"`
AdTest string `json:"adtest"`
Copy link
Collaborator

Choose a reason for hiding this comment

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

I understand that this data structure is not being used but please make it match what you've defined in your bidder params JSON file so that it contains all of the parameters you've defined there and have corresponding Go types. In that case you should add a bool debug field and adtest should be bool.

@@ -0,0 +1,27 @@
endpoint: "https://rtb.d.adup-tech.com/rtb/bid"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Confirmed endpoint is reachable:

curl -i --location --request POST https://rtb.d.adup-tech.com/rtb/bid
HTTP/2 200
date: Tue, 21 Jan 2025 17:14:24 GMT
content-type: application/json
content-length: 87
server: nginx

{"error":"Could not determine network. Publisher is missing in request parameters. {}"}

- CHE
- GBR
maintainer:
email: "[email protected]"
Copy link
Collaborator

Choose a reason for hiding this comment

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

We've sent an email to this address. Please respond with a message of "Received" to confirm it is active.

Copy link
Collaborator

Choose a reason for hiding this comment

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

👍 email received.

- GBR
maintainer:
email: "[email protected]"
gvlVendorID: 647
Copy link
Collaborator

Choose a reason for hiding this comment

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

GVL Vendor ID looks correct:

curl https://vendor-list.consensu.org/v3/vendor-list.json | jq '.vendors."647"'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  656k  100  656k    0     0  4138k      0 --:--:-- --:--:-- --:--:-- 4156k
{
  "id": 647,
  "name": "Axel Springer Teaser Ad GmbH",
  "purposes": [
    1,
    3,
    4,
    5,
    6
  ],
  "legIntPurposes": [
    2,
    7,
    10,
    11
  ],
  "flexiblePurposes": [
    2,
    7,
    10,
    11
  ],
  "specialPurposes": [
    1,
    2,
    3
  ],
  "features": [
    3
  ],
  "specialFeatures": [],
  "cookieMaxAgeSeconds": 31536000,
  "usesCookies": true,
  "cookieRefresh": true,
  "urls": [
    {
      "langId": "en",
      "privacy": "https://www.adup-tech.com/en/privacy-policy/",
      "legIntClaim": "https://www.adup-tech.com/en/privacy-policy/#c4489"
    },
    {
      "langId": "de",
      "privacy": "https://www.adup-tech.com/rechtliches/datenschutz/",
      "legIntClaim": "https://www.adup-tech.com/rechtliches/datenschutz/#c4488"
    }
  ],
  "usesNonCookieAccess": true,
  "dataRetention": {
    "stdRetention": 365,
    "purposes": {},
    "specialPurposes": {}
  },
  "dataDeclaration": [
    1,
    2,
    3,
    6,
    8,
    10,
    11
  ],
  "deviceStorageDisclosureUrl": "https://s.d.adup-tech.com/gdpr/deviceStorage.json"
}

Comment on lines +25 to +27
iframe:
url: "https://rtb.d.adup-tech.com/service/sync?iframe=1&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}"
userMacro: "[UID]"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Verified iframe works with id set in cookie:
Screenshot 2025-01-21 at 12 28 59 PM


var validParams = []string{
`{ "publisher": "123456789", "placement": "234567890" }`,
`{ "publisher": "123456789", "placement": "234567890", "query": "test" }`,
Copy link
Collaborator

Choose a reason for hiding this comment

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

According to your bidder params JSON file, your string params publisher, placement and query are considered valid if they are specified as empty strings. Please add a test case for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added minLength to publisher and placement, added more params tests

Comment on lines +85 to +87
if !errors.As(err, &convErr) {
return 0, 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 a supplemental JSON test case where imp[].bidfloorcur is invalid to cover this block.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added test

Comment on lines 93 to 95
if err != nil {
return 0, 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 a supplemental JSON test case where ext.prebid.currency.rates contains an invalid USD conversion to cover this block:
e.g.

"USD": {
     "INVALID": 2.0
 }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The currency rates are already validated before the json test runs.
See: https://github.com/prebid/prebid-server/blob/master/adapters/adapterstest/test_json.go#L149

Copy link
Collaborator

@bsardo bsardo Jan 24, 2025

Choose a reason for hiding this comment

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

Ah yes I understand but I'm just concerned with testing your adapter. We can force an intermediate currency conversion failure so that we achieve code coverage of this error block, though my original suggested approach was incorrect. Instead you can use this test:
currency-conversion-intermediate-failure.json

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, added that test. Thank you

Comment on lines 107 to 122
switch responseData.StatusCode {
case http.StatusNoContent:
return nil, nil
case http.StatusBadRequest:
return nil, []error{&errortypes.BadInput{
Message: "Unexpected status code: 400. Run with request.debug = 1 for more info.",
}}
case http.StatusOK:
// we don't need to do anything here and this is just so we can use the default case for the unexpected status code
break
default:
return nil, []error{&errortypes.BadServerResponse{
Message: fmt.Sprintf("Unexpected status code: %d.", responseData.StatusCode),
}}

}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please use the adapter utility functions IsResponseStatusCodeNoContent and CheckResponseStatusCodeForErrors found in adapters/response.go for processing the http status code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

now using the utility functions

}

func getBidType(markupType openrtb2.MarkupType) (openrtb_ext.BidType, error) {
switch markupType {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure why this is triggering but you can ignore it.

Copy link

Code coverage summary

Note:

  • Prebid team doesn't anticipate tests covering code paths that might result in marshal and unmarshal errors
  • Coverage summary encompasses all commits leading up to the latest one, 8315a50

aduptech

Refer here for heat map coverage report

github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:27:	Builder		85.7%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:45:	MakeRequests	92.3%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:80:	convertCurrency	91.7%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:106:	MakeBids	100.0%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:143:	getBidType	100.0%
total:									(statements)	94.6%

Copy link
Collaborator

@bsardo bsardo left a comment

Choose a reason for hiding this comment

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

This is looking good. I just have one last request in this comment.

Copy link

Code coverage summary

Note:

  • Prebid team doesn't anticipate tests covering code paths that might result in marshal and unmarshal errors
  • Coverage summary encompasses all commits leading up to the latest one, 37adf42

aduptech

Refer here for heat map coverage report

github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:27:	Builder		85.7%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:45:	MakeRequests	92.3%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:80:	convertCurrency	100.0%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:106:	MakeBids	100.0%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:143:	getBidType	100.0%
total:									(statements)	96.4%

bsardo
bsardo previously approved these changes Jan 27, 2025
@bsardo bsardo assigned guscarreon and unassigned przemkaczmarek Jan 27, 2025

if extraInfo.TargetCurrency == "" {
return nil, errors.New("invalid extra info: TargetCurrency is empty, pls check")
}
Copy link
Contributor

Choose a reason for hiding this comment

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

To make sure the AdUp Tech adapter is configured with a known currency string, can we further the validation by checking whether or not the config value represents a valid three-digit currency code? The ParseISO(string) function from the already imported currency library could come in handy:

27   func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
28       var extraInfo ExtraInfo
29       if err := jsonutil.Unmarshal([]byte(config.ExtraAdapterInfo), &extraInfo); err != nil {
30           return nil, fmt.Errorf("invalid extra info: %w", err)
31       }
32  
33       if extraInfo.TargetCurrency == "" {
34           return nil, errors.New("invalid extra info: TargetCurrency is empty, pls check")
35       }
36  
   +     targetCurrency, err := currency.ParseISO(extraInfo.TargetCurrency)
   +     if err != nil {
   +        return nil, fmt.Errorf("invalid TargetCurrency: %s", extraInfo.TargetCurrency)
   +     }
   +     extraInfo.TargetCurrency = targetCurrency
   +
37       bidder := &adapter{
38           endpoint:  config.Endpoint,
39           extraInfo: extraInfo,
40       }
41  
42       return bidder, nil
43   }
adapters/aduptech/aduptech.go

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi, it is not the same currency library, and ParseISO also returns a currency.Unit.
So I adapted your suggestion and added a corresponding test.

Copy link

Code coverage summary

Note:

  • Prebid team doesn't anticipate tests covering code paths that might result in marshal and unmarshal errors
  • Coverage summary encompasses all commits leading up to the latest one, 09f4c2c

aduptech

Refer here for heat map coverage report

github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:28:	Builder		90.9%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:52:	MakeRequests	92.3%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:87:	convertCurrency	100.0%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:113:	MakeBids	100.0%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:150:	getBidType	100.0%
total:									(statements)	96.7%

Copy link
Contributor

@guscarreon guscarreon left a comment

Choose a reason for hiding this comment

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

I'm ready to approve. I just have a suggestion about the error messages mentioned below that would be fairly straightforward to implement if you want. Let me know. I'll approve either way.

"expectedBidResponses": [],
"expectedMakeRequestsErrors": [
{
"value": "Currency conversion rate not found: 'USD' => 'EUR'",
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: I don't oppose this error message if you find it useful, but wouldn't "Converted currency of bid floor from 'AUD' to 'USD' but there was an error converting from 'USD' to 'EUR': Currency conversion rate not found: 'USD' => 'EUR'" be more accurate? We could tweak the convertCurrency function to get a more descriptive message:

 87   func (a *adapter) convertCurrency(value float64, cur string, reqInfo *adapters.ExtraRequestInfo) (float64, error) {
 88       convertedValue, err := reqInfo.ConvertCurrency(value, cur, a.extraInfo.TargetCurrency)
 89
 90       if err != nil {
 91           var convErr prebidcurrency.ConversionNotFoundError
 92           if !errors.As(err, &convErr) {
 93               return 0, err
 94           }
 95
 96           // try again by first converting to USD
 97           // then convert to target_currency
 98           convertedValue, err = reqInfo.ConvertCurrency(value, cur, "USD")
 99
100           if err != nil {
101 -             return 0, err
    +             return 0, fmt.Errorf("Currency conversion rate not found from '%s' to '%s'. Error converting from '%s' to 'USD': %w", cur, a.extraInfo.TargetCurrency, cur, err)
102           }
adapters/aduptech/aduptech.go

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree, I changed the error message.

"expectedBidResponses": [],
"expectedMakeRequestsErrors": [
{
"value": "Currency conversion rate not found: 'AUD' => 'USD'",
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: I don't oppose this error message if you find it useful, but wouldn't "Currency conversion rate not found from 'AUD' to 'EUR'. Error converting from 'AUD' to 'USD': Currency conversion rate not found: 'AUD' => 'USD'" be more accurate? We could tweak the convertCurrency function to get a more descriptive message:

104           convertedValue, err = reqInfo.ConvertCurrency(convertedValue, "USD", a.extraInfo.TargetCurrency)
105
106           if err != nil {
107 -             return 0, err
    +             return 0, fmt.Errorf("Currency conversion rate not found from '%s' to '%s'. Error converting from '%s' to 'USD': %w", cur, a.extraInfo.TargetCurrency, cur, err)
108           }
109       }
110       return convertedValue, nil
111   }
112
adapters/aduptech/aduptech.go

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree, I changed the error message.

Copy link

Code coverage summary

Note:

  • Prebid team doesn't anticipate tests covering code paths that might result in marshal and unmarshal errors
  • Coverage summary encompasses all commits leading up to the latest one, 842d4e7

aduptech

Refer here for heat map coverage report

github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:28:	Builder		90.9%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:52:	MakeRequests	92.3%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:87:	convertCurrency	100.0%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:113:	MakeBids	100.0%
github.com/prebid/prebid-server/v3/adapters/aduptech/aduptech.go:150:	getBidType	100.0%
total:									(statements)	96.7%

Copy link
Contributor

@guscarreon guscarreon left a comment

Choose a reason for hiding this comment

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

LGTM

@bsardo bsardo merged commit 502a438 into prebid:master Jan 30, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants