From 3021a1f53496eb7d27e8a73a8da524c56671b89c Mon Sep 17 00:00:00 2001
From: andreasmaurer0210 <62548508+andreasmaurer0210@users.noreply.github.com>
Date: Mon, 20 Dec 2021 19:29:00 +0100
Subject: [PATCH 01/14] Orbidder: bidfloor currency handling (#2093)
---
adapters/orbidder/orbidder.go | 66 ++++----
adapters/orbidder/orbidder_test.go | 147 ++++++++++++++++++
.../exemplary/simple-app-banner.json | 1 +
.../supplemental/dsp-bad-request-example.json | 1 +
.../dsp-bad-response-example.json | 1 +
.../dsp-internal-server-error-example.json | 1 +
.../dsp-invalid-accountid-example.json | 1 +
.../supplemental/empty-imp-request-error.json | 19 ---
.../supplemental/no-content-response.json | 1 +
.../supplemental/valid-and-invalid-imps.json | 1 +
10 files changed, 194 insertions(+), 45 deletions(-)
delete mode 100644 adapters/orbidder/orbiddertest/supplemental/empty-imp-request-error.json
diff --git a/adapters/orbidder/orbidder.go b/adapters/orbidder/orbidder.go
index 77985c8dae0..f2dda85e290 100644
--- a/adapters/orbidder/orbidder.go
+++ b/adapters/orbidder/orbidder.go
@@ -3,13 +3,13 @@ package orbidder
import (
"encoding/json"
"fmt"
- "net/http"
-
"github.com/mxmCherry/openrtb/v15/openrtb2"
"github.com/prebid/prebid-server/adapters"
"github.com/prebid/prebid-server/config"
"github.com/prebid/prebid-server/errortypes"
"github.com/prebid/prebid-server/openrtb_ext"
+ "net/http"
+ "strings"
)
type OrbidderAdapter struct {
@@ -18,30 +18,11 @@ type OrbidderAdapter struct {
// MakeRequests makes the HTTP requests which should be made to fetch bids from orbidder.
func (rcv *OrbidderAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
- var errs []error
- var validImps []openrtb2.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)
- }
-
+ validImps, errs := getValidImpressions(request, reqInfo)
if len(validImps) == 0 {
return nil, errs
}
- //set imp array to only valid imps
request.Imp = validImps
requestBodyJSON, err := json.Marshal(request)
@@ -55,14 +36,34 @@ func (rcv *OrbidderAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *
headers.Add("Accept", "application/json")
return []*adapters.RequestData{{
- Method: "POST",
+ Method: http.MethodPost,
Uri: rcv.endpoint,
Body: requestBodyJSON,
Headers: headers,
}}, errs
}
-func preprocess(imp *openrtb2.Imp) error {
+// getValidImpressions validate imps and check for bid floor currency. Convert to EUR if necessary
+func getValidImpressions(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]openrtb2.Imp, []error) {
+ var errs []error
+ var validImps []openrtb2.Imp
+
+ for _, imp := range request.Imp {
+ if err := preprocessBidFloorCurrency(&imp, reqInfo); err != nil {
+ errs = append(errs, err)
+ continue
+ }
+
+ if err := preprocessExtensions(&imp); err != nil {
+ errs = append(errs, err)
+ continue
+ }
+ validImps = append(validImps, imp)
+ }
+ return validImps, errs
+}
+
+func preprocessExtensions(imp *openrtb2.Imp) error {
var bidderExt adapters.ExtImpBidder
if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
return &errortypes.BadInput{
@@ -80,8 +81,21 @@ func preprocess(imp *openrtb2.Imp) error {
return nil
}
+func preprocessBidFloorCurrency(imp *openrtb2.Imp, reqInfo *adapters.ExtraRequestInfo) error {
+ // we expect every currency related data to be EUR
+ if imp.BidFloor > 0 && strings.ToUpper(imp.BidFloorCur) != "EUR" && imp.BidFloorCur != "" {
+ if convertedValue, err := reqInfo.ConvertCurrency(imp.BidFloor, imp.BidFloorCur, "EUR"); err != nil {
+ return err
+ } else {
+ imp.BidFloor = convertedValue
+ }
+ }
+ imp.BidFloorCur = "EUR"
+ return nil
+}
+
// MakeBids unpacks server response into Bids.
-func (rcv OrbidderAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
+func (rcv OrbidderAdapter) MakeBids(_ *openrtb2.BidRequest, _ *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
if response.StatusCode == http.StatusNoContent {
return nil, nil
}
@@ -125,7 +139,7 @@ func (rcv OrbidderAdapter) MakeBids(internalRequest *openrtb2.BidRequest, extern
}
// Builder builds a new instance of the Orbidder adapter for the given bidder with the given config.
-func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) {
+func Builder(_ openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) {
bidder := &OrbidderAdapter{
endpoint: config.Endpoint,
}
diff --git a/adapters/orbidder/orbidder_test.go b/adapters/orbidder/orbidder_test.go
index 0eaed23a971..bbda1c06223 100644
--- a/adapters/orbidder/orbidder_test.go
+++ b/adapters/orbidder/orbidder_test.go
@@ -2,6 +2,10 @@ package orbidder
import (
"encoding/json"
+ "errors"
+ "github.com/mxmCherry/openrtb/v15/openrtb2"
+ "github.com/prebid/prebid-server/adapters"
+ "github.com/stretchr/testify/mock"
"testing"
"github.com/prebid/prebid-server/adapters/adapterstest"
@@ -22,6 +26,16 @@ func TestUnmarshalOrbidderExtImp(t *testing.T) {
}, impExt)
}
+func TestPreprocessExtensions(t *testing.T) {
+ for name, tc := range testCasesExtension {
+ t.Run(name, func(t *testing.T) {
+ imp := tc.imp
+ err := preprocessExtensions(&imp)
+ tc.assertError(t, err)
+ })
+ }
+}
+
func TestJsonSamples(t *testing.T) {
bidder, buildErr := Builder(openrtb_ext.BidderOrbidder, config.Adapter{
Endpoint: "https://orbidder-test"})
@@ -32,3 +46,136 @@ func TestJsonSamples(t *testing.T) {
adapterstest.RunJSONBidderTest(t, "orbiddertest", bidder)
}
+
+var testCasesCurrency = map[string]struct {
+ imp openrtb2.Imp
+ setMock func(m *mock.Mock)
+ expectedImp openrtb2.Imp
+ assertError func(t assert.TestingT, err error, msgAndArgs ...interface{}) bool
+}{
+ "EUR: no bidfloor, no currency": {
+ imp: openrtb2.Imp{
+ BidFloor: 0,
+ BidFloorCur: "",
+ },
+ setMock: func(m *mock.Mock) {},
+ expectedImp: openrtb2.Imp{
+ BidFloor: 0,
+ BidFloorCur: "EUR",
+ },
+ assertError: assert.NoError,
+ },
+ "EUR: bidfloor, no currency": {
+ imp: openrtb2.Imp{
+ BidFloor: 1,
+ BidFloorCur: "",
+ },
+ setMock: func(m *mock.Mock) {},
+ expectedImp: openrtb2.Imp{
+ BidFloor: 1,
+ BidFloorCur: "EUR",
+ },
+ assertError: assert.NoError,
+ },
+ "EUR: bidfloor and currency": {
+ imp: openrtb2.Imp{
+ BidFloor: 1,
+ BidFloorCur: "EUR",
+ },
+ setMock: func(m *mock.Mock) {},
+ expectedImp: openrtb2.Imp{
+ BidFloor: 1,
+ BidFloorCur: "EUR",
+ },
+ assertError: assert.NoError,
+ },
+ "USD: bidfloor with currency": {
+ imp: openrtb2.Imp{
+ BidFloor: 1,
+ BidFloorCur: "USD",
+ },
+ setMock: func(m *mock.Mock) {
+ m.On("GetRate", "USD", "EUR").Return(2.5, nil)
+ },
+ expectedImp: openrtb2.Imp{
+ BidFloor: 2.5,
+ BidFloorCur: "EUR",
+ },
+ assertError: assert.NoError,
+ },
+ "USD: no bidfloor": {
+ imp: openrtb2.Imp{
+ BidFloor: 0,
+ BidFloorCur: "USD",
+ },
+ setMock: func(m *mock.Mock) {},
+ expectedImp: openrtb2.Imp{
+ BidFloor: 0,
+ BidFloorCur: "EUR",
+ },
+ assertError: assert.NoError,
+ },
+ "ABC: invalid currency code": {
+ imp: openrtb2.Imp{
+ BidFloor: 1,
+ BidFloorCur: "ABC",
+ },
+ setMock: func(m *mock.Mock) {
+ m.On("GetRate", "ABC", "EUR").Return(0.0, errors.New("currency conversion error"))
+ },
+ expectedImp: openrtb2.Imp{
+ BidFloor: 1,
+ BidFloorCur: "ABC",
+ },
+ assertError: assert.Error,
+ },
+}
+
+var testCasesExtension = map[string]struct {
+ imp openrtb2.Imp
+ assertError func(t assert.TestingT, err error, msgAndArgs ...interface{}) bool
+}{
+ "Valid Orbidder Extension": {
+ imp: openrtb2.Imp{
+ Ext: json.RawMessage(`{"bidder":{"accountId":"orbidder-test", "placementId":"center-banner", "bidfloor": 0.1}}`),
+ },
+ assertError: assert.NoError,
+ },
+ "Invalid Orbidder Extension": {
+ imp: openrtb2.Imp{
+ Ext: json.RawMessage(`{"there's'":{"something":"strange", "in the":"neighbourhood", "who you gonna call?": 0.1}}`),
+ },
+ assertError: assert.Error,
+ },
+}
+
+func TestPreprocessBidFloorCurrency(t *testing.T) {
+ for name, tc := range testCasesCurrency {
+ t.Run(name, func(t *testing.T) {
+ imp := tc.imp
+ mockConversions := &mockCurrencyConversion{}
+ tc.setMock(&mockConversions.Mock)
+ extraRequestInfo := adapters.ExtraRequestInfo{
+ CurrencyConversions: mockConversions,
+ }
+ err := preprocessBidFloorCurrency(&imp, &extraRequestInfo)
+ assert.True(t, mockConversions.AssertExpectations(t))
+ tc.assertError(t, err)
+ assert.Equal(t, tc.expectedImp, imp)
+ })
+ }
+}
+
+type mockCurrencyConversion struct {
+ mock.Mock
+}
+
+func (m *mockCurrencyConversion) GetRate(from string, to string) (float64, error) {
+ args := m.Called(from, to)
+ return args.Get(0).(float64), args.Error(1)
+}
+
+func (m *mockCurrencyConversion) GetRates() *map[string]map[string]float64 {
+ args := m.Called()
+ return args.Get(0).(*map[string]map[string]float64)
+}
diff --git a/adapters/orbidder/orbiddertest/exemplary/simple-app-banner.json b/adapters/orbidder/orbiddertest/exemplary/simple-app-banner.json
index 8697bff3a92..2315a52c130 100644
--- a/adapters/orbidder/orbiddertest/exemplary/simple-app-banner.json
+++ b/adapters/orbidder/orbiddertest/exemplary/simple-app-banner.json
@@ -51,6 +51,7 @@
}
]
},
+ "bidfloorcur": "EUR",
"ext": {
"bidder": {
"accountId": "orbidder-test",
diff --git a/adapters/orbidder/orbiddertest/supplemental/dsp-bad-request-example.json b/adapters/orbidder/orbiddertest/supplemental/dsp-bad-request-example.json
index 69496c4ff3f..dc199d24ead 100644
--- a/adapters/orbidder/orbiddertest/supplemental/dsp-bad-request-example.json
+++ b/adapters/orbidder/orbiddertest/supplemental/dsp-bad-request-example.json
@@ -51,6 +51,7 @@
}
]
},
+ "bidfloorcur": "EUR",
"ext": {
"bidder": {
"accountId": "orbidder-test",
diff --git a/adapters/orbidder/orbiddertest/supplemental/dsp-bad-response-example.json b/adapters/orbidder/orbiddertest/supplemental/dsp-bad-response-example.json
index d1c57a54a9e..61e70d315f7 100644
--- a/adapters/orbidder/orbiddertest/supplemental/dsp-bad-response-example.json
+++ b/adapters/orbidder/orbiddertest/supplemental/dsp-bad-response-example.json
@@ -51,6 +51,7 @@
}
]
},
+ "bidfloorcur": "EUR",
"ext": {
"bidder": {
"accountId": "orbidder-test",
diff --git a/adapters/orbidder/orbiddertest/supplemental/dsp-internal-server-error-example.json b/adapters/orbidder/orbiddertest/supplemental/dsp-internal-server-error-example.json
index 20ea36ab38c..66a766a9261 100644
--- a/adapters/orbidder/orbiddertest/supplemental/dsp-internal-server-error-example.json
+++ b/adapters/orbidder/orbiddertest/supplemental/dsp-internal-server-error-example.json
@@ -51,6 +51,7 @@
}
]
},
+ "bidfloorcur": "EUR",
"ext": {
"bidder": {
"accountId": "orbidder-test",
diff --git a/adapters/orbidder/orbiddertest/supplemental/dsp-invalid-accountid-example.json b/adapters/orbidder/orbiddertest/supplemental/dsp-invalid-accountid-example.json
index 6bc0482dd0c..7944db44bce 100644
--- a/adapters/orbidder/orbiddertest/supplemental/dsp-invalid-accountid-example.json
+++ b/adapters/orbidder/orbiddertest/supplemental/dsp-invalid-accountid-example.json
@@ -51,6 +51,7 @@
}
]
},
+ "bidfloorcur": "EUR",
"ext": {
"bidder": {
"accountId": "orbidder-test",
diff --git a/adapters/orbidder/orbiddertest/supplemental/empty-imp-request-error.json b/adapters/orbidder/orbiddertest/supplemental/empty-imp-request-error.json
deleted file mode 100644
index 0c5cf6d2faa..00000000000
--- a/adapters/orbidder/orbiddertest/supplemental/empty-imp-request-error.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "mockBidRequest": {
- "id": "test-request-id",
- "imp": [
- ],
- "app": {
- "bundle": "com.prebid"
- },
- "device": {
- "ifa":"87857b31-8942-4646-ae80-ab9c95bf3fab"
- }
- },
- "expectedMakeRequestsErrors": [
- {
- "value": "No impressions in request",
- "comparison": "literal"
- }
- ]
-}
diff --git a/adapters/orbidder/orbiddertest/supplemental/no-content-response.json b/adapters/orbidder/orbiddertest/supplemental/no-content-response.json
index f3b1b287da7..0a1e5f0fc4d 100644
--- a/adapters/orbidder/orbiddertest/supplemental/no-content-response.json
+++ b/adapters/orbidder/orbiddertest/supplemental/no-content-response.json
@@ -51,6 +51,7 @@
}
]
},
+ "bidfloorcur": "EUR",
"ext": {
"bidder": {
"accountId": "orbidder-test",
diff --git a/adapters/orbidder/orbiddertest/supplemental/valid-and-invalid-imps.json b/adapters/orbidder/orbiddertest/supplemental/valid-and-invalid-imps.json
index b6db9f48ee3..1ea133ab1d3 100644
--- a/adapters/orbidder/orbiddertest/supplemental/valid-and-invalid-imps.json
+++ b/adapters/orbidder/orbiddertest/supplemental/valid-and-invalid-imps.json
@@ -57,6 +57,7 @@
}
]
},
+ "bidfloorcur": "EUR",
"ext": {
"bidder": {
"accountId": "orbidder-test",
From d4d25d1e58df46a87cdf1ae36a6365879f96379e Mon Sep 17 00:00:00 2001
From: CompassSSP <95415988+CompassSSP@users.noreply.github.com>
Date: Mon, 20 Dec 2021 20:31:01 +0200
Subject: [PATCH 02/14] New Adapter: Compass (#2102)
---
adapters/compass/compass.go | 154 ++++++++++++++++++
adapters/compass/compass_test.go | 20 +++
.../compasstest/exemplary/endpointId.json | 133 +++++++++++++++
.../compasstest/exemplary/simple-banner.json | 133 +++++++++++++++
.../compasstest/exemplary/simple-native.json | 117 +++++++++++++
.../compasstest/exemplary/simple-video.json | 128 +++++++++++++++
.../exemplary/simple-web-banner.json | 133 +++++++++++++++
.../supplemental/bad_media_type.json | 86 ++++++++++
.../supplemental/bad_response.json | 84 ++++++++++
.../compasstest/supplemental/status-204.json | 79 +++++++++
.../supplemental/status-not-200.json | 84 ++++++++++
adapters/compass/params_test.go | 47 ++++++
config/config.go | 1 +
exchange/adapter_builders.go | 2 +
openrtb_ext/bidders.go | 2 +
openrtb_ext/imp_compass.go | 6 +
static/bidder-info/compass.yaml | 19 +++
static/bidder-params/compass.json | 23 +++
18 files changed, 1251 insertions(+)
create mode 100644 adapters/compass/compass.go
create mode 100644 adapters/compass/compass_test.go
create mode 100644 adapters/compass/compasstest/exemplary/endpointId.json
create mode 100644 adapters/compass/compasstest/exemplary/simple-banner.json
create mode 100644 adapters/compass/compasstest/exemplary/simple-native.json
create mode 100644 adapters/compass/compasstest/exemplary/simple-video.json
create mode 100644 adapters/compass/compasstest/exemplary/simple-web-banner.json
create mode 100644 adapters/compass/compasstest/supplemental/bad_media_type.json
create mode 100644 adapters/compass/compasstest/supplemental/bad_response.json
create mode 100644 adapters/compass/compasstest/supplemental/status-204.json
create mode 100644 adapters/compass/compasstest/supplemental/status-not-200.json
create mode 100644 adapters/compass/params_test.go
create mode 100644 openrtb_ext/imp_compass.go
create mode 100644 static/bidder-info/compass.yaml
create mode 100644 static/bidder-params/compass.json
diff --git a/adapters/compass/compass.go b/adapters/compass/compass.go
new file mode 100644
index 00000000000..eed846576bb
--- /dev/null
+++ b/adapters/compass/compass.go
@@ -0,0 +1,154 @@
+package compass
+
+import (
+ "encoding/json"
+ "fmt"
+ "net/http"
+
+ "github.com/mxmCherry/openrtb/v15/openrtb2"
+ "github.com/prebid/prebid-server/adapters"
+ "github.com/prebid/prebid-server/config"
+ "github.com/prebid/prebid-server/errortypes"
+ "github.com/prebid/prebid-server/openrtb_ext"
+)
+
+type adapter struct {
+ endpoint string
+}
+
+type reqBodyExt struct {
+ CompassBidderExt reqBodyExtBidder `json:"bidder"`
+}
+
+type reqBodyExtBidder struct {
+ Type string `json:"type"`
+ PlacementID string `json:"placementId,omitempty"`
+ EndpointID string `json:"endpointId,omitempty"`
+}
+
+func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) {
+ bidder := &adapter{
+ endpoint: config.Endpoint,
+ }
+ return bidder, nil
+}
+
+func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
+ var err error
+ var adapterRequests []*adapters.RequestData
+
+ reqCopy := *request
+ for _, imp := range request.Imp {
+ reqCopy.Imp = []openrtb2.Imp{imp}
+
+ var bidderExt adapters.ExtImpBidder
+ var compassExt openrtb_ext.ImpExtCompass
+
+ if err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil {
+ return nil, []error{err}
+ }
+ if err = json.Unmarshal(bidderExt.Bidder, &compassExt); err != nil {
+ return nil, []error{err}
+ }
+
+ temp := reqBodyExt{CompassBidderExt: reqBodyExtBidder{}}
+
+ if compassExt.PlacementID != "" {
+ temp.CompassBidderExt.PlacementID = compassExt.PlacementID
+ temp.CompassBidderExt.Type = "publisher"
+ } else if compassExt.EndpointID != "" {
+ temp.CompassBidderExt.EndpointID = compassExt.EndpointID
+ temp.CompassBidderExt.Type = "network"
+ }
+
+ finalyImpExt, err := json.Marshal(temp)
+ if err != nil {
+ return nil, []error{err}
+ }
+
+ reqCopy.Imp[0].Ext = finalyImpExt
+
+ adapterReq, err := a.makeRequest(&reqCopy)
+ if err != nil {
+ return nil, []error{err}
+ }
+
+ if adapterReq != nil {
+ adapterRequests = append(adapterRequests, adapterReq)
+ }
+ }
+ return adapterRequests, nil
+}
+
+func (a *adapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, error) {
+ reqJSON, err := json.Marshal(request)
+ if err != nil {
+ return nil, err
+ }
+
+ headers := http.Header{}
+ headers.Add("Content-Type", "application/json;charset=utf-8")
+ headers.Add("Accept", "application/json")
+ return &adapters.RequestData{
+ Method: "POST",
+ Uri: a.endpoint,
+ Body: reqJSON,
+ Headers: headers,
+ }, err
+}
+
+func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
+ if responseData.StatusCode == http.StatusNoContent {
+ return nil, nil
+ }
+
+ 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}
+ }
+
+ var response openrtb2.BidResponse
+ if err := json.Unmarshal(responseData.Body, &response); err != nil {
+ return nil, []error{err}
+ }
+
+ bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp))
+ bidResponse.Currency = response.Cur
+ for _, seatBid := range response.SeatBid {
+ for i := range seatBid.Bid {
+ bidType, err := getMediaTypeForImp(seatBid.Bid[i].ImpID, request.Imp)
+ if err != nil {
+ return nil, []error{err}
+ }
+
+ b := &adapters.TypedBid{
+ Bid: &seatBid.Bid[i],
+ BidType: bidType,
+ }
+ bidResponse.Bids = append(bidResponse.Bids, b)
+ }
+ }
+ return bidResponse, nil
+}
+
+func getMediaTypeForImp(impID string, imps []openrtb2.Imp) (openrtb_ext.BidType, error) {
+ for _, imp := range imps {
+ if imp.ID == impID {
+ if imp.Banner != nil {
+ return openrtb_ext.BidTypeBanner, nil
+ }
+ if imp.Video != nil {
+ return openrtb_ext.BidTypeVideo, nil
+ }
+ if imp.Native != nil {
+ return openrtb_ext.BidTypeNative, nil
+ }
+ }
+ }
+
+ return "", &errortypes.BadInput{
+ Message: fmt.Sprintf("Failed to find impression \"%s\"", impID),
+ }
+}
diff --git a/adapters/compass/compass_test.go b/adapters/compass/compass_test.go
new file mode 100644
index 00000000000..fce791e5997
--- /dev/null
+++ b/adapters/compass/compass_test.go
@@ -0,0 +1,20 @@
+package compass
+
+import (
+ "testing"
+
+ "github.com/prebid/prebid-server/adapters/adapterstest"
+ "github.com/prebid/prebid-server/config"
+ "github.com/prebid/prebid-server/openrtb_ext"
+)
+
+func TestJsonSamples(t *testing.T) {
+ bidder, buildErr := Builder(openrtb_ext.BidderCompass, config.Adapter{
+ Endpoint: "http://sa-lb.deliverimp.com/pserver"})
+
+ if buildErr != nil {
+ t.Fatalf("Builder returned unexpected error %v", buildErr)
+ }
+
+ adapterstest.RunJSONBidderTest(t, "compasstest", bidder)
+}
diff --git a/adapters/compass/compasstest/exemplary/endpointId.json b/adapters/compass/compasstest/exemplary/endpointId.json
new file mode 100644
index 00000000000..f02481b32a3
--- /dev/null
+++ b/adapters/compass/compasstest/exemplary/endpointId.json
@@ -0,0 +1,133 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "iPad"
+ },
+ "app": {
+ "id": "1",
+ "bundle": "com.wls.testwlsapplication"
+ },
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ },
+ {
+ "w": 300,
+ "h": 600
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "endpointId": "test"
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "http://sa-lb.deliverimp.com/pserver",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ },
+ {
+ "w": 300,
+ "h": 600
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "endpointId": "test",
+ "type": "network"
+ }
+ }
+ }
+ ],
+ "app": {
+ "id": "1",
+ "bundle": "com.wls.testwlsapplication"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "iPad"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "test_bid_id",
+ "impid": "test-imp-id",
+ "price": 0.27543,
+ "adm": "",
+ "cid": "test_cid",
+ "crid": "test_crid",
+ "dealid": "test_dealid",
+ "w": 300,
+ "h": 250,
+ "ext": {
+ "prebid": {
+ "type": "banner"
+ }
+ }
+ }
+ ],
+ "seat": "compass"
+ }
+ ],
+ "cur": "USD"
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "bids": [
+ {
+ "bid": {
+ "id": "test_bid_id",
+ "impid": "test-imp-id",
+ "price": 0.27543,
+ "adm": "",
+ "cid": "test_cid",
+ "crid": "test_crid",
+ "dealid": "test_dealid",
+ "w": 300,
+ "h": 250,
+ "ext": {
+ "prebid": {
+ "type": "banner"
+ }
+ }
+ },
+ "type": "banner"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/compass/compasstest/exemplary/simple-banner.json b/adapters/compass/compasstest/exemplary/simple-banner.json
new file mode 100644
index 00000000000..592570cda6b
--- /dev/null
+++ b/adapters/compass/compasstest/exemplary/simple-banner.json
@@ -0,0 +1,133 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "iPad"
+ },
+ "app": {
+ "id": "1",
+ "bundle": "com.wls.testwlsapplication"
+ },
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ },
+ {
+ "w": 300,
+ "h": 600
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test"
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "http://sa-lb.deliverimp.com/pserver",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ },
+ {
+ "w": 300,
+ "h": 600
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test",
+ "type": "publisher"
+ }
+ }
+ }
+ ],
+ "app": {
+ "id": "1",
+ "bundle": "com.wls.testwlsapplication"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "iPad"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "test_bid_id",
+ "impid": "test-imp-id",
+ "price": 0.27543,
+ "adm": "",
+ "cid": "test_cid",
+ "crid": "test_crid",
+ "dealid": "test_dealid",
+ "w": 300,
+ "h": 250,
+ "ext": {
+ "prebid": {
+ "type": "banner"
+ }
+ }
+ }
+ ],
+ "seat": "compass"
+ }
+ ],
+ "cur": "USD"
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "bids": [
+ {
+ "bid": {
+ "id": "test_bid_id",
+ "impid": "test-imp-id",
+ "price": 0.27543,
+ "adm": "",
+ "cid": "test_cid",
+ "crid": "test_crid",
+ "dealid": "test_dealid",
+ "w": 300,
+ "h": 250,
+ "ext": {
+ "prebid": {
+ "type": "banner"
+ }
+ }
+ },
+ "type": "banner"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/compass/compasstest/exemplary/simple-native.json b/adapters/compass/compasstest/exemplary/simple-native.json
new file mode 100644
index 00000000000..0ec8b43ce9c
--- /dev/null
+++ b/adapters/compass/compasstest/exemplary/simple-native.json
@@ -0,0 +1,117 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "iPad"
+ },
+ "app": {
+ "id": "1",
+ "bundle": "com.wls.testwlsapplication"
+ },
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test",
+ "native": {
+ "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}",
+ "ver": "1.1"
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test"
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "http://sa-lb.deliverimp.com/pserver",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test",
+ "native": {
+ "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}",
+ "ver": "1.1"
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test",
+ "type": "publisher"
+ }
+ }
+ }
+ ],
+ "app": {
+ "id": "1",
+ "bundle": "com.wls.testwlsapplication"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "iPad"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "test_bid_id",
+ "impid": "test-imp-id",
+ "price": 0.27543,
+ "adm": "",
+ "cid": "test_cid",
+ "crid": "test_crid",
+ "dealid": "test_dealid",
+ "w": 300,
+ "h": 250,
+ "ext": {
+ "prebid": {
+ "type": "native"
+ }
+ }
+ }
+ ],
+ "seat": "compass"
+ }
+ ],
+ "cur": "USD"
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "bids": [
+ {
+ "bid": {
+ "id": "test_bid_id",
+ "impid": "test-imp-id",
+ "price": 0.27543,
+ "adm": "",
+ "cid": "test_cid",
+ "crid": "test_crid",
+ "dealid": "test_dealid",
+ "w": 300,
+ "h": 250,
+ "ext": {
+ "prebid": {
+ "type": "native"
+ }
+ }
+ },
+ "type": "native"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/compass/compasstest/exemplary/simple-video.json b/adapters/compass/compasstest/exemplary/simple-video.json
new file mode 100644
index 00000000000..0f279496f36
--- /dev/null
+++ b/adapters/compass/compasstest/exemplary/simple-video.json
@@ -0,0 +1,128 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "iPad"
+ },
+ "app": {
+ "id": "1",
+ "bundle": "com.wls.testwlsapplication"
+ },
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test",
+ "video": {
+ "mimes": [
+ "video/mp4"
+ ],
+ "protocols": [
+ 2,
+ 5
+ ],
+ "w": 1024,
+ "h": 576
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test"
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "http://sa-lb.deliverimp.com/pserver",
+ "body": {
+ "id": "test-request-id",
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "iPad"
+ },
+ "app": {
+ "id": "1",
+ "bundle": "com.wls.testwlsapplication"
+ },
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test",
+ "video": {
+ "mimes": [
+ "video/mp4"
+ ],
+ "protocols": [
+ 2,
+ 5
+ ],
+ "w": 1024,
+ "h": 576
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test",
+ "type": "publisher"
+ }
+ }
+ }
+ ]
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "test_bid_id",
+ "impid": "test-imp-id",
+ "price": 0.27543,
+ "adm": "00:01:00",
+ "cid": "test_cid",
+ "crid": "test_crid",
+ "dealid": "test_dealid",
+ "ext": {
+ "prebid": {
+ "type": "video"
+ }
+ }
+ }
+ ],
+ "seat": "compass"
+ }
+ ],
+ "cur": "USD"
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "currency": "USD",
+ "bids": [
+ {
+ "bid": {
+ "id": "test_bid_id",
+ "impid": "test-imp-id",
+ "price": 0.27543,
+ "adm": "00:01:00",
+ "cid": "test_cid",
+ "crid": "test_crid",
+ "dealid": "test_dealid",
+ "ext": {
+ "prebid": {
+ "type": "video"
+ }
+ }
+ },
+ "type": "video"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/compass/compasstest/exemplary/simple-web-banner.json b/adapters/compass/compasstest/exemplary/simple-web-banner.json
new file mode 100644
index 00000000000..1896101ac68
--- /dev/null
+++ b/adapters/compass/compasstest/exemplary/simple-web-banner.json
@@ -0,0 +1,133 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ },
+ {
+ "w": 300,
+ "h": 600
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test"
+ }
+ }
+ }
+ ],
+ "site": {
+ "id": "1",
+ "domain": "test.com"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Ubuntu"
+ }
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "http://sa-lb.deliverimp.com/pserver",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "tagid": "test",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ },
+ {
+ "w": 300,
+ "h": 600
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test",
+ "type": "publisher"
+ }
+ }
+ }
+ ],
+ "site": {
+ "id": "1",
+ "domain": "test.com"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ua": "Ubuntu"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "test_bid_id",
+ "impid": "test-imp-id",
+ "price": 0.27543,
+ "adm": "",
+ "cid": "test_cid",
+ "crid": "test_crid",
+ "dealid": "test_dealid",
+ "w": 468,
+ "h": 60,
+ "ext": {
+ "prebid": {
+ "type": "banner"
+ }
+ }
+ }
+ ],
+ "seat": "compass"
+ }
+ ],
+ "cur": "USD"
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "bids": [
+ {
+ "bid": {
+ "id": "test_bid_id",
+ "impid": "test-imp-id",
+ "price": 0.27543,
+ "adm": "",
+ "cid": "test_cid",
+ "crid": "test_crid",
+ "dealid": "test_dealid",
+ "w": 468,
+ "h": 60,
+ "ext": {
+ "prebid": {
+ "type": "banner"
+ }
+ }
+ },
+ "type": "banner"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/compass/compasstest/supplemental/bad_media_type.json b/adapters/compass/compasstest/supplemental/bad_media_type.json
new file mode 100644
index 00000000000..0bfaec4f23d
--- /dev/null
+++ b/adapters/compass/compasstest/supplemental/bad_media_type.json
@@ -0,0 +1,86 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "ext": {
+ "bidder": {
+ "placementId": "test"
+ }
+ }
+ }
+ ],
+ "app": {
+ "id": "1",
+ "bundle": "com.wls.testwlsapplication"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ifa": "sdjfksdf-dfsds-dsdg-dsgg"
+ }
+ },
+ "httpCalls": [{
+ "expectedRequest": {
+ "uri": "http://sa-lb.deliverimp.com/pserver",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "ext": {
+ "bidder": {
+ "placementId": "test",
+ "type": "publisher"
+ }
+ }
+ }
+ ],
+ "app": {
+ "id": "1",
+ "bundle": "com.wls.testwlsapplication"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ifa": "sdjfksdf-dfsds-dsdg-dsgg"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "test_bid_id",
+ "impid": "test-imp-id",
+ "price": 0.27543,
+ "adm": "",
+ "cid": "test_cid",
+ "crid": "test_crid",
+ "dealid": "test_dealid",
+ "w": 300,
+ "h": 250,
+ "ext": {
+ "prebid": {
+ "type": "banner"
+ }
+ }
+ }
+ ],
+ "seat": "compass"
+ }
+ ],
+ "cur": "USD"
+ }
+ }
+ }],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "Failed to find impression \"test-imp-id\"",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/compass/compasstest/supplemental/bad_response.json b/adapters/compass/compasstest/supplemental/bad_response.json
new file mode 100644
index 00000000000..3c660338c63
--- /dev/null
+++ b/adapters/compass/compasstest/supplemental/bad_response.json
@@ -0,0 +1,84 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ },
+ {
+ "w": 300,
+ "h": 600
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test"
+ }
+ }
+ }
+ ],
+ "app": {
+ "id": "1",
+ "bundle": "com.wls.testwlsapplication"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ifa": "sdjfksdf-dfsds-dsdg-dsgg"
+ }
+ },
+ "httpCalls": [{
+ "expectedRequest": {
+ "uri": "http://sa-lb.deliverimp.com/pserver",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ },
+ {
+ "w": 300,
+ "h": 600
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test",
+ "type": "publisher"
+ }
+ }
+ }
+ ],
+ "app": {
+ "id": "1",
+ "bundle": "com.wls.testwlsapplication"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ifa": "sdjfksdf-dfsds-dsdg-dsgg"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": ""
+ }
+ }],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/compass/compasstest/supplemental/status-204.json b/adapters/compass/compasstest/supplemental/status-204.json
new file mode 100644
index 00000000000..1ff5c55abeb
--- /dev/null
+++ b/adapters/compass/compasstest/supplemental/status-204.json
@@ -0,0 +1,79 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ },
+ {
+ "w": 300,
+ "h": 600
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test"
+ }
+ }
+ }
+ ],
+ "app": {
+ "id": "1",
+ "bundle": "com.wls.testwlsapplication"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ifa": "sdjfksdf-dfsds-dsdg-dsgg"
+ }
+ },
+ "httpCalls": [{
+ "expectedRequest": {
+ "uri": "http://sa-lb.deliverimp.com/pserver",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ },
+ {
+ "w": 300,
+ "h": 600
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test",
+ "type": "publisher"
+ }
+ }
+ }
+ ],
+ "app": {
+ "id": "1",
+ "bundle": "com.wls.testwlsapplication"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ifa": "sdjfksdf-dfsds-dsdg-dsgg"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 204,
+ "body": {}
+ }
+ }],
+ "expectedBidResponses": []
+}
diff --git a/adapters/compass/compasstest/supplemental/status-not-200.json b/adapters/compass/compasstest/supplemental/status-not-200.json
new file mode 100644
index 00000000000..51f648de360
--- /dev/null
+++ b/adapters/compass/compasstest/supplemental/status-not-200.json
@@ -0,0 +1,84 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ },
+ {
+ "w": 300,
+ "h": 600
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test"
+ }
+ }
+ }
+ ],
+ "app": {
+ "id": "1",
+ "bundle": "com.wls.testwlsapplication"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ifa": "sdjfksdf-dfsds-dsdg-dsgg"
+ }
+ },
+ "httpCalls": [{
+ "expectedRequest": {
+ "uri": "http://sa-lb.deliverimp.com/pserver",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ },
+ {
+ "w": 300,
+ "h": 600
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test",
+ "type": "publisher"
+ }
+ }
+ }
+ ],
+ "app": {
+ "id": "1",
+ "bundle": "com.wls.testwlsapplication"
+ },
+ "device": {
+ "ip": "123.123.123.123",
+ "ifa": "sdjfksdf-dfsds-dsdg-dsgg"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 404,
+ "body": {}
+ }
+ }],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "Unexpected status code: 404. Run with request.debug = 1 for more info.",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/compass/params_test.go b/adapters/compass/params_test.go
new file mode 100644
index 00000000000..fca398b06fb
--- /dev/null
+++ b/adapters/compass/params_test.go
@@ -0,0 +1,47 @@
+package compass
+
+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 schema. %v", err)
+ }
+
+ for _, p := range validParams {
+ if err := validator.Validate(openrtb_ext.BidderCompass, json.RawMessage(p)); err != nil {
+ t.Errorf("Schema rejected valid params: %s", p)
+ }
+ }
+}
+
+func TestInvalidParams(t *testing.T) {
+ validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+ if err != nil {
+ t.Fatalf("Failed to fetch the json schema. %v", err)
+ }
+
+ for _, p := range invalidParams {
+ if err := validator.Validate(openrtb_ext.BidderCompass, json.RawMessage(p)); err == nil {
+ t.Errorf("Schema allowed invalid params: %s", p)
+ }
+ }
+}
+
+var validParams = []string{
+ `{"placementId": "test"}`,
+ `{"placementId": "1"}`,
+ `{"endpointId": "test"}`,
+ `{"endpointId": "1"}`,
+}
+
+var invalidParams = []string{
+ `{"placementId": 42}`,
+ `{"endpointId": 42}`,
+ `{"placementId": "1", "endpointId": "1"}`,
+}
diff --git a/config/config.go b/config/config.go
index f9dbc274ec1..dd842be72b9 100644
--- a/config/config.go
+++ b/config/config.go
@@ -809,6 +809,7 @@ func SetupViper(v *viper.Viper, filename string) {
v.SetDefault("adapters.brightroll.endpoint", "http://east-bid.ybp.yahoo.com/bid/appnexuspbs")
v.SetDefault("adapters.coinzilla.endpoint", "http://request-global.czilladx.com/serve/prebid-server.php")
v.SetDefault("adapters.colossus.endpoint", "http://colossusssp.com/?c=o&m=rtb")
+ v.SetDefault("adapters.compass.endpoint", "http://sa-lb.deliverimp.com/pserver")
v.SetDefault("adapters.connectad.endpoint", "http://bidder.connectad.io/API?src=pbs")
v.SetDefault("adapters.consumable.endpoint", "https://e.serverbid.com/api/v2")
v.SetDefault("adapters.conversant.endpoint", "http://api.hb.ad.cpe.dotomi.com/cvx/server/hb/ortb/25")
diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go
index 0f14b75c27f..59c892ab9e4 100755
--- a/exchange/adapter_builders.go
+++ b/exchange/adapter_builders.go
@@ -44,6 +44,7 @@ import (
"github.com/prebid/prebid-server/adapters/brightroll"
"github.com/prebid/prebid-server/adapters/coinzilla"
"github.com/prebid/prebid-server/adapters/colossus"
+ "github.com/prebid/prebid-server/adapters/compass"
"github.com/prebid/prebid-server/adapters/connectad"
"github.com/prebid/prebid-server/adapters/consumable"
"github.com/prebid/prebid-server/adapters/conversant"
@@ -183,6 +184,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
openrtb_ext.BidderBrightroll: brightroll.Builder,
openrtb_ext.BidderCoinzilla: coinzilla.Builder,
openrtb_ext.BidderColossus: colossus.Builder,
+ openrtb_ext.BidderCompass: compass.Builder,
openrtb_ext.BidderConnectAd: connectad.Builder,
openrtb_ext.BidderConsumable: consumable.Builder,
openrtb_ext.BidderConversant: conversant.Builder,
diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go
index 7ebfe631bdb..d02a7a48320 100644
--- a/openrtb_ext/bidders.go
+++ b/openrtb_ext/bidders.go
@@ -119,6 +119,7 @@ const (
BidderBrightroll BidderName = "brightroll"
BidderCoinzilla BidderName = "coinzilla"
BidderColossus BidderName = "colossus"
+ BidderCompass BidderName = "compass"
BidderConnectAd BidderName = "connectad"
BidderConsumable BidderName = "consumable"
BidderConversant BidderName = "conversant"
@@ -262,6 +263,7 @@ func CoreBidderNames() []BidderName {
BidderBrightroll,
BidderCoinzilla,
BidderColossus,
+ BidderCompass,
BidderConnectAd,
BidderConsumable,
BidderConversant,
diff --git a/openrtb_ext/imp_compass.go b/openrtb_ext/imp_compass.go
new file mode 100644
index 00000000000..3a150b9daaf
--- /dev/null
+++ b/openrtb_ext/imp_compass.go
@@ -0,0 +1,6 @@
+package openrtb_ext
+
+type ImpExtCompass struct {
+ PlacementID string `json:"placementId"`
+ EndpointID string `json:"endpointId"`
+}
diff --git a/static/bidder-info/compass.yaml b/static/bidder-info/compass.yaml
new file mode 100644
index 00000000000..5944b27eb5a
--- /dev/null
+++ b/static/bidder-info/compass.yaml
@@ -0,0 +1,19 @@
+maintainer:
+ email: "sa-support@brightcom.com"
+gvlVendorID: 883
+capabilities:
+ site:
+ mediaTypes:
+ - banner
+ - video
+ - native
+
+ app:
+ mediaTypes:
+ - banner
+ - video
+ - native
+userSync:
+ redirect:
+ url: "https://sa-cs.deliverimp.com/pserver?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir={{.RedirectURL}}"
+ userMacro: "[UID]"
diff --git a/static/bidder-params/compass.json b/static/bidder-params/compass.json
new file mode 100644
index 00000000000..11fcbf31ea4
--- /dev/null
+++ b/static/bidder-params/compass.json
@@ -0,0 +1,23 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "title": "Compass Adapter Params",
+ "description": "A schema which validates params accepted by the Compass adapter",
+ "type": "object",
+
+ "properties": {
+ "placementId": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Placement ID"
+ },
+ "endpointId": {
+ "type": "string",
+ "minLength": 1,
+ "description": "Endpoint ID"
+ }
+ },
+ "oneOf": [
+ { "required": ["placementId"] },
+ { "required": ["endpointId"] }
+ ]
+ }
\ No newline at end of file
From 61ece3521f3c3b6838896633f7b5a7b6747b0cee Mon Sep 17 00:00:00 2001
From: thuyhq <61451682+thuyhq@users.noreply.github.com>
Date: Tue, 21 Dec 2021 02:08:49 +0700
Subject: [PATCH 03/14] New Adapter: apacdex and Remove Adapter:
valueimpression (#2097)
Valueimpression to become apacdex adapter
---
adapters/apacdex/apacdex.go | 161 ++++++++++++++++++
.../apacdex_test.go} | 6 +-
.../exemplary/banner-and-video.json | 16 +-
.../apacdextest}/exemplary/banner.json | 17 +-
.../apacdextest}/exemplary/video.json | 0
.../supplemental/explicit-dimensions.json | 0
.../invalid-response-no-bids.json | 0
.../invalid-response-unmarshall-error.json | 0
.../supplemental/no-imps-in-request.json | 0
.../supplemental/server-error-code.json | 2 +-
.../supplemental/server-no-content.json | 0
.../supplemental/wrong-bid-ext.json} | 12 +-
.../supplemental/wrong-impression-ext.json | 2 +-
.../params_test.go | 22 ++-
adapters/valueimpression/valueimpression.go | 157 -----------------
config/config.go | 4 +-
exchange/adapter_builders.go | 6 +-
openrtb_ext/bidders.go | 4 +
openrtb_ext/imp_apacdex.go | 7 +
openrtb_ext/imp_valueimpression.go | 5 -
static/bidder-info/apacdex.yaml | 20 +++
static/bidder-info/quantumdex.yaml | 20 +++
static/bidder-info/valueimpression.yaml | 11 +-
static/bidder-params/apacdex.json | 32 ++++
static/bidder-params/quantumdex.json | 32 ++++
static/bidder-params/valueimpression.json | 43 +++--
26 files changed, 371 insertions(+), 208 deletions(-)
create mode 100644 adapters/apacdex/apacdex.go
rename adapters/{valueimpression/valueimpression_test.go => apacdex/apacdex_test.go} (65%)
rename adapters/{valueimpression/valueimpressiontest => apacdex/apacdextest}/exemplary/banner-and-video.json (88%)
rename adapters/{valueimpression/valueimpressiontest => apacdex/apacdextest}/exemplary/banner.json (85%)
rename adapters/{valueimpression/valueimpressiontest => apacdex/apacdextest}/exemplary/video.json (100%)
rename adapters/{valueimpression/valueimpressiontest => apacdex/apacdextest}/supplemental/explicit-dimensions.json (100%)
rename adapters/{valueimpression/valueimpressiontest => apacdex/apacdextest}/supplemental/invalid-response-no-bids.json (100%)
rename adapters/{valueimpression/valueimpressiontest => apacdex/apacdextest}/supplemental/invalid-response-unmarshall-error.json (100%)
rename adapters/{valueimpression/valueimpressiontest => apacdex/apacdextest}/supplemental/no-imps-in-request.json (100%)
rename adapters/{valueimpression/valueimpressiontest => apacdex/apacdextest}/supplemental/server-error-code.json (91%)
rename adapters/{valueimpression/valueimpressiontest => apacdex/apacdextest}/supplemental/server-no-content.json (100%)
rename adapters/{valueimpression/valueimpressiontest/supplemental/wrong-impression-mapping.json => apacdex/apacdextest/supplemental/wrong-bid-ext.json} (85%)
rename adapters/{valueimpression/valueimpressiontest => apacdex/apacdextest}/supplemental/wrong-impression-ext.json (89%)
rename adapters/{valueimpression => apacdex}/params_test.go (53%)
delete mode 100644 adapters/valueimpression/valueimpression.go
create mode 100644 openrtb_ext/imp_apacdex.go
delete mode 100644 openrtb_ext/imp_valueimpression.go
create mode 100644 static/bidder-info/apacdex.yaml
create mode 100644 static/bidder-info/quantumdex.yaml
create mode 100644 static/bidder-params/apacdex.json
create mode 100644 static/bidder-params/quantumdex.json
diff --git a/adapters/apacdex/apacdex.go b/adapters/apacdex/apacdex.go
new file mode 100644
index 00000000000..294b7188940
--- /dev/null
+++ b/adapters/apacdex/apacdex.go
@@ -0,0 +1,161 @@
+package apacdex
+
+import (
+ "encoding/json"
+ "fmt"
+ "net/http"
+
+ "github.com/mxmCherry/openrtb/v15/openrtb2"
+ "github.com/prebid/prebid-server/adapters"
+ "github.com/prebid/prebid-server/config"
+ "github.com/prebid/prebid-server/errortypes"
+ "github.com/prebid/prebid-server/openrtb_ext"
+)
+
+type adapter struct {
+ endpoint string
+}
+
+// Builder builds a new instance of the Apacdex adapter for the given bidder with the given config.
+func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) {
+ bidder := &adapter{
+ endpoint: config.Endpoint,
+ }
+ return bidder, nil
+}
+
+func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
+ var errs []error
+ var adapterRequests []*adapters.RequestData
+
+ if err := preprocess(request); err != nil {
+ errs = append(errs, err)
+ return nil, errs
+ }
+
+ adapterReq, err := a.makeRequest(request)
+ if err != nil {
+ errs = append(errs, err)
+ return nil, errs
+ }
+
+ adapterRequests = append(adapterRequests, adapterReq)
+
+ return adapterRequests, errs
+}
+
+func (a *adapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, error) {
+ var err error
+
+ jsonBody, err := json.Marshal(request)
+ if err != nil {
+ return nil, err
+ }
+
+ headers := http.Header{}
+ headers.Add("Content-Type", "application/json;charset=utf-8")
+ headers.Add("Accept", "application/json")
+ headers.Add("x-openrtb-version", "2.5")
+
+ return &adapters.RequestData{
+ Method: "POST",
+ Uri: a.endpoint,
+ Body: jsonBody,
+ Headers: headers,
+ }, nil
+}
+
+func preprocess(request *openrtb2.BidRequest) error {
+ if len(request.Imp) == 0 {
+ return &errortypes.BadInput{
+ Message: "No Imps in Bid Request",
+ }
+ }
+ for i := 0; i < len(request.Imp); i++ {
+ var imp = &request.Imp[i]
+ var bidderExt adapters.ExtImpBidder
+
+ if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
+ return &errortypes.BadInput{
+ Message: err.Error(),
+ }
+ }
+
+ var extImp openrtb_ext.ExtImpApacdex
+ if err := json.Unmarshal(bidderExt.Bidder, &extImp); err != nil {
+ return &errortypes.BadInput{
+ Message: err.Error(),
+ }
+ }
+
+ imp.Ext = bidderExt.Bidder
+ }
+
+ return nil
+}
+
+func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
+ if responseData.StatusCode == http.StatusNoContent {
+ return nil, nil
+ }
+
+ if responseData.StatusCode == http.StatusBadRequest {
+ err := &errortypes.BadInput{
+ Message: "Unexpected status code: 400. Bad request from publisher. 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}
+ }
+
+ var response openrtb2.BidResponse
+
+ if err := json.Unmarshal(responseData.Body, &response); err != nil {
+ return nil, []error{&errortypes.BadServerResponse{
+ Message: err.Error(),
+ }}
+ }
+
+ if len(response.SeatBid) == 0 {
+ return nil, nil
+ }
+
+ bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp))
+ bidResponse.Currency = response.Cur
+ var errors []error
+
+ for _, seatbid := range response.SeatBid {
+ for _, bid := range seatbid.Bid {
+ bidType, err := getMediaTypeForBid(bid)
+ if err != nil {
+ errors = append(errors, err)
+ continue
+ }
+ bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
+ Bid: &bid,
+ BidType: bidType,
+ })
+ }
+ }
+ return bidResponse, errors
+}
+
+// getMediaTypeForBid determines which type of bid.
+func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) {
+ if bid.Ext != nil {
+ var bidExt openrtb_ext.ExtBid
+ err := json.Unmarshal(bid.Ext, &bidExt)
+ if err == nil && bidExt.Prebid != nil {
+ return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type))
+ }
+ }
+
+ return "", &errortypes.BadServerResponse{
+ Message: fmt.Sprintf("Failed to parse bid mediatype for impression \"%s\"", bid.ImpID),
+ }
+}
diff --git a/adapters/valueimpression/valueimpression_test.go b/adapters/apacdex/apacdex_test.go
similarity index 65%
rename from adapters/valueimpression/valueimpression_test.go
rename to adapters/apacdex/apacdex_test.go
index f4d33864978..997302f6ea4 100644
--- a/adapters/valueimpression/valueimpression_test.go
+++ b/adapters/apacdex/apacdex_test.go
@@ -1,4 +1,4 @@
-package valueimpression
+package apacdex
import (
"testing"
@@ -9,12 +9,12 @@ import (
)
func TestJsonSamples(t *testing.T) {
- bidder, buildErr := Builder(openrtb_ext.BidderValueImpression, config.Adapter{
+ bidder, buildErr := Builder(openrtb_ext.BidderApacdex, config.Adapter{
Endpoint: "//host"})
if buildErr != nil {
t.Fatalf("Builder returned unexpected error %v", buildErr)
}
- adapterstest.RunJSONBidderTest(t, "valueimpressiontest", bidder)
+ adapterstest.RunJSONBidderTest(t, "apacdextest", bidder)
}
diff --git a/adapters/valueimpression/valueimpressiontest/exemplary/banner-and-video.json b/adapters/apacdex/apacdextest/exemplary/banner-and-video.json
similarity index 88%
rename from adapters/valueimpression/valueimpressiontest/exemplary/banner-and-video.json
rename to adapters/apacdex/apacdextest/exemplary/banner-and-video.json
index fd9d401cd44..78ce13fd106 100644
--- a/adapters/valueimpression/valueimpressiontest/exemplary/banner-and-video.json
+++ b/adapters/apacdex/apacdextest/exemplary/banner-and-video.json
@@ -92,7 +92,7 @@
"id": "test-request-id",
"seatbid": [
{
- "seat": "valueimpression",
+ "seat": "apacdex",
"bid": [
{
"id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
@@ -101,7 +101,12 @@
"adm": "some-test-ad",
"crid": "crid_10",
"h": 250,
- "w": 300
+ "w": 300,
+ "ext": {
+ "prebid": {
+ "type": "video"
+ }
+ }
}
]
}
@@ -121,7 +126,12 @@
"adm": "some-test-ad",
"crid": "crid_10",
"w": 300,
- "h": 250
+ "h": 250,
+ "ext": {
+ "prebid": {
+ "type": "video"
+ }
+ }
},
"type": "video"
}
diff --git a/adapters/valueimpression/valueimpressiontest/exemplary/banner.json b/adapters/apacdex/apacdextest/exemplary/banner.json
similarity index 85%
rename from adapters/valueimpression/valueimpressiontest/exemplary/banner.json
rename to adapters/apacdex/apacdextest/exemplary/banner.json
index 1ef11ade199..31b685da15f 100644
--- a/adapters/valueimpression/valueimpressiontest/exemplary/banner.json
+++ b/adapters/apacdex/apacdextest/exemplary/banner.json
@@ -56,7 +56,7 @@
"id": "test-request-id",
"seatbid": [
{
- "seat": "valueimpression",
+ "seat": "apacdex",
"bid": [
{
"id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
@@ -65,7 +65,12 @@
"adm": "some-test-ad",
"crid": "crid_10",
"h": 250,
- "w": 300
+ "w": 300,
+ "ext": {
+ "prebid": {
+ "type": "banner"
+ }
+ }
}
]
}
@@ -87,7 +92,12 @@
"adm": "some-test-ad",
"crid": "crid_10",
"w": 300,
- "h": 250
+ "h": 250,
+ "ext": {
+ "prebid": {
+ "type": "banner"
+ }
+ }
},
"type": "banner"
}
@@ -95,4 +105,3 @@
}
]
}
-
\ No newline at end of file
diff --git a/adapters/valueimpression/valueimpressiontest/exemplary/video.json b/adapters/apacdex/apacdextest/exemplary/video.json
similarity index 100%
rename from adapters/valueimpression/valueimpressiontest/exemplary/video.json
rename to adapters/apacdex/apacdextest/exemplary/video.json
diff --git a/adapters/valueimpression/valueimpressiontest/supplemental/explicit-dimensions.json b/adapters/apacdex/apacdextest/supplemental/explicit-dimensions.json
similarity index 100%
rename from adapters/valueimpression/valueimpressiontest/supplemental/explicit-dimensions.json
rename to adapters/apacdex/apacdextest/supplemental/explicit-dimensions.json
diff --git a/adapters/valueimpression/valueimpressiontest/supplemental/invalid-response-no-bids.json b/adapters/apacdex/apacdextest/supplemental/invalid-response-no-bids.json
similarity index 100%
rename from adapters/valueimpression/valueimpressiontest/supplemental/invalid-response-no-bids.json
rename to adapters/apacdex/apacdextest/supplemental/invalid-response-no-bids.json
diff --git a/adapters/valueimpression/valueimpressiontest/supplemental/invalid-response-unmarshall-error.json b/adapters/apacdex/apacdextest/supplemental/invalid-response-unmarshall-error.json
similarity index 100%
rename from adapters/valueimpression/valueimpressiontest/supplemental/invalid-response-unmarshall-error.json
rename to adapters/apacdex/apacdextest/supplemental/invalid-response-unmarshall-error.json
diff --git a/adapters/valueimpression/valueimpressiontest/supplemental/no-imps-in-request.json b/adapters/apacdex/apacdextest/supplemental/no-imps-in-request.json
similarity index 100%
rename from adapters/valueimpression/valueimpressiontest/supplemental/no-imps-in-request.json
rename to adapters/apacdex/apacdextest/supplemental/no-imps-in-request.json
diff --git a/adapters/valueimpression/valueimpressiontest/supplemental/server-error-code.json b/adapters/apacdex/apacdextest/supplemental/server-error-code.json
similarity index 91%
rename from adapters/valueimpression/valueimpressiontest/supplemental/server-error-code.json
rename to adapters/apacdex/apacdextest/supplemental/server-error-code.json
index ea31fdc2fe9..b8656aa74a5 100644
--- a/adapters/valueimpression/valueimpressiontest/supplemental/server-error-code.json
+++ b/adapters/apacdex/apacdextest/supplemental/server-error-code.json
@@ -46,7 +46,7 @@
"expectedMakeBidsErrors": [
{
- "value": "Bad server response: HTTP status 500",
+ "value": "Unexpected status code: 500. Run with request.debug = 1 for more info.",
"comparison": "literal"
}
]
diff --git a/adapters/valueimpression/valueimpressiontest/supplemental/server-no-content.json b/adapters/apacdex/apacdextest/supplemental/server-no-content.json
similarity index 100%
rename from adapters/valueimpression/valueimpressiontest/supplemental/server-no-content.json
rename to adapters/apacdex/apacdextest/supplemental/server-no-content.json
diff --git a/adapters/valueimpression/valueimpressiontest/supplemental/wrong-impression-mapping.json b/adapters/apacdex/apacdextest/supplemental/wrong-bid-ext.json
similarity index 85%
rename from adapters/valueimpression/valueimpressiontest/supplemental/wrong-impression-mapping.json
rename to adapters/apacdex/apacdextest/supplemental/wrong-bid-ext.json
index ef4d3a7526b..f2842d88d2f 100644
--- a/adapters/valueimpression/valueimpressiontest/supplemental/wrong-impression-mapping.json
+++ b/adapters/apacdex/apacdextest/supplemental/wrong-bid-ext.json
@@ -20,7 +20,6 @@
}
]
},
-
"httpCalls": [
{
"expectedRequest": {
@@ -29,7 +28,7 @@
"id": "test-request-id",
"imp": [
{
- "id":"test-imp-id",
+ "id": "test-imp-id",
"video": {
"w": 900,
"h": 250,
@@ -54,10 +53,11 @@
"bid": [
{
"id": "test-bid-id",
- "impid": "BOGUS-IMPID",
+ "impid": "another-imp-id",
"price": 3.5,
"w": 900,
- "h": 250
+ "h": 250,
+ "ext": {}
}
]
}
@@ -68,8 +68,8 @@
],
"expectedMakeBidsErrors": [
{
- "value": "bid id='test-bid-id' could not find valid impid='BOGUS-IMPID'",
+ "value": "Failed to parse bid mediatype for impression \"another-imp-id\"",
"comparison": "regex"
}
-]
+ ]
}
\ No newline at end of file
diff --git a/adapters/valueimpression/valueimpressiontest/supplemental/wrong-impression-ext.json b/adapters/apacdex/apacdextest/supplemental/wrong-impression-ext.json
similarity index 89%
rename from adapters/valueimpression/valueimpressiontest/supplemental/wrong-impression-ext.json
rename to adapters/apacdex/apacdextest/supplemental/wrong-impression-ext.json
index 13514ac8ab8..09efa59563d 100644
--- a/adapters/valueimpression/valueimpressiontest/supplemental/wrong-impression-ext.json
+++ b/adapters/apacdex/apacdextest/supplemental/wrong-impression-ext.json
@@ -19,7 +19,7 @@
"expectedMakeRequestsErrors": [
{
- "value": "json: cannot unmarshal number into Go struct field ExtImpValueImpression.siteId of type string",
+ "value": "json: cannot unmarshal number into Go struct field ExtImpApacdex.siteId of type string",
"comparison": "literal"
}
]
diff --git a/adapters/valueimpression/params_test.go b/adapters/apacdex/params_test.go
similarity index 53%
rename from adapters/valueimpression/params_test.go
rename to adapters/apacdex/params_test.go
index 46471de24bb..2e5f626e16d 100644
--- a/adapters/valueimpression/params_test.go
+++ b/adapters/apacdex/params_test.go
@@ -1,4 +1,4 @@
-package valueimpression
+package apacdex
import (
"encoding/json"
@@ -7,9 +7,9 @@ import (
"github.com/prebid/prebid-server/openrtb_ext"
)
-// This file actually intends to test static/bidder-params/valueimpression.json
-// These also validate the format of the external API: request.imp[i].ext.valueimpression
-// TestValidParams makes sure that the ValueImpression schema accepts all imp.ext fields which we intend to support.
+// This file actually intends to test static/bidder-params/apacdex.json
+// These also validate the format of the external API: request.imp[i].ext.apacdex
+// TestValidParams makes sure that the Apacdex schema accepts all imp.ext fields which we intend to support.
func TestValidParams(t *testing.T) {
validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
@@ -18,13 +18,13 @@ func TestValidParams(t *testing.T) {
}
for _, validParam := range validParams {
- if err := validator.Validate(openrtb_ext.BidderValueImpression, json.RawMessage(validParam)); err != nil {
- t.Errorf("Schema rejected ValueImpression params: %s", validParam)
+ if err := validator.Validate(openrtb_ext.BidderApacdex, json.RawMessage(validParam)); err != nil {
+ t.Errorf("Schema rejected Apacdex params: %s", validParam)
}
}
}
-// TestInvalidParams makes sure that the ValueImpression schema rejects all the imp.ext fields we don't support.
+// TestInvalidParams makes sure that the Apacdex schema rejects all the imp.ext fields we don't support.
func TestInvalidParams(t *testing.T) {
validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
if err != nil {
@@ -32,7 +32,7 @@ func TestInvalidParams(t *testing.T) {
}
for _, invalidParam := range invalidParams {
- if err := validator.Validate(openrtb_ext.BidderValueImpression, json.RawMessage(invalidParam)); err == nil {
+ if err := validator.Validate(openrtb_ext.BidderApacdex, json.RawMessage(invalidParam)); err == nil {
t.Errorf("Schema allowed unexpected params: %s", invalidParam)
}
}
@@ -40,6 +40,9 @@ func TestInvalidParams(t *testing.T) {
var validParams = []string{
`{"siteId": "123"}`,
+ `{"siteId": "123", "floorPrice": 0.05}`,
+ `{"placementId": "123123"}`,
+ `{"placementId": "123123", "floorPrice": 0.05}`,
}
var invalidParams = []string{
@@ -47,6 +50,7 @@ var invalidParams = []string{
`null`,
`true`,
`154`,
- `{"siteId": 123}`, // siteId should be string
+ `{"siteId": 123}`,
`{"invalid_param": "123"}`,
+ `{"siteId": "123", "placementId": "123123"}`,
}
diff --git a/adapters/valueimpression/valueimpression.go b/adapters/valueimpression/valueimpression.go
deleted file mode 100644
index aac8faab52c..00000000000
--- a/adapters/valueimpression/valueimpression.go
+++ /dev/null
@@ -1,157 +0,0 @@
-package valueimpression
-
-import (
- "encoding/json"
- "fmt"
- "net/http"
-
- "github.com/mxmCherry/openrtb/v15/openrtb2"
- "github.com/prebid/prebid-server/adapters"
- "github.com/prebid/prebid-server/config"
- "github.com/prebid/prebid-server/errortypes"
- "github.com/prebid/prebid-server/openrtb_ext"
-)
-
-type ValueImpressionAdapter struct {
- endpoint string
-}
-
-func (a *ValueImpressionAdapter) MakeRequests(request *openrtb2.BidRequest, unused *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
- var errs []error
- var adapterRequests []*adapters.RequestData
-
- if err := preprocess(request); err != nil {
- errs = append(errs, err)
- return nil, errs
- }
-
- adapterReq, err := a.makeRequest(request)
- if err != nil {
- errs = append(errs, err)
- return nil, errs
- }
-
- adapterRequests = append(adapterRequests, adapterReq)
-
- return adapterRequests, errs
-}
-
-func (a *ValueImpressionAdapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, error) {
- var err error
-
- jsonBody, err := json.Marshal(request)
- if err != nil {
- return nil, err
- }
-
- headers := http.Header{}
- headers.Add("Content-Type", "application/json;charset=utf-8")
-
- return &adapters.RequestData{
- Method: "POST",
- Uri: a.endpoint,
- Body: jsonBody,
- Headers: headers,
- }, nil
-}
-
-func preprocess(request *openrtb2.BidRequest) error {
- if len(request.Imp) == 0 {
- return &errortypes.BadInput{
- Message: "No Imps in Bid Request",
- }
- }
- for i := 0; i < len(request.Imp); i++ {
- var imp = &request.Imp[i]
- var bidderExt adapters.ExtImpBidder
-
- if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
- return &errortypes.BadInput{
- Message: err.Error(),
- }
- }
-
- var extImp openrtb_ext.ExtImpValueImpression
- if err := json.Unmarshal(bidderExt.Bidder, &extImp); err != nil {
- return &errortypes.BadInput{
- Message: err.Error(),
- }
- }
-
- imp.Ext = bidderExt.Bidder
- }
-
- return nil
-}
-
-// MakeBids based on valueimpression server response
-func (a *ValueImpressionAdapter) MakeBids(bidRequest *openrtb2.BidRequest, unused *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
- if responseData.StatusCode == http.StatusNoContent {
- return nil, nil
- }
-
- if responseData.StatusCode == http.StatusBadRequest {
- return nil, []error{&errortypes.BadInput{
- Message: fmt.Sprintf("Bad user input: HTTP status %d", responseData.StatusCode),
- }}
- }
-
- if responseData.StatusCode != http.StatusOK {
- return nil, []error{&errortypes.BadServerResponse{
- Message: fmt.Sprintf("Bad server response: HTTP status %d", responseData.StatusCode),
- }}
- }
-
- var bidResponse openrtb2.BidResponse
-
- if err := json.Unmarshal(responseData.Body, &bidResponse); err != nil {
- return nil, []error{&errortypes.BadServerResponse{
- Message: err.Error(),
- }}
- }
-
- if len(bidResponse.SeatBid) == 0 {
- return nil, nil
- }
-
- rv := adapters.NewBidderResponseWithBidsCapacity(len(bidResponse.SeatBid[0].Bid))
- var errors []error
-
- for _, seatbid := range bidResponse.SeatBid {
- for _, bid := range seatbid.Bid {
- foundMatchingBid := false
- bidType := openrtb_ext.BidTypeBanner
- for _, imp := range bidRequest.Imp {
- if imp.ID == bid.ImpID {
- foundMatchingBid = true
- if imp.Banner != nil {
- bidType = openrtb_ext.BidTypeBanner
- } else if imp.Video != nil {
- bidType = openrtb_ext.BidTypeVideo
- }
- break
- }
- }
-
- if foundMatchingBid {
- rv.Bids = append(rv.Bids, &adapters.TypedBid{
- Bid: &bid,
- BidType: bidType,
- })
- } else {
- errors = append(errors, &errortypes.BadServerResponse{
- Message: fmt.Sprintf("bid id='%s' could not find valid impid='%s'", bid.ID, bid.ImpID),
- })
- }
- }
- }
- return rv, errors
-}
-
-// Builder builds a new instance of the Valueimpression adapter for the given bidder with the given config.
-func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) {
- bidder := &ValueImpressionAdapter{
- endpoint: config.Endpoint,
- }
- return bidder, nil
-}
diff --git a/config/config.go b/config/config.go
index dd842be72b9..7c7f721ecbb 100644
--- a/config/config.go
+++ b/config/config.go
@@ -790,6 +790,7 @@ func SetupViper(v *viper.Viper, filename string) {
v.SetDefault("adapters.aja.endpoint", "https://ad.as.amanad.adtdp.com/v1/bid/4")
v.SetDefault("adapters.algorix.endpoint", "https://{{.Host}}.svr-algorix.com/rtb/sa?sid={{.SourceId}}&token={{.AccountID}}")
v.SetDefault("adapters.amx.endpoint", "http://pbs.amxrtb.com/auction/openrtb")
+ v.SetDefault("adapters.apacdex.endpoint", "http://useast.quantumdex.io/auction/pbs")
v.SetDefault("adapters.applogy.endpoint", "http://rtb.applogy.com/v1/prebid")
v.SetDefault("adapters.appnexus.endpoint", "http://ib.adnxs.com/openrtb2") // Docs: https://wiki.appnexus.com/display/supply/Incoming+Bid+Request+from+SSPs
v.SetDefault("adapters.appnexus.platform_id", "5")
@@ -868,6 +869,7 @@ func SetupViper(v *viper.Viper, filename string) {
v.SetDefault("adapters.pubmatic.endpoint", "https://hbopenbid.pubmatic.com/translator?source=prebid-server")
v.SetDefault("adapters.pubnative.endpoint", "http://dsp.pubnative.net/bid/v1/request")
v.SetDefault("adapters.pulsepoint.endpoint", "http://bid.contextweb.com/header/s/ortb/prebid-s2s")
+ v.SetDefault("adapters.quantumdex.endpoint", "http://useast.quantumdex.io/auction/pbs")
v.SetDefault("adapters.revcontent.disabled", true)
v.SetDefault("adapters.revcontent.endpoint", "https://trends.revcontent.com/rtb")
v.SetDefault("adapters.rhythmone.endpoint", "http://tag.1rx.io/rmp")
@@ -897,7 +899,7 @@ func SetupViper(v *viper.Viper, filename string) {
v.SetDefault("adapters.ucfunnel.endpoint", "https://pbs.aralego.com/prebid")
v.SetDefault("adapters.unicorn.endpoint", "https://ds.uncn.jp/pb/0/bid.json")
v.SetDefault("adapters.unruly.endpoint", "https://targeting.unrulymedia.com/unruly_prebid_server")
- v.SetDefault("adapters.valueimpression.endpoint", "https://rtb.valueimpression.com/endpoint")
+ v.SetDefault("adapters.valueimpression.endpoint", "http://useast.quantumdex.io/auction/pbs")
v.SetDefault("adapters.verizonmedia.disabled", true)
v.SetDefault("adapters.videobyte.endpoint", "https://x.videobyte.com/ortbhb")
v.SetDefault("adapters.viewdeos.endpoint", "http://ghb.sync.viewdeos.com/pbs/ortb")
diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go
index 59c892ab9e4..8075b7f1ff5 100755
--- a/exchange/adapter_builders.go
+++ b/exchange/adapter_builders.go
@@ -28,6 +28,7 @@ import (
"github.com/prebid/prebid-server/adapters/aja"
"github.com/prebid/prebid-server/adapters/algorix"
"github.com/prebid/prebid-server/adapters/amx"
+ "github.com/prebid/prebid-server/adapters/apacdex"
"github.com/prebid/prebid-server/adapters/applogy"
"github.com/prebid/prebid-server/adapters/appnexus"
"github.com/prebid/prebid-server/adapters/audienceNetwork"
@@ -123,7 +124,6 @@ import (
"github.com/prebid/prebid-server/adapters/ucfunnel"
"github.com/prebid/prebid-server/adapters/unicorn"
"github.com/prebid/prebid-server/adapters/unruly"
- "github.com/prebid/prebid-server/adapters/valueimpression"
"github.com/prebid/prebid-server/adapters/videobyte"
"github.com/prebid/prebid-server/adapters/visx"
"github.com/prebid/prebid-server/adapters/vrtcal"
@@ -168,6 +168,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
openrtb_ext.BidderAJA: aja.Builder,
openrtb_ext.BidderAlgorix: algorix.Builder,
openrtb_ext.BidderAMX: amx.Builder,
+ openrtb_ext.BidderApacdex: apacdex.Builder,
openrtb_ext.BidderApplogy: applogy.Builder,
openrtb_ext.BidderAppnexus: appnexus.Builder,
openrtb_ext.BidderAudienceNetwork: audienceNetwork.Builder,
@@ -241,6 +242,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
openrtb_ext.BidderPubmatic: pubmatic.Builder,
openrtb_ext.BidderPubnative: pubnative.Builder,
openrtb_ext.BidderPulsepoint: pulsepoint.Builder,
+ openrtb_ext.BidderQuantumdex: apacdex.Builder,
openrtb_ext.BidderRevcontent: revcontent.Builder,
openrtb_ext.BidderRhythmone: rhythmone.Builder,
openrtb_ext.BidderRichaudience: richaudience.Builder,
@@ -267,7 +269,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
openrtb_ext.BidderUcfunnel: ucfunnel.Builder,
openrtb_ext.BidderUnicorn: unicorn.Builder,
openrtb_ext.BidderUnruly: unruly.Builder,
- openrtb_ext.BidderValueImpression: valueimpression.Builder,
+ openrtb_ext.BidderValueImpression: apacdex.Builder,
openrtb_ext.BidderVerizonMedia: yahoossp.Builder,
openrtb_ext.BidderVideoByte: videobyte.Builder,
openrtb_ext.BidderViewdeos: adtelligent.Builder,
diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go
index d02a7a48320..941f1a561f0 100644
--- a/openrtb_ext/bidders.go
+++ b/openrtb_ext/bidders.go
@@ -103,6 +103,7 @@ const (
BidderAJA BidderName = "aja"
BidderAlgorix BidderName = "algorix"
BidderAMX BidderName = "amx"
+ BidderApacdex BidderName = "apacdex"
BidderApplogy BidderName = "applogy"
BidderAppnexus BidderName = "appnexus"
BidderAudienceNetwork BidderName = "audienceNetwork"
@@ -176,6 +177,7 @@ const (
BidderPubmatic BidderName = "pubmatic"
BidderPubnative BidderName = "pubnative"
BidderPulsepoint BidderName = "pulsepoint"
+ BidderQuantumdex BidderName = "quantumdex"
BidderRevcontent BidderName = "revcontent"
BidderRhythmone BidderName = "rhythmone"
BidderRichaudience BidderName = "richaudience"
@@ -247,6 +249,7 @@ func CoreBidderNames() []BidderName {
BidderAJA,
BidderAlgorix,
BidderAMX,
+ BidderApacdex,
BidderApplogy,
BidderAppnexus,
BidderAudienceNetwork,
@@ -320,6 +323,7 @@ func CoreBidderNames() []BidderName {
BidderPubmatic,
BidderPubnative,
BidderPulsepoint,
+ BidderQuantumdex,
BidderRevcontent,
BidderRhythmone,
BidderRichaudience,
diff --git a/openrtb_ext/imp_apacdex.go b/openrtb_ext/imp_apacdex.go
new file mode 100644
index 00000000000..dc8fb15b123
--- /dev/null
+++ b/openrtb_ext/imp_apacdex.go
@@ -0,0 +1,7 @@
+package openrtb_ext
+
+type ExtImpApacdex struct {
+ PlacementID string `json:"placementId"`
+ SiteID string `json:"siteId"`
+ FloorPrice float64 `json:"floorPrice"`
+}
diff --git a/openrtb_ext/imp_valueimpression.go b/openrtb_ext/imp_valueimpression.go
deleted file mode 100644
index 7c5c70ee0a7..00000000000
--- a/openrtb_ext/imp_valueimpression.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package openrtb_ext
-
-type ExtImpValueImpression struct {
- SiteId string `json:"siteId"`
-}
diff --git a/static/bidder-info/apacdex.yaml b/static/bidder-info/apacdex.yaml
new file mode 100644
index 00000000000..2e8cd08f621
--- /dev/null
+++ b/static/bidder-info/apacdex.yaml
@@ -0,0 +1,20 @@
+maintainer:
+ email: "support@apacdex.com"
+modifyingVastXmlAllowed: false
+capabilities:
+ app:
+ mediaTypes:
+ - banner
+ - video
+ site:
+ mediaTypes:
+ - banner
+ - video
+userSync:
+ default: iframe
+ iframe:
+ url: https://sync.quantumdex.io/usersync/pbs?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}
+ userMacro: "[UID]"
+ redirect:
+ url: "https://sync.quantumdex.io/getuid?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}"
+ userMacro: "[UID]"
diff --git a/static/bidder-info/quantumdex.yaml b/static/bidder-info/quantumdex.yaml
new file mode 100644
index 00000000000..2e8cd08f621
--- /dev/null
+++ b/static/bidder-info/quantumdex.yaml
@@ -0,0 +1,20 @@
+maintainer:
+ email: "support@apacdex.com"
+modifyingVastXmlAllowed: false
+capabilities:
+ app:
+ mediaTypes:
+ - banner
+ - video
+ site:
+ mediaTypes:
+ - banner
+ - video
+userSync:
+ default: iframe
+ iframe:
+ url: https://sync.quantumdex.io/usersync/pbs?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}
+ userMacro: "[UID]"
+ redirect:
+ url: "https://sync.quantumdex.io/getuid?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}"
+ userMacro: "[UID]"
diff --git a/static/bidder-info/valueimpression.yaml b/static/bidder-info/valueimpression.yaml
index 0782f897f2a..2e8cd08f621 100644
--- a/static/bidder-info/valueimpression.yaml
+++ b/static/bidder-info/valueimpression.yaml
@@ -1,5 +1,6 @@
maintainer:
- email: "info@valueimpression.com"
+ email: "support@apacdex.com"
+modifyingVastXmlAllowed: false
capabilities:
app:
mediaTypes:
@@ -10,6 +11,10 @@ capabilities:
- banner
- video
userSync:
+ default: iframe
+ iframe:
+ url: https://sync.quantumdex.io/usersync/pbs?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}
+ userMacro: "[UID]"
redirect:
- url: "https://rtb.valueimpression.com/usersync?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}"
- userMacro: "$UID"
+ url: "https://sync.quantumdex.io/getuid?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}"
+ userMacro: "[UID]"
diff --git a/static/bidder-params/apacdex.json b/static/bidder-params/apacdex.json
new file mode 100644
index 00000000000..0130fcee1c7
--- /dev/null
+++ b/static/bidder-params/apacdex.json
@@ -0,0 +1,32 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "title": "Apacdex Adapter Params",
+ "description": "A schema which validates params accepted by the Apacdex adapter",
+ "type": "object",
+ "properties": {
+ "placementId": {
+ "type": "string",
+ "description": "Placement ID provided by Apacdex"
+ },
+ "siteId": {
+ "type": "string",
+ "description": "Publisher site ID from Apacdex"
+ },
+ "floorPrice": {
+ "type": "number",
+ "description": "CPM bidfloor in USD"
+ }
+ },
+ "oneOf": [
+ {
+ "required": [
+ "placementId"
+ ]
+ },
+ {
+ "required": [
+ "siteId"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/static/bidder-params/quantumdex.json b/static/bidder-params/quantumdex.json
new file mode 100644
index 00000000000..3ef9abe34c6
--- /dev/null
+++ b/static/bidder-params/quantumdex.json
@@ -0,0 +1,32 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "title": "Quantumdex Adapter Params",
+ "description": "A schema which validates params accepted by the Quantumdex adapter",
+ "type": "object",
+ "properties": {
+ "placementId": {
+ "type": "string",
+ "description": "Placement ID provided by Quantumdex"
+ },
+ "siteId": {
+ "type": "string",
+ "description": "Publisher site ID from Quantumdex"
+ },
+ "floorPrice": {
+ "type": "number",
+ "description": "CPM bidfloor in USD"
+ }
+ },
+ "oneOf": [
+ {
+ "required": [
+ "placementId"
+ ]
+ },
+ {
+ "required": [
+ "siteId"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/static/bidder-params/valueimpression.json b/static/bidder-params/valueimpression.json
index 5b9c32c592e..793e940eb11 100644
--- a/static/bidder-params/valueimpression.json
+++ b/static/bidder-params/valueimpression.json
@@ -1,15 +1,32 @@
-
{
- "$schema": "http://json-schema.org/draft-04/schema#",
- "title": "ValueImpression Adapter Params",
- "description": "Schema to validate params accepted by the ValueImpression adapter",
-
- "type": "object",
- "properties": {
- "siteId": {
- "type": "string",
- "description": "Site ID"
- }
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "title": "Valueimpression Adapter Params",
+ "description": "A schema which validates params accepted by the Valueimpression adapter",
+ "type": "object",
+ "properties": {
+ "placementId": {
+ "type": "string",
+ "description": "Placement ID provided by Valueimpression"
},
- "required": ["siteId"]
- }
+ "siteId": {
+ "type": "string",
+ "description": "Publisher site ID from Valueimpression"
+ },
+ "floorPrice": {
+ "type": "number",
+ "description": "CPM bidfloor in USD"
+ }
+ },
+ "oneOf": [
+ {
+ "required": [
+ "placementId"
+ ]
+ },
+ {
+ "required": [
+ "siteId"
+ ]
+ }
+ ]
+}
\ No newline at end of file
From 6c33ed6bc9cf3a7405015b684d768015a503e3c1 Mon Sep 17 00:00:00 2001
From: Mikael Lundin
Date: Tue, 4 Jan 2022 19:16:11 +0100
Subject: [PATCH 04/14] Adnuntius: Read device information from ortb Request
(#2112)
---
adapters/adnuntius/adnuntius.go | 13 +-
.../supplemental/send-header-information.json | 122 ++++++++++++++++++
2 files changed, 133 insertions(+), 2 deletions(-)
create mode 100644 adapters/adnuntius/adnuntiustest/supplemental/send-header-information.json
diff --git a/adapters/adnuntius/adnuntius.go b/adapters/adnuntius/adnuntius.go
index f556081ae70..da66e4433ec 100644
--- a/adapters/adnuntius/adnuntius.go
+++ b/adapters/adnuntius/adnuntius.go
@@ -74,10 +74,19 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E
return a.generateRequests(*request)
}
-func setHeaders() http.Header {
+func setHeaders(ortbRequest openrtb2.BidRequest) http.Header {
+
headers := http.Header{}
headers.Add("Content-Type", "application/json;charset=utf-8")
headers.Add("Accept", "application/json")
+ if ortbRequest.Device != nil {
+ if ortbRequest.Device.IP != "" {
+ headers.Add("X-Forwarded-For", ortbRequest.Device.IP)
+ }
+ if ortbRequest.Device.UA != "" {
+ headers.Add("user-agent", ortbRequest.Device.UA)
+ }
+ }
return headers
}
@@ -113,7 +122,7 @@ func makeEndpointUrl(ortbRequest openrtb2.BidRequest, a *adapter) (string, []err
func (a *adapter) generateRequests(ortbRequest openrtb2.BidRequest) ([]*adapters.RequestData, []error) {
var requestData []*adapters.RequestData
networkAdunitMap := make(map[string][]adnAdunit)
- headers := setHeaders()
+ headers := setHeaders(ortbRequest)
endpoint, err := makeEndpointUrl(ortbRequest, a)
if err != nil {
diff --git a/adapters/adnuntius/adnuntiustest/supplemental/send-header-information.json b/adapters/adnuntius/adnuntiustest/supplemental/send-header-information.json
new file mode 100644
index 00000000000..96ddff858ac
--- /dev/null
+++ b/adapters/adnuntius/adnuntiustest/supplemental/send-header-information.json
@@ -0,0 +1,122 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "user": {
+ "id": "1kjh3429kjh295jkl",
+ "ext": {
+ "consent": "CONSENT_STRING"
+ }
+ },
+ "device": {
+ "ip": "158.174.81.143",
+ "ua": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Mobile Safari/537.36"
+ },
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ },
+ {
+ "w": 300,
+ "h": 600
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "auId": "123"
+ }
+ }
+ }
+ ]
+ },
+
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "headers": {
+ "Content-Type": [
+ "application/json;charset=utf-8"
+ ],
+ "Accept": [
+ "application/json"
+ ],
+ "X-Forwarded-For": [
+ "158.174.81.143"
+ ],
+ "User-Agent": [
+ "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Mobile Safari/537.36"
+ ]
+ },
+ "uri": "http://whatever.url?format=json&tzo=0",
+ "body": {
+ "adUnits": [
+ {
+ "auId": "123",
+ "targetId": "123-test-imp-id"
+ }
+ ],
+ "metaData": {
+ "usi": "1kjh3429kjh295jkl"
+ },
+ "context": "unknown"
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "adUnits": [
+ {
+ "auId": "0000000000000123",
+ "targetId": "123-test-imp-id",
+ "html": "",
+ "responseId": "adn-rsp-900646517",
+ "ads": [
+ {
+ "destinationUrls": {
+ "url": "http://www.google.com"
+ },
+ "bid": {
+ "amount": 20.0,
+ "currency": "NOK"
+ },
+ "adId": "adn-id-1559784094",
+ "creativeWidth": "980",
+ "creativeHeight": "240",
+ "creativeId": "jn9hpzvlsf8cpdmm",
+ "lineItemId": "q7y9qm5b0xt9htrv"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "bids": [
+ {
+ "bid": {
+ "id": "adn-id-1559784094",
+ "impid": "test-imp-id",
+ "price": 20000,
+ "adm": "",
+ "adid": "adn-id-1559784094",
+ "adomain": ["google.com"],
+ "cid": "q7y9qm5b0xt9htrv",
+ "crid": "jn9hpzvlsf8cpdmm",
+ "w": 980,
+ "h": 240
+ },
+ "type": "banner"
+ }
+ ],
+ "currency": "NOK"
+ }
+ ]
+}
From 9524fdb6a53aec02c05e184b07f449d477c0f686 Mon Sep 17 00:00:00 2001
From: "Takaaki.Kojima"
Date: Fri, 7 Jan 2022 02:29:14 +0900
Subject: [PATCH 05/14] Adgeneration: Update request to include device and app
related info in headers and query params (#2109)
---
adapters/adgeneration/adgeneration.go | 32 +++-
adapters/adgeneration/adgeneration_test.go | 2 +-
.../exemplary/single-banner-android.json | 166 ++++++++++++++++++
.../exemplary/single-banner-ios.json | 166 ++++++++++++++++++
.../exemplary/single-banner.json | 11 +-
.../supplemental/204-bid-response.json | 2 +-
.../supplemental/400-bid-response.json | 2 +-
.../supplemental/no-bid-response.json | 2 +-
8 files changed, 373 insertions(+), 10 deletions(-)
create mode 100644 adapters/adgeneration/adgenerationtest/exemplary/single-banner-android.json
create mode 100644 adapters/adgeneration/adgenerationtest/exemplary/single-banner-ios.json
diff --git a/adapters/adgeneration/adgeneration.go b/adapters/adgeneration/adgeneration.go
index 110ec5ce98a..55fafde1d85 100644
--- a/adapters/adgeneration/adgeneration.go
+++ b/adapters/adgeneration/adgeneration.go
@@ -55,8 +55,13 @@ func (adg *AdgenerationAdapter) MakeRequests(request *openrtb2.BidRequest, reqIn
headers := http.Header{}
headers.Add("Content-Type", "application/json;charset=utf-8")
headers.Add("Accept", "application/json")
- if request.Device != nil && len(request.Device.UA) > 0 {
- headers.Add("User-Agent", request.Device.UA)
+ if request.Device != nil {
+ if len(request.Device.UA) > 0 {
+ headers.Add("User-Agent", request.Device.UA)
+ }
+ if len(request.Device.IP) > 0 {
+ headers.Add("X-Forwarded-For", request.Device.IP)
+ }
}
bidRequestArray := make([]*adapters.RequestData, 0, numRequests)
@@ -102,7 +107,6 @@ func (adg *AdgenerationAdapter) getRawQuery(id string, request *openrtb2.BidRequ
v := url.Values{}
v.Set("posall", "SSPLOC")
v.Set("id", id)
- v.Set("sdktype", "0")
v.Set("hb", "true")
v.Set("t", "json3")
v.Set("currency", adg.getCurrency(request))
@@ -112,12 +116,32 @@ func (adg *AdgenerationAdapter) getRawQuery(id string, request *openrtb2.BidRequ
if adSize != "" {
v.Set("sizes", adSize)
}
+ if request.Device != nil && request.Device.OS == "android" {
+ v.Set("sdktype", "1")
+ } else if request.Device != nil && request.Device.OS == "ios" {
+ v.Set("sdktype", "2")
+ } else {
+ v.Set("sdktype", "0")
+ }
if request.Site != nil && request.Site.Page != "" {
v.Set("tp", request.Site.Page)
}
if request.Source != nil && request.Source.TID != "" {
v.Set("transactionid", request.Source.TID)
}
+ if request.App != nil && request.App.Bundle != "" {
+ v.Set("appbundle", request.App.Bundle)
+ }
+ if request.App != nil && request.App.Name != "" {
+ v.Set("appname", request.App.Name)
+ }
+ if request.Device != nil && request.Device.OS == "ios" && request.Device.IFA != "" {
+ v.Set("idfa", request.Device.IFA)
+ }
+ if request.Device != nil && request.Device.OS == "android" && request.Device.IFA != "" {
+ v.Set("advertising_id", request.Device.IFA)
+ }
+
return &v
}
@@ -263,7 +287,7 @@ func removeWrapper(ad string) string {
func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) {
bidder := &AdgenerationAdapter{
config.Endpoint,
- "1.0.2",
+ "1.0.3",
"JPY",
}
return bidder, nil
diff --git a/adapters/adgeneration/adgeneration_test.go b/adapters/adgeneration/adgeneration_test.go
index d5d93ac4e0b..c186f19f4c5 100644
--- a/adapters/adgeneration/adgeneration_test.go
+++ b/adapters/adgeneration/adgeneration_test.go
@@ -23,7 +23,7 @@ func TestJsonSamples(t *testing.T) {
adapterstest.RunJSONBidderTest(t, "adgenerationtest", bidder)
}
-func TestgetRequestUri(t *testing.T) {
+func TestGetRequestUri(t *testing.T) {
bidder, buildErr := Builder(openrtb_ext.BidderAdgeneration, config.Adapter{
Endpoint: "https://d.socdm.com/adsv/v1"})
diff --git a/adapters/adgeneration/adgenerationtest/exemplary/single-banner-android.json b/adapters/adgeneration/adgenerationtest/exemplary/single-banner-android.json
new file mode 100644
index 00000000000..487d44692e0
--- /dev/null
+++ b/adapters/adgeneration/adgenerationtest/exemplary/single-banner-android.json
@@ -0,0 +1,166 @@
+{
+ "mockBidRequest":{
+ "id": "some-request-id",
+ "site": {
+ "page": "http://example.com/test.html"
+ },
+ "device": {
+ "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36",
+ "ip": "0.0.0.0",
+ "os": "android",
+ "ifa": "advertising_id"
+ },
+ "app": {
+ "name": "adgneration"
+ },
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "id": "58278"
+ }
+ }
+ }
+ ],
+ "tmax": 500
+ },
+ "httpCalls": [
+ {
+ "internalRequest": {
+ "id": "some-request-id",
+ "site": {
+ "page": "http://example.com/test.html"
+ },
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "id": "58278"
+ }
+ }
+ }
+ ],
+ "tmax": 500
+ },
+ "expectedRequest":{
+ "uri": "https://d.socdm.com/adsv/v1?adapterver=1.0.3&advertising_id=advertising_id&appname=adgneration¤cy=JPY&hb=true&id=58278&posall=SSPLOC&sdkname=prebidserver&sdktype=1&sizes=300x250&t=json3&tp=http%3A%2F%2Fexample.com%2Ftest.html",
+ "headers": {
+ "Accept": [
+ "application/json"
+ ],
+ "Content-Type": [
+ "application/json;charset=utf-8"
+ ],
+ "User-Agent": [
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36"
+ ],
+ "X-Forwarded-For": [
+ "0.0.0.0"
+ ]
+ }
+ },
+ "mockResponse":{
+ "status": 200,
+ "body": {
+ "ad": "\n \n \n