Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapter alias - syncer changes #3082

Merged
merged 19 commits into from
Sep 29, 2023
Merged

Conversation

onkarvhanumante
Copy link
Contributor

@onkarvhanumante onkarvhanumante commented Sep 7, 2023

As of now on server startup, if an alias has not defined syncer cfg then PBS was inheriting entire syncer cfg of parent.

Now, if a parent has syncer cfg with key, endpoints etc then alias was inheriting syncer entire parent cfg including key. This is incorrect because as per syncer rule, bidders can have same key but only one of them should define endpoints.

Therefore inheriting entire syncer cfg of parent resulted in validation error on PBS server startup. To fix this, PR implements fix to only inherit parent key in alias syncer cfg.

Added log lines to print syncers build on PBS server start up.

	+++ b/router/router.go
	@@ -170,6 +170,9 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R
	                return nil, errortypes.NewAggregateError("user sync", errs)
	        }

	+       fmt.Printf("\ntest: %+v\n", syncersByBidder["test"])
	+       fmt.Printf("\nappnexus: %+v\n", syncersByBidder["appnexus"])
	+
	        syncerKeys := make([]string, 0, len(syncersByBidder))
	        syncerKeysHashSet := map[string]struct{}{}
  • Case1: Parent has defined syncer key.
    Expected: Alias should inherit entire Parent syncer cfg with parent syncer key as syncer key for alias

    appnexus.yml:

     	...
     	userSync:
     	  key: "adnxs"
     	  redirect:
     	    url: "https://ib.adnxs.com/getuid?{{.RedirectURL}}"
     	    userMacro: "$UID"
    

    test.yml (alias):

     	aliasOf: appnexus
    

    Based on following logs, test bidder (alias) has inherited config of alias

     prebid-server % go build . && ./prebid-server
    
     test: {key:adnxs defaultSyncType:redirect iframe:<nil> redirect:0x14000425f40 supportCORS:false}
    
     appnexus: {key:adnxs defaultSyncType:redirect iframe:<nil> redirect:0x1400012e000 supportCORS:false}
    
  • Case 2: parent has not defined syncer key
    Expected: Alias should inherit entire Parent syncer cfg with parent name as syncer key for alias.

    appnexus.yml:

     	...
     	userSync:
     	  redirect:
     	    url: "https://ib.adnxs.com/getuid?{{.RedirectURL}}"
     	    userMacro: "$UID"
    

    test.yml (alias):

     	aliasOf: appnexus
    

    Based on following logs, test bidder (alias) has inherited config of alias

     	prebid-server % go build . && ./prebid-server
    
     	test: {key:appnexus defaultSyncType:redirect iframe:<nil> redirect:0x140005c5ac0 supportCORS:false}
    
     	appnexus: {key:appnexus defaultSyncType:redirect iframe:<nil> redirect:0x140005c5a00 supportCORS:false}
    

Refactor BuildSyncers to use map[string]config.BidderInfo instead of map[string]config.Syncer. This is done because config.BidderInfo is needed to determine if bidder is an alias or non-alias bidder.
getSyncerKey will help to decide syncer key for an alias or non-alias bidder
Update chooseSyncerConfig to implement following adapter alias rules:
- alias and parent bidder can use same syncer key
- non-alias bidder cannot have same syncer key
- aliases of different parents cannot have same syncer key
- aliases of same parent and non-alias bidder have same syncer key
@onkarvhanumante onkarvhanumante changed the title Adapter alias/syncer changes Adapter alias - syncer changes Sep 7, 2023
@gargcreation1992 gargcreation1992 self-assigned this Sep 7, 2023
usersync/syncersbuilder.go Outdated Show resolved Hide resolved
usersync/syncersbuilder.go Outdated Show resolved Hide resolved
usersync/syncersbuilder.go Outdated Show resolved Hide resolved
Copy link
Contributor

@gargcreation1992 gargcreation1992 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!
Requesting @SyntaxNode to please take a look as well.

Copy link
Contributor

@AlexBVolcy AlexBVolcy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking good, i just left one comment regarding the nested if statements

usersync/syncersbuilder.go Outdated Show resolved Hide resolved
if _, ok := parentBidderNameMap[nonAliasBidderNames[0]]; !ok {
sort.Strings(aliasBidderNames)
return namedSyncerConfig{}, fmt.Errorf("either alias bidders %s defines endpoints (iframe and/or redirect) for the same syncer key used by other bidder, but only one bidder is permitted to define endpoints", strings.Join(aliasBidderNames, ", "))
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is getting a bit confusing to follow. This logic could be left alone if you resolve the alias user sync keys up front:

  • If the alias defines it's own syncer or syncer key, do nothing. The validation in this function will ensure the syncer rules are adhered.
  • if the alias does not define it's own syncer or syncer key but it's parent does, set the syncer key to match the parent. This is either the parent's syncer key or the parent's bidder name (the default implicit syncer key) - which you already have coded.

This may simplify the validation logic.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@onkarvhanumante was this comment addressed by you? Were you able to see if this validation logic can be simplified?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@onkarvhanumante was this comment addressed by you? Were you able to see if this validation logic can be simplified?

@AlexBVolcy, had some discussion with @SyntaxNode and have evaluated few cases to understand what syncer key should be assigned to alias and parent bidder. Will push updated changes and inform here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AlexBVolcy @gargcreation1992 PR is updated with latest commits. All previous commits are reverted and dd12c58 is the one to review.

Refer #3082 (comment) for testing details

usersync/syncersbuilder.go Outdated Show resolved Hide resolved
usersync/syncersbuilder.go Outdated Show resolved Hide resolved
if _, ok := parentBidderNameMap[nonAliasBidderNames[0]]; !ok {
sort.Strings(aliasBidderNames)
return namedSyncerConfig{}, fmt.Errorf("either alias bidders %s defines endpoints (iframe and/or redirect) for the same syncer key used by other bidder, but only one bidder is permitted to define endpoints", strings.Join(aliasBidderNames, ", "))
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@onkarvhanumante was this comment addressed by you? Were you able to see if this validation logic can be simplified?

As of now, in processBidderAliases if an alias has not defined syncer cfg then PBS was inheriting entire syncer cfg of parent.

Now, if a parent has syncer cfg with key, endpoints etc then alias was inheriting syncer entire parent cfg including key. This is incorrect because as per syncer rule, bidders can have same key but only one of them should define endpoints.

Therefore inheriting entire syncer cfg of parent resulted in validation error on PBS server startup. To fix this, commit updates processBidderAliases to only inherit parent key in alias syncer cfg.
Password: "pwd",
Tracker: "tracker",
},
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is correct. Suggestion - might wanna check if you could reduce BidderInfo struct fields to only include syncer since other fields seems un-important for this test case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah you can remove the other fields, just tested it myself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8b64cd6 makes suggested changes

Copy link
Contributor

@AlexBVolcy AlexBVolcy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good, left one minor comment

Password: "pwd",
Tracker: "tracker",
},
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah you can remove the other fields, just tested it myself.

@onkarvhanumante onkarvhanumante merged commit 061aa84 into master Sep 29, 2023
3 checks passed
@onkarvhanumante onkarvhanumante deleted the adapter-alias/syncer-changes branch September 29, 2023 11:21
Copy link
Contributor

@AlexBVolcy AlexBVolcy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this PR was merged before receiving two approvals, but I left a question regarding one of the cases this PR is addressing.

@@ -320,8 +320,13 @@ func processBidderAliases(aliasNillableFieldsByBidder map[string]aliasNillableFi
if aliasBidderInfo.PlatformID == "" {
aliasBidderInfo.PlatformID = parentBidderInfo.PlatformID
}
if aliasBidderInfo.Syncer == nil {
aliasBidderInfo.Syncer = parentBidderInfo.Syncer
if aliasBidderInfo.Syncer == nil && parentBidderInfo.Syncer != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a question regarding a case you laid out in your PR description:

Case 2: parent has not defined syncer key
Expected: Alias should inherit entire Parent syncer cfg with parent name as syncer key for alias.

Would this be referring to scenario where parentBidderInfo.Syncer == nil? And if so, where in this PR is the code that allows the alias to inherit the entire parent syncer cfg?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AlexBVolcy, we leverage on existing BuildSyncer() function to inherit parent cfg for alias.

As per adapter aliases feature, bidders (parent. + aliases ) can share user sync cfg as follow:

  • parent should define user sync config
  • alias should define parent name or parent syncer key in syncer cfg

We have BuildSyncer() function that,

  1. validates above adapter aliases rule
  2. groups all bidders with same key together (parent and aliases are grouped together)
  3. assigns parent syncer config to all bidders grouped on step 2

func BuildSyncers(hostConfig *config.Configuration, bidderInfos config.BidderInfos) (map[string]Syncer, []error) {

In this way, alias inherit the entire parent syncer cfg. Case where parentBidderInfo.Syncer == nil is already handled by BuildSyncer(). So changes were needed as part of this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants