Skip to content

Commit

Permalink
Priority Bidder Ejection (#2952)
Browse files Browse the repository at this point in the history
* Priority Bidder Code

* Tweak Priority Ejector to update pri groups

* Fallback Ejector

* Opt out non prioity key support for oldest ejector

* Simplified removeElementFromPriorityGroup

* Add ejector specific tests

* Ejector refactor, remove fallback, add tests

* Fix validate merge fail

* Address comments

* Update IsSyncerPriority, update Pri Ejector

* Update ejector logic

* Implement TieEjector logic

* Minor tweaks

* Update IsSyncerPriority logic

* One line update to pri ejector

* Clean up, add tests

* Sole element > MaxCookieSize edge case

* Pass syncerByBidder, add new test

* Return unaltered cookie and 200

* Just return 200 and warning, cookie unchanged
  • Loading branch information
AlexBVolcy authored Sep 19, 2023
1 parent f54d374 commit b96e2f7
Show file tree
Hide file tree
Showing 12 changed files with 943 additions and 87 deletions.
2 changes: 2 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,8 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) {

v.SetDefault("event.timeout_ms", 1000)

v.SetDefault("user_sync.priority_groups", [][]string{})

v.SetDefault("accounts.filesystem.enabled", false)
v.SetDefault("accounts.filesystem.directorypath", "./stored_requests/data/by_id")
v.SetDefault("accounts.in_memory_cache.type", "none")
Expand Down
10 changes: 5 additions & 5 deletions config/usersync.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package config

// UserSync specifies the static global user sync configuration.
type UserSync struct {
Cooperative UserSyncCooperative `mapstructure:"coop_sync"`
ExternalURL string `mapstructure:"external_url"`
RedirectURL string `mapstructure:"redirect_url"`
Cooperative UserSyncCooperative `mapstructure:"coop_sync"`
ExternalURL string `mapstructure:"external_url"`
RedirectURL string `mapstructure:"redirect_url"`
PriorityGroups [][]string `mapstructure:"priority_groups"`
}

// UserSyncCooperative specifies the static global default cooperative cookie sync
type UserSyncCooperative struct {
EnabledByDefault bool `mapstructure:"default"`
PriorityGroups [][]string `mapstructure:"priority_groups"`
EnabledByDefault bool `mapstructure:"default"`
}
3 changes: 2 additions & 1 deletion endpoints/cookie_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ var (
errCookieSyncAccountBlocked = errors.New("account is disabled, please reach out to the prebid server host")
errCookieSyncAccountConfigMalformed = errors.New("account config is malformed and could not be read")
errCookieSyncAccountInvalid = errors.New("account must be valid if provided, please reach out to the prebid server host")
errSyncerIsNotPriority = errors.New("syncer key is not a priority, and there are only priority elements left")
)

var cookieSyncBidderFilterAllowAll = usersync.NewUniformBidderFilter(usersync.BidderFilterModeInclude)
Expand Down Expand Up @@ -168,7 +169,7 @@ func (c *cookieSyncEndpoint) parseRequest(r *http.Request) (usersync.Request, ma
Bidders: request.Bidders,
Cooperative: usersync.Cooperative{
Enabled: (request.CooperativeSync != nil && *request.CooperativeSync) || (request.CooperativeSync == nil && c.config.UserSync.Cooperative.EnabledByDefault),
PriorityGroups: c.config.UserSync.Cooperative.PriorityGroups,
PriorityGroups: c.config.UserSync.PriorityGroups,
},
Limit: request.Limit,
Privacy: usersyncPrivacy{
Expand Down
25 changes: 12 additions & 13 deletions endpoints/cookie_sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -515,9 +515,9 @@ func TestCookieSyncParseRequest(t *testing.T) {
givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"},
givenCCPAEnabled: true,
givenConfig: config.UserSync{
PriorityGroups: [][]string{{"a", "b", "c"}},
Cooperative: config.UserSyncCooperative{
EnabledByDefault: false,
PriorityGroups: [][]string{{"a", "b", "c"}},
},
},
expectedPrivacy: macros.UserSyncPrivacy{
Expand Down Expand Up @@ -557,9 +557,9 @@ func TestCookieSyncParseRequest(t *testing.T) {
givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"},
givenCCPAEnabled: true,
givenConfig: config.UserSync{
PriorityGroups: [][]string{{"a", "b", "c"}},
Cooperative: config.UserSyncCooperative{
EnabledByDefault: false,
PriorityGroups: [][]string{{"a", "b", "c"}},
},
},
expectedPrivacy: macros.UserSyncPrivacy{
Expand Down Expand Up @@ -608,9 +608,9 @@ func TestCookieSyncParseRequest(t *testing.T) {
givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"},
givenCCPAEnabled: true,
givenConfig: config.UserSync{
PriorityGroups: [][]string{{"a", "b", "c"}},
Cooperative: config.UserSyncCooperative{
EnabledByDefault: true,
PriorityGroups: [][]string{{"a", "b", "c"}},
},
},
expectedPrivacy: macros.UserSyncPrivacy{},
Expand All @@ -635,9 +635,9 @@ func TestCookieSyncParseRequest(t *testing.T) {
givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"},
givenCCPAEnabled: true,
givenConfig: config.UserSync{
PriorityGroups: [][]string{{"a", "b", "c"}},
Cooperative: config.UserSyncCooperative{
EnabledByDefault: false,
PriorityGroups: [][]string{{"a", "b", "c"}},
},
},
expectedPrivacy: macros.UserSyncPrivacy{},
Expand All @@ -662,9 +662,9 @@ func TestCookieSyncParseRequest(t *testing.T) {
givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"},
givenCCPAEnabled: true,
givenConfig: config.UserSync{
PriorityGroups: [][]string{{"a", "b", "c"}},
Cooperative: config.UserSyncCooperative{
EnabledByDefault: true,
PriorityGroups: [][]string{{"a", "b", "c"}},
},
},
expectedPrivacy: macros.UserSyncPrivacy{},
Expand All @@ -689,9 +689,9 @@ func TestCookieSyncParseRequest(t *testing.T) {
givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"},
givenCCPAEnabled: true,
givenConfig: config.UserSync{
PriorityGroups: [][]string{{"a", "b", "c"}},
Cooperative: config.UserSyncCooperative{
EnabledByDefault: false,
PriorityGroups: [][]string{{"a", "b", "c"}},
},
},
expectedPrivacy: macros.UserSyncPrivacy{},
Expand All @@ -716,9 +716,9 @@ func TestCookieSyncParseRequest(t *testing.T) {
givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"},
givenCCPAEnabled: true,
givenConfig: config.UserSync{
PriorityGroups: [][]string{{"a", "b", "c"}},
Cooperative: config.UserSyncCooperative{
EnabledByDefault: true,
PriorityGroups: [][]string{{"a", "b", "c"}},
},
},
expectedPrivacy: macros.UserSyncPrivacy{},
Expand All @@ -743,9 +743,9 @@ func TestCookieSyncParseRequest(t *testing.T) {
givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"},
givenCCPAEnabled: true,
givenConfig: config.UserSync{
PriorityGroups: [][]string{{"a", "b", "c"}},
Cooperative: config.UserSyncCooperative{
EnabledByDefault: false,
PriorityGroups: [][]string{{"a", "b", "c"}},
},
},
expectedPrivacy: macros.UserSyncPrivacy{},
Expand Down Expand Up @@ -890,9 +890,8 @@ func TestCookieSyncParseRequest(t *testing.T) {
givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"},
givenCCPAEnabled: true,
givenConfig: config.UserSync{
Cooperative: config.UserSyncCooperative{
PriorityGroups: [][]string{{"a", "b", "c"}},
},
PriorityGroups: [][]string{{"a", "b", "c"}},
Cooperative: config.UserSyncCooperative{},
},
expectedPrivacy: macros.UserSyncPrivacy{},
expectedRequest: usersync.Request{
Expand Down Expand Up @@ -921,9 +920,9 @@ func TestCookieSyncParseRequest(t *testing.T) {
givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"},
givenCCPAEnabled: true,
givenConfig: config.UserSync{
PriorityGroups: [][]string{{"a", "b", "c"}},
Cooperative: config.UserSyncCooperative{
EnabledByDefault: false,
PriorityGroups: [][]string{{"a", "b", "c"}},
},
},
expectedPrivacy: macros.UserSyncPrivacy{},
Expand Down Expand Up @@ -953,9 +952,9 @@ func TestCookieSyncParseRequest(t *testing.T) {
givenGDPRConfig: config.GDPR{Enabled: true, DefaultValue: "0"},
givenCCPAEnabled: true,
givenConfig: config.UserSync{
PriorityGroups: [][]string{{"a", "b", "c"}},
Cooperative: config.UserSyncCooperative{
EnabledByDefault: false,
PriorityGroups: [][]string{{"a", "b", "c"}},
},
},
expectedPrivacy: macros.UserSyncPrivacy{},
Expand Down
28 changes: 25 additions & 3 deletions endpoints/setuid.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,22 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use

setSiteCookie := siteCookieCheck(r.UserAgent())

// Priority Ejector Set Up
priorityEjector := &usersync.PriorityBidderEjector{PriorityGroups: cfg.UserSync.PriorityGroups, TieEjector: &usersync.OldestEjector{}, SyncersByBidder: syncersByBidder}
priorityEjector.IsSyncerPriority = isSyncerPriority(bidderName, cfg.UserSync.PriorityGroups)

// Write Cookie
encodedCookie, err := cookie.PrepareCookieForWrite(&cfg.HostCookie, encoder)
encodedCookie, err := cookie.PrepareCookieForWrite(&cfg.HostCookie, encoder, priorityEjector)
if err != nil {
handleBadStatus(w, http.StatusBadRequest, metrics.SetUidBadRequest, err, metricsEngine, &so)
return
if err.Error() == errSyncerIsNotPriority.Error() {
w.WriteHeader(http.StatusOK)
w.Write([]byte("Warning: " + err.Error() + ", cookie not updated"))
so.Status = http.StatusOK
return
} else {
handleBadStatus(w, http.StatusBadRequest, metrics.SetUidBadRequest, err, metricsEngine, &so)
return
}
}
usersync.WriteCookie(w, encodedCookie, &cfg.HostCookie, setSiteCookie)

Expand Down Expand Up @@ -326,6 +337,17 @@ func getSyncer(query url.Values, syncersByBidder map[string]usersync.Syncer) (us
return syncer, bidder, nil
}

func isSyncerPriority(bidderNameFromSyncerQuery string, priorityGroups [][]string) bool {
for _, group := range priorityGroups {
for _, bidder := range group {
if bidderNameFromSyncerQuery == bidder {
return true
}
}
}
return false
}

// getResponseFormat reads the format query parameter or falls back to the syncer's default.
// Returns either "b" (iframe), "i" (redirect), or an empty string "" (legacy behavior of an
// empty response body with no content type).
Expand Down
Loading

0 comments on commit b96e2f7

Please sign in to comment.