diff --git a/adapters/adot/adot.go b/adapters/adot/adot.go index 5f99cf84518..55aa0b954a8 100644 --- a/adapters/adot/adot.go +++ b/adapters/adot/adot.go @@ -37,6 +37,7 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters // MakeRequests makes the HTTP requests which should be made to fetch bids. func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { var reqJSON []byte + var publisherPath string var err error if reqJSON, err = json.Marshal(request); err != nil { @@ -46,9 +47,17 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E headers := http.Header{} headers.Add("Content-Type", "application/json;charset=utf-8") + if adotExt := getImpAdotExt(&request.Imp[0]); adotExt != nil { + publisherPath = adotExt.PublisherPath + } else { + publisherPath = "" + } + + endpoint := strings.Replace(a.endpoint, "{PUBLISHER_PATH}", publisherPath, -1) + return []*adapters.RequestData{{ Method: "POST", - Uri: a.endpoint, + Uri: endpoint, Body: reqJSON, Headers: headers, }}, nil @@ -129,3 +138,18 @@ func resolveMacros(bid *openrtb2.Bid) { bid.NURL = strings.Replace(bid.NURL, "${AUCTION_PRICE}", price, -1) bid.AdM = strings.Replace(bid.AdM, "${AUCTION_PRICE}", price, -1) } + +// getImpAdotExt parses and return first imp ext or nil +func getImpAdotExt(imp *openrtb2.Imp) *openrtb_ext.ExtImpAdot { + var extImpAdot openrtb_ext.ExtImpAdot + var extBidder adapters.ExtImpBidder + err := json.Unmarshal(imp.Ext, &extBidder) + if err != nil { + return nil + } + err = json.Unmarshal(extBidder.Bidder, &extImpAdot) + if err != nil { + return nil + } + return &extImpAdot +} diff --git a/adapters/adot/adot_test.go b/adapters/adot/adot_test.go index 3e0944b6e03..99bf9bd968c 100644 --- a/adapters/adot/adot_test.go +++ b/adapters/adot/adot_test.go @@ -12,7 +12,7 @@ import ( "github.com/stretchr/testify/assert" ) -const testsBidderEndpoint = "https://dsp.adotmob.com/headerbidding/bidrequest" +const testsBidderEndpoint = "https://dsp.adotmob.com/headerbidding{PUBLISHER_PATH}/bidrequest" func TestJsonSamples(t *testing.T) { bidder, buildErr := Builder(openrtb_ext.BidderAdot, config.Adapter{ @@ -38,7 +38,7 @@ func TestMediaTypeError(t *testing.T) { func TestBidResponseNoContent(t *testing.T) { bidder, buildErr := Builder(openrtb_ext.BidderAdot, config.Adapter{ - Endpoint: "https://dsp.adotmob.com/headerbidding/bidrequest"}) + Endpoint: "https://dsp.adotmob.com/headerbidding{PUBLISHER_PATH}/bidrequest"}) if buildErr != nil { t.Fatalf("Builder returned unexpected error %v", buildErr) @@ -79,3 +79,18 @@ func TestResolveMacros(t *testing.T) { assert.Equal(t, "adm:imp_123.45 amd:creativeview_123.45", bid.AdM) assert.Equal(t, "nurl_123.45", bid.NURL) } + +func TestGetImpAdotExt(t *testing.T) { + ext := &openrtb2.Imp{Ext: json.RawMessage(`{"bidder":{"publisherPath": "/hubvisor"}}`)} + adotExt := getImpAdotExt(ext) + assert.Equal(t, adotExt.PublisherPath, "/hubvisor") + + emptyBidderExt := &openrtb2.Imp{Ext: json.RawMessage(`{"bidder":{}}`)} + emptyAdotBidderExt := getImpAdotExt(emptyBidderExt) + assert.NotNil(t, emptyAdotBidderExt) + assert.Equal(t, emptyAdotBidderExt.PublisherPath, "") + + emptyExt := &openrtb2.Imp{Ext: json.RawMessage(`{}`)} + emptyAdotExt := getImpAdotExt(emptyExt) + assert.Nil(t, emptyAdotExt) +} diff --git a/adapters/adot/adottest/exemplary/simple-native.json b/adapters/adot/adottest/exemplary/simple-native.json index ad7bccff12a..9ad26b260ac 100644 --- a/adapters/adot/adottest/exemplary/simple-native.json +++ b/adapters/adot/adottest/exemplary/simple-native.json @@ -41,20 +41,22 @@ "seatbid": [ { "seat": "adot", - "bid": [{ - "id": "test-request-native-id", - "impid": "test-imp-native-id", - "price": 1.16346, - "adm": "some-test-ad imp_${AUCTION_PRICE} creativeview_${AUCTION_PRICE}", - "nurl": "nurl.link/win?p=${AUCTION_PRICE}", - "w": 300, - "h": 250, - "ext": { - "adot": { - "media_type": "native" + "bid": [ + { + "id": "test-request-native-id", + "impid": "test-imp-native-id", + "price": 1.16346, + "adm": "some-test-ad imp_${AUCTION_PRICE} creativeview_${AUCTION_PRICE}", + "nurl": "nurl.link/win?p=${AUCTION_PRICE}", + "w": 300, + "h": 250, + "ext": { + "adot": { + "media_type": "native" + } } } - }] + ] } ], "cur": "USD" @@ -87,4 +89,3 @@ } ] } - diff --git a/adapters/adot/adottest/exemplary/simple-video.json b/adapters/adot/adottest/exemplary/simple-video.json index 4c85031863f..f4620a9e2cf 100644 --- a/adapters/adot/adottest/exemplary/simple-video.json +++ b/adapters/adot/adottest/exemplary/simple-video.json @@ -9,20 +9,10 @@ "h": 250, "maxduration": 60, "minduration": 1, - "api": [ - 1, - 2, - 5, - 6, - 7 - ], - "mimes": [ - "video\/mp4" - ], + "api": [1, 2, 5, 6, 7], + "mimes": ["video/mp4"], "placement": 4, - "protocols": [ - 2 - ] + "protocols": [2] }, "ext": { "adot": {} @@ -44,20 +34,10 @@ "h": 250, "maxduration": 60, "minduration": 1, - "api": [ - 1, - 2, - 5, - 6, - 7 - ], - "mimes": [ - "video\/mp4" - ], + "api": [1, 2, 5, 6, 7], + "mimes": ["video/mp4"], "placement": 4, - "protocols": [ - 2 - ] + "protocols": [2] }, "ext": { "adot": {} @@ -73,20 +53,22 @@ "seatbid": [ { "seat": "adot", - "bid": [{ - "id": "test-request-video-id", - "impid": "test-imp-video-id", - "price": 1.16346, - "adm": "some-test-ad imp_${AUCTION_PRICE} creativeview_${AUCTION_PRICE}", - "nurl": "nurl.link/win?p=${AUCTION_PRICE}", - "w": 300, - "h": 250, - "ext": { - "adot": { - "media_type": "video" + "bid": [ + { + "id": "test-request-video-id", + "impid": "test-imp-video-id", + "price": 1.16346, + "adm": "some-test-ad imp_${AUCTION_PRICE} creativeview_${AUCTION_PRICE}", + "nurl": "nurl.link/win?p=${AUCTION_PRICE}", + "w": 300, + "h": 250, + "ext": { + "adot": { + "media_type": "video" + } } } - }] + ] } ], "cur": "USD" @@ -119,4 +101,3 @@ } ] } - diff --git a/adapters/adot/adottest/supplemental/ext-bidder-empty.json b/adapters/adot/adottest/supplemental/ext-bidder-empty.json new file mode 100644 index 00000000000..b3fc956f3da --- /dev/null +++ b/adapters/adot/adottest/supplemental/ext-bidder-empty.json @@ -0,0 +1,107 @@ +{ + "mockBidRequest": { + "id": "test-request-publishPath-id", + "imp": [ + { + "id": "test-imp-publishPath-id", + "banner": { + "format": [ + { + "w": 320, + "h": 250 + } + ], + "w": 320, + "h": 250 + }, + "ext": { + "bidder": {}, + "adot": {} + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://dsp.adotmob.com/headerbidding/bidrequest", + "body": { + "id": "test-request-publishPath-id", + "imp": [ + { + "id": "test-imp-publishPath-id", + "banner": { + "format": [ + { + "w": 320, + "h": 250 + } + ], + "w": 320, + "h": 250 + }, + "ext": { + "bidder": { + }, + "adot": {} + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-publishPath-id", + "seatbid": [ + { + "seat": "adot", + "bid": [ + { + "id": "test-request-publishPath-id", + "impid": "test-imp-publishPath-id", + "price": 1.16346, + "adm": "some-test-ad imp_${AUCTION_PRICE} creativeview_${AUCTION_PRICE}", + "nurl": "nurl.link/win?p=${AUCTION_PRICE}", + "w": 320, + "h": 50, + "ext": { + "adot": { + "media_type": "banner" + } + } + } + ] + } + ], + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-request-publishPath-id", + "impid": "test-imp-publishPath-id", + "price": 1.16346, + "adm": "some-test-ad imp_1.16346 creativeview_1.16346", + "nurl": "nurl.link/win?p=1.16346", + "w": 320, + "h": 50, + "ext": { + "adot": { + "media_type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/adot/adottest/supplemental/ext-bidder-publisher-path.json b/adapters/adot/adottest/supplemental/ext-bidder-publisher-path.json new file mode 100644 index 00000000000..bf69d12a8d9 --- /dev/null +++ b/adapters/adot/adottest/supplemental/ext-bidder-publisher-path.json @@ -0,0 +1,110 @@ +{ + "mockBidRequest": { + "id": "test-request-publishPath-id", + "imp": [ + { + "id": "test-imp-publishPath-id", + "banner": { + "format": [ + { + "w": 320, + "h": 250 + } + ], + "w": 320, + "h": 250 + }, + "ext": { + "bidder": { + "publisherPath": "/hubvisor" + }, + "adot": {} + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://dsp.adotmob.com/headerbidding/hubvisor/bidrequest", + "body": { + "id": "test-request-publishPath-id", + "imp": [ + { + "id": "test-imp-publishPath-id", + "banner": { + "format": [ + { + "w": 320, + "h": 250 + } + ], + "w": 320, + "h": 250 + }, + "ext": { + "bidder": { + "publisherPath": "/hubvisor" + }, + "adot": {} + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-publishPath-id", + "seatbid": [ + { + "seat": "adot", + "bid": [ + { + "id": "test-request-publishPath-id", + "impid": "test-imp-publishPath-id", + "price": 1.16346, + "adm": "some-test-ad imp_${AUCTION_PRICE} creativeview_${AUCTION_PRICE}", + "nurl": "nurl.link/win?p=${AUCTION_PRICE}", + "w": 320, + "h": 50, + "ext": { + "adot": { + "media_type": "banner" + } + } + } + ] + } + ], + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-request-publishPath-id", + "impid": "test-imp-publishPath-id", + "price": 1.16346, + "adm": "some-test-ad imp_1.16346 creativeview_1.16346", + "nurl": "nurl.link/win?p=1.16346", + "w": 320, + "h": 50, + "ext": { + "adot": { + "media_type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/adot/adottest/supplemental/simple-audio.json b/adapters/adot/adottest/supplemental/simple-audio.json index 9be53c4cee9..cd19d1402c1 100644 --- a/adapters/adot/adottest/supplemental/simple-audio.json +++ b/adapters/adot/adottest/supplemental/simple-audio.json @@ -43,17 +43,19 @@ "seatbid": [ { "seat": "adot", - "bid": [{ - "id": "test-request-audio-id", - "impid": "test-imp-audio-id", - "price": 1.16346, - "adm": "some-audio-ad", - "ext": { - "adot": { - "media_type": "audio" + "bid": [ + { + "id": "test-request-audio-id", + "impid": "test-imp-audio-id", + "price": 1.16346, + "adm": "some-audio-ad", + "ext": { + "adot": { + "media_type": "audio" + } } } - }] + ] } ], "cur": "USD" diff --git a/adapters/adot/adottest/supplemental/status_500.json b/adapters/adot/adottest/supplemental/status_500.json index 879bb8c5581..f749ecc8a69 100644 --- a/adapters/adot/adottest/supplemental/status_500.json +++ b/adapters/adot/adottest/supplemental/status_500.json @@ -59,4 +59,3 @@ } ] } - diff --git a/adapters/adot/adottest/supplemental/unmarshal_error.json b/adapters/adot/adottest/supplemental/unmarshal_error.json index 3094fa865e4..557fb16cb43 100644 --- a/adapters/adot/adottest/supplemental/unmarshal_error.json +++ b/adapters/adot/adottest/supplemental/unmarshal_error.json @@ -49,8 +49,9 @@ "mockResponse": { "status": 200, "body": "fail for unmarshal" - } - }], + } + } + ], "expectedMakeBidsErrors": [ { @@ -59,4 +60,3 @@ } ] } - diff --git a/adapters/adot/params_test.go b/adapters/adot/params_test.go index 2f7b4b9af4e..bc458641694 100644 --- a/adapters/adot/params_test.go +++ b/adapters/adot/params_test.go @@ -2,8 +2,9 @@ package adot import ( "encoding/json" - "github.com/prebid/prebid-server/openrtb_ext" "testing" + + "github.com/prebid/prebid-server/openrtb_ext" ) // This file actually intends to test static/bidder-params/adot.json @@ -42,12 +43,16 @@ var validParams = []string{ `{"placementId": "test-114"}`, `{"placementId": "test-113", "parallax": true}`, `{"placementId": "test-113", "parallax": false}`, + `{"placementId": "test-113", "parallax": false, "publisherPath": "/hubvisor"}`, + `{"placementId": "test-113", "parallax": false, "publisherPath": ""}`, } var invalidParams = []string{ `{"parallax": 1}`, `{"placementId": 135123}`, + `{"publisherPath": 111}`, `{"placementId": 113, "parallax": 1}`, `{"placementId": 142, "parallax": true}`, `{"placementId": "test-114", "parallax": 1}`, + `{"placementId": "test-114", "parallax": true, "publisherPath": 111}`, } diff --git a/config/config.go b/config/config.go index 2cf8f1cd7af..8277ec1f785 100644 --- a/config/config.go +++ b/config/config.go @@ -822,7 +822,7 @@ func SetupViper(v *viper.Viper, filename string) { v.SetDefault("adapters.adocean.endpoint", "https://{{.Host}}") v.SetDefault("adapters.adnuntius.endpoint", "https://ads.adnuntius.delivery/i") v.SetDefault("adapters.adoppler.endpoint", "http://{{.AccountID}}.trustedmarketplace.io/ads/processHeaderBid/{{.AdUnit}}") - v.SetDefault("adapters.adot.endpoint", "https://dsp.adotmob.com/headerbidding/bidrequest") + v.SetDefault("adapters.adot.endpoint", "https://dsp.adotmob.com/headerbidding{PUBLISHER_PATH}/bidrequest") v.SetDefault("adapters.adpone.endpoint", "http://rtb.adpone.com/bid-request?src=prebid_server") v.SetDefault("adapters.adprime.endpoint", "http://delta.adprime.com/pserver") v.SetDefault("adapters.adtarget.endpoint", "http://ghb.console.adtarget.com.tr/pbs/ortb") diff --git a/openrtb_ext/imp_adot.go b/openrtb_ext/imp_adot.go index 5d741589896..e959c7c3f61 100644 --- a/openrtb_ext/imp_adot.go +++ b/openrtb_ext/imp_adot.go @@ -1,6 +1,7 @@ package openrtb_ext type ExtImpAdot struct { - Parallax bool `json:"parallax,omitempty"` - PlacementId string `json:"placementId,omitempty"` + Parallax bool `json:"parallax,omitempty"` + PlacementId string `json:"placementId,omitempty"` + PublisherPath string `json:"publisherPath,omitempty"` } diff --git a/static/bidder-params/adot.json b/static/bidder-params/adot.json index fa2b85333e2..e82b17be8d4 100644 --- a/static/bidder-params/adot.json +++ b/static/bidder-params/adot.json @@ -1,17 +1,21 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "The Adot Adapter Params", - "description": "A schema which validates params accepted by Adot adapter", - "type": "object", - "properties": { - "placementId": { - "type": "string", - "description": "An ID which identifies this placement of the impression" - }, - "parallax": { - "type": "boolean", - "description": "It determines if the wanted advertising format is a parallax." - } + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "The Adot Adapter Params", + "description": "A schema which validates params accepted by Adot adapter", + "type": "object", + "properties": { + "placementId": { + "type": "string", + "description": "An ID which identifies this placement of the impression" }, - "required": [] -} \ No newline at end of file + "parallax": { + "type": "boolean", + "description": "It determines if the wanted advertising format is a parallax." + }, + "publisherPath": { + "type": "string", + "description": "An optional path used in the bid endpoint" + } + }, + "required": [] +}