From fb564dd4ce583745b931780a54d8658c471c307b Mon Sep 17 00:00:00 2001 From: Veronika Solovei Date: Tue, 20 Sep 2022 05:58:40 -0700 Subject: [PATCH] Adapter aliases: moved adapter related configs to bidder.yaml files (#2353) * Adapter aliases: moved adapter related configs to bidder.yaml files * Moved adapter configs from config.go to bidder.yaml files * Removed ymal mappers * Clean up * Initial unit tests fix * Merge with latest master * Unit tests clean up * Added pbs.json or pbs.yaml config support * Fixes and unit tests, added ssyncer merge functions back * Merge fixes * Returned back adapter config set up using env variables * Unit tests fixes * Added test for adapter config overrides from environment variables * Minor improvements * Added more tests fro env variables, fixed mapstructures from bidder info * Code review refactoring * Code review refactoring and merge conflicts fixes * Typo fix Co-authored-by: vsolovei --- config/adapter.go | 80 +-- config/bidderinfo.go | 468 +++++++++++---- config/bidderinfo_test.go | 687 ++++++++++++++++++---- config/bidderinfo_validate_test.go | 161 ----- config/config.go | 242 ++------ config/config_test.go | 337 +++++------ endpoints/events/vtrack.go | 2 +- endpoints/events/vtrack_test.go | 8 +- endpoints/info/bidders.go | 4 +- endpoints/info/bidders_detail.go | 27 +- endpoints/info/bidders_detail_test.go | 204 +++---- endpoints/info/bidders_test.go | 12 +- endpoints/openrtb2/auction_test.go | 3 +- endpoints/openrtb2/test_utils.go | 31 +- exchange/adapter_util.go | 25 +- exchange/adapter_util_test.go | 99 ++-- exchange/bidder_test.go | 2 +- exchange/exchange_test.go | 105 ++-- main.go | 19 +- main_test.go | 10 +- router/router.go | 91 +-- router/router_test.go | 83 --- static/bidder-info/33across.yaml | 1 + static/bidder-info/aax.yaml | 4 +- static/bidder-info/aceex.yaml | 1 + static/bidder-info/acuityads.yaml | 3 +- static/bidder-info/adf.yaml | 1 + static/bidder-info/adform.yaml | 1 + static/bidder-info/adgeneration.yaml | 2 +- static/bidder-info/adhese.yaml | 1 + static/bidder-info/adkernel.yaml | 1 + static/bidder-info/adkernelAdn.yaml | 2 + static/bidder-info/adman.yaml | 2 + static/bidder-info/admixer.yaml | 1 + static/bidder-info/adnuntius.yaml | 1 + static/bidder-info/adocean.yaml | 3 +- static/bidder-info/adoppler.yaml | 1 + static/bidder-info/adot.yaml | 3 +- static/bidder-info/adpone.yaml | 3 +- static/bidder-info/adprime.yaml | 3 +- static/bidder-info/adrino.yaml | 1 + static/bidder-info/adtarget.yaml | 3 +- static/bidder-info/adtelligent.yaml | 3 +- static/bidder-info/adtrgtme.yaml | 3 +- static/bidder-info/advangelists.yaml | 1 + static/bidder-info/adview.yaml | 1 + static/bidder-info/adxcg.yaml | 1 + static/bidder-info/adyoulike.yaml | 1 + static/bidder-info/aja.yaml | 1 + static/bidder-info/algorix.yaml | 1 + static/bidder-info/amx.yaml | 2 + static/bidder-info/andbeyondmedia.yaml | 1 + static/bidder-info/apacdex.yaml | 1 + static/bidder-info/applogy.yaml | 1 + static/bidder-info/appnexus.yaml | 2 + static/bidder-info/audienceNetwork.yaml | 4 +- static/bidder-info/automatad.yaml | 1 + static/bidder-info/avocet.yaml | 1 + static/bidder-info/axonix.yaml | 1 + static/bidder-info/beachfront.yaml | 3 + static/bidder-info/beintoo.yaml | 1 + static/bidder-info/between.yaml | 2 + static/bidder-info/bidmachine.yaml | 3 +- static/bidder-info/bidmyadz.yaml | 1 + static/bidder-info/bidscube.yaml | 2 + static/bidder-info/bizzclick.yaml | 1 + static/bidder-info/bliink.yaml | 3 +- static/bidder-info/blue.yaml | 1 + static/bidder-info/bmtm.yaml | 3 +- static/bidder-info/boldwin.yaml | 1 + static/bidder-info/brightroll.yaml | 1 + static/bidder-info/coinzilla.yaml | 1 + static/bidder-info/colossus.yaml | 3 +- static/bidder-info/compass.yaml | 1 + static/bidder-info/connectad.yaml | 1 + static/bidder-info/consumable.yaml | 1 + static/bidder-info/conversant.yaml | 1 + static/bidder-info/cpmstar.yaml | 3 +- static/bidder-info/criteo.yaml | 3 +- static/bidder-info/datablocks.yaml | 1 + static/bidder-info/decenterads.yaml | 1 + static/bidder-info/deepintent.yaml | 2 + static/bidder-info/dianomi.yaml | 2 + static/bidder-info/dmx.yaml | 3 +- static/bidder-info/e_volution.yaml | 2 + static/bidder-info/emx_digital.yaml | 1 + static/bidder-info/engagebdr.yaml | 1 + static/bidder-info/eplanning.yaml | 1 + static/bidder-info/epom.yaml | 2 + static/bidder-info/gamma.yaml | 3 +- static/bidder-info/gamoshi.yaml | 1 + static/bidder-info/grid.yaml | 1 + static/bidder-info/groupm.yaml | 2 + static/bidder-info/gumgum.yaml | 1 + static/bidder-info/huaweiads.yaml | 4 +- static/bidder-info/impactify.yaml | 1 + static/bidder-info/improvedigital.yaml | 1 + static/bidder-info/infytv.yaml | 1 + static/bidder-info/inmobi.yaml | 2 + static/bidder-info/interactiveoffers.yaml | 1 + static/bidder-info/invibes.yaml | 1 + static/bidder-info/iqzone.yaml | 3 +- static/bidder-info/ix.yaml | 1 + static/bidder-info/janet.yaml | 1 + static/bidder-info/jixie.yaml | 1 + static/bidder-info/kargo.yaml | 1 + static/bidder-info/kayzen.yaml | 1 + static/bidder-info/kidoz.yaml | 1 + static/bidder-info/krushmedia.yaml | 1 + static/bidder-info/kubient.yaml | 1 + static/bidder-info/lockerdome.yaml | 3 +- static/bidder-info/logicad.yaml | 1 + static/bidder-info/lunamedia.yaml | 1 + static/bidder-info/madvertise.yaml | 1 + static/bidder-info/marsmedia.yaml | 1 + static/bidder-info/mediafuse.yaml | 3 +- static/bidder-info/medianet.yaml | 2 + static/bidder-info/mgid.yaml | 2 + static/bidder-info/mobfoxpb.yaml | 1 + static/bidder-info/mobilefuse.yaml | 1 + static/bidder-info/nanointeractive.yaml | 1 + static/bidder-info/nextmillennium.yaml | 1 + static/bidder-info/ninthdecimal.yaml | 1 + static/bidder-info/nobid.yaml | 1 + static/bidder-info/oftmedia.yaml | 1 + static/bidder-info/onetag.yaml | 1 + static/bidder-info/openweb.yaml | 3 +- static/bidder-info/openx.yaml | 2 + static/bidder-info/operaads.yaml | 1 + static/bidder-info/orbidder.yaml | 1 + static/bidder-info/outbrain.yaml | 1 + static/bidder-info/pangle.yaml | 1 + static/bidder-info/pgam.yaml | 1 + static/bidder-info/pubmatic.yaml | 1 + static/bidder-info/pubnative.yaml | 1 + static/bidder-info/pulsepoint.yaml | 1 + static/bidder-info/quantumdex.yaml | 1 + static/bidder-info/revcontent.yaml | 4 +- static/bidder-info/rhythmone.yaml | 3 +- static/bidder-info/richaudience.yaml | 1 + static/bidder-info/rtbhouse.yaml | 1 + static/bidder-info/rubicon.yaml | 2 + static/bidder-info/sa_lunamedia.yaml | 1 + static/bidder-info/seedingAlliance.yaml | 1 + static/bidder-info/sharethrough.yaml | 1 + static/bidder-info/silvermob.yaml | 3 +- static/bidder-info/smaato.yaml | 2 + static/bidder-info/smartadserver.yaml | 3 +- static/bidder-info/smarthub.yaml | 3 +- static/bidder-info/smartrtb.yaml | 2 + static/bidder-info/smartyads.yaml | 1 + static/bidder-info/smilewanted.yaml | 3 +- static/bidder-info/sonobi.yaml | 1 + static/bidder-info/sovrn.yaml | 1 + static/bidder-info/sspBC.yaml | 3 +- static/bidder-info/streamkey.yaml | 1 + static/bidder-info/stroeerCore.yaml | 4 +- static/bidder-info/synacormedia.yaml | 3 +- static/bidder-info/tappx.yaml | 1 + static/bidder-info/telaria.yaml | 3 +- static/bidder-info/trafficgate.yaml | 1 + static/bidder-info/triplelift.yaml | 1 + static/bidder-info/triplelift_native.yaml | 2 + static/bidder-info/trustx.yaml | 3 +- static/bidder-info/ucfunnel.yaml | 1 + static/bidder-info/unicorn.yaml | 3 +- static/bidder-info/unruly.yaml | 3 +- static/bidder-info/valueimpression.yaml | 3 +- static/bidder-info/verizonmedia.yaml | 1 + static/bidder-info/videobyte.yaml | 1 + static/bidder-info/vidoomy.yaml | 1 + static/bidder-info/viewdeos.yaml | 3 +- static/bidder-info/visx.yaml | 1 + static/bidder-info/vrtcal.yaml | 4 +- static/bidder-info/yahoossp.yaml | 1 + static/bidder-info/yeahmobi.yaml | 3 +- static/bidder-info/yieldlab.yaml | 1 + static/bidder-info/yieldmo.yaml | 3 +- static/bidder-info/yieldone.yaml | 1 + static/bidder-info/zeroclickfraud.yaml | 3 +- usersync/syncersbuilder.go | 2 +- usersync/syncersbuilder_test.go | 48 +- 182 files changed, 1629 insertions(+), 1391 deletions(-) delete mode 100644 config/bidderinfo_validate_test.go diff --git a/config/adapter.go b/config/adapter.go index eae47981a70..6a6a5fbef71 100644 --- a/config/adapter.go +++ b/config/adapter.go @@ -1,83 +1,13 @@ package config -import ( - "fmt" - "text/template" - - validator "github.com/asaskevich/govalidator" - "github.com/prebid/prebid-server/macros" -) - type Adapter struct { - Disabled bool `mapstructure:"disabled"` - Endpoint string `mapstructure:"endpoint"` - ExtraAdapterInfo string `mapstructure:"extra_info"` - Syncer *Syncer `mapstructure:"usersync"` - - // needed for backwards compatibility - UserSyncURL string `mapstructure:"usersync_url"` + Endpoint string + ExtraAdapterInfo string // needed for Rubicon - XAPI AdapterXAPI `mapstructure:"xapi"` + XAPI AdapterXAPI // needed for Facebook - PlatformID string `mapstructure:"platform_id"` - AppSecret string `mapstructure:"app_secret"` -} - -type AdapterXAPI struct { - Username string `mapstructure:"username"` - Password string `mapstructure:"password"` - Tracker string `mapstructure:"tracker"` -} - -// validateAdapters validates adapter's endpoint and user sync URL -func validateAdapters(adapterMap map[string]Adapter, errs []error) []error { - for adapterName, adapter := range adapterMap { - if !adapter.Disabled { - errs = validateAdapterEndpoint(adapter.Endpoint, adapterName, errs) - } - } - return errs -} - -var testEndpointTemplateParams = macros.EndpointTemplateParams{ - Host: "anyHost", - PublisherID: "anyPublisherID", - AccountID: "anyAccountID", - ZoneID: "anyZoneID", - SourceId: "anySourceID", - AdUnit: "anyAdUnit", -} - -// validateAdapterEndpoint makes sure that an adapter has a valid endpoint -// associated with it -func validateAdapterEndpoint(endpoint string, adapterName string, errs []error) []error { - if endpoint == "" { - return append(errs, fmt.Errorf("There's no default endpoint available for %s. Calls to this bidder/exchange will fail. "+ - "Please set adapters.%s.endpoint in your app config", adapterName, adapterName)) - } - - // Create endpoint template - endpointTemplate, err := template.New("endpointTemplate").Parse(endpoint) - if err != nil { - return append(errs, fmt.Errorf("Invalid endpoint template: %s for adapter: %s. %v", endpoint, adapterName, err)) - } - // Resolve macros (if any) in the endpoint URL - resolvedEndpoint, err := macros.ResolveMacros(endpointTemplate, testEndpointTemplateParams) - if err != nil { - return append(errs, fmt.Errorf("Unable to resolve endpoint: %s for adapter: %s. %v", endpoint, adapterName, err)) - } - // Validate the resolved endpoint - // - // Validating using both IsURL and IsRequestURL because IsURL allows relative paths - // whereas IsRequestURL requires absolute path but fails to check other valid URL - // format constraints. - // - // For example: IsURL will allow "abcd.com" but IsRequestURL won't - // IsRequestURL will allow "http://http://abcd.com" but IsURL won't - if !validator.IsURL(resolvedEndpoint) || !validator.IsRequestURL(resolvedEndpoint) { - errs = append(errs, fmt.Errorf("The endpoint: %s for %s is not a valid URL", resolvedEndpoint, adapterName)) - } - return errs + PlatformID string + AppSecret string } diff --git a/config/bidderinfo.go b/config/bidderinfo.go index fc307de977d..b4e9e74ec9b 100644 --- a/config/bidderinfo.go +++ b/config/bidderinfo.go @@ -1,9 +1,16 @@ package config import ( + "errors" "fmt" + validator "github.com/asaskevich/govalidator" + "github.com/golang/glog" + "github.com/prebid/prebid-server/macros" + "github.com/prebid/prebid-server/util/sliceutil" "io/ioutil" + "log" "strings" + "text/template" "github.com/prebid/prebid-server/openrtb_ext" "gopkg.in/yaml.v3" @@ -14,46 +21,68 @@ type BidderInfos map[string]BidderInfo // BidderInfo specifies all configuration for a bidder except for enabled status, endpoint, and extra information. type BidderInfo struct { - Enabled bool // copied from adapter config for convenience. to be refactored. - Maintainer *MaintainerInfo `yaml:"maintainer"` - Capabilities *CapabilitiesInfo `yaml:"capabilities"` - ModifyingVastXmlAllowed bool `yaml:"modifyingVastXmlAllowed"` - Debug *DebugInfo `yaml:"debug"` - GVLVendorID uint16 `yaml:"gvlVendorID"` - Syncer *Syncer `yaml:"userSync"` - Experiment BidderInfoExperiment `yaml:"experiment"` - EndpointCompression string `yaml:"endpointCompression"` // EndpointCompression determines, if set, the type of compression the bid request will undergo before being sent to the corresponding bid server + Disabled bool `yaml:"disabled" mapstructure:"disabled"` + Endpoint string `yaml:"endpoint" mapstructure:"endpoint"` + ExtraAdapterInfo string `yaml:"extra_info" mapstructure:"extra_info"` + + Maintainer *MaintainerInfo `yaml:"maintainer" mapstructure:"maintainer"` + Capabilities *CapabilitiesInfo `yaml:"capabilities" mapstructure:"capabilities"` + ModifyingVastXmlAllowed bool `yaml:"modifyingVastXmlAllowed" mapstructure:"modifyingVastXmlAllowed"` + Debug *DebugInfo `yaml:"debug" mapstructure:"debug"` + GVLVendorID uint16 `yaml:"gvlVendorID" mapstructure:"gvlVendorID"` + + Syncer *Syncer `yaml:"userSync" mapstructure:"userSync"` + + Experiment BidderInfoExperiment `yaml:"experiment" mapstructure:"experiment"` + + // needed for backwards compatibility + UserSyncURL string `yaml:"usersync_url" mapstructure:"usersync_url"` + + // needed for Rubicon + XAPI AdapterXAPI `yaml:"xapi" mapstructure:"xapi"` + + // needed for Facebook + PlatformID string `yaml:"platform_id" mapstructure:"platform_id"` + AppSecret string `yaml:"app_secret" mapstructure:"app_secret"` + // EndpointCompression determines, if set, the type of compression the bid request will undergo before being sent to the corresponding bid server + EndpointCompression string `yaml:"endpointCompression" mapstructure:"endpointCompression"` } // BidderInfoExperiment specifies non-production ready feature config for a bidder type BidderInfoExperiment struct { - AdsCert BidderAdsCert `yaml:"adsCert"` + AdsCert BidderAdsCert `yaml:"adsCert" mapstructure:"adsCert"` } // BidderAdsCert enables Call Sign feature for bidder type BidderAdsCert struct { - Enabled bool `yaml:"enabled"` + Enabled bool `yaml:"enabled" mapstructure:"enabled"` } // MaintainerInfo specifies the support email address for a bidder. type MaintainerInfo struct { - Email string `yaml:"email"` + Email string `yaml:"email" mapstructure:"email"` } // CapabilitiesInfo specifies the supported platforms for a bidder. type CapabilitiesInfo struct { - App *PlatformInfo `yaml:"app"` - Site *PlatformInfo `yaml:"site"` + App *PlatformInfo `yaml:"app" mapstructure:"app"` + Site *PlatformInfo `yaml:"site" mapstructure:"site"` } // PlatformInfo specifies the supported media types for a bidder. type PlatformInfo struct { - MediaTypes []openrtb_ext.BidType `yaml:"mediaTypes"` + MediaTypes []openrtb_ext.BidType `yaml:"mediaTypes" mapstructure:"mediaTypes"` } // DebugInfo specifies the supported debug options for a bidder. type DebugInfo struct { - Allow bool `yaml:"allow"` + Allow bool `yaml:"allow" mapstructure:"allow"` +} + +type AdapterXAPI struct { + Username string `yaml:"username" mapstructure:"username"` + Password string `yaml:"password" mapstructure:"password"` + Tracker string `yaml:"tracker" mapstructure:"tracker"` } // Syncer specifies the user sync settings for a bidder. This struct is shared by the account config, @@ -66,7 +95,7 @@ type Syncer struct { // Supports allows bidders to specify which user sync endpoints they support but which don't have // good defaults. Host companies should contact the bidder for the endpoint configuration. Hosts // may not override this value. - Supports []string `yaml:"supports"` + Supports []string `yaml:"supports" mapstructure:"supports"` // IFrame configures an iframe endpoint for user syncing. IFrame *SyncerEndpoint `yaml:"iframe" mapstructure:"iframe"` @@ -82,46 +111,6 @@ type Syncer struct { SupportCORS *bool `yaml:"supportCors" mapstructure:"support_cors"` } -// Override returns a new Syncer object where values in the original are replaced by non-empty/non-default -// values in the override, except for the Supports field which may not be overridden. No changes are made -// to the original or override Syncer. -func (s *Syncer) Override(original *Syncer) *Syncer { - if s == nil && original == nil { - return nil - } - - var copy Syncer - if original != nil { - copy = *original - } - - if s == nil { - return © - } - - if s.Key != "" { - copy.Key = s.Key - } - - if original == nil { - copy.IFrame = s.IFrame.Override(nil) - copy.Redirect = s.Redirect.Override(nil) - } else { - copy.IFrame = s.IFrame.Override(original.IFrame) - copy.Redirect = s.Redirect.Override(original.Redirect) - } - - if s.ExternalURL != "" { - copy.ExternalURL = s.ExternalURL - } - - if s.SupportCORS != nil { - copy.SupportCORS = s.SupportCORS - } - - return © -} - // SyncerEndpoint specifies the configuration of the URL returned by the /cookie_sync endpoint // for a specific bidder. Bidders must specify at least one endpoint configuration to be eligible // for selection during a user sync request. @@ -177,94 +166,349 @@ type SyncerEndpoint struct { UserMacro string `yaml:"userMacro" mapstructure:"user_macro"` } -// Override returns a new SyncerEndpoint object where values in the original are replaced by non-empty/non-default -// values in the override. No changes are made to the original or override SyncerEndpoint. -func (s *SyncerEndpoint) Override(original *SyncerEndpoint) *SyncerEndpoint { - if s == nil && original == nil { - return nil +func (bi BidderInfo) IsEnabled() bool { + return !bi.Disabled +} + +// LoadBidderInfo parses all static/bidder-info/{bidder}.yaml files from the file system. +func LoadBidderInfo(path string) (BidderInfos, error) { + bidderConfigs, err := ioutil.ReadDir(path) + if err != nil { + log.Fatal(err) } - var copy SyncerEndpoint - if original != nil { - copy = *original + infos := BidderInfos{} + + for _, bidderConfig := range bidderConfigs { + if bidderConfig.IsDir() { + continue //ignore directories + } + fileName := bidderConfig.Name() + filePath := fmt.Sprintf("%v/%v", path, fileName) + data, err := ioutil.ReadFile(filePath) + if err != nil { + return nil, err + } + + info := BidderInfo{} + if err := yaml.Unmarshal(data, &info); err != nil { + return nil, fmt.Errorf("error parsing yaml for bidder %s: %v", fileName, err) + } + + bidderName := strings.Split(fileName, ".") + if len(bidderName) == 2 && bidderName[1] == "yaml" { + infos[(bidderName[0])] = info + } } + return infos, nil +} - if s == nil { - return © +// ToGVLVendorIDMap transforms a BidderInfos object to a map of bidder names to GVL id. +// Disabled bidders are omitted from the result. +func (infos BidderInfos) ToGVLVendorIDMap() map[openrtb_ext.BidderName]uint16 { + gvlVendorIds := make(map[openrtb_ext.BidderName]uint16, len(infos)) + for name, info := range infos { + if info.IsEnabled() && info.GVLVendorID != 0 { + gvlVendorIds[openrtb_ext.BidderName(name)] = info.GVLVendorID + } } + return gvlVendorIds +} - if s.URL != "" { - copy.URL = s.URL +// validateBidderInfos validates bidder endpoint, info and syncer data +func (infos BidderInfos) validate(errs []error) []error { + for bidderName, bidder := range infos { + if bidder.IsEnabled() { + errs = validateAdapterEndpoint(bidder.Endpoint, bidderName, errs) + + validateInfoErr := validateInfo(bidder, bidderName) + if validateInfoErr != nil { + errs = append(errs, validateInfoErr) + } + + validateSyncerErr := validateSyncer(bidder) + if validateSyncerErr != nil { + errs = append(errs, validateSyncerErr) + } + } } + return errs +} - if s.RedirectURL != "" { - copy.RedirectURL = s.RedirectURL +var testEndpointTemplateParams = macros.EndpointTemplateParams{ + Host: "anyHost", + PublisherID: "anyPublisherID", + AccountID: "anyAccountID", + ZoneID: "anyZoneID", + SourceId: "anySourceID", + AdUnit: "anyAdUnit", +} + +// validateAdapterEndpoint makes sure that an adapter has a valid endpoint +// associated with it +func validateAdapterEndpoint(endpoint string, bidderName string, errs []error) []error { + if endpoint == "" { + return append(errs, fmt.Errorf("There's no default endpoint available for %s. Calls to this bidder/exchange will fail. "+ + "Please set adapters.%s.endpoint in your app config", bidderName, bidderName)) } - if s.ExternalURL != "" { - copy.ExternalURL = s.ExternalURL + // Create endpoint template + endpointTemplate, err := template.New("endpointTemplate").Parse(endpoint) + if err != nil { + return append(errs, fmt.Errorf("Invalid endpoint template: %s for adapter: %s. %v", endpoint, bidderName, err)) + } + // Resolve macros (if any) in the endpoint URL + resolvedEndpoint, err := macros.ResolveMacros(endpointTemplate, testEndpointTemplateParams) + if err != nil { + return append(errs, fmt.Errorf("Unable to resolve endpoint: %s for adapter: %s. %v", endpoint, bidderName, err)) + } + // Validate the resolved endpoint + // + // Validating using both IsURL and IsRequestURL because IsURL allows relative paths + // whereas IsRequestURL requires absolute path but fails to check other valid URL + // format constraints. + // + // For example: IsURL will allow "abcd.com" but IsRequestURL won't + // IsRequestURL will allow "http://http://abcd.com" but IsURL won't + if !validator.IsURL(resolvedEndpoint) || !validator.IsRequestURL(resolvedEndpoint) { + errs = append(errs, fmt.Errorf("The endpoint: %s for %s is not a valid URL", resolvedEndpoint, bidderName)) } + return errs +} - if s.UserMacro != "" { - copy.UserMacro = s.UserMacro +func validateInfo(info BidderInfo, bidderName string) error { + if err := validateMaintainer(info.Maintainer, bidderName); err != nil { + return err + } + if err := validateCapabilities(info.Capabilities, bidderName); err != nil { + return err } - return © + return nil } -// LoadBidderInfoFromDisk parses all static/bidder-info/{bidder}.yaml files from the file system. -func LoadBidderInfoFromDisk(path string, adapterConfigs map[string]Adapter, bidders []string) (BidderInfos, error) { - reader := infoReaderFromDisk{path} - return loadBidderInfo(reader, adapterConfigs, bidders) +func validateMaintainer(info *MaintainerInfo, bidderName string) error { + if info == nil || info.Email == "" { + return fmt.Errorf("missing required field: maintainer.email for adapter: %s", bidderName) + } + return nil } -func loadBidderInfo(r infoReader, adapterConfigs map[string]Adapter, bidders []string) (BidderInfos, error) { - infos := BidderInfos{} +func validateCapabilities(info *CapabilitiesInfo, bidderName string) error { + if info == nil { + return fmt.Errorf("missing required field: capabilities for adapter: %s", bidderName) + } - for _, bidder := range bidders { - data, err := r.Read(bidder) - if err != nil { - return nil, err + if info.App == nil && info.Site == nil { + return fmt.Errorf("at least one of capabilities.site or capabilities.app must exist for adapter: %s", bidderName) + } + + if info.App != nil { + if err := validatePlatformInfo(info.App); err != nil { + return fmt.Errorf("capabilities.app failed validation: %v for adapter: %s", err, bidderName) } + } - info := BidderInfo{} - if err := yaml.Unmarshal(data, &info); err != nil { - return nil, fmt.Errorf("error parsing yaml for bidder %s: %v", bidder, err) + if info.Site != nil { + if err := validatePlatformInfo(info.Site); err != nil { + return fmt.Errorf("capabilities.site failed validation: %v, for adapter: %s", err, bidderName) } + } + return nil +} - info.Enabled = isEnabledByConfig(adapterConfigs, bidder) - infos[bidder] = info +func validatePlatformInfo(info *PlatformInfo) error { + if len(info.MediaTypes) == 0 { + return errors.New("at least one media type needs to be specified") } - return infos, nil -} + for index, mediaType := range info.MediaTypes { + if mediaType != "banner" && mediaType != "video" && mediaType != "native" && mediaType != "audio" { + return fmt.Errorf("unrecognized media type at index %d: %s", index, mediaType) + } + } -func isEnabledByConfig(adapterConfigs map[string]Adapter, bidderName string) bool { - a, ok := adapterConfigs[strings.ToLower(bidderName)] - return ok && !a.Disabled + return nil } -type infoReader interface { - Read(bidder string) ([]byte, error) +func validateSyncer(bidderInfo BidderInfo) error { + if bidderInfo.Syncer == nil { + return nil + } + + for _, supports := range bidderInfo.Syncer.Supports { + if !strings.EqualFold(supports, "iframe") && !strings.EqualFold(supports, "redirect") { + return fmt.Errorf("syncer could not be created, invalid supported endpoint: %s", supports) + } + } + + return nil } -type infoReaderFromDisk struct { - path string +func applyBidderInfoConfigOverrides(configBidderInfos BidderInfos, fsBidderInfos BidderInfos) (BidderInfos, error) { + for bidderName, bidderInfo := range configBidderInfos { + if fsBidderCfg, exists := fsBidderInfos[bidderName]; exists { + bidderInfo.Syncer = bidderInfo.Syncer.Override(fsBidderCfg.Syncer) + + if bidderInfo.Endpoint == "" && len(fsBidderCfg.Endpoint) > 0 { + bidderInfo.Endpoint = fsBidderCfg.Endpoint + } + if bidderInfo.ExtraAdapterInfo == "" && len(fsBidderCfg.ExtraAdapterInfo) > 0 { + bidderInfo.ExtraAdapterInfo = fsBidderCfg.ExtraAdapterInfo + } + if bidderInfo.Maintainer == nil && fsBidderCfg.Maintainer != nil { + bidderInfo.Maintainer = fsBidderCfg.Maintainer + } + if bidderInfo.Capabilities == nil && fsBidderCfg.Capabilities != nil { + bidderInfo.Capabilities = fsBidderCfg.Capabilities + } + if bidderInfo.Debug == nil && fsBidderCfg.Debug != nil { + bidderInfo.Debug = fsBidderCfg.Debug + } + if bidderInfo.GVLVendorID == 0 && fsBidderCfg.GVLVendorID > 0 { + bidderInfo.GVLVendorID = fsBidderCfg.GVLVendorID + } + if bidderInfo.XAPI.Username == "" && fsBidderCfg.XAPI.Username != "" { + bidderInfo.XAPI.Username = fsBidderCfg.XAPI.Username + } + if bidderInfo.XAPI.Password == "" && fsBidderCfg.XAPI.Password != "" { + bidderInfo.XAPI.Password = fsBidderCfg.XAPI.Password + } + if bidderInfo.XAPI.Tracker == "" && fsBidderCfg.XAPI.Tracker != "" { + bidderInfo.XAPI.Tracker = fsBidderCfg.XAPI.Tracker + } + if bidderInfo.PlatformID == "" && fsBidderCfg.PlatformID != "" { + bidderInfo.PlatformID = fsBidderCfg.PlatformID + } + if bidderInfo.AppSecret == "" && fsBidderCfg.AppSecret != "" { + bidderInfo.AppSecret = fsBidderCfg.AppSecret + } + if bidderInfo.EndpointCompression == "" && fsBidderCfg.EndpointCompression != "" { + bidderInfo.EndpointCompression = fsBidderCfg.EndpointCompression + } + + // validate and try to apply the legacy usersync_url configuration in attempt to provide + // an easier upgrade path. be warned, this will break if the bidder adds a second syncer + // type and will eventually be removed after we've given hosts enough time to upgrade to + // the new config. + if bidderInfo.UserSyncURL != "" { + if fsBidderCfg.Syncer == nil { + return nil, fmt.Errorf("adapters.%s.usersync_url cannot be applied, bidder does not define a user sync", strings.ToLower(bidderName)) + } + + endpointsCount := 0 + if bidderInfo.Syncer.IFrame != nil { + bidderInfo.Syncer.IFrame.URL = bidderInfo.UserSyncURL + endpointsCount++ + } + if bidderInfo.Syncer.Redirect != nil { + bidderInfo.Syncer.Redirect.URL = bidderInfo.UserSyncURL + endpointsCount++ + } + + // use Supports as a hint if there are no good defaults provided + if endpointsCount == 0 { + if sliceutil.ContainsStringIgnoreCase(bidderInfo.Syncer.Supports, "iframe") { + bidderInfo.Syncer.IFrame = &SyncerEndpoint{URL: bidderInfo.UserSyncURL} + endpointsCount++ + } + if sliceutil.ContainsStringIgnoreCase(bidderInfo.Syncer.Supports, "redirect") { + bidderInfo.Syncer.Redirect = &SyncerEndpoint{URL: bidderInfo.UserSyncURL} + endpointsCount++ + } + } + + if endpointsCount == 0 { + return nil, fmt.Errorf("adapters.%s.usersync_url cannot be applied, bidder does not define user sync endpoints and does not define supported endpoints", strings.ToLower(bidderName)) + } + + // if the bidder defines both an iframe and redirect endpoint, we can't be sure which config value to + // override, and it wouldn't be both. this is a fatal configuration error. + if endpointsCount > 1 { + return nil, fmt.Errorf("adapters.%s.usersync_url cannot be applied, bidder defines multiple user sync endpoints or supports multiple endpoints", strings.ToLower(bidderName)) + } + + // provide a warning that this compatibility layer is temporary + glog.Warningf("adapters.%s.usersync_url is deprecated and will be removed in a future version, please update to the latest user sync config values", strings.ToLower(bidderName)) + } + + fsBidderInfos[bidderName] = bidderInfo + } + } + return fsBidderInfos, nil } -func (r infoReaderFromDisk) Read(bidder string) ([]byte, error) { - path := fmt.Sprintf("%v/%v.yaml", r.path, bidder) - return ioutil.ReadFile(path) +// Override returns a new Syncer object where values in the original are replaced by non-empty/non-default +// values in the override, except for the Supports field which may not be overridden. No changes are made +// to the original or override Syncer. +func (s *Syncer) Override(original *Syncer) *Syncer { + if s == nil && original == nil { + return nil + } + + var copy Syncer + if original != nil { + copy = *original + } + + if s == nil { + return © + } + + if s.Key != "" { + copy.Key = s.Key + } + + if original == nil { + copy.IFrame = s.IFrame.Override(nil) + copy.Redirect = s.Redirect.Override(nil) + } else { + copy.IFrame = s.IFrame.Override(original.IFrame) + copy.Redirect = s.Redirect.Override(original.Redirect) + } + + if s.ExternalURL != "" { + copy.ExternalURL = s.ExternalURL + } + + if s.SupportCORS != nil { + copy.SupportCORS = s.SupportCORS + } + + return © } -// ToGVLVendorIDMap transforms a BidderInfos object to a map of bidder names to GVL id. Disabled -// bidders are omitted from the result. -func (infos BidderInfos) ToGVLVendorIDMap() map[openrtb_ext.BidderName]uint16 { - m := make(map[openrtb_ext.BidderName]uint16, len(infos)) - for name, info := range infos { - if info.Enabled && info.GVLVendorID != 0 { - m[openrtb_ext.BidderName(name)] = info.GVLVendorID - } +// Override returns a new SyncerEndpoint object where values in the original are replaced by non-empty/non-default +// values in the override. No changes are made to the original or override SyncerEndpoint. +func (s *SyncerEndpoint) Override(original *SyncerEndpoint) *SyncerEndpoint { + if s == nil && original == nil { + return nil + } + + var copy SyncerEndpoint + if original != nil { + copy = *original + } + + if s == nil { + return © + } + + if s.URL != "" { + copy.URL = s.URL + } + + if s.RedirectURL != "" { + copy.RedirectURL = s.RedirectURL + } + + if s.ExternalURL != "" { + copy.ExternalURL = s.ExternalURL } - return m + + if s.UserMacro != "" { + copy.UserMacro = s.UserMacro + } + + return © } diff --git a/config/bidderinfo_test.go b/config/bidderinfo_test.go index b59f87dc802..ffc73edc443 100644 --- a/config/bidderinfo_test.go +++ b/config/bidderinfo_test.go @@ -2,6 +2,7 @@ package config import ( "errors" + "gopkg.in/yaml.v3" "strings" "testing" @@ -10,11 +11,6 @@ import ( ) const testInfoFilesPath = "./test/bidder-info" -const testSimpleYAML = ` -maintainer: - email: "some-email@domain.com" -gvlVendorID: 42 -` const fullBidderYAMLConfig = ` maintainer: email: "some-email@domain.com" @@ -33,19 +29,6 @@ modifyingVastXmlAllowed: true debug: allow: true gvlVendorID: 42 -userSync: - iframe: - url: "someURL" - userMacro: "aValue" - redirect: - url: "anotherURL" - userMacro: "anotherValue" - key: "aKey" - supports: - - item - - item2 - externalUrl: oneMoreUrl - supportCors: true experiment: adsCert: enabled: true @@ -59,14 +42,14 @@ func TestLoadBidderInfoFromDisk(t *testing.T) { adapterConfigs := make(map[string]Adapter) adapterConfigs[strings.ToLower(bidder)] = Adapter{} - infos, err := LoadBidderInfoFromDisk(testInfoFilesPath, adapterConfigs, []string{bidder}) + infos, err := LoadBidderInfo(testInfoFilesPath) if err != nil { t.Fatal(err) } expected := BidderInfos{ bidder: { - Enabled: true, + Disabled: false, Maintainer: &MaintainerInfo{ Email: "some-email@domain.com", }, @@ -100,98 +83,380 @@ func TestLoadBidderInfoFromDisk(t *testing.T) { assert.Equal(t, expected, infos) } -func TestLoadBidderInfo(t *testing.T) { - bidder := "someBidder" // important to be mixed case for tests +func TestToGVLVendorIDMap(t *testing.T) { + givenBidderInfos := BidderInfos{ + "bidderA": BidderInfo{Disabled: false, GVLVendorID: 0}, + "bidderB": BidderInfo{Disabled: false, GVLVendorID: 100}, + "bidderC": BidderInfo{Disabled: true, GVLVendorID: 0}, + "bidderD": BidderInfo{Disabled: true, GVLVendorID: 200}, + } + + expectedGVLVendorIDMap := map[openrtb_ext.BidderName]uint16{ + "bidderB": 100, + } + + result := givenBidderInfos.ToGVLVendorIDMap() + assert.Equal(t, expectedGVLVendorIDMap, result) +} + +const bidderInfoRelativePath = "../static/bidder-info" + +// TestBidderInfoFiles ensures each bidder has a valid static/bidder-info/bidder.yaml file. Validation is performed directly +// against the file system with separate yaml unmarshalling from the LoadBidderInfo func. +func TestBidderInfoFiles(t *testing.T) { + _, err := LoadBidderInfo(bidderInfoRelativePath) + if err != nil { + assert.Fail(t, err.Error(), "Errors in bidder info files") + } +} + +func TestBidderInfoValidationPositive(t *testing.T) { + bidderInfos := BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + PlatformID: "A", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + GVLVendorID: 1, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + openrtb_ext.BidTypeNative, + openrtb_ext.BidTypeBanner, + }, + }, + }, + Syncer: &Syncer{ + Key: "bidderAkey", + Redirect: &SyncerEndpoint{ + URL: "http://bidderA.com/usersync", + UserMacro: "UID", + }, + }, + }, + "bidderB": BidderInfo{ + Endpoint: "http://bidderB.com/openrtb2", + PlatformID: "B", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + GVLVendorID: 2, + Capabilities: &CapabilitiesInfo{ + Site: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + openrtb_ext.BidTypeNative, + openrtb_ext.BidTypeBanner, + }, + }, + }, + Syncer: &Syncer{ + Key: "bidderBkey", + Redirect: &SyncerEndpoint{ + URL: "http://bidderB.com/usersync", + UserMacro: "UID", + }, + }, + }, + } + errs := bidderInfos.validate(make([]error, 0)) + assert.Len(t, errs, 0, "All bidder infos should be correct") +} +func TestBidderInfoValidationNegative(t *testing.T) { testCases := []struct { - description string - givenConfigs map[string]Adapter - givenContent string - givenError error - expectedInfo BidderInfos - expectedError string + description string + bidderInfos BidderInfos + expectErrors []error }{ { - description: "Enabled", - givenConfigs: map[string]Adapter{strings.ToLower(bidder): {}}, - givenContent: testSimpleYAML, - expectedInfo: map[string]BidderInfo{ - bidder: { - Enabled: true, + "One bidder incorrect url", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "incorrect", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, + }, + }, + }, + []error{ + errors.New("The endpoint: incorrect for bidderA is not a valid URL"), + }, + }, + { + "One bidder empty url", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, + }, + }, + }, + []error{ + errors.New("There's no default endpoint available for bidderA. Calls to this bidder/exchange will fail. Please set adapters.bidderA.endpoint in your app config"), + }, + }, + { + "One bidder incorrect url template", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2/getuid?{{.incorrect}}", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, + }, + }, + }, + []error{ + errors.New("Unable to resolve endpoint: http://bidderA.com/openrtb2/getuid?{{.incorrect}} for adapter: bidderA. template: endpointTemplate:1:37: executing \"endpointTemplate\" at <.incorrect>: can't evaluate field incorrect in type macros.EndpointTemplateParams"), + }, + }, + { + "One bidder incorrect url template parameters", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2/getuid?r=[{{.]RedirectURL}}", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, + }, + }, + }, + []error{ + errors.New("Invalid endpoint template: http://bidderA.com/openrtb2/getuid?r=[{{.]RedirectURL}} for adapter: bidderA. template: endpointTemplate:1: bad character U+005D ']'"), + }, + }, + { + "One bidder no maintainer", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, + }, + }, + }, + []error{ + errors.New("missing required field: maintainer.email for adapter: bidderA"), + }, + }, + { + "One bidder missing maintainer email", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", Maintainer: &MaintainerInfo{ - Email: "some-email@domain.com", + Email: "", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, }, - GVLVendorID: 42, }, }, + []error{ + errors.New("missing required field: maintainer.email for adapter: bidderA"), + }, }, { - description: "Disabled - Bidder Not Configured", - givenConfigs: map[string]Adapter{}, - givenContent: testSimpleYAML, - expectedInfo: map[string]BidderInfo{ - bidder: { - Enabled: false, + "One bidder missing capabilities", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", Maintainer: &MaintainerInfo{ - Email: "some-email@domain.com", + Email: "maintainer@bidderA.com", }, - GVLVendorID: 42, }, }, + []error{ + errors.New("missing required field: capabilities for adapter: bidderA"), + }, }, { - description: "Disabled - Bidder Wrong Case", - givenConfigs: map[string]Adapter{bidder: {}}, - givenContent: testSimpleYAML, - expectedInfo: map[string]BidderInfo{ - bidder: { - Enabled: false, + "One bidder missing capabilities site and app", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", Maintainer: &MaintainerInfo{ - Email: "some-email@domain.com", + Email: "maintainer@bidderA.com", }, - GVLVendorID: 42, + Capabilities: &CapabilitiesInfo{}, }, }, + []error{ + errors.New("at least one of capabilities.site or capabilities.app must exist for adapter: bidderA"), + }, }, { - description: "Disabled - Explicitly Configured", - givenConfigs: map[string]Adapter{strings.ToLower(bidder): {Disabled: false}}, - givenContent: testSimpleYAML, - expectedInfo: map[string]BidderInfo{ - bidder: { - Enabled: true, + "One bidder incorrect capabilities for app", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", Maintainer: &MaintainerInfo{ - Email: "some-email@domain.com", + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + "incorrect", + }, + }, }, - GVLVendorID: 42, }, }, + []error{ + errors.New("capabilities.app failed validation: unrecognized media type at index 0: incorrect for adapter: bidderA"), + }, + }, + { + "One bidder nil capabilities", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: nil, + }, + }, + []error{ + errors.New("missing required field: capabilities for adapter: bidderA"), + }, + }, + { + "One bidder invalid syncer", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "http://bidderA.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + Site: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, + }, + Syncer: &Syncer{ + Supports: []string{"incorrect"}, + }, + }, + }, + []error{ + errors.New("syncer could not be created, invalid supported endpoint: incorrect"), + }, }, { - description: "Read Error", - givenConfigs: map[string]Adapter{strings.ToLower(bidder): {}}, - givenError: errors.New("any read error"), - expectedError: "any read error", + "Two bidders, one with incorrect url", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "incorrect", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, + }, + }, + "bidderB": BidderInfo{ + Endpoint: "http://bidderB.com/openrtb2", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderB.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, + }, + }, + }, + []error{ + errors.New("The endpoint: incorrect for bidderA is not a valid URL"), + }, }, { - description: "Unmarshal Error", - givenConfigs: map[string]Adapter{strings.ToLower(bidder): {}}, - givenContent: "invalid yaml", - expectedError: "error parsing yaml for bidder someBidder: yaml: unmarshal errors:\n line 1: cannot unmarshal !!str `invalid...` into config.BidderInfo", + "Two bidders, both with incorrect url", + BidderInfos{ + "bidderA": BidderInfo{ + Endpoint: "incorrect", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderA.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, + }, + }, + "bidderB": BidderInfo{ + Endpoint: "incorrect", + Maintainer: &MaintainerInfo{ + Email: "maintainer@bidderB.com", + }, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{ + openrtb_ext.BidTypeVideo, + }, + }, + }, + }, + }, + []error{ + errors.New("The endpoint: incorrect for bidderA is not a valid URL"), + errors.New("The endpoint: incorrect for bidderB is not a valid URL"), + }, }, } for _, test := range testCases { - r := fakeInfoReader{test.givenContent, test.givenError} - info, err := loadBidderInfo(r, test.givenConfigs, []string{bidder}) - - if test.expectedError == "" { - assert.NoError(t, err, test.description) - } else { - assert.EqualError(t, err, test.expectedError, test.description) - } - - assert.Equal(t, test.expectedInfo, info, test.description) + errs := test.bidderInfos.validate(make([]error, 0)) + assert.ElementsMatch(t, errs, test.expectErrors, "incorrect errors returned for test: %s", test.description) } } @@ -356,41 +621,250 @@ func TestSyncerEndpointOverride(t *testing.T) { } } -type fakeInfoReader struct { - content string - err error -} +func TestApplyBidderInfoConfigSyncerOverrides(t *testing.T) { + var testCases = []struct { + description string + givenFsBidderInfos BidderInfos + givenConfigBidderInfos BidderInfos + expectedError string + expectedBidderInfos BidderInfos + }{ + { + description: "Syncer Override", + givenFsBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "original"}}}, + givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "UserSyncURL Override IFrame", + givenFsBidderInfos: BidderInfos{"a": {Syncer: &Syncer{IFrame: &SyncerEndpoint{URL: "original"}}}}, + givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}}, + expectedBidderInfos: BidderInfos{"a": {UserSyncURL: "override", Syncer: &Syncer{IFrame: &SyncerEndpoint{URL: "override"}}}}, + }, + { + description: "UserSyncURL Supports IFrame", + givenFsBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Supports: []string{"iframe"}}}}, + givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}}, + expectedBidderInfos: BidderInfos{"a": {UserSyncURL: "override", Syncer: &Syncer{Supports: []string{"iframe"}, IFrame: &SyncerEndpoint{URL: "override"}}}}, + }, + { + description: "UserSyncURL Override Redirect", + givenFsBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Supports: []string{"redirect"}}}}, + givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}}, + expectedBidderInfos: BidderInfos{"a": {UserSyncURL: "override", Syncer: &Syncer{Supports: []string{"redirect"}, Redirect: &SyncerEndpoint{URL: "override"}}}}, + }, + { + description: "UserSyncURL Supports Redirect", + givenFsBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Redirect: &SyncerEndpoint{URL: "original"}}}}, + givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}}, + expectedBidderInfos: BidderInfos{"a": {UserSyncURL: "override", Syncer: &Syncer{Redirect: &SyncerEndpoint{URL: "override"}}}}, + }, + { + description: "UserSyncURL Override Syncer Not Defined", + givenFsBidderInfos: BidderInfos{"a": {}}, + givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}}, + expectedError: "adapters.a.usersync_url cannot be applied, bidder does not define a user sync", + }, + { + description: "UserSyncURL Override Syncer Endpoints Not Defined", + givenFsBidderInfos: BidderInfos{"a": {Syncer: &Syncer{}}}, + givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}}, + expectedError: "adapters.a.usersync_url cannot be applied, bidder does not define user sync endpoints and does not define supported endpoints", + }, + { + description: "UserSyncURL Override Ambiguous", + givenFsBidderInfos: BidderInfos{"a": {Syncer: &Syncer{IFrame: &SyncerEndpoint{URL: "originalIFrame"}, Redirect: &SyncerEndpoint{URL: "originalRedirect"}}}}, + givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}}, + expectedError: "adapters.a.usersync_url cannot be applied, bidder defines multiple user sync endpoints or supports multiple endpoints", + }, + { + description: "UserSyncURL Supports Ambiguous", + givenFsBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Supports: []string{"iframe", "redirect"}}}}, + givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}}, + expectedError: "adapters.a.usersync_url cannot be applied, bidder defines multiple user sync endpoints or supports multiple endpoints", + }, + } -func (r fakeInfoReader) Read(bidder string) ([]byte, error) { - return []byte(r.content), r.err + for _, test := range testCases { + bidderInfos, resultErr := applyBidderInfoConfigOverrides(test.givenConfigBidderInfos, test.givenFsBidderInfos) + if test.expectedError == "" { + assert.NoError(t, resultErr, test.description+":err") + assert.Equal(t, test.expectedBidderInfos, bidderInfos, test.description+":result") + } else { + assert.EqualError(t, resultErr, test.expectedError, test.description+":err") + } + } } -func TestToGVLVendorIDMap(t *testing.T) { - givenBidderInfos := BidderInfos{ - "bidderA": BidderInfo{Enabled: true, GVLVendorID: 0}, - "bidderB": BidderInfo{Enabled: true, GVLVendorID: 100}, - "bidderC": BidderInfo{Enabled: false, GVLVendorID: 0}, - "bidderD": BidderInfo{Enabled: false, GVLVendorID: 200}, +func TestApplyBidderInfoConfigOverrides(t *testing.T) { + var testCases = []struct { + description string + givenFsBidderInfos BidderInfos + givenConfigBidderInfos BidderInfos + expectedError string + expectedBidderInfos BidderInfos + }{ + { + description: "Don't override endpoint", + givenFsBidderInfos: BidderInfos{"a": {Endpoint: "original"}}, + givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": {Endpoint: "original", Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Override endpoint", + givenFsBidderInfos: BidderInfos{"a": {Endpoint: "original"}}, + givenConfigBidderInfos: BidderInfos{"a": {Endpoint: "override", Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": {Endpoint: "override", Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Don't override ExtraAdapterInfo", + givenFsBidderInfos: BidderInfos{"a": {ExtraAdapterInfo: "original"}}, + givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": {ExtraAdapterInfo: "original", Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Override ExtraAdapterInfo", + givenFsBidderInfos: BidderInfos{"a": {ExtraAdapterInfo: "original"}}, + givenConfigBidderInfos: BidderInfos{"a": {ExtraAdapterInfo: "override", Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": {ExtraAdapterInfo: "override", Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Don't override Maintainer", + givenFsBidderInfos: BidderInfos{"a": {Maintainer: &MaintainerInfo{Email: "original"}}}, + givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": {Maintainer: &MaintainerInfo{Email: "original"}, Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Override maintainer", + givenFsBidderInfos: BidderInfos{"a": {Maintainer: &MaintainerInfo{Email: "original"}}}, + givenConfigBidderInfos: BidderInfos{"a": {Maintainer: &MaintainerInfo{Email: "override"}, Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": {Maintainer: &MaintainerInfo{Email: "override"}, Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Don't override Capabilities", + givenFsBidderInfos: BidderInfos{"a": { + Capabilities: &CapabilitiesInfo{App: &PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeVideo}}}, + }}, + givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": { + Syncer: &Syncer{Key: "override"}, + Capabilities: &CapabilitiesInfo{App: &PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeVideo}}}, + }}, + }, + { + description: "Override Capabilities", + givenFsBidderInfos: BidderInfos{"a": { + Capabilities: &CapabilitiesInfo{App: &PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeVideo}}}, + }}, + givenConfigBidderInfos: BidderInfos{"a": { + Syncer: &Syncer{Key: "override"}, + Capabilities: &CapabilitiesInfo{App: &PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}}}, + }}, + expectedBidderInfos: BidderInfos{"a": { + Syncer: &Syncer{Key: "override"}, + Capabilities: &CapabilitiesInfo{App: &PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}}}, + }}, + }, + { + description: "Don't override Debug", + givenFsBidderInfos: BidderInfos{"a": {Debug: &DebugInfo{Allow: true}}}, + givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": {Debug: &DebugInfo{Allow: true}, Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Override Debug", + givenFsBidderInfos: BidderInfos{"a": {Debug: &DebugInfo{Allow: true}}}, + givenConfigBidderInfos: BidderInfos{"a": {Debug: &DebugInfo{Allow: false}, Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": {Debug: &DebugInfo{Allow: false}, Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Don't override GVLVendorID", + givenFsBidderInfos: BidderInfos{"a": {GVLVendorID: 5}}, + givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": {GVLVendorID: 5, Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Override GVLVendorID", + givenFsBidderInfos: BidderInfos{"a": {}}, + givenConfigBidderInfos: BidderInfos{"a": {GVLVendorID: 5, Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": {GVLVendorID: 5, Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Don't override XAPI", + givenFsBidderInfos: BidderInfos{"a": { + XAPI: AdapterXAPI{Username: "username1", Password: "password2", Tracker: "tracker3"}, + }}, + givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": { + XAPI: AdapterXAPI{Username: "username1", Password: "password2", Tracker: "tracker3"}, + Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Override XAPI", + givenFsBidderInfos: BidderInfos{"a": { + XAPI: AdapterXAPI{Username: "username", Password: "password", Tracker: "tracker"}}}, + givenConfigBidderInfos: BidderInfos{"a": { + XAPI: AdapterXAPI{Username: "username1", Password: "password2", Tracker: "tracker3"}, + Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": { + XAPI: AdapterXAPI{Username: "username1", Password: "password2", Tracker: "tracker3"}, + Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Don't override PlatformID", + givenFsBidderInfos: BidderInfos{"a": {PlatformID: "PlatformID"}}, + givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": {PlatformID: "PlatformID", Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Override PlatformID", + givenFsBidderInfos: BidderInfos{"a": {PlatformID: "PlatformID1"}}, + givenConfigBidderInfos: BidderInfos{"a": {PlatformID: "PlatformID2", Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": {PlatformID: "PlatformID2", Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Don't override AppSecret", + givenFsBidderInfos: BidderInfos{"a": {AppSecret: "AppSecret"}}, + givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": {AppSecret: "AppSecret", Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Override AppSecret", + givenFsBidderInfos: BidderInfos{"a": {AppSecret: "AppSecret1"}}, + givenConfigBidderInfos: BidderInfos{"a": {AppSecret: "AppSecret2", Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": {AppSecret: "AppSecret2", Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Don't override EndpointCompression", + givenFsBidderInfos: BidderInfos{"a": {EndpointCompression: "GZIP"}}, + givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": {EndpointCompression: "GZIP", Syncer: &Syncer{Key: "override"}}}, + }, + { + description: "Override EndpointCompression", + givenFsBidderInfos: BidderInfos{"a": {EndpointCompression: "GZIP"}}, + givenConfigBidderInfos: BidderInfos{"a": {EndpointCompression: "LZ77", Syncer: &Syncer{Key: "override"}}}, + expectedBidderInfos: BidderInfos{"a": {EndpointCompression: "LZ77", Syncer: &Syncer{Key: "override"}}}, + }, } - - expectedGVLVendorIDMap := map[openrtb_ext.BidderName]uint16{ - "bidderB": 100, + for _, test := range testCases { + bidderInfos, resultErr := applyBidderInfoConfigOverrides(test.givenConfigBidderInfos, test.givenFsBidderInfos) + assert.NoError(t, resultErr, test.description+":err") + assert.Equal(t, test.expectedBidderInfos, bidderInfos, test.description+":result") } - - result := givenBidderInfos.ToGVLVendorIDMap() - assert.Equal(t, expectedGVLVendorIDMap, result) } func TestReadFullYamlBidderConfig(t *testing.T) { bidder := "someBidder" - trueValue := true - r := fakeInfoReader{fullBidderYAMLConfig, nil} - actualBidderInfo, err := loadBidderInfo(r, map[string]Adapter{strings.ToLower(bidder): {}}, []string{bidder}) + bidderInf := BidderInfo{} + err := yaml.Unmarshal([]byte(fullBidderYAMLConfig), &bidderInf) + actualBidderInfo, err := applyBidderInfoConfigOverrides(BidderInfos{bidder: bidderInf}, BidderInfos{bidder: {Syncer: &Syncer{Supports: []string{"iframe"}}}}) + assert.NoError(t, err, "Error wasn't expected") expectedBidderInfo := BidderInfos{ bidder: { - Enabled: true, + Disabled: false, Maintainer: &MaintainerInfo{ Email: "some-email@domain.com", }, @@ -406,18 +880,7 @@ func TestReadFullYamlBidderConfig(t *testing.T) { Debug: &DebugInfo{Allow: true}, ModifyingVastXmlAllowed: true, Syncer: &Syncer{ - Key: "aKey", - IFrame: &SyncerEndpoint{ - URL: "someURL", - UserMacro: "aValue", - }, - Redirect: &SyncerEndpoint{ - URL: "anotherURL", - UserMacro: "anotherValue", - }, - Supports: []string{"item", "item2"}, - SupportCORS: &trueValue, - ExternalURL: "oneMoreUrl", + Supports: []string{"iframe"}, }, Experiment: BidderInfoExperiment{AdsCert: BidderAdsCert{Enabled: true}}, EndpointCompression: "GZIP", diff --git a/config/bidderinfo_validate_test.go b/config/bidderinfo_validate_test.go deleted file mode 100644 index c33c829fc43..00000000000 --- a/config/bidderinfo_validate_test.go +++ /dev/null @@ -1,161 +0,0 @@ -package config_test - -import ( - "errors" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "strings" - "testing" - - "github.com/stretchr/testify/assert" - "gopkg.in/yaml.v3" - - "github.com/prebid/prebid-server/config" - "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/usersync" -) - -const bidderInfoRelativePath = "../static/bidder-info" - -// TestBidderInfoFiles ensures each bidder has a valid static/bidder-info/bidder.yaml file. Validation is performed directly -// against the file system with separate yaml unmarshalling from the LoadBidderInfoFromDisk func. -func TestBidderInfoFiles(t *testing.T) { - fileInfos, err := ioutil.ReadDir(bidderInfoRelativePath) - if err != nil { - assert.FailNow(t, "Error reading the static/bidder-info directory: %v", err) - } - - // Ensure YAML Files Are For A Known Core Bidder - for _, fileInfo := range fileInfos { - bidder := strings.TrimSuffix(fileInfo.Name(), ".yaml") - - _, isKnown := openrtb_ext.NormalizeBidderName(bidder) - assert.True(t, isKnown, "unexpected bidder info yaml file %s", fileInfo.Name()) - } - - // Ensure YAML Files Are Defined For Each Core Bidder - expectedFileInfosLength := len(openrtb_ext.CoreBidderNames()) - assert.Len(t, fileInfos, expectedFileInfosLength, "static/bidder-info contains %d files, but there are %d known bidders. Did you forget to add a YAML file for your bidder?", len(fileInfos), expectedFileInfosLength) - - // Load & Validate Contents - bidderInfos := make(config.BidderInfos) - for _, fileInfo := range fileInfos { - path := fmt.Sprintf(bidderInfoRelativePath + "/" + fileInfo.Name()) - - infoFileData, err := os.Open(path) - assert.NoError(t, err, "Unexpected error: %v", err) - - content, err := ioutil.ReadAll(infoFileData) - assert.NoError(t, err, "Failed to read static/bidder-info/%s: %v", fileInfo.Name(), err) - - var fileInfoContent config.BidderInfo - err = yaml.Unmarshal(content, &fileInfoContent) - assert.NoError(t, err, "Error interpreting content from static/bidder-info/%s: %v", fileInfo.Name(), err) - - err = validateInfo(&fileInfoContent) - assert.NoError(t, err, "Invalid content in static/bidder-info/%s: %v", fileInfo.Name(), err) - - err = validateSyncer(fileInfoContent) - assert.NoError(t, err, "Invalid syncer config in static/bidder-info/%s: %v", fileInfo.Name(), err) - - fileNameWithoutExtension := fileInfo.Name()[:len(fileInfo.Name())-len(filepath.Ext(fileInfo.Name()))] - bidderInfos[fileNameWithoutExtension] = fileInfoContent - } - - errs := validateSyncers(t, bidderInfos) - assert.Empty(t, errs, "syncer errors") -} - -func validateInfo(info *config.BidderInfo) error { - if err := validateMaintainer(info.Maintainer); err != nil { - return err - } - - if err := validateCapabilities(info.Capabilities); err != nil { - return err - } - - return nil -} - -func validateMaintainer(info *config.MaintainerInfo) error { - if info == nil || info.Email == "" { - return errors.New("missing required field: maintainer.email") - } - return nil -} - -func validateCapabilities(info *config.CapabilitiesInfo) error { - if info == nil { - return errors.New("missing required field: capabilities") - } - - if info.App == nil && info.Site == nil { - return errors.New("at least one of capabilities.site or capabilities.app must exist") - } - - if info.App != nil { - if err := validatePlatformInfo(info.App); err != nil { - return fmt.Errorf("capabilities.app failed validation: %v", err) - } - } - - if info.Site != nil { - if err := validatePlatformInfo(info.Site); err != nil { - return fmt.Errorf("capabilities.site failed validation: %v", err) - } - } - return nil -} - -func validatePlatformInfo(info *config.PlatformInfo) error { - if info == nil { - return errors.New("object cannot be empty") - } - - if len(info.MediaTypes) == 0 { - return errors.New("mediaTypes should be an array with at least one string element") - } - - for index, mediaType := range info.MediaTypes { - if mediaType != "banner" && mediaType != "video" && mediaType != "native" && mediaType != "audio" { - return fmt.Errorf("unrecognized media type at index %d: %s", index, mediaType) - } - } - - return nil -} - -func validateSyncers(t *testing.T, bidderInfos config.BidderInfos) []error { - hostConfig := &config.Configuration{ - UserSync: config.UserSync{ - ExternalURL: "http://host.com", - RedirectURL: "{{.ExternalURL}}/host", - }, - } - - // enable all bidders to allow BuildSyncers to build all syncers - for k, v := range bidderInfos { - v.Enabled = true - bidderInfos[k] = v - } - - _, errs := usersync.BuildSyncers(hostConfig, bidderInfos) - return errs -} - -func validateSyncer(bidderInfo config.BidderInfo) error { - if bidderInfo.Syncer == nil { - return nil - } - - for _, v := range bidderInfo.Syncer.Supports { - if !strings.EqualFold(v, "iframe") && !strings.EqualFold(v, "redirect") { - return fmt.Errorf("syncer could not be created, invalid supported endpoint: %s", v) - } - } - - return nil -} diff --git a/config/config.go b/config/config.go index 827b098868f..a424a3f1fa0 100644 --- a/config/config.go +++ b/config/config.go @@ -54,17 +54,14 @@ type Configuration struct { StoredVideo StoredRequests `mapstructure:"stored_video_req"` StoredResponses StoredRequests `mapstructure:"stored_responses"` - // Adapters should have a key for every openrtb_ext.BidderName, converted to lower-case. - // Se also: https://github.com/spf13/viper/issues/371#issuecomment-335388559 - Adapters map[string]Adapter `mapstructure:"adapters"` - MaxRequestSize int64 `mapstructure:"max_request_size"` - Analytics Analytics `mapstructure:"analytics"` - AMPTimeoutAdjustment int64 `mapstructure:"amp_timeout_adjustment_ms"` - GDPR GDPR `mapstructure:"gdpr"` - CCPA CCPA `mapstructure:"ccpa"` - LMT LMT `mapstructure:"lmt"` - CurrencyConverter CurrencyConverter `mapstructure:"currency_converter"` - DefReqConfig DefReqConfig `mapstructure:"default_request"` + MaxRequestSize int64 `mapstructure:"max_request_size"` + Analytics Analytics `mapstructure:"analytics"` + AMPTimeoutAdjustment int64 `mapstructure:"amp_timeout_adjustment_ms"` + GDPR GDPR `mapstructure:"gdpr"` + CCPA CCPA `mapstructure:"ccpa"` + LMT LMT `mapstructure:"lmt"` + CurrencyConverter CurrencyConverter `mapstructure:"currency_converter"` + DefReqConfig DefReqConfig `mapstructure:"default_request"` VideoStoredRequestRequired bool `mapstructure:"video_stored_request_required"` @@ -98,6 +95,10 @@ type Configuration struct { HostSChainNode *openrtb2.SupplyChainNode `mapstructure:"host_schain_node"` // Experiment configures non-production ready features. Experiment Experiment `mapstructure:"experiment"` + + // BidderInfos supports adapter overrides in extra configs like pbs.json, pbs.yaml, etc. + // Refers to main.go `configFileName` constant + BidderInfos BidderInfos `mapstructure:"adapters"` } const MIN_COOKIE_SIZE_BYTES = 500 @@ -123,7 +124,6 @@ func (cfg *Configuration) validate(v *viper.Viper) []error { } errs = cfg.GDPR.validate(v, errs) errs = cfg.CurrencyConverter.validate(errs) - errs = validateAdapters(cfg.Adapters, errs) errs = cfg.Debug.validate(errs) errs = cfg.ExtCacheURL.validate(errs) if cfg.AccountDefaults.Disabled { @@ -133,6 +133,7 @@ func (cfg *Configuration) validate(v *viper.Viper) []error { glog.Warning(`account_defaults.events will currently not do anything as the feature is still under development. Please follow https://github.com/prebid/prebid-server/issues/1725 for more updates`) } errs = cfg.Experiment.validate(errs) + errs = cfg.BidderInfos.validate(errs) return errs } @@ -616,7 +617,7 @@ func (cfg *TimeoutNotification) validate(errs []error) []error { } // New uses viper to get our server configurations. -func New(v *viper.Viper) (*Configuration, error) { +func New(v *viper.Viper, bidderInfos BidderInfos) (*Configuration, error) { var c Configuration if err := v.Unmarshal(&c); err != nil { return nil, fmt.Errorf("viper failed to unmarshal app config: %v", err) @@ -699,6 +700,12 @@ func New(v *viper.Viper) (*Configuration, error) { // Migrate combo stored request config to separate stored_reqs and amp stored_reqs configs. resolvedStoredRequestsConfig(&c) + mergedBidderInfos, err := applyBidderInfoConfigOverrides(c.BidderInfos, bidderInfos) + if err != nil { + return nil, err + } + c.BidderInfos = mergedBidderInfos + glog.Info("Logging the resolved configuration:") logGeneral(reflect.ValueOf(c), " \t") if errs := c.validate(v); len(errs) > 0 { @@ -739,7 +746,7 @@ func (cfg *Configuration) GetCachedAssetURL(uuid string) string { } // Set the default config values for the viper object we are using. -func SetupViper(v *viper.Viper, filename string) { +func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { if filename != "" { v.SetConfigName(filename) v.AddConfigPath(".") @@ -906,185 +913,6 @@ func SetupViper(v *viper.Viper, filename string) { // macro substitution. it is important for the uid to be the last query parameter. v.SetDefault("user_sync.redirect_url", "{{.ExternalURL}}/setuid?bidder={{.SyncerKey}}&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&f={{.SyncType}}&uid={{.UserMacro}}") - for _, bidder := range openrtb_ext.CoreBidderNames() { - setBidderDefaults(v, strings.ToLower(string(bidder))) - } - - // Disabling adapters by default that require some specific config params. - // If you're using one of these, make sure you check out the documentation (https://github.com/prebid/prebid-server/tree/master/docs/bidders) - // for them and specify all the parameters they need for them to work correctly. - v.SetDefault("adapters.33across.endpoint", "https://ssc.33across.com/api/v1/s2s") - v.SetDefault("adapters.33across.partner_id", "") - v.SetDefault("adapters.aax.endpoint", "https://prebid.aaxads.com/rtb/pb/aax-prebid") - v.SetDefault("adapters.aax.extra_info", "https://aax.golang.pbs.com") - v.SetDefault("adapters.aceex.endpoint", "http://bl-us.aceex.io/?uqhash={{.AccountID}}") - v.SetDefault("adapters.acuityads.endpoint", "http://{{.Host}}.admanmedia.com/bid?token={{.AccountID}}") - v.SetDefault("adapters.adf.endpoint", "https://adx.adform.net/adx/openrtb") - v.SetDefault("adapters.adform.endpoint", "https://adx.adform.net/adx/openrtb") - v.SetDefault("adapters.adgeneration.endpoint", "https://d.socdm.com/adsv/v1") - v.SetDefault("adapters.adhese.endpoint", "https://ads-{{.AccountID}}.adhese.com/json") - v.SetDefault("adapters.adkernel.endpoint", "https://pbs.adksrv.com/hb?zone={{.ZoneID}}") - v.SetDefault("adapters.adkerneladn.endpoint", "https://pbs2.adksrv.com/rtbpub?account={{.PublisherID}}") - v.SetDefault("adapters.adman.endpoint", "http://pub.admanmedia.com/?c=o&m=ortb") - v.SetDefault("adapters.admixer.endpoint", "http://inv-nets.admixer.net/pbs.aspx") - v.SetDefault("adapters.adnuntius.endpoint", "https://ads.adnuntius.delivery/i") - v.SetDefault("adapters.adocean.endpoint", "https://{{.Host}}") - v.SetDefault("adapters.adoppler.endpoint", "http://{{.AccountID}}.trustedmarketplace.io/ads/processHeaderBid/{{.AdUnit}}") - v.SetDefault("adapters.adot.endpoint", "https://dsp.adotmob.com/headerbidding{PUBLISHER_PATH}/bidrequest") - v.SetDefault("adapters.adpone.endpoint", "http://rtb.adpone.com/bid-request?src=prebid_server") - v.SetDefault("adapters.adprime.endpoint", "http://delta.adprime.com/pserver") - v.SetDefault("adapters.adrino.endpoint", "https://prd-prebid-bidder.adrino.io/openrtb/bid") - v.SetDefault("adapters.adtarget.endpoint", "http://ghb.console.adtarget.com.tr/pbs/ortb") - v.SetDefault("adapters.adtrgtme.endpoint", "https://z.cdn.adtarget.market/ssp") - v.SetDefault("adapters.adtelligent.endpoint", "http://ghb.adtelligent.com/pbs/ortb") - v.SetDefault("adapters.advangelists.endpoint", "http://nep.advangelists.com/xp/get?pubid={{.PublisherID}}") - v.SetDefault("adapters.adview.endpoint", "https://bid.adview.com/agent/thirdAdxService/{{.AccountID}}") - v.SetDefault("adapters.adxcg.disabled", true) - v.SetDefault("adapters.adyoulike.endpoint", "https://broker.omnitagjs.com/broker/bid?partnerId=19340f4f097d16f41f34fc0274981ca4") - v.SetDefault("adapters.aja.endpoint", "https://ad.as.amanad.adtdp.com/v1/bid/4") - v.SetDefault("adapters.algorix.endpoint", "https://{{.Host}}.svr-algorix.com/rtb/sa?sid={{.SourceId}}&token={{.AccountID}}") - v.SetDefault("adapters.amx.endpoint", "http://pbs.amxrtb.com/auction/openrtb") - v.SetDefault("adapters.andbeyondmedia.endpoint", "http://backend.andbeyond.media/pserver") - v.SetDefault("adapters.apacdex.endpoint", "http://useast.quantumdex.io/auction/pbs") - v.SetDefault("adapters.applogy.endpoint", "http://rtb.applogy.com/v1/prebid") - v.SetDefault("adapters.appnexus.endpoint", "http://ib.adnxs.com/openrtb2") // Docs: https://wiki.appnexus.com/display/supply/Incoming+Bid+Request+from+SSPs - v.SetDefault("adapters.appnexus.platform_id", "5") - v.SetDefault("adapters.audiencenetwork.disabled", true) - v.SetDefault("adapters.audiencenetwork.endpoint", "https://an.facebook.com/placementbid.ortb") - v.SetDefault("adapters.automatad.endpoint", "https://s2s.atmtd.com") - v.SetDefault("adapters.avocet.disabled", true) - v.SetDefault("adapters.axonix.endpoint", "https://openrtb-us-east-1.axonix.com/supply/prebid-server/{{.AccountID}}") - v.SetDefault("adapters.beachfront.endpoint", "https://display.bfmio.com/prebid_display") - v.SetDefault("adapters.beachfront.extra_info", "{\"video_endpoint\":\"https://reachms.bfmio.com/bid.json?exchange_id\"}") - v.SetDefault("adapters.beintoo.endpoint", "https://ib.beintoo.com/um") - v.SetDefault("adapters.between.endpoint", "http://{{.Host}}.betweendigital.com/openrtb_bid?sspId={{.PublisherID}}") - v.SetDefault("adapters.bidmachine.endpoint", "https://{{.Host}}.bidmachine.io") - v.SetDefault("adapters.bidmyadz.endpoint", "http://endpoint.bidmyadz.com/c0f68227d14ed938c6c49f3967cbe9bc") - v.SetDefault("adapters.bidscube.endpoint", "http://supply.bidscube.com/?c=o&m=rtb") - v.SetDefault("adapters.bizzclick.endpoint", "http://us-e-node1.bizzclick.com/bid?rtb_seat_id={{.SourceId}}&secret_key={{.AccountID}}") - v.SetDefault("adapters.bliink.endpoint", "http://engine.bliink.io/bid") - v.SetDefault("adapters.blue.endpoint", "https://prebid-us-east-1.getblue.io/?src=prebid") - v.SetDefault("adapters.bmtm.endpoint", "https://one.elitebidder.com/api/pbs") - v.SetDefault("adapters.boldwin.endpoint", "http://ssp.videowalldirect.com/pserver") - v.SetDefault("adapters.brightroll.endpoint", "http://east-bid.ybp.yahoo.com/bid/appnexuspbs") - v.SetDefault("adapters.coinzilla.endpoint", "http://request-global.czilladx.com/serve/prebid-server.php") - v.SetDefault("adapters.colossus.endpoint", "http://colossusssp.com/?c=o&m=rtb") - v.SetDefault("adapters.compass.endpoint", "http://sa-lb.deliverimp.com/pserver") - v.SetDefault("adapters.connectad.endpoint", "http://bidder.connectad.io/API?src=pbs") - v.SetDefault("adapters.consumable.endpoint", "https://e.serverbid.com/api/v2") - v.SetDefault("adapters.conversant.endpoint", "http://api.hb.ad.cpe.dotomi.com/cvx/server/hb/ortb/25") - v.SetDefault("adapters.cpmstar.endpoint", "https://server.cpmstar.com/openrtbbidrq.aspx") - v.SetDefault("adapters.criteo.endpoint", "https://bidder.criteo.com/cdb?profileId=230") - v.SetDefault("adapters.datablocks.endpoint", "http://{{.Host}}/openrtb2?sid={{.SourceId}}") - v.SetDefault("adapters.decenterads.endpoint", "http://supply.decenterads.com/?c=o&m=rtb") - v.SetDefault("adapters.deepintent.endpoint", "https://prebid.deepintent.com/prebid") - v.SetDefault("adapters.dianomi.endpoint", "https://www-prebid.dianomi.com/cgi-bin/smartads_prebid.pl") - v.SetDefault("adapters.dianomi.disabled", true) - v.SetDefault("adapters.dmx.endpoint", "https://dmx-direct.districtm.io/b/v2") - v.SetDefault("adapters.e_volution.endpoint", "http://service.e-volution.ai/pbserver") - v.SetDefault("adapters.emx_digital.endpoint", "https://hb.emxdgt.com") - v.SetDefault("adapters.engagebdr.endpoint", "http://dsp.bnmla.com/hb") - v.SetDefault("adapters.eplanning.endpoint", "http://rtb.e-planning.net/pbs/1") - v.SetDefault("adapters.epom.disabled", true) - v.SetDefault("adapters.epom.endpoint", "https://an.epom.com/ortb") - v.SetDefault("adapters.gamma.endpoint", "https://hb.gammaplatform.com/adx/request/") - v.SetDefault("adapters.gamoshi.endpoint", "https://rtb.gamoshi.io") - v.SetDefault("adapters.grid.endpoint", "https://grid.bidswitch.net/sp_bid?sp=prebid") - v.SetDefault("adapters.groupm.endpoint", "https://hbopenbid.pubmatic.com/translator?source=prebid-server") - v.SetDefault("adapters.gumgum.endpoint", "https://g2.gumgum.com/providers/prbds2s/bid") - v.SetDefault("adapters.huaweiads.disabled", true) - v.SetDefault("adapters.huaweiads.endpoint", "https://acd.op.hicloud.com/ppsadx/getResult") - v.SetDefault("adapters.impactify.endpoint", "https://sonic.impactify.media/bidder") - v.SetDefault("adapters.improvedigital.endpoint", "http://ad.360yield.com/pbs") - v.SetDefault("adapters.infytv.endpoint", "https://nxs.infy.tv/pbs/openrtb") - v.SetDefault("adapters.inmobi.endpoint", "https://api.w.inmobi.com/showad/openrtb/bidder/prebid") - v.SetDefault("adapters.interactiveoffers.endpoint", "https://prebid-server.ioadx.com/bidRequest/?partnerId={{.AccountID}}") - v.SetDefault("adapters.invibes.endpoint", "https://{{.ZoneID}}.videostep.com/bid/ServerBidAdContent") - v.SetDefault("adapters.iqzone.endpoint", "http://smartssp-us-east.iqzone.com/pserver") - v.SetDefault("adapters.ix.disabled", true) - v.SetDefault("adapters.janet.endpoint", "http://ghb.bidder.jmgads.com/pbs/ortb") - v.SetDefault("adapters.jixie.endpoint", "https://hb.jixie.io/v2/hbsvrpost") - v.SetDefault("adapters.kargo.endpoint", "https://krk.kargo.com/api/v1/openrtb") - v.SetDefault("adapters.kayzen.endpoint", "https://bids-{{.ZoneID}}.bidder.kayzen.io/?exchange={{.AccountID}}") - v.SetDefault("adapters.kidoz.endpoint", "http://prebid-adapter.kidoz.net/openrtb2/auction?src=prebid-server") - v.SetDefault("adapters.krushmedia.endpoint", "http://ads4.krushmedia.com/?c=rtb&m=req&key={{.AccountID}}") - v.SetDefault("adapters.kubient.endpoint", "https://kssp.kbntx.ch/prebid") - v.SetDefault("adapters.lockerdome.endpoint", "https://lockerdome.com/ladbid/prebidserver/openrtb2") - v.SetDefault("adapters.logicad.endpoint", "https://pbs.ladsp.com/adrequest/prebidserver") - v.SetDefault("adapters.lunamedia.endpoint", "http://api.lunamedia.io/xp/get?pubid={{.PublisherID}}") - v.SetDefault("adapters.madvertise.endpoint", "https://mobile.mng-ads.com/bidrequest{{.ZoneID}}") - v.SetDefault("adapters.marsmedia.endpoint", "https://bid306.rtbsrv.com/bidder/?bid=f3xtet") - v.SetDefault("adapters.mediafuse.endpoint", "http://ib.adnxs.com/openrtb2") - v.SetDefault("adapters.medianet.endpoint", "https://prebid-adapter.media.net/rtb/pb/prebids2s") - v.SetDefault("adapters.medianet.extra_info", "https://medianet.golang.pbs.com") - v.SetDefault("adapters.mgid.endpoint", "https://prebid.mgid.com/prebid/") - v.SetDefault("adapters.mobfoxpb.endpoint", "http://bes.mobfox.com/?c=__route__&m=__method__&key=__key__") - v.SetDefault("adapters.mobilefuse.endpoint", "http://mfx.mobilefuse.com/openrtb?pub_id={{.PublisherID}}") - v.SetDefault("adapters.nanointeractive.endpoint", "https://ad.audiencemanager.de/hbs") - v.SetDefault("adapters.nextmillennium.endpoint", "https://pbs.nextmillmedia.com/openrtb2/auction") - v.SetDefault("adapters.ninthdecimal.endpoint", "http://rtb.ninthdecimal.com/xp/get?pubid={{.PublisherID}}") - v.SetDefault("adapters.nobid.endpoint", "https://ads.servenobid.com/ortb_adreq?tek=pbs&ver=1") - v.SetDefault("adapters.oftmedia.endpoint", "http://ghb.ortb.152media.info/pbs/ortb") - v.SetDefault("adapters.onetag.endpoint", "https://prebid-server.onetag-sys.com/prebid-server/{{.PublisherID}}") - v.SetDefault("adapters.openweb.endpoint", "http://ghb.spotim.market/pbs/ortb") - v.SetDefault("adapters.openx.endpoint", "http://rtb.openx.net/prebid") - v.SetDefault("adapters.operaads.endpoint", "https://s.adx.opera.com/ortb/v2/{{.PublisherID}}?ep={{.AccountID}}") - v.SetDefault("adapters.orbidder.endpoint", "https://orbidder.otto.de/openrtb2") - v.SetDefault("adapters.outbrain.endpoint", "https://prebidtest.zemanta.com/api/bidder/prebidtest/bid/") - v.SetDefault("adapters.pangle.disabled", true) - v.SetDefault("adapters.pgam.endpoint", "http://ghb.pgamssp.com/pbs/ortb") - v.SetDefault("adapters.pubmatic.endpoint", "https://hbopenbid.pubmatic.com/translator?source=prebid-server") - v.SetDefault("adapters.pubnative.endpoint", "http://dsp.pubnative.net/bid/v1/request") - v.SetDefault("adapters.pulsepoint.endpoint", "http://bid.contextweb.com/header/s/ortb/prebid-s2s") - v.SetDefault("adapters.quantumdex.endpoint", "http://useast.quantumdex.io/auction/pbs") - v.SetDefault("adapters.revcontent.disabled", true) - v.SetDefault("adapters.revcontent.endpoint", "https://trends.revcontent.com/rtb") - v.SetDefault("adapters.rhythmone.endpoint", "http://tag.1rx.io/rmp") - v.SetDefault("adapters.richaudience.endpoint", "http://ortb.richaudience.com/ortb/?bidder=pbs") - v.SetDefault("adapters.rtbhouse.endpoint", "http://prebidserver-s2s-ams.creativecdn.com/bidder/prebidserver/bids") - v.SetDefault("adapters.rubicon.disabled", true) - v.SetDefault("adapters.rubicon.endpoint", "http://exapi-us-east.rubiconproject.com/a/api/exchange.json") - v.SetDefault("adapters.seedingalliance.endpoint", "http://b.nativendo.de/cds/rtb/bid?ssp=pb") - v.SetDefault("adapters.sa_lunamedia.endpoint", "http://balancer.lmgssp.com/pserver") - v.SetDefault("adapters.sharethrough.endpoint", "https://btlr.sharethrough.com/universal/v1?supply_id=FGMrCMMc") - v.SetDefault("adapters.silvermob.endpoint", "http://{{.Host}}.silvermob.com/marketplace/api/dsp/bid/{{.ZoneID}}") - v.SetDefault("adapters.smaato.endpoint", "https://prebid.ad.smaato.net/oapi/prebid") - v.SetDefault("adapters.smartadserver.endpoint", "https://ssb-global.smartadserver.com") - v.SetDefault("adapters.smarthub.endpoint", "http://{{.Host}}-prebid.smart-hub.io/?seat={{.AccountID}}&token={{.SourceId}}") - v.SetDefault("adapters.smartrtb.endpoint", "http://market-east.smrtb.com/json/publisher/rtb?pubid={{.PublisherID}}") - v.SetDefault("adapters.smartyads.endpoint", "http://{{.Host}}.smartyads.com/bid?rtb_seat_id={{.SourceId}}&secret_key={{.AccountID}}") - v.SetDefault("adapters.smilewanted.endpoint", "http://prebid-server.smilewanted.com") - v.SetDefault("adapters.sonobi.endpoint", "https://apex.go.sonobi.com/prebid?partnerid=71d9d3d8af") - v.SetDefault("adapters.sovrn.endpoint", "http://pbs.lijit.com/rtb/bid?src=prebid_server") - v.SetDefault("adapters.sspbc.endpoint", "https://ssp.wp.pl/bidder/") - v.SetDefault("adapters.streamkey.endpoint", "http://ghb.hb.streamkey.net/pbs/ortb") - v.SetDefault("adapters.stroeercore.disabled", true) - v.SetDefault("adapters.stroeercore.endpoint", "http://mhb.adscale.de/s2sdsh") - v.SetDefault("adapters.synacormedia.endpoint", "http://{{.Host}}.technoratimedia.com/openrtb/bids/{{.Host}}") - v.SetDefault("adapters.tappx.endpoint", "http://{{.Host}}") - v.SetDefault("adapters.telaria.endpoint", "https://ads.tremorhub.com/ad/rtb/prebid") - v.SetDefault("adapters.trafficgate.endpoint", "http://{{.Host}}.bc-plugin.com/?c=o&m=rtb") - v.SetDefault("adapters.triplelift_native.disabled", true) - v.SetDefault("adapters.triplelift_native.extra_info", "{\"publisher_whitelist\":[]}") - v.SetDefault("adapters.triplelift.endpoint", "https://tlx.3lift.com/s2s/auction?sra=1&supplier_id=20") - v.SetDefault("adapters.trustx.endpoint", "https://grid.bidswitch.net/sp_bid?sp=trustx") - v.SetDefault("adapters.ucfunnel.endpoint", "https://pbs.aralego.com/prebid") - v.SetDefault("adapters.unicorn.endpoint", "https://ds.uncn.jp/pb/0/bid.json") - v.SetDefault("adapters.unruly.endpoint", "https://targeting.unrulymedia.com/unruly_prebid_server") - v.SetDefault("adapters.valueimpression.endpoint", "http://useast.quantumdex.io/auction/pbs") - v.SetDefault("adapters.verizonmedia.disabled", true) - v.SetDefault("adapters.videobyte.endpoint", "https://x.videobyte.com/ortbhb") - v.SetDefault("adapters.vidoomy.endpoint", "https://p.vidoomy.com/api/rtbserver/pbs") - v.SetDefault("adapters.viewdeos.endpoint", "http://ghb.sync.viewdeos.com/pbs/ortb") - v.SetDefault("adapters.visx.endpoint", "https://t.visx.net/s2s_bid?wrapperType=s2s_prebid_standard:0.1.1") - v.SetDefault("adapters.vrtcal.endpoint", "http://rtb.vrtcal.com/bidder_prebid.vap?ssp=1804") - v.SetDefault("adapters.yahoossp.endpoint", "https://s2shb.ssp.yahoo.com/admax/bid/partners/PBS") - v.SetDefault("adapters.yeahmobi.endpoint", "https://{{.Host}}/prebid/bid") - v.SetDefault("adapters.yieldlab.endpoint", "https://ad.yieldlab.net/yp/") - v.SetDefault("adapters.yieldmo.endpoint", "https://ads.yieldmo.com/exchange/prebid-server") - v.SetDefault("adapters.yieldone.endpoint", "https://y.one.impact-ad.jp/hbs_imp") - v.SetDefault("adapters.zeroclickfraud.endpoint", "http://{{.Host}}/openrtb2?sid={{.SourceId}}") - v.SetDefault("max_request_size", 1024*256) v.SetDefault("analytics.file.filename", "") v.SetDefault("analytics.pubstack.endpoint", "https://s2s.pbstck.com/v1") @@ -1229,6 +1057,10 @@ func SetupViper(v *viper.Viper, filename string) { v.SetDefault("experiment.adscert.inprocess.domain_renewal_interval_seconds", 30) v.SetDefault("experiment.adscert.remote.url", "") v.SetDefault("experiment.adscert.remote.signing_timeout_ms", 5) + + for bidderName := range bidderInfos { + setBidderDefaults(v, strings.ToLower(bidderName)) + } } func migrateConfig(v *viper.Viper) { @@ -1327,16 +1159,20 @@ func migrateConfigTCF2PurposeEnabledFlags(v *viper.Viper) { func setBidderDefaults(v *viper.Viper, bidder string) { adapterCfgPrefix := "adapters." + bidder - v.SetDefault(adapterCfgPrefix+".endpoint", "") - v.SetDefault(adapterCfgPrefix+".usersync_url", "") - v.SetDefault(adapterCfgPrefix+".platform_id", "") - v.SetDefault(adapterCfgPrefix+".app_secret", "") - v.SetDefault(adapterCfgPrefix+".xapi.username", "") - v.SetDefault(adapterCfgPrefix+".xapi.password", "") - v.SetDefault(adapterCfgPrefix+".xapi.tracker", "") - v.SetDefault(adapterCfgPrefix+".disabled", false) - v.SetDefault(adapterCfgPrefix+".partner_id", "") - v.SetDefault(adapterCfgPrefix+".extra_info", "") + v.BindEnv(adapterCfgPrefix+".disabled", "") + v.BindEnv(adapterCfgPrefix+".endpoint", "") + v.BindEnv(adapterCfgPrefix+".extra_info", "") + v.BindEnv(adapterCfgPrefix+".modifyingVastXmlAllowed", "") + v.BindEnv(adapterCfgPrefix+".debug.allow", "") + v.BindEnv(adapterCfgPrefix+".gvlVendorID", "") + v.BindEnv(adapterCfgPrefix+".usersync_url", "") + v.BindEnv(adapterCfgPrefix+".experiment.adsCert.enabled", "") + v.BindEnv(adapterCfgPrefix+".platform_id", "") + v.BindEnv(adapterCfgPrefix+".app_secret", "") + v.BindEnv(adapterCfgPrefix+".xapi.username", "") + v.BindEnv(adapterCfgPrefix+".xapi.password", "") + v.BindEnv(adapterCfgPrefix+".xapi.tracker", "") + v.BindEnv(adapterCfgPrefix+".endpointCompression", "") v.BindEnv(adapterCfgPrefix + ".usersync.key") v.BindEnv(adapterCfgPrefix + ".usersync.default") diff --git a/config/config_test.go b/config/config_test.go index 61c790def88..27077ad78a3 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -5,19 +5,37 @@ import ( "errors" "net" "os" - "strings" "testing" "time" - "encoding/json" - "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/openrtb_ext" "github.com/spf13/viper" "github.com/stretchr/testify/assert" ) +var bidderInfos = BidderInfos{ + "bidder1": BidderInfo{ + Endpoint: "http://bidder1.com", + Maintainer: &MaintainerInfo{Email: "maintainer@bidder1.com"}, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}, + }, + }, + }, + "bidder2": BidderInfo{ + Endpoint: "http://bidder2.com", + Maintainer: &MaintainerInfo{Email: "maintainer@bidder2.com"}, + Capabilities: &CapabilitiesInfo{ + App: &PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}, + }, + }, + UserSyncURL: "http://bidder2.com/usersync", + }, +} + func TestExternalCacheURLValidate(t *testing.T) { testCases := []struct { desc string @@ -131,7 +149,6 @@ func TestDefaults(t *testing.T) { cmpInts(t, "max_request_size", int(cfg.MaxRequestSize), 1024*256) cmpInts(t, "host_cookie.ttl_days", int(cfg.HostCookie.TTL), 90) cmpInts(t, "host_cookie.max_cookie_size_bytes", cfg.HostCookie.MaxCookieSizeBytes, 0) - cmpStrings(t, "adapters.pubmatic.endpoint", cfg.Adapters[string(openrtb_ext.BidderPubmatic)].Endpoint, "https://hbopenbid.pubmatic.com/translator?source=prebid-server") cmpInts(t, "currency_converter.fetch_interval_seconds", cfg.CurrencyConverter.FetchIntervalSeconds, 1800) cmpStrings(t, "currency_converter.fetch_url", cfg.CurrencyConverter.FetchURL, "https://cdn.jsdelivr.net/gh/prebid/currency-file@1/latest.json") cmpBools(t, "account_required", cfg.AccountRequired, false) @@ -261,9 +278,6 @@ func TestDefaults(t *testing.T) { 10: &expectedTCF2.Purpose10, } assert.Equal(t, expectedTCF2, cfg.GDPR.TCF2, "gdpr.tcf2") - - // Assert User Sync Override Defaults To Nil - assert.Nil(t, cfg.Adapters["appnexus"].Syncer, "User Sync") } var fullConfig = []byte(` @@ -364,31 +378,6 @@ metrics: account_stored_responses: false adapter_connections_metrics: true adapter_gdpr_request_blocked: true -adapters: - appnexus: - endpoint: http://ib.adnxs.com/some/endpoint - extra_info: "{\"native\":\"http://www.native.org/endpoint\",\"video\":\"http://www.video.org/endpoint\"}" - audienceNetwork: - endpoint: http://facebook.com/pbs - usersync_url: http://facebook.com/ortb/prebid-s2s - platform_id: abcdefgh1234 - app_secret: 987abc - ix: - endpoint: http://ixtest.com/api - rubicon: - endpoint: http://rubitest.com/api - xapi: - username: rubiuser - password: rubipw23 - usersync: - redirect: - url: http://rubitest.com/sync - user_macro: "{UID}" - brightroll: - usersync_url: http://test-bh.ybp.yahoo.com/sync/appnexuspbs?gdpr={{.GDPR}}&euconsent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&url=%s - endpoint: http://test-bid.ybp.yahoo.com/bid/appnexuspbs - adkerneladn: - usersync_url: https://tag.adkernel.com/syncr?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r= blacklisted_apps: ["spamAppID","sketchy-app-id"] account_required: true auto_gen_source_tid: false @@ -415,30 +404,6 @@ experiment: signing_timeout_ms: 10 `) -var adapterExtraInfoConfig = []byte(` -adapters: - appnexus: - endpoint: http://ib.adnxs.com/some/endpoint - usersync_url: http://adnxs.com/sync.php?p=prebid - platform_id: appNexus - xapi: - username: appuser - password: 123456 - tracker: anxsTrack - disabled: true - extra_info: "{\"native\":\"http://www.native.org/endpoint\",\"video\":\"http://www.video.org/endpoint\"}" -`) - -var invalidAdapterEndpointConfig = []byte(` -adapters: - appnexus: - endpoint: ib.adnxs.com/some/endpoint - brightroll: - usersync: - redirect: - url: http://http://test-bh.ybp.yahoo.com/sync/appnexuspbs?gdpr={{.GDPR}}&euconsent={{.GDPRConsent}}&url=%s -`) - var oldStoredRequestsConfig = []byte(` stored_requests: filesystem: true @@ -474,10 +439,10 @@ func TestFullConfig(t *testing.T) { int8One := int8(1) v := viper.New() - SetupViper(v, "") + SetupViper(v, "", bidderInfos) v.SetConfigType("yaml") v.ReadConfig(bytes.NewBuffer(fullConfig)) - cfg, err := New(v) + cfg, err := New(v, bidderInfos) assert.NoError(t, err, "Setting up config should work but it doesn't") cmpStrings(t, "cookie domain", cfg.HostCookie.Domain, "cookies.prebid.org") cmpStrings(t, "cookie name", cfg.HostCookie.CookieName, "userid") @@ -651,23 +616,6 @@ func TestFullConfig(t *testing.T) { cmpInts(t, "metrics.influxdb.metric_send_interval", cfg.Metrics.Influxdb.MetricSendInterval, 30) cmpStrings(t, "", cfg.CacheURL.GetBaseURL(), "http://prebidcache.net") cmpStrings(t, "", cfg.GetCachedAssetURL("a0eebc99-9c0b-4ef8-bb00-6bb9bd380a11"), "http://prebidcache.net/cache?uuid=a0eebc99-9c0b-4ef8-bb00-6bb9bd380a11") - cmpStrings(t, "adapters.appnexus.endpoint", cfg.Adapters[string(openrtb_ext.BidderAppnexus)].Endpoint, "http://ib.adnxs.com/some/endpoint") - cmpStrings(t, "adapters.appnexus.extra_info", cfg.Adapters[string(openrtb_ext.BidderAppnexus)].ExtraAdapterInfo, "{\"native\":\"http://www.native.org/endpoint\",\"video\":\"http://www.video.org/endpoint\"}") - cmpStrings(t, "adapters.audiencenetwork.endpoint", cfg.Adapters[strings.ToLower(string(openrtb_ext.BidderAudienceNetwork))].Endpoint, "http://facebook.com/pbs") - cmpStrings(t, "adapters.audiencenetwork.platform_id", cfg.Adapters[strings.ToLower(string(openrtb_ext.BidderAudienceNetwork))].PlatformID, "abcdefgh1234") - cmpStrings(t, "adapters.audiencenetwork.app_secret", cfg.Adapters[strings.ToLower(string(openrtb_ext.BidderAudienceNetwork))].AppSecret, "987abc") - cmpStrings(t, "adapters.audiencenetwork.usersync_url", cfg.Adapters[strings.ToLower(string(openrtb_ext.BidderAudienceNetwork))].UserSyncURL, "http://facebook.com/ortb/prebid-s2s") - cmpStrings(t, "adapters.beachfront.endpoint", cfg.Adapters[string(openrtb_ext.BidderBeachfront)].Endpoint, "https://display.bfmio.com/prebid_display") - cmpStrings(t, "adapters.beachfront.extra_info", cfg.Adapters[string(openrtb_ext.BidderBeachfront)].ExtraAdapterInfo, "{\"video_endpoint\":\"https://reachms.bfmio.com/bid.json?exchange_id\"}") - cmpStrings(t, "adapters.ix.endpoint", cfg.Adapters[strings.ToLower(string(openrtb_ext.BidderIx))].Endpoint, "http://ixtest.com/api") - cmpStrings(t, "adapters.rubicon.endpoint", cfg.Adapters[string(openrtb_ext.BidderRubicon)].Endpoint, "http://rubitest.com/api") - cmpStrings(t, "adapters.rubicon.xapi.username", cfg.Adapters[string(openrtb_ext.BidderRubicon)].XAPI.Username, "rubiuser") - cmpStrings(t, "adapters.rubicon.xapi.password", cfg.Adapters[string(openrtb_ext.BidderRubicon)].XAPI.Password, "rubipw23") - cmpStrings(t, "adapters.rubicon.usersync.redirect.url", cfg.Adapters[string(openrtb_ext.BidderRubicon)].Syncer.Redirect.URL, "http://rubitest.com/sync") - cmpNils(t, "adapters.rubicon.usersync.iframe", cfg.Adapters[string(openrtb_ext.BidderRubicon)].Syncer.IFrame) - cmpStrings(t, "adapters.rubicon.usersync.redirect.user_macro", cfg.Adapters[string(openrtb_ext.BidderRubicon)].Syncer.Redirect.UserMacro, "{UID}") - cmpStrings(t, "adapters.brightroll.endpoint", cfg.Adapters[string(openrtb_ext.BidderBrightroll)].Endpoint, "http://test-bid.ybp.yahoo.com/bid/appnexuspbs") - cmpStrings(t, "adapters.rhythmone.endpoint", cfg.Adapters[string(openrtb_ext.BidderRhythmone)].Endpoint, "http://tag.1rx.io/rmp") cmpBools(t, "account_required", cfg.AccountRequired, true) cmpBools(t, "auto_gen_source_tid", cfg.AutoGenSourceTID, false) cmpBools(t, "account_adapter_details", cfg.Metrics.Disabled.AccountAdapterDetails, true) @@ -690,36 +638,6 @@ func TestFullConfig(t *testing.T) { cmpInts(t, "experiment.adscert.remote.signing_timeout_ms", cfg.Experiment.AdCerts.Remote.SigningTimeoutMs, 10) } -func TestUnmarshalAdapterExtraInfo(t *testing.T) { - v := viper.New() - SetupViper(v, "") - v.Set("gdpr.default_value", "0") - v.SetConfigType("yaml") - v.ReadConfig(bytes.NewBuffer(adapterExtraInfoConfig)) - cfg, err := New(v) - - // Assert correctly unmarshaled - assert.NoError(t, err, "invalid endpoint in config should return an error") - - // Assert JSON-formatted string - assert.JSONEqf(t, `{"native":"http://www.native.org/endpoint","video":"http://www.video.org/endpoint"}`, cfg.Adapters[string(openrtb_ext.BidderAppnexus)].ExtraAdapterInfo, "Unexpected value of the ExtraAdapterInfo String \n") - - // Data type where we'll unmarshal endpoint values and adapter custom extra information - type AppNexusAdapterEndpoints struct { - NativeEndpoint string `json:"native,omitempty"` - VideoEndpoint string `json:"video,omitempty"` - } - var AppNexusAdapterExtraInfo AppNexusAdapterEndpoints - err = json.Unmarshal([]byte(cfg.Adapters[string(openrtb_ext.BidderAppnexus)].ExtraAdapterInfo), &AppNexusAdapterExtraInfo) - - // Assert correctly unmarshaled - assert.NoErrorf(t, err, "Error. Could not unmarshal cfg.Adapters[string(openrtb_ext.BidderAppnexus)].ExtraAdapterInfo. Value: %s. Error: %v \n", cfg.Adapters[string(openrtb_ext.BidderAppnexus)].ExtraAdapterInfo, err) - - // Assert endpoint values - assert.Equal(t, "http://www.native.org/endpoint", AppNexusAdapterExtraInfo.NativeEndpoint) - assert.Equal(t, "http://www.video.org/endpoint", AppNexusAdapterExtraInfo.VideoEndpoint) -} - func TestValidateConfig(t *testing.T) { cfg := Configuration{ GDPR: GDPR{ @@ -768,12 +686,12 @@ func TestValidateConfig(t *testing.T) { func TestMigrateConfig(t *testing.T) { v := viper.New() - SetupViper(v, "") + SetupViper(v, "", bidderInfos) v.Set("gdpr.default_value", "0") v.SetConfigType("yaml") v.ReadConfig(bytes.NewBuffer(oldStoredRequestsConfig)) migrateConfig(v) - cfg, err := New(v) + cfg, err := New(v, bidderInfos) assert.NoError(t, err, "Setting up config should work but it doesn't") cmpBools(t, "stored_requests.filesystem.enabled", true, cfg.StoredRequests.Files.Enabled) cmpStrings(t, "stored_requests.filesystem.path", "/somepath", cfg.StoredRequests.Files.Path) @@ -785,9 +703,139 @@ func TestMigrateConfigFromEnv(t *testing.T) { } else { defer os.Unsetenv("PBS_STORED_REQUESTS_FILESYSTEM") } + + if oldval, ok := os.LookupEnv("PBS_ADAPTERS_BIDDER1_ENDPOINT"); ok { + defer os.Setenv("PBS_ADAPTERS_BIDDER1_ENDPOINT", oldval) + } else { + defer os.Unsetenv("PBS_ADAPTERS_BIDDER1_ENDPOINT") + } + os.Setenv("PBS_STORED_REQUESTS_FILESYSTEM", "true") + os.Setenv("PBS_ADAPTERS_BIDDER1_ENDPOINT", "http://bidder1_override.com") cfg, _ := newDefaultConfig(t) cmpBools(t, "stored_requests.filesystem.enabled", true, cfg.StoredRequests.Files.Enabled) + cmpStrings(t, "adapters.bidder1.endpoint", "http://bidder1_override.com", cfg.BidderInfos["bidder1"].Endpoint) +} + +func TestUserSyncFromEnv(t *testing.T) { + truePtr := true + + // setup env vars for testing + if oldval, ok := os.LookupEnv("PBS_ADAPTERS_BIDDER1_USERSYNC_REDIRECT_URL"); ok { + defer os.Setenv("PBS_ADAPTERS_BIDDER1_USERSYNC_REDIRECT_URL", oldval) + } else { + defer os.Unsetenv("PBS_ADAPTERS_BIDDER1_USERSYNC_REDIRECT_URL") + } + + if oldval, ok := os.LookupEnv("PBS_ADAPTERS_BIDDER1_USERSYNC_REDIRECT_USER_MACRO"); ok { + defer os.Setenv("PBS_ADAPTERS_BIDDER1_USERSYNC_REDIRECT_USER_MACRO", oldval) + } else { + defer os.Unsetenv("PBS_ADAPTERS_BIDDER1_USERSYNC_REDIRECT_USER_MACRO") + } + + if oldval, ok := os.LookupEnv("PBS_ADAPTERS_BIDDER1_USERSYNC_SUPPORT_CORS"); ok { + defer os.Setenv("PBS_ADAPTERS_BIDDER1_USERSYNC_SUPPORT_CORS", oldval) + } else { + defer os.Unsetenv("PBS_ADAPTERS_BIDDER1_USERSYNC_SUPPORT_CORS") + } + + if oldval, ok := os.LookupEnv("PBS_ADAPTERS_BIDDER2_USERSYNC_IFRAME_URL"); ok { + defer os.Setenv("PBS_ADAPTERS_BIDDER2_USERSYNC_IFRAME_URL", oldval) + } else { + defer os.Unsetenv("PBS_ADAPTERS_BIDDER2_USERSYNC_IFRAME_URL") + } + + // set new + os.Setenv("PBS_ADAPTERS_BIDDER1_USERSYNC_REDIRECT_URL", "http://some.url/sync?redirect={{.RedirectURL}}") + os.Setenv("PBS_ADAPTERS_BIDDER1_USERSYNC_REDIRECT_USER_MACRO", "[UID]") + os.Setenv("PBS_ADAPTERS_BIDDER1_USERSYNC_SUPPORT_CORS", "true") + os.Setenv("PBS_ADAPTERS_BIDDER2_USERSYNC_IFRAME_URL", "http://somedifferent.url/sync?redirect={{.RedirectURL}}") + + cfg, _ := newDefaultConfig(t) + + assert.Equal(t, "http://some.url/sync?redirect={{.RedirectURL}}", cfg.BidderInfos["bidder1"].Syncer.Redirect.URL) + assert.Equal(t, "[UID]", cfg.BidderInfos["bidder1"].Syncer.Redirect.UserMacro) + assert.Nil(t, cfg.BidderInfos["bidder1"].Syncer.IFrame) + assert.Equal(t, &truePtr, cfg.BidderInfos["bidder1"].Syncer.SupportCORS) + + assert.Equal(t, "http://somedifferent.url/sync?redirect={{.RedirectURL}}", cfg.BidderInfos["bidder2"].Syncer.IFrame.URL) + assert.Nil(t, cfg.BidderInfos["bidder2"].Syncer.Redirect) + assert.Nil(t, cfg.BidderInfos["bidder2"].Syncer.SupportCORS) + + assert.Nil(t, cfg.BidderInfos["brightroll"].Syncer) +} + +func TestBidderInfoFromEnv(t *testing.T) { + // setup env vars for testing + if oldval, ok := os.LookupEnv("PBS_ADAPTERS_BIDDER1_DISABLED"); ok { + defer os.Setenv("PBS_ADAPTERS_BIDDER1_DISABLED", oldval) + } else { + defer os.Unsetenv("PBS_ADAPTERS_BIDDER1_DISABLED") + } + + if oldval, ok := os.LookupEnv("PBS_ADAPTERS_BIDDER1_ENDPOINT"); ok { + defer os.Setenv("PBS_ADAPTERS_BIDDER1_ENDPOINT", oldval) + } else { + defer os.Unsetenv("PBS_ADAPTERS_BIDDER1_ENDPOINT") + } + + if oldval, ok := os.LookupEnv("PBS_ADAPTERS_BIDDER1_EXTRA_INFO"); ok { + defer os.Setenv("PBS_ADAPTERS_BIDDER1_EXTRA_INFO", oldval) + } else { + defer os.Unsetenv("PBS_ADAPTERS_BIDDER1_EXTRA_INFO") + } + + if oldval, ok := os.LookupEnv("PBS_ADAPTERS_BIDDER1_DEBUG_ALLOW"); ok { + defer os.Setenv("PBS_ADAPTERS_BIDDER1_DEBUG_ALLOW", oldval) + } else { + defer os.Unsetenv("PBS_ADAPTERS_BIDDER1_DEBUG_ALLOW") + } + + if oldval, ok := os.LookupEnv("PBS_ADAPTERS_BIDDER1_GVLVENDORID"); ok { + defer os.Setenv("PBS_ADAPTERS_BIDDER1_GVLVENDORID", oldval) + } else { + defer os.Unsetenv("PBS_ADAPTERS_BIDDER1_GVLVENDORID") + } + + if oldval, ok := os.LookupEnv("PBS_ADAPTERS_BIDDER1_EXPERIMENT_ADSCERT_ENABLED"); ok { + defer os.Setenv("PBS_ADAPTERS_BIDDER1_EXPERIMENT_ADSCERT_ENABLED", oldval) + } else { + defer os.Unsetenv("PBS_ADAPTERS_BIDDER1_EXPERIMENT_ADSCERT_ENABLED") + } + + if oldval, ok := os.LookupEnv("PBS_ADAPTERS_BIDDER1_XAPI_USERNAME"); ok { + defer os.Setenv("PBS_ADAPTERS_BIDDER1_XAPI_USERNAME", oldval) + } else { + defer os.Unsetenv("PBS_ADAPTERS_BIDDER1_XAPI_USERNAME") + } + + if oldval, ok := os.LookupEnv("PBS_ADAPTERS_BIDDER1_USERSYNC_REDIRECT_URL"); ok { + defer os.Setenv("PBS_ADAPTERS_BIDDER1_USERSYNC_REDIRECT_URL", oldval) + } else { + defer os.Unsetenv("PBS_ADAPTERS_BIDDER1_USERSYNC_REDIRECT_URL") + } + + // set new + os.Setenv("PBS_ADAPTERS_BIDDER1_DISABLED", "true") + os.Setenv("PBS_ADAPTERS_BIDDER1_ENDPOINT", "http://some.url/override") + os.Setenv("PBS_ADAPTERS_BIDDER1_EXTRA_INFO", `{"extrainfo": true}`) + os.Setenv("PBS_ADAPTERS_BIDDER1_DEBUG_ALLOW", "true") + os.Setenv("PBS_ADAPTERS_BIDDER1_GVLVENDORID", "42") + os.Setenv("PBS_ADAPTERS_BIDDER1_EXPERIMENT_ADSCERT_ENABLED", "true") + os.Setenv("PBS_ADAPTERS_BIDDER1_XAPI_USERNAME", "username_override") + os.Setenv("PBS_ADAPTERS_BIDDER1_USERSYNC_REDIRECT_URL", "http://some.url/sync?redirect={{.RedirectURL}}") + + cfg, _ := newDefaultConfig(t) + + assert.Equal(t, true, cfg.BidderInfos["bidder1"].Disabled) + assert.Equal(t, "http://some.url/override", cfg.BidderInfos["bidder1"].Endpoint) + assert.Equal(t, `{"extrainfo": true}`, cfg.BidderInfos["bidder1"].ExtraAdapterInfo) + + assert.Equal(t, true, cfg.BidderInfos["bidder1"].Debug.Allow) + assert.Equal(t, uint16(42), cfg.BidderInfos["bidder1"].GVLVendorID) + + assert.Equal(t, true, cfg.BidderInfos["bidder1"].Experiment.AdsCert.Enabled) + assert.Equal(t, "username_override", cfg.BidderInfos["bidder1"].XAPI.Username) } func TestMigrateConfigPurposeOneTreatment(t *testing.T) { @@ -1535,20 +1583,6 @@ func TestMigrateConfigTCF2EnforcePurposeFlags(t *testing.T) { } } -func TestInvalidAdapterEndpointConfig(t *testing.T) { - v := viper.New() - SetupViper(v, "") - v.Set("gdpr.default_value", "0") - v.SetConfigType("yaml") - v.ReadConfig(bytes.NewBuffer(invalidAdapterEndpointConfig)) - _, err := New(v) - - if assert.IsType(t, errortypes.AggregateError{}, err) { - aggErr := err.(errortypes.AggregateError) - assert.ElementsMatch(t, []error{errors.New("The endpoint: ib.adnxs.com/some/endpoint for appnexus is not a valid URL")}, aggErr.Errors) - } -} - func TestNegativeRequestSize(t *testing.T) { cfg, v := newDefaultConfig(t) cfg.MaxRequestSize = -1 @@ -1712,14 +1746,14 @@ func TestNewCallsRequestValidation(t *testing.T) { for _, test := range testCases { v := viper.New() - SetupViper(v, "") + SetupViper(v, "", bidderInfos) v.Set("gdpr.default_value", "0") v.SetConfigType("yaml") v.ReadConfig(bytes.NewBuffer([]byte( `request_validation: ipv4_private_networks: ` + test.privateIPNetworks))) - result, resultErr := New(v) + result, resultErr := New(v, bidderInfos) if test.expectedError == "" { assert.NoError(t, resultErr, test.description+":err") @@ -1749,59 +1783,12 @@ func TestValidateAccountsConfigRestrictions(t *testing.T) { assert.Contains(t, errs, errors.New("accounts.postgres: retrieving accounts via postgres not available, use accounts.files")) } -func TestUserSyncFromEnv(t *testing.T) { - truePtr := true - - // setup env vars for testing - if oldval, ok := os.LookupEnv("PBS_ADAPTERS_APPNEXUS_USERSYNC_REDIRECT_URL"); ok { - defer os.Setenv("PBS_ADAPTERS_APPNEXUS_USERSYNC_REDIRECT_URL", oldval) - } else { - defer os.Unsetenv("PBS_ADAPTERS_APPNEXUS_USERSYNC_REDIRECT_URL") - } - - if oldval, ok := os.LookupEnv("PBS_ADAPTERS_APPNEXUS_USERSYNC_REDIRECT_USER_MACRO"); ok { - defer os.Setenv("PBS_ADAPTERS_APPNEXUS_USERSYNC_REDIRECT_USER_MACRO", oldval) - } else { - defer os.Unsetenv("PBS_ADAPTERS_APPNEXUS_USERSYNC_REDIRECT_USER_MACRO") - } - - if oldval, ok := os.LookupEnv("PBS_ADAPTERS_APPNEXUS_USERSYNC_SUPPORT_CORS"); ok { - defer os.Setenv("PBS_ADAPTERS_APPNEXUS_USERSYNC_SUPPORT_CORS", oldval) - } else { - defer os.Unsetenv("PBS_ADAPTERS_APPNEXUS_USERSYNC_SUPPORT_CORS") - } - - if oldval, ok := os.LookupEnv("PBS_ADAPTERS_RUBICON_USERSYNC_IFRAME_URL"); ok { - defer os.Setenv("PBS_ADAPTERS_RUBICON_USERSYNC_IFRAME_URL", oldval) - } else { - defer os.Unsetenv("PBS_ADAPTERS_RUBICON_USERSYNC_IFRAME_URL") - } - - // set new - os.Setenv("PBS_ADAPTERS_APPNEXUS_USERSYNC_REDIRECT_URL", "http://some.url/sync?redirect={{.RedirectURL}}") - os.Setenv("PBS_ADAPTERS_APPNEXUS_USERSYNC_REDIRECT_USER_MACRO", "[UID]") - os.Setenv("PBS_ADAPTERS_APPNEXUS_USERSYNC_SUPPORT_CORS", "true") - os.Setenv("PBS_ADAPTERS_RUBICON_USERSYNC_IFRAME_URL", "http://somedifferent.url/sync?redirect={{.RedirectURL}}") - - cfg, _ := newDefaultConfig(t) - assert.Equal(t, cfg.Adapters["appnexus"].Syncer.Redirect.URL, "http://some.url/sync?redirect={{.RedirectURL}}") - assert.Equal(t, cfg.Adapters["appnexus"].Syncer.Redirect.UserMacro, "[UID]") - assert.Nil(t, cfg.Adapters["appnexus"].Syncer.IFrame) - assert.Equal(t, cfg.Adapters["appnexus"].Syncer.SupportCORS, &truePtr) - - assert.Equal(t, cfg.Adapters["rubicon"].Syncer.IFrame.URL, "http://somedifferent.url/sync?redirect={{.RedirectURL}}") - assert.Nil(t, cfg.Adapters["rubicon"].Syncer.Redirect) - assert.Nil(t, cfg.Adapters["rubicon"].Syncer.SupportCORS) - - assert.Nil(t, cfg.Adapters["brightroll"].Syncer) -} - func newDefaultConfig(t *testing.T) (*Configuration, *viper.Viper) { v := viper.New() - SetupViper(v, "") + SetupViper(v, "", bidderInfos) v.Set("gdpr.default_value", "0") v.SetConfigType("yaml") - cfg, err := New(v) + cfg, err := New(v, bidderInfos) assert.NoError(t, err, "Setting up config should work but it doesn't") return cfg, v } @@ -1868,10 +1855,10 @@ func TestSpecialFeature1VendorExceptionMap(t *testing.T) { config := append(baseConfig, tt.configVendorExceptions...) v := viper.New() - SetupViper(v, "") + SetupViper(v, "", bidderInfos) v.SetConfigType("yaml") v.ReadConfig(bytes.NewBuffer(config)) - cfg, err := New(v) + cfg, err := New(v, bidderInfos) assert.NoError(t, err, "Setting up config error", tt.description) assert.Equal(t, tt.wantVendorExceptions, cfg.GDPR.TCF2.SpecialFeature1.VendorExceptions, tt.description) diff --git a/endpoints/events/vtrack.go b/endpoints/events/vtrack.go index 5e6a90249d1..573e3122da8 100644 --- a/endpoints/events/vtrack.go +++ b/endpoints/events/vtrack.go @@ -267,7 +267,7 @@ func isAllowVastForBidder(bidder string, bidderInfos *config.BidderInfos, allowU // check if bidder is configured if b, ok := (*bidderInfos)[bidder]; bidderInfos != nil && ok { // check if bidder is enabled - return b.Enabled && b.ModifyingVastXmlAllowed + return b.IsEnabled() && b.ModifyingVastXmlAllowed } return allowUnknownBidder diff --git a/endpoints/events/vtrack_test.go b/endpoints/events/vtrack_test.go index d8905d7b443..7dd22e60242 100644 --- a/endpoints/events/vtrack_test.go +++ b/endpoints/events/vtrack_test.go @@ -378,11 +378,11 @@ func TestShouldSendToCacheExpectedPutsAndUpdatableBiddersWhenBidderVastNotAllowe // bidder info bidderInfos := make(config.BidderInfos) bidderInfos["bidder"] = config.BidderInfo{ - Enabled: true, + Disabled: false, ModifyingVastXmlAllowed: false, } bidderInfos["updatable_bidder"] = config.BidderInfo{ - Enabled: true, + Disabled: false, ModifyingVastXmlAllowed: true, } @@ -441,11 +441,11 @@ func TestShouldSendToCacheExpectedPutsAndUpdatableBiddersWhenBidderVastAllowed(t // bidder info bidderInfos := make(config.BidderInfos) bidderInfos["bidder"] = config.BidderInfo{ - Enabled: true, + Disabled: false, ModifyingVastXmlAllowed: true, } bidderInfos["updatable_bidder"] = config.BidderInfo{ - Enabled: true, + Disabled: false, ModifyingVastXmlAllowed: true, } diff --git a/endpoints/info/bidders.go b/endpoints/info/bidders.go index 54a9104ec81..989f70b848f 100644 --- a/endpoints/info/bidders.go +++ b/endpoints/info/bidders.go @@ -79,13 +79,13 @@ func prepareBiddersResponseEnabledOnly(bidders config.BidderInfos, aliases map[s bidderNames := make([]string, 0, len(bidders)+len(aliases)) for name, info := range bidders { - if info.Enabled { + if info.IsEnabled() { bidderNames = append(bidderNames, name) } } for name, bidder := range aliases { - if info, ok := bidders[bidder]; ok && info.Enabled { + if info, ok := bidders[bidder]; ok && info.IsEnabled() { bidderNames = append(bidderNames, name) } } diff --git a/endpoints/info/bidders_detail.go b/endpoints/info/bidders_detail.go index 04bc9b04fca..1446e3ac22a 100644 --- a/endpoints/info/bidders_detail.go +++ b/endpoints/info/bidders_detail.go @@ -18,8 +18,8 @@ const ( ) // NewBiddersDetailEndpoint builds a handler for the /info/bidders/ endpoint. -func NewBiddersDetailEndpoint(bidders config.BidderInfos, biddersConfig map[string]config.Adapter, aliases map[string]string) httprouter.Handle { - responses, err := prepareBiddersDetailResponse(bidders, biddersConfig, aliases) +func NewBiddersDetailEndpoint(bidders config.BidderInfos, aliases map[string]string) httprouter.Handle { + responses, err := prepareBiddersDetailResponse(bidders, aliases) if err != nil { glog.Fatalf("error creating /info/bidders/ endpoint response: %v", err) } @@ -38,8 +38,8 @@ func NewBiddersDetailEndpoint(bidders config.BidderInfos, biddersConfig map[stri } } -func prepareBiddersDetailResponse(bidders config.BidderInfos, biddersConfig map[string]config.Adapter, aliases map[string]string) (map[string][]byte, error) { - details, err := mapDetails(bidders, biddersConfig, aliases) +func prepareBiddersDetailResponse(bidders config.BidderInfos, aliases map[string]string) (map[string][]byte, error) { + details, err := mapDetails(bidders, aliases) if err != nil { return nil, err } @@ -58,12 +58,11 @@ func prepareBiddersDetailResponse(bidders config.BidderInfos, biddersConfig map[ return responses, nil } -func mapDetails(bidders config.BidderInfos, biddersConfig map[string]config.Adapter, aliases map[string]string) (map[string]bidderDetail, error) { +func mapDetails(bidders config.BidderInfos, aliases map[string]string) (map[string]bidderDetail, error) { details := map[string]bidderDetail{} for bidderName, bidderInfo := range bidders { - endpoint := resolveEndpoint(bidderName, biddersConfig) - details[bidderName] = mapDetailFromConfig(bidderInfo, endpoint) + details[bidderName] = mapDetailFromConfig(bidderInfo) } for aliasName, bidderName := range aliases { @@ -80,14 +79,6 @@ func mapDetails(bidders config.BidderInfos, biddersConfig map[string]config.Adap return details, nil } -func resolveEndpoint(bidder string, biddersConfig map[string]config.Adapter) string { - if c, found := biddersConfig[bidder]; found { - return c.Endpoint - } - - return "" -} - func marshalDetailsResponse(details map[string]bidderDetail) (map[string][]byte, error) { responses := map[string][]byte{} @@ -137,7 +128,7 @@ type platform struct { MediaTypes []string `json:"mediaTypes"` } -func mapDetailFromConfig(c config.BidderInfo, endpoint string) bidderDetail { +func mapDetailFromConfig(c config.BidderInfo) bidderDetail { var bidderDetail bidderDetail if c.Maintainer != nil { @@ -146,10 +137,10 @@ func mapDetailFromConfig(c config.BidderInfo, endpoint string) bidderDetail { } } - if c.Enabled { + if c.IsEnabled() { bidderDetail.Status = statusActive - usesHTTPS := strings.HasPrefix(strings.ToLower(endpoint), "https://") + usesHTTPS := strings.HasPrefix(strings.ToLower(c.Endpoint), "https://") bidderDetail.UsesHTTPS = &usesHTTPS if c.Capabilities != nil { diff --git a/endpoints/info/bidders_detail_test.go b/endpoints/info/bidders_detail_test.go index d8b6f2bf4ad..5a3a0fca6aa 100644 --- a/endpoints/info/bidders_detail_test.go +++ b/endpoints/info/bidders_detail_test.go @@ -14,12 +14,10 @@ import ( ) func TestPrepareBiddersDetailResponse(t *testing.T) { - bidderAInfo := config.BidderInfo{Enabled: true, Maintainer: &config.MaintainerInfo{Email: "bidderA"}} - bidderAConfig := config.Adapter{Endpoint: "https://secureEndpoint.com"} + bidderAInfo := config.BidderInfo{Endpoint: "https://secureEndpoint.com", Disabled: false, Maintainer: &config.MaintainerInfo{Email: "bidderA"}} bidderAResponse := []byte(`{"status":"ACTIVE","usesHttps":true,"maintainer":{"email":"bidderA"}}`) - bidderBInfo := config.BidderInfo{Enabled: true, Maintainer: &config.MaintainerInfo{Email: "bidderB"}} - bidderBConfig := config.Adapter{Endpoint: "http://unsecureEndpoint.com"} + bidderBInfo := config.BidderInfo{Endpoint: "http://unsecureEndpoint.com", Disabled: false, Maintainer: &config.MaintainerInfo{Email: "bidderB"}} bidderBResponse := []byte(`{"status":"ACTIVE","usesHttps":false,"maintainer":{"email":"bidderB"}}`) allResponseBidderA := bytes.Buffer{} @@ -35,45 +33,40 @@ func TestPrepareBiddersDetailResponse(t *testing.T) { allResponseBidderAB.WriteString(`}`) var testCases = []struct { - description string - givenBidders config.BidderInfos - givenBiddersConfig map[string]config.Adapter - givenAliases map[string]string - expectedResponses map[string][]byte - expectedError string + description string + givenBidders config.BidderInfos + givenAliases map[string]string + expectedResponses map[string][]byte + expectedError string }{ { - description: "None", - givenBidders: config.BidderInfos{}, - givenBiddersConfig: map[string]config.Adapter{}, - givenAliases: map[string]string{}, - expectedResponses: map[string][]byte{"all": []byte(`{}`)}, + description: "None", + givenBidders: config.BidderInfos{}, + givenAliases: map[string]string{}, + expectedResponses: map[string][]byte{"all": []byte(`{}`)}, }, { - description: "One", - givenBidders: config.BidderInfos{"a": bidderAInfo}, - givenBiddersConfig: map[string]config.Adapter{"a": bidderAConfig}, - givenAliases: map[string]string{}, - expectedResponses: map[string][]byte{"a": bidderAResponse, "all": allResponseBidderA.Bytes()}, + description: "One", + givenBidders: config.BidderInfos{"a": bidderAInfo}, + givenAliases: map[string]string{}, + expectedResponses: map[string][]byte{"a": bidderAResponse, "all": allResponseBidderA.Bytes()}, }, { - description: "Many", - givenBidders: config.BidderInfos{"a": bidderAInfo, "b": bidderBInfo}, - givenBiddersConfig: map[string]config.Adapter{"a": bidderAConfig, "b": bidderBConfig}, - givenAliases: map[string]string{}, - expectedResponses: map[string][]byte{"a": bidderAResponse, "b": bidderBResponse, "all": allResponseBidderAB.Bytes()}, + description: "Many", + givenBidders: config.BidderInfos{"a": bidderAInfo, "b": bidderBInfo}, + givenAliases: map[string]string{}, + expectedResponses: map[string][]byte{"a": bidderAResponse, "b": bidderBResponse, "all": allResponseBidderAB.Bytes()}, }, { - description: "Error - Map Details", // Returns error due to invalid alias. - givenBidders: config.BidderInfos{"a": bidderAInfo}, - givenBiddersConfig: map[string]config.Adapter{"a": bidderAConfig}, - givenAliases: map[string]string{"zAlias": "z"}, - expectedError: "base adapter z for alias zAlias not found", + description: "Error - Map Details", // Returns error due to invalid alias. + givenBidders: config.BidderInfos{"a": bidderAInfo}, + givenAliases: map[string]string{"zAlias": "z"}, + expectedError: "base adapter z for alias zAlias not found", }, } for _, test := range testCases { - responses, err := prepareBiddersDetailResponse(test.givenBidders, test.givenBiddersConfig, test.givenAliases) + responses, err := prepareBiddersDetailResponse(test.givenBidders, test.givenAliases) if test.expectedError == "" { assert.Equal(t, test.expectedResponses, responses, test.description+":responses") @@ -89,77 +82,67 @@ func TestMapDetails(t *testing.T) { trueValue := true falseValue := false - bidderAInfo := config.BidderInfo{Enabled: true, Maintainer: &config.MaintainerInfo{Email: "bidderA"}} - bidderAConfig := config.Adapter{Endpoint: "https://secureEndpoint.com"} + bidderAInfo := config.BidderInfo{Endpoint: "https://secureEndpoint.com", Disabled: false, Maintainer: &config.MaintainerInfo{Email: "bidderA"}} bidderADetail := bidderDetail{Status: "ACTIVE", UsesHTTPS: &trueValue, Maintainer: &maintainer{Email: "bidderA"}} aliasADetail := bidderDetail{Status: "ACTIVE", UsesHTTPS: &trueValue, Maintainer: &maintainer{Email: "bidderA"}, AliasOf: "a"} - bidderBInfo := config.BidderInfo{Enabled: true, Maintainer: &config.MaintainerInfo{Email: "bidderB"}} - bidderBConfig := config.Adapter{Endpoint: "http://unsecureEndpoint.com"} + bidderBInfo := config.BidderInfo{Endpoint: "http://unsecureEndpoint.com", Disabled: false, Maintainer: &config.MaintainerInfo{Email: "bidderB"}} bidderBDetail := bidderDetail{Status: "ACTIVE", UsesHTTPS: &falseValue, Maintainer: &maintainer{Email: "bidderB"}} aliasBDetail := bidderDetail{Status: "ACTIVE", UsesHTTPS: &falseValue, Maintainer: &maintainer{Email: "bidderB"}, AliasOf: "b"} var testCases = []struct { - description string - givenBidders config.BidderInfos - givenBiddersConfig map[string]config.Adapter - givenAliases map[string]string - expectedDetails map[string]bidderDetail - expectedError string + description string + givenBidders config.BidderInfos + givenAliases map[string]string + expectedDetails map[string]bidderDetail + expectedError string }{ { - description: "None", - givenBidders: config.BidderInfos{}, - givenBiddersConfig: map[string]config.Adapter{}, - givenAliases: map[string]string{}, - expectedDetails: map[string]bidderDetail{}, + description: "None", + givenBidders: config.BidderInfos{}, + givenAliases: map[string]string{}, + expectedDetails: map[string]bidderDetail{}, }, { - description: "One Core Bidder", - givenBidders: config.BidderInfos{"a": bidderAInfo}, - givenBiddersConfig: map[string]config.Adapter{"a": bidderAConfig}, - givenAliases: map[string]string{}, - expectedDetails: map[string]bidderDetail{"a": bidderADetail}, + description: "One Core Bidder", + givenBidders: config.BidderInfos{"a": bidderAInfo}, + givenAliases: map[string]string{}, + expectedDetails: map[string]bidderDetail{"a": bidderADetail}, }, { - description: "Many Core Bidders", - givenBidders: config.BidderInfos{"a": bidderAInfo, "b": bidderBInfo}, - givenBiddersConfig: map[string]config.Adapter{"a": bidderAConfig, "b": bidderBConfig}, - givenAliases: map[string]string{}, - expectedDetails: map[string]bidderDetail{"a": bidderADetail, "b": bidderBDetail}, + description: "Many Core Bidders", + givenBidders: config.BidderInfos{"a": bidderAInfo, "b": bidderBInfo}, + givenAliases: map[string]string{}, + expectedDetails: map[string]bidderDetail{"a": bidderADetail, "b": bidderBDetail}, }, { - description: "One Alias", - givenBidders: config.BidderInfos{"a": bidderAInfo}, - givenBiddersConfig: map[string]config.Adapter{"a": bidderAConfig}, - givenAliases: map[string]string{"aAlias": "a"}, - expectedDetails: map[string]bidderDetail{"a": bidderADetail, "aAlias": aliasADetail}, + description: "One Alias", + givenBidders: config.BidderInfos{"a": bidderAInfo}, + givenAliases: map[string]string{"aAlias": "a"}, + expectedDetails: map[string]bidderDetail{"a": bidderADetail, "aAlias": aliasADetail}, }, { - description: "Many Aliases - Same Core Bidder", - givenBidders: config.BidderInfos{"a": bidderAInfo}, - givenBiddersConfig: map[string]config.Adapter{"a": bidderAConfig}, - givenAliases: map[string]string{"aAlias1": "a", "aAlias2": "a"}, - expectedDetails: map[string]bidderDetail{"a": bidderADetail, "aAlias1": aliasADetail, "aAlias2": aliasADetail}, + description: "Many Aliases - Same Core Bidder", + givenBidders: config.BidderInfos{"a": bidderAInfo}, + givenAliases: map[string]string{"aAlias1": "a", "aAlias2": "a"}, + expectedDetails: map[string]bidderDetail{"a": bidderADetail, "aAlias1": aliasADetail, "aAlias2": aliasADetail}, }, { - description: "Many Aliases - Different Core Bidders", - givenBidders: config.BidderInfos{"a": bidderAInfo, "b": bidderBInfo}, - givenBiddersConfig: map[string]config.Adapter{"a": bidderAConfig, "b": bidderBConfig}, - givenAliases: map[string]string{"aAlias": "a", "bAlias": "b"}, - expectedDetails: map[string]bidderDetail{"a": bidderADetail, "b": bidderBDetail, "aAlias": aliasADetail, "bAlias": aliasBDetail}, + description: "Many Aliases - Different Core Bidders", + givenBidders: config.BidderInfos{"a": bidderAInfo, "b": bidderBInfo}, + givenAliases: map[string]string{"aAlias": "a", "bAlias": "b"}, + expectedDetails: map[string]bidderDetail{"a": bidderADetail, "b": bidderBDetail, "aAlias": aliasADetail, "bAlias": aliasBDetail}, }, { - description: "Error - Alias Without Core Bidder", - givenBidders: config.BidderInfos{"a": bidderAInfo}, - givenBiddersConfig: map[string]config.Adapter{"a": bidderAConfig}, - givenAliases: map[string]string{"zAlias": "z"}, - expectedError: "base adapter z for alias zAlias not found", + description: "Error - Alias Without Core Bidder", + givenBidders: config.BidderInfos{"a": bidderAInfo}, + givenAliases: map[string]string{"zAlias": "z"}, + expectedError: "base adapter z for alias zAlias not found", }, } for _, test := range testCases { - details, err := mapDetails(test.givenBidders, test.givenBiddersConfig, test.givenAliases) + details, err := mapDetails(test.givenBidders, test.givenAliases) if test.expectedError == "" { assert.Equal(t, test.expectedDetails, details, test.description+":details") @@ -171,33 +154,6 @@ func TestMapDetails(t *testing.T) { } } -func TestResolveEndpoint(t *testing.T) { - var testCases = []struct { - description string - givenBidder string - givenBiddersConfig map[string]config.Adapter - expectedEndpoint string - }{ - { - description: "Bidder Found - Uses Config Value", - givenBidder: "a", - givenBiddersConfig: map[string]config.Adapter{"a": {Endpoint: "anyEndpoint"}}, - expectedEndpoint: "anyEndpoint", - }, - { - description: "Bidder Not Found - Returns Empty", - givenBidder: "hasNoConfig", - givenBiddersConfig: map[string]config.Adapter{"a": {Endpoint: "anyEndpoint"}}, - expectedEndpoint: "", - }, - } - - for _, test := range testCases { - result := resolveEndpoint(test.givenBidder, test.givenBiddersConfig) - assert.Equal(t, test.expectedEndpoint, result, test.description) - } -} - func TestMarshalDetailsResponse(t *testing.T) { // Verifies omitempty is working correctly for bidderDetail, maintainer, capabilities, and aliasOf. bidderDetailA := bidderDetail{Status: "ACTIVE", Maintainer: &maintainer{Email: "bidderA"}} @@ -256,13 +212,13 @@ func TestMapDetailFromConfig(t *testing.T) { var testCases = []struct { description string givenBidderInfo config.BidderInfo - givenEndpoint string expected bidderDetail }{ { description: "Enabled - All Values Present", givenBidderInfo: config.BidderInfo{ - Enabled: true, + Endpoint: "http://anyEndpoint", + Disabled: false, Maintainer: &config.MaintainerInfo{ Email: "foo@bar.com", }, @@ -271,7 +227,6 @@ func TestMapDetailFromConfig(t *testing.T) { Site: &config.PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeVideo}}, }, }, - givenEndpoint: "http://amyEndpoint", expected: bidderDetail{ Status: "ACTIVE", UsesHTTPS: &falseValue, @@ -288,7 +243,8 @@ func TestMapDetailFromConfig(t *testing.T) { { description: "Disabled - All Values Present", givenBidderInfo: config.BidderInfo{ - Enabled: false, + Endpoint: "http://anyEndpoint", + Disabled: true, Maintainer: &config.MaintainerInfo{ Email: "foo@bar.com", }, @@ -297,7 +253,6 @@ func TestMapDetailFromConfig(t *testing.T) { Site: &config.PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeVideo}}, }, }, - givenEndpoint: "http://amyEndpoint", expected: bidderDetail{ Status: "DISABLED", UsesHTTPS: nil, @@ -311,9 +266,9 @@ func TestMapDetailFromConfig(t *testing.T) { { description: "Enabled - No Values Present", givenBidderInfo: config.BidderInfo{ - Enabled: true, + Endpoint: "http://amyEndpoint", + Disabled: false, }, - givenEndpoint: "http://amyEndpoint", expected: bidderDetail{ Status: "ACTIVE", UsesHTTPS: &falseValue, @@ -322,9 +277,9 @@ func TestMapDetailFromConfig(t *testing.T) { { description: "Enabled - Protocol - HTTP", givenBidderInfo: config.BidderInfo{ - Enabled: true, + Endpoint: "http://amyEndpoint", + Disabled: false, }, - givenEndpoint: "http://amyEndpoint", expected: bidderDetail{ Status: "ACTIVE", UsesHTTPS: &falseValue, @@ -333,9 +288,9 @@ func TestMapDetailFromConfig(t *testing.T) { { description: "Enabled - Protocol - HTTPS", givenBidderInfo: config.BidderInfo{ - Enabled: true, + Endpoint: "https://amyEndpoint", + Disabled: false, }, - givenEndpoint: "https://amyEndpoint", expected: bidderDetail{ Status: "ACTIVE", UsesHTTPS: &trueValue, @@ -344,9 +299,9 @@ func TestMapDetailFromConfig(t *testing.T) { { description: "Enabled - Protocol - HTTPS - Case Insensitive", givenBidderInfo: config.BidderInfo{ - Enabled: true, + Disabled: false, + Endpoint: "https://amyEndpoint", }, - givenEndpoint: "https://amyEndpoint", expected: bidderDetail{ Status: "ACTIVE", UsesHTTPS: &trueValue, @@ -355,9 +310,9 @@ func TestMapDetailFromConfig(t *testing.T) { { description: "Enabled - Protocol - Unknown", givenBidderInfo: config.BidderInfo{ - Enabled: true, + Endpoint: "endpointWithoutProtocol", + Disabled: false, }, - givenEndpoint: "endpointWithoutProtocol", expected: bidderDetail{ Status: "ACTIVE", UsesHTTPS: &falseValue, @@ -366,7 +321,7 @@ func TestMapDetailFromConfig(t *testing.T) { } for _, test := range testCases { - result := mapDetailFromConfig(test.givenBidderInfo, test.givenEndpoint) + result := mapDetailFromConfig(test.givenBidderInfo) assert.Equal(t, test.expected, result, test.description) } } @@ -406,13 +361,11 @@ func TestMapMediaTypes(t *testing.T) { } func TestBiddersDetailHandler(t *testing.T) { - bidderAInfo := config.BidderInfo{Enabled: true, Maintainer: &config.MaintainerInfo{Email: "bidderA"}} - bidderAConfig := config.Adapter{Endpoint: "https://secureEndpoint.com"} + bidderAInfo := config.BidderInfo{Endpoint: "https://secureEndpoint.com", Disabled: false, Maintainer: &config.MaintainerInfo{Email: "bidderA"}} bidderAResponse := []byte(`{"status":"ACTIVE","usesHttps":true,"maintainer":{"email":"bidderA"}}`) aliasAResponse := []byte(`{"status":"ACTIVE","usesHttps":true,"maintainer":{"email":"bidderA"},"aliasOf":"a"}`) - bidderBInfo := config.BidderInfo{Enabled: true, Maintainer: &config.MaintainerInfo{Email: "bidderB"}} - bidderBConfig := config.Adapter{Endpoint: "http://unsecureEndpoint.com"} + bidderBInfo := config.BidderInfo{Endpoint: "http://unsecureEndpoint.com", Disabled: false, Maintainer: &config.MaintainerInfo{Email: "bidderB"}} bidderBResponse := []byte(`{"status":"ACTIVE","usesHttps":false,"maintainer":{"email":"bidderB"}}`) allResponse := bytes.Buffer{} @@ -425,10 +378,9 @@ func TestBiddersDetailHandler(t *testing.T) { allResponse.WriteString(`}`) bidders := config.BidderInfos{"a": bidderAInfo, "b": bidderBInfo} - biddersConfig := map[string]config.Adapter{"a": bidderAConfig, "b": bidderBConfig} aliases := map[string]string{"aAlias": "a"} - handler := NewBiddersDetailEndpoint(bidders, biddersConfig, aliases) + handler := NewBiddersDetailEndpoint(bidders, aliases) var testCases = []struct { description string diff --git a/endpoints/info/bidders_test.go b/endpoints/info/bidders_test.go index 9be25f44c4f..ff069c98c8c 100644 --- a/endpoints/info/bidders_test.go +++ b/endpoints/info/bidders_test.go @@ -12,8 +12,8 @@ import ( func TestPrepareBiddersResponseAll(t *testing.T) { var ( - enabled = config.BidderInfo{Enabled: true} - disabled = config.BidderInfo{Enabled: false} + enabled = config.BidderInfo{Disabled: false} + disabled = config.BidderInfo{Disabled: true} ) testCases := []struct { @@ -88,8 +88,8 @@ func TestPrepareBiddersResponseAll(t *testing.T) { func TestPrepareBiddersResponseEnabledOnly(t *testing.T) { var ( - enabled = config.BidderInfo{Enabled: true} - disabled = config.BidderInfo{Enabled: false} + enabled = config.BidderInfo{Disabled: false} + disabled = config.BidderInfo{Disabled: true} ) testCases := []struct { @@ -164,8 +164,8 @@ func TestPrepareBiddersResponseEnabledOnly(t *testing.T) { func TestBiddersHandler(t *testing.T) { var ( - enabled = config.BidderInfo{Enabled: true} - disabled = config.BidderInfo{Enabled: false} + enabled = config.BidderInfo{Disabled: false} + disabled = config.BidderInfo{Disabled: true} ) bidders := config.BidderInfos{"a": enabled, "b": disabled} diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index 4b16379a72e..ea047397bd7 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -414,9 +414,8 @@ func doBadAliasRequest(t *testing.T, filename string, expectMsg string) { // aliasJSON lacks a comma after the "appnexus" entry so is bad JSON aliasJSON := []byte(`{"ext":{"prebid":{"aliases": {"test1": "appnexus" "test2": "rubicon", "test3": "openx"}}}}`) - adaptersConfigs := make(map[string]config.Adapter) - bidderInfos := getBidderInfos(adaptersConfigs, openrtb_ext.CoreBidderNames()) + bidderInfos := getBidderInfos(nil, openrtb_ext.CoreBidderNames()) bidderMap := exchange.GetActiveBidders(bidderInfos) disabledBidders := exchange.GetDisabledBiddersErrorMessages(bidderInfos) diff --git a/endpoints/openrtb2/test_utils.go b/endpoints/openrtb2/test_utils.go index db70852cc51..c1cd1320c16 100644 --- a/endpoints/openrtb2/test_utils.go +++ b/endpoints/openrtb2/test_utils.go @@ -1064,21 +1064,24 @@ func (a mockAdapter) MakeBids(request *openrtb2.BidRequest, requestData *adapter // Auxiliary functions that don't make assertions and don't // take t *testing.T as parameter // --------------------------------------------------------- -func getBidderInfos(cfg map[string]config.Adapter, biddersNames []openrtb_ext.BidderName) config.BidderInfos { +func getBidderInfos(disabledAdapters []string, biddersNames []openrtb_ext.BidderName) config.BidderInfos { biddersInfos := make(config.BidderInfos) for _, name := range biddersNames { - adapterConfig, ok := cfg[string(name)] - if !ok { - adapterConfig = config.Adapter{} + isDisabled := false + for _, disabledAdapter := range disabledAdapters { + if string(name) == disabledAdapter { + isDisabled = true + break + } } - biddersInfos[string(name)] = newBidderInfo(adapterConfig) + biddersInfos[string(name)] = newBidderInfo(isDisabled) } return biddersInfos } -func newBidderInfo(cfg config.Adapter) config.BidderInfo { +func newBidderInfo(isDisabled bool) config.BidderInfo { return config.BidderInfo{ - Enabled: !cfg.Disabled, + Disabled: isDisabled, } } @@ -1165,18 +1168,6 @@ func (tc *testConfigValues) getBlackListedAccountMap() map[string]bool { return blacklistedAccountMap } -func (tc *testConfigValues) getAdaptersConfigMap() map[string]config.Adapter { - var adaptersConfig map[string]config.Adapter - - if len(tc.DisabledAdapters) > 0 { - adaptersConfig = make(map[string]config.Adapter, len(tc.DisabledAdapters)) - for _, adapterName := range tc.DisabledAdapters { - adaptersConfig[adapterName] = config.Adapter{Disabled: true} - } - } - return adaptersConfig -} - // exchangeTestWrapper is a wrapper that asserts the openrtb2 bid request just before the HoldAuction call type exchangeTestWrapper struct { ex exchange.Exchange @@ -1258,7 +1249,7 @@ func buildTestEndpoint(test testCase, cfg *config.Configuration) (httprouter.Han paramValidator = mockBidderParamValidator{} } - bidderInfos := getBidderInfos(test.Config.getAdaptersConfigMap(), openrtb_ext.CoreBidderNames()) + bidderInfos := getBidderInfos(test.Config.DisabledAdapters, openrtb_ext.CoreBidderNames()) bidderMap := exchange.GetActiveBidders(bidderInfos) disabledBidders := exchange.GetDisabledBiddersErrorMessages(bidderInfos) met := &metricsConfig.NilMetricsEngine{} diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index 6ecac1ea51a..81f744cdaf5 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -11,7 +11,7 @@ import ( ) func BuildAdapters(client *http.Client, cfg *config.Configuration, infos config.BidderInfos, me metrics.MetricsEngine) (map[openrtb_ext.BidderName]AdaptedBidder, []error) { - bidders, errs := buildBidders(cfg.Adapters, infos, newAdapterBuilders()) + bidders, errs := buildBidders(infos, newAdapterBuilders()) if len(errs) > 0 { return nil, errs } @@ -26,11 +26,11 @@ func BuildAdapters(client *http.Client, cfg *config.Configuration, infos config. return exchangeBidders, nil } -func buildBidders(adapterConfig map[string]config.Adapter, infos config.BidderInfos, builders map[openrtb_ext.BidderName]adapters.Builder) (map[openrtb_ext.BidderName]adapters.Bidder, []error) { +func buildBidders(infos config.BidderInfos, builders map[openrtb_ext.BidderName]adapters.Builder) (map[openrtb_ext.BidderName]adapters.Bidder, []error) { bidders := make(map[openrtb_ext.BidderName]adapters.Bidder) var errs []error - for bidder, cfg := range adapterConfig { + for bidder := range infos { bidderName, bidderNameFound := openrtb_ext.NormalizeBidderName(bidder) if !bidderNameFound { errs = append(errs, fmt.Errorf("%v: unknown bidder", bidder)) @@ -49,8 +49,9 @@ func buildBidders(adapterConfig map[string]config.Adapter, infos config.BidderIn continue } - if info.Enabled { - bidderInstance, builderErr := builder(bidderName, cfg) + if info.IsEnabled() { + adapterInfo := buildAdapterInfo(info) + bidderInstance, builderErr := builder(bidderName, adapterInfo) if builderErr != nil { errs = append(errs, fmt.Errorf("%v: %v", bidder, builderErr)) continue @@ -62,12 +63,22 @@ func buildBidders(adapterConfig map[string]config.Adapter, infos config.BidderIn return bidders, errs } +func buildAdapterInfo(bidderInfo config.BidderInfo) config.Adapter { + adapter := config.Adapter{} + adapter.Endpoint = bidderInfo.Endpoint + adapter.ExtraAdapterInfo = bidderInfo.ExtraAdapterInfo + adapter.PlatformID = bidderInfo.PlatformID + adapter.AppSecret = bidderInfo.AppSecret + adapter.XAPI = bidderInfo.XAPI + return adapter +} + // GetActiveBidders returns a map of all active bidder names. func GetActiveBidders(infos config.BidderInfos) map[string]openrtb_ext.BidderName { activeBidders := make(map[string]openrtb_ext.BidderName) for name, info := range infos { - if info.Enabled { + if info.IsEnabled() { activeBidders[name] = openrtb_ext.BidderName(name) } } @@ -85,7 +96,7 @@ func GetDisabledBiddersErrorMessages(infos config.BidderInfos) map[string]string } for name, info := range infos { - if !info.Enabled { + if info.Disabled { msg := fmt.Sprintf(`Bidder "%s" has been disabled on this instance of Prebid Server. Please work with the PBS host to enable this bidder again.`, name) disabledBidders[name] = msg } diff --git a/exchange/adapter_util_test.go b/exchange/adapter_util_test.go index 5266e67e3b6..fd22e3c5102 100644 --- a/exchange/adapter_util_test.go +++ b/exchange/adapter_util_test.go @@ -16,8 +16,8 @@ import ( ) var ( - infoEnabled = config.BidderInfo{Enabled: true} - infoDisabled = config.BidderInfo{Enabled: false} + infoEnabled = config.BidderInfo{Disabled: false} + infoDisabled = config.BidderInfo{Disabled: true} ) func TestBuildAdapters(t *testing.T) { @@ -32,51 +32,46 @@ func TestBuildAdapters(t *testing.T) { rubiconBidder, _ := rubicon.Builder(openrtb_ext.BidderRubicon, config.Adapter{}) rubiconBidderWithInfo := adapters.BuildInfoAwareBidder(rubiconBidder, infoEnabled) rubiconBidderAdapted := AdaptBidder(rubiconBidderWithInfo, client, &config.Configuration{}, metricEngine, openrtb_ext.BidderRubicon, nil, "") - rubiconbidderValidated := addValidatedBidderMiddleware(rubiconBidderAdapted) + rubiconBidderValidated := addValidatedBidderMiddleware(rubiconBidderAdapted) testCases := []struct { description string - adapterConfig map[string]config.Adapter bidderInfos map[string]config.BidderInfo expectedBidders map[openrtb_ext.BidderName]AdaptedBidder expectedErrors []error }{ { description: "No Bidders", - adapterConfig: map[string]config.Adapter{}, bidderInfos: map[string]config.BidderInfo{}, expectedBidders: map[openrtb_ext.BidderName]AdaptedBidder{}, }, { - description: "One Bidder", - adapterConfig: map[string]config.Adapter{"appnexus": {}}, - bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled}, + description: "One Bidder", + bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled}, expectedBidders: map[openrtb_ext.BidderName]AdaptedBidder{ openrtb_ext.BidderAppnexus: appnexusValidated, }, }, { - description: "Many Bidders", - adapterConfig: map[string]config.Adapter{"appnexus": {}, "rubicon": {}}, - bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled, "rubicon": infoEnabled}, + description: "Many Bidders", + bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled, "rubicon": infoEnabled}, expectedBidders: map[openrtb_ext.BidderName]AdaptedBidder{ openrtb_ext.BidderAppnexus: appnexusValidated, - openrtb_ext.BidderRubicon: rubiconbidderValidated, + openrtb_ext.BidderRubicon: rubiconBidderValidated, }, }, { - description: "Invalid - Builder Errors", - adapterConfig: map[string]config.Adapter{"appnexus": {}, "unknown": {}}, - bidderInfos: map[string]config.BidderInfo{}, + description: "Invalid - Builder Errors", + bidderInfos: map[string]config.BidderInfo{"unknown": {}, "appNexus": {}}, expectedErrors: []error{ - errors.New("appnexus: bidder info not found"), + errors.New("appNexus: bidder info not found"), errors.New("unknown: unknown bidder"), }, }, } + cfg := &config.Configuration{} for _, test := range testCases { - cfg := &config.Configuration{Adapters: test.adapterConfig} bidders, errs := BuildAdapters(client, cfg, test.bidderInfos, metricEngine) assert.Equal(t, test.expectedBidders, bidders, test.description+":bidders") assert.ElementsMatch(t, test.expectedErrors, errs, test.description+":errors") @@ -93,95 +88,77 @@ func TestBuildBidders(t *testing.T) { testCases := []struct { description string - adapterConfig map[string]config.Adapter bidderInfos map[string]config.BidderInfo builders map[openrtb_ext.BidderName]adapters.Builder expectedBidders map[openrtb_ext.BidderName]adapters.Bidder expectedErrors []error }{ { - description: "Invalid - Unknown Bidder", - adapterConfig: map[string]config.Adapter{"unknown": {}}, - bidderInfos: map[string]config.BidderInfo{"unknown": infoEnabled}, - builders: map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder}, + description: "Invalid - Unknown Bidder", + bidderInfos: map[string]config.BidderInfo{"unknown": infoEnabled}, + builders: map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder}, expectedErrors: []error{ errors.New("unknown: unknown bidder"), }, }, { - description: "Invalid - No Bidder Info", - adapterConfig: map[string]config.Adapter{"appnexus": {}}, - bidderInfos: map[string]config.BidderInfo{}, - builders: map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder}, + description: "Invalid - No Bidder Info", + bidderInfos: map[string]config.BidderInfo{"appNexus": {}}, + builders: map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder}, expectedErrors: []error{ - errors.New("appnexus: bidder info not found"), + errors.New("appNexus: bidder info not found"), }, }, { - description: "Invalid - No Builder", - adapterConfig: map[string]config.Adapter{"appnexus": {}}, - bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled}, - builders: map[openrtb_ext.BidderName]adapters.Builder{}, + description: "Invalid - No Builder", + bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled}, + builders: map[openrtb_ext.BidderName]adapters.Builder{}, expectedErrors: []error{ errors.New("appnexus: builder not registered"), }, }, { - description: "Success - Builder Error", - adapterConfig: map[string]config.Adapter{"appnexus": {}}, - bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled}, - builders: map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilderWithError}, + description: "Success - Builder Error", + bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled}, + builders: map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilderWithError}, expectedErrors: []error{ errors.New("appnexus: anyError"), }, }, { - description: "Success - None", - adapterConfig: map[string]config.Adapter{}, - bidderInfos: map[string]config.BidderInfo{}, - builders: map[openrtb_ext.BidderName]adapters.Builder{}, + description: "Success - None", + bidderInfos: map[string]config.BidderInfo{}, + builders: map[openrtb_ext.BidderName]adapters.Builder{}, }, { - description: "Success - One", - adapterConfig: map[string]config.Adapter{"appnexus": {}}, - bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled}, - builders: map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder}, + description: "Success - One", + bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled}, + builders: map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder}, expectedBidders: map[openrtb_ext.BidderName]adapters.Bidder{ openrtb_ext.BidderAppnexus: adapters.BuildInfoAwareBidder(appnexusBidder, infoEnabled), }, }, { - description: "Success - Many", - adapterConfig: map[string]config.Adapter{"appnexus": {}, "rubicon": {}}, - bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled, "rubicon": infoEnabled}, - builders: map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder, openrtb_ext.BidderRubicon: rubiconBuilder}, + description: "Success - Many", + bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled, "rubicon": infoEnabled}, + builders: map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder, openrtb_ext.BidderRubicon: rubiconBuilder}, expectedBidders: map[openrtb_ext.BidderName]adapters.Bidder{ openrtb_ext.BidderAppnexus: adapters.BuildInfoAwareBidder(appnexusBidder, infoEnabled), openrtb_ext.BidderRubicon: adapters.BuildInfoAwareBidder(rubiconBidder, infoEnabled), }, }, { - description: "Success - Ignores Disabled", - adapterConfig: map[string]config.Adapter{"appnexus": {}, "rubicon": {}}, - bidderInfos: map[string]config.BidderInfo{"appnexus": infoDisabled, "rubicon": infoEnabled}, - builders: map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder, openrtb_ext.BidderRubicon: rubiconBuilder}, + description: "Success - Ignores Disabled", + bidderInfos: map[string]config.BidderInfo{"appnexus": infoDisabled, "rubicon": infoEnabled}, + builders: map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder, openrtb_ext.BidderRubicon: rubiconBuilder}, expectedBidders: map[openrtb_ext.BidderName]adapters.Bidder{ openrtb_ext.BidderRubicon: adapters.BuildInfoAwareBidder(rubiconBidder, infoEnabled), }, }, - { - description: "Success - Ignores Adapter Config Case", - adapterConfig: map[string]config.Adapter{"AppNexus": {}}, - bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled}, - builders: map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder}, - expectedBidders: map[openrtb_ext.BidderName]adapters.Bidder{ - openrtb_ext.BidderAppnexus: adapters.BuildInfoAwareBidder(appnexusBidder, infoEnabled), - }, - }, } for _, test := range testCases { - bidders, errs := buildBidders(test.adapterConfig, test.bidderInfos, test.builders) + bidders, errs := buildBidders(test.bidderInfos, test.builders) // For Test Setup Convenience if test.expectedBidders == nil { diff --git a/exchange/bidder_test.go b/exchange/bidder_test.go index 2da7c5a21c0..d6a74ac747e 100644 --- a/exchange/bidder_test.go +++ b/exchange/bidder_test.go @@ -2157,7 +2157,7 @@ func TestRequestBidsWithAdsCertsSigner(t *testing.T) { func wrapWithBidderInfo(bidder adapters.Bidder) adapters.Bidder { bidderInfo := config.BidderInfo{ - Enabled: true, + Disabled: false, Capabilities: &config.CapabilitiesInfo{ App: &config.PlatformInfo{ MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}, diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go index 8ef79e30f29..bf31a8be2bf 100644 --- a/exchange/exchange_test.go +++ b/exchange/exchange_test.go @@ -51,13 +51,12 @@ func TestNewExchange(t *testing.T) { CacheURL: config.Cache{ ExpectedTimeMillis: 20, }, - Adapters: blankAdapterConfig(knownAdapters), GDPR: config.GDPR{ EEACountries: []string{"FIN", "FRA", "GUF"}, }, } - biddersInfo, err := config.LoadBidderInfoFromDisk("../static/bidder-info", cfg.Adapters, openrtb_ext.BuildBidderStringSlice()) + biddersInfo, err := config.LoadBidderInfo("../static/bidder-info") if err != nil { t.Fatal(err) } @@ -81,7 +80,9 @@ func TestNewExchange(t *testing.T) { e := NewExchange(adapters, nil, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, biddersInfo, gdprPermsBuilder, tcf2ConfigBuilder, currencyConverter, nilCategoryFetcher{}, &adscert.NilSigner{}).(*exchange) for _, bidderName := range knownAdapters { if _, ok := e.adapterMap[bidderName]; !ok { - t.Errorf("NewExchange produced an Exchange without bidder %s", bidderName) + if biddersInfo[string(bidderName)].IsEnabled() { + t.Errorf("NewExchange produced an Exchange without bidder %s", bidderName) + } } } if e.cacheTime != time.Duration(cfg.CacheURL.ExpectedTimeMillis)*time.Millisecond { @@ -100,25 +101,18 @@ func TestNewExchange(t *testing.T) { // 4. Build a BidResponse struct using exchange.buildBidResponse(ctx.Background(), liveA... ) // 5. Assert we have no '&' characters in the response that exchange.buildBidResponse returns func TestCharacterEscape(t *testing.T) { + // 1) Adapter with a '& char in its endpoint property // https://github.com/prebid/prebid-server/issues/465 - cfg := &config.Configuration{ - Adapters: make(map[string]config.Adapter, 1), - } - cfg.Adapters["appnexus"] = config.Adapter{ - Endpoint: "http://ib.adnxs.com/openrtb2?query1&query2", //Note the '&' character in there - } + cfg := &config.Configuration{} + biddersInfo := config.BidderInfos{"appnexus": config.BidderInfo{Endpoint: "http://ib.adnxs.com/openrtb2?query1&query2"}} //Note the '&' character in there // 2) Init new exchange with said configuration //Other parameters also needed to create exchange handlerNoBidServer := func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(204) } server := httptest.NewServer(http.HandlerFunc(handlerNoBidServer)) - defer server.Close() - biddersInfo, err := config.LoadBidderInfoFromDisk("../static/bidder-info", cfg.Adapters, openrtb_ext.BuildBidderStringSlice()) - if err != nil { - t.Fatal(err) - } + defer server.Close() adapters, adaptersErr := BuildAdapters(server.Client(), cfg, biddersInfo, &metricsConf.NilMetricsEngine{}) if adaptersErr != nil { @@ -1227,11 +1221,6 @@ func TestGetBidCacheInfoEndToEnd(t *testing.T) { bidderName := openrtb_ext.BidderName("appnexus") cfg := &config.Configuration{ - Adapters: map[string]config.Adapter{ - string(bidderName): { - Endpoint: "http://ib.adnxs.com/endpoint", - }, - }, CacheURL: config.Cache{ Host: "www.internalprebidcache.net", }, @@ -1250,7 +1239,7 @@ func TestGetBidCacheInfoEndToEnd(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(handlerNoBidServer)) defer server.Close() - biddersInfo, err := config.LoadBidderInfoFromDisk("../static/bidder-info", cfg.Adapters, openrtb_ext.BuildBidderStringSlice()) + biddersInfo, err := config.LoadBidderInfo("../static/bidder-info") if err != nil { t.Fatal(err) } @@ -1607,14 +1596,13 @@ func TestGetBidCacheInfo(t *testing.T) { func TestBidResponseCurrency(t *testing.T) { // Init objects - cfg := &config.Configuration{Adapters: make(map[string]config.Adapter, 1)} - cfg.Adapters["appnexus"] = config.Adapter{Endpoint: "http://ib.adnxs.com"} + cfg := &config.Configuration{} handlerNoBidServer := func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(204) } server := httptest.NewServer(http.HandlerFunc(handlerNoBidServer)) defer server.Close() - biddersInfo, err := config.LoadBidderInfoFromDisk("../static/bidder-info", cfg.Adapters, openrtb_ext.BuildBidderStringSlice()) + biddersInfo, err := config.LoadBidderInfo("../static/bidder-info") if err != nil { t.Fatal(err) } @@ -1771,8 +1759,7 @@ func TestBidResponseCurrency(t *testing.T) { func TestBidResponseImpExtInfo(t *testing.T) { // Init objects - cfg := &config.Configuration{Adapters: make(map[string]config.Adapter, 1)} - cfg.Adapters["appnexus"] = config.Adapter{Endpoint: "http://ib.adnxs.com"} + cfg := &config.Configuration{} gdprPermsBuilder := fakePermissionsBuilder{ permissions: &permissionsMock{ @@ -1783,7 +1770,18 @@ func TestBidResponseImpExtInfo(t *testing.T) { cfg: gdpr.NewTCF2Config(config.TCF2{}, config.AccountGDPR{}), }.Builder - e := NewExchange(nil, nil, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, nil, gdprPermsBuilder, tcf2ConfigBuilder, nil, nilCategoryFetcher{}, &adscert.NilSigner{}).(*exchange) + noBidHandler := func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(204) } + server := httptest.NewServer(http.HandlerFunc(noBidHandler)) + defer server.Close() + + biddersInfo := config.BidderInfos{"appnexus": config.BidderInfo{Endpoint: "http://ib.adnxs.com"}} + + adapters, adaptersErr := BuildAdapters(server.Client(), cfg, biddersInfo, &metricsConf.NilMetricsEngine{}) + if adaptersErr != nil { + t.Fatalf("Error intializing adapters: %v", adaptersErr) + } + + e := NewExchange(adapters, nil, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, nil, gdprPermsBuilder, tcf2ConfigBuilder, nil, nilCategoryFetcher{}, &adscert.NilSigner{}).(*exchange) liveAdapters := make([]openrtb_ext.BidderName, 1) liveAdapters[0] = "appnexus" @@ -1846,25 +1844,9 @@ func TestRaceIntegration(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(noBidServer)) defer server.Close() - cfg := &config.Configuration{ - Adapters: make(map[string]config.Adapter), - } - for _, bidder := range openrtb_ext.CoreBidderNames() { - cfg.Adapters[strings.ToLower(string(bidder))] = config.Adapter{ - Endpoint: server.URL, - } - } - cfg.Adapters[strings.ToLower(string(openrtb_ext.BidderAudienceNetwork))] = config.Adapter{ - Endpoint: server.URL, - AppSecret: "any", - PlatformID: "abc", - } - cfg.Adapters[strings.ToLower(string(openrtb_ext.BidderBeachfront))] = config.Adapter{ - Endpoint: server.URL, - ExtraAdapterInfo: "{\"video_endpoint\":\"" + server.URL + "\"}", - } + cfg := &config.Configuration{} - biddersInfo, err := config.LoadBidderInfoFromDisk("../static/bidder-info", cfg.Adapters, openrtb_ext.BuildBidderStringSlice()) + biddersInfo, err := config.LoadBidderInfo("../static/bidder-info") if err != nil { t.Fatal(err) } @@ -1971,10 +1953,9 @@ func TestPanicRecovery(t *testing.T) { CacheURL: config.Cache{ ExpectedTimeMillis: 20, }, - Adapters: blankAdapterConfig(openrtb_ext.CoreBidderNames()), } - biddersInfo, err := config.LoadBidderInfoFromDisk("../static/bidder-info", cfg.Adapters, openrtb_ext.BuildBidderStringSlice()) + biddersInfo, err := config.LoadBidderInfo("../static/bidder-info") if err != nil { t.Fatal(err) } @@ -2041,17 +2022,9 @@ func TestPanicRecoveryHighLevel(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(noBidServer)) defer server.Close() - cfg := &config.Configuration{ - Adapters: make(map[string]config.Adapter), - } - for _, bidder := range openrtb_ext.CoreBidderNames() { - cfg.Adapters[strings.ToLower(string(bidder))] = config.Adapter{ - Endpoint: server.URL, - } - } - cfg.Adapters["audiencenetwork"] = config.Adapter{Disabled: true} + cfg := &config.Configuration{} - biddersInfo, err := config.LoadBidderInfoFromDisk("../static/bidder-info", cfg.Adapters, openrtb_ext.BuildBidderStringSlice()) + biddersInfo, err := config.LoadBidderInfo("../static/bidder-info") if err != nil { t.Fatal(err) } @@ -4108,16 +4081,21 @@ func TestPassExperimentConfigsToHoldAuction(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(noBidServer)) defer server.Close() - cfg := &config.Configuration{ - Adapters: make(map[string]config.Adapter, 1), - } - cfg.Adapters["appnexus"] = config.Adapter{ - Endpoint: "test.com", - } - biddersInfo, err := config.LoadBidderInfoFromDisk("../static/bidder-info", cfg.Adapters, openrtb_ext.BuildBidderStringSlice()) + cfg := &config.Configuration{} + + biddersInfo, err := config.LoadBidderInfo("../static/bidder-info") if err != nil { t.Fatal(err) } + biddersInfo["appnexus"] = config.BidderInfo{ + Endpoint: "test.com", + Capabilities: &config.CapabilitiesInfo{ + Site: &config.PlatformInfo{ + MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo}, + }, + }, + Experiment: config.BidderInfoExperiment{AdsCert: config.BidderAdsCert{Enabled: true}}} + signer := MockSigner{} adapters, adaptersErr := BuildAdapters(server.Client(), cfg, biddersInfo, &metricsConf.NilMetricsEngine{}) @@ -4136,7 +4114,6 @@ func TestPassExperimentConfigsToHoldAuction(t *testing.T) { cfg: gdpr.NewTCF2Config(config.TCF2{}, config.AccountGDPR{}), }.Builder - biddersInfo["appnexus"] = config.BidderInfo{Experiment: config.BidderInfoExperiment{AdsCert: config.BidderAdsCert{Enabled: true}}} e := NewExchange(adapters, nil, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, biddersInfo, gdprPermsBuilder, tcf2ConfigBuilder, currencyConverter, nilCategoryFetcher{}, &signer).(*exchange) // Define mock incoming bid requeset diff --git a/main.go b/main.go index c103863107d..bdd79f11cc2 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ import ( "flag" "math/rand" "net/http" + "path/filepath" "runtime" "time" @@ -24,7 +25,16 @@ func init() { func main() { flag.Parse() // required for glog flags and testing package flags - cfg, err := loadConfig() + bidderInfoPath, err := filepath.Abs(infoDirectory) + if err != nil { + glog.Exitf("Unable to build configuration directory path: %v", err) + } + + bidderInfos, err := config.LoadBidderInfo(bidderInfoPath) + if err != nil { + glog.Exitf("Unable to load bidder configurations: %v", err) + } + cfg, err := loadConfig(bidderInfos) if err != nil { glog.Exitf("Configuration could not be loaded or did not pass validation: %v", err) } @@ -44,11 +54,12 @@ func main() { } const configFileName = "pbs" +const infoDirectory = "./static/bidder-info" -func loadConfig() (*config.Configuration, error) { +func loadConfig(bidderInfos config.BidderInfos) (*config.Configuration, error) { v := viper.New() - config.SetupViper(v, configFileName) - return config.New(v) + config.SetupViper(v, configFileName, bidderInfos) + return config.New(v, bidderInfos) } func serve(cfg *config.Configuration) error { diff --git a/main_test.go b/main_test.go index 70eea2825f0..25812ba96ab 100644 --- a/main_test.go +++ b/main_test.go @@ -40,18 +40,18 @@ func forceEnv(t *testing.T, key string, val string) func() { // Test the viper setup func TestViperInit(t *testing.T) { v := viper.New() - config.SetupViper(v, "") + config.SetupViper(v, "", nil) compareStrings(t, "Viper error: external_url expected to be %s, found %s", "http://localhost:8000", v.Get("external_url").(string)) - compareStrings(t, "Viper error: adapters.pulsepoint.endpoint expected to be %s, found %s", "http://bid.contextweb.com/header/s/ortb/prebid-s2s", v.Get("adapters.pulsepoint.endpoint").(string)) + compareStrings(t, "Viper error: accounts.filesystem.directorypath expected to be %s, found %s", "./stored_requests/data/by_id", v.Get("accounts.filesystem.directorypath").(string)) } func TestViperEnv(t *testing.T) { v := viper.New() - config.SetupViper(v, "") + config.SetupViper(v, "", nil) port := forceEnv(t, "PBS_PORT", "7777") defer port() - endpt := forceEnv(t, "PBS_ADAPTERS_PUBMATIC_ENDPOINT", "not_an_endpoint") + endpt := forceEnv(t, "PBS_EXPERIMENT_ADSCERT_INPROCESS_ORIGIN", "not_an_endpoint") defer endpt() ttl := forceEnv(t, "PBS_HOST_COOKIE_TTL_DAYS", "60") @@ -61,7 +61,7 @@ func TestViperEnv(t *testing.T) { defer ipv4Networks() assert.Equal(t, 7777, v.Get("port"), "Basic Config") - assert.Equal(t, "not_an_endpoint", v.Get("adapters.pubmatic.endpoint"), "Nested Config") + assert.Equal(t, "not_an_endpoint", v.Get("experiment.adscert.inprocess.origin"), "Nested Config") assert.Equal(t, 60, v.Get("host_cookie.ttl_days"), "Config With Underscores") assert.ElementsMatch(t, []string{"1.1.1.1/24", "2.2.2.2/24"}, v.Get("request_validation.ipv4_private_networks"), "Arrays") } diff --git a/router/router.go b/router/router.go index f2ec00479f0..5a4e5027ef4 100644 --- a/router/router.go +++ b/router/router.go @@ -7,7 +7,6 @@ import ( "fmt" "io/ioutil" "net/http" - "path/filepath" "strings" "time" @@ -31,7 +30,6 @@ import ( "github.com/prebid/prebid-server/server/ssl" storedRequestsConf "github.com/prebid/prebid-server/stored_requests/config" "github.com/prebid/prebid-server/usersync" - "github.com/prebid/prebid-server/util/sliceutil" "github.com/prebid/prebid-server/util/uuidutil" "github.com/prebid/prebid-server/version" @@ -114,7 +112,6 @@ type Router struct { func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *Router, err error) { const schemaDirectory = "./static/bidder-params" - const infoDirectory = "./static/bidder-info" r = &Router{ Router: httprouter.New(), @@ -150,21 +147,11 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R }, } - p, _ := filepath.Abs(infoDirectory) - bidderInfos, err := config.LoadBidderInfoFromDisk(p, cfg.Adapters, openrtb_ext.BuildBidderStringSlice()) - if err != nil { - return nil, err - } - - if err := applyBidderInfoConfigOverrides(bidderInfos, cfg.Adapters); err != nil { - return nil, err - } - - if err := checkSupportedUserSyncEndpoints(bidderInfos); err != nil { + if err := checkSupportedUserSyncEndpoints(cfg.BidderInfos); err != nil { return nil, err } - syncersByBidder, errs := usersync.BuildSyncers(cfg, bidderInfos) + syncersByBidder, errs := usersync.BuildSyncers(cfg, cfg.BidderInfos) if len(errs) > 0 { return nil, errortypes.NewAggregateError("user sync", errs) } @@ -191,22 +178,22 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R glog.Fatalf("Failed to create the bidder params validator. %v", err) } - activeBidders := exchange.GetActiveBidders(bidderInfos) - disabledBidders := exchange.GetDisabledBiddersErrorMessages(bidderInfos) + activeBidders := exchange.GetActiveBidders(cfg.BidderInfos) + disabledBidders := exchange.GetDisabledBiddersErrorMessages(cfg.BidderInfos) defaultAliases, defReqJSON := readDefaultRequest(cfg.DefReqConfig) if err := validateDefaultAliases(defaultAliases); err != nil { return nil, err } - gvlVendorIDs := bidderInfos.ToGVLVendorIDMap() + gvlVendorIDs := cfg.BidderInfos.ToGVLVendorIDMap() vendorListFetcher := gdpr.NewVendorListFetcher(context.Background(), cfg.GDPR, generalHttpClient, gdpr.VendorListURLMaker) gdprPermsBuilder := gdpr.NewPermissionsBuilder(cfg.GDPR, gvlVendorIDs, vendorListFetcher) tcf2CfgBuilder := gdpr.NewTCF2Config cacheClient := pbc.NewClient(cacheHttpClient, &cfg.CacheURL, &cfg.ExtCacheURL, r.MetricsEngine) - adapters, adaptersErrs := exchange.BuildAdapters(generalHttpClient, cfg, bidderInfos, r.MetricsEngine) + adapters, adaptersErrs := exchange.BuildAdapters(generalHttpClient, cfg, cfg.BidderInfos, r.MetricsEngine) if len(adaptersErrs) > 0 { errs := errortypes.NewAggregateError("Failed to initialize adapters", adaptersErrs) return nil, errs @@ -216,7 +203,7 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R glog.Fatalf("Failed to create ads cert signer: %v", err) } - theExchange := exchange.NewExchange(adapters, cacheClient, cfg, syncersByBidder, r.MetricsEngine, bidderInfos, gdprPermsBuilder, tcf2CfgBuilder, rateConvertor, categoriesFetcher, adsCertSigner) + theExchange := exchange.NewExchange(adapters, cacheClient, cfg, syncersByBidder, r.MetricsEngine, cfg.BidderInfos, gdprPermsBuilder, tcf2CfgBuilder, rateConvertor, categoriesFetcher, adsCertSigner) var uuidGenerator uuidutil.UUIDRandomGenerator openrtbEndpoint, err := openrtb2.NewEndpoint(uuidGenerator, theExchange, paramsValidator, fetcher, accounts, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBidders, storedRespFetcher) if err != nil { @@ -241,8 +228,8 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R r.POST("/openrtb2/auction", openrtbEndpoint) r.POST("/openrtb2/video", videoEndpoint) r.GET("/openrtb2/amp", ampEndpoint) - r.GET("/info/bidders", infoEndpoints.NewBiddersEndpoint(bidderInfos, defaultAliases)) - r.GET("/info/bidders/:bidderName", infoEndpoints.NewBiddersDetailEndpoint(bidderInfos, cfg.Adapters, defaultAliases)) + r.GET("/info/bidders", infoEndpoints.NewBiddersEndpoint(cfg.BidderInfos, defaultAliases)) + r.GET("/info/bidders/:bidderName", infoEndpoints.NewBiddersDetailEndpoint(cfg.BidderInfos, defaultAliases)) r.GET("/bidders/params", NewJsonDirectoryServer(schemaDirectory, paramsValidator, defaultAliases)) r.POST("/cookie_sync", endpoints.NewCookieSyncEndpoint(syncersByBidder, cfg, gdprPermsBuilder, tcf2CfgBuilder, r.MetricsEngine, pbsAnalytics, accounts, activeBidders).Handle) r.GET("/status", endpoints.NewStatusEndpoint(cfg.StatusResponse)) @@ -252,7 +239,7 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R // vtrack endpoint if cfg.VTrack.Enabled { - vtrackEndpoint := events.NewVTrackEndpoint(cfg, accounts, cacheClient, bidderInfos) + vtrackEndpoint := events.NewVTrackEndpoint(cfg, accounts, cacheClient, cfg.BidderInfos) r.POST("/vtrack", vtrackEndpoint) } @@ -274,64 +261,6 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R return r, nil } -func applyBidderInfoConfigOverrides(bidderInfos config.BidderInfos, adaptersCfg map[string]config.Adapter) error { - for bidderName, bidderInfo := range bidderInfos { - // bidder name from bidderInfos is case-sensitive, but bidder name from adaptersCfg - // is always expressed as lower case. need to adapt for the difference here. - if adapterCfg, exists := adaptersCfg[strings.ToLower(bidderName)]; exists { - bidderInfo.Syncer = adapterCfg.Syncer.Override(bidderInfo.Syncer) - - // validate and try to apply the legacy usersync_url configuration in attempt to provide - // an easier upgrade path. be warned, this will break if the bidder adds a second syncer - // type and will eventually be removed after we've given hosts enough time to upgrade to - // the new config. - if adapterCfg.UserSyncURL != "" { - if bidderInfo.Syncer == nil { - return fmt.Errorf("adapters.%s.usersync_url cannot be applied, bidder does not define a user sync", strings.ToLower(bidderName)) - } - - endpointsCount := 0 - if bidderInfo.Syncer.IFrame != nil { - bidderInfo.Syncer.IFrame.URL = adapterCfg.UserSyncURL - endpointsCount++ - } - if bidderInfo.Syncer.Redirect != nil { - bidderInfo.Syncer.Redirect.URL = adapterCfg.UserSyncURL - endpointsCount++ - } - - // use Supports as a hint if there are no good defaults provided - if endpointsCount == 0 { - if sliceutil.ContainsStringIgnoreCase(bidderInfo.Syncer.Supports, "iframe") { - bidderInfo.Syncer.IFrame = &config.SyncerEndpoint{URL: adapterCfg.UserSyncURL} - endpointsCount++ - } - if sliceutil.ContainsStringIgnoreCase(bidderInfo.Syncer.Supports, "redirect") { - bidderInfo.Syncer.Redirect = &config.SyncerEndpoint{URL: adapterCfg.UserSyncURL} - endpointsCount++ - } - } - - if endpointsCount == 0 { - return fmt.Errorf("adapters.%s.usersync_url cannot be applied, bidder does not define user sync endpoints and does not define supported endpoints", strings.ToLower(bidderName)) - } - - // if the bidder defines both an iframe and redirect endpoint, we can't be sure which config value to - // override, and it wouldn't be both. this is a fatal configuration error. - if endpointsCount > 1 { - return fmt.Errorf("adapters.%s.usersync_url cannot be applied, bidder defines multiple user sync endpoints or supports multiple endpoints", strings.ToLower(bidderName)) - } - - // provide a warning that this compatibility layer is temporary - glog.Warningf("adapters.%s.usersync_url is deprecated and will be removed in a future version, please update to the latest user sync config values", strings.ToLower(bidderName)) - } - - bidderInfos[bidderName] = bidderInfo - } - } - return nil -} - func checkSupportedUserSyncEndpoints(bidderInfos config.BidderInfos) error { for name, info := range bidderInfos { if info.Syncer == nil { diff --git a/router/router_test.go b/router/router_test.go index b4ceaff16a9..177ef0e0902 100644 --- a/router/router_test.go +++ b/router/router_test.go @@ -61,89 +61,6 @@ func TestNewJsonDirectoryServer(t *testing.T) { ensureHasKey(t, data, "aliastest") } -func TestApplyBidderInfoConfigOverrides(t *testing.T) { - var testCases = []struct { - description string - givenBidderInfos config.BidderInfos - givenAdaptersCfg map[string]config.Adapter - expectedError string - expectedBidderInfos config.BidderInfos - }{ - { - description: "Syncer Override", - givenBidderInfos: config.BidderInfos{"a": {Syncer: &config.Syncer{Key: "original"}}}, - givenAdaptersCfg: map[string]config.Adapter{"a": {Syncer: &config.Syncer{Key: "override"}}}, - expectedBidderInfos: config.BidderInfos{"a": {Syncer: &config.Syncer{Key: "override"}}}, - }, - { - // Adapter Configs use a lower case bidder name, but the Bidder Infos follow the official - // bidder name casing. - description: "Syncer Override - Case Sensitivity", - givenBidderInfos: config.BidderInfos{"A": {Syncer: &config.Syncer{Key: "original"}}}, - givenAdaptersCfg: map[string]config.Adapter{"a": {Syncer: &config.Syncer{Key: "override"}}}, - expectedBidderInfos: config.BidderInfos{"A": {Syncer: &config.Syncer{Key: "override"}}}, - }, - { - description: "UserSyncURL Override IFrame", - givenBidderInfos: config.BidderInfos{"a": {Syncer: &config.Syncer{IFrame: &config.SyncerEndpoint{URL: "original"}}}}, - givenAdaptersCfg: map[string]config.Adapter{"a": {UserSyncURL: "override"}}, - expectedBidderInfos: config.BidderInfos{"a": {Syncer: &config.Syncer{IFrame: &config.SyncerEndpoint{URL: "override"}}}}, - }, - { - description: "UserSyncURL Supports IFrame", - givenBidderInfos: config.BidderInfos{"a": {Syncer: &config.Syncer{Supports: []string{"iframe"}}}}, - givenAdaptersCfg: map[string]config.Adapter{"a": {UserSyncURL: "override"}}, - expectedBidderInfos: config.BidderInfos{"a": {Syncer: &config.Syncer{Supports: []string{"iframe"}, IFrame: &config.SyncerEndpoint{URL: "override"}}}}, - }, - { - description: "UserSyncURL Override Redirect", - givenBidderInfos: config.BidderInfos{"a": {Syncer: &config.Syncer{Supports: []string{"redirect"}}}}, - givenAdaptersCfg: map[string]config.Adapter{"a": {UserSyncURL: "override"}}, - expectedBidderInfos: config.BidderInfos{"a": {Syncer: &config.Syncer{Supports: []string{"redirect"}, Redirect: &config.SyncerEndpoint{URL: "override"}}}}, - }, - { - description: "UserSyncURL Supports Redirect", - givenBidderInfos: config.BidderInfos{"a": {Syncer: &config.Syncer{Redirect: &config.SyncerEndpoint{URL: "original"}}}}, - givenAdaptersCfg: map[string]config.Adapter{"a": {UserSyncURL: "override"}}, - expectedBidderInfos: config.BidderInfos{"a": {Syncer: &config.Syncer{Redirect: &config.SyncerEndpoint{URL: "override"}}}}, - }, - { - description: "UserSyncURL Override Syncer Not Defined", - givenBidderInfos: config.BidderInfos{"a": {}}, - givenAdaptersCfg: map[string]config.Adapter{"a": {UserSyncURL: "override"}}, - expectedError: "adapters.a.usersync_url cannot be applied, bidder does not define a user sync", - }, - { - description: "UserSyncURL Override Syncer Endpoints Not Defined", - givenBidderInfos: config.BidderInfos{"a": {Syncer: &config.Syncer{}}}, - givenAdaptersCfg: map[string]config.Adapter{"a": {UserSyncURL: "override"}}, - expectedError: "adapters.a.usersync_url cannot be applied, bidder does not define user sync endpoints and does not define supported endpoints", - }, - { - description: "UserSyncURL Override Ambiguous", - givenBidderInfos: config.BidderInfos{"a": {Syncer: &config.Syncer{IFrame: &config.SyncerEndpoint{URL: "originalIFrame"}, Redirect: &config.SyncerEndpoint{URL: "originalRedirect"}}}}, - givenAdaptersCfg: map[string]config.Adapter{"a": {UserSyncURL: "override"}}, - expectedError: "adapters.a.usersync_url cannot be applied, bidder defines multiple user sync endpoints or supports multiple endpoints", - }, - { - description: "UserSyncURL Supports Ambiguous", - givenBidderInfos: config.BidderInfos{"a": {Syncer: &config.Syncer{Supports: []string{"iframe", "redirect"}}}}, - givenAdaptersCfg: map[string]config.Adapter{"a": {UserSyncURL: "override"}}, - expectedError: "adapters.a.usersync_url cannot be applied, bidder defines multiple user sync endpoints or supports multiple endpoints", - }, - } - - for _, test := range testCases { - resultErr := applyBidderInfoConfigOverrides(test.givenBidderInfos, test.givenAdaptersCfg) - if test.expectedError == "" { - assert.NoError(t, resultErr, test.description+":err") - assert.Equal(t, test.expectedBidderInfos, test.givenBidderInfos, test.description+":result") - } else { - assert.EqualError(t, resultErr, test.expectedError, test.description+":err") - } - } -} - func TestCheckSupportedUserSyncEndpoints(t *testing.T) { anyEndpoint := &config.SyncerEndpoint{URL: "anyURL"} diff --git a/static/bidder-info/33across.yaml b/static/bidder-info/33across.yaml index bdda5a7e5a6..902db6b362b 100644 --- a/static/bidder-info/33across.yaml +++ b/static/bidder-info/33across.yaml @@ -1,3 +1,4 @@ +endpoint: "https://ssc.33across.com/api/v1/s2s" maintainer: email: "headerbidding@33across.com" gvlVendorID: 58 diff --git a/static/bidder-info/aax.yaml b/static/bidder-info/aax.yaml index e08cb559770..a7dee8a70b0 100644 --- a/static/bidder-info/aax.yaml +++ b/static/bidder-info/aax.yaml @@ -1,3 +1,5 @@ +endpoint: "https://prebid.aaxads.com/rtb/pb/aax-prebid" +extra_info: "https://aax.golang.pbs.com" maintainer: email: product@aax.media gvlVendorID: 720 @@ -16,4 +18,4 @@ capabilities: userSync: redirect: url: https://c.aaxads.com/aacxc.php?fv=1&wbsh=psa&ryvlg=setstatuscode&bidder=aax&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}} - userMacro: \ No newline at end of file + userMacro: diff --git a/static/bidder-info/aceex.yaml b/static/bidder-info/aceex.yaml index a94d37528d1..b845d648101 100644 --- a/static/bidder-info/aceex.yaml +++ b/static/bidder-info/aceex.yaml @@ -1,3 +1,4 @@ +endpoint: "http://bl-us.aceex.io/?uqhash={{.AccountID}}" maintainer: email: "tech@aceex.io" capabilities: diff --git a/static/bidder-info/acuityads.yaml b/static/bidder-info/acuityads.yaml index c806294d644..3efbd189cd7 100644 --- a/static/bidder-info/acuityads.yaml +++ b/static/bidder-info/acuityads.yaml @@ -1,3 +1,4 @@ +endpoint: "http://{{.Host}}.admanmedia.com/bid?token={{.AccountID}}" maintainer: email: "integrations@acuityads.com" gvlVendorID: 231 @@ -15,4 +16,4 @@ capabilities: userSync: redirect: url: "https://cs.admanmedia.com/sync/prebid?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir={{.RedirectURL}}" - userMacro: "[UID]" \ No newline at end of file + userMacro: "[UID]" diff --git a/static/bidder-info/adf.yaml b/static/bidder-info/adf.yaml index 2e312bff788..2310f346c25 100644 --- a/static/bidder-info/adf.yaml +++ b/static/bidder-info/adf.yaml @@ -1,3 +1,4 @@ +endpoint: "https://adx.adform.net/adx/openrtb" maintainer: email: "scope.sspp@adform.com" gvlVendorID: 50 diff --git a/static/bidder-info/adform.yaml b/static/bidder-info/adform.yaml index 2e312bff788..2310f346c25 100644 --- a/static/bidder-info/adform.yaml +++ b/static/bidder-info/adform.yaml @@ -1,3 +1,4 @@ +endpoint: "https://adx.adform.net/adx/openrtb" maintainer: email: "scope.sspp@adform.com" gvlVendorID: 50 diff --git a/static/bidder-info/adgeneration.yaml b/static/bidder-info/adgeneration.yaml index 55f653143dd..a750dc6ee80 100644 --- a/static/bidder-info/adgeneration.yaml +++ b/static/bidder-info/adgeneration.yaml @@ -1,3 +1,4 @@ +endpoint: "https://d.socdm.com/adsv/v1" maintainer: email: "ssp-ope@supership.jp" capabilities: @@ -7,4 +8,3 @@ capabilities: site: mediaTypes: - banner - diff --git a/static/bidder-info/adhese.yaml b/static/bidder-info/adhese.yaml index 25058e82409..532c114de5b 100644 --- a/static/bidder-info/adhese.yaml +++ b/static/bidder-info/adhese.yaml @@ -1,3 +1,4 @@ +endpoint: "https://ads-{{.AccountID}}.adhese.com/json" maintainer: email: info@adhese.com gvlVendorID: 553 diff --git a/static/bidder-info/adkernel.yaml b/static/bidder-info/adkernel.yaml index a267bb672db..864ca71a088 100644 --- a/static/bidder-info/adkernel.yaml +++ b/static/bidder-info/adkernel.yaml @@ -1,3 +1,4 @@ +endpoint: "https://pbs.adksrv.com/hb?zone={{.ZoneID}}" maintainer: email: "prebid-dev@adkernel.com" gvlVendorID: 14 diff --git a/static/bidder-info/adkernelAdn.yaml b/static/bidder-info/adkernelAdn.yaml index e401cb83923..eb4c06b6cc8 100644 --- a/static/bidder-info/adkernelAdn.yaml +++ b/static/bidder-info/adkernelAdn.yaml @@ -1,3 +1,4 @@ +endpoint: "https://pbs2.adksrv.com/rtbpub?account={{.PublisherID}}" maintainer: email: "prebid-dev@adkernel.com" gvlVendorID: 14 @@ -13,3 +14,4 @@ userSync: redirect: url: "https://tag.adkernel.com/syncr?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}" userMacro: "{UID}" + diff --git a/static/bidder-info/adman.yaml b/static/bidder-info/adman.yaml index d7869fdc536..ad49f8fbe61 100644 --- a/static/bidder-info/adman.yaml +++ b/static/bidder-info/adman.yaml @@ -1,3 +1,4 @@ +endpoint: "http://pub.admanmedia.com/?c=o&m=ortb" maintainer: email: "prebid@admanmedia.com" gvlVendorID: 149 @@ -14,3 +15,4 @@ userSync: redirect: url: "https://sync.admanmedia.com/pbs.gif?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir={{.RedirectURL}}" userMacro: "[UID]" + diff --git a/static/bidder-info/admixer.yaml b/static/bidder-info/admixer.yaml index 5cb07ef5579..596c2271a83 100644 --- a/static/bidder-info/admixer.yaml +++ b/static/bidder-info/admixer.yaml @@ -1,3 +1,4 @@ +endpoint: "http://inv-nets.admixer.net/pbs.aspx" maintainer: email: "prebid@admixer.net" gvlVendorID: 511 diff --git a/static/bidder-info/adnuntius.yaml b/static/bidder-info/adnuntius.yaml index 86a0192cd62..22cb1c77da7 100644 --- a/static/bidder-info/adnuntius.yaml +++ b/static/bidder-info/adnuntius.yaml @@ -1,3 +1,4 @@ +endpoint: "https://ads.adnuntius.delivery/i" maintainer: email: hello@adnuntius.com gvlVendorID: 855 diff --git a/static/bidder-info/adocean.yaml b/static/bidder-info/adocean.yaml index 680e7496725..5001309593e 100644 --- a/static/bidder-info/adocean.yaml +++ b/static/bidder-info/adocean.yaml @@ -1,3 +1,4 @@ +endpoint: "https://{{.Host}}" maintainer: email: "aoteam@gemius.com" gvlVendorID: 328 @@ -12,4 +13,4 @@ userSync: # adocean supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. supports: - - redirect \ No newline at end of file + - redirect diff --git a/static/bidder-info/adoppler.yaml b/static/bidder-info/adoppler.yaml index 1b10103923e..3db2c1f998d 100644 --- a/static/bidder-info/adoppler.yaml +++ b/static/bidder-info/adoppler.yaml @@ -1,3 +1,4 @@ +endpoint: "http://{{.AccountID}}.trustedmarketplace.io/ads/processHeaderBid/{{.AdUnit}}" maintainer: email: pbs@adoppler.com capabilities: diff --git a/static/bidder-info/adot.yaml b/static/bidder-info/adot.yaml index cd2cd3c4f73..4f51bbc9457 100644 --- a/static/bidder-info/adot.yaml +++ b/static/bidder-info/adot.yaml @@ -1,3 +1,4 @@ +endpoint: "https://dsp.adotmob.com/headerbidding{PUBLISHER_PATH}/bidrequest" maintainer: email: "admin@we-are-adot.com" gvlVendorID: 272 @@ -16,4 +17,4 @@ capabilities: userSync: redirect: url: "https://sync.adotmob.com/cookie/pbs?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}" - userMacro: "{amob_user_id}" \ No newline at end of file + userMacro: "{amob_user_id}" diff --git a/static/bidder-info/adpone.yaml b/static/bidder-info/adpone.yaml index c5fb83fb39c..cfa49dc7361 100644 --- a/static/bidder-info/adpone.yaml +++ b/static/bidder-info/adpone.yaml @@ -1,3 +1,4 @@ +endpoint: "http://rtb.adpone.com/bid-request?src=prebid_server" maintainer: email: "tech@adpone.com" gvlVendorID: 799 @@ -11,4 +12,4 @@ capabilities: userSync: redirect: url: "https://usersync.adpone.com/csync?redir={{.RedirectURL}}" - userMacro: "{uid}" \ No newline at end of file + userMacro: "{uid}" diff --git a/static/bidder-info/adprime.yaml b/static/bidder-info/adprime.yaml index 4e5ff75fb71..2aab94c6b9d 100644 --- a/static/bidder-info/adprime.yaml +++ b/static/bidder-info/adprime.yaml @@ -1,3 +1,4 @@ +endpoint: "http://delta.adprime.com/pserver" maintainer: email: "prebid@adprime.com" capabilities: @@ -10,4 +11,4 @@ capabilities: mediaTypes: - banner - video - - native + - native diff --git a/static/bidder-info/adrino.yaml b/static/bidder-info/adrino.yaml index 24bdfb37899..a9d7f77afaf 100644 --- a/static/bidder-info/adrino.yaml +++ b/static/bidder-info/adrino.yaml @@ -1,3 +1,4 @@ +endpoint: "https://prd-prebid-bidder.adrino.io/openrtb/bid" maintainer: email: dev@adrino.pl gvlVendorID: 1072 diff --git a/static/bidder-info/adtarget.yaml b/static/bidder-info/adtarget.yaml index 9ef7e259d22..446959d109c 100644 --- a/static/bidder-info/adtarget.yaml +++ b/static/bidder-info/adtarget.yaml @@ -1,3 +1,4 @@ +endpoint: "http://ghb.console.adtarget.com.tr/pbs/ortb" maintainer: email: "kamil@adtarget.com.tr" gvlVendorID: 779 @@ -14,4 +15,4 @@ userSync: # adtarget supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. supports: - - iframe \ No newline at end of file + - iframe diff --git a/static/bidder-info/adtelligent.yaml b/static/bidder-info/adtelligent.yaml index f8ce434d481..0b73f065426 100644 --- a/static/bidder-info/adtelligent.yaml +++ b/static/bidder-info/adtelligent.yaml @@ -1,3 +1,4 @@ +endpoint: "http://ghb.adtelligent.com/pbs/ortb" maintainer: email: "hb@adtelligent.com" gvlVendorID: 410 @@ -14,4 +15,4 @@ userSync: # adtelligent supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. supports: - - iframe \ No newline at end of file + - iframe diff --git a/static/bidder-info/adtrgtme.yaml b/static/bidder-info/adtrgtme.yaml index 69deda5b5f1..3c509c0a007 100644 --- a/static/bidder-info/adtrgtme.yaml +++ b/static/bidder-info/adtrgtme.yaml @@ -1,3 +1,4 @@ +endpoint: "https://z.cdn.adtarget.market/ssp" maintainer: email: "info@adtarget.me" capabilities: @@ -6,4 +7,4 @@ capabilities: - banner site: mediaTypes: - - banner \ No newline at end of file + - banner diff --git a/static/bidder-info/advangelists.yaml b/static/bidder-info/advangelists.yaml index 35495d4d97f..0ffa16eafb1 100644 --- a/static/bidder-info/advangelists.yaml +++ b/static/bidder-info/advangelists.yaml @@ -1,3 +1,4 @@ +endpoint: "http://nep.advangelists.com/xp/get?pubid={{.PublisherID}}" maintainer: email: "prebid@advangelists.com" capabilities: diff --git a/static/bidder-info/adview.yaml b/static/bidder-info/adview.yaml index 077bce62b45..53158cf49e2 100644 --- a/static/bidder-info/adview.yaml +++ b/static/bidder-info/adview.yaml @@ -1,3 +1,4 @@ +endpoint: "https://bid.adview.com/agent/thirdAdxService/{{.AccountID}}" maintainer: email: "partner@adview.com" gvlVendorID: 1022 diff --git a/static/bidder-info/adxcg.yaml b/static/bidder-info/adxcg.yaml index 14c7c8bb572..fa37ff5defd 100644 --- a/static/bidder-info/adxcg.yaml +++ b/static/bidder-info/adxcg.yaml @@ -1,3 +1,4 @@ +disabled: true maintainer: email: "info@adxcg.com" capabilities: diff --git a/static/bidder-info/adyoulike.yaml b/static/bidder-info/adyoulike.yaml index 59711ff03a3..d1ddae74173 100644 --- a/static/bidder-info/adyoulike.yaml +++ b/static/bidder-info/adyoulike.yaml @@ -1,3 +1,4 @@ +endpoint: "https://broker.omnitagjs.com/broker/bid?partnerId=19340f4f097d16f41f34fc0274981ca4" maintainer: email: "core@adyoulike.com" gvlVendorID: 259 diff --git a/static/bidder-info/aja.yaml b/static/bidder-info/aja.yaml index 1d18dd7e75d..db0c1cad200 100644 --- a/static/bidder-info/aja.yaml +++ b/static/bidder-info/aja.yaml @@ -1,3 +1,4 @@ +endpoint: "https://ad.as.amanad.adtdp.com/v1/bid/4" maintainer: email: "dev@aja-kk.co.jp" capabilities: diff --git a/static/bidder-info/algorix.yaml b/static/bidder-info/algorix.yaml index 75ab4c09123..9e6c3738f68 100644 --- a/static/bidder-info/algorix.yaml +++ b/static/bidder-info/algorix.yaml @@ -1,3 +1,4 @@ +endpoint: "https://{{.Host}}.svr-algorix.com/rtb/sa?sid={{.SourceId}}&token={{.AccountID}}" maintainer: email: "prebid@algorix.co" capabilities: diff --git a/static/bidder-info/amx.yaml b/static/bidder-info/amx.yaml index ae2942c460b..3ede0d0875f 100644 --- a/static/bidder-info/amx.yaml +++ b/static/bidder-info/amx.yaml @@ -1,3 +1,4 @@ +endpoint: "http://pbs.amxrtb.com/auction/openrtb" maintainer: email: "prebid@amxrtb.com" gvlVendorID: 737 @@ -16,3 +17,4 @@ userSync: redirect: url: "https://prebid.a-mo.net/cchain/0?gdpr={{.GDPR}}&us_privacy={{.USPrivacy}}&cb={{.RedirectURL}}" userMacro: "" + diff --git a/static/bidder-info/andbeyondmedia.yaml b/static/bidder-info/andbeyondmedia.yaml index 34db6782334..4fb782b740c 100644 --- a/static/bidder-info/andbeyondmedia.yaml +++ b/static/bidder-info/andbeyondmedia.yaml @@ -1,3 +1,4 @@ +endpoint: "http://backend.andbeyond.media/pserver" maintainer: email: "sysengg@andbeyond.media" capabilities: diff --git a/static/bidder-info/apacdex.yaml b/static/bidder-info/apacdex.yaml index 5ef240219fe..590737ac28b 100644 --- a/static/bidder-info/apacdex.yaml +++ b/static/bidder-info/apacdex.yaml @@ -1,3 +1,4 @@ +endpoint: "http://useast.quantumdex.io/auction/pbs" maintainer: email: "support@apacdex.com" modifyingVastXmlAllowed: false diff --git a/static/bidder-info/applogy.yaml b/static/bidder-info/applogy.yaml index bb908c94e70..62a70a17f28 100644 --- a/static/bidder-info/applogy.yaml +++ b/static/bidder-info/applogy.yaml @@ -1,3 +1,4 @@ +endpoint: "http://rtb.applogy.com/v1/prebid" maintainer: email: work@applogy.com capabilities: diff --git a/static/bidder-info/appnexus.yaml b/static/bidder-info/appnexus.yaml index 41838159bbe..06afe454f89 100644 --- a/static/bidder-info/appnexus.yaml +++ b/static/bidder-info/appnexus.yaml @@ -1,3 +1,5 @@ +endpoint: "http://ib.adnxs.com/openrtb2" +platform_id: "5" maintainer: email: "prebid-server@xandr.com" gvlVendorID: 32 diff --git a/static/bidder-info/audienceNetwork.yaml b/static/bidder-info/audienceNetwork.yaml index 5e567318a89..10117ce708b 100644 --- a/static/bidder-info/audienceNetwork.yaml +++ b/static/bidder-info/audienceNetwork.yaml @@ -1,3 +1,5 @@ +endpoint: "https://an.facebook.com/placementbid.ortb" +disabled: true maintainer: email: "none" capabilities: @@ -9,4 +11,4 @@ capabilities: userSync: # facebook's audience network supports user syncing, but requires configuration by the host. supports: - - redirect \ No newline at end of file + - redirect diff --git a/static/bidder-info/automatad.yaml b/static/bidder-info/automatad.yaml index 0cdbb887db9..a8b1427d908 100644 --- a/static/bidder-info/automatad.yaml +++ b/static/bidder-info/automatad.yaml @@ -1,3 +1,4 @@ +endpoint: "https://s2s.atmtd.com" maintainer: email: "tech@automatad.com" capabilities: diff --git a/static/bidder-info/avocet.yaml b/static/bidder-info/avocet.yaml index ad8ca157a75..c2c4bb91d76 100644 --- a/static/bidder-info/avocet.yaml +++ b/static/bidder-info/avocet.yaml @@ -1,3 +1,4 @@ +disabled: true maintainer: email: "developers@avocet.io" gvlVendorID: 63 diff --git a/static/bidder-info/axonix.yaml b/static/bidder-info/axonix.yaml index 3c73501d9cc..8bb68a4b77a 100644 --- a/static/bidder-info/axonix.yaml +++ b/static/bidder-info/axonix.yaml @@ -1,3 +1,4 @@ +endpoint: "https://openrtb-us-east-1.axonix.com/supply/prebid-server/{{.AccountID}}" maintainer: email: support.axonix@emodoinc.com gvlVendorID: 678 diff --git a/static/bidder-info/beachfront.yaml b/static/bidder-info/beachfront.yaml index 64e04dc6eec..c98416ffe48 100644 --- a/static/bidder-info/beachfront.yaml +++ b/static/bidder-info/beachfront.yaml @@ -1,3 +1,5 @@ +endpoint: "https://display.bfmio.com/prebid_display" +extra_info: "{\"video_endpoint\":\"https://reachms.bfmio.com/bid.json?exchange_id\"}" maintainer: email: "prebid@beachfront.com" gvlVendorID: 335 @@ -14,3 +16,4 @@ userSync: iframe: url: "https://sync.bfmio.com/sync_s2s?gdpr={{.GDPR}}&us_privacy={{.USPrivacy}}&url={{.RedirectURL}}" userMacro: "[io_cid]" + diff --git a/static/bidder-info/beintoo.yaml b/static/bidder-info/beintoo.yaml index d804a29818d..3fa1838d03d 100644 --- a/static/bidder-info/beintoo.yaml +++ b/static/bidder-info/beintoo.yaml @@ -1,3 +1,4 @@ +endpoint: "https://ib.beintoo.com/um" maintainer: email: "adops@beintoo.com" gvlVendorID: 618 diff --git a/static/bidder-info/between.yaml b/static/bidder-info/between.yaml index 5649c328d62..cf5ce25ba7c 100644 --- a/static/bidder-info/between.yaml +++ b/static/bidder-info/between.yaml @@ -1,3 +1,4 @@ +endpoint: "http://{{.Host}}.betweendigital.com/openrtb_bid?sspId={{.PublisherID}}" maintainer: email: "buying@betweenx.com" gvlVendorID: 724 @@ -12,3 +13,4 @@ userSync: redirect: url: "https://ads.betweendigital.com/match?bidder_id=pbs&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&callback_url={{.RedirectURL}}" userMacro: "${USER_ID}" + diff --git a/static/bidder-info/bidmachine.yaml b/static/bidder-info/bidmachine.yaml index 6868125b6e6..9f3e1da0d16 100644 --- a/static/bidder-info/bidmachine.yaml +++ b/static/bidder-info/bidmachine.yaml @@ -1,3 +1,4 @@ +endpoint: "https://{{.Host}}.bidmachine.io" maintainer: email: hi@bidmachine.io gvlVendorID: 736 @@ -5,4 +6,4 @@ capabilities: app: mediaTypes: - banner - - video \ No newline at end of file + - video diff --git a/static/bidder-info/bidmyadz.yaml b/static/bidder-info/bidmyadz.yaml index 41cf4ecaa0a..a83947c5127 100644 --- a/static/bidder-info/bidmyadz.yaml +++ b/static/bidder-info/bidmyadz.yaml @@ -1,3 +1,4 @@ +endpoint: "http://endpoint.bidmyadz.com/c0f68227d14ed938c6c49f3967cbe9bc" maintainer: email: "contact@bidmyadz.com" capabilities: diff --git a/static/bidder-info/bidscube.yaml b/static/bidder-info/bidscube.yaml index 046eb6224d7..631433e4724 100644 --- a/static/bidder-info/bidscube.yaml +++ b/static/bidder-info/bidscube.yaml @@ -1,3 +1,4 @@ +endpoint: "http://supply.bidscube.com/?c=o&m=rtb" maintainer: email: "support@bidscube.com" modifyingVastXmlAllowed: true @@ -12,3 +13,4 @@ capabilities: - banner - video - native + diff --git a/static/bidder-info/bizzclick.yaml b/static/bidder-info/bizzclick.yaml index 48921c391b3..28ff0d44285 100644 --- a/static/bidder-info/bizzclick.yaml +++ b/static/bidder-info/bizzclick.yaml @@ -1,3 +1,4 @@ +endpoint: "http://us-e-node1.bizzclick.com/bid?rtb_seat_id={{.SourceId}}&secret_key={{.AccountID}}" maintainer: email: "support@bizzclick.com" capabilities: diff --git a/static/bidder-info/bliink.yaml b/static/bidder-info/bliink.yaml index 648f14db8c6..8afacff11ab 100644 --- a/static/bidder-info/bliink.yaml +++ b/static/bidder-info/bliink.yaml @@ -1,3 +1,4 @@ +endpoint: "http://engine.bliink.io/bid" maintainer: email: "support@bliink.io" gvlVendorID: 658 @@ -16,4 +17,4 @@ capabilities: userSync: redirect: url: "https://cookiesync.api.bliink.io/getuid?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&url={{.RedirectURL}}" - userMacro: "$UID" \ No newline at end of file + userMacro: "$UID" diff --git a/static/bidder-info/blue.yaml b/static/bidder-info/blue.yaml index e7b7769f70a..26d184005e9 100644 --- a/static/bidder-info/blue.yaml +++ b/static/bidder-info/blue.yaml @@ -1,3 +1,4 @@ +endpoint: "https://prebid-us-east-1.getblue.io/?src=prebid" maintainer: email: "prebid@getblue.io" gvlVendorID: 620 diff --git a/static/bidder-info/bmtm.yaml b/static/bidder-info/bmtm.yaml index bc7d2aed806..2992d0fbc7b 100644 --- a/static/bidder-info/bmtm.yaml +++ b/static/bidder-info/bmtm.yaml @@ -1,3 +1,4 @@ +endpoint: "https://one.elitebidder.com/api/pbs" maintainer: email: dev@brightmountainmedia.com modifyingVastXmlAllowed: false @@ -10,4 +11,4 @@ userSync: # bmtm supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. supports: - - redirect \ No newline at end of file + - redirect diff --git a/static/bidder-info/boldwin.yaml b/static/bidder-info/boldwin.yaml index 4be00e6ac77..39c1caf34f8 100644 --- a/static/bidder-info/boldwin.yaml +++ b/static/bidder-info/boldwin.yaml @@ -1,3 +1,4 @@ +endpoint: "http://ssp.videowalldirect.com/pserver" maintainer: email: "wls_demo_box@smartyads.com" capabilities: diff --git a/static/bidder-info/brightroll.yaml b/static/bidder-info/brightroll.yaml index db822bc4f7b..196344e9f25 100644 --- a/static/bidder-info/brightroll.yaml +++ b/static/bidder-info/brightroll.yaml @@ -1,3 +1,4 @@ +endpoint: "http://east-bid.ybp.yahoo.com/bid/appnexuspbs" maintainer: email: "dsp-supply-prebid@verizonmedia.com" gvlVendorID: 25 diff --git a/static/bidder-info/coinzilla.yaml b/static/bidder-info/coinzilla.yaml index dc63d32cd23..4d6ce4381d3 100644 --- a/static/bidder-info/coinzilla.yaml +++ b/static/bidder-info/coinzilla.yaml @@ -1,3 +1,4 @@ +endpoint: "http://request-global.czilladx.com/serve/prebid-server.php" maintainer: email: "technical@sevio.com" capabilities: diff --git a/static/bidder-info/colossus.yaml b/static/bidder-info/colossus.yaml index 11189c62cf3..c19a2326f42 100644 --- a/static/bidder-info/colossus.yaml +++ b/static/bidder-info/colossus.yaml @@ -1,3 +1,4 @@ +endpoint: "http://colossusssp.com/?c=o&m=rtb" maintainer: email: "support@huddledmasses.com" capabilities: @@ -12,4 +13,4 @@ capabilities: userSync: redirect: url: "https://sync.colossusssp.com/pbs.gif?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir={{.RedirectURL}}" - userMacro: "[UID]" \ No newline at end of file + userMacro: "[UID]" diff --git a/static/bidder-info/compass.yaml b/static/bidder-info/compass.yaml index 5944b27eb5a..c25c4be0862 100644 --- a/static/bidder-info/compass.yaml +++ b/static/bidder-info/compass.yaml @@ -1,3 +1,4 @@ +endpoint: "http://sa-lb.deliverimp.com/pserver" maintainer: email: "sa-support@brightcom.com" gvlVendorID: 883 diff --git a/static/bidder-info/connectad.yaml b/static/bidder-info/connectad.yaml index 63cf05427de..d9bf283c1ac 100644 --- a/static/bidder-info/connectad.yaml +++ b/static/bidder-info/connectad.yaml @@ -1,3 +1,4 @@ +endpoint: "http://bidder.connectad.io/API?src=pbs" maintainer: email: "support@connectad.io" gvlVendorID: 138 diff --git a/static/bidder-info/consumable.yaml b/static/bidder-info/consumable.yaml index 5200c738200..76bfbf705ef 100644 --- a/static/bidder-info/consumable.yaml +++ b/static/bidder-info/consumable.yaml @@ -1,3 +1,4 @@ +endpoint: "https://e.serverbid.com/api/v2" maintainer: email: "naffis@consumable.com" gvlVendorID: 591 diff --git a/static/bidder-info/conversant.yaml b/static/bidder-info/conversant.yaml index 1d298f8b582..da003b25c83 100644 --- a/static/bidder-info/conversant.yaml +++ b/static/bidder-info/conversant.yaml @@ -1,3 +1,4 @@ +endpoint: "http://api.hb.ad.cpe.dotomi.com/cvx/server/hb/ortb/25" maintainer: email: "CNVR_PublisherIntegration@conversantmedia.com" gvlVendorID: 24 diff --git a/static/bidder-info/cpmstar.yaml b/static/bidder-info/cpmstar.yaml index 46a7451bd1c..7c54ba53ca2 100644 --- a/static/bidder-info/cpmstar.yaml +++ b/static/bidder-info/cpmstar.yaml @@ -1,3 +1,4 @@ +endpoint: "https://server.cpmstar.com/openrtbbidrq.aspx" maintainer: email: "prebid@cpmstar.com" capabilities: @@ -12,4 +13,4 @@ capabilities: userSync: redirect: url: "https://server.cpmstar.com/usersync.aspx?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}" - userMacro: "$UID" \ No newline at end of file + userMacro: "$UID" diff --git a/static/bidder-info/criteo.yaml b/static/bidder-info/criteo.yaml index 5eb7eb37512..a522a14468d 100644 --- a/static/bidder-info/criteo.yaml +++ b/static/bidder-info/criteo.yaml @@ -1,3 +1,4 @@ +endpoint: "https://bidder.criteo.com/cdb?profileId=230" maintainer: email: "prebid@criteo.com" gvlVendorID: 91 @@ -12,4 +13,4 @@ userSync: # criteo supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. supports: - - redirect \ No newline at end of file + - redirect diff --git a/static/bidder-info/datablocks.yaml b/static/bidder-info/datablocks.yaml index 415dbc3546e..418b0cabc1e 100644 --- a/static/bidder-info/datablocks.yaml +++ b/static/bidder-info/datablocks.yaml @@ -1,3 +1,4 @@ +endpoint: "http://{{.Host}}/openrtb2?sid={{.SourceId}}" maintainer: email: "prebid@datablocks.net" capabilities: diff --git a/static/bidder-info/decenterads.yaml b/static/bidder-info/decenterads.yaml index c9b349cd78a..4324bbcac86 100644 --- a/static/bidder-info/decenterads.yaml +++ b/static/bidder-info/decenterads.yaml @@ -1,3 +1,4 @@ +endpoint: "http://supply.decenterads.com/?c=o&m=rtb" maintainer: email: "support@decenterads.com" modifyingVastXmlAllowed: true diff --git a/static/bidder-info/deepintent.yaml b/static/bidder-info/deepintent.yaml index 10ef458f133..95aba4207a1 100644 --- a/static/bidder-info/deepintent.yaml +++ b/static/bidder-info/deepintent.yaml @@ -1,3 +1,4 @@ +endpoint: "https://prebid.deepintent.com/prebid" maintainer: email: "prebiddev@deepintent.com" gvlVendorID: 541 @@ -12,3 +13,4 @@ userSync: redirect: url: "https://match.deepintent.com/usersync/136?id=unk&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir={{.RedirectURL}}" userMacro: "[UID]" + diff --git a/static/bidder-info/dianomi.yaml b/static/bidder-info/dianomi.yaml index d4a8d2f8bcb..1129e3c659c 100644 --- a/static/bidder-info/dianomi.yaml +++ b/static/bidder-info/dianomi.yaml @@ -1,3 +1,5 @@ +endpoint: "https://www-prebid.dianomi.com/cgi-bin/smartads_prebid.pl" +disabled: true maintainer: email: 'prebid-maintainer@dianomi.com' gvlVendorID: 885 diff --git a/static/bidder-info/dmx.yaml b/static/bidder-info/dmx.yaml index fa31886d229..d88d54e38c5 100644 --- a/static/bidder-info/dmx.yaml +++ b/static/bidder-info/dmx.yaml @@ -1,3 +1,4 @@ +endpoint: "https://dmx-direct.districtm.io/b/v2" maintainer: email: "prebid@districtm.net" gvlVendorID: 144 @@ -14,4 +15,4 @@ userSync: # dmx supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. supports: - - redirect \ No newline at end of file + - redirect diff --git a/static/bidder-info/e_volution.yaml b/static/bidder-info/e_volution.yaml index ddfef3dff36..b9d5532ca04 100644 --- a/static/bidder-info/e_volution.yaml +++ b/static/bidder-info/e_volution.yaml @@ -1,3 +1,4 @@ +endpoint: "http://service.e-volution.ai/pbserver" maintainer: email: "admin@e-volution.ai" gvlVendorID: 957 @@ -16,3 +17,4 @@ userSync: redirect: url: "https://sync.e-volution.ai/pbserver?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&ccpa={{.USPrivacy}}&redirect={{.RedirectURL}}" userMacro: "[UID]" + diff --git a/static/bidder-info/emx_digital.yaml b/static/bidder-info/emx_digital.yaml index a4cbd095934..0d8aa7f3a6d 100644 --- a/static/bidder-info/emx_digital.yaml +++ b/static/bidder-info/emx_digital.yaml @@ -1,3 +1,4 @@ +endpoint: "https://hb.emxdgt.com" maintainer: email: "adops@emxdigital.com" gvlVendorID: 183 diff --git a/static/bidder-info/engagebdr.yaml b/static/bidder-info/engagebdr.yaml index 0f9cc12fd89..8218040c605 100644 --- a/static/bidder-info/engagebdr.yaml +++ b/static/bidder-info/engagebdr.yaml @@ -1,3 +1,4 @@ +endpoint: "http://dsp.bnmla.com/hb" maintainer: email: "tech@engagebdr.com" capabilities: diff --git a/static/bidder-info/eplanning.yaml b/static/bidder-info/eplanning.yaml index 960244446aa..614d0f3b4c6 100644 --- a/static/bidder-info/eplanning.yaml +++ b/static/bidder-info/eplanning.yaml @@ -1,3 +1,4 @@ +endpoint: "http://rtb.e-planning.net/pbs/1" maintainer: email: "producto@e-planning.net" gvlVendorID: 90 diff --git a/static/bidder-info/epom.yaml b/static/bidder-info/epom.yaml index 991944ea35f..dc3b9908bca 100644 --- a/static/bidder-info/epom.yaml +++ b/static/bidder-info/epom.yaml @@ -1,3 +1,5 @@ +endpoint: "https://an.epom.com/ortb" +disabled: true maintainer: email: "support@epom.com" modifyingVastXmlAllowed: true diff --git a/static/bidder-info/gamma.yaml b/static/bidder-info/gamma.yaml index 4a79fafb0fd..7563dd40765 100644 --- a/static/bidder-info/gamma.yaml +++ b/static/bidder-info/gamma.yaml @@ -1,3 +1,4 @@ +endpoint: "https://hb.gammaplatform.com/adx/request/" maintainer: email: "support@gammassp.com" capabilities: @@ -9,4 +10,4 @@ userSync: # gamma supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. supports: - - iframe \ No newline at end of file + - iframe diff --git a/static/bidder-info/gamoshi.yaml b/static/bidder-info/gamoshi.yaml index c72d1770082..231d3a86f44 100644 --- a/static/bidder-info/gamoshi.yaml +++ b/static/bidder-info/gamoshi.yaml @@ -1,3 +1,4 @@ +endpoint: "https://rtb.gamoshi.io" maintainer: email: "dev@gamoshi.com" gvlVendorID: 644 diff --git a/static/bidder-info/grid.yaml b/static/bidder-info/grid.yaml index b6c13bc7000..409bad60369 100644 --- a/static/bidder-info/grid.yaml +++ b/static/bidder-info/grid.yaml @@ -1,3 +1,4 @@ +endpoint: "https://grid.bidswitch.net/sp_bid?sp=prebid" maintainer: email: "grid-tech@themediagrid.com" gvlVendorID: 686 diff --git a/static/bidder-info/groupm.yaml b/static/bidder-info/groupm.yaml index 9e487ad50a8..189527d5471 100644 --- a/static/bidder-info/groupm.yaml +++ b/static/bidder-info/groupm.yaml @@ -1,3 +1,4 @@ +endpoint: "https://hbopenbid.pubmatic.com/translator?source=prebid-server" maintainer: email: "header-bidding@pubmatic.com" gvlVendorID: 98 @@ -16,3 +17,4 @@ userSync: userMacro: "" # groupm appends the user id to end of the redirect url and does not utilize a macro + diff --git a/static/bidder-info/gumgum.yaml b/static/bidder-info/gumgum.yaml index 34b6f47d39e..f7e782e40df 100644 --- a/static/bidder-info/gumgum.yaml +++ b/static/bidder-info/gumgum.yaml @@ -1,3 +1,4 @@ +endpoint: "https://g2.gumgum.com/providers/prbds2s/bid" maintainer: email: "prebid@gumgum.com" gvlVendorID: 61 diff --git a/static/bidder-info/huaweiads.yaml b/static/bidder-info/huaweiads.yaml index 24e759f7b6f..8fe35b4e012 100644 --- a/static/bidder-info/huaweiads.yaml +++ b/static/bidder-info/huaweiads.yaml @@ -1,3 +1,5 @@ +endpoint: "https://acd.op.hicloud.com/ppsadx/getResult" +disabled: true maintainer: email: hwads@huawei.com gvlVendorID: 856 @@ -7,4 +9,4 @@ capabilities: mediaTypes: - banner - native - - video \ No newline at end of file + - video diff --git a/static/bidder-info/impactify.yaml b/static/bidder-info/impactify.yaml index c0ca61ae4b6..ec2cb7276f2 100644 --- a/static/bidder-info/impactify.yaml +++ b/static/bidder-info/impactify.yaml @@ -1,3 +1,4 @@ +endpoint: "https://sonic.impactify.media/bidder" maintainer: email: "support@impactify.io" gvlVendorID: 606 diff --git a/static/bidder-info/improvedigital.yaml b/static/bidder-info/improvedigital.yaml index 3a33275faa9..4a990e24929 100644 --- a/static/bidder-info/improvedigital.yaml +++ b/static/bidder-info/improvedigital.yaml @@ -1,3 +1,4 @@ +endpoint: "http://ad.360yield.com/pbs" maintainer: email: "hb@azerion.com" gvlVendorID: 253 diff --git a/static/bidder-info/infytv.yaml b/static/bidder-info/infytv.yaml index 02a045ee815..a262f3a6720 100644 --- a/static/bidder-info/infytv.yaml +++ b/static/bidder-info/infytv.yaml @@ -1,3 +1,4 @@ +endpoint: "https://nxs.infy.tv/pbs/openrtb" maintainer: email: "tech+hb@infy.tv" capabilities: diff --git a/static/bidder-info/inmobi.yaml b/static/bidder-info/inmobi.yaml index 43040658964..ad3562de64b 100644 --- a/static/bidder-info/inmobi.yaml +++ b/static/bidder-info/inmobi.yaml @@ -1,3 +1,4 @@ +endpoint: "https://api.w.inmobi.com/showad/openrtb/bidder/prebid" maintainer: email: "technology-irv@inmobi.com" gvlVendorID: 333 @@ -15,3 +16,4 @@ userSync: redirect: url: "https://sync.inmobi.com/prebid?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}" userMacro: "{ID5UID}" + diff --git a/static/bidder-info/interactiveoffers.yaml b/static/bidder-info/interactiveoffers.yaml index 70e810f5fda..040d9c02eb6 100644 --- a/static/bidder-info/interactiveoffers.yaml +++ b/static/bidder-info/interactiveoffers.yaml @@ -1,3 +1,4 @@ +endpoint: "https://prebid-server.ioadx.com/bidRequest/?partnerId={{.AccountID}}" maintainer: email: "dev@interactiveoffers.com" capabilities: diff --git a/static/bidder-info/invibes.yaml b/static/bidder-info/invibes.yaml index 1b87ea09b17..2e004f19958 100644 --- a/static/bidder-info/invibes.yaml +++ b/static/bidder-info/invibes.yaml @@ -1,3 +1,4 @@ +endpoint: "https://{{.ZoneID}}.videostep.com/bid/ServerBidAdContent" maintainer: email: "system_operations@invibes.com" gvlVendorID: 436 diff --git a/static/bidder-info/iqzone.yaml b/static/bidder-info/iqzone.yaml index 254caa8c6e3..3465cfabcb0 100644 --- a/static/bidder-info/iqzone.yaml +++ b/static/bidder-info/iqzone.yaml @@ -1,3 +1,4 @@ +endpoint: "http://smartssp-us-east.iqzone.com/pserver" maintainer: email: "smartssp@iqzone.com" capabilities: @@ -12,4 +13,4 @@ capabilities: - banner - video - native - + diff --git a/static/bidder-info/ix.yaml b/static/bidder-info/ix.yaml index 1efa8af063a..9ac7dba32dc 100644 --- a/static/bidder-info/ix.yaml +++ b/static/bidder-info/ix.yaml @@ -1,3 +1,4 @@ +disabled: true maintainer: email: "pdu-supply-prebid@indexexchange.com" gvlVendorID: 10 diff --git a/static/bidder-info/janet.yaml b/static/bidder-info/janet.yaml index a6e98f02c96..0a3abb53af4 100644 --- a/static/bidder-info/janet.yaml +++ b/static/bidder-info/janet.yaml @@ -1,3 +1,4 @@ +endpoint: "http://ghb.bidder.jmgads.com/pbs/ortb" maintainer: email: "info@thejmg.com" capabilities: diff --git a/static/bidder-info/jixie.yaml b/static/bidder-info/jixie.yaml index 0553f1f7393..88edd7877a8 100644 --- a/static/bidder-info/jixie.yaml +++ b/static/bidder-info/jixie.yaml @@ -1,3 +1,4 @@ +endpoint: "https://hb.jixie.io/v2/hbsvrpost" maintainer: email: contact@jixie.io modifyingVastXmlAllowed: true diff --git a/static/bidder-info/kargo.yaml b/static/bidder-info/kargo.yaml index 852c7ef3f8c..e73eabe9cdf 100644 --- a/static/bidder-info/kargo.yaml +++ b/static/bidder-info/kargo.yaml @@ -1,3 +1,4 @@ +endpoint: "https://krk.kargo.com/api/v1/openrtb" maintainer: email: "kraken@kargo.com" gvlVendorID: 972 diff --git a/static/bidder-info/kayzen.yaml b/static/bidder-info/kayzen.yaml index 45fd43c5a11..760bd3c3a4f 100644 --- a/static/bidder-info/kayzen.yaml +++ b/static/bidder-info/kayzen.yaml @@ -1,3 +1,4 @@ +endpoint: "https://bids-{{.ZoneID}}.bidder.kayzen.io/?exchange={{.AccountID}}" maintainer: email: "platform-dev@kayzen.io" gvlVendorID: 528 diff --git a/static/bidder-info/kidoz.yaml b/static/bidder-info/kidoz.yaml index e2a9eee3fc7..dd9eb3c668b 100644 --- a/static/bidder-info/kidoz.yaml +++ b/static/bidder-info/kidoz.yaml @@ -1,3 +1,4 @@ +endpoint: "http://prebid-adapter.kidoz.net/openrtb2/auction?src=prebid-server" maintainer: email: prebid-support@kidoz.net capabilities: diff --git a/static/bidder-info/krushmedia.yaml b/static/bidder-info/krushmedia.yaml index 82055a29988..75d29b5ebe7 100644 --- a/static/bidder-info/krushmedia.yaml +++ b/static/bidder-info/krushmedia.yaml @@ -1,3 +1,4 @@ +endpoint: "http://ads4.krushmedia.com/?c=rtb&m=req&key={{.AccountID}}" maintainer: email: "adapter@krushmedia.com" capabilities: diff --git a/static/bidder-info/kubient.yaml b/static/bidder-info/kubient.yaml index bd294372d93..15c2708bcb3 100644 --- a/static/bidder-info/kubient.yaml +++ b/static/bidder-info/kubient.yaml @@ -1,3 +1,4 @@ +endpoint: "https://kssp.kbntx.ch/prebid" maintainer: email: "prebid@kubient.com" capabilities: diff --git a/static/bidder-info/lockerdome.yaml b/static/bidder-info/lockerdome.yaml index cdb0434935d..cfefb2f995b 100644 --- a/static/bidder-info/lockerdome.yaml +++ b/static/bidder-info/lockerdome.yaml @@ -1,3 +1,4 @@ +endpoint: "https://lockerdome.com/ladbid/prebidserver/openrtb2" maintainer: email: "bidding@lockerdome.com" capabilities: @@ -25,4 +26,4 @@ userSync: # url: "https://lockerdome.com/usync/prebidserver?pid=<>&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}" # userMacro: "{{uid}}" supports: - - redirect \ No newline at end of file + - redirect diff --git a/static/bidder-info/logicad.yaml b/static/bidder-info/logicad.yaml index 4748cc75f09..b23e954d9a0 100644 --- a/static/bidder-info/logicad.yaml +++ b/static/bidder-info/logicad.yaml @@ -1,3 +1,4 @@ +endpoint: "https://pbs.ladsp.com/adrequest/prebidserver" maintainer: email: "prebid@so-netmedia.jp" capabilities: diff --git a/static/bidder-info/lunamedia.yaml b/static/bidder-info/lunamedia.yaml index 216fae9becf..79e19a4393f 100644 --- a/static/bidder-info/lunamedia.yaml +++ b/static/bidder-info/lunamedia.yaml @@ -1,3 +1,4 @@ +endpoint: "http://api.lunamedia.io/xp/get?pubid={{.PublisherID}}" maintainer: email: "josh@lunamedia.io" capabilities: diff --git a/static/bidder-info/madvertise.yaml b/static/bidder-info/madvertise.yaml index 6156940e6d5..262987a6654 100644 --- a/static/bidder-info/madvertise.yaml +++ b/static/bidder-info/madvertise.yaml @@ -1,3 +1,4 @@ +endpoint: "https://mobile.mng-ads.com/bidrequest{{.ZoneID}}" maintainer: email: "support@madvertise.com" gvlVendorID: 153 diff --git a/static/bidder-info/marsmedia.yaml b/static/bidder-info/marsmedia.yaml index 3080962d37c..7ba4ea6ee7a 100644 --- a/static/bidder-info/marsmedia.yaml +++ b/static/bidder-info/marsmedia.yaml @@ -1,3 +1,4 @@ +endpoint: "https://bid306.rtbsrv.com/bidder/?bid=f3xtet" maintainer: email: "prebid@mars.media" gvlVendorID: 776 diff --git a/static/bidder-info/mediafuse.yaml b/static/bidder-info/mediafuse.yaml index ca6bbb4be62..b78b21e16ea 100644 --- a/static/bidder-info/mediafuse.yaml +++ b/static/bidder-info/mediafuse.yaml @@ -1,3 +1,4 @@ +endpoint: "http://ib.adnxs.com/openrtb2" maintainer: email: "support@mediafuse.com" capabilities: @@ -12,4 +13,4 @@ capabilities: - video - native userSync: - key: "adnxs" \ No newline at end of file + key: "adnxs" diff --git a/static/bidder-info/medianet.yaml b/static/bidder-info/medianet.yaml index b4b5a21161a..ea47de2b11d 100644 --- a/static/bidder-info/medianet.yaml +++ b/static/bidder-info/medianet.yaml @@ -1,3 +1,5 @@ +endpoint: "https://prebid-adapter.media.net/rtb/pb/prebids2s" +extra_info: "https://medianet.golang.pbs.com" maintainer: email: "prebid-support@media.net" gvlVendorID: 142 diff --git a/static/bidder-info/mgid.yaml b/static/bidder-info/mgid.yaml index a9e20d631c0..8100fb4d348 100644 --- a/static/bidder-info/mgid.yaml +++ b/static/bidder-info/mgid.yaml @@ -1,3 +1,4 @@ +endpoint: "https://prebid.mgid.com/prebid/" maintainer: email: "prebid@mgid.com" gvlVendorID: 358 @@ -14,3 +15,4 @@ userSync: redirect: url: "https://cm.mgid.com/m?cdsp=363893&adu={{.RedirectURL}}" userMacro: "{muidn}" + diff --git a/static/bidder-info/mobfoxpb.yaml b/static/bidder-info/mobfoxpb.yaml index ba3bb60d554..0a1e78ec23c 100644 --- a/static/bidder-info/mobfoxpb.yaml +++ b/static/bidder-info/mobfoxpb.yaml @@ -1,3 +1,4 @@ +endpoint: "http://bes.mobfox.com/?c=__route__&m=__method__&key=__key__" maintainer: email: "platform@mobfox.com" capabilities: diff --git a/static/bidder-info/mobilefuse.yaml b/static/bidder-info/mobilefuse.yaml index 1a58889804c..ac0f89295ed 100644 --- a/static/bidder-info/mobilefuse.yaml +++ b/static/bidder-info/mobilefuse.yaml @@ -1,3 +1,4 @@ +endpoint: "http://mfx.mobilefuse.com/openrtb?pub_id={{.PublisherID}}" maintainer: email: prebid@mobilefuse.com gvlVendorID: 909 diff --git a/static/bidder-info/nanointeractive.yaml b/static/bidder-info/nanointeractive.yaml index 3b4db38dff8..639c5450d2e 100644 --- a/static/bidder-info/nanointeractive.yaml +++ b/static/bidder-info/nanointeractive.yaml @@ -1,3 +1,4 @@ +endpoint: "https://ad.audiencemanager.de/hbs" maintainer: email: "development@nanointeractive.com" gvlVendorID: 72 diff --git a/static/bidder-info/nextmillennium.yaml b/static/bidder-info/nextmillennium.yaml index e596e5d1ed1..e6f498ca159 100644 --- a/static/bidder-info/nextmillennium.yaml +++ b/static/bidder-info/nextmillennium.yaml @@ -1,3 +1,4 @@ +endpoint: "https://pbs.nextmillmedia.com/openrtb2/auction" maintainer: email: "accountmanagers@nextmillennium.io" capabilities: diff --git a/static/bidder-info/ninthdecimal.yaml b/static/bidder-info/ninthdecimal.yaml index db1392d78c8..8a4d7b8d299 100755 --- a/static/bidder-info/ninthdecimal.yaml +++ b/static/bidder-info/ninthdecimal.yaml @@ -1,3 +1,4 @@ +endpoint: "http://rtb.ninthdecimal.com/xp/get?pubid={{.PublisherID}}" maintainer: email: "abudig@ninthdecimal.com" capabilities: diff --git a/static/bidder-info/nobid.yaml b/static/bidder-info/nobid.yaml index 6fa65fe93bc..7c33998bf20 100644 --- a/static/bidder-info/nobid.yaml +++ b/static/bidder-info/nobid.yaml @@ -1,3 +1,4 @@ +endpoint: "https://ads.servenobid.com/ortb_adreq?tek=pbs&ver=1" maintainer: email: "developers@nobid.io" gvlVendorID: 816 diff --git a/static/bidder-info/oftmedia.yaml b/static/bidder-info/oftmedia.yaml index 8ec6862fdc0..587a6643109 100644 --- a/static/bidder-info/oftmedia.yaml +++ b/static/bidder-info/oftmedia.yaml @@ -1,3 +1,4 @@ +endpoint: "http://ghb.ortb.152media.info/pbs/ortb" maintainer: email: "admin@152media.com" gvlVendorID: 1111 diff --git a/static/bidder-info/onetag.yaml b/static/bidder-info/onetag.yaml index 1a00a9f3a07..4d03afe04bd 100644 --- a/static/bidder-info/onetag.yaml +++ b/static/bidder-info/onetag.yaml @@ -1,3 +1,4 @@ +endpoint: "https://prebid-server.onetag-sys.com/prebid-server/{{.PublisherID}}" maintainer: email: devops@onetag.com gvlVendorID: 241 diff --git a/static/bidder-info/openweb.yaml b/static/bidder-info/openweb.yaml index 5886c4a7845..9272719cf19 100644 --- a/static/bidder-info/openweb.yaml +++ b/static/bidder-info/openweb.yaml @@ -1,3 +1,4 @@ +endpoint: "http://ghb.spotim.market/pbs/ortb" maintainer: email: "monetization@openweb.com" gvlVendorID: 280 @@ -14,4 +15,4 @@ userSync: # openweb supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. supports: - - redirect \ No newline at end of file + - redirect diff --git a/static/bidder-info/openx.yaml b/static/bidder-info/openx.yaml index 96add482a07..9837b5dc92c 100644 --- a/static/bidder-info/openx.yaml +++ b/static/bidder-info/openx.yaml @@ -1,3 +1,4 @@ +endpoint: "http://rtb.openx.net/prebid" maintainer: email: "prebid@openx.com" gvlVendorID: 69 @@ -18,3 +19,4 @@ userSync: redirect: url: "https://rtb.openx.net/sync/prebid?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r={{.RedirectURL}}" userMacro: "${UID}" + diff --git a/static/bidder-info/operaads.yaml b/static/bidder-info/operaads.yaml index d28492b139a..fd16463f719 100644 --- a/static/bidder-info/operaads.yaml +++ b/static/bidder-info/operaads.yaml @@ -1,3 +1,4 @@ +endpoint: "https://s.adx.opera.com/ortb/v2/{{.PublisherID}}?ep={{.AccountID}}" maintainer: email: adtech-prebid-group@opera.com modifyingVastXmlAllowed: true diff --git a/static/bidder-info/orbidder.yaml b/static/bidder-info/orbidder.yaml index 467093c1256..b7891af3195 100644 --- a/static/bidder-info/orbidder.yaml +++ b/static/bidder-info/orbidder.yaml @@ -1,3 +1,4 @@ +endpoint: "https://orbidder.otto.de/openrtb2" maintainer: email: "realtime-siggi@otto.de" gvlVendorID: 559 diff --git a/static/bidder-info/outbrain.yaml b/static/bidder-info/outbrain.yaml index d24c603a6dc..69a12ca6dfa 100644 --- a/static/bidder-info/outbrain.yaml +++ b/static/bidder-info/outbrain.yaml @@ -1,3 +1,4 @@ +endpoint: "https://prebidtest.zemanta.com/api/bidder/prebidtest/bid/" maintainer: email: prog-ops-team@outbrain.com gvlVendorID: 164 diff --git a/static/bidder-info/pangle.yaml b/static/bidder-info/pangle.yaml index 3ac3a0ced0f..b70315679ef 100644 --- a/static/bidder-info/pangle.yaml +++ b/static/bidder-info/pangle.yaml @@ -1,3 +1,4 @@ +disabled: true maintainer: email: pangle_dsp@bytedance.com modifyingVastXmlAllowed: true diff --git a/static/bidder-info/pgam.yaml b/static/bidder-info/pgam.yaml index 16d25850fad..0c9b2f008b6 100644 --- a/static/bidder-info/pgam.yaml +++ b/static/bidder-info/pgam.yaml @@ -1,3 +1,4 @@ +endpoint: "http://ghb.pgamssp.com/pbs/ortb" maintainer: email: "ppatel@pgammedia.com" capabilities: diff --git a/static/bidder-info/pubmatic.yaml b/static/bidder-info/pubmatic.yaml index 085acfdb561..9841e8992e1 100644 --- a/static/bidder-info/pubmatic.yaml +++ b/static/bidder-info/pubmatic.yaml @@ -1,3 +1,4 @@ +endpoint: "https://hbopenbid.pubmatic.com/translator?source=prebid-server" maintainer: email: "header-bidding@pubmatic.com" gvlVendorID: 76 diff --git a/static/bidder-info/pubnative.yaml b/static/bidder-info/pubnative.yaml index 44bba23d7f3..00e80f41643 100644 --- a/static/bidder-info/pubnative.yaml +++ b/static/bidder-info/pubnative.yaml @@ -1,3 +1,4 @@ +endpoint: "http://dsp.pubnative.net/bid/v1/request" maintainer: email: product@pubnative.net gvlVendorID: 512 diff --git a/static/bidder-info/pulsepoint.yaml b/static/bidder-info/pulsepoint.yaml index 635ceb46006..762dbbb0c73 100644 --- a/static/bidder-info/pulsepoint.yaml +++ b/static/bidder-info/pulsepoint.yaml @@ -1,3 +1,4 @@ +endpoint: "http://bid.contextweb.com/header/s/ortb/prebid-s2s" maintainer: email: "ExchangeTeam@pulsepoint.com" gvlVendorID: 81 diff --git a/static/bidder-info/quantumdex.yaml b/static/bidder-info/quantumdex.yaml index 5ef240219fe..590737ac28b 100644 --- a/static/bidder-info/quantumdex.yaml +++ b/static/bidder-info/quantumdex.yaml @@ -1,3 +1,4 @@ +endpoint: "http://useast.quantumdex.io/auction/pbs" maintainer: email: "support@apacdex.com" modifyingVastXmlAllowed: false diff --git a/static/bidder-info/revcontent.yaml b/static/bidder-info/revcontent.yaml index 57e887565ce..a2e095a3e22 100644 --- a/static/bidder-info/revcontent.yaml +++ b/static/bidder-info/revcontent.yaml @@ -1,3 +1,5 @@ +endpoint: "https://trends.revcontent.com/rtb" +disabled: true maintainer: email: "developers@revcontent.com" gvlVendorID: 203 @@ -9,4 +11,4 @@ capabilities: site: mediaTypes: - banner - - native + - native \ No newline at end of file diff --git a/static/bidder-info/rhythmone.yaml b/static/bidder-info/rhythmone.yaml index 0ea79afc766..529eae12628 100644 --- a/static/bidder-info/rhythmone.yaml +++ b/static/bidder-info/rhythmone.yaml @@ -1,3 +1,4 @@ +endpoint: "http://tag.1rx.io/rmp" maintainer: email: "support@rhythmone.com" gvlVendorID: 36 @@ -13,4 +14,4 @@ capabilities: userSync: redirect: url: "https://sync.1rx.io/usersync2/rmphb?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir={{.RedirectURL}}" - userMacro: "[RX_UUID]" + userMacro: "[RX_UUID]" \ No newline at end of file diff --git a/static/bidder-info/richaudience.yaml b/static/bidder-info/richaudience.yaml index 3ec74ccdc82..d2f7abadeba 100644 --- a/static/bidder-info/richaudience.yaml +++ b/static/bidder-info/richaudience.yaml @@ -1,3 +1,4 @@ +endpoint: "http://ortb.richaudience.com/ortb/?bidder=pbs" maintainer: email: partnerintegrations@richaudience.com gvlVendorID: 108 diff --git a/static/bidder-info/rtbhouse.yaml b/static/bidder-info/rtbhouse.yaml index f93dc5e9c37..6a116448f22 100644 --- a/static/bidder-info/rtbhouse.yaml +++ b/static/bidder-info/rtbhouse.yaml @@ -1,3 +1,4 @@ +endpoint: "http://prebidserver-s2s-ams.creativecdn.com/bidder/prebidserver/bids" maintainer: email: "prebid@rtbhouse.com" gvlVendorID: 16 diff --git a/static/bidder-info/rubicon.yaml b/static/bidder-info/rubicon.yaml index a9f65f6e441..21f59e9db74 100644 --- a/static/bidder-info/rubicon.yaml +++ b/static/bidder-info/rubicon.yaml @@ -1,3 +1,5 @@ +endpoint: "http://exapi-us-east.rubiconproject.com/a/api/exchange.json" +disabled: true maintainer: email: "header-bidding@rubiconproject.com" gvlVendorID: 52 diff --git a/static/bidder-info/sa_lunamedia.yaml b/static/bidder-info/sa_lunamedia.yaml index f5c2cf78e20..568eb088397 100644 --- a/static/bidder-info/sa_lunamedia.yaml +++ b/static/bidder-info/sa_lunamedia.yaml @@ -1,3 +1,4 @@ +endpoint: "http://balancer.lmgssp.com/pserver" maintainer: email: "support@lunamedia.io" gvlVendorID: 998 diff --git a/static/bidder-info/seedingAlliance.yaml b/static/bidder-info/seedingAlliance.yaml index 10f37ddeb61..8d21218e2a4 100644 --- a/static/bidder-info/seedingAlliance.yaml +++ b/static/bidder-info/seedingAlliance.yaml @@ -1,3 +1,4 @@ +endpoint: "http://b.nativendo.de/cds/rtb/bid?ssp=pb" maintainer: email: tech@seeding-alliance.de gvlVendorID: 371 diff --git a/static/bidder-info/sharethrough.yaml b/static/bidder-info/sharethrough.yaml index 51cca6d0576..0a8453d516f 100644 --- a/static/bidder-info/sharethrough.yaml +++ b/static/bidder-info/sharethrough.yaml @@ -1,3 +1,4 @@ +endpoint: "https://btlr.sharethrough.com/universal/v1?supply_id=FGMrCMMc" maintainer: email: pubgrowth.engineering@sharethrough.com gvlVendorID: 80 diff --git a/static/bidder-info/silvermob.yaml b/static/bidder-info/silvermob.yaml index 5f1e4809dd3..c6f6d8acde5 100644 --- a/static/bidder-info/silvermob.yaml +++ b/static/bidder-info/silvermob.yaml @@ -1,3 +1,4 @@ +endpoint: "http://{{.Host}}.silvermob.com/marketplace/api/dsp/bid/{{.ZoneID}}" maintainer: email: "support@silvermob.com" capabilities: @@ -5,4 +6,4 @@ capabilities: mediaTypes: - banner - video - - native \ No newline at end of file + - native diff --git a/static/bidder-info/smaato.yaml b/static/bidder-info/smaato.yaml index a070db1d7d3..b9e9445e411 100644 --- a/static/bidder-info/smaato.yaml +++ b/static/bidder-info/smaato.yaml @@ -1,3 +1,4 @@ +endpoint: "https://prebid.ad.smaato.net/oapi/prebid" maintainer: email: "prebid@smaato.com" gvlVendorID: 82 @@ -14,3 +15,4 @@ userSync: redirect: url: "https://s.ad.smaato.net/c/?adExInit=p&redir={{.RedirectURL}}" userMacro: "$UID" + diff --git a/static/bidder-info/smartadserver.yaml b/static/bidder-info/smartadserver.yaml index ba36e551a74..48e88d94efa 100644 --- a/static/bidder-info/smartadserver.yaml +++ b/static/bidder-info/smartadserver.yaml @@ -1,3 +1,4 @@ +endpoint: "https://ssb-global.smartadserver.com" maintainer: email: "support@smartadserver.com" gvlVendorID: 45 @@ -15,4 +16,4 @@ capabilities: userSync: redirect: url: "https://ssbsync-global.smartadserver.com/api/sync?callerId=5&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirectUri={{.RedirectURL}}" - userMacro: "[ssb_sync_pid]" + userMacro: "[ssb_sync_pid]" \ No newline at end of file diff --git a/static/bidder-info/smarthub.yaml b/static/bidder-info/smarthub.yaml index 6932780f195..dcb65ede0ce 100644 --- a/static/bidder-info/smarthub.yaml +++ b/static/bidder-info/smarthub.yaml @@ -1,3 +1,4 @@ +endpoint: "http://{{.Host}}-prebid.smart-hub.io/?seat={{.AccountID}}&token={{.SourceId}}" maintainer: email: "support@smart-hub.io" capabilities: @@ -15,4 +16,4 @@ userSync: # smarthub supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. supports: - - redirect \ No newline at end of file + - redirect diff --git a/static/bidder-info/smartrtb.yaml b/static/bidder-info/smartrtb.yaml index d73afe0440c..8399f237177 100644 --- a/static/bidder-info/smartrtb.yaml +++ b/static/bidder-info/smartrtb.yaml @@ -1,3 +1,4 @@ +endpoint: "http://market-east.smrtb.com/json/publisher/rtb?pubid={{.PublisherID}}" maintainer: email: "engineering@smrtb.com" capabilities: @@ -13,3 +14,4 @@ userSync: redirect: url: "https://market-global.smrtb.com/sync/all?nid=smartrtb&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&rr={{.RedirectURL}}" userMacro: "{XID}" + diff --git a/static/bidder-info/smartyads.yaml b/static/bidder-info/smartyads.yaml index 2704f007ca3..b36983bc7b1 100644 --- a/static/bidder-info/smartyads.yaml +++ b/static/bidder-info/smartyads.yaml @@ -1,3 +1,4 @@ +endpoint: "http://{{.Host}}.smartyads.com/bid?rtb_seat_id={{.SourceId}}&secret_key={{.AccountID}}" maintainer: email: "support@smartyads.com" capabilities: diff --git a/static/bidder-info/smilewanted.yaml b/static/bidder-info/smilewanted.yaml index e3d62bd5db6..44aff8a055a 100644 --- a/static/bidder-info/smilewanted.yaml +++ b/static/bidder-info/smilewanted.yaml @@ -1,3 +1,4 @@ +endpoint: "http://prebid-server.smilewanted.com" maintainer: email: "tech@smilewanted.com" gvlVendorID: 639 @@ -13,4 +14,4 @@ capabilities: userSync: redirect: url: "https://csync.smilewanted.com/getuid?source=prebid-server&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}" - userMacro: "$UID" + userMacro: "$UID" \ No newline at end of file diff --git a/static/bidder-info/sonobi.yaml b/static/bidder-info/sonobi.yaml index 9961d322083..6f9afc36b3f 100644 --- a/static/bidder-info/sonobi.yaml +++ b/static/bidder-info/sonobi.yaml @@ -1,3 +1,4 @@ +endpoint: "https://apex.go.sonobi.com/prebid?partnerid=71d9d3d8af" maintainer: email: "apex.prebid@sonobi.com" gvlVendorID: 104 diff --git a/static/bidder-info/sovrn.yaml b/static/bidder-info/sovrn.yaml index f26d2d93fc0..2c77e0c0ac7 100644 --- a/static/bidder-info/sovrn.yaml +++ b/static/bidder-info/sovrn.yaml @@ -1,3 +1,4 @@ +endpoint: "http://pbs.lijit.com/rtb/bid?src=prebid_server" maintainer: email: "sovrnoss@sovrn.com" gvlVendorID: 13 diff --git a/static/bidder-info/sspBC.yaml b/static/bidder-info/sspBC.yaml index aefdf58ac34..572105d2407 100644 --- a/static/bidder-info/sspBC.yaml +++ b/static/bidder-info/sspBC.yaml @@ -1,3 +1,4 @@ +endpoint: "https://ssp.wp.pl/bidder/" maintainer: email: "prebid-dev@grupawp.pl" gvlVendorID: 676 @@ -9,4 +10,4 @@ userSync: default: iframe iframe: url: https://ssp.wp.pl/bidder/usersync?tcf=2&redirect={{.RedirectURL}} - userMacro: $UID \ No newline at end of file + userMacro: $UID diff --git a/static/bidder-info/streamkey.yaml b/static/bidder-info/streamkey.yaml index a13b71e588a..9e5d05abaec 100644 --- a/static/bidder-info/streamkey.yaml +++ b/static/bidder-info/streamkey.yaml @@ -1,3 +1,4 @@ +endpoint: "http://ghb.hb.streamkey.net/pbs/ortb" maintainer: email: "contact@streamkey.tv" capabilities: diff --git a/static/bidder-info/stroeerCore.yaml b/static/bidder-info/stroeerCore.yaml index 4db50faceeb..32c78590bb8 100644 --- a/static/bidder-info/stroeerCore.yaml +++ b/static/bidder-info/stroeerCore.yaml @@ -1,3 +1,5 @@ +endpoint: "http://mhb.adscale.de/s2sdsh" +disabled: true maintainer: email: "help@cz.stroeer-labs.com" gvlVendorID: 136 @@ -15,4 +17,4 @@ userSync: userMacro: "" redirect: url: "https://ih.adscale.de/uu?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&cburl={{.RedirectURL}}" - userMacro: "" + userMacro: "" \ No newline at end of file diff --git a/static/bidder-info/synacormedia.yaml b/static/bidder-info/synacormedia.yaml index 1769ab8282d..30f5308c517 100644 --- a/static/bidder-info/synacormedia.yaml +++ b/static/bidder-info/synacormedia.yaml @@ -1,3 +1,4 @@ +endpoint: "http://{{.Host}}.technoratimedia.com/openrtb/bids/{{.Host}}" maintainer: email: "eng-demand@imds.tv" capabilities: @@ -12,4 +13,4 @@ capabilities: userSync: iframe: url: "https://ad-cdn.technoratimedia.com/html/usersync.html?cb={{.RedirectURL}}" - userMacro: "[USER_ID]" + userMacro: "[USER_ID]" \ No newline at end of file diff --git a/static/bidder-info/tappx.yaml b/static/bidder-info/tappx.yaml index 6a321af0727..02f0fe805d7 100644 --- a/static/bidder-info/tappx.yaml +++ b/static/bidder-info/tappx.yaml @@ -1,3 +1,4 @@ +endpoint: "http://{{.Host}}" maintainer: email: "tappx@tappx.com" gvlVendorID: 628 diff --git a/static/bidder-info/telaria.yaml b/static/bidder-info/telaria.yaml index 7d9501dc086..f3411509a22 100644 --- a/static/bidder-info/telaria.yaml +++ b/static/bidder-info/telaria.yaml @@ -1,3 +1,4 @@ +endpoint: "https://ads.tremorhub.com/ad/rtb/prebid" maintainer: email: "github@telaria.com" gvlVendorID: 202 @@ -11,4 +12,4 @@ capabilities: userSync: redirect: url: "https://pbs.publishers.tremorhub.com/pubsync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redir={{.RedirectURL}}" - userMacro: "[tvid]" + userMacro: "[tvid]" \ No newline at end of file diff --git a/static/bidder-info/trafficgate.yaml b/static/bidder-info/trafficgate.yaml index 1d9ff63cac9..61cfd84537f 100644 --- a/static/bidder-info/trafficgate.yaml +++ b/static/bidder-info/trafficgate.yaml @@ -1,3 +1,4 @@ +endpoint: "http://{{.Host}}.bc-plugin.com/?c=o&m=rtb" maintainer: email: "support@bidscube.com" modifyingVastXmlAllowed: true diff --git a/static/bidder-info/triplelift.yaml b/static/bidder-info/triplelift.yaml index 0347161da33..45811c0c868 100644 --- a/static/bidder-info/triplelift.yaml +++ b/static/bidder-info/triplelift.yaml @@ -1,3 +1,4 @@ +endpoint: "https://tlx.3lift.com/s2s/auction?sra=1&supplier_id=20" maintainer: email: "prebid@triplelift.com" gvlVendorID: 28 diff --git a/static/bidder-info/triplelift_native.yaml b/static/bidder-info/triplelift_native.yaml index 96d49b32968..c3ea9299f01 100644 --- a/static/bidder-info/triplelift_native.yaml +++ b/static/bidder-info/triplelift_native.yaml @@ -1,3 +1,5 @@ +disabled: true +extra_info: "{\"publisher_whitelist\":[]}" maintainer: email: "prebid@triplelift.com" gvlVendorID: 28 diff --git a/static/bidder-info/trustx.yaml b/static/bidder-info/trustx.yaml index b6c13bc7000..5e407782e6a 100644 --- a/static/bidder-info/trustx.yaml +++ b/static/bidder-info/trustx.yaml @@ -1,3 +1,4 @@ +endpoint: "https://grid.bidswitch.net/sp_bid?sp=trustx" maintainer: email: "grid-tech@themediagrid.com" gvlVendorID: 686 @@ -13,4 +14,4 @@ capabilities: userSync: redirect: url: "https://x.bidswitch.net/check_uuid/{{.RedirectURL}}?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}" - userMacro: "${BSW_UUID}" + userMacro: "${BSW_UUID}" \ No newline at end of file diff --git a/static/bidder-info/ucfunnel.yaml b/static/bidder-info/ucfunnel.yaml index ca366c395c6..0034b9d4650 100644 --- a/static/bidder-info/ucfunnel.yaml +++ b/static/bidder-info/ucfunnel.yaml @@ -1,3 +1,4 @@ +endpoint: "https://pbs.aralego.com/prebid" maintainer: email: "support@ucfunnel.com" gvlVendorID: 607 diff --git a/static/bidder-info/unicorn.yaml b/static/bidder-info/unicorn.yaml index f1b5a4e7f3e..ba7fde10f15 100644 --- a/static/bidder-info/unicorn.yaml +++ b/static/bidder-info/unicorn.yaml @@ -1,6 +1,7 @@ +endpoint: "https://ds.uncn.jp/pb/0/bid.json" maintainer: email: prebid@unicorn.inc capabilities: app: mediaTypes: - - banner \ No newline at end of file + - banner diff --git a/static/bidder-info/unruly.yaml b/static/bidder-info/unruly.yaml index 9b1ba9c6f54..6389f831a64 100644 --- a/static/bidder-info/unruly.yaml +++ b/static/bidder-info/unruly.yaml @@ -1,3 +1,4 @@ +endpoint: "https://targeting.unrulymedia.com/unruly_prebid_server" maintainer: email: "prebidsupport@unrulygroup.com" gvlVendorID: 36 @@ -13,4 +14,4 @@ capabilities: userSync: redirect: url: "https://sync.1rx.io/usersync2/rmphb?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir={{.RedirectURL}}" - userMacro: "[RX_UUID]" + userMacro: "[RX_UUID]" \ No newline at end of file diff --git a/static/bidder-info/valueimpression.yaml b/static/bidder-info/valueimpression.yaml index 5ef240219fe..9e6e583967c 100644 --- a/static/bidder-info/valueimpression.yaml +++ b/static/bidder-info/valueimpression.yaml @@ -1,3 +1,4 @@ +endpoint: "http://useast.quantumdex.io/auction/pbs" maintainer: email: "support@apacdex.com" modifyingVastXmlAllowed: false @@ -16,4 +17,4 @@ userSync: userMacro: "[UID]" redirect: url: "https://sync.quantumdex.io/getuid?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}" - userMacro: "[UID]" + userMacro: "[UID]" \ No newline at end of file diff --git a/static/bidder-info/verizonmedia.yaml b/static/bidder-info/verizonmedia.yaml index 80db16ed28b..9be15b84091 100644 --- a/static/bidder-info/verizonmedia.yaml +++ b/static/bidder-info/verizonmedia.yaml @@ -1,3 +1,4 @@ +disabled: true maintainer: email: "dsp-supply-prebid@verizonmedia.com" gvlVendorID: 25 diff --git a/static/bidder-info/videobyte.yaml b/static/bidder-info/videobyte.yaml index fc0e767e1af..742b4dc6641 100644 --- a/static/bidder-info/videobyte.yaml +++ b/static/bidder-info/videobyte.yaml @@ -1,3 +1,4 @@ +endpoint: "https://x.videobyte.com/ortbhb" maintainer: email: "prebid@videobyte.com" gvlVendorID: 1011 diff --git a/static/bidder-info/vidoomy.yaml b/static/bidder-info/vidoomy.yaml index 1cd683a71e0..ef9db4ff752 100644 --- a/static/bidder-info/vidoomy.yaml +++ b/static/bidder-info/vidoomy.yaml @@ -1,3 +1,4 @@ +endpoint: "https://p.vidoomy.com/api/rtbserver/pbs" maintainer: email: support@vidoomy.com gvlVendorID: 380 diff --git a/static/bidder-info/viewdeos.yaml b/static/bidder-info/viewdeos.yaml index bf0c1789fe3..c5e1e8ef02c 100644 --- a/static/bidder-info/viewdeos.yaml +++ b/static/bidder-info/viewdeos.yaml @@ -1,3 +1,4 @@ +endpoint: "http://ghb.sync.viewdeos.com/pbs/ortb" maintainer: email: "contact@viewdeos.com" gvlVendorID: 924 @@ -14,4 +15,4 @@ userSync: # viewdeos supports user syncing, but requires configuration by the host. contact this # bidder directly at the email address in this file to ask about enabling user sync. supports: - - redirect \ No newline at end of file + - redirect diff --git a/static/bidder-info/visx.yaml b/static/bidder-info/visx.yaml index 7faf1b94ed9..b2acafaaedd 100644 --- a/static/bidder-info/visx.yaml +++ b/static/bidder-info/visx.yaml @@ -1,3 +1,4 @@ +endpoint: "https://t.visx.net/s2s_bid?wrapperType=s2s_prebid_standard:0.1.1" maintainer: email: "supply.partners@yoc.com" gvlVendorID: 154 diff --git a/static/bidder-info/vrtcal.yaml b/static/bidder-info/vrtcal.yaml index c6876836bde..0983d546fe9 100644 --- a/static/bidder-info/vrtcal.yaml +++ b/static/bidder-info/vrtcal.yaml @@ -1,6 +1,7 @@ +endpoint: "http://rtb.vrtcal.com/bidder_prebid.vap?ssp=1804" maintainer: email: "support@vrtcal.com" -gvlVendorID: 706 +gvlVendorID: 706 capabilities: app: mediaTypes: @@ -15,3 +16,4 @@ userSync: # bidder directly at the email address in this file to ask about enabling user sync. supports: - redirect + diff --git a/static/bidder-info/yahoossp.yaml b/static/bidder-info/yahoossp.yaml index cefa603dfd7..8c23c01e181 100644 --- a/static/bidder-info/yahoossp.yaml +++ b/static/bidder-info/yahoossp.yaml @@ -1,3 +1,4 @@ +endpoint: "https://s2shb.ssp.yahoo.com/admax/bid/partners/PBS" maintainer: email: "hb-fe-tech@oath.com" gvlVendorID: 25 diff --git a/static/bidder-info/yeahmobi.yaml b/static/bidder-info/yeahmobi.yaml index 063b09d0f75..ae41464f6fa 100644 --- a/static/bidder-info/yeahmobi.yaml +++ b/static/bidder-info/yeahmobi.yaml @@ -1,3 +1,4 @@ +endpoint: "https://{{.Host}}/prebid/bid" maintainer: email: "junping.zhao@yeahmobi.com" capabilities: @@ -5,4 +6,4 @@ capabilities: mediaTypes: - banner - video - - native \ No newline at end of file + - native diff --git a/static/bidder-info/yieldlab.yaml b/static/bidder-info/yieldlab.yaml index 14960089cd1..21932904a55 100644 --- a/static/bidder-info/yieldlab.yaml +++ b/static/bidder-info/yieldlab.yaml @@ -1,3 +1,4 @@ +endpoint: "https://ad.yieldlab.net/yp/" maintainer: email: "solutions@yieldlab.de" gvlVendorID: 70 diff --git a/static/bidder-info/yieldmo.yaml b/static/bidder-info/yieldmo.yaml index c5feacc83b9..9356a541f60 100644 --- a/static/bidder-info/yieldmo.yaml +++ b/static/bidder-info/yieldmo.yaml @@ -1,3 +1,4 @@ +endpoint: "https://ads.yieldmo.com/exchange/prebid-server" maintainer: email: "prebid@yieldmo.com" gvlVendorID: 173 @@ -13,4 +14,4 @@ capabilities: userSync: redirect: url: "https://ads.yieldmo.com/pbsync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirectUri={{.RedirectURL}}" - userMacro: "$UID" + userMacro: "$UID" \ No newline at end of file diff --git a/static/bidder-info/yieldone.yaml b/static/bidder-info/yieldone.yaml index 46215b5e8ec..1664ed9f674 100644 --- a/static/bidder-info/yieldone.yaml +++ b/static/bidder-info/yieldone.yaml @@ -1,3 +1,4 @@ +endpoint: "https://y.one.impact-ad.jp/hbs_imp" maintainer: email: "y1dev@platform-one.co.jp" capabilities: diff --git a/static/bidder-info/zeroclickfraud.yaml b/static/bidder-info/zeroclickfraud.yaml index 8f7149ea137..9a2b6979a5e 100644 --- a/static/bidder-info/zeroclickfraud.yaml +++ b/static/bidder-info/zeroclickfraud.yaml @@ -1,3 +1,4 @@ +endpoint: "http://{{.Host}}/openrtb2?sid={{.SourceId}}" maintainer: email: "support@datablocks.net" capabilities: @@ -14,4 +15,4 @@ capabilities: userSync: iframe: url: "https://s.0cf.io/sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}" - userMacro: "${uid}" + userMacro: "${uid}" \ No newline at end of file diff --git a/usersync/syncersbuilder.go b/usersync/syncersbuilder.go index 4c4c4207af6..c521d36dde2 100644 --- a/usersync/syncersbuilder.go +++ b/usersync/syncersbuilder.go @@ -81,7 +81,7 @@ func BuildSyncers(hostConfig *config.Configuration, bidderInfos config.BidderInf } func shouldCreateSyncer(cfg config.BidderInfo) bool { - if !cfg.Enabled { + if cfg.Disabled { return false } diff --git a/usersync/syncersbuilder_test.go b/usersync/syncersbuilder_test.go index 79727be6742..b3672a501bb 100644 --- a/usersync/syncersbuilder_test.go +++ b/usersync/syncersbuilder_test.go @@ -23,14 +23,14 @@ func TestBuildSyncers(t *testing.T) { hostConfig = config.Configuration{ExternalURL: "http://host.com", UserSync: config.UserSync{RedirectURL: "{{.ExternalURL}}/{{.SyncerKey}}/host"}} iframeConfig = &config.SyncerEndpoint{URL: "https://bidder.com/iframe?redirect={{.RedirectURL}}"} iframeConfigError = &config.SyncerEndpoint{URL: "https://bidder.com/iframe?redirect={{xRedirectURL}}"} // Error caused by invalid macro - infoKeyAPopulated = config.BidderInfo{Enabled: true, Syncer: &config.Syncer{Key: "a", IFrame: iframeConfig}} - infoKeyADisabled = config.BidderInfo{Enabled: false, Syncer: &config.Syncer{Key: "a", IFrame: iframeConfig}} - infoKeyAEmpty = config.BidderInfo{Enabled: true, Syncer: &config.Syncer{Key: "a"}} - infoKeyAError = config.BidderInfo{Enabled: true, Syncer: &config.Syncer{Key: "a", IFrame: iframeConfigError}} - infoKeyASupportsOnly = config.BidderInfo{Enabled: true, Syncer: &config.Syncer{Supports: []string{"iframe"}}} - infoKeyBPopulated = config.BidderInfo{Enabled: true, Syncer: &config.Syncer{Key: "b", IFrame: iframeConfig}} - infoKeyBEmpty = config.BidderInfo{Enabled: true, Syncer: &config.Syncer{Key: "b"}} - infoKeyMissingPopulated = config.BidderInfo{Enabled: true, Syncer: &config.Syncer{IFrame: iframeConfig}} + infoKeyAPopulated = config.BidderInfo{Disabled: false, Syncer: &config.Syncer{Key: "a", IFrame: iframeConfig}} + infoKeyADisabled = config.BidderInfo{Disabled: true, Syncer: &config.Syncer{Key: "a", IFrame: iframeConfig}} + infoKeyAEmpty = config.BidderInfo{Disabled: false, Syncer: &config.Syncer{Key: "a"}} + infoKeyAError = config.BidderInfo{Disabled: false, Syncer: &config.Syncer{Key: "a", IFrame: iframeConfigError}} + infoKeyASupportsOnly = config.BidderInfo{Disabled: false, Syncer: &config.Syncer{Supports: []string{"iframe"}}} + infoKeyBPopulated = config.BidderInfo{Disabled: false, Syncer: &config.Syncer{Key: "b", IFrame: iframeConfig}} + infoKeyBEmpty = config.BidderInfo{Disabled: false, Syncer: &config.Syncer{Key: "b"}} + infoKeyMissingPopulated = config.BidderInfo{Disabled: false, Syncer: &config.Syncer{IFrame: iframeConfig}} ) // NOTE: The hostConfig includes the syncer key in the RedirectURL to distinguish between the syncer keys @@ -190,82 +190,82 @@ func TestShouldCreateSyncer(t *testing.T) { }{ { description: "Enabled, No Syncer", - given: config.BidderInfo{Enabled: true, Syncer: nil}, + given: config.BidderInfo{Disabled: false, Syncer: nil}, expected: false, }, { description: "Enabled, Syncer", - given: config.BidderInfo{Enabled: true, Syncer: &config.Syncer{Key: "anyKey"}}, + given: config.BidderInfo{Disabled: false, Syncer: &config.Syncer{Key: "anyKey"}}, expected: true, }, { description: "Enabled, Syncer - Fully Loaded", - given: config.BidderInfo{Enabled: true, Syncer: &config.Syncer{Key: "anyKey", Supports: anySupports, IFrame: anyEndpoint, Redirect: anyEndpoint, SupportCORS: &anyCORS}}, + given: config.BidderInfo{Disabled: false, Syncer: &config.Syncer{Key: "anyKey", Supports: anySupports, IFrame: anyEndpoint, Redirect: anyEndpoint, SupportCORS: &anyCORS}}, expected: true, }, { description: "Enabled, Syncer - Only Key", - given: config.BidderInfo{Enabled: true, Syncer: &config.Syncer{Key: "anyKey"}}, + given: config.BidderInfo{Disabled: false, Syncer: &config.Syncer{Key: "anyKey"}}, expected: true, }, { description: "Enabled, Syncer - Only Supports", - given: config.BidderInfo{Enabled: true, Syncer: &config.Syncer{Supports: anySupports}}, + given: config.BidderInfo{Disabled: false, Syncer: &config.Syncer{Supports: anySupports}}, expected: false, }, { description: "Enabled, Syncer - Only IFrame", - given: config.BidderInfo{Enabled: true, Syncer: &config.Syncer{IFrame: anyEndpoint}}, + given: config.BidderInfo{Disabled: false, Syncer: &config.Syncer{IFrame: anyEndpoint}}, expected: true, }, { description: "Enabled, Syncer - Only Redirect", - given: config.BidderInfo{Enabled: true, Syncer: &config.Syncer{Redirect: anyEndpoint}}, + given: config.BidderInfo{Disabled: false, Syncer: &config.Syncer{Redirect: anyEndpoint}}, expected: true, }, { description: "Enabled, Syncer - Only SupportCORS", - given: config.BidderInfo{Enabled: true, Syncer: &config.Syncer{SupportCORS: &anyCORS}}, + given: config.BidderInfo{Disabled: false, Syncer: &config.Syncer{SupportCORS: &anyCORS}}, expected: true, }, { description: "Disabled, No Syncer", - given: config.BidderInfo{Enabled: false, Syncer: nil}, + given: config.BidderInfo{Disabled: true, Syncer: nil}, expected: false, }, { description: "Disabled, Syncer", - given: config.BidderInfo{Enabled: false, Syncer: &config.Syncer{Key: "anyKey"}}, + given: config.BidderInfo{Disabled: true, Syncer: &config.Syncer{Key: "anyKey"}}, expected: false, }, { description: "Disabled, Syncer - Fully Loaded", - given: config.BidderInfo{Enabled: false, Syncer: &config.Syncer{Key: "anyKey", Supports: anySupports, IFrame: anyEndpoint, Redirect: anyEndpoint, SupportCORS: &anyCORS}}, + given: config.BidderInfo{Disabled: true, Syncer: &config.Syncer{Key: "anyKey", Supports: anySupports, IFrame: anyEndpoint, Redirect: anyEndpoint, SupportCORS: &anyCORS}}, expected: false, }, { description: "Disabled, Syncer - Only Key", - given: config.BidderInfo{Enabled: false, Syncer: &config.Syncer{Key: "anyKey"}}, + given: config.BidderInfo{Disabled: true, Syncer: &config.Syncer{Key: "anyKey"}}, expected: false, }, { description: "Disabled, Syncer - Only Supports", - given: config.BidderInfo{Enabled: false, Syncer: &config.Syncer{Supports: anySupports}}, + given: config.BidderInfo{Disabled: true, Syncer: &config.Syncer{Supports: anySupports}}, expected: false, }, { description: "Disabled, Syncer - Only IFrame", - given: config.BidderInfo{Enabled: false, Syncer: &config.Syncer{IFrame: anyEndpoint}}, + given: config.BidderInfo{Disabled: true, Syncer: &config.Syncer{IFrame: anyEndpoint}}, expected: false, }, { description: "Disabled, Syncer - Only Redirect", - given: config.BidderInfo{Enabled: false, Syncer: &config.Syncer{Redirect: anyEndpoint}}, + given: config.BidderInfo{Disabled: true, Syncer: &config.Syncer{Redirect: anyEndpoint}}, expected: false, }, { description: "Disabled, Syncer - Only SupportCORS", - given: config.BidderInfo{Enabled: false, Syncer: &config.Syncer{SupportCORS: &anyCORS}}, + given: config.BidderInfo{Disabled: true, Syncer: &config.Syncer{SupportCORS: &anyCORS}}, expected: false, }, }