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

Update Alias Behavior #3639

Merged
merged 4 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/main/java/org/prebid/server/auction/BidderAliases.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,18 @@ public boolean isAliasDefined(String alias) {
}

public String resolveBidder(String aliasOrBidder) {
return aliasToBidder.getOrDefault(aliasOrBidder, aliasOrBidder);
return bidderCatalog.isValidName(aliasOrBidder)
? aliasOrBidder
: aliasToBidder.getOrDefault(aliasOrBidder, aliasOrBidder);
}

public boolean isSame(String bidder1, String bidder2) {
return StringUtils.equalsIgnoreCase(resolveBidder(bidder1), resolveBidder(bidder2));
}

public Integer resolveAliasVendorId(String alias) {
return aliasToVendorId.containsKey(alias)
? aliasToVendorId.get(alias)
: resolveAliasVendorIdViaCatalog(alias);
final Integer vendorId = resolveAliasVendorIdViaCatalog(alias);
return vendorId == null ? aliasToVendorId.get(alias) : vendorId;
}

private Integer resolveAliasVendorIdViaCatalog(String alias) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public Future<List<BidderPrivacyResult>> enforce(AuctionContext auctionContext,

return tcfDefinerService.resultForBidderNames(
bidders,
VendorIdResolver.of(aliases, bidderCatalog),
VendorIdResolver.of(aliases),
auctionContext.getPrivacyContext().getTcfContext(),
accountGdprConfig(auctionContext.getAccount()))
.map(TcfResponse::getActions)
Expand Down
20 changes: 5 additions & 15 deletions src/main/java/org/prebid/server/privacy/gdpr/VendorIdResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,20 @@
public class VendorIdResolver {

private final BidderAliases aliases;
private final BidderCatalog bidderCatalog;

private VendorIdResolver(BidderAliases aliases, BidderCatalog bidderCatalog) {
private VendorIdResolver(BidderAliases aliases) {
this.aliases = aliases;
this.bidderCatalog = bidderCatalog;
}

public static VendorIdResolver of(BidderAliases aliases, BidderCatalog bidderCatalog) {
return new VendorIdResolver(aliases, bidderCatalog);
public static VendorIdResolver of(BidderAliases aliases) {
return new VendorIdResolver(aliases);
}

public static VendorIdResolver of(BidderCatalog bidderCatalog) {
return of(null, bidderCatalog);
return of(BidderAliases.of(null, null, bidderCatalog));
}

public Integer resolve(String aliasOrBidder) {
final Integer requestAliasVendorId = aliases != null ? aliases.resolveAliasVendorId(aliasOrBidder) : null;

return requestAliasVendorId != null ? requestAliasVendorId : resolveViaCatalog(aliasOrBidder);
}

private Integer resolveViaCatalog(String aliasOrBidder) {
final String bidderName = aliases != null ? aliases.resolveBidder(aliasOrBidder) : aliasOrBidder;

return bidderCatalog.isActive(bidderName) ? bidderCatalog.vendorIdByName(bidderName) : null;
return aliases != null ? aliases.resolveAliasVendorId(aliasOrBidder) : null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ enum BidderName {
ALIAS_CAMEL_CASE("AlIaS"),
GENERIC_CAMEL_CASE("GeNerIc"),
GENERIC("generic"),
GENER_X("gener_x"),
RUBICON("rubicon"),
APPNEXUS("appnexus"),
RUBICON_ALIAS("rubiconAlias"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class Bidder {

Generic alias
Generic generic
@JsonProperty("gener_x")
Generic generX
@JsonProperty("GeNerIc")
Generic genericCamelCase
Rubicon rubicon
Expand Down
103 changes: 102 additions & 1 deletion src/test/groovy/org/prebid/server/functional/tests/AliasSpec.groovy
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package org.prebid.server.functional.tests

import org.prebid.server.functional.model.bidder.Generic
import org.prebid.server.functional.model.bidder.Openx
import org.prebid.server.functional.model.request.auction.BidRequest
import org.prebid.server.functional.service.PrebidServerException
import org.prebid.server.functional.testcontainers.Dependencies
import org.prebid.server.functional.util.PBSUtils

import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST
import static org.prebid.server.functional.model.bidder.BidderName.ALIAS
import static org.prebid.server.functional.model.bidder.BidderName.BOGUS
import static org.prebid.server.functional.model.bidder.BidderName.GENERIC
import static org.prebid.server.functional.model.bidder.BidderName.GENER_X
import static org.prebid.server.functional.model.bidder.BidderName.OPENX
import static org.prebid.server.functional.model.bidder.CompressionType.GZIP
import static org.prebid.server.functional.testcontainers.Dependencies.getNetworkServiceContainer
import static org.prebid.server.functional.testcontainers.Dependencies.networkServiceContainer
import static org.prebid.server.functional.util.HttpUtil.CONTENT_ENCODING_HEADER

class AliasSpec extends BaseSpec {
Expand Down Expand Up @@ -144,4 +148,101 @@ class AliasSpec extends BaseSpec {
def bidderRequests = bidder.getBidderRequests(bidRequest.id)
assert bidderRequests.size() == 2
}

def "PBS should ignore alias logic when hardcoded alias endpoints are present"() {
given: "PBs server with aliases config"
def pbsConfig = ["adapters.generic.aliases.alias.enabled" : "true",
"adapters.generic.aliases.alias.endpoint": "$networkServiceContainer.rootUri/alias/auction".toString(),
"adapters.openx.enabled" : "true",
"adapters.openx.endpoint" : "$networkServiceContainer.rootUri/openx/auction".toString()]
def pbsService = pbsServiceFactory.getService(pbsConfig)

and: "Default bid request with openx and alias bidder"
def bidRequest = BidRequest.defaultBidRequest.tap {
imp[0].ext.prebid.bidder.alias = new Generic()
imp[0].ext.prebid.bidder.generic = new Generic()
imp[0].ext.prebid.bidder.openx = new Openx()
ext.prebid.aliases = [(ALIAS.value): OPENX]
}

when: "PBS processes auction request"
def bidResponse = pbsService.sendAuctionRequest(bidRequest)

then: "PBS should call only generic bidder"
def responseDebug = bidResponse.ext.debug
assert responseDebug.httpcalls[GENERIC.value]

and: "PBS shouldn't call only opexn,alias bidder"
assert !responseDebug.httpcalls[OPENX.value]
assert !responseDebug.httpcalls[ALIAS.value]

and: "PBS should call only generic bidder"
assert bidder.getBidderRequest(bidRequest.id)

cleanup: "Stop and remove pbs container"
pbsServiceFactory.removeContainer(pbsConfig)
}

def "PBS should ignore aliases for requests with a base adapter"() {
given: "PBs server with aliases config"
def pbsConfig = ["adapters.openx.enabled" : "true",
"adapters.openx.endpoint": "$networkServiceContainer.rootUri/openx/auction".toString()]
def pbsService = pbsServiceFactory.getService(pbsConfig)

and: "Default bid request with openx and alias bidder"
def bidRequest = BidRequest.defaultBidRequest.tap {
imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx
imp[0].ext.prebid.bidder.generic = new Generic()
ext.prebid.aliases = [(OPENX.value): GENERIC]
}

when: "PBS processes auction request"
def bidResponse = pbsService.sendAuctionRequest(bidRequest)

then: "PBS contain two http calls and the different url for both"
def responseDebug = bidResponse.ext.debug
assert responseDebug.httpcalls.size() == 2
assert responseDebug.httpcalls[OPENX.value]*.uri == ["$networkServiceContainer.rootUri/openx/auction"]
assert responseDebug.httpcalls[GENERIC.value]*.uri == ["$networkServiceContainer.rootUri/auction"]

cleanup: "Stop and remove pbs container"
pbsServiceFactory.removeContainer(pbsConfig)
}

def "PBS should invoke as aliases when alias is unknown and core bidder is specified"() {
given: "Default bid request with generic and alias bidder"
def bidRequest = BidRequest.defaultBidRequest.tap {
imp[0].ext.prebid.bidder.generX = new Generic()
ext.prebid.aliases = [(GENER_X.value): GENERIC]
}

when: "PBS processes auction request"
def bidResponse = defaultPbsService.sendAuctionRequest(bidRequest)

then: "PBS contain two http calls and the same url for both"
def responseDebug = bidResponse.ext.debug
assert responseDebug.httpcalls.size() == 2
assert responseDebug.httpcalls[GENER_X.value]*.uri == responseDebug.httpcalls[GENERIC.value]*.uri

and: "Bidder request should contain request per-alies"
def bidderRequests = bidder.getBidderRequests(bidRequest.id)
assert bidderRequests.size() == 2
}

def "PBS should invoke aliases when alias is unknown and no core bidder is specified"() {
given: "Default bid request with generic and alias bidder"
def bidRequest = BidRequest.defaultBidRequest.tap {
imp[0].ext.prebid.bidder.generX = new Generic()
imp[0].ext.prebid.bidder.generic = null
ext.prebid.aliases = [(GENER_X.value): GENERIC]
}

when: "PBS processes auction request"
def bidResponse = defaultPbsService.sendAuctionRequest(bidRequest)

then: "PBS contain two http calls and the same url for both"
def responseDebug = bidResponse.ext.debug
assert responseDebug.httpcalls.size() == 1
assert responseDebug.httpcalls[GENER_X.value]
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.prebid.server.functional.tests

import org.prebid.server.functional.model.bidder.Generic
import org.prebid.server.functional.model.bidder.Openx
import org.prebid.server.functional.model.db.StoredImp
import org.prebid.server.functional.model.request.auction.BidRequest
Expand Down Expand Up @@ -103,8 +104,10 @@ class ImpRequestSpec extends BaseSpec {
imp.first.tap {
pmp = Pmp.defaultPmp
ext.prebid.imp = [(aliasName): new Imp(pmp: extPmp)]
ext.prebid.bidder.generic = null
ext.prebid.bidder.alias = new Generic()
}
ext.prebid.aliases = [(aliasName.value): GENERIC]
ext.prebid.aliases = [(aliasName.value): bidderName]
}

when: "Requesting PBS auction"
Expand Down
70 changes: 67 additions & 3 deletions src/test/java/org/prebid/server/auction/BidderAliasesTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.prebid.server.auction;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
Expand All @@ -10,13 +11,22 @@

import static java.util.Collections.singletonMap;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mock.Strictness.LENIENT;

@ExtendWith(MockitoExtension.class)
public class BidderAliasesTest {

@Mock
@Mock(strictness = LENIENT)
private BidderCatalog bidderCatalog;

@BeforeEach
public void before() {
given(bidderCatalog.isValidName(any())).willReturn(false);
given(bidderCatalog.isActive(any())).willReturn(false);
}

@Test
public void isAliasDefinedShouldReturnFalseWhenNoAliasesInRequest() {
// given
Expand Down Expand Up @@ -53,6 +63,16 @@ public void resolveBidderShouldReturnInputWhenNoAliasesInRequest() {
assertThat(aliases.resolveBidder("alias")).isEqualTo("alias");
}

@Test
public void resolveBidderShouldReturnInputWhenNoAliasesInRequestButAliasIsValidInBidderCatalog() {
// given
given(bidderCatalog.isValidName("alias")).willReturn(true);
final BidderAliases aliases = BidderAliases.of(null, null, bidderCatalog);

// when and then
assertThat(aliases.resolveBidder("alias")).isEqualTo("alias");
}

@Test
public void resolveBidderShouldReturnInputWhenAliasIsNotDefinedInRequest() {
// given
Expand All @@ -62,6 +82,16 @@ public void resolveBidderShouldReturnInputWhenAliasIsNotDefinedInRequest() {
assertThat(aliases.resolveBidder("alias")).isEqualTo("alias");
}

@Test
public void resolveBidderShouldReturnInputWhenAliasIsNotDefinedInRequestButAliasIsValidInBidderCatalog() {
// given
given(bidderCatalog.isValidName("alias")).willReturn(true);
final BidderAliases aliases = BidderAliases.of(singletonMap("anotherAlias", "bidder"), null, bidderCatalog);

// when and then
assertThat(aliases.resolveBidder("alias")).isEqualTo("alias");
}

@Test
public void resolveBidderShouldDetectAliasInRequest() {
// given
Expand All @@ -71,6 +101,16 @@ public void resolveBidderShouldDetectAliasInRequest() {
assertThat(aliases.resolveBidder("alias")).isEqualTo("bidder");
}

@Test
public void resolveBidderShouldDetectInBidderCatalogWhenItIsValid() {
// given
given(bidderCatalog.isValidName("alias")).willReturn(true);
final BidderAliases aliases = BidderAliases.of(singletonMap("alias", "bidder"), null, bidderCatalog);

// when and then
assertThat(aliases.resolveBidder("alias")).isEqualTo("alias");
}

@Test
public void isSameShouldReturnTrueIfBiddersSameConsideringAliases() {
// given
Expand Down Expand Up @@ -110,6 +150,17 @@ public void resolveAliasVendorIdShouldReturnNullWhenNoVendorIdsInRequest() {
assertThat(aliases.resolveAliasVendorId("alias")).isNull();
}

@Test
public void resolveAliasVendorIdShouldReturnVendorIdFromBidderCatalogWhenNoVendorIdsInRequest() {
// given
given(bidderCatalog.isActive("alias")).willReturn(true);
given(bidderCatalog.vendorIdByName("alias")).willReturn(3);
final BidderAliases aliases = BidderAliases.of(null, null, bidderCatalog);

// when and then
assertThat(aliases.resolveAliasVendorId("alias")).isEqualTo(3);
}

@Test
public void resolveAliasVendorIdShouldReturnNullWhenVendorIdIsNotDefinedInRequest() {
// given
Expand All @@ -120,11 +171,24 @@ public void resolveAliasVendorIdShouldReturnNullWhenVendorIdIsNotDefinedInReques
}

@Test
public void resolveAliasVendorIdShouldDetectVendorIdInRequest() {
public void resolveAliasVendorIdShouldReturnVendorIdFromBidderCatalogWhenVendorIdIsNotDefinedInRequest() {
// given
given(bidderCatalog.isActive("alias")).willReturn(true);
given(bidderCatalog.vendorIdByName("alias")).willReturn(3);
final BidderAliases aliases = BidderAliases.of(null, singletonMap("anotherAlias", 2), bidderCatalog);

// when and then
assertThat(aliases.resolveAliasVendorId("alias")).isEqualTo(3);
}

@Test
public void resolveAliasVendorIdShouldReturnVendorIdFromBidderCatalogWhenVendorIdIsInRequest() {
// given
given(bidderCatalog.isActive("alias")).willReturn(true);
given(bidderCatalog.vendorIdByName("alias")).willReturn(3);
final BidderAliases aliases = BidderAliases.of(null, singletonMap("alias", 2), bidderCatalog);

// when and then
assertThat(aliases.resolveAliasVendorId("alias")).isEqualTo(2);
assertThat(aliases.resolveAliasVendorId("alias")).isEqualTo(3);
}
}
Loading
Loading