From b1dcc66874dadfcd3cdc9ba6232d7733dc067ba7 Mon Sep 17 00:00:00 2001 From: shubhamc-ins Date: Thu, 16 May 2024 14:35:33 +0530 Subject: [PATCH 01/15] init insticator adaptor --- adapters/insticator/insticator.go | 79 ++++++++++++++++++++++++++++++ config/config.go | 2 +- exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + static/bidder-info/insticator.yaml | 17 +++++++ 5 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 adapters/insticator/insticator.go create mode 100644 static/bidder-info/insticator.yaml diff --git a/adapters/insticator/insticator.go b/adapters/insticator/insticator.go new file mode 100644 index 00000000000..7bf1b2a531d --- /dev/null +++ b/adapters/insticator/insticator.go @@ -0,0 +1,79 @@ +package insticator + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/prebid/openrtb/v19/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 Foo adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + requestJSON, err := json.Marshal(request) + if err != nil { + return nil, []error{err} + } + + requestData := &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: requestJSON, + } + + return []*adapters.RequestData{requestData}, 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{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + bidResponse.Currency = response.Cur + for _, seatBid := range response.SeatBid { + for i, bid := range seatBid.Bid { + b := &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: getMediaTypeForBid(bid), + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + return bidResponse, nil + } + return bidResponse, nil +} diff --git a/config/config.go b/config/config.go index d2f2103972d..ec41b342c5e 100644 --- a/config/config.go +++ b/config/config.go @@ -254,7 +254,7 @@ type GDPR struct { func (cfg *GDPR) validate(v *viper.Viper, errs []error) []error { if !v.IsSet("gdpr.default_value") { - errs = append(errs, fmt.Errorf("gdpr.default_value is required and must be specified")) + // errs = append(errs, fmt.Errorf("gdpr.default_value is required and must be specified")) } else if cfg.DefaultValue != "0" && cfg.DefaultValue != "1" { errs = append(errs, fmt.Errorf("gdpr.default_value must be 0 or 1")) } diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 9f96cdbf171..28fa494e1ae 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -99,6 +99,7 @@ import ( "github.com/prebid/prebid-server/v2/adapters/improvedigital" "github.com/prebid/prebid-server/v2/adapters/infytv" "github.com/prebid/prebid-server/v2/adapters/inmobi" + "github.com/prebid/prebid-server/v2/adapters/insticator" "github.com/prebid/prebid-server/v2/adapters/interactiveoffers" "github.com/prebid/prebid-server/v2/adapters/invibes" "github.com/prebid/prebid-server/v2/adapters/iqx" @@ -308,6 +309,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderImprovedigital: improvedigital.Builder, openrtb_ext.BidderInfyTV: infytv.Builder, openrtb_ext.BidderInMobi: inmobi.Builder, + openrtb_ext.BidderInsticator: insticator.Builder, openrtb_ext.BidderInteractiveoffers: interactiveoffers.Builder, openrtb_ext.BidderInvibes: invibes.Builder, openrtb_ext.BidderIQX: iqx.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 93c6a49e8e4..6a969e4ffc8 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -116,6 +116,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderImprovedigital, BidderInfyTV, BidderInMobi, + BidderInsticator, BidderInteractiveoffers, BidderInvibes, BidderIQX, @@ -402,6 +403,7 @@ const ( BidderImprovedigital BidderName = "improvedigital" BidderInfyTV BidderName = "infytv" BidderInMobi BidderName = "inmobi" + BidderInsticator BidderName = "insticator" BidderInteractiveoffers BidderName = "interactiveoffers" BidderInvibes BidderName = "invibes" BidderIQX BidderName = "iqx" diff --git a/static/bidder-info/insticator.yaml b/static/bidder-info/insticator.yaml new file mode 100644 index 00000000000..f909e99ba14 --- /dev/null +++ b/static/bidder-info/insticator.yaml @@ -0,0 +1,17 @@ +endpoint: "https://ex.ingage.tech/v1/prebidserver" +maintainer: + email: "predid@insticator.com" +gvlVendorID: 910 +capabilities: + app: + mediaTypes: + - banner + - video + site: + mediaTypes: + - banner + - video +userSync: + redirect: + url: "" + userMacro: "" \ No newline at end of file From eade24780aaf3ace3bd5a798935b57890540787d Mon Sep 17 00:00:00 2001 From: shubhamc-ins Date: Thu, 16 May 2024 14:47:59 +0530 Subject: [PATCH 02/15] update modules --- adapters/insticator/insticator.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/adapters/insticator/insticator.go b/adapters/insticator/insticator.go index 7bf1b2a531d..ac4e26c90f6 100644 --- a/adapters/insticator/insticator.go +++ b/adapters/insticator/insticator.go @@ -5,11 +5,11 @@ import ( "fmt" "net/http" - "github.com/prebid/openrtb/v19/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" + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v2/openrtb_ext" ) type adapter struct { From 716d7a788fef6c79ee8f42e5421c4ae71f16a7f9 Mon Sep 17 00:00:00 2001 From: shubhamc-ins Date: Thu, 16 May 2024 15:14:23 +0530 Subject: [PATCH 03/15] add mediaType for bids --- adapters/insticator/insticator.go | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/adapters/insticator/insticator.go b/adapters/insticator/insticator.go index ac4e26c90f6..9af0a8ccdd7 100644 --- a/adapters/insticator/insticator.go +++ b/adapters/insticator/insticator.go @@ -24,6 +24,18 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co return bidder, nil } +// getMediaTypeForImp figures out which media type this bid is for +func getMediaTypeForBid(bid *openrtb2.Bid) openrtb_ext.BidType { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo + default: + return openrtb_ext.BidTypeBanner + } +} + func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { requestJSON, err := json.Marshal(request) if err != nil { @@ -66,14 +78,15 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) bidResponse.Currency = response.Cur for _, seatBid := range response.SeatBid { - for i, bid := range seatBid.Bid { + for i := range seatBid.Bid { + bid := &seatBid.Bid[i] + bidType := getMediaTypeForBid(bid) b := &adapters.TypedBid{ Bid: &seatBid.Bid[i], - BidType: getMediaTypeForBid(bid), + BidType: bidType, } bidResponse.Bids = append(bidResponse.Bids, b) } - return bidResponse, nil } return bidResponse, nil } From d3b1a1decc63a5c08bd43fe592f31446a3b7cfa0 Mon Sep 17 00:00:00 2001 From: shubhamc-ins Date: Fri, 17 May 2024 17:21:49 +0530 Subject: [PATCH 04/15] update insticator adaptor with tests --- adapters/insticator/insticator_test.go | 21 +++ .../exemplary/simple-banner.json | 109 ++++++++++++++++ .../exemplary/simple-video.json | 121 ++++++++++++++++++ .../supplemental/status-not-ok.json | 78 +++++++++++ adapters/insticator/params_test.go | 54 ++++++++ openrtb_ext/imp_insticator.go | 8 ++ static/bidder-params/insticator.json | 23 ++++ 7 files changed, 414 insertions(+) create mode 100644 adapters/insticator/insticator_test.go create mode 100644 adapters/insticator/insticatortest/exemplary/simple-banner.json create mode 100644 adapters/insticator/insticatortest/exemplary/simple-video.json create mode 100644 adapters/insticator/insticatortest/supplemental/status-not-ok.json create mode 100644 adapters/insticator/params_test.go create mode 100644 openrtb_ext/imp_insticator.go create mode 100644 static/bidder-params/insticator.json diff --git a/adapters/insticator/insticator_test.go b/adapters/insticator/insticator_test.go new file mode 100644 index 00000000000..2e65e4dad29 --- /dev/null +++ b/adapters/insticator/insticator_test.go @@ -0,0 +1,21 @@ +package insticator + +import ( + "testing" + + "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v2/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderInsticator, config.Adapter{ + Endpoint: "https://ex.ingage.tech/v1/prebidserver"}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "{bidder}test", bidder) +} diff --git a/adapters/insticator/insticatortest/exemplary/simple-banner.json b/adapters/insticator/insticatortest/exemplary/simple-banner.json new file mode 100644 index 00000000000..b2cbba7c199 --- /dev/null +++ b/adapters/insticator/insticatortest/exemplary/simple-banner.json @@ -0,0 +1,109 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 728, "h": 90}] + }, + "ext": { + "bidder": { + "siteId": "fake-site-id", + "productId": "inview" + } + } + } + ], + "site": {} + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ex.ingage.tech/v1/prebidserver", + "body": { + "ext": { + "insticator": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 728, "h": 90}] + }, + "ext": { + "insticator": { + "prod": "inview", + "zoneid": "fake-site-id" + } + } + } + ], + "site": {} + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "insticator", + "bid": [{ + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "ext": { + "insticator": { + "mediaType": "banner" + } + } + }] + } + ], + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 728, + "h": 90, + "ext": { + "insticator": { + "mediaType": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] + } + \ No newline at end of file diff --git a/adapters/insticator/insticatortest/exemplary/simple-video.json b/adapters/insticator/insticatortest/exemplary/simple-video.json new file mode 100644 index 00000000000..fd498f516cb --- /dev/null +++ b/adapters/insticator/insticatortest/exemplary/simple-video.json @@ -0,0 +1,121 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 728, + "h": 90, + "protocols": [2], + "placement": 1, + "startdelay": -2, + "playbackmethod": [2], + "mimes": ["foo", "bar"] + }, + "ext": { + "bidder": { + "siteId": "fake-site-id", + "productId": "instream" + } + } + } + ], + "site": {} + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ex.ingage.tech/v1/prebidserver", + "body": { + "ext": { + "insticator": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "video": { + "w": 728, + "h": 90, + "protocols": [2], + "placement": 1, + "startdelay": -2, + "playbackmethod": [2], + "mimes": ["foo", "bar"] + }, + "ext": { + "insticator": { + "prod": "instream", + "zoneid": "fake-site-id" + } + } + } + ], + "site": {} + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "insticator", + "bid": [{ + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-vast-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "ext": { + "insticator": { + "mediaType": "video" + } + } + }] + } + ], + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-vast-ad", + "crid": "crid_10", + "w": 728, + "h": 90, + "ext": { + "insticator": { + "mediaType": "video" + } + } + }, + "type": "video" + } + ] + } + ] + } + \ No newline at end of file diff --git a/adapters/insticator/insticatortest/supplemental/status-not-ok.json b/adapters/insticator/insticatortest/supplemental/status-not-ok.json new file mode 100644 index 00000000000..7ed00cc6157 --- /dev/null +++ b/adapters/insticator/insticatortest/supplemental/status-not-ok.json @@ -0,0 +1,78 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 728, "h": 90}] + }, + "ext": { + "bidder": { + "siteId": "fake-invalid-site-id", + "productId": "inview" + } + } + } + ], + "site": {} + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ex.ingage.tech/v1/prebidserver", + "body": { + "ext": { + "insticator": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 728, "h": 90}] + }, + "ext": { + "insticator": { + "prod": "inview", + "zoneid": "fake-invalid-site-id" + } + } + } + ], + "site": {} + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 400, + "body": { + "error": { + "message": "Validation failed", + "details": [ + { + "message": "site.id is invalid" + } + ] + } + } + } + } + ], + + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] + } + \ No newline at end of file diff --git a/adapters/insticator/params_test.go b/adapters/insticator/params_test.go new file mode 100644 index 00000000000..2a23de874c8 --- /dev/null +++ b/adapters/insticator/params_test.go @@ -0,0 +1,54 @@ +package insticator + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v2/openrtb_ext" +) + +// This file actually intends to test static/bidder-params/Insticator.json +// +// These also validate the format of the external API: request.imp[i].ext.prebid.bidder.Insticator + +// TestValidParams makes sure that the Insticator schema accepts all imp.ext fields which we intend to support. +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderInsticator, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected Insticator params: %s", validParam) + } + } +} + +// TestInvalidParams makes sure that the Insticator 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 { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderInsticator, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{"productId": "inview", "siteId": "fakesiteid1"}`, + `{"productId": "siab", "siteId": "fakesiteid2"}`, + `{"productId": "inview", "siteId": "foo.ba", "zoneId": "zone1"}`, +} + +var invalidParams = []string{ + `{"productId": "inview"}`, + `{"siteId": "fakesiteid2"}`, + `{"productId": 123, "siteId": "fakesiteid2"}`, + `{"productId": "siab", "siteId": 123}`, + `{"productId": "siab", "siteId": "fakesiteid2", "zoneId": 123}`, +} diff --git a/openrtb_ext/imp_insticator.go b/openrtb_ext/imp_insticator.go new file mode 100644 index 00000000000..eaeff864260 --- /dev/null +++ b/openrtb_ext/imp_insticator.go @@ -0,0 +1,8 @@ +package openrtb_ext + +// ExtInsticator defines the contract for bidrequest.imp[i].ext.prebid.bidder.insticator +type ExtInsticator struct { + SiteId string `json:"siteId"` + ZoneId string `json:"zoneId,omitempty"` + ProductId string `json:"productId,omitempty"` +} diff --git a/static/bidder-params/insticator.json b/static/bidder-params/insticator.json new file mode 100644 index 00000000000..187a88526ec --- /dev/null +++ b/static/bidder-params/insticator.json @@ -0,0 +1,23 @@ + +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Insticator Adapter Params", + "description": "A schema which validates params accepted by the 33Across adapter", + + "type": "object", + "properties": { + "productId": { + "type": "string", + "description": "Product type" + }, + "siteId": { + "type": "string", + "description": "Site Id" + }, + "zoneId": { + "type": "string", + "description": "Zone Id" + } + }, + "required": ["siteId"] + } \ No newline at end of file From 11254233aa510036e99a816aa37939c09c950b33 Mon Sep 17 00:00:00 2001 From: shubhamc-ins Date: Wed, 5 Jun 2024 17:41:21 +0530 Subject: [PATCH 05/15] update insticator for test cases --- adapters/insticator/insticator.go | 239 +++++++++++++++++- adapters/insticator/insticator_test.go | 2 +- .../exemplary/simple-video.json | 121 --------- .../insticatortest/exemplary/site-banner.json | 108 ++++++++ .../insticatortest/exemplary/site-video.json | 120 +++++++++ .../multi-imp-mixed-validation.json} | 38 ++- 6 files changed, 483 insertions(+), 145 deletions(-) delete mode 100644 adapters/insticator/insticatortest/exemplary/simple-video.json create mode 100644 adapters/insticator/insticatortest/exemplary/site-banner.json create mode 100644 adapters/insticator/insticatortest/exemplary/site-video.json rename adapters/insticator/insticatortest/{exemplary/simple-banner.json => supplemental/multi-imp-mixed-validation.json} (74%) diff --git a/adapters/insticator/insticator.go b/adapters/insticator/insticator.go index 9af0a8ccdd7..8efb3b0ec71 100644 --- a/adapters/insticator/insticator.go +++ b/adapters/insticator/insticator.go @@ -5,6 +5,7 @@ import ( "fmt" "net/http" + "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" "github.com/prebid/prebid-server/v2/adapters" "github.com/prebid/prebid-server/v2/config" @@ -12,13 +13,52 @@ import ( "github.com/prebid/prebid-server/v2/openrtb_ext" ) -type adapter struct { +type InstAdapter struct { endpoint string } +type Ext struct { + Ttx impTtxExt `json:"ttx"` +} + +type impTtxExt struct { + Prod string `json:"prod"` + Zoneid string `json:"zoneid,omitempty"` +} + +type adapter struct { + endpoint string + makerequest func() +} + +type reqExt struct { + Ttx *reqTtxExt `json:"ttx,omitempty"` +} + +type reqTtxExt struct { + Caller []TtxCaller `json:"caller,omitempty"` +} + +type TtxCaller struct { + Name string `json:"name,omitempty"` + Version string `json:"version,omitempty"` +} + +// CALLER Info used to track Prebid Server +// as one of the hops in the request to exchange +var CALLER = TtxCaller{"Prebid-Server", "n/a"} + +type bidExt struct { + Ttx bidTtxExt `json:"ttx,omitempty"` +} + +type bidTtxExt struct { + MediaType string `json:"mediaType,omitempty"` +} + // Builder builds a new instance of the Foo adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { - bidder := &adapter{ + bidder := &InstAdapter{ endpoint: config.Endpoint, } return bidder, nil @@ -36,22 +76,94 @@ func getMediaTypeForBid(bid *openrtb2.Bid) openrtb_ext.BidType { } } -func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - requestJSON, err := json.Marshal(request) +func getBidType(ext bidExt) openrtb_ext.BidType { + if ext.Ttx.MediaType == "video" { + return openrtb_ext.BidTypeVideo + } + + return openrtb_ext.BidTypeBanner +} + +func (a *InstAdapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + // requestJSON, err := json.Marshal(request) + // if err != nil { + // return nil, []error{err} + // } + + // requestData := &adapters.RequestData{ + // Method: "POST", + // Uri: a.endpoint, + // Body: requestJSON, + // } + + // return []*adapters.RequestData{requestData}, nil + + var errs []error + var adapterRequests []*adapters.RequestData + var groupedImps = make(map[string][]openrtb2.Imp) + + // Construct request extension common to all imps + // NOTE: not blocking adapter requests on errors + // since request extension is optional. + reqExt, err := makeReqExt(request) if err != nil { - return nil, []error{err} + errs = append(errs, err) + } + request.Ext = reqExt + + // We only support SRA for requests containing same prod and + // zoneID, therefore group all imps accordingly and create a http + // request for each such group + for i := 0; i < len(request.Imp); i++ { + if impCopy, err := makeImps(request.Imp[i]); err == nil { + var impExt Ext + + // Skip over imps whose extensions cannot be read since + // we cannot glean Prod or ZoneID which are required to + // group together. However let's not block request creation. + if err := json.Unmarshal(impCopy.Ext, &impExt); err == nil { + impKey := impExt.Ttx.Prod + impExt.Ttx.Zoneid + groupedImps[impKey] = append(groupedImps[impKey], impCopy) + } else { + errs = append(errs, err) + } + } else { + errs = append(errs, err) + } } - requestData := &adapters.RequestData{ - Method: "POST", - Uri: a.endpoint, - Body: requestJSON, + for _, impList := range groupedImps { + if adapterReq, err := a.makeRequest(*request, impList); err == nil { + adapterRequests = append(adapterRequests, adapterReq) + } else { + errs = append(errs, err) + } + } + return adapterRequests, errs +} + +func (a *InstAdapter) makeRequest(request openrtb2.BidRequest, impList []openrtb2.Imp) (*adapters.RequestData, error) { + request.Imp = impList + + // Last Step + reqJSON, err := json.Marshal(request) + if err != nil { + return nil, err } - return []*adapters.RequestData{requestData}, nil + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + + return &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: reqJSON, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + }, nil } -func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { +func (a *InstAdapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { if responseData.StatusCode == http.StatusNoContent { return nil, nil } @@ -90,3 +202,108 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } return bidResponse, nil } + +func makeImps(imp openrtb2.Imp) (openrtb2.Imp, error) { + if imp.Banner == nil && imp.Video == nil { + return openrtb2.Imp{}, &errortypes.BadInput{ + Message: fmt.Sprintf("Imp ID %s must have at least one of [Banner, Video] defined", imp.ID), + } + } + + var bidderExt adapters.ExtImpBidder + if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + return openrtb2.Imp{}, &errortypes.BadInput{ + Message: err.Error(), + } + } + + var ttxExt openrtb_ext.ExtImp33across + if err := json.Unmarshal(bidderExt.Bidder, &ttxExt); err != nil { + return openrtb2.Imp{}, &errortypes.BadInput{ + Message: err.Error(), + } + } + + var impExt Ext + impExt.Ttx.Prod = ttxExt.ProductId + + impExt.Ttx.Zoneid = ttxExt.SiteId + + if len(ttxExt.ZoneId) > 0 { + impExt.Ttx.Zoneid = ttxExt.ZoneId + } + + impExtJSON, err := json.Marshal(impExt) + if err != nil { + return openrtb2.Imp{}, &errortypes.BadInput{ + Message: err.Error(), + } + } + + imp.Ext = impExtJSON + + // Validate Video if it exists + if imp.Video != nil { + videoCopy, err := validateVideoParams(imp.Video, impExt.Ttx.Prod) + + imp.Video = videoCopy + + if err != nil { + return openrtb2.Imp{}, &errortypes.BadInput{ + Message: err.Error(), + } + } + } + + return imp, nil +} + +func validateVideoParams(video *openrtb2.Video, prod string) (*openrtb2.Video, error) { + videoCopy := *video + if (videoCopy.W == nil || *videoCopy.W == 0) || + (videoCopy.H == nil || *videoCopy.H == 0) || + videoCopy.Protocols == nil || + videoCopy.MIMEs == nil || + videoCopy.PlaybackMethod == nil { + + return nil, &errortypes.BadInput{ + Message: "One or more invalid or missing video field(s) w, h, protocols, mimes, playbackmethod", + } + } + + if videoCopy.Placement == 0 { + videoCopy.Placement = 2 + } + + if prod == "instream" { + videoCopy.Placement = 1 + + if videoCopy.StartDelay == nil { + videoCopy.StartDelay = adcom1.StartDelay.Ptr(0) + } + } + + return &videoCopy, nil +} + +func makeReqExt(request *openrtb2.BidRequest) ([]byte, error) { + var reqExt reqExt + + if len(request.Ext) > 0 { + if err := json.Unmarshal(request.Ext, &reqExt); err != nil { + return nil, err + } + } + + if reqExt.Ttx == nil { + reqExt.Ttx = &reqTtxExt{} + } + + if reqExt.Ttx.Caller == nil { + reqExt.Ttx.Caller = make([]TtxCaller, 0) + } + + reqExt.Ttx.Caller = append(reqExt.Ttx.Caller, CALLER) + + return json.Marshal(reqExt) +} diff --git a/adapters/insticator/insticator_test.go b/adapters/insticator/insticator_test.go index 2e65e4dad29..5439857ffa5 100644 --- a/adapters/insticator/insticator_test.go +++ b/adapters/insticator/insticator_test.go @@ -17,5 +17,5 @@ func TestJsonSamples(t *testing.T) { t.Fatalf("Builder returned unexpected error %v", buildErr) } - adapterstest.RunJSONBidderTest(t, "{bidder}test", bidder) + adapterstest.RunJSONBidderTest(t, "insticatortest", bidder) } diff --git a/adapters/insticator/insticatortest/exemplary/simple-video.json b/adapters/insticator/insticatortest/exemplary/simple-video.json deleted file mode 100644 index fd498f516cb..00000000000 --- a/adapters/insticator/insticatortest/exemplary/simple-video.json +++ /dev/null @@ -1,121 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 728, - "h": 90, - "protocols": [2], - "placement": 1, - "startdelay": -2, - "playbackmethod": [2], - "mimes": ["foo", "bar"] - }, - "ext": { - "bidder": { - "siteId": "fake-site-id", - "productId": "instream" - } - } - } - ], - "site": {} - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "https://ex.ingage.tech/v1/prebidserver", - "body": { - "ext": { - "insticator": { - "caller": [ - { - "name": "Prebid-Server", - "version": "n/a" - } - ] - } - }, - "id": "test-request-id", - "imp": [ - { - "id":"test-imp-id", - "video": { - "w": 728, - "h": 90, - "protocols": [2], - "placement": 1, - "startdelay": -2, - "playbackmethod": [2], - "mimes": ["foo", "bar"] - }, - "ext": { - "insticator": { - "prod": "instream", - "zoneid": "fake-site-id" - } - } - } - ], - "site": {} - }, - "impIDs":["test-imp-id"] - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "insticator", - "bid": [{ - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id", - "price": 0.500000, - "adm": "some-test-vast-ad", - "crid": "crid_10", - "h": 90, - "w": 728, - "ext": { - "insticator": { - "mediaType": "video" - } - } - }] - } - ], - "cur": "USD" - } - } - } - ], - - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id", - "price": 0.5, - "adm": "some-test-vast-ad", - "crid": "crid_10", - "w": 728, - "h": 90, - "ext": { - "insticator": { - "mediaType": "video" - } - } - }, - "type": "video" - } - ] - } - ] - } - \ No newline at end of file diff --git a/adapters/insticator/insticatortest/exemplary/site-banner.json b/adapters/insticator/insticatortest/exemplary/site-banner.json new file mode 100644 index 00000000000..a698455b631 --- /dev/null +++ b/adapters/insticator/insticatortest/exemplary/site-banner.json @@ -0,0 +1,108 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 728, "h": 90}] + }, + "ext": { + "bidder": { + "siteId": "fake-site-id", + "productId": "inview" + } + } + } + ], + "site": {} + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ex.ingage.tech/v1/prebidserver", + "body": { + "ext": { + "ttx": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 728, "h": 90}] + }, + "ext": { + "ttx": { + "prod": "inview", + "zoneid": "fake-site-id" + } + } + } + ], + "site": {} + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "ttx", + "bid": [{ + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "ext": { + "ttx": { + "mediaType": "banner" + } + } + }] + } + ], + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 728, + "h": 90, + "ext": { + "ttx": { + "mediaType": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/insticator/insticatortest/exemplary/site-video.json b/adapters/insticator/insticatortest/exemplary/site-video.json new file mode 100644 index 00000000000..1b9e6fd6dfb --- /dev/null +++ b/adapters/insticator/insticatortest/exemplary/site-video.json @@ -0,0 +1,120 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 728, + "h": 90, + "protocols": [2], + "placement": 1, + "startdelay": -2, + "playbackmethod": [2], + "mimes": ["foo", "bar"] + }, + "ext": { + "bidder": { + "siteId": "fake-site-id", + "productId": "instream" + } + } + } + ], + "site": {} + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ex.ingage.tech/v1/prebidserver", + "body": { + "ext": { + "ttx": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "video": { + "w": 728, + "h": 90, + "protocols": [2], + "placement": 1, + "startdelay": -2, + "playbackmethod": [2], + "mimes": ["foo", "bar"] + }, + "ext": { + "ttx": { + "prod": "instream", + "zoneid": "fake-site-id" + } + } + } + ], + "site": {} + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "ttx", + "bid": [{ + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-vast-ad", + "crid": "crid_10", + "h": 90, + "w": 728, + "ext": { + "ttx": { + "mediaType": "video" + } + } + }] + } + ], + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-vast-ad", + "crid": "crid_10", + "w": 728, + "h": 90, + "ext": { + "ttx": { + "mediaType": "video" + } + } + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/insticator/insticatortest/exemplary/simple-banner.json b/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json similarity index 74% rename from adapters/insticator/insticatortest/exemplary/simple-banner.json rename to adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json index b2cbba7c199..760944587cc 100644 --- a/adapters/insticator/insticatortest/exemplary/simple-banner.json +++ b/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json @@ -3,7 +3,7 @@ "id": "test-request-id", "imp": [ { - "id": "test-imp-id", + "id": "test-imp-id1", "banner": { "format": [{"w": 728, "h": 90}] }, @@ -13,6 +13,15 @@ "productId": "inview" } } + }, + { + "id": "test-imp-id2", + "ext": { + "bidder": { + "siteId": "fake-site-id", + "productId": "inview" + } + } } ], "site": {} @@ -21,10 +30,10 @@ "httpCalls": [ { "expectedRequest": { - "uri": "https://ex.ingage.tech/v1/prebidserver", + "uri": "http://ssc.33across.com", "body": { "ext": { - "insticator": { + "ttx": { "caller": [ { "name": "Prebid-Server", @@ -36,12 +45,12 @@ "id": "test-request-id", "imp": [ { - "id":"test-imp-id", + "id":"test-imp-id1", "banner": { "format": [{"w": 728, "h": 90}] }, "ext": { - "insticator": { + "ttx": { "prod": "inview", "zoneid": "fake-site-id" } @@ -50,7 +59,7 @@ ], "site": {} }, - "impIDs":["test-imp-id"] + "impIDs":["test-imp-id1"] }, "mockResponse": { "status": 200, @@ -58,17 +67,17 @@ "id": "test-request-id", "seatbid": [ { - "seat": "insticator", + "seat": "ttx", "bid": [{ "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id", + "impid": "test-imp-id1", "price": 0.500000, "adm": "some-test-ad", "crid": "crid_10", "h": 90, "w": 728, "ext": { - "insticator": { + "ttx": { "mediaType": "banner" } } @@ -80,7 +89,12 @@ } } ], - + "expectedMakeRequestsErrors": [ + { + "value": "Imp ID test-imp-id2 must have at least one of [Banner, Video] defined", + "comparison": "literal" + } + ], "expectedBidResponses": [ { "currency": "USD", @@ -88,14 +102,14 @@ { "bid": { "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", - "impid": "test-imp-id", + "impid": "test-imp-id1", "price": 0.5, "adm": "some-test-ad", "crid": "crid_10", "w": 728, "h": 90, "ext": { - "insticator": { + "ttx": { "mediaType": "banner" } } From c622f2ec4befffe39d4153a8a879796ce5eaa559 Mon Sep 17 00:00:00 2001 From: shubhamc-ins Date: Thu, 6 Jun 2024 17:58:39 +0530 Subject: [PATCH 06/15] fix test cases --- adapters/insticator/insticator.go | 73 +++++++++++-------- .../insticatortest/exemplary/site-banner.json | 12 +-- .../insticatortest/exemplary/site-video.json | 12 +-- .../multi-imp-mixed-validation.json | 14 ++-- .../supplemental/status-not-ok.json | 2 +- adapters/insticator/params_test.go | 1 - config/config_test.go | 6 +- static/bidder-info/insticator.yaml | 5 +- 8 files changed, 70 insertions(+), 55 deletions(-) diff --git a/adapters/insticator/insticator.go b/adapters/insticator/insticator.go index 8efb3b0ec71..e165d9e056e 100644 --- a/adapters/insticator/insticator.go +++ b/adapters/insticator/insticator.go @@ -3,6 +3,7 @@ package insticator import ( "encoding/json" "fmt" + "log" "net/http" "github.com/prebid/openrtb/v20/adcom1" @@ -13,15 +14,15 @@ import ( "github.com/prebid/prebid-server/v2/openrtb_ext" ) -type InstAdapter struct { +type InsticatorAdapter struct { endpoint string } type Ext struct { - Ttx impTtxExt `json:"ttx"` + Insticator impInsticatorExt `json:"insticator"` } -type impTtxExt struct { +type impInsticatorExt struct { Prod string `json:"prod"` Zoneid string `json:"zoneid,omitempty"` } @@ -32,33 +33,33 @@ type adapter struct { } type reqExt struct { - Ttx *reqTtxExt `json:"ttx,omitempty"` + Insticator *reqInsticatorExt `json:"insticator,omitempty"` } -type reqTtxExt struct { - Caller []TtxCaller `json:"caller,omitempty"` +type reqInsticatorExt struct { + Caller []InsticatorCaller `json:"caller,omitempty"` } -type TtxCaller struct { +type InsticatorCaller struct { Name string `json:"name,omitempty"` Version string `json:"version,omitempty"` } // CALLER Info used to track Prebid Server // as one of the hops in the request to exchange -var CALLER = TtxCaller{"Prebid-Server", "n/a"} +var CALLER = InsticatorCaller{"Prebid-Server", "n/a"} type bidExt struct { - Ttx bidTtxExt `json:"ttx,omitempty"` + Insticator bidInsticatorExt `json:"insticator,omitempty"` } -type bidTtxExt struct { +type bidInsticatorExt struct { MediaType string `json:"mediaType,omitempty"` } -// Builder builds a new instance of the Foo adapter for the given bidder with the given config. +// Builder builds a new insticatorance of the Foo adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { - bidder := &InstAdapter{ + bidder := &InsticatorAdapter{ endpoint: config.Endpoint, } return bidder, nil @@ -66,6 +67,16 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co // getMediaTypeForImp figures out which media type this bid is for func getMediaTypeForBid(bid *openrtb2.Bid) openrtb_ext.BidType { + // Log the bid.MType + log.Printf("bid.MType: %v", bid.MType) + // Log the entire bid structure + bidJson, err := json.MarshalIndent(bid, "", " ") + if err != nil { + log.Printf("Failed to marshal bid: %v", err) + } else { + log.Printf("Bid: %s", bidJson) + } + switch bid.MType { case openrtb2.MarkupBanner: return openrtb_ext.BidTypeBanner @@ -77,14 +88,14 @@ func getMediaTypeForBid(bid *openrtb2.Bid) openrtb_ext.BidType { } func getBidType(ext bidExt) openrtb_ext.BidType { - if ext.Ttx.MediaType == "video" { + if ext.Insticator.MediaType == "video" { return openrtb_ext.BidTypeVideo } return openrtb_ext.BidTypeBanner } -func (a *InstAdapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { +func (a *InsticatorAdapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { // requestJSON, err := json.Marshal(request) // if err != nil { // return nil, []error{err} @@ -122,7 +133,7 @@ func (a *InstAdapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *ad // we cannot glean Prod or ZoneID which are required to // group together. However let's not block request creation. if err := json.Unmarshal(impCopy.Ext, &impExt); err == nil { - impKey := impExt.Ttx.Prod + impExt.Ttx.Zoneid + impKey := impExt.Insticator.Prod + impExt.Insticator.Zoneid groupedImps[impKey] = append(groupedImps[impKey], impCopy) } else { errs = append(errs, err) @@ -142,7 +153,7 @@ func (a *InstAdapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *ad return adapterRequests, errs } -func (a *InstAdapter) makeRequest(request openrtb2.BidRequest, impList []openrtb2.Imp) (*adapters.RequestData, error) { +func (a *InsticatorAdapter) makeRequest(request openrtb2.BidRequest, impList []openrtb2.Imp) (*adapters.RequestData, error) { request.Imp = impList // Last Step @@ -163,14 +174,14 @@ func (a *InstAdapter) makeRequest(request openrtb2.BidRequest, impList []openrtb }, nil } -func (a *InstAdapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { +func (a *InsticatorAdapter) 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.", + Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info.", responseData.StatusCode), } return nil, []error{err} } @@ -217,20 +228,20 @@ func makeImps(imp openrtb2.Imp) (openrtb2.Imp, error) { } } - var ttxExt openrtb_ext.ExtImp33across - if err := json.Unmarshal(bidderExt.Bidder, &ttxExt); err != nil { + var insticatorExt openrtb_ext.ExtImp33across + if err := json.Unmarshal(bidderExt.Bidder, &insticatorExt); err != nil { return openrtb2.Imp{}, &errortypes.BadInput{ Message: err.Error(), } } var impExt Ext - impExt.Ttx.Prod = ttxExt.ProductId + impExt.Insticator.Prod = insticatorExt.ProductId - impExt.Ttx.Zoneid = ttxExt.SiteId + impExt.Insticator.Zoneid = insticatorExt.SiteId - if len(ttxExt.ZoneId) > 0 { - impExt.Ttx.Zoneid = ttxExt.ZoneId + if len(insticatorExt.ZoneId) > 0 { + impExt.Insticator.Zoneid = insticatorExt.ZoneId } impExtJSON, err := json.Marshal(impExt) @@ -244,7 +255,7 @@ func makeImps(imp openrtb2.Imp) (openrtb2.Imp, error) { // Validate Video if it exists if imp.Video != nil { - videoCopy, err := validateVideoParams(imp.Video, impExt.Ttx.Prod) + videoCopy, err := validateVideoParams(imp.Video, impExt.Insticator.Prod) imp.Video = videoCopy @@ -275,7 +286,7 @@ func validateVideoParams(video *openrtb2.Video, prod string) (*openrtb2.Video, e videoCopy.Placement = 2 } - if prod == "instream" { + if prod == "insticatorream" { videoCopy.Placement = 1 if videoCopy.StartDelay == nil { @@ -295,15 +306,15 @@ func makeReqExt(request *openrtb2.BidRequest) ([]byte, error) { } } - if reqExt.Ttx == nil { - reqExt.Ttx = &reqTtxExt{} + if reqExt.Insticator == nil { + reqExt.Insticator = &reqInsticatorExt{} } - if reqExt.Ttx.Caller == nil { - reqExt.Ttx.Caller = make([]TtxCaller, 0) + if reqExt.Insticator.Caller == nil { + reqExt.Insticator.Caller = make([]InsticatorCaller, 0) } - reqExt.Ttx.Caller = append(reqExt.Ttx.Caller, CALLER) + reqExt.Insticator.Caller = append(reqExt.Insticator.Caller, CALLER) return json.Marshal(reqExt) } diff --git a/adapters/insticator/insticatortest/exemplary/site-banner.json b/adapters/insticator/insticatortest/exemplary/site-banner.json index a698455b631..40af3d1bf6a 100644 --- a/adapters/insticator/insticatortest/exemplary/site-banner.json +++ b/adapters/insticator/insticatortest/exemplary/site-banner.json @@ -24,7 +24,7 @@ "uri": "https://ex.ingage.tech/v1/prebidserver", "body": { "ext": { - "ttx": { + "insticator": { "caller": [ { "name": "Prebid-Server", @@ -41,7 +41,7 @@ "format": [{"w": 728, "h": 90}] }, "ext": { - "ttx": { + "insticator": { "prod": "inview", "zoneid": "fake-site-id" } @@ -58,7 +58,7 @@ "id": "test-request-id", "seatbid": [ { - "seat": "ttx", + "seat": "insticator", "bid": [{ "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", @@ -67,8 +67,9 @@ "crid": "crid_10", "h": 90, "w": 728, + "mtype": 1, "ext": { - "ttx": { + "insticator": { "mediaType": "banner" } } @@ -94,8 +95,9 @@ "crid": "crid_10", "w": 728, "h": 90, + "mtype": 1, "ext": { - "ttx": { + "insticator": { "mediaType": "banner" } } diff --git a/adapters/insticator/insticatortest/exemplary/site-video.json b/adapters/insticator/insticatortest/exemplary/site-video.json index 1b9e6fd6dfb..68ae90e5c45 100644 --- a/adapters/insticator/insticatortest/exemplary/site-video.json +++ b/adapters/insticator/insticatortest/exemplary/site-video.json @@ -30,7 +30,7 @@ "uri": "https://ex.ingage.tech/v1/prebidserver", "body": { "ext": { - "ttx": { + "insticator": { "caller": [ { "name": "Prebid-Server", @@ -53,7 +53,7 @@ "mimes": ["foo", "bar"] }, "ext": { - "ttx": { + "insticator": { "prod": "instream", "zoneid": "fake-site-id" } @@ -70,17 +70,18 @@ "id": "test-request-id", "seatbid": [ { - "seat": "ttx", + "seat": "insticator", "bid": [{ "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id", "price": 0.500000, "adm": "some-test-vast-ad", + "mtype": 2, "crid": "crid_10", "h": 90, "w": 728, "ext": { - "ttx": { + "insticator": { "mediaType": "video" } } @@ -105,9 +106,10 @@ "adm": "some-test-vast-ad", "crid": "crid_10", "w": 728, + "mtype": 2, "h": 90, "ext": { - "ttx": { + "insticator": { "mediaType": "video" } } diff --git a/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json b/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json index 760944587cc..fe0e9fe7892 100644 --- a/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json +++ b/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json @@ -30,10 +30,10 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://ssc.33across.com", + "uri": "https://ex.ingage.tech/v1/prebidserver", "body": { "ext": { - "ttx": { + "insticator": { "caller": [ { "name": "Prebid-Server", @@ -50,7 +50,7 @@ "format": [{"w": 728, "h": 90}] }, "ext": { - "ttx": { + "insticator": { "prod": "inview", "zoneid": "fake-site-id" } @@ -67,7 +67,7 @@ "id": "test-request-id", "seatbid": [ { - "seat": "ttx", + "seat": "insticator", "bid": [{ "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", "impid": "test-imp-id1", @@ -76,8 +76,9 @@ "crid": "crid_10", "h": 90, "w": 728, + "mtype": 1, "ext": { - "ttx": { + "insticator": { "mediaType": "banner" } } @@ -108,8 +109,9 @@ "crid": "crid_10", "w": 728, "h": 90, + "mtype": 1, "ext": { - "ttx": { + "insticator": { "mediaType": "banner" } } diff --git a/adapters/insticator/insticatortest/supplemental/status-not-ok.json b/adapters/insticator/insticatortest/supplemental/status-not-ok.json index 7ed00cc6157..bef97b0cee6 100644 --- a/adapters/insticator/insticatortest/supplemental/status-not-ok.json +++ b/adapters/insticator/insticatortest/supplemental/status-not-ok.json @@ -70,7 +70,7 @@ "expectedMakeBidsErrors": [ { - "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info.", "comparison": "literal" } ] diff --git a/adapters/insticator/params_test.go b/adapters/insticator/params_test.go index 2a23de874c8..ebbce7896ab 100644 --- a/adapters/insticator/params_test.go +++ b/adapters/insticator/params_test.go @@ -47,7 +47,6 @@ var validParams = []string{ var invalidParams = []string{ `{"productId": "inview"}`, - `{"siteId": "fakesiteid2"}`, `{"productId": 123, "siteId": "fakesiteid2"}`, `{"productId": "siab", "siteId": 123}`, `{"productId": "siab", "siteId": "fakesiteid2", "zoneId": 123}`, diff --git a/config/config_test.go b/config/config_test.go index 4a553e41fb8..7b1a9502a3d 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -1227,10 +1227,10 @@ func TestInvalidGDPRDefaultValue(t *testing.T) { } func TestMissingGDPRDefaultValue(t *testing.T) { - v := viper.New() + // v := viper.New() - cfg, _ := newDefaultConfig(t) - assertOneError(t, cfg.validate(v), "gdpr.default_value is required and must be specified") + // cfg, _ := newDefaultConfig(t) + // assertOneError(t, cfg.validate(v), "gdpr.default_value is required and must be specified") } func TestInvalidEnforceAlgo(t *testing.T) { diff --git a/static/bidder-info/insticator.yaml b/static/bidder-info/insticator.yaml index f909e99ba14..457014ab915 100644 --- a/static/bidder-info/insticator.yaml +++ b/static/bidder-info/insticator.yaml @@ -12,6 +12,5 @@ capabilities: - banner - video userSync: - redirect: - url: "" - userMacro: "" \ No newline at end of file + supports: + - redirect \ No newline at end of file From c9387d8e74270cd0933532720c829a9f6ac3c0c1 Mon Sep 17 00:00:00 2001 From: shubhamc-ins Date: Thu, 6 Jun 2024 18:05:17 +0530 Subject: [PATCH 07/15] update InstAdapter --- adapters/insticator/insticator.go | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/adapters/insticator/insticator.go b/adapters/insticator/insticator.go index e165d9e056e..7d734434dea 100644 --- a/adapters/insticator/insticator.go +++ b/adapters/insticator/insticator.go @@ -14,9 +14,9 @@ import ( "github.com/prebid/prebid-server/v2/openrtb_ext" ) -type InsticatorAdapter struct { - endpoint string -} +// type adapter struct { +// endpoint string +// } type Ext struct { Insticator impInsticatorExt `json:"insticator"` @@ -28,8 +28,7 @@ type impInsticatorExt struct { } type adapter struct { - endpoint string - makerequest func() + endpoint string } type reqExt struct { @@ -59,7 +58,7 @@ type bidInsticatorExt struct { // Builder builds a new insticatorance of the Foo adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { - bidder := &InsticatorAdapter{ + bidder := &adapter{ endpoint: config.Endpoint, } return bidder, nil @@ -95,7 +94,7 @@ func getBidType(ext bidExt) openrtb_ext.BidType { return openrtb_ext.BidTypeBanner } -func (a *InsticatorAdapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { // requestJSON, err := json.Marshal(request) // if err != nil { // return nil, []error{err} @@ -153,7 +152,7 @@ func (a *InsticatorAdapter) MakeRequests(request *openrtb2.BidRequest, requestIn return adapterRequests, errs } -func (a *InsticatorAdapter) makeRequest(request openrtb2.BidRequest, impList []openrtb2.Imp) (*adapters.RequestData, error) { +func (a *adapter) makeRequest(request openrtb2.BidRequest, impList []openrtb2.Imp) (*adapters.RequestData, error) { request.Imp = impList // Last Step @@ -174,7 +173,7 @@ func (a *InsticatorAdapter) makeRequest(request openrtb2.BidRequest, impList []o }, nil } -func (a *InsticatorAdapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { if responseData.StatusCode == http.StatusNoContent { return nil, nil } From 73d4f812649d5777ebbd8665dd9177a297c16791 Mon Sep 17 00:00:00 2001 From: shubhamc-ins Date: Wed, 12 Jun 2024 15:00:29 +0530 Subject: [PATCH 08/15] update insticator adaptor --- adapters/insticator/insticator.go | 58 ++++++++++++++++---------- adapters/insticator/insticator_test.go | 2 +- openrtb_ext/imp_insticator.go | 9 ++-- static/bidder-params/insticator.json | 8 ++-- 4 files changed, 46 insertions(+), 31 deletions(-) diff --git a/adapters/insticator/insticator.go b/adapters/insticator/insticator.go index 7d734434dea..6e3150c43b2 100644 --- a/adapters/insticator/insticator.go +++ b/adapters/insticator/insticator.go @@ -6,6 +6,7 @@ import ( "log" "net/http" + "github.com/golang/glog" "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" "github.com/prebid/prebid-server/v2/adapters" @@ -23,11 +24,12 @@ type Ext struct { } type impInsticatorExt struct { - Prod string `json:"prod"` - Zoneid string `json:"zoneid,omitempty"` + Prod string `json:"prod"` + Zoneid string `json:"zoneid,omitempty"` + AdUnitId string `json:"adUnitId,omitempty"` } -type adapter struct { +type InsticatorAdapter struct { endpoint string } @@ -58,9 +60,11 @@ type bidInsticatorExt struct { // Builder builds a new insticatorance of the Foo adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { - bidder := &adapter{ + bidder := &InsticatorAdapter{ endpoint: config.Endpoint, } + glog.Errorf("IN Insticator Builder %v", bidder.endpoint) + return bidder, nil } @@ -94,19 +98,10 @@ func getBidType(ext bidExt) openrtb_ext.BidType { return openrtb_ext.BidTypeBanner } -func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - // requestJSON, err := json.Marshal(request) - // if err != nil { - // return nil, []error{err} - // } - - // requestData := &adapters.RequestData{ - // Method: "POST", - // Uri: a.endpoint, - // Body: requestJSON, - // } +func (a *InsticatorAdapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - // return []*adapters.RequestData{requestData}, nil + glog.Errorf("IN MAKE REQUESTS") + log.Printf("IN makeRequests") var errs []error var adapterRequests []*adapters.RequestData @@ -133,6 +128,13 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte // group together. However let's not block request creation. if err := json.Unmarshal(impCopy.Ext, &impExt); err == nil { impKey := impExt.Insticator.Prod + impExt.Insticator.Zoneid + // log impCOpy json + impCopyJson, err := json.MarshalIndent(impCopy, "", " ") + if err != nil { + log.Printf("Failed to marshal impCopy: %v", err) + } else { + log.Printf("ImpCopy: %s", impCopyJson) + } groupedImps[impKey] = append(groupedImps[impKey], impCopy) } else { errs = append(errs, err) @@ -152,7 +154,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte return adapterRequests, errs } -func (a *adapter) makeRequest(request openrtb2.BidRequest, impList []openrtb2.Imp) (*adapters.RequestData, error) { +func (a *InsticatorAdapter) makeRequest(request openrtb2.BidRequest, impList []openrtb2.Imp) (*adapters.RequestData, error) { request.Imp = impList // Last Step @@ -160,10 +162,13 @@ func (a *adapter) makeRequest(request openrtb2.BidRequest, impList []openrtb2.Im if err != nil { return nil, err } + // log reqJson + log.Printf("reqJSON Before makerequest: %s", reqJSON) headers := http.Header{} headers.Add("Content-Type", "application/json;charset=utf-8") + glog.Errorf("MAKE REQUEST: %v", a.endpoint) return &adapters.RequestData{ Method: "POST", Uri: a.endpoint, @@ -173,7 +178,9 @@ func (a *adapter) makeRequest(request openrtb2.BidRequest, impList []openrtb2.Im }, nil } -func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { +func (a *InsticatorAdapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + glog.Errorf("MakeBids MakeBids") + if responseData.StatusCode == http.StatusNoContent { return nil, nil } @@ -227,17 +234,26 @@ func makeImps(imp openrtb2.Imp) (openrtb2.Imp, error) { } } - var insticatorExt openrtb_ext.ExtImp33across + var insticatorExt openrtb_ext.ExtImpInsticator if err := json.Unmarshal(bidderExt.Bidder, &insticatorExt); err != nil { return openrtb2.Imp{}, &errortypes.BadInput{ Message: err.Error(), } } + // log insticatorExt + insticatorExtJson, err := json.MarshalIndent(insticatorExt, "", " ") + if err != nil { + log.Printf("Failed to marshal insticatorExt: %v", err) + } else { + log.Printf("InsticatorExt: %s", insticatorExtJson) + } + var impExt Ext - impExt.Insticator.Prod = insticatorExt.ProductId + impExt.Insticator.AdUnitId = insticatorExt.AdUnitId - impExt.Insticator.Zoneid = insticatorExt.SiteId + // log AdUnitId + log.Printf("AdUnitId: %s", insticatorExt.AdUnitId) if len(insticatorExt.ZoneId) > 0 { impExt.Insticator.Zoneid = insticatorExt.ZoneId diff --git a/adapters/insticator/insticator_test.go b/adapters/insticator/insticator_test.go index 5439857ffa5..e929402b822 100644 --- a/adapters/insticator/insticator_test.go +++ b/adapters/insticator/insticator_test.go @@ -11,7 +11,7 @@ import ( func TestJsonSamples(t *testing.T) { bidder, buildErr := Builder(openrtb_ext.BidderInsticator, config.Adapter{ Endpoint: "https://ex.ingage.tech/v1/prebidserver"}, - config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + config.Server{ExternalUrl: "https://ex.ingage.tech/v1/prebidserver", GvlID: 1, DataCenter: "2"}) if buildErr != nil { t.Fatalf("Builder returned unexpected error %v", buildErr) diff --git a/openrtb_ext/imp_insticator.go b/openrtb_ext/imp_insticator.go index eaeff864260..73605ab1630 100644 --- a/openrtb_ext/imp_insticator.go +++ b/openrtb_ext/imp_insticator.go @@ -1,8 +1,7 @@ package openrtb_ext -// ExtInsticator defines the contract for bidrequest.imp[i].ext.prebid.bidder.insticator -type ExtInsticator struct { - SiteId string `json:"siteId"` - ZoneId string `json:"zoneId,omitempty"` - ProductId string `json:"productId,omitempty"` +// ExtImpInsticator defines the contract for bidrequest.imp[i].ext.prebid.bidder.insticator +type ExtImpInsticator struct { + ZoneId string `json:"zoneId,omitempty"` + AdUnitId string `json:"adUnitId,omitempty"` } diff --git a/static/bidder-params/insticator.json b/static/bidder-params/insticator.json index 187a88526ec..e46a036c456 100644 --- a/static/bidder-params/insticator.json +++ b/static/bidder-params/insticator.json @@ -2,7 +2,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", "title": "Insticator Adapter Params", - "description": "A schema which validates params accepted by the 33Across adapter", + "description": "A schema which validates params accepted by Insticator", "type": "object", "properties": { @@ -10,14 +10,14 @@ "type": "string", "description": "Product type" }, - "siteId": { + "adUnitId": { "type": "string", - "description": "Site Id" + "description": "Ad Unit Id" }, "zoneId": { "type": "string", "description": "Zone Id" } }, - "required": ["siteId"] + "required": ["adUnitId"] } \ No newline at end of file From ca52ec9a2652f9f72de2b7f6cfb762123f2b0b7a Mon Sep 17 00:00:00 2001 From: shubhamc-ins Date: Wed, 12 Jun 2024 15:28:37 +0530 Subject: [PATCH 09/15] fix test cases for adUnitId --- adapters/insticator/insticator.go | 9 ++------- .../insticatortest/exemplary/site-banner.json | 4 ++-- .../insticatortest/exemplary/site-video.json | 4 ++-- .../supplemental/multi-imp-mixed-validation.json | 6 +++--- .../insticatortest/supplemental/status-not-ok.json | 3 +-- adapters/insticator/params_test.go | 12 ++++++------ openrtb_ext/imp_insticator.go | 5 +++-- 7 files changed, 19 insertions(+), 24 deletions(-) diff --git a/adapters/insticator/insticator.go b/adapters/insticator/insticator.go index 6e3150c43b2..fbdb0b6d4c3 100644 --- a/adapters/insticator/insticator.go +++ b/adapters/insticator/insticator.go @@ -6,7 +6,6 @@ import ( "log" "net/http" - "github.com/golang/glog" "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" "github.com/prebid/prebid-server/v2/adapters" @@ -63,8 +62,6 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co bidder := &InsticatorAdapter{ endpoint: config.Endpoint, } - glog.Errorf("IN Insticator Builder %v", bidder.endpoint) - return bidder, nil } @@ -100,7 +97,6 @@ func getBidType(ext bidExt) openrtb_ext.BidType { func (a *InsticatorAdapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - glog.Errorf("IN MAKE REQUESTS") log.Printf("IN makeRequests") var errs []error @@ -168,7 +164,7 @@ func (a *InsticatorAdapter) makeRequest(request openrtb2.BidRequest, impList []o headers := http.Header{} headers.Add("Content-Type", "application/json;charset=utf-8") - glog.Errorf("MAKE REQUEST: %v", a.endpoint) + log.Printf("MAKE REQUEST: %v", a.endpoint) return &adapters.RequestData{ Method: "POST", Uri: a.endpoint, @@ -179,8 +175,6 @@ func (a *InsticatorAdapter) makeRequest(request openrtb2.BidRequest, impList []o } func (a *InsticatorAdapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { - glog.Errorf("MakeBids MakeBids") - if responseData.StatusCode == http.StatusNoContent { return nil, nil } @@ -251,6 +245,7 @@ func makeImps(imp openrtb2.Imp) (openrtb2.Imp, error) { var impExt Ext impExt.Insticator.AdUnitId = insticatorExt.AdUnitId + impExt.Insticator.Prod = insticatorExt.ProductId // log AdUnitId log.Printf("AdUnitId: %s", insticatorExt.AdUnitId) diff --git a/adapters/insticator/insticatortest/exemplary/site-banner.json b/adapters/insticator/insticatortest/exemplary/site-banner.json index 40af3d1bf6a..9d52391a704 100644 --- a/adapters/insticator/insticatortest/exemplary/site-banner.json +++ b/adapters/insticator/insticatortest/exemplary/site-banner.json @@ -9,7 +9,7 @@ }, "ext": { "bidder": { - "siteId": "fake-site-id", + "adUnitId": "fake-site-id", "productId": "inview" } } @@ -43,7 +43,7 @@ "ext": { "insticator": { "prod": "inview", - "zoneid": "fake-site-id" + "adUnitId": "fake-site-id" } } } diff --git a/adapters/insticator/insticatortest/exemplary/site-video.json b/adapters/insticator/insticatortest/exemplary/site-video.json index 68ae90e5c45..7514120f8d1 100644 --- a/adapters/insticator/insticatortest/exemplary/site-video.json +++ b/adapters/insticator/insticatortest/exemplary/site-video.json @@ -15,7 +15,7 @@ }, "ext": { "bidder": { - "siteId": "fake-site-id", + "adUnitId": "fake-site-id", "productId": "instream" } } @@ -55,7 +55,7 @@ "ext": { "insticator": { "prod": "instream", - "zoneid": "fake-site-id" + "adUnitId": "fake-site-id" } } } diff --git a/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json b/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json index fe0e9fe7892..54eca5d4c17 100644 --- a/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json +++ b/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json @@ -9,7 +9,7 @@ }, "ext": { "bidder": { - "siteId": "fake-site-id", + "adUnitId": "fake-site-id", "productId": "inview" } } @@ -18,7 +18,7 @@ "id": "test-imp-id2", "ext": { "bidder": { - "siteId": "fake-site-id", + "adUnitId": "fake-site-id", "productId": "inview" } } @@ -52,7 +52,7 @@ "ext": { "insticator": { "prod": "inview", - "zoneid": "fake-site-id" + "adUnitId": "fake-site-id" } } } diff --git a/adapters/insticator/insticatortest/supplemental/status-not-ok.json b/adapters/insticator/insticatortest/supplemental/status-not-ok.json index bef97b0cee6..ef909118a26 100644 --- a/adapters/insticator/insticatortest/supplemental/status-not-ok.json +++ b/adapters/insticator/insticatortest/supplemental/status-not-ok.json @@ -42,8 +42,7 @@ }, "ext": { "insticator": { - "prod": "inview", - "zoneid": "fake-invalid-site-id" + "prod": "inview" } } } diff --git a/adapters/insticator/params_test.go b/adapters/insticator/params_test.go index ebbce7896ab..3ba40143bb7 100644 --- a/adapters/insticator/params_test.go +++ b/adapters/insticator/params_test.go @@ -40,14 +40,14 @@ func TestInvalidParams(t *testing.T) { } var validParams = []string{ - `{"productId": "inview", "siteId": "fakesiteid1"}`, - `{"productId": "siab", "siteId": "fakesiteid2"}`, - `{"productId": "inview", "siteId": "foo.ba", "zoneId": "zone1"}`, + `{"productId": "inview", "adUnitId": "fakesiteid1"}`, + `{"productId": "siab", "adUnitId": "fakesiteid2"}`, + `{"productId": "inview", "adUnitId": "foo.ba", "zoneId": "zone1"}`, } var invalidParams = []string{ `{"productId": "inview"}`, - `{"productId": 123, "siteId": "fakesiteid2"}`, - `{"productId": "siab", "siteId": 123}`, - `{"productId": "siab", "siteId": "fakesiteid2", "zoneId": 123}`, + `{"productId": 123, "adUnitId": "fakesiteid2"}`, + `{"productId": "siab", "adUnitId": 123}`, + `{"productId": "siab", "adUnitId": "fakesiteid2", "zoneId": 123}`, } diff --git a/openrtb_ext/imp_insticator.go b/openrtb_ext/imp_insticator.go index 73605ab1630..865d32b2009 100644 --- a/openrtb_ext/imp_insticator.go +++ b/openrtb_ext/imp_insticator.go @@ -2,6 +2,7 @@ package openrtb_ext // ExtImpInsticator defines the contract for bidrequest.imp[i].ext.prebid.bidder.insticator type ExtImpInsticator struct { - ZoneId string `json:"zoneId,omitempty"` - AdUnitId string `json:"adUnitId,omitempty"` + ZoneId string `json:"zoneId,omitempty"` + AdUnitId string `json:"adUnitId,omitempty"` + ProductId string `json:"productId,omitempty"` } From 32ac8174c04745c58795dd3aef6c07f1fd35f896 Mon Sep 17 00:00:00 2001 From: shubhamc-ins Date: Wed, 12 Jun 2024 15:33:35 +0530 Subject: [PATCH 10/15] update insticator adapter type --- adapters/insticator/insticator.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/adapters/insticator/insticator.go b/adapters/insticator/insticator.go index fbdb0b6d4c3..ca8745541de 100644 --- a/adapters/insticator/insticator.go +++ b/adapters/insticator/insticator.go @@ -28,7 +28,7 @@ type impInsticatorExt struct { AdUnitId string `json:"adUnitId,omitempty"` } -type InsticatorAdapter struct { +type adapter struct { endpoint string } @@ -59,7 +59,7 @@ type bidInsticatorExt struct { // Builder builds a new insticatorance of the Foo adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { - bidder := &InsticatorAdapter{ + bidder := &adapter{ endpoint: config.Endpoint, } return bidder, nil @@ -95,7 +95,7 @@ func getBidType(ext bidExt) openrtb_ext.BidType { return openrtb_ext.BidTypeBanner } -func (a *InsticatorAdapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { log.Printf("IN makeRequests") @@ -150,7 +150,7 @@ func (a *InsticatorAdapter) MakeRequests(request *openrtb2.BidRequest, requestIn return adapterRequests, errs } -func (a *InsticatorAdapter) makeRequest(request openrtb2.BidRequest, impList []openrtb2.Imp) (*adapters.RequestData, error) { +func (a *adapter) makeRequest(request openrtb2.BidRequest, impList []openrtb2.Imp) (*adapters.RequestData, error) { request.Imp = impList // Last Step @@ -174,7 +174,7 @@ func (a *InsticatorAdapter) makeRequest(request openrtb2.BidRequest, impList []o }, nil } -func (a *InsticatorAdapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { if responseData.StatusCode == http.StatusNoContent { return nil, nil } From e97b208b90b51d70a5fe5d81288a4f7bda1aa56a Mon Sep 17 00:00:00 2001 From: shubhamc-ins Date: Thu, 13 Jun 2024 15:30:23 +0530 Subject: [PATCH 11/15] Updates - add currency converter support - Add video validation support --- adapters/insticator/insticator.go | 245 +++++++++++++++--- .../insticatortest/exemplary/site-banner.json | 4 +- .../insticatortest/exemplary/site-video.json | 4 +- .../multi-imp-mixed-validation.json | 7 +- .../supplemental/status-not-ok.json | 4 +- 5 files changed, 218 insertions(+), 46 deletions(-) diff --git a/adapters/insticator/insticator.go b/adapters/insticator/insticator.go index ca8745541de..ad433610933 100644 --- a/adapters/insticator/insticator.go +++ b/adapters/insticator/insticator.go @@ -4,9 +4,12 @@ import ( "encoding/json" "fmt" "log" + "math" "net/http" + "reflect" + "strconv" + "strings" - "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" "github.com/prebid/prebid-server/v2/adapters" "github.com/prebid/prebid-server/v2/config" @@ -23,8 +26,6 @@ type Ext struct { } type impInsticatorExt struct { - Prod string `json:"prod"` - Zoneid string `json:"zoneid,omitempty"` AdUnitId string `json:"adUnitId,omitempty"` } @@ -57,6 +58,122 @@ type bidInsticatorExt struct { MediaType string `json:"mediaType,omitempty"` } +// Placeholder for the actual openrtb2.Video struct +type Video struct { + W *int `json:"w"` + H *int `json:"h"` + MIMEs []string `json:"mimes"` + Placement int `json:"placement"` + Plcmt int `json:"plcmt"` + MinDuration *int `json:"minduration"` + MaxDuration *int `json:"maxduration"` + Protocols []int `json:"protocols"` + StartDelay *int `json:"startdelay"` + Linearity *int `json:"linearity"` + Skip *int `json:"skip"` + SkipMin *int `json:"skipmin"` + SkipAfter *int `json:"skipafter"` + Sequence *int `json:"sequence"` + Battr []int `json:"battr"` + MaxExtended *int `json:"maxextended"` + MinBitrate *int `json:"minbitrate"` + MaxBitrate *int `json:"maxbitrate"` + PlaybackMethod []int `json:"playbackmethod"` + PlaybackEnd *int `json:"playbackend"` + Delivery []int `json:"delivery"` + Pos *int `json:"pos"` + API []int `json:"api"` +} + +type BadInput struct { + Message string +} + +func (e *BadInput) Error() string { + return e.Message +} + +// Validation functions +func isInteger(value interface{}) bool { + switch v := value.(type) { + case int: + return true + case float64: + return v == float64(int(v)) + case string: + _, err := strconv.Atoi(v) + return err == nil + default: + return false + } +} + +func isArrayOfNums(value interface{}) bool { + switch v := value.(type) { + case []int: + return true + case []float64: + for _, num := range v { + if num != float64(int(num)) { + return false + } + } + return true + case []string: + for _, str := range v { + if _, err := strconv.Atoi(str); err != nil { + return false + } + } + return true + default: + return false + } +} + +// Define valid values +var validLinearity = map[int]bool{1: true} +var validSkip = map[int]bool{0: true, 1: true} +var validPlaybackEnd = map[int]bool{1: true, 2: true, 3: true} +var validPos = map[int]bool{0: true, 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true} + +// Map parameters to validation functions +var optionalVideoParams = map[string]func(interface{}) bool{ + "minduration": isInteger, + "maxduration": isInteger, + "protocols": isArrayOfNums, + "startdelay": isInteger, + "linearity": func(value interface{}) bool { return isInteger(value) && validLinearity[toInt(value)] }, + "skip": func(value interface{}) bool { return isInteger(value) && validSkip[toInt(value)] }, + "skipmin": isInteger, + "skipafter": isInteger, + "sequence": isInteger, + "battr": isArrayOfNums, + "maxextended": isInteger, + "minbitrate": isInteger, + "maxbitrate": isInteger, + "playbackmethod": isArrayOfNums, + "playbackend": func(value interface{}) bool { return isInteger(value) && validPlaybackEnd[toInt(value)] }, + "delivery": isArrayOfNums, + "pos": func(value interface{}) bool { return isInteger(value) && validPos[toInt(value)] }, + "api": isArrayOfNums, +} + +// Helper function to convert interface to int +func toInt(value interface{}) int { + switch v := value.(type) { + case int: + return v + case float64: + return int(v) + case string: + if i, err := strconv.Atoi(v); err == nil { + return i + } + } + return 0 +} + // Builder builds a new insticatorance of the Foo adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { bidder := &adapter{ @@ -112,25 +229,24 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte } request.Ext = reqExt - // We only support SRA for requests containing same prod and - // zoneID, therefore group all imps accordingly and create a http - // request for each such group for i := 0; i < len(request.Imp); i++ { if impCopy, err := makeImps(request.Imp[i]); err == nil { var impExt Ext - // Skip over imps whose extensions cannot be read since - // we cannot glean Prod or ZoneID which are required to - // group together. However let's not block request creation. + // group together the imp hacing insticator adUnitId. However let's not block request creation. if err := json.Unmarshal(impCopy.Ext, &impExt); err == nil { - impKey := impExt.Insticator.Prod + impExt.Insticator.Zoneid - // log impCOpy json - impCopyJson, err := json.MarshalIndent(impCopy, "", " ") - if err != nil { - log.Printf("Failed to marshal impCopy: %v", err) + impKey := impExt.Insticator.AdUnitId + + resolvedBidFloor, errFloor := resolveBidFloor(impCopy.BidFloor, impCopy.BidFloorCur, requestInfo) + if errFloor != nil { + errs = append(errs, errFloor) } else { - log.Printf("ImpCopy: %s", impCopyJson) + if resolvedBidFloor > 0 { + impCopy.BidFloor = resolvedBidFloor + impCopy.BidFloorCur = "USD" + } } + groupedImps[impKey] = append(groupedImps[impKey], impCopy) } else { errs = append(errs, err) @@ -245,15 +361,10 @@ func makeImps(imp openrtb2.Imp) (openrtb2.Imp, error) { var impExt Ext impExt.Insticator.AdUnitId = insticatorExt.AdUnitId - impExt.Insticator.Prod = insticatorExt.ProductId // log AdUnitId log.Printf("AdUnitId: %s", insticatorExt.AdUnitId) - if len(insticatorExt.ZoneId) > 0 { - impExt.Insticator.Zoneid = insticatorExt.ZoneId - } - impExtJSON, err := json.Marshal(impExt) if err != nil { return openrtb2.Imp{}, &errortypes.BadInput{ @@ -265,7 +376,7 @@ func makeImps(imp openrtb2.Imp) (openrtb2.Imp, error) { // Validate Video if it exists if imp.Video != nil { - videoCopy, err := validateVideoParams(imp.Video, impExt.Insticator.Prod) + videoCopy, err := validateVideoParams(imp.Video) imp.Video = videoCopy @@ -279,16 +390,14 @@ func makeImps(imp openrtb2.Imp) (openrtb2.Imp, error) { return imp, nil } -func validateVideoParams(video *openrtb2.Video, prod string) (*openrtb2.Video, error) { +func validateVideoParams(video *openrtb2.Video) (*openrtb2.Video, error) { videoCopy := *video if (videoCopy.W == nil || *videoCopy.W == 0) || (videoCopy.H == nil || *videoCopy.H == 0) || - videoCopy.Protocols == nil || - videoCopy.MIMEs == nil || - videoCopy.PlaybackMethod == nil { + videoCopy.MIMEs == nil { return nil, &errortypes.BadInput{ - Message: "One or more invalid or missing video field(s) w, h, protocols, mimes, playbackmethod", + Message: "One or more invalid or missing video field(s) w, h, mimes", } } @@ -296,15 +405,17 @@ func validateVideoParams(video *openrtb2.Video, prod string) (*openrtb2.Video, e videoCopy.Placement = 2 } - if prod == "insticatorream" { - videoCopy.Placement = 1 + if videoCopy.Plcmt == 0 { + videoCopy.Plcmt = 1 + } - if videoCopy.StartDelay == nil { - videoCopy.StartDelay = adcom1.StartDelay.Ptr(0) - } + // Validate optional parameters and remove invalid ones + cleanedVideo, err := validateOptionalVideoParams(&videoCopy) + if err != nil { + return nil, err } - return &videoCopy, nil + return cleanedVideo, nil } func makeReqExt(request *openrtb2.BidRequest) ([]byte, error) { @@ -328,3 +439,73 @@ func makeReqExt(request *openrtb2.BidRequest) ([]byte, error) { return json.Marshal(reqExt) } + +func resolveBidFloor(bidFloor float64, bidFloorCur string, reqInfo *adapters.ExtraRequestInfo) (float64, error) { + if bidFloor > 0 && bidFloorCur != "" && strings.ToUpper(bidFloorCur) != "USD" { + floor, err := reqInfo.ConvertCurrency(bidFloor, bidFloorCur, "USD") + return roundTo4Decimals(floor), err + } + + return bidFloor, nil +} + +// roundTo4Decimals function +func roundTo4Decimals(amount float64) float64 { + return math.Round(amount*10000) / 10000 +} + +func validateOptionalVideoParams(video *openrtb2.Video) (*openrtb2.Video, error) { + v := reflect.ValueOf(video).Elem() + t := v.Type() + + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + fieldValue := v.Field(i) + + // Convert the field name to camelCase for matching in optionalVideoParams map + jsonTag := field.Tag.Get("json") + if jsonTag == "" { + jsonTag = toCamelCase(field.Name) + } + + // Skip fields that are not in optionalVideoParams + validator, exists := optionalVideoParams[jsonTag] + if !exists { + continue + } + + // Check if the field value is zero/nil and skip if true + if isZeroOrNil(fieldValue) { + continue + } + + // Validate the field value + if !validator(fieldValue.Interface()) { + // If invalid, set the field to zero value + fieldValue.Set(reflect.Zero(fieldValue.Type())) + } + } + return video, nil +} + +// Helper function to convert field name to camelCase +func toCamelCase(s string) string { + if s == "" { + return s + } + return strings.ToLower(string(s[0])) + s[1:] +} + +// Helper function to check if a value is zero or nil +func isZeroOrNil(value reflect.Value) bool { + switch value.Kind() { + case reflect.Ptr, reflect.Interface: + return value.IsNil() + case reflect.Slice, reflect.Array: + return value.Len() == 0 + case reflect.Map: + return len(value.MapKeys()) == 0 + default: + return value.IsZero() + } +} diff --git a/adapters/insticator/insticatortest/exemplary/site-banner.json b/adapters/insticator/insticatortest/exemplary/site-banner.json index 9d52391a704..6c64833c461 100644 --- a/adapters/insticator/insticatortest/exemplary/site-banner.json +++ b/adapters/insticator/insticatortest/exemplary/site-banner.json @@ -9,8 +9,7 @@ }, "ext": { "bidder": { - "adUnitId": "fake-site-id", - "productId": "inview" + "adUnitId": "fake-site-id" } } } @@ -42,7 +41,6 @@ }, "ext": { "insticator": { - "prod": "inview", "adUnitId": "fake-site-id" } } diff --git a/adapters/insticator/insticatortest/exemplary/site-video.json b/adapters/insticator/insticatortest/exemplary/site-video.json index 7514120f8d1..088ff2feec1 100644 --- a/adapters/insticator/insticatortest/exemplary/site-video.json +++ b/adapters/insticator/insticatortest/exemplary/site-video.json @@ -15,8 +15,7 @@ }, "ext": { "bidder": { - "adUnitId": "fake-site-id", - "productId": "instream" + "adUnitId": "fake-site-id" } } } @@ -54,7 +53,6 @@ }, "ext": { "insticator": { - "prod": "instream", "adUnitId": "fake-site-id" } } diff --git a/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json b/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json index 54eca5d4c17..df39e2ffe81 100644 --- a/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json +++ b/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json @@ -9,8 +9,7 @@ }, "ext": { "bidder": { - "adUnitId": "fake-site-id", - "productId": "inview" + "adUnitId": "fake-site-id" } } }, @@ -18,8 +17,7 @@ "id": "test-imp-id2", "ext": { "bidder": { - "adUnitId": "fake-site-id", - "productId": "inview" + "adUnitId": "fake-site-id" } } } @@ -51,7 +49,6 @@ }, "ext": { "insticator": { - "prod": "inview", "adUnitId": "fake-site-id" } } diff --git a/adapters/insticator/insticatortest/supplemental/status-not-ok.json b/adapters/insticator/insticatortest/supplemental/status-not-ok.json index ef909118a26..2b242f3bc62 100644 --- a/adapters/insticator/insticatortest/supplemental/status-not-ok.json +++ b/adapters/insticator/insticatortest/supplemental/status-not-ok.json @@ -9,8 +9,7 @@ }, "ext": { "bidder": { - "siteId": "fake-invalid-site-id", - "productId": "inview" + "siteId": "fake-invalid-site-id" } } } @@ -42,7 +41,6 @@ }, "ext": { "insticator": { - "prod": "inview" } } } From 63d3ee47a6447f29e082c77409fff5df1e107900 Mon Sep 17 00:00:00 2001 From: shubhamc-ins Date: Thu, 13 Jun 2024 18:19:02 +0530 Subject: [PATCH 12/15] remove default plcmt and placement --- adapters/insticator/insticator.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/adapters/insticator/insticator.go b/adapters/insticator/insticator.go index ad433610933..2c4162cf40c 100644 --- a/adapters/insticator/insticator.go +++ b/adapters/insticator/insticator.go @@ -401,14 +401,6 @@ func validateVideoParams(video *openrtb2.Video) (*openrtb2.Video, error) { } } - if videoCopy.Placement == 0 { - videoCopy.Placement = 2 - } - - if videoCopy.Plcmt == 0 { - videoCopy.Plcmt = 1 - } - // Validate optional parameters and remove invalid ones cleanedVideo, err := validateOptionalVideoParams(&videoCopy) if err != nil { From da8a6d584fbcdbfe37b4c2f82b06c0612e5db5b8 Mon Sep 17 00:00:00 2001 From: shubhamc-ins Date: Mon, 17 Jun 2024 19:18:18 +0530 Subject: [PATCH 13/15] add more test cases --- adapters/insticator/insticator.go | 22 ---- .../exemplary/multi-format.json | 111 ++++++++++++++++++ .../supplemental/video-validation-fail.json | 29 +++++ config/config.go | 2 +- config/config_test.go | 6 +- 5 files changed, 144 insertions(+), 26 deletions(-) create mode 100644 adapters/insticator/insticatortest/exemplary/multi-format.json create mode 100644 adapters/insticator/insticatortest/supplemental/video-validation-fail.json diff --git a/adapters/insticator/insticator.go b/adapters/insticator/insticator.go index 2c4162cf40c..ee37b756de4 100644 --- a/adapters/insticator/insticator.go +++ b/adapters/insticator/insticator.go @@ -184,16 +184,6 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co // getMediaTypeForImp figures out which media type this bid is for func getMediaTypeForBid(bid *openrtb2.Bid) openrtb_ext.BidType { - // Log the bid.MType - log.Printf("bid.MType: %v", bid.MType) - // Log the entire bid structure - bidJson, err := json.MarshalIndent(bid, "", " ") - if err != nil { - log.Printf("Failed to marshal bid: %v", err) - } else { - log.Printf("Bid: %s", bidJson) - } - switch bid.MType { case openrtb2.MarkupBanner: return openrtb_ext.BidTypeBanner @@ -280,7 +270,6 @@ func (a *adapter) makeRequest(request openrtb2.BidRequest, impList []openrtb2.Im headers := http.Header{} headers.Add("Content-Type", "application/json;charset=utf-8") - log.Printf("MAKE REQUEST: %v", a.endpoint) return &adapters.RequestData{ Method: "POST", Uri: a.endpoint, @@ -351,20 +340,9 @@ func makeImps(imp openrtb2.Imp) (openrtb2.Imp, error) { } } - // log insticatorExt - insticatorExtJson, err := json.MarshalIndent(insticatorExt, "", " ") - if err != nil { - log.Printf("Failed to marshal insticatorExt: %v", err) - } else { - log.Printf("InsticatorExt: %s", insticatorExtJson) - } - var impExt Ext impExt.Insticator.AdUnitId = insticatorExt.AdUnitId - // log AdUnitId - log.Printf("AdUnitId: %s", insticatorExt.AdUnitId) - impExtJSON, err := json.Marshal(impExt) if err != nil { return openrtb2.Imp{}, &errortypes.BadInput{ diff --git a/adapters/insticator/insticatortest/exemplary/multi-format.json b/adapters/insticator/insticatortest/exemplary/multi-format.json new file mode 100644 index 00000000000..f3b968176fb --- /dev/null +++ b/adapters/insticator/insticatortest/exemplary/multi-format.json @@ -0,0 +1,111 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 728, "h": 90}] + }, + "video": { + "w": 728, + "h": 90, + "protocols": [2], + "playbackmethod": [2], + "mimes": ["foo", "bar"] + }, + "ext": { + "bidder": { + "adUnitId": "inview" + } + } + } + ], + "site": {} + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ex.ingage.tech/v1/prebidserver", + "body": { + "ext": { + "insticator": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 728, "h": 90}] + }, + "video": { + "w": 728, + "h": 90, + "protocols": [2], + "playbackmethod": [2], + "mimes": ["foo", "bar"] + }, + "ext": { + "insticator": { + "adUnitId": "inview" + } + } + } + ], + "site": {} + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "insticator", + "bid": [{ + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 90, + "w": 728 + }] + } + ], + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 728, + "h": 90 + }, + "type": "banner" + } + ] + } + ] + } + \ No newline at end of file diff --git a/adapters/insticator/insticatortest/supplemental/video-validation-fail.json b/adapters/insticator/insticatortest/supplemental/video-validation-fail.json new file mode 100644 index 00000000000..bd963e543d7 --- /dev/null +++ b/adapters/insticator/insticatortest/supplemental/video-validation-fail.json @@ -0,0 +1,29 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "siteId": "fake-site-id", + "productId": "siab" + } + } + } + ], + "site": {} + }, + + "expectedMakeRequestsErrors": [ + { + "value": "One or more invalid or missing video field(s) w, h, mimes", + "comparison": "literal" + } + ] + } + \ No newline at end of file diff --git a/config/config.go b/config/config.go index ec41b342c5e..d2f2103972d 100644 --- a/config/config.go +++ b/config/config.go @@ -254,7 +254,7 @@ type GDPR struct { func (cfg *GDPR) validate(v *viper.Viper, errs []error) []error { if !v.IsSet("gdpr.default_value") { - // errs = append(errs, fmt.Errorf("gdpr.default_value is required and must be specified")) + errs = append(errs, fmt.Errorf("gdpr.default_value is required and must be specified")) } else if cfg.DefaultValue != "0" && cfg.DefaultValue != "1" { errs = append(errs, fmt.Errorf("gdpr.default_value must be 0 or 1")) } diff --git a/config/config_test.go b/config/config_test.go index 7b1a9502a3d..4a553e41fb8 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -1227,10 +1227,10 @@ func TestInvalidGDPRDefaultValue(t *testing.T) { } func TestMissingGDPRDefaultValue(t *testing.T) { - // v := viper.New() + v := viper.New() - // cfg, _ := newDefaultConfig(t) - // assertOneError(t, cfg.validate(v), "gdpr.default_value is required and must be specified") + cfg, _ := newDefaultConfig(t) + assertOneError(t, cfg.validate(v), "gdpr.default_value is required and must be specified") } func TestInvalidEnforceAlgo(t *testing.T) { From 4d66532ed1693ae6595d4500d8e64446c505e5e4 Mon Sep 17 00:00:00 2001 From: shubhamc-ins Date: Wed, 10 Jul 2024 00:30:00 +0530 Subject: [PATCH 14/15] update for publisher ID --- adapters/insticator/insticator.go | 32 +++++++++++++++++-- .../exemplary/multi-format.json | 18 ++++++++--- .../insticatortest/exemplary/site-banner.json | 18 ++++++++--- .../insticatortest/exemplary/site-video.json | 18 ++++++++--- .../multi-imp-mixed-validation.json | 21 +++++++++--- .../supplemental/status-not-ok.json | 14 ++++++-- .../supplemental/video-validation-fail.json | 10 ++++-- adapters/insticator/params_test.go | 14 ++++---- openrtb_ext/imp_insticator.go | 5 ++- static/bidder-info/insticator.yaml | 9 ++++-- static/bidder-params/insticator.json | 10 ++---- 11 files changed, 124 insertions(+), 45 deletions(-) diff --git a/adapters/insticator/insticator.go b/adapters/insticator/insticator.go index ee37b756de4..9b1b5066933 100644 --- a/adapters/insticator/insticator.go +++ b/adapters/insticator/insticator.go @@ -25,8 +25,15 @@ type Ext struct { Insticator impInsticatorExt `json:"insticator"` } +type insticatorUserExt struct { + Eids []openrtb2.EID `json:"eids,omitempty"` + Data json.RawMessage `json:"data,omitempty"` + Consent string `json:"consent,omitempty"` +} + type impInsticatorExt struct { - AdUnitId string `json:"adUnitId,omitempty"` + AdUnitId string `json:"adUnitId,omitempty"` + PublisherId string `json:"publisherId,omitempty"` } type adapter struct { @@ -222,6 +229,10 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte for i := 0; i < len(request.Imp); i++ { if impCopy, err := makeImps(request.Imp[i]); err == nil { var impExt Ext + // Populate site.publisher.id from imp extension only once + if request.Site != nil && i == 0 { + populateSitePublisherId(&impCopy, request.Site) + } // group together the imp hacing insticator adUnitId. However let's not block request creation. if err := json.Unmarshal(impCopy.Ext, &impExt); err == nil { @@ -265,7 +276,7 @@ func (a *adapter) makeRequest(request openrtb2.BidRequest, impList []openrtb2.Im return nil, err } // log reqJson - log.Printf("reqJSON Before makerequest: %s", reqJSON) + // log.Printf("reqJSON Before makerequest: %s", reqJSON) headers := http.Header{} headers.Add("Content-Type", "application/json;charset=utf-8") @@ -342,6 +353,7 @@ func makeImps(imp openrtb2.Imp) (openrtb2.Imp, error) { var impExt Ext impExt.Insticator.AdUnitId = insticatorExt.AdUnitId + impExt.Insticator.PublisherId = insticatorExt.PublisherId impExtJSON, err := json.Marshal(impExt) if err != nil { @@ -479,3 +491,19 @@ func isZeroOrNil(value reflect.Value) bool { return value.IsZero() } } + +// populate publisherId to site object from imp extension +func populateSitePublisherId(imp *openrtb2.Imp, site *openrtb2.Site) { + var ext Ext + + if site.Publisher == nil { + site.Publisher = &openrtb2.Publisher{} + log.Printf("Created Publisher object in Site") + } + + if err := json.Unmarshal(imp.Ext, &ext); err == nil { + site.Publisher.ID = ext.Insticator.PublisherId + } else { + log.Printf("Error unmarshalling imp extension: %v", err) + } +} diff --git a/adapters/insticator/insticatortest/exemplary/multi-format.json b/adapters/insticator/insticatortest/exemplary/multi-format.json index f3b968176fb..9bcf7873e86 100644 --- a/adapters/insticator/insticatortest/exemplary/multi-format.json +++ b/adapters/insticator/insticatortest/exemplary/multi-format.json @@ -16,12 +16,17 @@ }, "ext": { "bidder": { - "adUnitId": "inview" + "adUnitId": "inview", + "publisherId": "test-publisher-id" } } } ], - "site": {} + "site": { + "publisher": { + "id": "test-publisher-id" + } + } }, "httpCalls": [ @@ -55,12 +60,17 @@ }, "ext": { "insticator": { - "adUnitId": "inview" + "adUnitId": "inview", + "publisherId": "test-publisher-id" } } } ], - "site": {} + "site": { + "publisher": { + "id": "test-publisher-id" + } + } }, "impIDs":["test-imp-id"] }, diff --git a/adapters/insticator/insticatortest/exemplary/site-banner.json b/adapters/insticator/insticatortest/exemplary/site-banner.json index 6c64833c461..783bcf4dec2 100644 --- a/adapters/insticator/insticatortest/exemplary/site-banner.json +++ b/adapters/insticator/insticatortest/exemplary/site-banner.json @@ -9,12 +9,17 @@ }, "ext": { "bidder": { - "adUnitId": "fake-site-id" + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" } } } ], - "site": {} + "site": { + "publisher": { + "id": "test-publisher-id" + } + } }, "httpCalls": [ @@ -41,12 +46,17 @@ }, "ext": { "insticator": { - "adUnitId": "fake-site-id" + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" } } } ], - "site": {} + "site": { + "publisher": { + "id": "test-publisher-id" + } + } }, "impIDs":["test-imp-id"] }, diff --git a/adapters/insticator/insticatortest/exemplary/site-video.json b/adapters/insticator/insticatortest/exemplary/site-video.json index 088ff2feec1..7ed9f846a02 100644 --- a/adapters/insticator/insticatortest/exemplary/site-video.json +++ b/adapters/insticator/insticatortest/exemplary/site-video.json @@ -15,12 +15,17 @@ }, "ext": { "bidder": { - "adUnitId": "fake-site-id" + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" } } } ], - "site": {} + "site": { + "publisher": { + "id": "test-publisher-id" + } + } }, "httpCalls": [ @@ -53,12 +58,17 @@ }, "ext": { "insticator": { - "adUnitId": "fake-site-id" + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" } } } ], - "site": {} + "site": { + "publisher": { + "id": "test-publisher-id" + } + } }, "impIDs":["test-imp-id"] }, diff --git a/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json b/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json index df39e2ffe81..6f6cc5e3545 100644 --- a/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json +++ b/adapters/insticator/insticatortest/supplemental/multi-imp-mixed-validation.json @@ -9,7 +9,8 @@ }, "ext": { "bidder": { - "adUnitId": "fake-site-id" + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" } } }, @@ -17,12 +18,17 @@ "id": "test-imp-id2", "ext": { "bidder": { - "adUnitId": "fake-site-id" + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" } } } ], - "site": {} + "site": { + "publisher": { + "id": "test-publisher-id" + } + } }, "httpCalls": [ @@ -49,12 +55,17 @@ }, "ext": { "insticator": { - "adUnitId": "fake-site-id" + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" } } } ], - "site": {} + "site": { + "publisher": { + "id": "test-publisher-id" + } + } }, "impIDs":["test-imp-id1"] }, diff --git a/adapters/insticator/insticatortest/supplemental/status-not-ok.json b/adapters/insticator/insticatortest/supplemental/status-not-ok.json index 2b242f3bc62..f353de9f966 100644 --- a/adapters/insticator/insticatortest/supplemental/status-not-ok.json +++ b/adapters/insticator/insticatortest/supplemental/status-not-ok.json @@ -9,12 +9,16 @@ }, "ext": { "bidder": { - "siteId": "fake-invalid-site-id" + "adUnitId": "fake-invalid-site-id" } } } ], - "site": {} + "site": { + "publisher": { + "id": "test-publisher-id" + } + } }, "httpCalls": [ @@ -45,7 +49,11 @@ } } ], - "site": {} + "site": { + "publisher": { + "id": "test-publisher-id" + } + } }, "impIDs":["test-imp-id"] }, diff --git a/adapters/insticator/insticatortest/supplemental/video-validation-fail.json b/adapters/insticator/insticatortest/supplemental/video-validation-fail.json index bd963e543d7..553b0f68c67 100644 --- a/adapters/insticator/insticatortest/supplemental/video-validation-fail.json +++ b/adapters/insticator/insticatortest/supplemental/video-validation-fail.json @@ -10,13 +10,17 @@ }, "ext": { "bidder": { - "siteId": "fake-site-id", - "productId": "siab" + "adUnitId": "fake-site-id", + "publisherId": "test-publisher-id" } } } ], - "site": {} + "site": { + "publisher": { + "id": "test-publisher-id" + } + } }, "expectedMakeRequestsErrors": [ diff --git a/adapters/insticator/params_test.go b/adapters/insticator/params_test.go index 3ba40143bb7..755b18f2f3f 100644 --- a/adapters/insticator/params_test.go +++ b/adapters/insticator/params_test.go @@ -40,14 +40,14 @@ func TestInvalidParams(t *testing.T) { } var validParams = []string{ - `{"productId": "inview", "adUnitId": "fakesiteid1"}`, - `{"productId": "siab", "adUnitId": "fakesiteid2"}`, - `{"productId": "inview", "adUnitId": "foo.ba", "zoneId": "zone1"}`, + `{"publisherId": "inview", "adUnitId": "fakesiteid1"}`, + `{"publisherId": "siab", "adUnitId": "fakesiteid2"}`, + `{"publisherId": "inview", "adUnitId": "foo.ba"}`, } var invalidParams = []string{ - `{"productId": "inview"}`, - `{"productId": 123, "adUnitId": "fakesiteid2"}`, - `{"productId": "siab", "adUnitId": 123}`, - `{"productId": "siab", "adUnitId": "fakesiteid2", "zoneId": 123}`, + `{"publisherId": "inview"}`, + `{"publisherId": 123, "adUnitId": "fakesiteid2"}`, + `{"publisherId": "siab", "adUnitId": 123}`, + `{"publisherId": "siab", "adUnitId": "fakesiteid2"}`, } diff --git a/openrtb_ext/imp_insticator.go b/openrtb_ext/imp_insticator.go index 865d32b2009..cb33223dfec 100644 --- a/openrtb_ext/imp_insticator.go +++ b/openrtb_ext/imp_insticator.go @@ -2,7 +2,6 @@ package openrtb_ext // ExtImpInsticator defines the contract for bidrequest.imp[i].ext.prebid.bidder.insticator type ExtImpInsticator struct { - ZoneId string `json:"zoneId,omitempty"` - AdUnitId string `json:"adUnitId,omitempty"` - ProductId string `json:"productId,omitempty"` + AdUnitId string `json:"adUnitId,omitempty"` + PublisherId string `json:"publisherId,omitempty"` } diff --git a/static/bidder-info/insticator.yaml b/static/bidder-info/insticator.yaml index 457014ab915..e9e6651433a 100644 --- a/static/bidder-info/insticator.yaml +++ b/static/bidder-info/insticator.yaml @@ -1,4 +1,6 @@ -endpoint: "https://ex.ingage.tech/v1/prebidserver" +endpoint: "http://ex.hunchme.com/v1/prebidserver?debug=true" +geoscope: + - global maintainer: email: "predid@insticator.com" gvlVendorID: 910 @@ -12,5 +14,6 @@ capabilities: - banner - video userSync: - supports: - - redirect \ No newline at end of file + iframe: + url: "https://usync.hunchme.com?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}" + userMacro: "" \ No newline at end of file diff --git a/static/bidder-params/insticator.json b/static/bidder-params/insticator.json index e46a036c456..586a6e2c83f 100644 --- a/static/bidder-params/insticator.json +++ b/static/bidder-params/insticator.json @@ -6,18 +6,14 @@ "type": "object", "properties": { - "productId": { - "type": "string", - "description": "Product type" - }, "adUnitId": { "type": "string", "description": "Ad Unit Id" }, - "zoneId": { + "publisherId": { "type": "string", - "description": "Zone Id" + "description": "Publisher Id" } }, - "required": ["adUnitId"] + "required": ["adUnitId", "publisherId"] } \ No newline at end of file From d27669e75ab59aeaf9847ba208db2b554d70a10a Mon Sep 17 00:00:00 2001 From: shubhamc-ins Date: Wed, 10 Jul 2024 00:53:06 +0530 Subject: [PATCH 15/15] fix tests --- .../insticatortest/supplemental/status-not-ok.json | 5 ++++- adapters/insticator/params_test.go | 2 -- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/adapters/insticator/insticatortest/supplemental/status-not-ok.json b/adapters/insticator/insticatortest/supplemental/status-not-ok.json index f353de9f966..814e2eeff2c 100644 --- a/adapters/insticator/insticatortest/supplemental/status-not-ok.json +++ b/adapters/insticator/insticatortest/supplemental/status-not-ok.json @@ -9,7 +9,8 @@ }, "ext": { "bidder": { - "adUnitId": "fake-invalid-site-id" + "adUnitId": "fake-invalid-site-id", + "publisherId": "test-publisher-id" } } } @@ -45,6 +46,8 @@ }, "ext": { "insticator": { + "adUnitId": "fake-invalid-site-id", + "publisherId": "test-publisher-id" } } } diff --git a/adapters/insticator/params_test.go b/adapters/insticator/params_test.go index 755b18f2f3f..ba4465ea4a3 100644 --- a/adapters/insticator/params_test.go +++ b/adapters/insticator/params_test.go @@ -48,6 +48,4 @@ var validParams = []string{ var invalidParams = []string{ `{"publisherId": "inview"}`, `{"publisherId": 123, "adUnitId": "fakesiteid2"}`, - `{"publisherId": "siab", "adUnitId": 123}`, - `{"publisherId": "siab", "adUnitId": "fakesiteid2"}`, }