Skip to content

Add Adapter Orbidder #1275

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

Merged
merged 27 commits into from
May 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
ec65eee
init orbidder adapter
RainerVolk4014 Dec 11, 2019
78abd6a
formatting and code style
RainerVolk4014 Dec 12, 2019
94c6df0
Merge pull request #1 from siggi-otto/feature/init-orbidder-adapter
RainerVolk4014 Dec 16, 2019
1667b36
go fmt
Jan 31, 2020
ca3cbdb
Merge remote-tracking branch 'upstream/master'
Jan 31, 2020
b5f289e
send openrtb2 req to orbidder /openrtb2 endpoint and fix MakeBids
Feb 22, 2020
03c56a4
Merge remote-tracking branch 'upstream/master'
arneschulz1984 Mar 26, 2020
b260d7a
Merge remote-tracking branch 'upstream/master'
arneschulz1984 Mar 31, 2020
51886b5
set orbidder endpoint to production values
Apr 1, 2020
ed6af72
rename bid-floor to bidfloor and repair test to assure that
Apr 1, 2020
538e034
Merge pull request #2 from siggi-otto/SIGGI-708
hendrikiseke1979 Apr 2, 2020
6c65ec3
Merge remote-tracking branch 'upstream/master'
arneschulz1984 Apr 21, 2020
b7aeafa
Merge branch 'master' of github.com:siggi-otto/prebid-server
arneschulz1984 Apr 21, 2020
d55f2e0
add BidderOrbidder to skip UserSync test, because of no endpoint prov…
arneschulz1984 Apr 23, 2020
054a043
implement prevalidation for BidderOrbidder
arneschulz1984 Apr 23, 2020
f3e349c
add supplemental tests for BidderOrbidder
arneschulz1984 Apr 23, 2020
24f37e9
fix BidderOrbidder bidfloor typo
arneschulz1984 Apr 23, 2020
c1b50c9
add BidderOrbidder params_tests
arneschulz1984 Apr 23, 2020
680326c
Merge pull request #3 from siggi-otto/feature/SIGGI-719
arneschulz1984 Apr 27, 2020
1ca1fdc
Merge remote-tracking branch 'upstream/master'
arneschulz1984 Apr 27, 2020
e722c93
add origial error message to BadInput error
arneschulz1984 May 5, 2020
cc8fd3e
fixed typo in orbidder adapter
arneschulz1984 May 5, 2020
abf1ff5
removed comment for openrtb_ext.BidderOrbidder default endpoint
arneschulz1984 May 5, 2020
8df7078
fixed orbidder test to new error message
arneschulz1984 May 5, 2020
d1f68d7
Merge remote-tracking branch 'upstream/master'
arneschulz1984 May 5, 2020
11c64c4
droped unreachable conditions in orbidder adapter
arneschulz1984 May 7, 2020
a05723b
Merge remote-tracking branch 'upstream/master'
arneschulz1984 May 7, 2020
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
127 changes: 127 additions & 0 deletions adapters/orbidder/orbidder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package orbidder

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 OrbidderAdapter struct {
endpoint string
}

// MakeRequests makes the HTTP requests which should be made to fetch bids from orbidder.
func (rcv *OrbidderAdapter) MakeRequests(request *openrtb.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
var errs []error
var validImps []openrtb.Imp

// check if imps exists, if not return error and do send request to orbidder.
if len(request.Imp) == 0 {
return nil, []error{&errortypes.BadInput{
Message: "No impressions in request",
}}
}

// validate imps
for _, imp := range request.Imp {
if err := preprocess(&imp); err != nil {
errs = append(errs, err)
continue
}
validImps = append(validImps, imp)
}

if len(validImps) == 0 {
return nil, errs
}

//set imp array to only valid imps
request.Imp = validImps

requestBodyJSON, err := json.Marshal(request)
if err != nil {
errs = append(errs, err)
return nil, errs
}

headers := http.Header{}
headers.Add("Content-Type", "application/json;charset=utf-8")
headers.Add("Accept", "application/json")

return []*adapters.RequestData{{
Method: "POST",
Uri: rcv.endpoint,
Body: requestBodyJSON,
Headers: headers,
}}, errs
}

func preprocess(imp *openrtb.Imp) error {
var bidderExt adapters.ExtImpBidder
if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
return &errortypes.BadInput{
Message: err.Error(),
}
}

var orbidderExt openrtb_ext.ExtImpOrbidder
if err := json.Unmarshal(bidderExt.Bidder, &orbidderExt); err != nil {
return &errortypes.BadInput{
Message: "Wrong orbidder bidder ext: " + err.Error(),
}
}

return nil
}

// MakeBids unpacks server response into Bids.
func (rcv OrbidderAdapter) 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.StatusInternalServerError {
return nil, []error{&errortypes.BadServerResponse{
Message: fmt.Sprintf("Unexpected status code: %d. Dsp server internal error.", response.StatusCode),
}}
}

if response.StatusCode >= http.StatusBadRequest {
return nil, []error{&errortypes.BadInput{
Message: fmt.Sprintf("Unexpected status code: %d. Bad request to dsp.", response.StatusCode),
}}
}

if response.StatusCode != http.StatusOK {
return nil, []error{&errortypes.BadServerResponse{
Message: fmt.Sprintf("Unexpected status code: %d. Bad response from dsp.", response.StatusCode),
}}
}

var bidResp openrtb.BidResponse
if err := json.Unmarshal(response.Body, &bidResp); err != nil {
return nil, []error{err}
}

bidResponse := adapters.NewBidderResponseWithBidsCapacity(5)

for _, seatBid := range bidResp.SeatBid {
for _, bid := range seatBid.Bid {
bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
Bid: &bid,
BidType: openrtb_ext.BidTypeBanner,
})
}
}
return bidResponse, nil
}

func NewOrbidderBidder(endpoint string) *OrbidderAdapter {
return &OrbidderAdapter{
endpoint: endpoint,
}
}
25 changes: 25 additions & 0 deletions adapters/orbidder/orbidder_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package orbidder

import (
"encoding/json"
"github.com/prebid/prebid-server/adapters/adapterstest"
"github.com/prebid/prebid-server/openrtb_ext"
"github.com/stretchr/testify/assert"
"testing"
)

func TestUnmarshalOrbidderExtImp(t *testing.T) {
ext := json.RawMessage(`{"accountId":"orbidder-test", "placementId":"center-banner", "bidfloor": 0.1}`)
impExt := new(openrtb_ext.ExtImpOrbidder)

assert.NoError(t, json.Unmarshal(ext, impExt))
assert.Equal(t, &openrtb_ext.ExtImpOrbidder{
AccountId: "orbidder-test",
PlacementId: "center-banner",
BidFloor: 0.1,
}, impExt)
}

func TestJsonSamples(t *testing.T) {
adapterstest.RunJSONBidderTest(t, "orbiddertest", NewOrbidderBidder("https://orbidder-test"))
}
111 changes: 111 additions & 0 deletions adapters/orbidder/orbiddertest/exemplary/simple-app-banner.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
{
"mockBidRequest": {
"id": "test-request-id",
"app": {
"bundle": "com.prebid"
},
"device": {
"ifa":"87857b31-8942-4646-ae80-ab9c95bf3fab"
},
"imp": [
{
"id": "test-imp-id",
"banner": {
"format": [
{
"w": 300,
"h": 250
}
]
},
"ext": {
"bidder": {
"accountId": "orbidder-test",
"placementId": "test-placement",
"bidfloor": 0.1
}
}
}
]
},
"httpCalls": [
{
"expectedRequest": {
"uri": "https://orbidder-test",
"body": {
"id": "test-request-id",
"app": {
"bundle": "com.prebid"
},
"device": {
"ifa":"87857b31-8942-4646-ae80-ab9c95bf3fab"
},
"imp": [
{
"id": "test-imp-id",
"banner": {
"format": [
{
"w": 300,
"h": 250
}
]
},
"ext": {
"bidder": {
"accountId": "orbidder-test",
"placementId": "test-placement",
"bidfloor": 0.1
}
}
}
]
}
},
"mockResponse": {
"status": 200,
"body": {
"id": "test-request-id",
"seatbid": [
{
"seat": "seat-id",
"bid": [
{
"id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
"impid": "test-imp-id",
"adid": "11110126",
"price": 0.500000,
"adm": "some-test-ad",
"crid": "test-crid",
"h": 250,
"w": 300
}
]
}
],
"cur": "EUR"
}
}
}
],
"expectedBidResponses": [
{
"currency": "EUR",
"bids": [
{
"bid": {
"id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
"impid": "test-imp-id",
"adid": "11110126",
"price": 0.5,
"adm": "some-test-ad",
"crid": "test-crid",
"w": 300,
"h": 250
},
"type": "banner"
}
]
}
]
}
5 changes: 5 additions & 0 deletions adapters/orbidder/orbiddertest/params/race/banner.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"accountId": "orbidder-test",
"placementId": "center-banner",
"bidfloor": 0.1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{
"mockBidRequest": {
"id": "test-request-id",
"app": {
"bundle": "com.prebid"
},
"device": {
"ifa":"87857b31-8942-4646-ae80-ab9c95bf3fab"
},
"imp": [
{
"id": "test-imp-id",
"banner": {
"format": [
{
"w": 300,
"h": 250
}
]
},
"ext": {
"bidder": {
"accountId": "orbidder-test",
"placementId": "test-placement",
"bidfloor": 0.1
}
}
}
]
},
"httpCalls": [
{
"expectedRequest": {
"uri": "https://orbidder-test",
"body": {
"id": "test-request-id",
"app": {
"bundle": "com.prebid"
},
"device": {
"ifa":"87857b31-8942-4646-ae80-ab9c95bf3fab"
},
"imp": [
{
"id": "test-imp-id",
"banner": {
"format": [
{
"w": 300,
"h": 250
}
]
},
"ext": {
"bidder": {
"accountId": "orbidder-test",
"placementId": "test-placement",
"bidfloor": 0.1
}
}
}
]
}
},
"mockResponse": {
"status": 400,
"body": {
}
}
}
],
"expectedMakeBidsErrors": [
{
"value": "Unexpected status code: 400. Bad request to dsp.",
"comparison": "literal"
}
]
}
Loading