From 781dc7beb873df33be13183ac1fe74465c7fc50d Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Wed, 4 Oct 2023 12:25:14 -0400 Subject: [PATCH 1/4] Remove Config Backwards Compatibility: User Sync URL (#3163) --- config/bidderinfo.go | 53 --------------------- config/bidderinfo_test.go | 97 ++++++--------------------------------- config/config_test.go | 1 - 3 files changed, 15 insertions(+), 136 deletions(-) diff --git a/config/bidderinfo.go b/config/bidderinfo.go index 3b3f86d4ec9..f1f437c5c93 100644 --- a/config/bidderinfo.go +++ b/config/bidderinfo.go @@ -9,10 +9,8 @@ import ( "strings" "text/template" - "github.com/golang/glog" "github.com/prebid/prebid-server/macros" "github.com/prebid/prebid-server/openrtb_ext" - "github.com/prebid/prebid-server/util/sliceutil" validator "github.com/asaskevich/govalidator" "gopkg.in/yaml.v3" @@ -38,9 +36,6 @@ type BidderInfo struct { 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"` @@ -329,9 +324,6 @@ func processBidderAliases(aliasNillableFieldsByBidder map[string]aliasNillableFi syncer := Syncer{Key: syncerKey} aliasBidderInfo.Syncer = &syncer } - if aliasBidderInfo.UserSyncURL == "" { - aliasBidderInfo.UserSyncURL = parentBidderInfo.UserSyncURL - } if alias.Disabled == nil { aliasBidderInfo.Disabled = parentBidderInfo.Disabled } @@ -614,51 +606,6 @@ func applyBidderInfoConfigOverrides(configBidderInfos BidderInfos, fsBidderInfos 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[string(normalizedBidderName)] = bidderInfo } else { return nil, fmt.Errorf("error finding configuration for bidder %s: unknown bidder", bidderName) diff --git a/config/bidderinfo_test.go b/config/bidderinfo_test.go index 0900421a574..7b134314609 100644 --- a/config/bidderinfo_test.go +++ b/config/bidderinfo_test.go @@ -9,6 +9,7 @@ import ( "github.com/prebid/prebid-server/openrtb_ext" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const testInfoFilesPathValid = "./test/bidder-info-valid" @@ -50,7 +51,6 @@ disabled: false extra_info: extra-info app_secret: app-secret platform_id: 123 -usersync_url: user-url userSync: key: foo default: iframe @@ -217,7 +217,6 @@ func TestProcessBidderInfo(t *testing.T) { UserMacro: "UID", }, }, - UserSyncURL: "user-url", XAPI: AdapterXAPI{ Username: "uname", Password: "pwd", @@ -263,7 +262,6 @@ func TestProcessBidderInfo(t *testing.T) { Syncer: &Syncer{ Key: "foo", }, - UserSyncURL: "user-url", XAPI: AdapterXAPI{ Username: "uname", Password: "pwd", @@ -273,6 +271,7 @@ func TestProcessBidderInfo(t *testing.T) { }, }, } + for _, test := range testCases { reader := StubInfoReader{test.bidderInfos} bidderInfos, err := processBidderInfos(reader, mockNormalizeBidderName) @@ -281,9 +280,7 @@ func TestProcessBidderInfo(t *testing.T) { } else { assert.Equal(t, test.expectedBidderInfos, bidderInfos, "incorrect bidder infos for test case: %s", test.description) } - } - } func TestProcessAliasBidderInfo(t *testing.T) { @@ -328,7 +325,6 @@ func TestProcessAliasBidderInfo(t *testing.T) { UserMacro: "UID", }, }, - UserSyncURL: "user-url", XAPI: AdapterXAPI{ Username: "uname", Password: "pwd", @@ -376,7 +372,6 @@ func TestProcessAliasBidderInfo(t *testing.T) { UserMacro: "alias-UID", }, }, - UserSyncURL: "alias-user-url", XAPI: AdapterXAPI{ Username: "alias-uname", Password: "alias-pwd", @@ -1493,78 +1488,15 @@ func TestSyncerEndpointOverride(t *testing.T) { } 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", - }, - } + var ( + givenFileSystem = BidderInfos{"a": {Syncer: &Syncer{Key: "original"}}} + givenConfig = BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}} + expected = BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}} + ) - for _, test := range testCases { - bidderInfos, resultErr := applyBidderInfoConfigOverrides(test.givenConfigBidderInfos, test.givenFsBidderInfos, mockNormalizeBidderName) - 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") - } - } + result, resultErr := applyBidderInfoConfigOverrides(givenConfig, givenFileSystem, mockNormalizeBidderName) + assert.NoError(t, resultErr) + assert.Equal(t, expected, result) } func TestApplyBidderInfoConfigOverrides(t *testing.T) { @@ -1754,10 +1686,12 @@ func TestApplyBidderInfoConfigOverridesInvalid(t *testing.T) { func TestReadFullYamlBidderConfig(t *testing.T) { bidder := "bidderA" bidderInf := BidderInfo{} + err := yaml.Unmarshal([]byte(fullBidderYAMLConfig), &bidderInf) - actualBidderInfo, err := applyBidderInfoConfigOverrides(BidderInfos{bidder: bidderInf}, BidderInfos{bidder: {Syncer: &Syncer{Supports: []string{"iframe"}}}}, mockNormalizeBidderName) + require.NoError(t, err) - assert.NoError(t, err, "Error wasn't expected") + actualBidderInfo, err := applyBidderInfoConfigOverrides(BidderInfos{bidder: bidderInf}, BidderInfos{bidder: {Syncer: &Syncer{Supports: []string{"iframe"}}}}, mockNormalizeBidderName) + require.NoError(t, err) expectedBidderInfo := BidderInfos{ bidder: { @@ -1794,11 +1728,10 @@ func TestReadFullYamlBidderConfig(t *testing.T) { ExtraAdapterInfo: "extra-info", AppSecret: "app-secret", PlatformID: "123", - UserSyncURL: "user-url", Syncer: &Syncer{ Key: "foo", IFrame: &SyncerEndpoint{ - URL: "user-url", + URL: "https://foo.com/sync?mode=iframe&r={{.RedirectURL}}", RedirectURL: "https://redirect/setuid/iframe", ExternalURL: "https://iframe.host", UserMacro: "UID", diff --git a/config/config_test.go b/config/config_test.go index 97be28eb6e3..21d1681c1e7 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -32,7 +32,6 @@ var bidderInfos = BidderInfos{ MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}, }, }, - UserSyncURL: "http://bidder2.com/usersync", }, } From 134e9aa739da331754cfe4694f5fe8b767a1adb3 Mon Sep 17 00:00:00 2001 From: Veronika Solovei Date: Wed, 4 Oct 2023 16:33:06 -0700 Subject: [PATCH 2/4] Analytics activities (#3024) --- .../{config/config.go => build/build.go} | 47 ++++--- .../config_test.go => build/build_test.go} | 116 +++++++++++++++--- analytics/core.go | 4 +- analytics/filesystem/file_module.go | 2 +- analytics/pubstack/pubstack_module.go | 4 +- analytics/pubstack/pubstack_module_test.go | 14 +-- analytics/runner.go | 14 +++ endpoints/cookie_sync.go | 6 +- endpoints/cookie_sync_test.go | 44 +++---- endpoints/events/event.go | 9 +- endpoints/events/event_test.go | 9 +- endpoints/openrtb2/amp_auction.go | 12 +- endpoints/openrtb2/amp_auction_test.go | 37 +++--- endpoints/openrtb2/auction.go | 15 +-- endpoints/openrtb2/auction_benchmark_test.go | 4 +- endpoints/openrtb2/auction_test.go | 66 +++++----- endpoints/openrtb2/test_utils.go | 6 +- endpoints/openrtb2/video_auction.go | 10 +- endpoints/openrtb2/video_auction_test.go | 18 +-- endpoints/setuid.go | 4 +- endpoints/setuid_test.go | 34 ++--- router/router.go | 16 +-- 22 files changed, 307 insertions(+), 184 deletions(-) rename analytics/{config/config.go => build/build.go} (55%) rename analytics/{config/config_test.go => build/build_test.go} (50%) create mode 100644 analytics/runner.go diff --git a/analytics/config/config.go b/analytics/build/build.go similarity index 55% rename from analytics/config/config.go rename to analytics/build/build.go index 557fec361dc..6fb48705981 100644 --- a/analytics/config/config.go +++ b/analytics/build/build.go @@ -1,4 +1,4 @@ -package config +package build import ( "github.com/benbjohnson/clock" @@ -8,14 +8,15 @@ import ( "github.com/prebid/prebid-server/analytics/filesystem" "github.com/prebid/prebid-server/analytics/pubstack" "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/privacy" ) // Modules that need to be logged to need to be initialized here -func NewPBSAnalytics(analytics *config.Analytics) analytics.PBSAnalyticsModule { +func New(analytics *config.Analytics) analytics.Runner { modules := make(enabledAnalytics, 0) if len(analytics.File.Filename) > 0 { if mod, err := filesystem.NewFileLogger(analytics.File.Filename); err == nil { - modules = append(modules, mod) + modules["filelogger"] = mod } else { glog.Fatalf("Could not initialize FileLogger for file %v :%v", analytics.File.Filename, err) } @@ -32,7 +33,7 @@ func NewPBSAnalytics(analytics *config.Analytics) analytics.PBSAnalyticsModule { analytics.Pubstack.Buffers.Timeout, clock.New()) if err == nil { - modules = append(modules, pubstackModule) + modules["pubstack"] = pubstackModule } else { glog.Errorf("Could not initialize PubstackModule: %v", err) } @@ -41,17 +42,23 @@ func NewPBSAnalytics(analytics *config.Analytics) analytics.PBSAnalyticsModule { } // Collection of all the correctly configured analytics modules - implements the PBSAnalyticsModule interface -type enabledAnalytics []analytics.PBSAnalyticsModule +type enabledAnalytics map[string]analytics.Module -func (ea enabledAnalytics) LogAuctionObject(ao *analytics.AuctionObject) { - for _, module := range ea { - module.LogAuctionObject(ao) +func (ea enabledAnalytics) LogAuctionObject(ao *analytics.AuctionObject, ac privacy.ActivityControl) { + for name, module := range ea { + component := privacy.Component{Type: privacy.ComponentTypeAnalytics, Name: name} + if ac.Allow(privacy.ActivityReportAnalytics, component, privacy.ActivityRequest{}) { + module.LogAuctionObject(ao) + } } } -func (ea enabledAnalytics) LogVideoObject(vo *analytics.VideoObject) { - for _, module := range ea { - module.LogVideoObject(vo) +func (ea enabledAnalytics) LogVideoObject(vo *analytics.VideoObject, ac privacy.ActivityControl) { + for name, module := range ea { + component := privacy.Component{Type: privacy.ComponentTypeAnalytics, Name: name} + if ac.Allow(privacy.ActivityReportAnalytics, component, privacy.ActivityRequest{}) { + module.LogVideoObject(vo) + } } } @@ -67,14 +74,20 @@ func (ea enabledAnalytics) LogSetUIDObject(so *analytics.SetUIDObject) { } } -func (ea enabledAnalytics) LogAmpObject(ao *analytics.AmpObject) { - for _, module := range ea { - module.LogAmpObject(ao) +func (ea enabledAnalytics) LogAmpObject(ao *analytics.AmpObject, ac privacy.ActivityControl) { + for name, module := range ea { + component := privacy.Component{Type: privacy.ComponentTypeAnalytics, Name: name} + if ac.Allow(privacy.ActivityReportAnalytics, component, privacy.ActivityRequest{}) { + module.LogAmpObject(ao) + } } } -func (ea enabledAnalytics) LogNotificationEventObject(ne *analytics.NotificationEvent) { - for _, module := range ea { - module.LogNotificationEventObject(ne) +func (ea enabledAnalytics) LogNotificationEventObject(ne *analytics.NotificationEvent, ac privacy.ActivityControl) { + for name, module := range ea { + component := privacy.Component{Type: privacy.ComponentTypeAnalytics, Name: name} + if ac.Allow(privacy.ActivityReportAnalytics, component, privacy.ActivityRequest{}) { + module.LogNotificationEventObject(ne) + } } } diff --git a/analytics/config/config_test.go b/analytics/build/build_test.go similarity index 50% rename from analytics/config/config_test.go rename to analytics/build/build_test.go index c0ad9c26a16..dbd129a7afd 100644 --- a/analytics/config/config_test.go +++ b/analytics/build/build_test.go @@ -1,15 +1,16 @@ -package config +package build import ( + "github.com/prebid/prebid-server/analytics" "net/http" "os" "testing" "github.com/prebid/openrtb/v19/openrtb2" - "github.com/stretchr/testify/assert" - - "github.com/prebid/prebid-server/analytics" "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/privacy" + "github.com/prebid/prebid-server/util/ptrutil" + "github.com/stretchr/testify/assert" ) const TEST_DIR string = "testFiles" @@ -21,7 +22,7 @@ func TestSampleModule(t *testing.T) { Status: http.StatusOK, Errors: nil, Response: &openrtb2.BidResponse{}, - }) + }, privacy.ActivityControl{}) if count != 1 { t.Errorf("PBSAnalyticsModule failed at LogAuctionObject") } @@ -42,17 +43,17 @@ func TestSampleModule(t *testing.T) { t.Errorf("PBSAnalyticsModule failed at LogCookieSyncObject") } - am.LogAmpObject(&analytics.AmpObject{}) + am.LogAmpObject(&analytics.AmpObject{}, privacy.ActivityControl{}) if count != 4 { t.Errorf("PBSAnalyticsModule failed at LogAmpObject") } - am.LogVideoObject(&analytics.VideoObject{}) + am.LogVideoObject(&analytics.VideoObject{}, privacy.ActivityControl{}) if count != 5 { t.Errorf("PBSAnalyticsModule failed at LogVideoObject") } - am.LogNotificationEventObject(&analytics.NotificationEvent{}) + am.LogNotificationEventObject(&analytics.NotificationEvent{}, privacy.ActivityControl{}) if count != 6 { t.Errorf("PBSAnalyticsModule failed at LogNotificationEventObject") } @@ -74,14 +75,14 @@ func (m *sampleModule) LogAmpObject(ao *analytics.AmpObject) { *m.count++ } func (m *sampleModule) LogNotificationEventObject(ne *analytics.NotificationEvent) { *m.count++ } -func initAnalytics(count *int) analytics.PBSAnalyticsModule { +func initAnalytics(count *int) analytics.Runner { modules := make(enabledAnalytics, 0) - modules = append(modules, &sampleModule{count}) + modules["sampleModule"] = &sampleModule{count} return &modules } func TestNewPBSAnalytics(t *testing.T) { - pbsAnalytics := NewPBSAnalytics(&config.Analytics{}) + pbsAnalytics := New(&config.Analytics{}) instance := pbsAnalytics.(enabledAnalytics) assert.Equal(t, len(instance), 0) @@ -94,7 +95,7 @@ func TestNewPBSAnalytics_FileLogger(t *testing.T) { } } defer os.RemoveAll(TEST_DIR) - mod := NewPBSAnalytics(&config.Analytics{File: config.FileLogs{Filename: TEST_DIR + "/test"}}) + mod := New(&config.Analytics{File: config.FileLogs{Filename: TEST_DIR + "/test"}}) switch modType := mod.(type) { case enabledAnalytics: if len(enabledAnalytics(modType)) != 1 { @@ -104,7 +105,7 @@ func TestNewPBSAnalytics_FileLogger(t *testing.T) { t.Fatalf("Failed to initialize analytics module") } - pbsAnalytics := NewPBSAnalytics(&config.Analytics{File: config.FileLogs{Filename: TEST_DIR + "/test"}}) + pbsAnalytics := New(&config.Analytics{File: config.FileLogs{Filename: TEST_DIR + "/test"}}) instance := pbsAnalytics.(enabledAnalytics) assert.Equal(t, len(instance), 1) @@ -112,7 +113,7 @@ func TestNewPBSAnalytics_FileLogger(t *testing.T) { func TestNewPBSAnalytics_Pubstack(t *testing.T) { - pbsAnalyticsWithoutError := NewPBSAnalytics(&config.Analytics{ + pbsAnalyticsWithoutError := New(&config.Analytics{ Pubstack: config.Pubstack{ Enabled: true, ScopeId: "scopeId", @@ -129,7 +130,7 @@ func TestNewPBSAnalytics_Pubstack(t *testing.T) { assert.Equal(t, len(instanceWithoutError), 1) - pbsAnalyticsWithError := NewPBSAnalytics(&config.Analytics{ + pbsAnalyticsWithError := New(&config.Analytics{ Pubstack: config.Pubstack{ Enabled: true, }, @@ -137,3 +138,88 @@ func TestNewPBSAnalytics_Pubstack(t *testing.T) { instanceWithError := pbsAnalyticsWithError.(enabledAnalytics) assert.Equal(t, len(instanceWithError), 0) } + +func TestSampleModuleActivitiesAllowed(t *testing.T) { + var count int + am := initAnalytics(&count) + + acAllowed := privacy.NewActivityControl(getDefaultActivityConfig("sampleModule", true)) + + ao := &analytics.AuctionObject{ + Status: http.StatusOK, + Errors: nil, + Response: &openrtb2.BidResponse{}, + } + + am.LogAuctionObject(ao, acAllowed) + if count != 1 { + t.Errorf("PBSAnalyticsModule failed at LogAuctionObject") + } + + am.LogAmpObject(&analytics.AmpObject{}, acAllowed) + if count != 2 { + t.Errorf("PBSAnalyticsModule failed at LogAmpObject") + } + + am.LogVideoObject(&analytics.VideoObject{}, acAllowed) + if count != 3 { + t.Errorf("PBSAnalyticsModule failed at LogVideoObject") + } + + am.LogNotificationEventObject(&analytics.NotificationEvent{}, acAllowed) + if count != 4 { + t.Errorf("PBSAnalyticsModule failed at LogNotificationEventObject") + } +} + +func TestSampleModuleActivitiesDenied(t *testing.T) { + var count int + am := initAnalytics(&count) + + acDenied := privacy.NewActivityControl(getDefaultActivityConfig("sampleModule", false)) + + ao := &analytics.AuctionObject{ + Status: http.StatusOK, + Errors: nil, + Response: &openrtb2.BidResponse{}, + } + + am.LogAuctionObject(ao, acDenied) + if count != 0 { + t.Errorf("PBSAnalyticsModule failed at LogAuctionObject") + } + + am.LogAmpObject(&analytics.AmpObject{}, acDenied) + if count != 0 { + t.Errorf("PBSAnalyticsModule failed at LogAmpObject") + } + + am.LogVideoObject(&analytics.VideoObject{}, acDenied) + if count != 0 { + t.Errorf("PBSAnalyticsModule failed at LogVideoObject") + } + + am.LogNotificationEventObject(&analytics.NotificationEvent{}, acDenied) + if count != 0 { + t.Errorf("PBSAnalyticsModule failed at LogNotificationEventObject") + } +} + +func getDefaultActivityConfig(componentName string, allow bool) *config.AccountPrivacy { + return &config.AccountPrivacy{ + AllowActivities: &config.AllowActivities{ + ReportAnalytics: config.Activity{ + Default: ptrutil.ToPtr(true), + Rules: []config.ActivityRule{ + { + Allow: allow, + Condition: config.ActivityCondition{ + ComponentName: []string{componentName}, + ComponentType: []string{"analytics"}, + }, + }, + }, + }, + }, + } +} diff --git a/analytics/core.go b/analytics/core.go index eca93741bd2..0279ae83868 100644 --- a/analytics/core.go +++ b/analytics/core.go @@ -9,10 +9,10 @@ import ( "github.com/prebid/prebid-server/openrtb_ext" ) -// PBSAnalyticsModule must be implemented by analytics modules to extract the required information and logging +// Module must be implemented by analytics modules to extract the required information and logging // activities. Do not use marshal the parameter objects directly as they can change over time. Use a separate // model for each analytics module and transform as appropriate. -type PBSAnalyticsModule interface { +type Module interface { LogAuctionObject(*AuctionObject) LogVideoObject(*VideoObject) LogCookieSyncObject(*CookieSyncObject) diff --git a/analytics/filesystem/file_module.go b/analytics/filesystem/file_module.go index 9a357529c3a..f055e4470b1 100644 --- a/analytics/filesystem/file_module.go +++ b/analytics/filesystem/file_module.go @@ -86,7 +86,7 @@ func (f *FileLogger) LogNotificationEventObject(ne *analytics.NotificationEvent) } // Method to initialize the analytic module -func NewFileLogger(filename string) (analytics.PBSAnalyticsModule, error) { +func NewFileLogger(filename string) (analytics.Module, error) { options := glog.LogOptions{ File: filename, Flag: glog.LstdFlags, diff --git a/analytics/pubstack/pubstack_module.go b/analytics/pubstack/pubstack_module.go index 987c935f884..f2d8726d356 100644 --- a/analytics/pubstack/pubstack_module.go +++ b/analytics/pubstack/pubstack_module.go @@ -50,7 +50,7 @@ type PubstackModule struct { clock clock.Clock } -func NewModule(client *http.Client, scope, endpoint, configRefreshDelay string, maxEventCount int, maxByteSize, maxTime string, clock clock.Clock) (analytics.PBSAnalyticsModule, error) { +func NewModule(client *http.Client, scope, endpoint, configRefreshDelay string, maxEventCount int, maxByteSize, maxTime string, clock clock.Clock) (analytics.Module, error) { configUpdateTask, err := NewConfigUpdateHttpTask( client, scope, @@ -63,7 +63,7 @@ func NewModule(client *http.Client, scope, endpoint, configRefreshDelay string, return NewModuleWithConfigTask(client, scope, endpoint, maxEventCount, maxByteSize, maxTime, configUpdateTask, clock) } -func NewModuleWithConfigTask(client *http.Client, scope, endpoint string, maxEventCount int, maxByteSize, maxTime string, configTask ConfigUpdateTask, clock clock.Clock) (analytics.PBSAnalyticsModule, error) { +func NewModuleWithConfigTask(client *http.Client, scope, endpoint string, maxEventCount int, maxByteSize, maxTime string, configTask ConfigUpdateTask, clock clock.Clock) (analytics.Module, error) { glog.Infof("[pubstack] Initializing module scope=%s endpoint=%s\n", scope, endpoint) // parse args diff --git a/analytics/pubstack/pubstack_module_test.go b/analytics/pubstack/pubstack_module_test.go index 504a1cfe17e..23e110df9c1 100644 --- a/analytics/pubstack/pubstack_module_test.go +++ b/analytics/pubstack/pubstack_module_test.go @@ -50,47 +50,47 @@ func TestNewModuleSuccess(t *testing.T) { tests := []struct { description string feature string - logObject func(analytics.PBSAnalyticsModule) + logObject func(analytics.Module) }{ { description: "auction events are only published when logging an auction object with auction feature on", feature: auction, - logObject: func(module analytics.PBSAnalyticsModule) { + logObject: func(module analytics.Module) { module.LogAuctionObject(&analytics.AuctionObject{Status: http.StatusOK}) }, }, { description: "AMP events are only published when logging an AMP object with AMP feature on", feature: amp, - logObject: func(module analytics.PBSAnalyticsModule) { + logObject: func(module analytics.Module) { module.LogAmpObject(&analytics.AmpObject{Status: http.StatusOK}) }, }, { description: "video events are only published when logging a video object with video feature on", feature: video, - logObject: func(module analytics.PBSAnalyticsModule) { + logObject: func(module analytics.Module) { module.LogVideoObject(&analytics.VideoObject{Status: http.StatusOK}) }, }, { description: "cookie events are only published when logging a cookie object with cookie feature on", feature: cookieSync, - logObject: func(module analytics.PBSAnalyticsModule) { + logObject: func(module analytics.Module) { module.LogCookieSyncObject(&analytics.CookieSyncObject{Status: http.StatusOK}) }, }, { description: "setUID events are only published when logging a setUID object with setUID feature on", feature: setUID, - logObject: func(module analytics.PBSAnalyticsModule) { + logObject: func(module analytics.Module) { module.LogSetUIDObject(&analytics.SetUIDObject{Status: http.StatusOK}) }, }, { description: "Ignore excluded fields from marshal", feature: auction, - logObject: func(module analytics.PBSAnalyticsModule) { + logObject: func(module analytics.Module) { module.LogAuctionObject(&analytics.AuctionObject{ RequestWrapper: &openrtb_ext.RequestWrapper{}, SeatNonBid: []openrtb_ext.SeatNonBid{ diff --git a/analytics/runner.go b/analytics/runner.go new file mode 100644 index 00000000000..08f67561f8a --- /dev/null +++ b/analytics/runner.go @@ -0,0 +1,14 @@ +package analytics + +import ( + "github.com/prebid/prebid-server/privacy" +) + +type Runner interface { + LogAuctionObject(*AuctionObject, privacy.ActivityControl) + LogVideoObject(*VideoObject, privacy.ActivityControl) + LogCookieSyncObject(*CookieSyncObject) + LogSetUIDObject(*SetUIDObject) + LogAmpObject(*AmpObject, privacy.ActivityControl) + LogNotificationEventObject(*NotificationEvent, privacy.ActivityControl) +} diff --git a/endpoints/cookie_sync.go b/endpoints/cookie_sync.go index bbee3847014..24530efa56a 100644 --- a/endpoints/cookie_sync.go +++ b/endpoints/cookie_sync.go @@ -50,7 +50,7 @@ func NewCookieSyncEndpoint( gdprPermsBuilder gdpr.PermissionsBuilder, tcf2CfgBuilder gdpr.TCF2ConfigBuilder, metrics metrics.MetricsEngine, - pbsAnalytics analytics.PBSAnalyticsModule, + analyticsRunner analytics.Runner, accountsFetcher stored_requests.AccountFetcher, bidders map[string]openrtb_ext.BidderName) HTTPRouterHandler { @@ -70,7 +70,7 @@ func NewCookieSyncEndpoint( bidderHashSet: bidderHashSet, }, metrics: metrics, - pbsAnalytics: pbsAnalytics, + pbsAnalytics: analyticsRunner, accountsFetcher: accountsFetcher, } } @@ -80,7 +80,7 @@ type cookieSyncEndpoint struct { config *config.Configuration privacyConfig usersyncPrivacyConfig metrics metrics.MetricsEngine - pbsAnalytics analytics.PBSAnalyticsModule + pbsAnalytics analytics.Runner accountsFetcher stored_requests.AccountFetcher } diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go index 80de2b5ff50..45f7a75da0c 100644 --- a/endpoints/cookie_sync_test.go +++ b/endpoints/cookie_sync_test.go @@ -42,7 +42,7 @@ func TestNewCookieSyncEndpoint(t *testing.T) { configGDPR = config.GDPR{HostVendorID: 42} configCCPAEnforce = true metrics = metrics.MetricsEngineMock{} - analytics = MockAnalytics{} + analytics = MockAnalyticsRunner{} fetcher = FakeAccountsFetcher{} bidders = map[string]openrtb_ext.BidderName{"bidderA": openrtb_ext.BidderName("bidderA"), "bidderB": openrtb_ext.BidderName("bidderB")} ) @@ -114,7 +114,7 @@ func TestCookieSyncHandle(t *testing.T) { expectedStatusCode int expectedBody string setMetricsExpectations func(*metrics.MetricsEngineMock) - setAnalyticsExpectations func(*MockAnalytics) + setAnalyticsExpectations func(*MockAnalyticsRunner) }{ { description: "Request With Cookie", @@ -133,7 +133,7 @@ func TestCookieSyncHandle(t *testing.T) { m.On("RecordCookieSync", metrics.CookieSyncOK).Once() m.On("RecordSyncerRequest", "aSyncer", metrics.SyncerCookieSyncOK).Once() }, - setAnalyticsExpectations: func(a *MockAnalytics) { + setAnalyticsExpectations: func(a *MockAnalyticsRunner) { expected := analytics.CookieSyncObject{ Status: 200, Errors: nil, @@ -165,7 +165,7 @@ func TestCookieSyncHandle(t *testing.T) { m.On("RecordCookieSync", metrics.CookieSyncOK).Once() m.On("RecordSyncerRequest", "aSyncer", metrics.SyncerCookieSyncOK).Once() }, - setAnalyticsExpectations: func(a *MockAnalytics) { + setAnalyticsExpectations: func(a *MockAnalyticsRunner) { expected := analytics.CookieSyncObject{ Status: 200, Errors: nil, @@ -194,7 +194,7 @@ func TestCookieSyncHandle(t *testing.T) { setMetricsExpectations: func(m *metrics.MetricsEngineMock) { m.On("RecordCookieSync", metrics.CookieSyncBadRequest).Once() }, - setAnalyticsExpectations: func(a *MockAnalytics) { + setAnalyticsExpectations: func(a *MockAnalyticsRunner) { expected := analytics.CookieSyncObject{ Status: 400, Errors: []error{errors.New("JSON parsing failed: invalid character 'm' looking for beginning of value")}, @@ -217,7 +217,7 @@ func TestCookieSyncHandle(t *testing.T) { setMetricsExpectations: func(m *metrics.MetricsEngineMock) { m.On("RecordCookieSync", metrics.CookieSyncOptOut).Once() }, - setAnalyticsExpectations: func(a *MockAnalytics) { + setAnalyticsExpectations: func(a *MockAnalyticsRunner) { expected := analytics.CookieSyncObject{ Status: 401, Errors: []error{errors.New("User has opted out")}, @@ -240,7 +240,7 @@ func TestCookieSyncHandle(t *testing.T) { setMetricsExpectations: func(m *metrics.MetricsEngineMock) { m.On("RecordCookieSync", metrics.CookieSyncGDPRHostCookieBlocked).Once() }, - setAnalyticsExpectations: func(a *MockAnalytics) { + setAnalyticsExpectations: func(a *MockAnalyticsRunner) { expected := analytics.CookieSyncObject{ Status: 200, Errors: nil, @@ -255,7 +255,7 @@ func TestCookieSyncHandle(t *testing.T) { mockMetrics := metrics.MetricsEngineMock{} test.setMetricsExpectations(&mockMetrics) - mockAnalytics := MockAnalytics{} + mockAnalytics := MockAnalyticsRunner{} test.setAnalyticsExpectations(&mockAnalytics) fakeAccountFetcher := FakeAccountsFetcher{} @@ -1248,7 +1248,7 @@ func TestSetCooperativeSync(t *testing.T) { func TestWriteParseRequestErrorMetrics(t *testing.T) { err := errors.New("anyError") - mockAnalytics := MockAnalytics{} + mockAnalytics := MockAnalyticsRunner{} mockAnalytics.On("LogCookieSyncObject", mock.Anything) writer := httptest.NewRecorder() @@ -1471,7 +1471,7 @@ func TestParseBidderFilter(t *testing.T) { func TestCookieSyncHandleError(t *testing.T) { err := errors.New("anyError") - mockAnalytics := MockAnalytics{} + mockAnalytics := MockAnalyticsRunner{} mockAnalytics.On("LogCookieSyncObject", mock.Anything) writer := httptest.NewRecorder() @@ -1664,7 +1664,7 @@ func TestCookieSyncHandleResponse(t *testing.T) { } for _, test := range testCases { - mockAnalytics := MockAnalytics{} + mockAnalytics := MockAnalyticsRunner{} mockAnalytics.On("LogCookieSyncObject", &test.expectedAnalytics).Once() cookie := usersync.NewCookie() @@ -1996,32 +1996,32 @@ func (m *MockSyncer) GetSync(syncTypes []usersync.SyncType, privacyMacros macros return args.Get(0).(usersync.Sync), args.Error(1) } -type MockAnalytics struct { +type MockAnalyticsRunner struct { mock.Mock } -func (m *MockAnalytics) LogAuctionObject(obj *analytics.AuctionObject) { - m.Called(obj) +func (m *MockAnalyticsRunner) LogAuctionObject(obj *analytics.AuctionObject, ac privacy.ActivityControl) { + m.Called(obj, ac) } -func (m *MockAnalytics) LogVideoObject(obj *analytics.VideoObject) { - m.Called(obj) +func (m *MockAnalyticsRunner) LogVideoObject(obj *analytics.VideoObject, ac privacy.ActivityControl) { + m.Called(obj, ac) } -func (m *MockAnalytics) LogCookieSyncObject(obj *analytics.CookieSyncObject) { +func (m *MockAnalyticsRunner) LogCookieSyncObject(obj *analytics.CookieSyncObject) { m.Called(obj) } -func (m *MockAnalytics) LogSetUIDObject(obj *analytics.SetUIDObject) { +func (m *MockAnalyticsRunner) LogSetUIDObject(obj *analytics.SetUIDObject) { m.Called(obj) } -func (m *MockAnalytics) LogAmpObject(obj *analytics.AmpObject) { - m.Called(obj) +func (m *MockAnalyticsRunner) LogAmpObject(obj *analytics.AmpObject, ac privacy.ActivityControl) { + m.Called(obj, ac) } -func (m *MockAnalytics) LogNotificationEventObject(obj *analytics.NotificationEvent) { - m.Called(obj) +func (m *MockAnalyticsRunner) LogNotificationEventObject(obj *analytics.NotificationEvent, ac privacy.ActivityControl) { + m.Called(obj, ac) } type MockGDPRPerms struct { diff --git a/endpoints/events/event.go b/endpoints/events/event.go index 7f923eda09d..d5cf89b2ef5 100644 --- a/endpoints/events/event.go +++ b/endpoints/events/event.go @@ -16,6 +16,7 @@ import ( "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/metrics" + "github.com/prebid/prebid-server/privacy" "github.com/prebid/prebid-server/stored_requests" "github.com/prebid/prebid-server/util/httputil" ) @@ -40,13 +41,13 @@ const integrationParamMaxLength = 64 type eventEndpoint struct { Accounts stored_requests.AccountFetcher - Analytics analytics.PBSAnalyticsModule + Analytics analytics.Runner Cfg *config.Configuration TrackingPixel *httputil.Pixel MetricsEngine metrics.MetricsEngine } -func NewEventEndpoint(cfg *config.Configuration, accounts stored_requests.AccountFetcher, analytics analytics.PBSAnalyticsModule, me metrics.MetricsEngine) httprouter.Handle { +func NewEventEndpoint(cfg *config.Configuration, accounts stored_requests.AccountFetcher, analytics analytics.Runner, me metrics.MetricsEngine) httprouter.Handle { ee := &eventEndpoint{ Accounts: accounts, Analytics: analytics, @@ -114,11 +115,13 @@ func (e *eventEndpoint) Handle(w http.ResponseWriter, r *http.Request, _ httprou return } + activities := privacy.NewActivityControl(&account.Privacy) + // handle notification event e.Analytics.LogNotificationEventObject(&analytics.NotificationEvent{ Request: eventRequest, Account: account, - }) + }, activities) // Add tracking pixel if format == image if eventRequest.Format == analytics.Image { diff --git a/endpoints/events/event_test.go b/endpoints/events/event_test.go index 7f129634221..d721187b6ff 100644 --- a/endpoints/events/event_test.go +++ b/endpoints/events/event_test.go @@ -16,6 +16,7 @@ import ( "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/metrics" + "github.com/prebid/prebid-server/privacy" "github.com/prebid/prebid-server/stored_requests" "github.com/stretchr/testify/assert" ) @@ -26,13 +27,13 @@ type eventsMockAnalyticsModule struct { Invoked bool } -func (e *eventsMockAnalyticsModule) LogAuctionObject(ao *analytics.AuctionObject) { +func (e *eventsMockAnalyticsModule) LogAuctionObject(ao *analytics.AuctionObject, _ privacy.ActivityControl) { if e.Fail { panic(e.Error) } } -func (e *eventsMockAnalyticsModule) LogVideoObject(vo *analytics.VideoObject) { +func (e *eventsMockAnalyticsModule) LogVideoObject(vo *analytics.VideoObject, _ privacy.ActivityControl) { if e.Fail { panic(e.Error) } @@ -50,13 +51,13 @@ func (e *eventsMockAnalyticsModule) LogSetUIDObject(so *analytics.SetUIDObject) } } -func (e *eventsMockAnalyticsModule) LogAmpObject(ao *analytics.AmpObject) { +func (e *eventsMockAnalyticsModule) LogAmpObject(ao *analytics.AmpObject, _ privacy.ActivityControl) { if e.Fail { panic(e.Error) } } -func (e *eventsMockAnalyticsModule) LogNotificationEventObject(ne *analytics.NotificationEvent) { +func (e *eventsMockAnalyticsModule) LogNotificationEventObject(ne *analytics.NotificationEvent, _ privacy.ActivityControl) { if e.Fail { panic(e.Error) } diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index aa80d0756c3..76762d8b9ea 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -11,8 +11,6 @@ import ( "strings" "time" - "github.com/prebid/prebid-server/privacy" - "github.com/buger/jsonparser" "github.com/golang/glog" "github.com/julienschmidt/httprouter" @@ -33,6 +31,7 @@ import ( "github.com/prebid/prebid-server/hooks" "github.com/prebid/prebid-server/metrics" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/privacy" "github.com/prebid/prebid-server/stored_requests" "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" "github.com/prebid/prebid-server/stored_responses" @@ -64,7 +63,7 @@ func NewAmpEndpoint( accounts stored_requests.AccountFetcher, cfg *config.Configuration, metricsEngine metrics.MetricsEngine, - pbsAnalytics analytics.PBSAnalyticsModule, + analyticsRunner analytics.Runner, disabledBidders map[string]string, defReqJSON []byte, bidderMap map[string]openrtb_ext.BidderName, @@ -93,7 +92,7 @@ func NewAmpEndpoint( accounts, cfg, metricsEngine, - pbsAnalytics, + analyticsRunner, disabledBidders, defRequest, defReqJSON, @@ -134,11 +133,12 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h CookieFlag: metrics.CookieFlagUnknown, RequestStatus: metrics.RequestStatusOK, } + activityControl := privacy.ActivityControl{} defer func() { deps.metricsEngine.RecordRequest(labels) deps.metricsEngine.RecordRequestTime(labels, time.Since(start)) - deps.analytics.LogAmpObject(&ao) + deps.analytics.LogAmpObject(&ao, activityControl) }() // Add AMP headers @@ -230,7 +230,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h tcf2Config := gdpr.NewTCF2Config(deps.cfg.GDPR.TCF2, account.GDPR) - activityControl := privacy.NewActivityControl(&account.Privacy) + activityControl = privacy.NewActivityControl(&account.Privacy) secGPC := r.Header.Get("Sec-GPC") diff --git a/endpoints/openrtb2/amp_auction_test.go b/endpoints/openrtb2/amp_auction_test.go index 89d9c472925..3c0feb4f7ab 100644 --- a/endpoints/openrtb2/amp_auction_test.go +++ b/endpoints/openrtb2/amp_auction_test.go @@ -20,7 +20,7 @@ import ( "github.com/prebid/prebid-server/amp" "github.com/prebid/prebid-server/analytics" - analyticsConf "github.com/prebid/prebid-server/analytics/config" + analyticsBuild "github.com/prebid/prebid-server/analytics/build" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/exchange" @@ -30,6 +30,7 @@ import ( "github.com/prebid/prebid-server/metrics" metricsConfig "github.com/prebid/prebid-server/metrics/config" "github.com/prebid/prebid-server/openrtb_ext" + "github.com/prebid/prebid-server/privacy" "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" ) @@ -201,7 +202,7 @@ func TestAMPPageInfo(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -305,7 +306,7 @@ func TestGDPRConsent(t *testing.T) { GDPR: config.GDPR{Enabled: true}, }, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -729,7 +730,7 @@ func TestCCPAConsent(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -843,7 +844,7 @@ func TestConsentWarnings(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -942,7 +943,7 @@ func TestNewAndLegacyConsentBothProvided(t *testing.T) { GDPR: config.GDPR{Enabled: true}, }, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -997,7 +998,7 @@ func TestAMPSiteExt(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), nil, nil, openrtb_ext.BuildBidderMap(), @@ -1040,7 +1041,7 @@ func TestAmpBadRequests(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -1074,7 +1075,7 @@ func TestAmpDebug(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -1210,7 +1211,7 @@ func TestQueryParamOverrides(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -1368,7 +1369,7 @@ func (s formatOverrideSpec) execute(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -1631,25 +1632,25 @@ type mockLogger struct { auctionObject *analytics.AuctionObject } -func newMockLogger(ao *analytics.AmpObject, aucObj *analytics.AuctionObject) analytics.PBSAnalyticsModule { +func newMockLogger(ao *analytics.AmpObject, aucObj *analytics.AuctionObject) analytics.Runner { return &mockLogger{ ampObject: ao, auctionObject: aucObj, } } -func (logger mockLogger) LogAuctionObject(ao *analytics.AuctionObject) { +func (logger mockLogger) LogAuctionObject(ao *analytics.AuctionObject, _ privacy.ActivityControl) { *logger.auctionObject = *ao } -func (logger mockLogger) LogVideoObject(vo *analytics.VideoObject) { +func (logger mockLogger) LogVideoObject(vo *analytics.VideoObject, _ privacy.ActivityControl) { } func (logger mockLogger) LogCookieSyncObject(cookieObject *analytics.CookieSyncObject) { } func (logger mockLogger) LogSetUIDObject(uuidObj *analytics.SetUIDObject) { } -func (logger mockLogger) LogNotificationEventObject(uuidObj *analytics.NotificationEvent) { +func (logger mockLogger) LogNotificationEventObject(uuidObj *analytics.NotificationEvent, _ privacy.ActivityControl) { } -func (logger mockLogger) LogAmpObject(ao *analytics.AmpObject) { +func (logger mockLogger) LogAmpObject(ao *analytics.AmpObject, _ privacy.ActivityControl) { *logger.ampObject = *ao } @@ -1962,7 +1963,7 @@ func TestAmpAuctionResponseHeaders(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -1998,7 +1999,7 @@ func TestRequestWithTargeting(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), nil, nil, openrtb_ext.BuildBidderMap(), diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index b625c0ff54c..4fce4c15786 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -14,8 +14,6 @@ import ( "strings" "time" - "github.com/prebid/prebid-server/privacy" - "github.com/buger/jsonparser" "github.com/gofrs/uuid" "github.com/golang/glog" @@ -30,6 +28,7 @@ import ( "github.com/prebid/prebid-server/bidadjustment" "github.com/prebid/prebid-server/hooks" "github.com/prebid/prebid-server/ortb" + "github.com/prebid/prebid-server/privacy" "golang.org/x/net/publicsuffix" jsonpatch "gopkg.in/evanphx/json-patch.v4" @@ -89,7 +88,7 @@ func NewEndpoint( accounts stored_requests.AccountFetcher, cfg *config.Configuration, metricsEngine metrics.MetricsEngine, - pbsAnalytics analytics.PBSAnalyticsModule, + analyticsRunner analytics.Runner, disabledBidders map[string]string, defReqJSON []byte, bidderMap map[string]openrtb_ext.BidderName, @@ -117,7 +116,7 @@ func NewEndpoint( accounts, cfg, metricsEngine, - pbsAnalytics, + analyticsRunner, disabledBidders, defRequest, defReqJSON, @@ -139,7 +138,7 @@ type endpointDeps struct { accounts stored_requests.AccountFetcher cfg *config.Configuration metricsEngine metrics.MetricsEngine - analytics analytics.PBSAnalyticsModule + analytics analytics.Runner disabledBidders map[string]string defaultRequest bool defReqJSON []byte @@ -176,10 +175,12 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http CookieFlag: metrics.CookieFlagUnknown, RequestStatus: metrics.RequestStatusOK, } + + activityControl := privacy.ActivityControl{} defer func() { deps.metricsEngine.RecordRequest(labels) deps.metricsEngine.RecordRequestTime(labels, time.Since(start)) - deps.analytics.LogAuctionObject(&ao) + deps.analytics.LogAuctionObject(&ao, activityControl) }() w.Header().Set("X-Prebid", version.BuildXPrebidHeader(version.Ver)) @@ -197,7 +198,7 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http tcf2Config := gdpr.NewTCF2Config(deps.cfg.GDPR.TCF2, account.GDPR) - activityControl := privacy.NewActivityControl(&account.Privacy) + activityControl = privacy.NewActivityControl(&account.Privacy) ctx := context.Background() diff --git a/endpoints/openrtb2/auction_benchmark_test.go b/endpoints/openrtb2/auction_benchmark_test.go index ee74548ea47..f3e82dca099 100644 --- a/endpoints/openrtb2/auction_benchmark_test.go +++ b/endpoints/openrtb2/auction_benchmark_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - analyticsConf "github.com/prebid/prebid-server/analytics/config" + analyticsBuild "github.com/prebid/prebid-server/analytics/build" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/currency" "github.com/prebid/prebid-server/exchange" @@ -105,7 +105,7 @@ func BenchmarkOpenrtbEndpoint(b *testing.B) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, nilMetrics, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, nil, diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index b5631c93d3d..55bf68ff730 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -23,7 +23,7 @@ import ( nativeRequests "github.com/prebid/openrtb/v19/native1/request" "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/analytics" - analyticsConf "github.com/prebid/prebid-server/analytics/config" + analyticsBuild "github.com/prebid/prebid-server/analytics/build" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/exchange" @@ -447,7 +447,7 @@ func TestExplicitUserId(t *testing.T) { empty_fetcher.EmptyFetcher{}, cfg, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -505,7 +505,7 @@ func doBadAliasRequest(t *testing.T, filename string, expectMsg string) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), disabledBidders, aliasJSON, bidderMap, @@ -560,7 +560,7 @@ func TestNilExchange(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), map[string]string{}, + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), empty_fetcher.EmptyFetcher{}, @@ -585,7 +585,7 @@ func TestNilValidator(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -611,7 +611,7 @@ func TestExchangeError(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -738,7 +738,7 @@ func TestImplicitIPsEndToEnd(t *testing.T) { empty_fetcher.EmptyFetcher{}, cfg, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -938,7 +938,7 @@ func TestImplicitDNTEndToEnd(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -1175,7 +1175,7 @@ func TestStoredRequests(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -1624,7 +1624,7 @@ func TestValidateRequest(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -2403,7 +2403,7 @@ func TestSetIntegrationType(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -2469,7 +2469,7 @@ func TestStoredRequestGenerateUuid(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -2573,7 +2573,7 @@ func TestOversizedRequest(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(len(reqBody) - 1)}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -2612,7 +2612,7 @@ func TestRequestSizeEdgeCase(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(len(reqBody))}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -2649,7 +2649,7 @@ func TestNoEncoding(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -2734,7 +2734,7 @@ func TestContentType(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -2951,7 +2951,7 @@ func TestValidateImpExt(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(8096)}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{"disabledbidder": "The bidder 'disabledbidder' has been disabled."}, false, []byte{}, @@ -3006,7 +3006,7 @@ func TestCurrencyTrunc(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -3054,7 +3054,7 @@ func TestCCPAInvalid(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -3106,7 +3106,7 @@ func TestNoSaleInvalid(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -3161,7 +3161,7 @@ func TestValidateSourceTID(t *testing.T) { empty_fetcher.EmptyFetcher{}, cfg, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -3206,7 +3206,7 @@ func TestSChainInvalid(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -3774,7 +3774,7 @@ func TestEidPermissionsInvalid(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -4028,7 +4028,7 @@ func TestIOS14EndToEnd(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -4091,7 +4091,7 @@ func TestAuctionWarnings(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -4137,7 +4137,7 @@ func TestParseRequestParseImpInfoError(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(len(reqBody))}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -4217,7 +4217,7 @@ func TestParseGzipedRequest(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(50), Compression: config.Compression{Request: config.CompressionInfo{GZIP: false}}}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -4716,7 +4716,7 @@ func TestAuctionResponseHeaders(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, []byte{}, openrtb_ext.BuildBidderMap(), @@ -4817,7 +4817,7 @@ func TestParseRequestMergeBidderParams(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(len(test.givenRequestBody))}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -4920,7 +4920,7 @@ func TestParseRequestStoredResponses(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(len(test.givenRequestBody))}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -5018,7 +5018,7 @@ func TestParseRequestStoredBidResponses(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(len(test.givenRequestBody))}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -5054,7 +5054,7 @@ func TestValidateStoredResp(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -5867,7 +5867,7 @@ func TestParseRequestMultiBid(t *testing.T) { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: int64(len(test.givenRequestBody))}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, diff --git a/endpoints/openrtb2/test_utils.go b/endpoints/openrtb2/test_utils.go index 2d22f1e4ebe..365f480eb4c 100644 --- a/endpoints/openrtb2/test_utils.go +++ b/endpoints/openrtb2/test_utils.go @@ -20,7 +20,7 @@ import ( "github.com/prebid/openrtb/v19/openrtb3" "github.com/prebid/prebid-server/adapters" "github.com/prebid/prebid-server/analytics" - analyticsConf "github.com/prebid/prebid-server/analytics/config" + analyticsBuild "github.com/prebid/prebid-server/analytics/build" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/currency" "github.com/prebid/prebid-server/errortypes" @@ -1275,7 +1275,7 @@ func buildTestEndpoint(test testCase, cfg *config.Configuration) (httprouter.Han planBuilder = hooks.EmptyPlanBuilder{} } - var endpointBuilder func(uuidutil.UUIDGenerator, exchange.Exchange, openrtb_ext.BidderParamValidator, stored_requests.Fetcher, stored_requests.AccountFetcher, *config.Configuration, metrics.MetricsEngine, analytics.PBSAnalyticsModule, map[string]string, []byte, map[string]openrtb_ext.BidderName, stored_requests.Fetcher, hooks.ExecutionPlanBuilder, *exchange.TmaxAdjustmentsPreprocessed) (httprouter.Handle, error) + var endpointBuilder func(uuidutil.UUIDGenerator, exchange.Exchange, openrtb_ext.BidderParamValidator, stored_requests.Fetcher, stored_requests.AccountFetcher, *config.Configuration, metrics.MetricsEngine, analytics.Runner, map[string]string, []byte, map[string]openrtb_ext.BidderName, stored_requests.Fetcher, hooks.ExecutionPlanBuilder, *exchange.TmaxAdjustmentsPreprocessed) (httprouter.Handle, error) switch test.endpointType { case AMP_ENDPOINT: @@ -1292,7 +1292,7 @@ func buildTestEndpoint(test testCase, cfg *config.Configuration) (httprouter.Han accountFetcher, cfg, met, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), disabledBidders, []byte(test.Config.AliasJSON), bidderMap, diff --git a/endpoints/openrtb2/video_auction.go b/endpoints/openrtb2/video_auction.go index 7b2a7a5295a..fc6d2a91a62 100644 --- a/endpoints/openrtb2/video_auction.go +++ b/endpoints/openrtb2/video_auction.go @@ -52,7 +52,7 @@ func NewVideoEndpoint( accounts stored_requests.AccountFetcher, cfg *config.Configuration, met metrics.MetricsEngine, - pbsAnalytics analytics.PBSAnalyticsModule, + analyticsRunner analytics.Runner, disabledBidders map[string]string, defReqJSON []byte, bidderMap map[string]openrtb_ext.BidderName, @@ -82,7 +82,7 @@ func NewVideoEndpoint( accounts, cfg, met, - pbsAnalytics, + analyticsRunner, disabledBidders, defRequest, defReqJSON, @@ -149,6 +149,8 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re } debugLog.DebugEnabledOrOverridden = debugLog.Enabled || debugLog.DebugOverride + activityControl := privacy.ActivityControl{} + defer func() { if len(debugLog.CacheKey) > 0 && vo.VideoResponse == nil { err := debugLog.PutDebugLogError(deps.cache, deps.cfg.CacheURL.ExpectedTimeMillis, vo.Errors) @@ -158,7 +160,7 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re } deps.metricsEngine.RecordRequest(labels) deps.metricsEngine.RecordRequestTime(labels, time.Since(start)) - deps.analytics.LogVideoObject(&vo) + deps.analytics.LogVideoObject(&vo, activityControl) }() w.Header().Set("X-Prebid", version.BuildXPrebidHeader(version.Ver)) @@ -303,7 +305,7 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re return } - activityControl := privacy.NewActivityControl(&account.Privacy) + activityControl = privacy.NewActivityControl(&account.Privacy) secGPC := r.Header.Get("Sec-GPC") auctionRequest := &exchange.AuctionRequest{ diff --git a/endpoints/openrtb2/video_auction_test.go b/endpoints/openrtb2/video_auction_test.go index f3135ff48db..181a68929ed 100644 --- a/endpoints/openrtb2/video_auction_test.go +++ b/endpoints/openrtb2/video_auction_test.go @@ -12,7 +12,7 @@ import ( "testing" "github.com/prebid/prebid-server/analytics" - analyticsConf "github.com/prebid/prebid-server/analytics/config" + analyticsBuild "github.com/prebid/prebid-server/analytics/build" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/exchange" @@ -21,6 +21,7 @@ import ( metricsConfig "github.com/prebid/prebid-server/metrics/config" "github.com/prebid/prebid-server/openrtb_ext" "github.com/prebid/prebid-server/prebid_cache_client" + "github.com/prebid/prebid-server/privacy" "github.com/prebid/prebid-server/stored_requests/backends/empty_fetcher" "github.com/prebid/prebid-server/util/ptrutil" @@ -1235,11 +1236,11 @@ type mockAnalyticsModule struct { videoObjects []*analytics.VideoObject } -func (m *mockAnalyticsModule) LogAuctionObject(ao *analytics.AuctionObject) { +func (m *mockAnalyticsModule) LogAuctionObject(ao *analytics.AuctionObject, _ privacy.ActivityControl) { m.auctionObjects = append(m.auctionObjects, ao) } -func (m *mockAnalyticsModule) LogVideoObject(vo *analytics.VideoObject) { +func (m *mockAnalyticsModule) LogVideoObject(vo *analytics.VideoObject, _ privacy.ActivityControl) { m.videoObjects = append(m.videoObjects, vo) } @@ -1247,9 +1248,10 @@ func (m *mockAnalyticsModule) LogCookieSyncObject(cso *analytics.CookieSyncObjec func (m *mockAnalyticsModule) LogSetUIDObject(so *analytics.SetUIDObject) {} -func (m *mockAnalyticsModule) LogAmpObject(ao *analytics.AmpObject) {} +func (m *mockAnalyticsModule) LogAmpObject(ao *analytics.AmpObject, _ privacy.ActivityControl) {} -func (m *mockAnalyticsModule) LogNotificationEventObject(ne *analytics.NotificationEvent) {} +func (m *mockAnalyticsModule) LogNotificationEventObject(ne *analytics.NotificationEvent, _ privacy.ActivityControl) { +} func mockDeps(t *testing.T, ex *mockExchangeVideo) *endpointDeps { return &endpointDeps{ @@ -1261,7 +1263,7 @@ func mockDeps(t *testing.T, ex *mockExchangeVideo) *endpointDeps { &mockAccountFetcher{data: mockVideoAccountData}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -1285,7 +1287,7 @@ func mockDepsAppendBidderNames(t *testing.T, ex *mockExchangeAppendBidderNames) empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, @@ -1311,7 +1313,7 @@ func mockDepsNoBids(t *testing.T, ex *mockExchangeVideoNoBids) *endpointDeps { empty_fetcher.EmptyFetcher{}, &config.Configuration{MaxRequestSize: maxSize}, &metricsConfig.NilMetricsEngine{}, - analyticsConf.NewPBSAnalytics(&config.Analytics{}), + analyticsBuild.New(&config.Analytics{}), map[string]string{}, false, []byte{}, diff --git a/endpoints/setuid.go b/endpoints/setuid.go index 520a133b51e..1bf3b575273 100644 --- a/endpoints/setuid.go +++ b/endpoints/setuid.go @@ -36,7 +36,7 @@ const ( const uidCookieName = "uids" -func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]usersync.Syncer, gdprPermsBuilder gdpr.PermissionsBuilder, tcf2CfgBuilder gdpr.TCF2ConfigBuilder, pbsanalytics analytics.PBSAnalyticsModule, accountsFetcher stored_requests.AccountFetcher, metricsEngine metrics.MetricsEngine) httprouter.Handle { +func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]usersync.Syncer, gdprPermsBuilder gdpr.PermissionsBuilder, tcf2CfgBuilder gdpr.TCF2ConfigBuilder, analyticsRunner analytics.Runner, accountsFetcher stored_requests.AccountFetcher, metricsEngine metrics.MetricsEngine) httprouter.Handle { encoder := usersync.Base64Encoder{} decoder := usersync.Base64Decoder{} @@ -46,7 +46,7 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use Errors: make([]error, 0), } - defer pbsanalytics.LogSetUIDObject(&so) + defer analyticsRunner.LogSetUIDObject(&so) cookie := usersync.ReadCookie(r, decoder, &cfg.HostCookie) if !cookie.AllowSyncs() { diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go index 18099193045..3636f7fbbdc 100644 --- a/endpoints/setuid_test.go +++ b/endpoints/setuid_test.go @@ -13,6 +13,7 @@ import ( "time" "github.com/prebid/prebid-server/analytics" + analyticsBuild "github.com/prebid/prebid-server/analytics/build" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/gdpr" @@ -22,7 +23,6 @@ import ( "github.com/prebid/prebid-server/usersync" "github.com/stretchr/testify/assert" - analyticsConf "github.com/prebid/prebid-server/analytics/config" metricsConf "github.com/prebid/prebid-server/metrics/config" ) @@ -328,7 +328,7 @@ func TestSetUIDEndpoint(t *testing.T) { }, } - analytics := analyticsConf.NewPBSAnalytics(&config.Analytics{}) + analytics := analyticsBuild.New(&config.Analytics{}) metrics := &metricsConf.NilMetricsEngine{} for _, test := range testCases { @@ -362,7 +362,7 @@ func TestSetUIDEndpoint(t *testing.T) { func TestSetUIDPriorityEjection(t *testing.T) { decoder := usersync.Base64Decoder{} - analytics := analyticsConf.NewPBSAnalytics(&config.Analytics{}) + analytics := analyticsBuild.New(&config.Analytics{}) syncersByBidder := map[string]string{ "pubmatic": "pubmatic", "syncer1": "syncer1", @@ -1093,7 +1093,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { cfgAccountRequired bool expectedResponseCode int expectedMetrics func(*metrics.MetricsEngineMock) - expectedAnalytics func(*MockAnalytics) + expectedAnalytics func(*MockAnalyticsRunner) }{ { description: "Success - Sync", @@ -1106,7 +1106,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { m.On("RecordSetUid", metrics.SetUidOK).Once() m.On("RecordSyncerSet", "pubmatic", metrics.SyncerSetUidOK).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 200, Bidder: "pubmatic", @@ -1128,7 +1128,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { m.On("RecordSetUid", metrics.SetUidOK).Once() m.On("RecordSyncerSet", "pubmatic", metrics.SyncerSetUidCleared).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 200, Bidder: "pubmatic", @@ -1149,7 +1149,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { expectedMetrics: func(m *metrics.MetricsEngineMock) { m.On("RecordSetUid", metrics.SetUidOptOut).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 401, Bidder: "", @@ -1170,7 +1170,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { expectedMetrics: func(m *metrics.MetricsEngineMock) { m.On("RecordSetUid", metrics.SetUidSyncerUnknown).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 400, Bidder: "", @@ -1191,7 +1191,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { expectedMetrics: func(m *metrics.MetricsEngineMock) { m.On("RecordSetUid", metrics.SetUidBadRequest).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 400, Bidder: "pubmatic", @@ -1212,7 +1212,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { expectedMetrics: func(m *metrics.MetricsEngineMock) { m.On("RecordSetUid", metrics.SetUidBadRequest).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 400, Bidder: "pubmatic", @@ -1233,7 +1233,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { expectedMetrics: func(m *metrics.MetricsEngineMock) { m.On("RecordSetUid", metrics.SetUidGDPRHostCookieBlocked).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 451, Bidder: "pubmatic", @@ -1255,7 +1255,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { expectedMetrics: func(m *metrics.MetricsEngineMock) { m.On("RecordSetUid", metrics.SetUidAccountInvalid).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 400, Bidder: "pubmatic", @@ -1277,7 +1277,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { expectedMetrics: func(m *metrics.MetricsEngineMock) { m.On("RecordSetUid", metrics.SetUidAccountConfigMalformed).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 400, Bidder: "pubmatic", @@ -1299,7 +1299,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { expectedMetrics: func(m *metrics.MetricsEngineMock) { m.On("RecordSetUid", metrics.SetUidBadRequest).Once() }, - expectedAnalytics: func(a *MockAnalytics) { + expectedAnalytics: func(a *MockAnalyticsRunner) { expected := analytics.SetUIDObject{ Status: 400, Bidder: "pubmatic", @@ -1313,7 +1313,7 @@ func TestSetUIDEndpointMetrics(t *testing.T) { } for _, test := range testCases { - analyticsEngine := &MockAnalytics{} + analyticsEngine := &MockAnalyticsRunner{} test.expectedAnalytics(analyticsEngine) metricsEngine := &metrics.MetricsEngineMock{} @@ -1337,7 +1337,7 @@ func TestOptedOut(t *testing.T) { cookie.SetOptOut(true) addCookie(request, cookie) syncersBidderNameToKey := map[string]string{"pubmatic": "pubmatic"} - analytics := analyticsConf.NewPBSAnalytics(&config.Analytics{}) + analytics := analyticsBuild.New(&config.Analytics{}) metrics := &metricsConf.NilMetricsEngine{} response := doRequest(request, analytics, metrics, syncersBidderNameToKey, true, false, false, false, 0, nil) @@ -1525,7 +1525,7 @@ func makeRequest(uri string, existingSyncs map[string]string) *http.Request { return request } -func doRequest(req *http.Request, analytics analytics.PBSAnalyticsModule, metrics metrics.MetricsEngine, syncersBidderNameToKey map[string]string, gdprAllowsHostCookies, gdprReturnsError, gdprReturnsMalformedError, cfgAccountRequired bool, maxCookieSize int, priorityGroups [][]string) *httptest.ResponseRecorder { +func doRequest(req *http.Request, analytics analytics.Runner, metrics metrics.MetricsEngine, syncersBidderNameToKey map[string]string, gdprAllowsHostCookies, gdprReturnsError, gdprReturnsMalformedError, cfgAccountRequired bool, maxCookieSize int, priorityGroups [][]string) *httptest.ResponseRecorder { cfg := config.Configuration{ AccountRequired: cfgAccountRequired, AccountDefaults: config.Account{}, diff --git a/router/router.go b/router/router.go index f2b1f7e7447..29bd8382e78 100644 --- a/router/router.go +++ b/router/router.go @@ -10,7 +10,7 @@ import ( "strings" "time" - analyticsConf "github.com/prebid/prebid-server/analytics/config" + analyticsBuild "github.com/prebid/prebid-server/analytics/build" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/currency" "github.com/prebid/prebid-server/endpoints" @@ -191,7 +191,7 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R // todo(zachbadgett): better shutdown r.Shutdown = shutdown - pbsAnalytics := analyticsConf.NewPBSAnalytics(&cfg.Analytics) + analyticsRunner := analyticsBuild.New(&cfg.Analytics) paramsValidator, err := openrtb_ext.NewBidderParamsValidator(schemaDirectory) if err != nil { @@ -228,17 +228,17 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R macroReplacer := macros.NewStringIndexBasedReplacer() theExchange := exchange.NewExchange(adapters, cacheClient, cfg, syncersByBidder, r.MetricsEngine, cfg.BidderInfos, gdprPermsBuilder, rateConvertor, categoriesFetcher, adsCertSigner, macroReplacer) var uuidGenerator uuidutil.UUIDRandomGenerator - openrtbEndpoint, err := openrtb2.NewEndpoint(uuidGenerator, theExchange, paramsValidator, fetcher, accounts, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBidders, storedRespFetcher, planBuilder, tmaxAdjustments) + openrtbEndpoint, err := openrtb2.NewEndpoint(uuidGenerator, theExchange, paramsValidator, fetcher, accounts, cfg, r.MetricsEngine, analyticsRunner, disabledBidders, defReqJSON, activeBidders, storedRespFetcher, planBuilder, tmaxAdjustments) if err != nil { glog.Fatalf("Failed to create the openrtb2 endpoint handler. %v", err) } - ampEndpoint, err := openrtb2.NewAmpEndpoint(uuidGenerator, theExchange, paramsValidator, ampFetcher, accounts, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBidders, storedRespFetcher, planBuilder, tmaxAdjustments) + ampEndpoint, err := openrtb2.NewAmpEndpoint(uuidGenerator, theExchange, paramsValidator, ampFetcher, accounts, cfg, r.MetricsEngine, analyticsRunner, disabledBidders, defReqJSON, activeBidders, storedRespFetcher, planBuilder, tmaxAdjustments) if err != nil { glog.Fatalf("Failed to create the amp endpoint handler. %v", err) } - videoEndpoint, err := openrtb2.NewVideoEndpoint(uuidGenerator, theExchange, paramsValidator, fetcher, videoFetcher, accounts, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBidders, cacheClient, tmaxAdjustments) + videoEndpoint, err := openrtb2.NewVideoEndpoint(uuidGenerator, theExchange, paramsValidator, fetcher, videoFetcher, accounts, cfg, r.MetricsEngine, analyticsRunner, disabledBidders, defReqJSON, activeBidders, cacheClient, tmaxAdjustments) if err != nil { glog.Fatalf("Failed to create the video endpoint handler. %v", err) } @@ -254,7 +254,7 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R 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.POST("/cookie_sync", endpoints.NewCookieSyncEndpoint(syncersByBidder, cfg, gdprPermsBuilder, tcf2CfgBuilder, r.MetricsEngine, analyticsRunner, accounts, activeBidders).Handle) r.GET("/status", endpoints.NewStatusEndpoint(cfg.StatusResponse)) r.GET("/", serveIndex) r.Handler("GET", "/version", endpoints.NewVersionEndpoint(version.Ver, version.Rev)) @@ -267,7 +267,7 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R } // event endpoint - eventEndpoint := events.NewEventEndpoint(cfg, accounts, pbsAnalytics, r.MetricsEngine) + eventEndpoint := events.NewEventEndpoint(cfg, accounts, analyticsRunner, r.MetricsEngine) r.GET("/event", eventEndpoint) userSyncDeps := &pbs.UserSyncDeps{ @@ -277,7 +277,7 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R PriorityGroups: cfg.UserSync.PriorityGroups, } - r.GET("/setuid", endpoints.NewSetUIDEndpoint(cfg, syncersByBidder, gdprPermsBuilder, tcf2CfgBuilder, pbsAnalytics, accounts, r.MetricsEngine)) + r.GET("/setuid", endpoints.NewSetUIDEndpoint(cfg, syncersByBidder, gdprPermsBuilder, tcf2CfgBuilder, analyticsRunner, accounts, r.MetricsEngine)) r.GET("/getuids", endpoints.NewGetUIDsEndpoint(cfg.HostCookie)) r.POST("/optout", userSyncDeps.OptOut) r.GET("/optout", userSyncDeps.OptOut) From 324a9735e5e32210d2f1650321540e7544c4e777 Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 5 Oct 2023 02:01:14 -0400 Subject: [PATCH 3/4] update lunamedia contact info (#3137) --- static/bidder-info/lunamedia.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/bidder-info/lunamedia.yaml b/static/bidder-info/lunamedia.yaml index ef34143eb40..4064a566040 100644 --- a/static/bidder-info/lunamedia.yaml +++ b/static/bidder-info/lunamedia.yaml @@ -1,6 +1,6 @@ endpoint: "http://rtb.lunamedia.live/?pid={{.PublisherID}}" maintainer: - email: "josh@lunamedia.io" + email: "cs@lunamedia.io" capabilities: site: mediaTypes: From 8cdfe486d33a3cd33ad5ae544ebd706e64806b5b Mon Sep 17 00:00:00 2001 From: Ashish Garg Date: Thu, 5 Oct 2023 16:58:10 +0530 Subject: [PATCH 4/4] enable adapter alias feature (#3179) --- exchange/adapter_util.go | 4 ---- exchange/adapter_util_test.go | 7 ------- 2 files changed, 11 deletions(-) diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index 2337f7f6bbb..1890635cb3d 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -33,10 +33,6 @@ func buildBidders(infos config.BidderInfos, builders map[openrtb_ext.BidderName] var errs []error for bidder, info := range infos { - if len(info.AliasOf) > 0 { - errs = append(errs, fmt.Errorf("This feature is currently under development")) - continue - } bidderName, bidderNameFound := openrtb_ext.NormalizeBidderName(bidder) if !bidderNameFound { errs = append(errs, fmt.Errorf("%v: unknown bidder", bidder)) diff --git a/exchange/adapter_util_test.go b/exchange/adapter_util_test.go index 611498fea0c..08d751cdadf 100644 --- a/exchange/adapter_util_test.go +++ b/exchange/adapter_util_test.go @@ -68,13 +68,6 @@ func TestBuildAdapters(t *testing.T) { errors.New("unknown: unknown bidder"), }, }, - { - description: "Alias feature disabled", - bidderInfos: map[string]config.BidderInfo{"appNexus": {AliasOf: "rubicon"}}, - expectedErrors: []error{ - errors.New("This feature is currently under development"), - }, - }, } cfg := &config.Configuration{}