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 2 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
11 changes: 7 additions & 4 deletions src/main/java/org/prebid/server/auction/BidderAliases.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,14 @@ public static BidderAliases of(Map<String, String> aliasToBidder,
}

public boolean isAliasDefined(String alias) {
return aliasToBidder.containsKey(alias);
return bidderCatalog.isValidName(alias) || aliasToBidder.containsKey(alias);
AntoxaAntoxic marked this conversation as resolved.
Show resolved Hide resolved
}

public String resolveBidder(String aliasOrBidder) {
if (bidderCatalog.isValidName(aliasOrBidder)) {
return aliasOrBidder;
}
AntoxaAntoxic marked this conversation as resolved.
Show resolved Hide resolved

return aliasToBidder.getOrDefault(aliasOrBidder, aliasOrBidder);
}

Expand All @@ -47,9 +51,8 @@ public boolean isSame(String bidder1, String 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
6 changes: 1 addition & 5 deletions src/main/java/org/prebid/server/auction/ExchangeService.java
AntoxaAntoxic marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -455,18 +455,14 @@ private Future<List<AuctionParticipation>> extractAuctionParticipations(
private Set<String> bidderNamesFromImpExt(Imp imp, BidderAliases aliases) {
return Optional.ofNullable(bidderParamsFromImpExt(imp.getExt())).stream()
.flatMap(paramsNode -> StreamUtil.asStream(paramsNode.fieldNames()))
.filter(bidder -> isValidBidder(bidder, aliases))
.filter(aliases::isAliasDefined)
.collect(Collectors.toSet());
}

private static JsonNode bidderParamsFromImpExt(ObjectNode ext) {
return ext.get(PREBID_EXT).get(BIDDER_EXT);
}

private boolean isValidBidder(String bidder, BidderAliases aliases) {
return bidderCatalog.isValidName(bidder) || aliases.isAliasDefined(bidder);
}

private static boolean isBidderCallActivityAllowed(String bidder, AuctionContext auctionContext) {
final ActivityInfrastructure activityInfrastructure = auctionContext.getActivityInfrastructure();
final ActivityInvocationPayload activityInvocationPayload = BidRequestActivityInvocationPayload.of(
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;
}
}
90 changes: 87 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 All @@ -26,6 +36,16 @@ public void isAliasDefinedShouldReturnFalseWhenNoAliasesInRequest() {
assertThat(aliases.isAliasDefined("alias")).isFalse();
}

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

// when and then
assertThat(aliases.isAliasDefined("alias")).isTrue();
}

@Test
public void isAliasDefinedShouldReturnFalseWhenAliasIsNotDefinedInRequest() {
// given
Expand All @@ -35,6 +55,16 @@ public void isAliasDefinedShouldReturnFalseWhenAliasIsNotDefinedInRequest() {
assertThat(aliases.isAliasDefined("alias")).isFalse();
}

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

// when and then
assertThat(aliases.isAliasDefined("alias")).isTrue();
}

@Test
public void isAliasDefinedShouldDetectAliasInRequest() {
// given
Expand All @@ -53,6 +83,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 +102,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 +121,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 +170,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 +191,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);
}
}
64 changes: 64 additions & 0 deletions src/test/java/org/prebid/server/auction/ExchangeServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1086,6 +1086,8 @@ public void shouldReturnProperStoredResponseIfAvailableOnlySingleImpRequests() {
@Test
public void shouldExtractRequestByAliasForCorrectBidder() {
// given
given(bidderCatalog.isValidName("bidderAlias")).willReturn(false);

final Bidder<?> bidder = mock(Bidder.class);
givenBidder("bidder", bidder, givenEmptySeatBid());

Expand All @@ -1108,9 +1110,36 @@ public void shouldExtractRequestByAliasForCorrectBidder() {
.contains(1);
}

@Test
public void shouldExtractRequestByAliasForHardcodedBidderAlias() {
// given
final Bidder<?> bidder = mock(Bidder.class);
givenBidder("bidderAlias", bidder, givenEmptySeatBid());

final BidRequest bidRequest = givenBidRequest(singletonList(
givenImp(singletonMap("bidderAlias", 1), identity())),
builder -> builder.ext(ExtRequest.of(ExtRequestPrebid.builder()
.aliases(singletonMap("bidderAlias", "bidder"))
.auctiontimestamp(1000L)
.build())));

// when
target.holdAuction(givenRequestContext(bidRequest));

// then
final ArgumentCaptor<BidderRequest> bidRequestCaptor = ArgumentCaptor.forClass(BidderRequest.class);
verify(httpBidderRequester)
.requestBids(same(bidder), bidRequestCaptor.capture(), any(), any(), any(), any(), anyBoolean());
assertThat(bidRequestCaptor.getValue().getBidRequest().getImp()).hasSize(1)
.extracting(imp -> imp.getExt().get("bidder").asInt())
.contains(1);
}

@Test
public void shouldExtractMultipleRequestsForTheSameBidderIfAliasesWereUsed() {
// given
given(bidderCatalog.isValidName("bidderAlias")).willReturn(false);

final Bidder<?> bidder = mock(Bidder.class);
givenBidder("bidder", bidder, givenEmptySeatBid());

Expand All @@ -1136,6 +1165,39 @@ public void shouldExtractMultipleRequestsForTheSameBidderIfAliasesWereUsed() {
.containsOnly(2, 1);
}

@Test
public void shouldExtractMultipleRequestsForBidderAndItsHardcodedAlias() {
// given
final Bidder<?> bidder = mock(Bidder.class);
final Bidder<?> bidderAlias = mock(Bidder.class);
givenBidder("bidder", bidder, givenEmptySeatBid());
givenBidder("bidderAlias", bidderAlias, givenEmptySeatBid());

final BidRequest bidRequest = givenBidRequest(singletonList(
givenImp(doubleMap("bidder", 1, "bidderAlias", 2), identity())),
builder -> builder.ext(ExtRequest.of(ExtRequestPrebid.builder()
.aliases(singletonMap("bidderAlias", "bidder"))
.auctiontimestamp(1000L)
.build())));

// when
target.holdAuction(givenRequestContext(bidRequest));

// then
final ArgumentCaptor<BidderRequest> bidRequestCaptor = ArgumentCaptor.forClass(BidderRequest.class);
verify(httpBidderRequester)
.requestBids(same(bidder), bidRequestCaptor.capture(), any(), any(), any(), any(), anyBoolean());
verify(httpBidderRequester)
.requestBids(same(bidderAlias), bidRequestCaptor.capture(), any(), any(), any(), any(), anyBoolean());

final List<BidderRequest> capturedBidderRequests = bidRequestCaptor.getAllValues();

assertThat(capturedBidderRequests).hasSize(2)
.extracting(BidderRequest::getBidRequest)
.extracting(capturedBidRequest -> capturedBidRequest.getImp().getFirst().getExt().get("bidder").asInt())
.containsOnly(2, 1);
}

@Test
public void shouldTolerateBidderResultWithoutBids() {
// given
Expand Down Expand Up @@ -2962,6 +3024,8 @@ public void shouldNotAddExtPrebidEventsWhenEventsServiceReturnsEmptyEventsServic
@Test
public void shouldIncrementCommonMetrics() {
// given
given(bidderCatalog.isValidName("someAlias")).willReturn(false);

given(httpBidderRequester.requestBids(any(), any(), any(), any(), any(), any(), anyBoolean()))
.willReturn(Future.succeededFuture(givenSeatBid(singletonList(
givenBidderBid(Bid.builder().impid("impId").price(TEN).build())))));
Expand Down
Loading