From d31c0721c65824a3e61a0b7c9b6f3ceed98c98cd Mon Sep 17 00:00:00 2001 From: Aleksei Lin Date: Sat, 4 Jan 2020 00:36:38 +0300 Subject: [PATCH] Add Applogy adapter (#1151) --- adapters/applogy/applogy.go | 160 +++++++++++++++ adapters/applogy/applogy_test.go | 11 ++ .../applogytest/exemplary/simple-banner.json | 170 ++++++++++++++++ .../applogytest/exemplary/simple-native.json | 164 ++++++++++++++++ .../applogytest/exemplary/simple-video.json | 182 ++++++++++++++++++ .../applogytest/supplemental/all-failed.json | 16 ++ .../supplemental/invalid-params.json | 133 +++++++++++++ .../applogytest/supplemental/status-204.json | 41 ++++ .../applogytest/supplemental/status-400.json | 45 +++++ .../applogytest/supplemental/status-502.json | 45 +++++ config/config.go | 1 + exchange/adapter_map.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_applogy.go | 5 + static/bidder-info/applogy.yaml | 13 ++ static/bidder-params/applogy.json | 13 ++ usersync/usersyncers/syncer_test.go | 1 + 17 files changed, 1004 insertions(+) create mode 100644 adapters/applogy/applogy.go create mode 100644 adapters/applogy/applogy_test.go create mode 100644 adapters/applogy/applogytest/exemplary/simple-banner.json create mode 100644 adapters/applogy/applogytest/exemplary/simple-native.json create mode 100644 adapters/applogy/applogytest/exemplary/simple-video.json create mode 100644 adapters/applogy/applogytest/supplemental/all-failed.json create mode 100644 adapters/applogy/applogytest/supplemental/invalid-params.json create mode 100644 adapters/applogy/applogytest/supplemental/status-204.json create mode 100644 adapters/applogy/applogytest/supplemental/status-400.json create mode 100644 adapters/applogy/applogytest/supplemental/status-502.json create mode 100644 openrtb_ext/imp_applogy.go create mode 100644 static/bidder-info/applogy.yaml create mode 100644 static/bidder-params/applogy.json diff --git a/adapters/applogy/applogy.go b/adapters/applogy/applogy.go new file mode 100644 index 00000000000..a1215e24940 --- /dev/null +++ b/adapters/applogy/applogy.go @@ -0,0 +1,160 @@ +package applogy + +import ( + "encoding/json" + "errors" + "net/http" + "strconv" + + "github.com/mxmCherry/openrtb" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/openrtb_ext" +) + +type ApplogyAdapter struct { + endpoint string +} + +func (a *ApplogyAdapter) MakeRequests(request *openrtb.BidRequest, _ *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + impressions := request.Imp + result := make([]*adapters.RequestData, 0, len(impressions)) + errs := make([]error, 0, len(impressions)) + + for i, impression := range impressions { + if impression.Banner == nil && impression.Video == nil && impression.Native == nil { + errs = append(errs, &errortypes.BadInput{ + Message: "Applogy only supports banner, video or native ads", + }) + continue + } + if impression.Banner != nil { + banner := impression.Banner + if banner.W == nil || banner.H == nil || *banner.W == 0 || *banner.H == 0 { + if len(banner.Format) == 0 { + errs = append(errs, &errortypes.BadInput{ + Message: "banner size information missing", + }) + continue + } + format := banner.Format[0] + banner.W = &format.W + banner.H = &format.H + } + } + if len(impression.Ext) == 0 { + errs = append(errs, errors.New("impression extensions required")) + continue + } + var bidderExt adapters.ExtImpBidder + err := json.Unmarshal(impression.Ext, &bidderExt) + if err != nil { + errs = append(errs, err) + continue + } + if len(bidderExt.Bidder) == 0 { + errs = append(errs, errors.New("bidder required")) + continue + } + var impressionExt openrtb_ext.ExtImpApplogy + err = json.Unmarshal(bidderExt.Bidder, &impressionExt) + if err != nil { + errs = append(errs, err) + continue + } + if impressionExt.Token == "" { + errs = append(errs, errors.New("Applogy token required")) + continue + } + request.Imp = impressions[i : i+1] + body, err := json.Marshal(request) + if err != nil { + errs = append(errs, err) + continue + } + result = append(result, &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint + "/" + impressionExt.Token, + Body: body, + Headers: headers, + }) + } + + request.Imp = impressions + + if len(result) == 0 { + return nil, errs + } + return result, errs +} + +func (a *ApplogyAdapter) MakeBids(request *openrtb.BidRequest, _ *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + var errs []error + + switch responseData.StatusCode { + case http.StatusNoContent: + return nil, nil + case http.StatusBadRequest: + return nil, []error{&errortypes.BadInput{ + Message: "unexpected status code: " + strconv.Itoa(responseData.StatusCode), + }} + case http.StatusOK: + break + default: + return nil, []error{&errortypes.BadServerResponse{ + Message: "unexpected status code: " + strconv.Itoa(responseData.StatusCode), + }} + } + + var bidResponse openrtb.BidResponse + err := json.Unmarshal(responseData.Body, &bidResponse) + if err != nil { + return nil, []error{&errortypes.BadServerResponse{ + Message: err.Error(), + }} + } + + response := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + + for _, seatBid := range bidResponse.SeatBid { + for _, bid := range seatBid.Bid { + bid := bid // pin https://github.com/kyoh86/scopelint#whats-this + var bidType openrtb_ext.BidType + for _, impression := range request.Imp { + if impression.ID != bid.ImpID { + continue + } + switch { + case impression.Banner != nil: + bidType = openrtb_ext.BidTypeBanner + case impression.Video != nil: + bidType = openrtb_ext.BidTypeVideo + case impression.Native != nil: + bidType = openrtb_ext.BidTypeNative + } + break + } + if bidType == "" { + errs = append(errs, &errortypes.BadServerResponse{ + Message: "ignoring bid id=" + bid.ID + ", request doesn't contain any valid impression with id=" + bid.ImpID, + }) + continue + } + response.Bids = append(response.Bids, &adapters.TypedBid{ + Bid: &bid, + BidType: bidType, + }) + } + } + + return response, errs +} + +func NewApplogyBidder(endpoint string) *ApplogyAdapter { + return &ApplogyAdapter{ + endpoint: endpoint, + } +} diff --git a/adapters/applogy/applogy_test.go b/adapters/applogy/applogy_test.go new file mode 100644 index 00000000000..8883db5786a --- /dev/null +++ b/adapters/applogy/applogy_test.go @@ -0,0 +1,11 @@ +package applogy + +import ( + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" +) + +func TestJsonSamples(t *testing.T) { + adapterstest.RunJSONBidderTest(t, "applogytest", NewApplogyBidder("http://example.com/prebid")) +} diff --git a/adapters/applogy/applogytest/exemplary/simple-banner.json b/adapters/applogy/applogytest/exemplary/simple-banner.json new file mode 100644 index 00000000000..a3926dea623 --- /dev/null +++ b/adapters/applogy/applogytest/exemplary/simple-banner.json @@ -0,0 +1,170 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-1", + "banner": { + "format": [{ + "h": 250, + "w": 300 + }] + }, + "ext": { + "bidder": { + "token": "test-token-1" + } + } + }, { + "id": "test-impression-id-2", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "token": "test-token-1" + } + } + }, { + "id": "test-impression-id-3", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "token": "test-token-2" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://example.com/prebid/test-token-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-1", + "banner": { + "format": [{ + "h": 250, + "w": 300 + }], + "h": 250, + "w": 300 + }, + "ext": { + "bidder": { + "token": "test-token-1" + } + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id-1", + "impid": "test-impression-id-1", + "price": 1 + }] + }] + } + } + }, { + "expectedRequest": { + "uri": "http://example.com/prebid/test-token-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-2", + "banner": { + "h": 250, + "w": 300 + }, + "ext": { + "bidder": { + "token": "test-token-1" + } + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id-2", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id-2", + "impid": "test-impression-id-2", + "price": 2 + }] + }] + } + } + }, { + "expectedRequest": { + "uri": "http://example.com/prebid/test-token-2", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-3", + "banner": { + "h": 250, + "w": 300 + }, + "ext": { + "bidder": { + "token": "test-token-2" + } + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id-3", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id-3", + "impid": "test-impression-id-3", + "price": 3 + }] + }] + } + } + }], + "expectedBidResponses": [{ + "bids": [{ + "bid": { + "id": "test-bid-id-1", + "impid": "test-impression-id-1", + "price": 1 + }, + "type": "banner" + }] + }, { + "bids": [{ + "bid": { + "id": "test-bid-id-2", + "impid": "test-impression-id-2", + "price": 2 + }, + "type": "banner" + }] + }, { + "bids": [{ + "bid": { + "id": "test-bid-id-3", + "impid": "test-impression-id-3", + "price": 3 + }, + "type": "banner" + }] + }] +} diff --git a/adapters/applogy/applogytest/exemplary/simple-native.json b/adapters/applogy/applogytest/exemplary/simple-native.json new file mode 100644 index 00000000000..84565ec5575 --- /dev/null +++ b/adapters/applogy/applogytest/exemplary/simple-native.json @@ -0,0 +1,164 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-1", + "native": { + "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "token": "test-token-1" + } + } + }, { + "id": "test-impression-id-2", + "native": { + "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "token": "test-token-1" + } + } + }, { + "id": "test-impression-id-3", + "native": { + "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "token": "test-token-2" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://example.com/prebid/test-token-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-1", + "native": { + "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "token": "test-token-1" + } + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id-1", + "impid": "test-impression-id-1", + "price": 1 + }] + }] + } + } + }, { + "expectedRequest": { + "uri": "http://example.com/prebid/test-token-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-2", + "native": { + "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "token": "test-token-1" + } + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id-2", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id-2", + "impid": "test-impression-id-2", + "price": 2 + }] + }] + } + } + }, { + "expectedRequest": { + "uri": "http://example.com/prebid/test-token-2", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-3", + "native": { + "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "token": "test-token-2" + } + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id-3", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id-3", + "impid": "test-impression-id-3", + "price": 3 + }] + }] + } + } + }], + "expectedBidResponses": [{ + "bids": [{ + "bid": { + "id": "test-bid-id-1", + "impid": "test-impression-id-1", + "price": 1 + }, + "type": "native" + }] + }, { + "bids": [{ + "bid": { + "id": "test-bid-id-2", + "impid": "test-impression-id-2", + "price": 2 + }, + "type": "native" + }] + }, { + "bids": [{ + "bid": { + "id": "test-bid-id-3", + "impid": "test-impression-id-3", + "price": 3 + }, + "type": "native" + }] + }] +} diff --git a/adapters/applogy/applogytest/exemplary/simple-video.json b/adapters/applogy/applogytest/exemplary/simple-video.json new file mode 100644 index 00000000000..30237cccd10 --- /dev/null +++ b/adapters/applogy/applogytest/exemplary/simple-video.json @@ -0,0 +1,182 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-1", + "video": { + "w": 900, + "h": 250, + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "token": "test-token-1" + } + } + }, { + "id": "test-impression-id-2", + "video": { + "w": 900, + "h": 250, + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "token": "test-token-1" + } + } + }, { + "id": "test-impression-id-3", + "video": { + "w": 900, + "h": 250, + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "token": "test-token-2" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://example.com/prebid/test-token-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-1", + "video": { + "w": 900, + "h": 250, + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "token": "test-token-1" + } + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id-1", + "impid": "test-impression-id-1", + "price": 1 + }] + }] + } + } + }, { + "expectedRequest": { + "uri": "http://example.com/prebid/test-token-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-2", + "video": { + "w": 900, + "h": 250, + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "token": "test-token-1" + } + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id-2", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id-2", + "impid": "test-impression-id-2", + "price": 2 + }] + }] + } + } + }, { + "expectedRequest": { + "uri": "http://example.com/prebid/test-token-2", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-3", + "video": { + "w": 900, + "h": 250, + "mimes": [ + "video/mp4" + ] + }, + "ext": { + "bidder": { + "token": "test-token-2" + } + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id-3", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id-3", + "impid": "test-impression-id-3", + "price": 3 + }] + }] + } + } + }], + "expectedBidResponses": [{ + "bids": [{ + "bid": { + "id": "test-bid-id-1", + "impid": "test-impression-id-1", + "price": 1 + }, + "type": "video" + }] + }, { + "bids": [{ + "bid": { + "id": "test-bid-id-2", + "impid": "test-impression-id-2", + "price": 2 + }, + "type": "video" + }] + }, { + "bids": [{ + "bid": { + "id": "test-bid-id-3", + "impid": "test-impression-id-3", + "price": 3 + }, + "type": "video" + }] + }] +} diff --git a/adapters/applogy/applogytest/supplemental/all-failed.json b/adapters/applogy/applogytest/supplemental/all-failed.json new file mode 100644 index 00000000000..7f0244afcfb --- /dev/null +++ b/adapters/applogy/applogytest/supplemental/all-failed.json @@ -0,0 +1,16 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-1", + "banner": { + "w": 300, + "h": 250 + } + }] + }, + "expectedMakeRequestsErrors": [{ + "value": "impression extensions required", + "comparison": "literal" + }] +} diff --git a/adapters/applogy/applogytest/supplemental/invalid-params.json b/adapters/applogy/applogytest/supplemental/invalid-params.json new file mode 100644 index 00000000000..6b5d5e3224d --- /dev/null +++ b/adapters/applogy/applogytest/supplemental/invalid-params.json @@ -0,0 +1,133 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-1", + "banner": {} + }, { + "id": "test-impression-id-2", + "banner": { + "w": 300, + "h": 250 + } + }, { + "id": "test-impression-id-3", + "banner": { + "w": 300, + "h": 250 + }, + "ext": {} + }, { + "id": "test-impression-id-4" + }, { + "id": "test-impression-id-5", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "token": "test-token-5" + } + } + }, { + "id": "test-impression-id-0", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": "invalid bidder" + } + }, { + "id": "test-impression-id-0", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": {} + } + }, { + "id": "test-impression-id-0", + "banner": { + "w": 300, + "h": 250 + }, + "ext": "invalid ext" + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://example.com/prebid/test-token-5", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-5", + "banner": { + "h": 250, + "w": 300 + }, + "ext": { + "bidder": { + "token": "test-token-5" + } + } + }] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-response-id", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id-5", + "impid": "test-impression-id-5", + "price": 5 + }, { + "id": "test-bid-id-6", + "impid": "test-impression-id-6", + "price": 6 + }] + }] + } + } + }], + "expectedBidResponses": [{ + "bids": [{ + "bid": { + "id": "test-bid-id-5", + "impid": "test-impression-id-5", + "price": 5 + }, + "type": "banner" + }] + }], + "expectedMakeRequestsErrors": [{ + "value": "banner size information missing", + "comparison": "literal" + }, { + "value": "impression extensions required", + "comparison": "literal" + }, { + "value": "bidder required", + "comparison": "literal" + }, { + "value": "Applogy only supports banner, video or native ads", + "comparison": "literal" + }, { + "value": "json: cannot unmarshal string into Go value of type openrtb_ext.ExtImpApplogy", + "comparison": "literal" + }, { + "value": "Applogy token required", + "comparison": "literal" + }, { + "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "comparison": "literal" + }], + "expectedMakeBidsErrors": [{ + "value": "ignoring bid id=test-bid-id-6, request doesn't contain any valid impression with id=test-impression-id-6", + "comparison": "literal" + }] +} diff --git a/adapters/applogy/applogytest/supplemental/status-204.json b/adapters/applogy/applogytest/supplemental/status-204.json new file mode 100644 index 00000000000..c3516b184b5 --- /dev/null +++ b/adapters/applogy/applogytest/supplemental/status-204.json @@ -0,0 +1,41 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-1", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "token": "test-token-1" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://example.com/prebid/test-token-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-1", + "banner": { + "h": 250, + "w": 300 + }, + "ext": { + "bidder": { + "token": "test-token-1" + } + } + }] + } + }, + "mockResponse": { + "status": 204, + "body": {} + } + }] +} diff --git a/adapters/applogy/applogytest/supplemental/status-400.json b/adapters/applogy/applogytest/supplemental/status-400.json new file mode 100644 index 00000000000..95e271bae8e --- /dev/null +++ b/adapters/applogy/applogytest/supplemental/status-400.json @@ -0,0 +1,45 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-1", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "token": "test-token-1" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://example.com/prebid/test-token-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-1", + "banner": { + "h": 250, + "w": 300 + }, + "ext": { + "bidder": { + "token": "test-token-1" + } + } + }] + } + }, + "mockResponse": { + "status": 400, + "body": {} + } + }], + "expectedMakeBidsErrors": [{ + "value": "unexpected status code: 400", + "comparison": "literal" + }] +} diff --git a/adapters/applogy/applogytest/supplemental/status-502.json b/adapters/applogy/applogytest/supplemental/status-502.json new file mode 100644 index 00000000000..c0b1641653a --- /dev/null +++ b/adapters/applogy/applogytest/supplemental/status-502.json @@ -0,0 +1,45 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-1", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "token": "test-token-1" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://example.com/prebid/test-token-1", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-impression-id-1", + "banner": { + "h": 250, + "w": 300 + }, + "ext": { + "bidder": { + "token": "test-token-1" + } + } + }] + } + }, + "mockResponse": { + "status": 502, + "body": {} + } + }], + "expectedMakeBidsErrors": [{ + "value": "unexpected status code: 502", + "comparison": "literal" + }] +} diff --git a/config/config.go b/config/config.go index 1c7ef66eaa7..59f41e9131f 100644 --- a/config/config.go +++ b/config/config.go @@ -670,6 +670,7 @@ func SetupViper(v *viper.Viper, filename string) { v.SetDefault("adapters.adpone.endpoint", "http://rtb.adpone.com/bid-request?src=prebid_server") v.SetDefault("adapters.adtelligent.endpoint", "http://hb.adtelligent.com/auction") v.SetDefault("adapters.advangelists.endpoint", "http://nep.advangelists.com/xp/get?pubid={{.PublisherID}}") + 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") v.SetDefault("adapters.beachfront.endpoint", "https://display.bfmio.com/prebid_display") diff --git a/exchange/adapter_map.go b/exchange/adapter_map.go index d5e205378f1..30a31727d6b 100644 --- a/exchange/adapter_map.go +++ b/exchange/adapter_map.go @@ -15,6 +15,7 @@ import ( "github.com/prebid/prebid-server/adapters/adpone" "github.com/prebid/prebid-server/adapters/adtelligent" "github.com/prebid/prebid-server/adapters/advangelists" + "github.com/prebid/prebid-server/adapters/applogy" "github.com/prebid/prebid-server/adapters/appnexus" "github.com/prebid/prebid-server/adapters/audienceNetwork" "github.com/prebid/prebid-server/adapters/beachfront" @@ -71,6 +72,7 @@ func newAdapterMap(client *http.Client, cfg *config.Configuration, infos adapter openrtb_ext.BidderAdpone: adpone.NewAdponeBidder(cfg.Adapters[string(openrtb_ext.BidderAdpone)].Endpoint), openrtb_ext.BidderAdtelligent: adtelligent.NewAdtelligentBidder(cfg.Adapters[string(openrtb_ext.BidderAdtelligent)].Endpoint), openrtb_ext.BidderAdvangelists: advangelists.NewAdvangelistsBidder(cfg.Adapters[string(openrtb_ext.BidderAdvangelists)].Endpoint), + openrtb_ext.BidderApplogy: applogy.NewApplogyBidder(cfg.Adapters[string(openrtb_ext.BidderApplogy)].Endpoint), openrtb_ext.BidderAppnexus: appnexus.NewAppNexusBidder(client, cfg.Adapters[string(openrtb_ext.BidderAppnexus)].Endpoint, cfg.Adapters[string(openrtb_ext.BidderAppnexus)].PlatformID), // TODO #615: Update the config setup so that the Beachfront URLs can be configured, and use those in TestRaceIntegration in exchange_test.go openrtb_ext.BidderBeachfront: beachfront.NewBeachfrontBidder(), diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 386eb93d2f0..9621b23dc81 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -27,6 +27,7 @@ const ( BidderAdpone BidderName = "adpone" BidderAdtelligent BidderName = "adtelligent" BidderAdvangelists BidderName = "advangelists" + BidderApplogy BidderName = "applogy" BidderAppnexus BidderName = "appnexus" BidderBeachfront BidderName = "beachfront" BidderBrightroll BidderName = "brightroll" @@ -79,6 +80,7 @@ var BidderMap = map[string]BidderName{ "adpone": BidderAdpone, "adtelligent": BidderAdtelligent, "advangelists": BidderAdvangelists, + "applogy": BidderApplogy, "appnexus": BidderAppnexus, "beachfront": BidderBeachfront, "brightroll": BidderBrightroll, diff --git a/openrtb_ext/imp_applogy.go b/openrtb_ext/imp_applogy.go new file mode 100644 index 00000000000..45774a05afb --- /dev/null +++ b/openrtb_ext/imp_applogy.go @@ -0,0 +1,5 @@ +package openrtb_ext + +type ExtImpApplogy struct { + Token string `json:"token"` +} diff --git a/static/bidder-info/applogy.yaml b/static/bidder-info/applogy.yaml new file mode 100644 index 00000000000..bb908c94e70 --- /dev/null +++ b/static/bidder-info/applogy.yaml @@ -0,0 +1,13 @@ +maintainer: + email: work@applogy.com +capabilities: + app: + mediaTypes: + - banner + - video + - native + site: + mediaTypes: + - banner + - video + - native diff --git a/static/bidder-params/applogy.json b/static/bidder-params/applogy.json new file mode 100644 index 00000000000..2650640c115 --- /dev/null +++ b/static/bidder-params/applogy.json @@ -0,0 +1,13 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Applogy Adapter Params", + "description": "A schema which validates params accepted by the Applogy adapter", + "type": "object", + "properties": { + "token": { + "type": "string", + "description": "Applogy token" + } + }, + "required": ["token"] +} diff --git a/usersync/usersyncers/syncer_test.go b/usersync/usersyncers/syncer_test.go index 7917f81cc40..dd2b5b5d1e9 100644 --- a/usersync/usersyncers/syncer_test.go +++ b/usersync/usersyncers/syncer_test.go @@ -63,6 +63,7 @@ func TestNewSyncerMap(t *testing.T) { } adaptersWithoutSyncers := map[openrtb_ext.BidderName]bool{ + openrtb_ext.BidderApplogy: true, openrtb_ext.BidderTappx: true, openrtb_ext.BidderKubient: true, openrtb_ext.BidderPubnative: true,