Skip to content

Commit 6e452fe

Browse files
committed
Submit trustx adapter
1 parent be0a6b2 commit 6e452fe

20 files changed

+1846
-6
lines changed

adapters/trustx/params_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package trustx
2+
3+
import (
4+
"encoding/json"
5+
"testing"
6+
7+
"github.com/prebid/prebid-server/v3/openrtb_ext"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
// This file actually intends to test static/bidder-params/trustx.json
12+
//
13+
// These also validate the format of the external API: request.imp[i].ext.prebid.bidder.trustx
14+
15+
// TestValidParams makes sure that the trustx schema accepts all imp.ext fields which we intend to support.
16+
func TestValidParams(t *testing.T) {
17+
validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
18+
require.NoError(t, err, "Failed to fetch the json-schemas")
19+
20+
for _, validParam := range validParams {
21+
err := validator.Validate(openrtb_ext.BidderTrustX, json.RawMessage(validParam))
22+
require.NoError(t, err, "Schema rejected trustx params: %s", validParam)
23+
}
24+
}
25+
26+
// TestInvalidParams makes sure that the trustx schema rejects all the imp.ext fields we don't support.
27+
func TestInvalidParams(t *testing.T) {
28+
validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
29+
require.NoError(t, err, "Failed to fetch the json-schemas")
30+
31+
for _, invalidParam := range invalidParams {
32+
err := validator.Validate(openrtb_ext.BidderTrustX, json.RawMessage(invalidParam))
33+
require.Error(t, err, "Schema allowed unexpected params: %s", invalidParam)
34+
}
35+
}
36+
37+
var validParams = []string{
38+
`{}`,
39+
`{"uid": 1234}`,
40+
`{"uid": 1234, "keywords":{"site": {}, "user": {}}}`,
41+
}
42+
var invalidParams = []string{
43+
``,
44+
`null`,
45+
`true`,
46+
`5`,
47+
`4.2`,
48+
`[]`,
49+
}

adapters/trustx/trustx.go

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
package trustx
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
8+
"github.com/prebid/openrtb/v20/openrtb2"
9+
"github.com/prebid/prebid-server/v3/adapters"
10+
"github.com/prebid/prebid-server/v3/config"
11+
"github.com/prebid/prebid-server/v3/errortypes"
12+
"github.com/prebid/prebid-server/v3/openrtb_ext"
13+
"github.com/prebid/prebid-server/v3/util/jsonutil"
14+
)
15+
16+
type impExt struct {
17+
Prebid *openrtb_ext.ExtImpPrebid `json:"prebid,omitempty"`
18+
Bidder json.RawMessage `json:"bidder"`
19+
Data *impExtData `json:"data,omitempty"`
20+
Gpid string `json:"gpid,omitempty"`
21+
}
22+
23+
type impExtData struct {
24+
PbAdslot string `json:"pbadslot,omitempty"`
25+
AdServer *impExtDataAdServer `json:"adserver,omitempty"`
26+
}
27+
28+
type impExtDataAdServer struct {
29+
Name string `json:"name,omitempty"`
30+
AdSlot string `json:"adslot,omitempty"`
31+
}
32+
33+
type bidExt struct {
34+
Bidder bidExtBidder `json:"bidder,omitempty"`
35+
}
36+
37+
type bidExtBidder struct {
38+
TrustX bidExtBidderTrustX `json:"trustx,omitempty"`
39+
}
40+
41+
type bidExtBidderTrustX struct {
42+
NetworkName string `json:"networkName,omitempty"`
43+
}
44+
45+
type adapter struct {
46+
endpoint string
47+
}
48+
49+
// Builder builds a new instance of the TRUSTX adapter for the given bidder with the given config.
50+
func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
51+
bidder := &adapter{
52+
endpoint: config.Endpoint,
53+
}
54+
return bidder, nil
55+
}
56+
57+
func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
58+
var errs []error
59+
for i := range request.Imp {
60+
setImpExtData(&request.Imp[i])
61+
}
62+
63+
body, err := jsonutil.Marshal(request)
64+
if err != nil {
65+
errs = append(errs, err)
66+
return nil, errs
67+
}
68+
69+
reqs := make([]*adapters.RequestData, 0, 1)
70+
requestData := &adapters.RequestData{
71+
Method: http.MethodPost,
72+
Uri: a.endpoint,
73+
Body: body,
74+
Headers: getHeaders(request),
75+
ImpIDs: openrtb_ext.GetImpIDs(request.Imp),
76+
}
77+
reqs = append(reqs, requestData)
78+
79+
return reqs, errs
80+
}
81+
82+
func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
83+
if adapters.IsResponseStatusCodeNoContent(response) {
84+
return nil, nil
85+
}
86+
87+
if err := adapters.CheckResponseStatusCodeForErrors(response); err != nil {
88+
return nil, []error{err}
89+
}
90+
91+
var resp openrtb2.BidResponse
92+
if err := jsonutil.Unmarshal(response.Body, &resp); err != nil {
93+
return nil, []error{&errortypes.BadServerResponse{
94+
Message: "Bad Server Response",
95+
}}
96+
}
97+
98+
var bidErrors []error
99+
bidderResponse := adapters.NewBidderResponseWithBidsCapacity(1)
100+
for i := range resp.SeatBid {
101+
seatBid := &resp.SeatBid[i]
102+
for j := range seatBid.Bid {
103+
bid := &seatBid.Bid[j]
104+
typedBid, err := getTypedBid(bid)
105+
if err != nil {
106+
bidErrors = append(bidErrors, err)
107+
continue
108+
}
109+
bidderResponse.Bids = append(bidderResponse.Bids, typedBid)
110+
}
111+
}
112+
113+
return bidderResponse, bidErrors
114+
}
115+
116+
func setImpExtData(imp *openrtb2.Imp) {
117+
var ext impExt
118+
if err := jsonutil.Unmarshal(imp.Ext, &ext); err != nil {
119+
return
120+
}
121+
if ext.Data != nil && ext.Data.AdServer != nil && ext.Data.AdServer.AdSlot != "" {
122+
ext.Gpid = ext.Data.AdServer.AdSlot
123+
extJSON, err := jsonutil.Marshal(ext)
124+
if err == nil {
125+
imp.Ext = extJSON
126+
}
127+
}
128+
}
129+
130+
func getHeaders(request *openrtb2.BidRequest) http.Header {
131+
headers := http.Header{}
132+
headers.Set("Content-Type", "application/json;charset=utf-8")
133+
headers.Set("Accept", "application/json")
134+
headers.Set("X-Openrtb-Version", "2.6")
135+
136+
if request.Site != nil {
137+
if request.Site.Ref != "" {
138+
headers.Set("Referer", request.Site.Ref)
139+
}
140+
if request.Site.Domain != "" {
141+
headers.Set("Origin", request.Site.Domain)
142+
}
143+
}
144+
145+
if request.Device != nil {
146+
if len(request.Device.IP) > 0 {
147+
headers.Set("X-Forwarded-For", request.Device.IP)
148+
}
149+
150+
if len(request.Device.IPv6) > 0 {
151+
headers.Set("X-Forwarded-For", request.Device.IPv6)
152+
}
153+
154+
if len(request.Device.UA) > 0 {
155+
headers.Set("User-Agent", request.Device.UA)
156+
}
157+
}
158+
159+
return headers
160+
}
161+
162+
func getTypedBid(bid *openrtb2.Bid) (*adapters.TypedBid, error) {
163+
var bidType openrtb_ext.BidType
164+
switch bid.MType {
165+
case openrtb2.MarkupBanner:
166+
bidType = openrtb_ext.BidTypeBanner
167+
case openrtb2.MarkupVideo:
168+
bidType = openrtb_ext.BidTypeVideo
169+
default:
170+
return nil, &errortypes.BadServerResponse{
171+
Message: fmt.Sprintf("Unsupported MType: %v", bid.MType),
172+
}
173+
}
174+
175+
var extBidPrebidVideo *openrtb_ext.ExtBidPrebidVideo
176+
if bidType == openrtb_ext.BidTypeVideo {
177+
extBidPrebidVideo = &openrtb_ext.ExtBidPrebidVideo{}
178+
if len(bid.Cat) > 0 {
179+
extBidPrebidVideo.PrimaryCategory = bid.Cat[0]
180+
}
181+
if bid.Dur > 0 {
182+
extBidPrebidVideo.Duration = int(bid.Dur)
183+
}
184+
}
185+
return &adapters.TypedBid{
186+
Bid: bid,
187+
BidType: bidType,
188+
BidVideo: extBidPrebidVideo,
189+
BidMeta: getBidMeta(bid.Ext),
190+
}, nil
191+
}
192+
193+
func getBidMeta(ext json.RawMessage) *openrtb_ext.ExtBidPrebidMeta {
194+
if ext == nil {
195+
return nil
196+
}
197+
var be bidExt
198+
199+
if err := jsonutil.Unmarshal(ext, &be); err != nil {
200+
return nil
201+
}
202+
var bidMeta *openrtb_ext.ExtBidPrebidMeta
203+
if be.Bidder.TrustX.NetworkName != "" {
204+
bidMeta = &openrtb_ext.ExtBidPrebidMeta{
205+
NetworkName: be.Bidder.TrustX.NetworkName,
206+
}
207+
}
208+
return bidMeta
209+
}

adapters/trustx/trustx_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package trustx
2+
3+
import (
4+
"testing"
5+
6+
"github.com/prebid/prebid-server/v3/adapters/adapterstest"
7+
"github.com/prebid/prebid-server/v3/config"
8+
"github.com/prebid/prebid-server/v3/openrtb_ext"
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
func TestJsonSamples(t *testing.T) {
13+
bidder, buildErr := Builder(openrtb_ext.BidderTrustX, config.Adapter{
14+
Endpoint: "https://test.localhost.com"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
15+
16+
require.NoError(t, buildErr, "Builder returned unexpected error")
17+
adapterstest.RunJSONBidderTest(t, "trustxtest", bidder)
18+
}

0 commit comments

Comments
 (0)