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

Pass Through First Party Context Data #1479

Merged
merged 9 commits into from
Sep 10, 2020

Conversation

SyntaxNode
Copy link
Contributor

PBS-Go does not yet support the First Party Data feature (#879), but there is a conflict with how we map bidder data and it's causing issues for some publishers. We'll need to fix this eventually, so why not now?

The First Party Data feature allows for context to be provided on an imp to be shared among all bidders, such as:

{
    imp: [
        ...
        ext: {
            context: {
                data: {
                    // everyone sees this data
                    ADUNIT SPECIFIC CONTEXT DATA
                }
            }
         }
    ]
}

However, PBS-Go expects all fields within the "ext" to either be bidder data or the prebid section, such as:

{
    imp: [
        ...
        ext: {
            appnexus: {
                        placementId: 1
            },
            context: {
                data: {
                    // everyone sees this data
                    ADUNIT SPECIFIC CONTEXT DATA
                }
            }
        }
    ]
}

We attempt to validate that context is a valid bidder and return an error. We already have a special case for the prebid section. This PR also adds a special case for the context section, to pass it down to all bid requests.

requestExt: json.RawMessage(`{"prebid":{"bidder":{"appnexus":{"placement_id":555}}}}`),
expectedExt: `{"prebid":{"bidder":{"appnexus":{"placement_id":555}}}}`,
expectedErrs: []error{},
// request.ext.prebid.bidder.{biddername} is only promoted/copied to request.ext.{biddername} if there is at least one disabled bidder.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We need to talk about this behavior. It makes no sense to me and looks like a bug.

  • I can understand removing a disabled bidder, but that's not happening for imp.ext.bidder definitions.
  • I have no idea why we're copying the bidder up a level here. That hoisting is already performed by the exchange during imp sanitization. Maybe this was added first and never removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought about this more and now consider it a bug. As a follow-up PR, I'd like to make the validate method only actually validate and move the disabled bidder logic to exchange.go, if it's not already there.

"appnexus": {
"placementId": 12883451
},
"context": {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This throws a validation exception currently.

"bidder": {
"placementId": 1
},
"context": {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is considered a bidder today and causes all sorts of panics currently (when the validation now allows it).

// It will not mutate the input imp.
// This function will write the new imps to the output map passed in
func sanitizedImpCopy(imp *openrtb.Imp,
bidderExts map[string]json.RawMessage,
rawPrebidExt json.RawMessage,
firstPartyDataContext json.RawMessage,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, this is hacky. This method is in need of a refactor. I wanted to keep my "new feature' hat on for now and limited the scope of this PR from a full on refactor.

errs = append(errs, err)
// Remove the entire bidder field. We will already have the content we need in bidderExts. We
// don't want to include other demand partners' bidder params in the sanitized imp.
if _, hasBidderField := prebidExt["bidder"]; hasBidderField {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, except for this slight optimization. No need to marshal if there was no bidder section to remove.

// ExtRequestFirstPartyDataContext is a special case for the first party data context section
// and is not considered a bidder.

return bidder != openrtb_ext.PrebidExtKey && bidder != openrtb_ext.ExtRequestFirstPartyDataContext
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should it be RequestFirstPartyDataContextExtKey to match the PrebidExtKey pattern?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll rename it to FirstPartyDataContextExtKey. Push incoming.

hhhjort
hhhjort previously approved these changes Sep 10, 2020
Copy link
Collaborator

@hhhjort hhhjort left a comment

Choose a reason for hiding this comment

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

It is a bit hacky, but doing better does require a major refactor which is better off in its own PR.

hardcodedResponseIPValidator{response: true},

for _, test := range testCases {
deps := &endpointDeps{
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd suggest moving the deps assignment outside the for loop as it is common for all test cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved.

errList = append(errList, errs...)
}
}

return splitImps, nil
}

// sanitizedImpCopy returns a copy of imp with its ext filtered so that only "prebid" and bidder params exist.
// sanitizedImpCopy returns a copy of imp with its ext filtered so that only "prebid", "comtext", and bidder params exist.
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo: "context"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I cna't spell. Fixed.

@@ -61,3 +61,8 @@ func TestBidderListDoesNotDefineGeneral(t *testing.T) {
bidders := BidderList()
assert.NotContains(t, bidders, BidderNameGeneral)
}

func TestBidderListDoesNotDefineContext(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

If the BidderNameContext is only being used in this test, can we just define that as a constant here in this specific test file? The reason being it can be otherwise easily confused with FirstPartyDataContextExtKey which is what we're actually using when looking at the ext to separate it out from the bidders

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I included BidderNameContext alongside the other bidder name definitions to act as documentation of expected cases while also providing a BidderName instance (FirstPartyDataContextExtKey is a string). I used the same pattern for BidderNameGeneral for the same reason.

The variables also refer to slightly different things:
BidderNameContext = A reserved bidder name due to a conflict with another imp.ext use case. Will eventually go away when we move entirely to imp.ext.prebid.bidder.xxx

FirstPartyDataContextExtKey = Name of the first party data context imp.ext field. Likely to be used more in the future when building out the first party data feature.

mansinahar
mansinahar previously approved these changes Sep 10, 2020
@SyntaxNode SyntaxNode merged commit 42e6765 into prebid:master Sep 10, 2020
@SyntaxNode SyntaxNode deleted the fpd_allowcontext branch September 10, 2020 18:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants