Skip to content
This repository has been archived by the owner on Dec 22, 2022. It is now read-only.

Commit

Permalink
Initial RhythmOne Prebid Server Adapter (prebid#704)
Browse files Browse the repository at this point in the history
* Initial RhythmOne Prebid Server Adapter

* Updated UserSync URL

* Fixed gofmt issue

* Code review comments updated, UserSync URL updated

* Updated code based on review comments - Removed unused client parameter in NewRhythmoneBidder method

* Incorporated review comments

* Updated adapter with resolved conflict
  • Loading branch information
dineshkumarjayaram authored and hhhjort committed Oct 15, 2018
1 parent feb0a9d commit 27fe2a9
Show file tree
Hide file tree
Showing 21 changed files with 1,248 additions and 4 deletions.
57 changes: 57 additions & 0 deletions adapters/rhythmone/params_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package rhythmone

import (
"encoding/json"
"testing"

"github.com/prebid/prebid-server/openrtb_ext"
)

func TestValidParams(t *testing.T) {
validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
if err != nil {
t.Fatalf("Failed to fetch the json-schemas. %v", err)
}

for _, validParam := range validParams {
if err := validator.Validate(openrtb_ext.BidderRhythmone, json.RawMessage(validParam)); err != nil {
t.Errorf("Schema rejected rhythmone params: %s", validParam)
}
}
}

func TestInvalidParams(t *testing.T) {
validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
if err != nil {
t.Fatalf("Failed to fetch the json-schemas. %v", err)
}

for _, invalidParam := range invalidParams {
if err := validator.Validate(openrtb_ext.BidderRhythmone, json.RawMessage(invalidParam)); err == nil {
t.Errorf("Schema allowed unexpected params: %s", invalidParam)
}
}
}

var validParams = []string{
`{"placementId":"123", "zone":"12345", "path":"34567"}`,
}

var invalidParams = []string{
`{"placementId":"123", "zone":"12345", "path":34567}`,
`{"placementId":"123", "zone":12345, "path":"34567"}`,
`{"placementId":123, "zone":"12345", "path":"34567"}`,
`{"placementId":123, "zone":12345, "path":34567}`,
`{"placementId":123, "zone":12345, "path":"34567"}`,
`{"appId":"123", "bidfloor":0.01}`,
`{"publisherName": 100}`,
`{"placementId": 1234}`,
`{"zone": true}`,
``,
`null`,
`nil`,
`true`,
`9`,
`[]`,
`{}`,
}
146 changes: 146 additions & 0 deletions adapters/rhythmone/rhythmone.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package rhythmone

import (
"encoding/json"
"fmt"

"github.com/mxmCherry/openrtb"
"github.com/prebid/prebid-server/adapters"
"github.com/prebid/prebid-server/errortypes"
"github.com/prebid/prebid-server/openrtb_ext"
"net/http"
)

type RhythmoneAdapter struct {
endPoint string
}

func (a *RhythmoneAdapter) MakeRequests(request *openrtb.BidRequest) ([]*adapters.RequestData, []error) {
errs := make([]error, 0, len(request.Imp))

var uri string
request, uri, errs = a.preProcess(request, errs)
if request != nil {
reqJSON, err := json.Marshal(request)
if err != nil {
errs = append(errs, err)
return nil, errs
}
if uri != "" {
headers := http.Header{}
headers.Add("Content-Type", "application/json;charset=utf-8")
headers.Add("Accept", "application/json")
return []*adapters.RequestData{{
Method: "POST",
Uri: uri,
Body: reqJSON,
Headers: headers,
}}, errs
}
}
return nil, errs
}

func (a *RhythmoneAdapter) MakeBids(internalRequest *openrtb.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
if response.StatusCode == http.StatusNoContent {
return nil, nil
}

if response.StatusCode == http.StatusBadRequest {
return nil, []error{&errortypes.BadInput{
Message: fmt.Sprintf("unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode),
}}
}

if response.StatusCode != http.StatusOK {
return nil, []error{&errortypes.BadServerResponse{
Message: fmt.Sprintf("unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode),
}}
}
var bidResp openrtb.BidResponse
if err := json.Unmarshal(response.Body, &bidResp); err != nil {
return nil, []error{&errortypes.BadServerResponse{
Message: fmt.Sprintf("bad server response: %d. ", err),
}}
}

var errs []error
bidResponse := adapters.NewBidderResponseWithBidsCapacity(5)

for _, sb := range bidResp.SeatBid {
for i := range sb.Bid {
bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
Bid: &sb.Bid[i],
BidType: getMediaTypeForImp(sb.Bid[i].ImpID, internalRequest.Imp),
})
}
}
return bidResponse, errs
}

func getMediaTypeForImp(impId string, imps []openrtb.Imp) openrtb_ext.BidType {
mediaType := openrtb_ext.BidTypeBanner
for _, imp := range imps {
if imp.ID == impId {
if imp.Banner != nil {
mediaType = openrtb_ext.BidTypeBanner
} else if imp.Video != nil {
mediaType = openrtb_ext.BidTypeVideo
}
return mediaType
}
}
return mediaType
}

func NewRhythmoneBidder(endpoint string) *RhythmoneAdapter {
return &RhythmoneAdapter{
endPoint: endpoint,
}
}

func (a *RhythmoneAdapter) preProcess(req *openrtb.BidRequest, errors []error) (*openrtb.BidRequest, string, []error) {
numRequests := len(req.Imp)
var uri string = ""
for i := 0; i < numRequests; i++ {
imp := req.Imp[i]
var bidderExt adapters.ExtImpBidder
err := json.Unmarshal(imp.Ext, &bidderExt)
if err != nil {
err = &errortypes.BadInput{
Message: fmt.Sprintf("ext data not provided in imp id=%s. Abort all Request", imp.ID),
}
errors = append(errors, err)
return nil, "", errors
}
var rhythmoneExt openrtb_ext.ExtImpRhythmone
err = json.Unmarshal(bidderExt.Bidder, &rhythmoneExt)
if err != nil {
err = &errortypes.BadInput{
Message: fmt.Sprintf("placementId | zone | path not provided in imp id=%s. Abort all Request", imp.ID),
}
errors = append(errors, err)
return nil, "", errors
}
rhythmoneExt.S2S = true
rhythmoneExtCopy, err := json.Marshal(&rhythmoneExt)
if err != nil {
errors = append(errors, err)
return nil, "", errors
}
bidderExtCopy := openrtb_ext.ExtBid{
Bidder: rhythmoneExtCopy,
}
impExtCopy, err := json.Marshal(&bidderExtCopy)
if err != nil {
errors = append(errors, err)
return nil, "", errors
}
imp.Ext = impExtCopy
req.Imp[i] = imp
if uri == "" {
uri = fmt.Sprintf("%s/%s/0/%s?z=%s&s2s=%s", a.endPoint, rhythmoneExt.PlacementId, rhythmoneExt.Path, rhythmoneExt.Zone, "true")
}
}
return req, uri, errors
}
10 changes: 10 additions & 0 deletions adapters/rhythmone/rhythmone_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package rhythmone

import (
"github.com/prebid/prebid-server/adapters/adapterstest"
"testing"
)

func TestJsonSamples(t *testing.T) {
adapterstest.RunJSONBidderTest(t, "rhythmonetest", NewRhythmoneBidder("http://tag.1rx.io/rmp"))
}
Loading

0 comments on commit 27fe2a9

Please sign in to comment.