-
Notifications
You must be signed in to change notification settings - Fork 770
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: Mediasquare #3994
base: master
Are you sure you want to change the base?
New Adapter: Mediasquare #3994
Changes from all commits
b4a4a3f
1e3b225
1c8be46
f36098a
6051fdb
14677dd
f49cc00
355ddb0
c7221a2
7a2966b
3a1f90d
747bff3
8de23e9
0a0e2b2
01c1674
71d2d6d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
package mediasquare | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
|
||
"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/errortypes" | ||
"github.com/prebid/prebid-server/v3/openrtb_ext" | ||
"github.com/prebid/prebid-server/v3/util/jsonutil" | ||
) | ||
|
||
type adapter struct { | ||
endpoint string | ||
} | ||
|
||
func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { | ||
return &adapter{ | ||
endpoint: config.Endpoint, | ||
}, nil | ||
} | ||
|
||
func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { | ||
var ( | ||
requestData []*adapters.RequestData | ||
errs []error | ||
) | ||
if request == nil || request.Imp == nil { | ||
errs = append(errs, errorWriter("<MakeRequests> request", nil, true)) | ||
return nil, errs | ||
} | ||
|
||
msqParams := initMsqParams(request) | ||
msqParams.Test = (request.Test == int8(1)) | ||
for _, imp := range request.Imp { | ||
var ( | ||
bidderExt adapters.ExtImpBidder | ||
msqExt openrtb_ext.ImpExtMediasquare | ||
currentCode = msqParametersCodes{ | ||
AdUnit: imp.TagID, | ||
AuctionId: request.ID, | ||
BidId: imp.ID, | ||
} | ||
) | ||
|
||
if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { | ||
errs = append(errs, errorWriter("<MakeRequests> imp[ext]", err, len(imp.Ext) == 0)) | ||
continue | ||
} | ||
if err := jsonutil.Unmarshal(bidderExt.Bidder, &msqExt); err != nil { | ||
errs = append(errs, errorWriter("<MakeRequests> imp-bidder[ext]", err, len(bidderExt.Bidder) == 0)) | ||
continue | ||
} | ||
currentCode.Owner = msqExt.Owner | ||
currentCode.Code = msqExt.Code | ||
|
||
if currentCode.setContent(imp) { | ||
msqParams.Codes = append(msqParams.Codes, currentCode) | ||
} | ||
} | ||
|
||
req, err := a.makeRequest(request, &msqParams) | ||
if err != nil { | ||
errs = append(errs, err) | ||
} else if req != nil { | ||
requestData = append(requestData, req) | ||
} | ||
return requestData, errs | ||
} | ||
|
||
func (a *adapter) makeRequest(request *openrtb2.BidRequest, msqParams *msqParameters) (requestData *adapters.RequestData, err error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why You have two makeRequest func()? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess you mean why we do have a Can you elaborate on the the reason(s) why the files There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will confirm with the team, but I think it's totally ok to have extra files (within the adapter directory) to make code more readable and structured. This adapter accepts and returns it's own format, not OpenRTB format. Having all the structures and converters in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed. For simple adapters a single file should suffice. However, in this case, the adapter is rather complex so I do appreciate and prefer the code organization across multiple files. |
||
var requestJsonBytes []byte | ||
if msqParams == nil { | ||
err = errorWriter("<makeRequest> msqParams", nil, true) | ||
return | ||
} | ||
if requestJsonBytes, err = jsonutil.Marshal(msqParams); err == nil { | ||
var headers http.Header = headerList | ||
requestData = &adapters.RequestData{ | ||
Method: "POST", | ||
Uri: a.endpoint, | ||
Body: requestJsonBytes, | ||
Headers: headers, | ||
ImpIDs: openrtb_ext.GetImpIDs(request.Imp), | ||
} | ||
} else { | ||
err = errorWriter("<makeRequest> jsonutil.Marshal", err, false) | ||
} | ||
|
||
return | ||
} | ||
|
||
func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { | ||
var ( | ||
bidderResponse *adapters.BidderResponse | ||
errs []error | ||
) | ||
if response.StatusCode != http.StatusOK { | ||
switch response.StatusCode { | ||
case http.StatusBadRequest: | ||
errs = []error{&errortypes.BadInput{Message: fmt.Sprintf("<MakeBids> Unexpected status code: %d.", response.StatusCode)}} | ||
default: | ||
errs = []error{&errortypes.BadServerResponse{ | ||
Message: fmt.Sprintf("<MakeBids> Unexpected status code: %d. Run with request.debug = 1 for more info.", response.StatusCode), | ||
}} | ||
} | ||
return bidderResponse, errs | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would you consider to clean up error handling using I also noticed an interesting thing. When I run the request to mediasquare and bids are not returned - you still return http 200 with error message. This is not typical behavior. If bids are not returned we usually get http 204. If this is something you cannot change, please consider to add a check for empty |
||
|
||
var msqResp msqResponse | ||
if err := jsonutil.Unmarshal(response.Body, &msqResp); err != nil { | ||
errs = []error{&errortypes.BadServerResponse{ | ||
Message: fmt.Sprintf("<MakeBids> Unexpected status code: %d. Bad server response: %s.", | ||
http.StatusNotAcceptable, err.Error())}, | ||
} | ||
return bidderResponse, errs | ||
} | ||
if len(msqResp.Responses) == 0 { | ||
errs = []error{&errortypes.BadServerResponse{ | ||
Message: fmt.Sprintf("<MakeBids> Unexpected status code: %d. No responses found into body content.", | ||
http.StatusNoContent)}, | ||
} | ||
return bidderResponse, errs | ||
} | ||
bidderResponse = adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) | ||
msqResp.getContent(bidderResponse) | ||
|
||
return bidderResponse, errs | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package mediasquare | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/prebid/openrtb/v20/openrtb2" | ||
"github.com/prebid/prebid-server/v3/adapters" | ||
"github.com/prebid/prebid-server/v3/adapters/adapterstest" | ||
"github.com/prebid/prebid-server/v3/config" | ||
"github.com/prebid/prebid-server/v3/openrtb_ext" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestBidderMediasquare(t *testing.T) { | ||
bidder, buildErr := Builder(openrtb_ext.BidderMediasquare, config.Adapter{ | ||
Endpoint: "https://pbs-front.mediasquare.fr/msq_prebid"}, | ||
config.Server{ExternalUrl: "https://pbs-front.mediasquare.fr/msq_prebid", GvlID: 1, DataCenter: "2"}) | ||
if buildErr != nil { | ||
t.Fatalf("Builder returned unexpected error %v", buildErr) | ||
} | ||
adapterstest.RunJSONBidderTest(t, "mediasquaretest", bidder) | ||
} | ||
|
||
func TestMakeRequests(t *testing.T) { | ||
bidder, buildErr := Builder(openrtb_ext.BidderMediasquare, config.Adapter{ | ||
Endpoint: "https://pbs-front.mediasquare.fr/msq_prebid"}, | ||
config.Server{ExternalUrl: "https://pbs-front.mediasquare.fr/msq_prebid", GvlID: 1, DataCenter: "2"}) | ||
if buildErr != nil { | ||
t.Fatalf("Builder returned unexpected error %v", buildErr) | ||
} | ||
|
||
// MakeRequests : case request is empty. | ||
resp, errs := bidder.MakeRequests(nil, nil) | ||
expectingErrors := []error{errorWriter("<MakeRequests> request", nil, true)} | ||
assert.Equal(t, []*adapters.RequestData(nil), resp, "resp, was supposed to be empty result.") | ||
assert.Equal(t, expectingErrors, errs, "errs, was supposed to be :", expectingErrors) | ||
|
||
// MakeRequests : case request.Imp is empty. | ||
bidResquest := openrtb2.BidRequest{ID: "id-test", Imp: nil} | ||
resp, errs = bidder.MakeRequests(&bidResquest, nil) | ||
expectingErrors = []error{errorWriter("<MakeRequests> request", nil, true)} | ||
assert.Equal(t, []*adapters.RequestData(nil), resp, "resp, was supposed to be empty result.") | ||
assert.Equal(t, expectingErrors, errs, "errs, was supposed to be :", expectingErrors) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't seen this behavior before. Is this added because the msqParams.Test field is required by the MediaSquare backend to recognize the request as a test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is.