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

sovrn: Add video support #2232

Merged
merged 77 commits into from
May 16, 2022
Merged

sovrn: Add video support #2232

merged 77 commits into from
May 16, 2022

Conversation

cpabst
Copy link
Contributor

@cpabst cpabst commented Apr 22, 2022

No description provided.

kevinKalmbach and others added 30 commits July 28, 2017 12:53
sort bids by price so multiple sovrn tags in a unit can function properly
}

return imp.TagID, nil
return response, nil
}

func getTagid(sovrnExt openrtb_ext.ExtImpSovrn) string {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm curious what is the purpose of this function? I know this is not in scope of this PR, but do you think you need it?

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 have inherited this code from someone who is no longer at Sovrn. But it appears that our original work with Prebid Server used a spelling on our tagid parameter that we quickly decided was wrong. 😄

So the old version is deprecated, but not removed yet. Not sure how we will go forward with the actual removal, but we will figure that out.

@@ -10,6 +10,7 @@
// Options
"INSTALL_NODE": "false",
"NODE_VERSION": "lts/*",
"TEST": "false"
Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove this line, you probably pushed it accidentally.

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.

if video != nil {
if video.MIMEs == nil ||
video.MinDuration == 0 ||
video.MaxDuration == 0 ||
Copy link
Contributor

@VeronikaSolovei9 VeronikaSolovei9 May 2, 2022

Choose a reason for hiding this comment

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

Please review this logic again. For video endpoint there is a possibility to have only maxDuration when requireExactDuration if false or not specified. In this case the entire request will be rejected.

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'll need to review this with product. I'll let you know how that conversation goes.

Copy link
Contributor

Choose a reason for hiding this comment

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

@cpabst Were you able to check about this with your team?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

He has been very busy. 😄
I'd like to keep it this way, and look at this idea as a future enhancement. I see others doing it the same way.

}
if request.Imp[0].Video != nil {
bidType = openrtb_ext.BidTypeVideo
}
Copy link
Contributor

Choose a reason for hiding this comment

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

In case you return bid type in bid.ext we recommend to use this approach:

func getBidType(bid openrtb2.Bid, imps []openrtb2.Imp) (openrtb_ext.BidType, error) {

It will also help to determine bid type correctly in case if req.imp is multi typed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We do not support multi-typed imps yet.

Copy link
Contributor

Choose a reason for hiding this comment

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

You may not support it, but request may have it. In your code you take imp type from request and match it with response: request.Imp[impIdx]

imp.TagID = getTagid(sovrnExt)

if imp.BidFloor == 0 && sovrnExt.BidFloor > 0 {
imp.BidFloor = sovrnExt.BidFloor
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you please add coverage for this branch?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Fixed a bunch of other tests as well.

@mansinahar mansinahar requested review from mansinahar and removed request for bsardo May 4, 2022 17:17
@mansinahar mansinahar assigned mansinahar and unassigned bsardo May 4, 2022
errs = append(errs, &errortypes.BadInput{
Message: "Missing required video parameter",
})
return nil, errs
Copy link
Contributor

Choose a reason for hiding this comment

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

Are you sure you wanna throw away the entire request only if a single video imp isn't valid? You could just continue here and process the imps that are valid.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. Thanks.

}
}
if request.Imp[0].Video != nil {
bidType = openrtb_ext.BidTypeVideo
Copy link
Contributor

Choose a reason for hiding this comment

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

As mentioned by @VeronikaSolovei9, this can return the wrong bid type in case where the imp is a multi-format imp. But also, since you're only looking at the first imp in the request, this might also return the wrong bid types if not all imps in the request are of same type. For example, say the first imp in the request is of type video but the second one is of type banner, then you'll be returning wrong bid type for the bid corresponding to the second imp.

We highly recommend using bid.Ext.MediaType to send back this information to Prebid Server.

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'm solving this presently with using the Bid.impid value to set bid type. We will look into using the recommended value in the future.

@@ -20,7 +20,8 @@
"bidder": {
"tagid": "123456"
}
}
},
Copy link
Contributor

Choose a reason for hiding this comment

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

Wondering why was imp.tagid added to this and a few other test requests in this PR? Won't it be added by your adapter code based on what you have in your tagid bidder param?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep. Figured that out today. Those all should be fixed now.

}
]
},
"bidfloor": 4.2,
Copy link
Contributor

Choose a reason for hiding this comment

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

The test name indicates that this test case is where there's only custom bid floor present, which as I understand is the one in the bidder ext. In that case shouldn't this be not present in the original request? This will then be filled by your adapter

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, you are correct. This has been fixed.

"format": [
{
"w": 300,
"h": 250
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider the imp order reversed in this test case where the first imp is a video imp and the second one is the banner imp, in that case the bid type in the response will be incorrectly set to video.. Now also consider the imps in the same order as you have in this test, if your bidder service were to send back a bid for the video imp as well, in this case the video bid would have the bid type incorrectly set to banner

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 believe this has been solved by using the response Bid.impid value.

@cpabst
Copy link
Contributor Author

cpabst commented May 4, 2022

@mansinahar @VeronikaSolovei9 I have made quite a few updates based on these comments. This PR is ready for another review.

continue
}

imp.TagID = getTagid(sovrnExt)
Copy link
Contributor

Choose a reason for hiding this comment

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

You've already gotten the tagId value from the getTagid function on L63 so this line should be just:

imp.TagID = tagId

Also, can you please rename the getTagid function to getTagId?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Both done

return nil, errs
}

reqJSON, err := json.Marshal(request)
Copy link
Contributor

Choose a reason for hiding this comment

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

At this point, this request can have both valid and invalid imps because on L92 you're just reassigning the valid imps to the same place in the imps array of the request. You'd actually have to remove the invalid ones as you find them in the for loop so that you're only left with the valid ones or a much easier way would be to just create a new validImps array and keep appending each valid imp you find to that array and then outside the for loop, you can just replace request.Imp with that new validImps array before JSON marshalling

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. Done.

@@ -75,71 +116,54 @@ func addHeaderIfNonEmpty(headers http.Header, headerName string, headerValue str
}
}

func (s *SovrnAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
if response.StatusCode == http.StatusNoContent {
func (s *SovrnAdapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: The names requestData and responseData don't really convey the proper context here IMHO. How about using, bidderRequest and bidderResponse, respectively?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure. 😄

}
}

return -1 // hopefully this never happens
Copy link
Contributor

Choose a reason for hiding this comment

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

We should be returning an error if this does happen.. This would mean that for some reason your bidder bid for an imp that doesn't match an ID with the imps in the request. By returning an explicit error, it will be much easier to debug and fix the issue rather than silently just setting the bid type to banner

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 see your point. I believe I have fixed this correctly now. Please let me know if you feel otherwise.

}
}

return -1 // hopefully this never happens
return -1, &errortypes.BadInput{
Message: fmt.Sprintf("Could not find imp ID '%s' in bid, dropping bid", impId),
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you please rephrase this as something like:

Imp ID %s in bid didn't match with any imp in the original request

The above indicates we're trying to find the imp ID in a list of bids whereas the other way round is true. We're trying to match the impID in the bid with the list of imps in the request

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Works for me. Done.

{
"mockBidRequest": {
"id": "test-request-id",
"imp": [
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this test case testing anything different from the full video test case you have above?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This one just has the required parameters, and the other one has all parameters. I like that it shows the minimum viable request, but don't feel strongly if you'd like it to go.

}
}
},
"mockResponse": {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please consider adding a response for video as well in this test case. This will allow this test case to verify that responses with multiple bids for various imps are processed correctly and will also verify the getBidType logic to make sure it matches bids to imps properly based on the imp ID

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. Done.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. Done.


impIdx, impIdErr := getImpIdx(bid.ImpID, request)
if impIdErr != nil {
errs = append(errs, impIdErr)
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 test case for this error condition

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@mansinahar
Copy link
Contributor

@cpabst Thanks for addressing the comments. This is looking to be in good shape now. Just have a couple minor comments.

@mansinahar mansinahar merged commit bd471be into prebid:master May 16, 2022
jorgeluisrocha pushed a commit to jwplayer/prebid-server that referenced this pull request Sep 28, 2022
shunj-nb pushed a commit to ParticleMedia/prebid-server that referenced this pull request Nov 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants