diff --git a/src/main/java/org/prebid/server/validation/ImpValidator.java b/src/main/java/org/prebid/server/validation/ImpValidator.java index d5d9ecba2f1..986e63eca68 100644 --- a/src/main/java/org/prebid/server/validation/ImpValidator.java +++ b/src/main/java/org/prebid/server/validation/ImpValidator.java @@ -28,6 +28,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; +import org.prebid.server.auction.BidderAliases; import org.prebid.server.bidder.BidderCatalog; import org.prebid.server.json.JacksonMapper; import org.prebid.server.proto.openrtb.ext.request.ExtImpPrebid; @@ -365,9 +366,10 @@ private void validateImpExt(ObjectNode ext, Map aliases, int imp validateImpExtPrebid(ext != null ? ext.get(PREBID_EXT) : null, aliases, impIndex, warnings); } - private void validateImpExtPrebid(JsonNode extPrebidNode, Map aliases, int impIndex, - List warnings) - throws ValidationException { + private void validateImpExtPrebid(JsonNode extPrebidNode, + Map requestAliases, + int impIndex, + List warnings) throws ValidationException { if (extPrebidNode == null) { throw new ValidationException( @@ -387,15 +389,21 @@ private void validateImpExtPrebid(JsonNode extPrebidNode, Map al } final ExtImpPrebid extPrebid = parseExtImpPrebid((ObjectNode) extPrebidNode, impIndex); - validateImpExtPrebidBidder(extPrebidBidderNode, extPrebid.getStoredAuctionResponse(), - aliases, impIndex, warnings); - validateImpExtPrebidStoredResponses(extPrebid, aliases, impIndex, warnings); + final BidderAliases aliases = BidderAliases.of(requestAliases, null, bidderCatalog); + validateImpExtPrebidBidder( + extPrebidBidderNode, + extPrebid.getStoredAuctionResponse(), + aliases, + impIndex, + warnings); + + validateImpExtPrebidStoredResponses(extPrebid, aliases, impIndex, warnings); validateImpExtPrebidImp(extPrebidNode.get(IMP_EXT), aliases, impIndex, warnings); } private void validateImpExtPrebidImp(JsonNode imp, - Map aliases, + BidderAliases aliases, int impIndex, List warnings) { if (imp == null) { @@ -406,7 +414,7 @@ private void validateImpExtPrebidImp(JsonNode imp, while (bidders.hasNext()) { final Map.Entry bidder = bidders.next(); final String bidderName = bidder.getKey(); - final String resolvedBidderName = aliases.getOrDefault(bidderName, bidderName); + final String resolvedBidderName = aliases.resolveBidder(bidderName); if (!bidderCatalog.isValidName(resolvedBidderName) && !bidderCatalog.isDeprecatedName(resolvedBidderName)) { bidders.remove(); warnings.add("WARNING: request.imp[%d].ext.prebid.imp.%s was dropped with the reason: invalid bidder" @@ -417,7 +425,7 @@ private void validateImpExtPrebidImp(JsonNode imp, private void validateImpExtPrebidBidder(JsonNode extPrebidBidder, ExtStoredAuctionResponse storedAuctionResponse, - Map aliases, + BidderAliases aliases, int impIndex, List warnings) throws ValidationException { if (extPrebidBidder == null) { @@ -433,7 +441,7 @@ private void validateImpExtPrebidBidder(JsonNode extPrebidBidder, final Map.Entry bidderExtension = bidderExtensions.next(); final String bidder = bidderExtension.getKey(); try { - validateImpBidderExtName(impIndex, bidderExtension, aliases.getOrDefault(bidder, bidder)); + validateImpBidderExtName(impIndex, bidderExtension, aliases.resolveBidder(bidder)); } catch (ValidationException ex) { bidderExtensions.remove(); warnings.add("WARNING: request.imp[%d].ext.prebid.bidder.%s was dropped with a reason: %s" @@ -447,7 +455,7 @@ private void validateImpExtPrebidBidder(JsonNode extPrebidBidder, } private void validateImpExtPrebidStoredResponses(ExtImpPrebid extPrebid, - Map aliases, + BidderAliases aliases, int impIndex, List warnings) throws ValidationException { final ExtStoredAuctionResponse extStoredAuctionResponse = extPrebid.getStoredAuctionResponse(); @@ -479,8 +487,11 @@ private void validateImpExtPrebidStoredResponses(ExtImpPrebid extPrebid, } } - private void validateStoredBidResponse(ExtStoredBidResponse extStoredBidResponse, ObjectNode bidderNode, - Map aliases, int impIndex) throws ValidationException { + private void validateStoredBidResponse(ExtStoredBidResponse extStoredBidResponse, + ObjectNode bidderNode, + BidderAliases aliases, + int impIndex) throws ValidationException { + final String bidder = extStoredBidResponse.getBidder(); final String id = extStoredBidResponse.getId(); if (StringUtils.isEmpty(bidder)) { @@ -493,7 +504,7 @@ private void validateStoredBidResponse(ExtStoredBidResponse extStoredBidResponse "Id was not defined for request.imp[%d].ext.prebid.storedbidresponse.id".formatted(impIndex)); } - final String resolvedBidder = aliases.getOrDefault(bidder, bidder); + final String resolvedBidder = aliases.resolveBidder(bidder); if (!bidderCatalog.isValidName(resolvedBidder)) { throw new ValidationException( @@ -518,8 +529,10 @@ private ExtImpPrebid parseExtImpPrebid(ObjectNode extImpPrebid, int impIndex) th } } - private void validateImpBidderExtName(int impIndex, Map.Entry bidderExtension, String bidderName) - throws ValidationException { + private void validateImpBidderExtName(int impIndex, + Map.Entry bidderExtension, + String bidderName) throws ValidationException { + if (bidderCatalog.isValidName(bidderName)) { final Set messages = bidderParamValidator.validate(bidderName, bidderExtension.getValue()); if (!messages.isEmpty()) { diff --git a/src/test/java/org/prebid/server/validation/ImpValidatorTest.java b/src/test/java/org/prebid/server/validation/ImpValidatorTest.java index 652150b6732..fa109dc8f58 100644 --- a/src/test/java/org/prebid/server/validation/ImpValidatorTest.java +++ b/src/test/java/org/prebid/server/validation/ImpValidatorTest.java @@ -49,6 +49,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; import static org.mockito.Mock.Strictness.LENIENT; +import static org.mockito.Mockito.verify; @ExtendWith(MockitoExtension.class) public class ImpValidatorTest extends VertxTest { @@ -1516,6 +1517,42 @@ public void validateImpsShouldReturnWarningMessageAndDropBidderWhenBidderExtIsIn .containsOnly(mapper.createObjectNode()); } + @Test + public void validateImpsShouldReturnWarningMessageAndDropBidderWhenBidderExtIsInvalidAndBidderIsHardcodedAlias() + throws ValidationException { + + // given + final List givenImps = singletonList(validImpBuilder() + .ext(mapper.valueToTree(singletonMap("prebid", singletonMap("bidder", singletonMap("someAlias", 0))))) + .build()); + given(bidderParamValidator.validate(any(), any())) + .willReturn(new LinkedHashSet<>(asList("errorMessage1", "errorMessage2"))); + given(bidderCatalog.isValidName("someAlias")).willReturn(true); + + final List debugMessages = new ArrayList<>(); + + // when + target.validateImps(givenImps, Map.of("someAlias", "rubicon"), debugMessages); + + // then + assertThat(debugMessages) + .containsExactly( + """ + WARNING: request.imp[0].ext.prebid.bidder.someAlias was dropped with a reason: \ + request.imp[0].ext.prebid.bidder.someAlias failed validation. + errorMessage1 + errorMessage2""", + "WARNING: request.imp[0].ext must contain at least one valid bidder"); + + assertThat(givenImps) + .extracting(Imp::getExt) + .extracting(impExt -> impExt.get("prebid")) + .extracting(prebid -> prebid.get("bidder")) + .containsOnly(mapper.createObjectNode()); + + verify(bidderParamValidator).validate(eq("someAlias"), any()); + } + @Test public void validateImpsShouldReturnWarningMessageAndDropBidderWhenImpExtPrebidImpBidderIsUnknown() throws ValidationException {