From d83789adc2b17ecb0177105e920923f25d0e1273 Mon Sep 17 00:00:00 2001 From: Dubyk Danylo <45672370+CTMBNara@users.noreply.github.com> Date: Wed, 27 Jul 2022 17:29:55 +0300 Subject: [PATCH] ORTB 2.6: Add `cattax` field support for blocking module (#1966) --- .../blocking/core/AccountConfigReader.java | 174 +++++++---- .../ortb2/blocking/core/BidsBlocker.java | 123 +++++--- .../core/BlockedAttributesResolver.java | 31 +- .../ortb2/blocking/core/RequestUpdater.java | 34 +-- .../ortb2/blocking/core/ResponseUpdater.java | 7 +- .../core/model/BlockedAttributes.java | 2 + .../core/model/ResponseBlockingConfig.java | 2 + .../ortb2/blocking/core/util/MergeUtils.java | 13 - .../ortb2/blocking/model/ModuleContext.java | 27 +- .../Ortb2BlockingModuleConfiguration.java | 6 +- .../v1/Ortb2BlockingBidderRequestHook.java | 73 +++-- .../blocking/v1/Ortb2BlockingModule.java | 20 +- .../Ortb2BlockingRawBidderResponseHook.java | 39 ++- .../core/AccountConfigReaderTest.java | 229 +++++++++++---- .../ortb2/blocking/core/BidsBlockerTest.java | 150 ++++++++-- .../core/BlockedAttributesResolverTest.java | 14 +- .../blocking/core/RequestUpdaterTest.java | 274 ++++++++++-------- .../blocking/core/ResponseUpdaterTest.java | 18 +- .../blocking/model/ModuleContextTest.java | 39 +-- .../Ortb2BlockingBidderRequestHookTest.java | 64 +++- ...rtb2BlockingRawBidderResponseHookTest.java | 14 +- extra/modules/pom.xml | 22 ++ .../server/auction/ExchangeService.java | 32 +- .../server/auction/model/BidderRequest.java | 5 +- ...idRequestOrtbVersionConversionManager.java | 11 +- .../spring/config/ServiceConfiguration.java | 5 +- .../server/auction/ExchangeServiceTest.java | 24 +- .../auction/StoredResponseProcessorTest.java | 6 +- .../BidRequestConversionManagerTest.java | 29 +- .../bidder/HttpBidderRequesterTest.java | 41 +-- ...imulationAwareHttpBidderRequesterTest.java | 12 +- .../floors/BasicPriceFloorEnforcerTest.java | 1 + .../execution/HookStageExecutorTest.java | 8 +- .../server/log/HttpInteractionLoggerTest.java | 2 +- 34 files changed, 1021 insertions(+), 530 deletions(-) diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/AccountConfigReader.java b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/AccountConfigReader.java index 48dde0367e3..599be6e981c 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/AccountConfigReader.java +++ b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/AccountConfigReader.java @@ -6,9 +6,11 @@ import com.iab.openrtb.request.Imp; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.IterableUtils; +import org.apache.commons.collections4.SetUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; +import org.prebid.server.auction.versionconverter.OrtbVersion; import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.hooks.modules.ortb2.blocking.core.exception.InvalidAccountConfigurationException; import org.prebid.server.hooks.modules.ortb2.blocking.core.model.BidAttributeBlockingConfig; @@ -16,6 +18,7 @@ import org.prebid.server.hooks.modules.ortb2.blocking.core.model.ResponseBlockingConfig; import org.prebid.server.hooks.modules.ortb2.blocking.core.model.Result; import org.prebid.server.hooks.modules.ortb2.blocking.core.util.MergeUtils; +import org.prebid.server.util.ObjectUtil; import org.prebid.server.util.StreamUtil; import java.util.ArrayList; @@ -41,6 +44,7 @@ public class AccountConfigReader { private static final String BLOCKED_ADOMAIN_FIELD = "blocked-adomain"; private static final String ALLOWED_ADOMAIN_FOR_DEALS_FIELD = "allowed-adomain-for-deals"; private static final String BLOCKED_ADV_CAT_FIELD = "blocked-adv-cat"; + private static final String CATEGORY_TAXONOMY_FIELD = "category-taxonomy"; private static final String BLOCK_UNKNOWN_ADV_CAT_FIELD = "block-unknown-adv-cat"; private static final String ALLOWED_ADV_CAT_FOR_DEALS_FIELD = "allowed-adv-cat-for-deals"; private static final String BLOCKED_APP_FIELD = "blocked-app"; @@ -62,16 +66,22 @@ public class AccountConfigReader { private final ObjectNode config; private final String bidder; + private final OrtbVersion ortbVersion; private final boolean debugEnabled; - private AccountConfigReader(ObjectNode config, String bidder, boolean debugEnabled) { + private AccountConfigReader(ObjectNode config, String bidder, OrtbVersion ortbVersion, boolean debugEnabled) { this.config = config; this.bidder = bidder; + this.ortbVersion = ortbVersion; this.debugEnabled = debugEnabled; } - public static AccountConfigReader create(ObjectNode config, String bidder, boolean debugEnabled) { - return new AccountConfigReader(config, bidder, debugEnabled); + public static AccountConfigReader create(ObjectNode config, + String bidder, + OrtbVersion ortbVersion, + boolean debugEnabled) { + + return new AccountConfigReader(config, bidder, ortbVersion, debugEnabled); } public Result blockedAttributesFor(BidRequest bidRequest) { @@ -85,6 +95,7 @@ public Result blockedAttributesFor(BidRequest bidRequest) { blockedAttribute(BADV_FIELD, String.class, BLOCKED_ADOMAIN_FIELD, requestMediaTypes); final Result> bcat = blockedAttribute(BCAT_FIELD, String.class, BLOCKED_ADV_CAT_FIELD, requestMediaTypes); + final Result cattaxComplement = blockedCattaxComplement(bidRequest); final Result> bapp = blockedAttribute(BAPP_FIELD, String.class, BLOCKED_APP_FIELD, requestMediaTypes); final Result>> btype = @@ -93,8 +104,8 @@ public Result blockedAttributesFor(BidRequest bidRequest) { blockedAttributesForImps(BATTR_FIELD, Integer.class, BLOCKED_BANNER_ATTR_FIELD, bidRequest); return Result.of( - toBlockedAttributes(badv, bcat, bapp, btype, battr), - MergeUtils.mergeMessages(badv, bcat, bapp, btype, battr)); + toBlockedAttributes(badv, bcat, cattaxComplement, bapp, btype, battr), + MergeUtils.mergeMessages(badv, bcat, cattaxComplement, bapp, btype, battr)); } public Result responseBlockingConfigFor(BidderBid bidderBid) { @@ -115,6 +126,7 @@ public Result responseBlockingConfigFor(BidderBid bidder ALLOWED_ADV_CAT_FOR_DEALS_FIELD, bidMediaTypes, dealid); + final Result> cattax = blockingConfigForCattax(bcat.getValue()); final Result> bapp = blockingConfigForAttribute( BAPP_FIELD, String.class, @@ -131,40 +143,69 @@ public Result responseBlockingConfigFor(BidderBid bidder final ResponseBlockingConfig response = ResponseBlockingConfig.builder() .badv(badv.getValue()) .bcat(bcat.getValue()) + .cattax(cattax.getValue()) .bapp(bapp.getValue()) .battr(battr.getValue()) .build(); - final List warnings = MergeUtils.mergeMessages(badv, bcat, bapp, battr); + final List warnings = MergeUtils.mergeMessages(badv, bcat, cattax, bapp, battr); return Result.of(response, warnings); } - private Result> blockedAttribute( - String attribute, Class attributeType, String fieldName, Set actualMediaTypes) { + private Result> blockedAttribute(String attribute, + Class attributeType, + String fieldName, + Set actualMediaTypes) { final JsonNode attributeConfig = attributeConfig(attribute); if (attributeConfig == null) { return Result.empty(); } - final Result override = - overrideFor(attributeConfig, actualMediaTypes, fieldName); + final Result override = overrideFor(attributeConfig, actualMediaTypes, fieldName); final List result = overrideArrayAttribute(attributeConfig, override.getValue(), attributeType, fieldName); return Result.of(result, override.getMessages()); } - private Result>> blockedAttributesForImps( - String attribute, Class attributeType, String fieldName, BidRequest bidRequest) { + private Result blockedCattaxComplement(BidRequest bidRequest) { + if (ortbVersion.ordinal() < OrtbVersion.ORTB_2_6.ordinal()) { + return Result.empty(); + } + + return Result.withValue( + ObjectUtil.firstNonNull( + bidRequest::getCattax, + this::blockedCattaxComplementFromConfig)); + } + + private Integer blockedCattaxComplementFromConfig() { + final JsonNode config = attributeConfig(BCAT_FIELD); + if (config == null) { + return null; + } + + final JsonNode blockedCattaxComplementNode = config.get(CATEGORY_TAXONOMY_FIELD); + if (blockedCattaxComplementNode == null) { + return null; + } + + return typedAs(blockedCattaxComplementNode, Integer.class, CATEGORY_TAXONOMY_FIELD); + } + + private Result>> blockedAttributesForImps(String attribute, + Class attributeType, + String fieldName, + BidRequest bidRequest) { final Map> attributeValues = new HashMap<>(); final List> results = new ArrayList<>(); for (final Imp imp : bidRequest.getImp()) { - final Result> attributeForImp = - blockedAttribute(attribute, attributeType, fieldName, mediaTypesFrom(imp)); + final Result> attributeForImp = blockedAttribute( + attribute, attributeType, fieldName, mediaTypesFrom(imp)); if (attributeForImp.hasValue()) { attributeValues.put(imp.getId(), attributeForImp.getValue()); @@ -177,23 +218,22 @@ private Result>> blockedAttributesForImps( MergeUtils.mergeMessages(results)); } - private Result> blockingConfigForAttribute( - String attribute, - Class attributeType, - String blockUnknownField, - String allowedForDealsField, - Set bidMediaTypes, - String dealid) { + private Result> blockingConfigForAttribute(String attribute, + Class attributeType, + String blockUnknownField, + String allowedForDealsField, + Set bidMediaTypes, + String dealid) { final JsonNode attributeConfig = attributeConfig(attribute); if (attributeConfig == null) { return Result.empty(); } - final Result enforceBlocksOverrideResult = - overrideFor(attributeConfig, bidMediaTypes, ENFORCE_BLOCKS_FIELD); - final boolean enforceBlocks = - mergeBoolean(attributeConfig, enforceBlocksOverrideResult.getValue(), ENFORCE_BLOCKS_FIELD); + final Result enforceBlocksOverrideResult = overrideFor( + attributeConfig, bidMediaTypes, ENFORCE_BLOCKS_FIELD); + final boolean enforceBlocks = mergeBoolean( + attributeConfig, enforceBlocksOverrideResult.getValue(), ENFORCE_BLOCKS_FIELD); // for attributes that don't support blocking bids with unknown values final Result blockUnknownOverrideResult = blockUnknownField != null @@ -202,32 +242,41 @@ private Result> blockingConfigForAttribute( final boolean blockUnknown = blockUnknownField != null && mergeBoolean(attributeConfig, blockUnknownOverrideResult.getValue(), blockUnknownField); - final Set dealExceptions = - StringUtils.isNotBlank(dealid) - ? mergeDealExceptions( - attributeConfig, - dealExceptionsFor(attributeConfig, dealid, allowedForDealsField), - attributeType, - allowedForDealsField) - : Collections.emptySet(); - - final BidAttributeBlockingConfig blockingConfig = - BidAttributeBlockingConfig.of(enforceBlocks, blockUnknown, dealExceptions); + final Set dealExceptions = StringUtils.isNotBlank(dealid) + ? mergeDealExceptions( + attributeConfig, + dealExceptionsFor(attributeConfig, dealid, allowedForDealsField), + attributeType, + allowedForDealsField) + : Collections.emptySet(); + + final BidAttributeBlockingConfig blockingConfig = BidAttributeBlockingConfig.of( + enforceBlocks, blockUnknown, dealExceptions); final List warnings = MergeUtils.mergeMessages(enforceBlocksOverrideResult, blockUnknownOverrideResult); return Result.of(blockingConfig, warnings); } - private Result> blockingConfigForAttribute( - String attribute, - Class type, - String allowedForDealsField, - Set bidMediaTypes, - String dealid) { + private Result> blockingConfigForAttribute(String attribute, + Class type, + String allowedForDealsField, + Set bidMediaTypes, + String dealid) { return blockingConfigForAttribute(attribute, type, null, allowedForDealsField, bidMediaTypes, dealid); } + private static Result> blockingConfigForCattax( + BidAttributeBlockingConfig bcat) { + + return bcat != null + ? Result.withValue(BidAttributeBlockingConfig.of( + bcat.isEnforceBlocks(), + true, + SetUtils.emptySet())) + : Result.empty(); + } + private JsonNode attributes() { return config != null ? objectNodeFrom(config, ATTRIBUTES_FIELD) : null; } @@ -279,8 +328,7 @@ private Result overrideFor(JsonNode parent, Set actualMediaTyp final List catchAllBidderResults = new ArrayList<>(); for (final JsonNode override : overridesForField) { - final JsonNode conditions = requireNonNull( - objectNodeFrom(override, CONDITIONS_FIELD), CONDITIONS_FIELD); + final JsonNode conditions = requireNonNull(objectNodeFrom(override, CONDITIONS_FIELD), CONDITIONS_FIELD); final List bidders = typedArrayFrom(conditions, String.class, BIDDERS_FIELD); final List mediaTypes = typedArrayFrom(conditions, String.class, MEDIA_TYPE_FIELD); @@ -294,8 +342,7 @@ private Result overrideFor(JsonNode parent, Set actualMediaTyp final boolean catchAllBidders = bidders == null; final boolean matchesBidder = catchAllBidders || bidders.contains(bidder); - final boolean matchesMediaTypes = - mediaTypes == null || !Collections.disjoint(mediaTypes, actualMediaTypes); + final boolean matchesMediaTypes = mediaTypes == null || !Collections.disjoint(mediaTypes, actualMediaTypes); if (matchesBidder && matchesMediaTypes) { final JsonNode actions = requireNonNull(override.get(OVERRIDE_FIELD), OVERRIDE_FIELD); @@ -308,10 +355,9 @@ private Result overrideFor(JsonNode parent, Set actualMediaTyp return toResult(specificBidderResults, catchAllBidderResults, actualMediaTypes); } - private Result toResult( - List specificBidderResults, - List catchAllBidderResults, - Set actualMediaTypes) { + private Result toResult(List specificBidderResults, + List catchAllBidderResults, + Set actualMediaTypes) { final JsonNode value = ObjectUtils.firstNonNull( specificBidderResults.size() > 0 ? specificBidderResults.get(0) : null, @@ -325,21 +371,29 @@ private Result toResult( return Result.of(value, warnings); } - private static BlockedAttributes toBlockedAttributes( - Result> badv, - Result> bcat, - Result> bapp, - Result>> btype, - Result>> battr) { + private static BlockedAttributes toBlockedAttributes(Result> badv, + Result> bcat, + Result cattaxComplement, + Result> bapp, + Result>> btype, + Result>> battr) { + + return badv.hasValue() + || bcat.hasValue() + || cattaxComplement.hasValue() + || bapp.hasValue() + || btype.hasValue() + || battr.hasValue() - return badv.hasValue() || bcat.hasValue() || bapp.hasValue() || btype.hasValue() || battr.hasValue() ? BlockedAttributes.builder() .badv(badv.getValue()) .bcat(bcat.getValue()) + .cattaxComplement(cattaxComplement.getValue()) .bapp(bapp.getValue()) .btype(btype.getValue()) .battr(battr.getValue()) .build() + : null; } @@ -380,8 +434,10 @@ private static boolean mergeBoolean(JsonNode parent, JsonNode override, String f BooleanUtils.toBooleanDefaultIfNull(typedFieldFrom(parent, Boolean.class, field), false)); } - private static Set mergeDealExceptions( - JsonNode parent, List overrides, Class type, String field) { + private static Set mergeDealExceptions(JsonNode parent, + List overrides, + Class type, + String field) { final List defaultValue = typedArrayFrom(parent, type, field); if (defaultValue == null && CollectionUtils.isEmpty(overrides)) { diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BidsBlocker.java b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BidsBlocker.java index 3927fcd4cb9..28bdccdd136 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BidsBlocker.java +++ b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BidsBlocker.java @@ -3,7 +3,9 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.Value; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; +import org.prebid.server.auction.versionconverter.OrtbVersion; import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.hooks.modules.ortb2.blocking.core.exception.InvalidAccountConfigurationException; import org.prebid.server.hooks.modules.ortb2.blocking.core.model.AnalyticsResult; @@ -36,43 +38,49 @@ public class BidsBlocker { private static final String BUNDLE_FIELD = "bundle"; private static final String ATTR_FIELD = "attr"; + private static final Integer DEFAULT_BLOCKED_CATTAX_COMPLEMENT = 1; + private final List bids; private final String bidder; + private final OrtbVersion ortbVersion; private final ObjectNode accountConfig; private final BlockedAttributes blockedAttributes; private final boolean debugEnabled; - private BidsBlocker( - List bids, - String bidder, - ObjectNode accountConfig, - BlockedAttributes blockedAttributes, - boolean debugEnabled) { + private BidsBlocker(List bids, + String bidder, + OrtbVersion ortbVersion, + ObjectNode accountConfig, + BlockedAttributes blockedAttributes, + boolean debugEnabled) { this.bids = bids; this.bidder = bidder; + this.ortbVersion = ortbVersion; this.accountConfig = accountConfig; this.blockedAttributes = blockedAttributes; this.debugEnabled = debugEnabled; } - public static BidsBlocker create( - List bids, - String bidder, - ObjectNode accountConfig, - BlockedAttributes blockedAttributes, - boolean debugEnabled) { + public static BidsBlocker create(List bids, + String bidder, + OrtbVersion ortbVersion, + ObjectNode accountConfig, + BlockedAttributes blockedAttributes, + boolean debugEnabled) { return new BidsBlocker( Objects.requireNonNull(bids), Objects.requireNonNull(bidder), + Objects.requireNonNull(ortbVersion), accountConfig, blockedAttributes, debugEnabled); } public ExecutionResult block() { - final AccountConfigReader accountConfigReader = AccountConfigReader.create(accountConfig, bidder, debugEnabled); + final AccountConfigReader accountConfigReader = AccountConfigReader.create( + accountConfig, bidder, ortbVersion, debugEnabled); try { final List> blockedBidResults = bids.stream() @@ -100,14 +108,15 @@ public ExecutionResult block() { } private Result isBlocked(BidderBid bidderBid, AccountConfigReader accountConfigReader) { - final Result blockingConfigResult = - accountConfigReader.responseBlockingConfigFor(bidderBid); + final Result blockingConfigResult = accountConfigReader + .responseBlockingConfigFor(bidderBid); final ResponseBlockingConfig blockingConfig = blockingConfigResult.getValue(); final BlockingResult blockingResult = BlockingResult.of( bidderBid.getBid().getImpid(), checkBadv(bidderBid, blockingConfig), checkBcat(bidderBid, blockingConfig), + checkCattax(bidderBid, blockingConfig), checkBapp(bidderBid, blockingConfig), checkBattr(bidderBid, blockingConfig)); @@ -128,6 +137,20 @@ private AttributeCheckResult checkBcat(BidderBid bidderBid, ResponseBloc blockedAttributeValues(BlockedAttributes::getBcat)); } + private AttributeCheckResult checkCattax(BidderBid bidderBid, ResponseBlockingConfig blockingConfig) { + final Integer cattax = bidderBid.getBid().getCattax(); + if (cattax == null || ortbVersion.ordinal() < OrtbVersion.ORTB_2_6.ordinal()) { + return AttributeCheckResult.succeeded(); + } + + return checkAttributeComplement( + cattax, + blockingConfig.getCattax(), + ObjectUtils.defaultIfNull( + blockedAttributeValues(BlockedAttributes::getCattaxComplement), + DEFAULT_BLOCKED_CATTAX_COMPLEMENT)); + } + private AttributeCheckResult checkBapp(BidderBid bidderBid, ResponseBlockingConfig blockingConfig) { return checkAttribute( bidderBid.getBid().getBundle(), @@ -135,8 +158,7 @@ private AttributeCheckResult checkBapp(BidderBid bidderBid, ResponseBloc blockedAttributeValues(BlockedAttributes::getBapp)); } - private AttributeCheckResult checkBattr( - BidderBid bidderBid, ResponseBlockingConfig blockingConfig) { + private AttributeCheckResult checkBattr(BidderBid bidderBid, ResponseBlockingConfig blockingConfig) { return checkAttribute( bidderBid.getBid().getAttr(), @@ -144,8 +166,9 @@ private AttributeCheckResult checkBattr( blockedAttributeValues(BlockedAttributes::getBattr, bidderBid.getBid().getImpid())); } - private AttributeCheckResult checkAttribute( - List attribute, BidAttributeBlockingConfig blockingConfig, List blockedAttributeValues) { + private AttributeCheckResult checkAttribute(List attribute, + BidAttributeBlockingConfig blockingConfig, + List blockedAttributeValues) { if (blockingConfig == null || !blockingConfig.isEnforceBlocks()) { return AttributeCheckResult.succeeded(); @@ -171,8 +194,9 @@ private AttributeCheckResult checkAttribute( return AttributeCheckResult.succeeded(); } - private AttributeCheckResult checkAttribute( - String attribute, BidAttributeBlockingConfig blockingConfig, List blockedAttributeValues) { + private AttributeCheckResult checkAttribute(String attribute, + BidAttributeBlockingConfig blockingConfig, + List blockedAttributeValues) { if (blockingConfig == null || !blockingConfig.isEnforceBlocks() @@ -182,8 +206,23 @@ private AttributeCheckResult checkAttribute( return AttributeCheckResult.succeeded(); } - final boolean blocked = - blockedAttributeValues.contains(attribute) && !blockingConfig.getAllowedValues().contains(attribute); + final boolean blocked = blockedAttributeValues.contains(attribute) + && !blockingConfig.getAllowedValues().contains(attribute); + + return blocked + ? AttributeCheckResult.failed(Collections.singletonList(attribute)) + : AttributeCheckResult.succeeded(); + } + + private AttributeCheckResult checkAttributeComplement(Integer attribute, + BidAttributeBlockingConfig blockingConfig, + Integer blockedAttributeComplementValue) { + + if (blockingConfig == null || !blockingConfig.isEnforceBlocks()) { + return AttributeCheckResult.succeeded(); + } + + final boolean blocked = !blockedAttributeComplementValue.equals(attribute); return blocked ? AttributeCheckResult.failed(Collections.singletonList(attribute)) @@ -200,10 +239,7 @@ private T blockedAttributeValues(Function> return blockedAttributeValues != null ? blockedAttributeValues.get(impId) : null; } - private List debugMessages( - Set blockedBidIndexes, - List> blockedBidResults) { - + private List debugMessages(Set blockedBidIndexes, List> blockedBidResults) { if (!debugEnabled) { return null; } @@ -244,6 +280,10 @@ private Map toAnalyticsResultValues(BlockingResult blockingResul if (bcatResult.isFailed()) { values.put(BCAT_FIELD, bcatResult.getFailedValues()); } + final AttributeCheckResult cattaxResult = blockingResult.getCattaxCheckResult(); + if (cattaxResult.isFailed()) { + values.put(BCAT_FIELD, cattaxResult.getFailedValues()); + } final AttributeCheckResult bappResult = blockingResult.getBappCheckResult(); if (bappResult.isFailed()) { values.put(BUNDLE_FIELD, bappResult.getFailedValues().get(0)); @@ -261,6 +301,7 @@ private static class BlockingResult { private static final String BADV_ATTRIBUTE = "badv"; private static final String BCAT_ATTRIBUTE = "bcat"; + private static final String CATTAX_ATTRIBUTE = "cattax"; private static final String BAPP_ATTRIBUTE = "bapp"; private static final String BATTR_ATTRIBUTE = "battr"; @@ -272,28 +313,31 @@ private static class BlockingResult { AttributeCheckResult bcatCheckResult; + AttributeCheckResult cattaxCheckResult; + AttributeCheckResult bappCheckResult; AttributeCheckResult battrCheckResult; - public static BlockingResult of( - String impId, - AttributeCheckResult badvCheckResult, - AttributeCheckResult bcatCheckResult, - AttributeCheckResult bappCheckResult, - AttributeCheckResult battrCheckResult) { + public static BlockingResult of(String impId, + AttributeCheckResult badvCheckResult, + AttributeCheckResult bcatCheckResult, + AttributeCheckResult cattaxCheckResult, + AttributeCheckResult bappCheckResult, + AttributeCheckResult battrCheckResult) { - final boolean blocked = - badvCheckResult.isFailed() - || bcatCheckResult.isFailed() - || bappCheckResult.isFailed() - || battrCheckResult.isFailed(); + final boolean blocked = badvCheckResult.isFailed() + || bcatCheckResult.isFailed() + || cattaxCheckResult.isFailed() + || bappCheckResult.isFailed() + || battrCheckResult.isFailed(); return of( impId, blocked, badvCheckResult, bcatCheckResult, + cattaxCheckResult, bappCheckResult, battrCheckResult); } @@ -310,6 +354,9 @@ public List getFailedChecks() { if (bcatCheckResult.isFailed()) { failedChecks.add(BCAT_ATTRIBUTE); } + if (cattaxCheckResult.isFailed()) { + failedChecks.add(CATTAX_ATTRIBUTE); + } if (bappCheckResult.isFailed()) { failedChecks.add(BAPP_ATTRIBUTE); } diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BlockedAttributesResolver.java b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BlockedAttributesResolver.java index 30a4acc8c9c..145a90b671d 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BlockedAttributesResolver.java +++ b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BlockedAttributesResolver.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.iab.openrtb.request.BidRequest; +import org.prebid.server.auction.versionconverter.OrtbVersion; import org.prebid.server.hooks.modules.ortb2.blocking.core.exception.InvalidAccountConfigurationException; import org.prebid.server.hooks.modules.ortb2.blocking.core.model.BlockedAttributes; import org.prebid.server.hooks.modules.ortb2.blocking.core.model.ExecutionResult; @@ -13,40 +14,44 @@ public class BlockedAttributesResolver { private final BidRequest bidRequest; private final String bidder; + private final OrtbVersion ortbVersion; private final ObjectNode accountConfig; private final boolean debugEnabled; - private BlockedAttributesResolver( - BidRequest bidRequest, - String bidder, - ObjectNode accountConfig, - boolean debugEnabled) { + private BlockedAttributesResolver(BidRequest bidRequest, + String bidder, + OrtbVersion ortbVersion, + ObjectNode accountConfig, + boolean debugEnabled) { this.bidRequest = bidRequest; this.bidder = bidder; + this.ortbVersion = ortbVersion; this.accountConfig = accountConfig; this.debugEnabled = debugEnabled; } - public static BlockedAttributesResolver create( - BidRequest bidRequest, - String bidder, - ObjectNode accountConfig, - boolean debugEnabled) { + public static BlockedAttributesResolver create(BidRequest bidRequest, + String bidder, + OrtbVersion ortbVersion, + ObjectNode accountConfig, + boolean debugEnabled) { return new BlockedAttributesResolver( Objects.requireNonNull(bidRequest), Objects.requireNonNull(bidder), + Objects.requireNonNull(ortbVersion), accountConfig, debugEnabled); } public ExecutionResult resolve() { - final AccountConfigReader accountConfigReader = AccountConfigReader.create(accountConfig, bidder, debugEnabled); + final AccountConfigReader accountConfigReader = AccountConfigReader.create( + accountConfig, bidder, ortbVersion, debugEnabled); try { - final Result blockedAttributesResult = - accountConfigReader.blockedAttributesFor(bidRequest); + final Result blockedAttributesResult = accountConfigReader + .blockedAttributesFor(bidRequest); return ExecutionResult.builder() .value(blockedAttributesResult.getValue()) diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/RequestUpdater.java b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/RequestUpdater.java index b148038edcf..b17bf0a6b7f 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/RequestUpdater.java +++ b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/RequestUpdater.java @@ -10,7 +10,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.stream.Collectors; public class RequestUpdater { @@ -27,14 +26,16 @@ public static RequestUpdater create(BlockedAttributes blockedAttributes) { public BidRequest update(BidRequest bidRequest) { final List blockedAdomain = blockedAttributes.getBadv(); final List blockedAdvCat = blockedAttributes.getBcat(); + final Integer cattax = bidRequest.getCattax(); final List blockedApp = blockedAttributes.getBapp(); return bidRequest.toBuilder() - .badv(CollectionUtils.isNotEmpty(blockedAdomain) ? blockedAdomain : bidRequest.getBadv()) - .bcat(CollectionUtils.isNotEmpty(blockedAdvCat) ? blockedAdvCat : bidRequest.getBcat()) - .bapp(CollectionUtils.isNotEmpty(blockedApp) ? blockedApp : bidRequest.getBapp()) - .imp(updateImps(bidRequest.getImp())) - .build(); + .badv(CollectionUtils.isNotEmpty(blockedAdomain) ? blockedAdomain : bidRequest.getBadv()) + .bcat(CollectionUtils.isNotEmpty(blockedAdvCat) ? blockedAdvCat : bidRequest.getBcat()) + .cattax(cattax != null ? cattax : blockedAttributes.getCattaxComplement()) + .bapp(CollectionUtils.isNotEmpty(blockedApp) ? blockedApp : bidRequest.getBapp()) + .imp(updateImps(bidRequest.getImp())) + .build(); } private List updateImps(List imps) { @@ -46,14 +47,13 @@ private List updateImps(List imps) { } return imps.stream() - .map(imp -> updateImp(imp, blockedBannerType, blockedBannerAttr)) - .toList(); + .map(imp -> updateImp(imp, blockedBannerType, blockedBannerAttr)) + .toList(); } - private Imp updateImp( - Imp imp, - Map> blockedBannerType, - Map> blockedBannerAttr) { + private Imp updateImp(Imp imp, + Map> blockedBannerType, + Map> blockedBannerAttr) { final String impId = imp.getId(); final List btypeForImp = blockedBannerType != null ? blockedBannerType.get(impId) : null; @@ -69,10 +69,10 @@ private Imp updateImp( final Banner.BannerBuilder bannerBuilder = banner != null ? banner.toBuilder() : Banner.builder(); return imp.toBuilder() - .banner(bannerBuilder - .btype(CollectionUtils.isNotEmpty(btypeForImp) ? btypeForImp : existingBtype) - .battr(CollectionUtils.isNotEmpty(battrForImp) ? battrForImp : existingBattr) - .build()) - .build(); + .banner(bannerBuilder + .btype(CollectionUtils.isNotEmpty(btypeForImp) ? btypeForImp : existingBtype) + .battr(CollectionUtils.isNotEmpty(battrForImp) ? battrForImp : existingBattr) + .build()) + .build(); } } diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/ResponseUpdater.java b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/ResponseUpdater.java index cd265d0bd3c..75ca43c153a 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/ResponseUpdater.java +++ b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/ResponseUpdater.java @@ -5,7 +5,6 @@ import java.util.List; import java.util.Objects; -import java.util.stream.Collectors; import java.util.stream.IntStream; public class ResponseUpdater { @@ -22,8 +21,8 @@ public static ResponseUpdater create(BlockedBids blockedBids) { public List update(List bids) { return IntStream.range(0, bids.size()) - .filter(index -> !blockedBids.getIndexes().contains(index)) - .mapToObj(bids::get) - .toList(); + .filter(index -> !blockedBids.getIndexes().contains(index)) + .mapToObj(bids::get) + .toList(); } } diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BlockedAttributes.java b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BlockedAttributes.java index 20b0cb9aecc..d3d3049b57c 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BlockedAttributes.java +++ b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BlockedAttributes.java @@ -16,6 +16,8 @@ public class BlockedAttributes { List bapp; + Integer cattaxComplement; + Map> btype; Map> battr; diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/ResponseBlockingConfig.java b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/ResponseBlockingConfig.java index 5ce04803865..c2108eb8a8f 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/ResponseBlockingConfig.java +++ b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/ResponseBlockingConfig.java @@ -11,6 +11,8 @@ public class ResponseBlockingConfig { BidAttributeBlockingConfig bcat; + BidAttributeBlockingConfig cattax; + BidAttributeBlockingConfig bapp; BidAttributeBlockingConfig battr; diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/util/MergeUtils.java b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/util/MergeUtils.java index 123085e4f6f..b87baf8f1aa 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/util/MergeUtils.java +++ b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/util/MergeUtils.java @@ -1,13 +1,11 @@ package org.prebid.server.hooks.modules.ortb2.blocking.core.util; -import org.apache.commons.collections4.ListUtils; import org.prebid.server.hooks.modules.ortb2.blocking.core.model.Result; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Objects; -import java.util.stream.Collectors; import java.util.stream.Stream; public interface MergeUtils { @@ -30,15 +28,4 @@ static List mergeMessages(Stream> results) { return !warnings.isEmpty() ? warnings : null; } - - static List merge(List defaultValues, List overriddenValues) { - if (overriddenValues == null) { - return defaultValues; - } - if (defaultValues == null) { - return overriddenValues; - } - - return ListUtils.union(defaultValues, overriddenValues); - } } diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/model/ModuleContext.java b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/model/ModuleContext.java index fc95f74fc24..23e01bcc4f2 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/model/ModuleContext.java +++ b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/model/ModuleContext.java @@ -1,30 +1,45 @@ package org.prebid.server.hooks.modules.ortb2.blocking.model; +import lombok.Value; +import org.prebid.server.auction.versionconverter.OrtbVersion; import org.prebid.server.hooks.modules.ortb2.blocking.core.model.BlockedAttributes; import java.util.HashMap; import java.util.Map; +@Value(staticConstructor = "create") public class ModuleContext { - private final Map blockedAttributes = new HashMap<>(); + Map bidderToOrtbVersion = new HashMap<>(); + Map blockedAttributes = new HashMap<>(); - public static ModuleContext create(String bidder, BlockedAttributes blockedAttributes) { - final ModuleContext moduleContext = new ModuleContext(); - moduleContext.blockedAttributes.put(bidder, blockedAttributes); + public ModuleContext with(String bidder, OrtbVersion ortbVersion) { + final ModuleContext moduleContext = copy(); + moduleContext.bidderToOrtbVersion.put(bidder, ortbVersion); return moduleContext; } public ModuleContext with(String bidder, BlockedAttributes blockedAttributes) { - final ModuleContext moduleContext = new ModuleContext(); - moduleContext.blockedAttributes.putAll(this.blockedAttributes); + final ModuleContext moduleContext = copy(); moduleContext.blockedAttributes.put(bidder, blockedAttributes); return moduleContext; } + public OrtbVersion ortbVersionOf(String bidder) { + return bidderToOrtbVersion.get(bidder); + } + public BlockedAttributes blockedAttributesFor(String bidder) { return blockedAttributes.get(bidder); } + + private ModuleContext copy() { + final ModuleContext copy = ModuleContext.create(); + copy.bidderToOrtbVersion.putAll(this.bidderToOrtbVersion); + copy.blockedAttributes.putAll(this.blockedAttributes); + + return copy; + } } diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/spring/config/Ortb2BlockingModuleConfiguration.java b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/spring/config/Ortb2BlockingModuleConfiguration.java index 6f34e0c2157..a8b9b312cb3 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/spring/config/Ortb2BlockingModuleConfiguration.java +++ b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/spring/config/Ortb2BlockingModuleConfiguration.java @@ -1,6 +1,8 @@ package org.prebid.server.hooks.modules.ortb2.blocking.spring.config; +import org.prebid.server.bidder.BidderCatalog; import org.prebid.server.hooks.modules.ortb2.blocking.v1.Ortb2BlockingModule; +import org.prebid.server.json.ObjectMapperProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -10,7 +12,7 @@ public class Ortb2BlockingModuleConfiguration { @Bean - Ortb2BlockingModule ortb2BlockingModule() { - return new Ortb2BlockingModule(); + Ortb2BlockingModule ortb2BlockingModule(BidderCatalog bidderCatalog) { + return new Ortb2BlockingModule(bidderCatalog, ObjectMapperProvider.mapper()); } } diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHook.java b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHook.java index 85cce62f5ef..0bd01505596 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHook.java +++ b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHook.java @@ -1,6 +1,10 @@ package org.prebid.server.hooks.modules.ortb2.blocking.v1; +import com.iab.openrtb.request.BidRequest; import io.vertx.core.Future; +import org.prebid.server.auction.BidderAliases; +import org.prebid.server.auction.versionconverter.OrtbVersion; +import org.prebid.server.bidder.BidderCatalog; import org.prebid.server.hooks.modules.ortb2.blocking.core.BlockedAttributesResolver; import org.prebid.server.hooks.modules.ortb2.blocking.core.RequestUpdater; import org.prebid.server.hooks.modules.ortb2.blocking.core.model.BlockedAttributes; @@ -14,24 +18,40 @@ import org.prebid.server.hooks.v1.bidder.BidderInvocationContext; import org.prebid.server.hooks.v1.bidder.BidderRequestHook; import org.prebid.server.hooks.v1.bidder.BidderRequestPayload; +import org.prebid.server.proto.openrtb.ext.request.ExtRequest; +import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebid; + +import java.util.Map; +import java.util.Objects; public class Ortb2BlockingBidderRequestHook implements BidderRequestHook { private static final String CODE = "ortb2-blocking-bidder-request"; + private final BidderCatalog bidderCatalog; + + public Ortb2BlockingBidderRequestHook(BidderCatalog bidderCatalog) { + this.bidderCatalog = Objects.requireNonNull(bidderCatalog); + } + @Override - public Future> call( - BidderRequestPayload bidderRequestPayload, - BidderInvocationContext invocationContext) { - - final ExecutionResult blockedAttributesResult = - BlockedAttributesResolver - .create( - bidderRequestPayload.bidRequest(), - invocationContext.bidder(), - invocationContext.accountConfig(), - invocationContext.debugEnabled()) - .resolve(); + public Future> call(BidderRequestPayload bidderRequestPayload, + BidderInvocationContext invocationContext) { + + final String bidder = invocationContext.bidder(); + final BidRequest bidRequest = bidderRequestPayload.bidRequest(); + + final ModuleContext moduleContext = moduleContext(invocationContext) + .with(bidder, bidderSupportedOrtbVersion(bidder, aliases(bidRequest))); + + final ExecutionResult blockedAttributesResult = BlockedAttributesResolver + .create( + bidRequest, + bidder, + moduleContext.ortbVersionOf(bidder), + invocationContext.accountConfig(), + invocationContext.debugEnabled()) + .resolve(); final InvocationResultImpl.InvocationResultImplBuilder resultBuilder = InvocationResultImpl.builder() @@ -39,15 +59,16 @@ public Future> call( .action(blockedAttributesResult.hasValue() ? InvocationAction.update : InvocationAction.no_action) + .moduleContext(moduleContext) .warnings(blockedAttributesResult.getWarnings()) .errors(blockedAttributesResult.getErrors()); + if (blockedAttributesResult.hasValue()) { final BlockedAttributes blockedAttributes = blockedAttributesResult.getValue(); final RequestUpdater requestUpdater = RequestUpdater.create(blockedAttributes); resultBuilder - .payloadUpdate(payload -> - BidderRequestPayloadImpl.of(requestUpdater.update(payload.bidRequest()))) - .moduleContext(moduleContext(invocationContext, blockedAttributes)); + .payloadUpdate(payload -> BidderRequestPayloadImpl.of(requestUpdater.update(payload.bidRequest()))) + .moduleContext(moduleContext.with(bidder, blockedAttributes)); } return Future.succeededFuture(resultBuilder.build()); @@ -58,14 +79,22 @@ public String code() { return CODE; } - private static ModuleContext moduleContext( - BidderInvocationContext invocationContext, BlockedAttributes blockedAttributes) { + private static ModuleContext moduleContext(BidderInvocationContext invocationContext) { + return invocationContext.moduleContext() instanceof ModuleContext moduleContext + ? moduleContext + : ModuleContext.create(); + } + + private BidderAliases aliases(BidRequest bidRequest) { + final ExtRequest requestExt = bidRequest.getExt(); + final ExtRequestPrebid prebid = requestExt != null ? requestExt.getPrebid() : null; + final Map aliases = prebid != null ? prebid.getAliases() : null; + final Map aliasgvlids = prebid != null ? prebid.getAliasgvlids() : null; - final Object moduleContext = invocationContext.moduleContext(); - final String bidder = invocationContext.bidder(); + return BidderAliases.of(aliases, aliasgvlids, bidderCatalog); + } - return moduleContext instanceof ModuleContext - ? ((ModuleContext) moduleContext).with(bidder, blockedAttributes) - : ModuleContext.create(bidder, blockedAttributes); + private OrtbVersion bidderSupportedOrtbVersion(String bidder, BidderAliases aliases) { + return bidderCatalog.bidderInfoByName(aliases.resolveBidder(bidder)).getOrtbVersion(); } } diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingModule.java b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingModule.java index bd6ab7254a0..747728c0d40 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingModule.java +++ b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingModule.java @@ -1,16 +1,30 @@ package org.prebid.server.hooks.modules.ortb2.blocking.v1; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.prebid.server.bidder.BidderCatalog; import org.prebid.server.hooks.v1.Hook; import org.prebid.server.hooks.v1.InvocationContext; import org.prebid.server.hooks.v1.Module; -import java.util.Arrays; import java.util.Collection; +import java.util.List; +import java.util.Objects; public class Ortb2BlockingModule implements Module { public static final String CODE = "ortb2-blocking"; + private final List> hooks; + + public Ortb2BlockingModule(BidderCatalog bidderCatalog, ObjectMapper mapper) { + Objects.requireNonNull(bidderCatalog); + Objects.requireNonNull(mapper); + + hooks = List.of( + new Ortb2BlockingBidderRequestHook(bidderCatalog), + new Ortb2BlockingRawBidderResponseHook(mapper)); + } + @Override public String code() { return CODE; @@ -18,8 +32,6 @@ public String code() { @Override public Collection> hooks() { - return Arrays.asList( - new Ortb2BlockingBidderRequestHook(), - new Ortb2BlockingRawBidderResponseHook()); + return hooks; } } diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHook.java b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHook.java index ae5c8c7fcf7..7ba82dd5b09 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHook.java +++ b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHook.java @@ -4,10 +4,11 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import io.vertx.core.Future; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.prebid.server.auction.versionconverter.OrtbVersion; import org.prebid.server.hooks.modules.ortb2.blocking.core.BidsBlocker; import org.prebid.server.hooks.modules.ortb2.blocking.core.ResponseUpdater; import org.prebid.server.hooks.modules.ortb2.blocking.core.model.AnalyticsResult; -import org.prebid.server.hooks.modules.ortb2.blocking.core.model.BlockedAttributes; import org.prebid.server.hooks.modules.ortb2.blocking.core.model.BlockedBids; import org.prebid.server.hooks.modules.ortb2.blocking.core.model.ExecutionResult; import org.prebid.server.hooks.modules.ortb2.blocking.model.ModuleContext; @@ -29,7 +30,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; +import java.util.Objects; public class Ortb2BlockingRawBidderResponseHook implements RawBidderResponseHook { @@ -38,19 +39,26 @@ public class Ortb2BlockingRawBidderResponseHook implements RawBidderResponseHook private static final String ENFORCE_BLOCKING_ACTIVITY = "enforce-blocking"; private static final String SUCCESS_STATUS = "success"; - private final ObjectMapper mapper = new ObjectMapper(); + private final ObjectMapper mapper; + + public Ortb2BlockingRawBidderResponseHook(ObjectMapper mapper) { + this.mapper = Objects.requireNonNull(mapper); + } @Override - public Future> call( - BidderResponsePayload bidderResponsePayload, - BidderInvocationContext invocationContext) { + public Future> call(BidderResponsePayload bidderResponsePayload, + BidderInvocationContext invocationContext) { + + final String bidder = invocationContext.bidder(); + final ModuleContext moduleContext = moduleContext(invocationContext); final ExecutionResult blockedBidsResult = BidsBlocker .create( bidderResponsePayload.bids(), - invocationContext.bidder(), + bidder, + ObjectUtils.defaultIfNull(moduleContext.ortbVersionOf(bidder), OrtbVersion.ORTB_2_5), invocationContext.accountConfig(), - blockedAttributesFrom(invocationContext), + moduleContext.blockedAttributesFor(bidder), invocationContext.debugEnabled()) .block(); @@ -60,14 +68,16 @@ public Future> call( .action(blockedBidsResult.hasValue() ? InvocationAction.update : InvocationAction.no_action) + .moduleContext(moduleContext) .errors(blockedBidsResult.getErrors()) .warnings(blockedBidsResult.getWarnings()) .debugMessages(blockedBidsResult.getDebugMessages()) .analyticsTags(toAnalyticsTags(blockedBidsResult.getAnalyticsResults())); + if (blockedBidsResult.hasValue()) { final ResponseUpdater responseUpdater = ResponseUpdater.create(blockedBidsResult.getValue()); - resultBuilder.payloadUpdate(payload -> - BidderResponsePayloadImpl.of(responseUpdater.update(payload.bids()))); + resultBuilder + .payloadUpdate(payload -> BidderResponsePayloadImpl.of(responseUpdater.update(payload.bids()))); } return Future.succeededFuture(resultBuilder.build()); @@ -78,11 +88,10 @@ public String code() { return CODE; } - private static BlockedAttributes blockedAttributesFrom(BidderInvocationContext invocationContext) { - final Object moduleContext = invocationContext.moduleContext(); - return moduleContext instanceof ModuleContext - ? ((ModuleContext) moduleContext).blockedAttributesFor(invocationContext.bidder()) - : null; + private static ModuleContext moduleContext(BidderInvocationContext invocationContext) { + return invocationContext.moduleContext() instanceof ModuleContext moduleContext + ? moduleContext + : ModuleContext.create(); } private Tags toAnalyticsTags(List analyticsResults) { diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/AccountConfigReaderTest.java b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/AccountConfigReaderTest.java index bf5ac39cbea..52035b7a2b4 100644 --- a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/AccountConfigReaderTest.java +++ b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/AccountConfigReaderTest.java @@ -1,6 +1,7 @@ package org.prebid.server.hooks.modules.ortb2.blocking.core; import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategies; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -11,7 +12,8 @@ import com.iab.openrtb.request.Native; import com.iab.openrtb.request.Video; import com.iab.openrtb.response.Bid; -import org.junit.jupiter.api.Test; +import org.junit.Test; +import org.prebid.server.auction.versionconverter.OrtbVersion; import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.hooks.modules.ortb2.blocking.core.config.AllowedForDealsOverride; import org.prebid.server.hooks.modules.ortb2.blocking.core.config.ArrayOverride; @@ -33,6 +35,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.UnaryOperator; import static java.util.Arrays.asList; @@ -42,16 +45,18 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -class AccountConfigReaderTest { +public class AccountConfigReaderTest { private static final ObjectMapper mapper = new ObjectMapper() .setPropertyNamingStrategy(PropertyNamingStrategies.KEBAB_CASE) .setSerializationInclusion(JsonInclude.Include.NON_NULL); + private static final OrtbVersion ORTB_VERSION = OrtbVersion.ORTB_2_5; + @Test public void blockedAttributesForShouldReturnEmptyResultWhenNoAccountConfig() { // given - final AccountConfigReader reader = AccountConfigReader.create(null, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(null, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader.blockedAttributesFor(emptyRequest())).isEqualTo(Result.empty()); @@ -61,7 +66,7 @@ public void blockedAttributesForShouldReturnEmptyResultWhenNoAccountConfig() { public void blockedAttributesForShouldReturnEmptyResultWhenNoAttributesField() { // given final ObjectNode accountConfig = toObjectNode(ModuleConfig.of(null)); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader.blockedAttributesFor(emptyRequest())).isEqualTo(Result.empty()); @@ -71,7 +76,7 @@ public void blockedAttributesForShouldReturnEmptyResultWhenNoAttributesField() { public void blockedAttributesForShouldReturnEmptyResultWhenNoBlockedAttributes() { // given final ObjectNode accountConfig = toObjectNode(ModuleConfig.of(Attributes.builder().build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader.blockedAttributesFor(emptyRequest())).isEqualTo(Result.empty()); @@ -83,7 +88,7 @@ public void blockedAttributesForShouldReturnEmptyResultWhenNoBlockedAdomains() { final ObjectNode accountConfig = toObjectNode(ModuleConfig.of(Attributes.builder() .badv(Attribute.badvBuilder().build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader.blockedAttributesFor(emptyRequest())).isEqualTo(Result.empty()); @@ -93,7 +98,7 @@ public void blockedAttributesForShouldReturnEmptyResultWhenNoBlockedAdomains() { public void blockedAttributesForShouldReturnErrorWhenAttributesIsNotObject() { // given final ObjectNode accountConfig = mapper.createObjectNode().put("attributes", 1); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.blockedAttributesFor(emptyRequest())) @@ -107,7 +112,7 @@ public void blockedAttributesForShouldReturnErrorWhenBadvIsNotObject() { final ObjectNode accountConfig = mapper.createObjectNode() .set("attributes", mapper.createObjectNode() .put("badv", 1)); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.blockedAttributesFor(emptyRequest())) @@ -122,7 +127,7 @@ public void blockedAttributesForShouldReturnErrorWhenBlockedAdomainsIsNotArray() .set("attributes", mapper.createObjectNode() .set("badv", mapper.createObjectNode() .put("blocked-adomain", 1))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.blockedAttributesFor(emptyRequest())) @@ -139,7 +144,7 @@ public void blockedAttributesForShouldReturnErrorWhenBlockedAdomainsIsNotStringA .set("blocked-adomain", mapper.createArrayNode() .add(1) .add("domain2.com")))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.blockedAttributesFor(emptyRequest())) @@ -155,7 +160,7 @@ public void blockedAttributesForShouldReturnErrorWhenBadvActionOverridesIsNotObj .set("attributes", mapper.createObjectNode() .set("badv", mapper.createObjectNode() .put("action-overrides", 1))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.blockedAttributesFor(emptyRequest())) @@ -173,7 +178,7 @@ public void blockedAttributesForShouldReturnErrorWhenBadvActionOverridesBlockedA .set("blocked-adomain", mapper.createArrayNode() .add(1) .add(mapper.createObjectNode()))))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.blockedAttributesFor(emptyRequest())) @@ -190,7 +195,7 @@ public void blockedAttributesForShouldReturnErrorWhenOverridesHasNoConditions() .set("action-overrides", mapper.createObjectNode() .set("blocked-adomain", mapper.createArrayNode() .add(mapper.createObjectNode()))))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.blockedAttributesFor(emptyRequest())) @@ -208,7 +213,7 @@ public void blockedAttributesForShouldReturnErrorWhenConditionsIsNotObject() { .set("blocked-adomain", mapper.createArrayNode() .add(mapper.createObjectNode() .put("conditions", 1)))))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.blockedAttributesFor(emptyRequest())) @@ -226,7 +231,7 @@ public void blockedAttributesForShouldReturnErrorWhenBadvActionOverridesBlockedA .set("blocked-adomain", mapper.createArrayNode() .add(mapper.createObjectNode() .set("conditions", mapper.createObjectNode())))))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.blockedAttributesFor(emptyRequest())) @@ -246,7 +251,7 @@ public void blockedAttributesForShouldReturnErrorWhenConditionBiddersIsNotArray( .add(mapper.createObjectNode() .set("conditions", mapper.createObjectNode() .put("bidders", 1))))))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.blockedAttributesFor(emptyRequest())) @@ -267,7 +272,7 @@ public void blockedAttributesForShouldReturnErrorWhenConditionBiddersIsNotString .set("bidders", mapper.createArrayNode() .add(1) .add("abc")))))))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.blockedAttributesFor(emptyRequest())) @@ -287,7 +292,7 @@ public void blockedAttributesForShouldReturnErrorWhenConditionMediaTypeIsNotArra .add(mapper.createObjectNode() .set("conditions", mapper.createObjectNode() .put("media-type", 1))))))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.blockedAttributesFor(emptyRequest())) @@ -308,7 +313,7 @@ public void blockedAttributesForShouldReturnErrorWhenConditionMediaTypeIsNotStri .set("media-type", mapper.createArrayNode() .add(1) .add("abc")))))))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.blockedAttributesFor(emptyRequest())) @@ -329,7 +334,7 @@ public void blockedAttributesForShouldReturnErrorWhenActionOverridesHasNoOverrid .set("conditions", mapper.createObjectNode() .set("bidders", mapper.createArrayNode() .add("bidder1")))))))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.blockedAttributesFor(emptyRequest())) @@ -350,7 +355,7 @@ public void blockedAttributesForShouldReturnErrorWhenBadvBlockedAdomainOverrideI .set("bidders", mapper.createArrayNode() .add("bidder1"))) .put("override", 1)))))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.blockedAttributesFor(emptyRequest())) @@ -373,7 +378,7 @@ public void blockedAttributesForShouldReturnErrorWhenBlockedAdomainOverrideIsNot .set("override", mapper.createArrayNode() .add(1) .add("abc"))))))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.blockedAttributesFor(emptyRequest())) @@ -391,7 +396,7 @@ public void blockedAttributesForShouldReturnErrorWhenBlockedBannerTypeIsNotInteg .set("blocked-banner-type", mapper.createArrayNode() .add(1) .add("type2")))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.blockedAttributesFor(emptyRequest())) @@ -408,7 +413,7 @@ public void blockedAttributesForShouldReturnResultWithDefaultBadvWhenNoOverrides .blocked(asList("domain1.com", "domain2.com")) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader.blockedAttributesFor(emptyRequest())).isEqualTo( @@ -428,7 +433,7 @@ public void blockedAttributesForShouldReturnResultWithDefaultBadvWhenOverridesDo singletonList("domain3.com"))))) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader.blockedAttributesFor(emptyRequest())).isEqualTo( @@ -448,7 +453,7 @@ public void blockedAttributesForShouldReturnResultWithDefaultBadvWhenOverridesDo singletonList("domain3.com"))))) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader.blockedAttributesFor(emptyRequest())).isEqualTo( @@ -468,7 +473,7 @@ public void blockedAttributesForShouldReturnResultWithOverridedBadvWhenOverrides singletonList("domain3.com"))))) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader.blockedAttributesFor(emptyRequest())).isEqualTo( @@ -487,7 +492,7 @@ public void blockedAttributesForShouldReturnResultWithBadvFromOverridesWhenMatch singletonList("domain3.com"))))) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); final BidRequest request = BidRequest.builder() .imp(asList( @@ -512,7 +517,7 @@ public void blockedAttributesForShouldReturnResultWithBadvFromOverridesWhenMatch singletonList("domain3.com"))))) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader.blockedAttributesFor(emptyRequest())).isEqualTo( @@ -531,7 +536,7 @@ public void blockedAttributesForShouldReturnResultWithBadvFromOverridesWhenMatch singletonList("domain3.com"))))) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader.blockedAttributesFor(request(imp -> imp.video(Video.builder().build())))).isEqualTo( @@ -555,19 +560,19 @@ public void blockedAttributesForShouldReturnResultWithBadvFromOverridesWhenMatch // when and then assertThat(AccountConfigReader - .create(accountConfig, "bidder1", true) + .create(accountConfig, "bidder1", ORTB_VERSION, true) .blockedAttributesFor(request(imp -> imp.audio(Audio.builder().build())))) .isEqualTo(Result.withValue(attributesWithBadv(singletonList("domain3.com")))); assertThat(AccountConfigReader - .create(accountConfig, "bidder1", true) + .create(accountConfig, "bidder1", ORTB_VERSION, true) .blockedAttributesFor(request(imp -> imp.video(Video.builder().build())))) .isEqualTo(Result.withValue(attributesWithBadv(singletonList("domain3.com")))); assertThat(AccountConfigReader - .create(accountConfig, "bidder1", true) + .create(accountConfig, "bidder1", ORTB_VERSION, true) .blockedAttributesFor(request(imp -> imp.banner(Banner.builder().build())))) .isEqualTo(Result.withValue(attributesWithBadv(singletonList("domain3.com")))); assertThat(AccountConfigReader - .create(accountConfig, "bidder1", true) + .create(accountConfig, "bidder1", ORTB_VERSION, true) .blockedAttributesFor(request(imp -> imp.xNative(Native.builder().build())))) .isEqualTo(Result.withValue(attributesWithBadv(singletonList("domain3.com")))); } @@ -587,7 +592,7 @@ public void blockedAttributesForShouldReturnResultWithBadvAndWarningFromOverride singletonList("domain4.com"))))) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader @@ -615,7 +620,7 @@ public void blockedAttributesForShouldReturnResultWithoutWarningWhenMultipleSpec singletonList("domain4.com"))))) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", false); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, false); // when and then assertThat(reader @@ -646,7 +651,7 @@ public void blockedAttributesForShouldReturnResultWithBadvAndWarningFromOverride singletonList("domain6.com"))))) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader @@ -674,7 +679,7 @@ public void blockedAttributesForShouldReturnResultWithBadvAndWarningFromOverride singletonList("domain6.com"))))) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader @@ -707,7 +712,7 @@ public void blockedAttributesForShouldReturnResultWithBtypeAndWarningsFromOverri singletonList(4))))) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then final Map> expectedBtype = new HashMap<>(); @@ -769,7 +774,7 @@ public void blockedAttributesForShouldReturnResultWithAllAttributes() { singletonList(3))))) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader.blockedAttributesFor(request(imp -> imp.id("impId1")))).isEqualTo( @@ -782,6 +787,70 @@ public void blockedAttributesForShouldReturnResultWithAllAttributes() { .build())); } + @Test + public void blockedAttributesForShouldNotReturnCattaxIfBidderSupportsLowerThan26() throws JsonProcessingException { + // given + final ObjectNode accountConfig = (ObjectNode) mapper.readTree(""" + { + "attributes": { + "bcat": { + "enforce-blocks": true, + "block-unknown-adv-cat": false, + "category-taxonomy": 6 + } + } + } + """); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); + + // when and then + assertThat(reader.blockedAttributesFor(request(imp -> imp.id("impId1")))).isEqualTo(Result.empty()); + } + + @Test + public void blockedAttributesForShouldReturnCattaxFromRequestIfPresent() throws JsonProcessingException { + // given + final ObjectNode accountConfig = (ObjectNode) mapper.readTree(""" + { + "attributes": { + "bcat": { + "enforce-blocks": true, + "block-unknown-adv-cat": false, + "category-taxonomy": 6 + } + } + } + """); + final AccountConfigReader reader = AccountConfigReader.create( + accountConfig, "bidder1", OrtbVersion.ORTB_2_6, true); + + // when and then + assertThat(reader.blockedAttributesFor(request(imp -> imp.id("impId1"), request -> request.cattax(2)))) + .isEqualTo(Result.withValue(BlockedAttributes.builder().cattaxComplement(2).build())); + } + + @Test + public void blockedAttributesForShouldReturnCattaxFromConfigIfNotPresentInRequest() throws JsonProcessingException { + // given + final ObjectNode accountConfig = (ObjectNode) mapper.readTree(""" + { + "attributes": { + "bcat": { + "enforce-blocks": true, + "block-unknown-adv-cat": false, + "category-taxonomy": 6 + } + } + } + """); + final AccountConfigReader reader = AccountConfigReader.create( + accountConfig, "bidder1", OrtbVersion.ORTB_2_6, true); + + // when and then + assertThat(reader.blockedAttributesFor(request(imp -> imp.id("impId1")))) + .isEqualTo(Result.withValue(BlockedAttributes.builder().cattaxComplement(6).build())); + } + @Test public void responseBlockingConfigForShouldReturnErrorWhenDefaultEnforceBlocksIsNotBoolean() { // given @@ -789,7 +858,7 @@ public void responseBlockingConfigForShouldReturnErrorWhenDefaultEnforceBlocksIs .set("attributes", mapper.createObjectNode() .set("badv", mapper.createObjectNode() .put("enforce-blocks", 1))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.responseBlockingConfigFor(bid())) @@ -805,7 +874,7 @@ public void responseBlockingConfigForShouldReturnErrorWhenDefaultAllowedAdomainI .set("attributes", mapper.createObjectNode() .set("badv", mapper.createObjectNode() .put("allowed-adomain-for-deals", 1))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.responseBlockingConfigFor(bid())) @@ -822,7 +891,7 @@ public void responseBlockingConfigForShouldReturnErrorWhenDefaultAllowedAdomainI .set("allowed-adomain-for-deals", mapper.createArrayNode() .add(1) .add("domain1.com")))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.responseBlockingConfigFor(bid())) @@ -840,7 +909,7 @@ public void responseBlockingConfigForShouldReturnErrorWhenDefaultAllowedBlockedA .set("allowed-banner-attr-for-deals", mapper.createArrayNode() .add(1) .add("domain1.com")))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.responseBlockingConfigFor(bid())) @@ -859,7 +928,7 @@ public void responseBlockingConfigForShouldReturnErrorWhenDealConditionsIsEmpty( .set("allowed-adomain-for-deals", mapper.createArrayNode() .add(mapper.createObjectNode() .set("conditions", mapper.createObjectNode())))))); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThatThrownBy(() -> reader.responseBlockingConfigFor(bid())) @@ -873,7 +942,7 @@ public void responseBlockingConfigForShouldReturnDefaultResultWhenNoValues() { final ObjectNode accountConfig = toObjectNode(ModuleConfig.of(Attributes.builder() .badv(Attribute.badvBuilder().build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader.responseBlockingConfigFor(bid())).satisfies(result -> { @@ -891,7 +960,7 @@ public void responseBlockingConfigForShouldReturnResultWithoutDealExceptionWhenN .allowedForDeals(asList("domain1.com", "domain2.com")) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); final BidderBid bid = BidderBid.of(Bid.builder().build(), BidType.banner, "USD"); @@ -913,7 +982,7 @@ public void responseBlockingConfigForShouldReturnResultWithDefaultValuesWhenNoOv .allowedForDeals(asList("domain1.com", "domain2.com")) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader.responseBlockingConfigFor(bid())).satisfies(result -> { @@ -944,7 +1013,7 @@ public void responseBlockingConfigForShouldReturnResultWithDefaultValuesWhenOver singletonList("domain3.com"))))) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader.responseBlockingConfigFor(bid())).satisfies(result -> { @@ -975,7 +1044,7 @@ public void responseBlockingConfigForShouldReturnResultWithDefaultAndOverridesWh singletonList("domain3.com"))))) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader.responseBlockingConfigFor(bid())).satisfies(result -> { @@ -1003,7 +1072,7 @@ public void responseBlockingConfigForShouldReturnResultWithOverridesWhenOverride singletonList("domain3.com"))))) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader.responseBlockingConfigFor(bid())).satisfies(result -> { @@ -1036,7 +1105,7 @@ public void responseBlockingConfigForShouldReturnResultWithWarningAndOverrideWhe true)))) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader.responseBlockingConfigFor(bid())).satisfies(result -> { @@ -1062,7 +1131,7 @@ public void responseBlockingConfigForShouldReturnResultWithMergedDealExceptionsW singletonList("domain4.com"))))) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader.responseBlockingConfigFor(bid())).satisfies(result -> { @@ -1132,19 +1201,49 @@ public void responseBlockingConfigForShouldReturnAllAttributes() { singletonList(3))))) .build()) .build())); - final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", true); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); // when and then assertThat(reader.responseBlockingConfigFor(bid())).satisfies(result -> { assertThat(result.getValue()).isEqualTo(ResponseBlockingConfig.builder() .badv(BidAttributeBlockingConfig.of( - false, false, new HashSet<>(asList("domain1.com", "domain2.com", "domain3.com")))) - .bcat(BidAttributeBlockingConfig.of( - false, false, new HashSet<>(asList("cat1", "cat2", "cat3")))) - .bapp(BidAttributeBlockingConfig.of( - false, false, new HashSet<>(asList("app1", "app2", "app3")))) - .battr(BidAttributeBlockingConfig.of( - false, false, new HashSet<>(asList(1, 2, 3)))) + false, false, Set.of("domain1.com", "domain2.com", "domain3.com"))) + .bcat(BidAttributeBlockingConfig.of(false, false, Set.of("cat1", "cat2", "cat3"))) + .cattax(BidAttributeBlockingConfig.of(false, true, emptySet())) + .bapp(BidAttributeBlockingConfig.of(false, false, Set.of("app1", "app2", "app3"))) + .battr(BidAttributeBlockingConfig.of(false, false, Set.of(1, 2, 3))) + .build()); + assertThat(result.getMessages()).isNull(); + }); + } + + @Test + public void responseBlockingConfigForShouldReturnCattaxConfigDependsOnBcatConfig() { + // given + final ObjectNode accountConfig = toObjectNode(ModuleConfig.of(Attributes.builder() + .bcat(Attribute.bcatBuilder() + .enforceBlocks(false) + .blockUnknown(true) + .allowedForDeals(asList("cat1", "cat2")) + .actionOverrides(AttributeActionOverrides.response( + singletonList(BooleanOverride.of( + Conditions.of(singletonList("bidder1"), null), + true)), + singletonList(BooleanOverride.of( + Conditions.of(singletonList("bidder1"), null), + false)), + singletonList(AllowedForDealsOverride.of( + DealsConditions.of(singletonList("dealid1")), + singletonList("cat3"))))) + .build()) + .build())); + final AccountConfigReader reader = AccountConfigReader.create(accountConfig, "bidder1", ORTB_VERSION, true); + + // when and then + assertThat(reader.responseBlockingConfigFor(bid())).satisfies(result -> { + assertThat(result.getValue()).isEqualTo(ResponseBlockingConfig.builder() + .bcat(BidAttributeBlockingConfig.of(true, false, Set.of("cat1", "cat2", "cat3"))) + .cattax(BidAttributeBlockingConfig.of(true, true, emptySet())) .build()); assertThat(result.getMessages()).isNull(); }); @@ -1162,6 +1261,14 @@ private static BidRequest request(UnaryOperator impCustomizer) { .build(); } + private static BidRequest request(UnaryOperator impCustomizer, + UnaryOperator bidRequestCustomizer) { + + return bidRequestCustomizer.apply(BidRequest.builder() + .imp(singletonList(impCustomizer.apply(Imp.builder()).build()))) + .build(); + } + private static BidderBid bid() { return BidderBid.of( Bid.builder().dealid("dealid1").build(), diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BidsBlockerTest.java b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BidsBlockerTest.java index 0bca3bdf6a4..96d53a95f0a 100644 --- a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BidsBlockerTest.java +++ b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BidsBlockerTest.java @@ -3,10 +3,10 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.node.ObjectNode; import com.iab.openrtb.response.Bid; -import org.junit.jupiter.api.Test; +import org.junit.Test; +import org.prebid.server.auction.versionconverter.OrtbVersion; import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.hooks.modules.ortb2.blocking.core.config.Attribute; import org.prebid.server.hooks.modules.ortb2.blocking.core.config.Attributes; @@ -18,9 +18,9 @@ import org.prebid.server.proto.openrtb.ext.response.BidType; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.UnaryOperator; import static java.util.Arrays.asList; @@ -30,17 +30,19 @@ import static java.util.function.UnaryOperator.identity; import static org.assertj.core.api.Assertions.assertThat; -class BidsBlockerTest { +public class BidsBlockerTest { private static final ObjectMapper mapper = new ObjectMapper() .setPropertyNamingStrategy(PropertyNamingStrategies.KEBAB_CASE) .setSerializationInclusion(JsonInclude.Include.NON_NULL); + private static final OrtbVersion ORTB_VERSION = OrtbVersion.ORTB_2_5; + @Test public void shouldReturnEmptyResultWhenNoBlockingResponseConfig() { // given final List bids = singletonList(bid()); - final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", null, null, true); + final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", ORTB_VERSION, null, null, true); // when and then assertThat(blocker.block()).satisfies(BidsBlockerTest::isEmpty); @@ -53,7 +55,7 @@ public void shouldReturnEmptyResultWithErrorWhenInvalidAccountConfig() { .put("attributes", 1); final List bids = singletonList(bid()); - final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", accountConfig, null, true); + final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", ORTB_VERSION, accountConfig, null, true); // when and then assertThat(blocker.block()).isEqualTo(ExecutionResult.builder() @@ -68,7 +70,7 @@ public void shouldReturnEmptyResultWithoutErrorWhenInvalidAccountConfigAndDebugD .put("attributes", 1); final List bids = singletonList(bid()); - final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", accountConfig, null, false); + final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", ORTB_VERSION, accountConfig, null, false); // when and then assertThat(blocker.block()).isEqualTo(ExecutionResult.empty()); @@ -86,7 +88,7 @@ public void shouldReturnEmptyResultWhenBidWithoutAdomainAndBlockUnknownFalse() { // when final List bids = singletonList(bid()); - final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", accountConfig, null, true); + final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", ORTB_VERSION, accountConfig, null, true); // when and then assertThat(blocker.block()).satisfies(BidsBlockerTest::isEmpty); @@ -104,7 +106,7 @@ public void shouldReturnEmptyResultWhenBidWithoutAdomainAndEnforceBlocksFalseAnd // when final List bids = singletonList(bid()); - final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", accountConfig, null, true); + final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", ORTB_VERSION, accountConfig, null, true); // when and then assertThat(blocker.block()).satisfies(BidsBlockerTest::isEmpty); @@ -122,7 +124,7 @@ public void shouldReturnResultWithBidWhenBidWithoutAdomainAndBlockUnknownTrue() // when final List bids = singletonList(bid()); - final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", accountConfig, null, false); + final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", ORTB_VERSION, accountConfig, null, false); // when and then assertThat(blocker.block()).satisfies(result -> hasValue(result, 0)); @@ -140,7 +142,7 @@ public void shouldReturnEmptyResultWhenBidWithBlockedAdomainAndEnforceBlocksFals // when final List bids = singletonList(bid(bid -> bid.adomain(singletonList("domain1.com")))); final BlockedAttributes blockedAttributes = attributesWithBadv(singletonList("domain1.com")); - final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", accountConfig, blockedAttributes, true); + final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", ORTB_VERSION, accountConfig, blockedAttributes, true); // when and then assertThat(blocker.block()).satisfies(BidsBlockerTest::isEmpty); @@ -158,7 +160,7 @@ public void shouldReturnEmptyResultWhenBidWithNotBlockedAdomain() { // when final List bids = singletonList(bid(bid -> bid.adomain(singletonList("domain1.com")))); final BlockedAttributes blockedAttributes = attributesWithBadv(singletonList("domain2.com")); - final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", accountConfig, blockedAttributes, true); + final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", ORTB_VERSION, accountConfig, blockedAttributes, true); // when and then assertThat(blocker.block()).satisfies(BidsBlockerTest::isEmpty); @@ -176,7 +178,7 @@ public void shouldReturnResultWithBidWhenBidWithBlockedAdomainAndEnforceBlocksTr // when final List bids = singletonList(bid(bid -> bid.adomain(singletonList("domain1.com")))); final BlockedAttributes blockedAttributes = attributesWithBadv(singletonList("domain1.com")); - final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", accountConfig, blockedAttributes, false); + final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", ORTB_VERSION, accountConfig, blockedAttributes, false); // when and then assertThat(blocker.block()).satisfies(result -> hasValue(result, 0)); @@ -193,7 +195,7 @@ public void shouldReturnEmptyResultWhenBidWithAdomainAndNoBlockedAttributes() { // when final List bids = singletonList(bid(bid -> bid.adomain(singletonList("domain1.com")))); - final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", accountConfig, null, true); + final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", ORTB_VERSION, accountConfig, null, true); // when and then assertThat(blocker.block()).satisfies(BidsBlockerTest::isEmpty); @@ -215,7 +217,7 @@ public void shouldReturnEmptyResultWhenBidWithAttrAndNoBlockedBannerAttrForImp() final BlockedAttributes blockedAttributes = BlockedAttributes.builder() .battr(singletonMap("impId1", asList(1, 2))) .build(); - final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", accountConfig, blockedAttributes, true); + final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", ORTB_VERSION, accountConfig, blockedAttributes, true); // when and then assertThat(blocker.block()).satisfies(BidsBlockerTest::isEmpty); @@ -234,7 +236,7 @@ public void shouldReturnEmptyResultWhenBidWithBlockedAdomainAndInDealsExceptions // when final List bids = singletonList(bid(bid -> bid.adomain(singletonList("domain1.com")))); final BlockedAttributes blockedAttributes = attributesWithBadv(singletonList("domain1.com")); - final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", accountConfig, blockedAttributes, true); + final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", ORTB_VERSION, accountConfig, blockedAttributes, true); // when and then assertThat(blocker.block()).satisfies(BidsBlockerTest::isEmpty); @@ -253,7 +255,7 @@ public void shouldReturnResultWithBidWhenBidWithBlockedAdomainAndNotInDealsExcep // when final List bids = singletonList(bid(bid -> bid.adomain(singletonList("domain1.com")))); final BlockedAttributes blockedAttributes = attributesWithBadv(singletonList("domain1.com")); - final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", accountConfig, blockedAttributes, false); + final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", ORTB_VERSION, accountConfig, blockedAttributes, false); // when and then assertThat(blocker.block()).satisfies(result -> hasValue(result, 0)); @@ -271,7 +273,7 @@ public void shouldReturnResultWithBidAndDebugMessageWhenBidIsBlocked() { // when final List bids = singletonList(bid()); - final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", accountConfig, null, true); + final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", ORTB_VERSION, accountConfig, null, true); // when and then assertThat(blocker.block()).satisfies(result -> { @@ -293,7 +295,7 @@ public void shouldReturnResultWithBidWithoutDebugMessageWhenBidIsBlockedAndDebug // when final List bids = singletonList(bid()); - final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", accountConfig, null, false); + final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", ORTB_VERSION, accountConfig, null, false); // when and then assertThat(blocker.block()).satisfies(result -> hasValue(result, 0)); @@ -339,11 +341,11 @@ public void shouldReturnResultWithAnalyticsResults() { .bapp(asList("app1", "app2", "app3")) .battr(singletonMap("impId2", asList(1, 2, 3))) .build(); - final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", accountConfig, blockedAttributes, true); + final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", ORTB_VERSION, accountConfig, blockedAttributes, true); // when and then assertThat(blocker.block()).satisfies(result -> { - assertThat(result.getValue()).isEqualTo(BlockedBids.of(new HashSet<>(asList(0, 1)))); + assertThat(result.getValue()).isEqualTo(BlockedBids.of(Set.of(0, 1))); final Map analyticsResultValues1 = new HashMap<>(); analyticsResultValues1.put("attributes", asList("badv", "bapp")); @@ -409,11 +411,11 @@ public void shouldReturnResultWithoutSomeBidsWhenAllAttributesInConfig() { .bapp(asList("app1", "app2")) .battr(singletonMap("impId1", asList(1, 2))) .build(); - final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", accountConfig, blockedAttributes, true); + final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", ORTB_VERSION, accountConfig, blockedAttributes, true); // when and then assertThat(blocker.block()).satisfies(result -> { - assertThat(result.getValue()).isEqualTo(BlockedBids.of(new HashSet<>(asList(0, 1, 3, 5, 7)))); + assertThat(result.getValue()).isEqualTo(BlockedBids.of(Set.of(0, 1, 3, 5, 7))); assertThat(result.getDebugMessages()).containsOnly( "Bid 0 from bidder bidder1 has been rejected, failed checks: [badv, bcat]", "Bid 1 from bidder bidder1 has been rejected, failed checks: [bcat]", @@ -423,6 +425,106 @@ public void shouldReturnResultWithoutSomeBidsWhenAllAttributesInConfig() { }); } + @Test + public void shouldReturnEmptyResultForCattaxIfBidderSupportsLowerThan26() { + // given + final ObjectNode accountConfig = toObjectNode(ModuleConfig.of(Attributes.builder() + .bcat(Attribute.bcatBuilder() + .enforceBlocks(true) + .blockUnknown(false) + .build()) + .build())); + + // when + final List bids = asList( + bid(bid -> bid.cattax(null)), + bid(bid -> bid.cattax(1)), + bid(bid -> bid.cattax(2)), + bid(bid -> bid.cattax(3)), + bid()); + final BlockedAttributes blockedAttributes = BlockedAttributes.builder().build(); + final BidsBlocker blocker = BidsBlocker.create(bids, "bidder1", ORTB_VERSION, accountConfig, blockedAttributes, true); + + // when and then + assertThat(blocker.block()) + .extracting(ExecutionResult::getValue) + .isNull(); + } + + @Test + public void shouldPassBidIfCattaxIsNull() { + // given + final ObjectNode accountConfig = toObjectNode(ModuleConfig.of(Attributes.builder() + .bcat(Attribute.bcatBuilder() + .enforceBlocks(true) + .blockUnknown(false) + .build()) + .build())); + + // when + final List bids = singletonList(bid()); + final BlockedAttributes blockedAttributes = BlockedAttributes.builder().build(); + final BidsBlocker blocker = BidsBlocker.create( + bids, "bidder1", OrtbVersion.ORTB_2_6, accountConfig, blockedAttributes, true); + + // when and then + assertThat(blocker.block()) + .extracting(ExecutionResult::getValue) + .isNull(); + } + + @Test + public void shouldBlockBidIfCattaxNotEqualsAllowedCattax() { + // given + final ObjectNode accountConfig = toObjectNode(ModuleConfig.of(Attributes.builder() + .bcat(Attribute.bcatBuilder() + .enforceBlocks(true) + .blockUnknown(false) + .build()) + .build())); + + // when + final List bids = asList( + bid(bid -> bid.cattax(1)), + bid(bid -> bid.cattax(2))); + final BlockedAttributes blockedAttributes = BlockedAttributes.builder().cattaxComplement(2).build(); + final BidsBlocker blocker = BidsBlocker.create( + bids, "bidder1", OrtbVersion.ORTB_2_6, accountConfig, blockedAttributes, true); + + // when and then + assertThat(blocker.block()).satisfies(result -> { + assertThat(result.getValue()).isEqualTo(BlockedBids.of(Set.of(0))); + assertThat(result.getDebugMessages()).containsExactly( + "Bid 0 from bidder bidder1 has been rejected, failed checks: [cattax]"); + }); + } + + @Test + public void shouldBlockBidIfCattaxNotEquals1IfBlockedAttributesCattaxAbsent() { + // given + final ObjectNode accountConfig = toObjectNode(ModuleConfig.of(Attributes.builder() + .bcat(Attribute.bcatBuilder() + .enforceBlocks(true) + .blockUnknown(false) + .build()) + .build())); + + // when + final List bids = asList( + bid(bid -> bid.cattax(1)), + bid(bid -> bid.cattax(2))); + final BlockedAttributes blockedAttributes = BlockedAttributes.builder().build(); + final BidsBlocker blocker = BidsBlocker.create( + bids, "bidder1", OrtbVersion.ORTB_2_6, accountConfig, blockedAttributes, true); + + // when and then + assertThat(blocker.block()).satisfies(result -> { + assertThat(result.getValue()).isEqualTo(BlockedBids.of(Set.of(1))); + assertThat(result.getDebugMessages()).containsExactly( + "Bid 1 from bidder bidder1 has been rejected, failed checks: [cattax]"); + }); + } + private static BidderBid bid() { return bid(identity()); } @@ -453,7 +555,7 @@ private static void isEmpty(ExecutionResult result) { } private static void hasValue(ExecutionResult result, Integer... indexes) { - assertThat(result.getValue()).isEqualTo(BlockedBids.of(new HashSet<>(asList(indexes)))); + assertThat(result.getValue()).isEqualTo(BlockedBids.of(Set.of(indexes))); assertThat(result.getErrors()).isNull(); assertThat(result.getWarnings()).isNull(); assertThat(result.getDebugMessages()).isNull(); diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BlockedAttributesResolverTest.java b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BlockedAttributesResolverTest.java index 35f1f9555a6..be55ca645a1 100644 --- a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BlockedAttributesResolverTest.java +++ b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BlockedAttributesResolverTest.java @@ -3,13 +3,13 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.node.ObjectNode; import com.iab.openrtb.request.Banner; import com.iab.openrtb.request.BidRequest; import com.iab.openrtb.request.Imp; import com.iab.openrtb.request.Video; -import org.junit.jupiter.api.Test; +import org.junit.Test; +import org.prebid.server.auction.versionconverter.OrtbVersion; import org.prebid.server.hooks.modules.ortb2.blocking.core.config.ArrayOverride; import org.prebid.server.hooks.modules.ortb2.blocking.core.config.Attribute; import org.prebid.server.hooks.modules.ortb2.blocking.core.config.AttributeActionOverrides; @@ -25,18 +25,20 @@ import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; -class BlockedAttributesResolverTest { +public class BlockedAttributesResolverTest { private static final ObjectMapper mapper = new ObjectMapper() .setPropertyNamingStrategy(PropertyNamingStrategies.KEBAB_CASE) .setSerializationInclusion(JsonInclude.Include.NON_NULL); + private static final OrtbVersion ORTB_VERSION = OrtbVersion.ORTB_2_5; + @Test public void shouldReturnEmptyResultWhenInvalidAccountConfigurationAndDebugDisabled() { // given final ObjectNode accountConfig = mapper.createObjectNode().put("block-lists", 1); final BlockedAttributesResolver resolver = BlockedAttributesResolver.create( - emptyRequest(), "bidder1", accountConfig, false); + emptyRequest(), "bidder1", ORTB_VERSION, accountConfig, false); // when and then assertThat(resolver.resolve()).isEqualTo(ExecutionResult.empty()); @@ -47,7 +49,7 @@ public void shouldReturnResultWithErrorWhenInvalidAccountConfiguration() { // given final ObjectNode accountConfig = mapper.createObjectNode().put("attributes", 1); final BlockedAttributesResolver resolver = BlockedAttributesResolver.create( - emptyRequest(), "bidder1", accountConfig, true); + emptyRequest(), "bidder1", ORTB_VERSION, accountConfig, true); // when and then assertThat(resolver.resolve()).isEqualTo( @@ -74,6 +76,7 @@ public void shouldReturnResultWithValueAndWarnings() { .video(Video.builder().build()) .banner(Banner.builder().build())), "bidder1", + ORTB_VERSION, accountConfig, true); @@ -105,6 +108,7 @@ public void shouldReturnResultWithValueAndWarningsWhenDebugDisabled() { .video(Video.builder().build()) .banner(Banner.builder().build())), "bidder1", + ORTB_VERSION, accountConfig, false); diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/RequestUpdaterTest.java b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/RequestUpdaterTest.java index 99da36297b6..b2b3a363a57 100644 --- a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/RequestUpdaterTest.java +++ b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/RequestUpdaterTest.java @@ -3,7 +3,7 @@ import com.iab.openrtb.request.Banner; import com.iab.openrtb.request.BidRequest; import com.iab.openrtb.request.Imp; -import org.junit.jupiter.api.Test; +import org.junit.Test; import org.prebid.server.hooks.modules.ortb2.blocking.core.model.BlockedAttributes; import java.util.List; @@ -13,157 +13,185 @@ import static java.util.Collections.singletonMap; import static org.assertj.core.api.Assertions.assertThat; -class RequestUpdaterTest { +public class RequestUpdaterTest { @Test public void shouldReplaceBadv() { // given final RequestUpdater updater = RequestUpdater.create( - BlockedAttributes.builder().badv(asList("domain1.com", "domain2.com")).build()); + BlockedAttributes.builder().badv(asList("domain1.com", "domain2.com")).build()); final BidRequest request = BidRequest.builder() - .badv(singletonList("overriddendomain1.com")) - .build(); + .badv(singletonList("overriddendomain1.com")) + .build(); // when and then assertThat(updater.update(request)).isEqualTo(BidRequest.builder() - .badv(asList("domain1.com", "domain2.com")) - .build()); + .badv(asList("domain1.com", "domain2.com")) + .build()); } @Test public void shouldKeepBadvWhenNoBlockedBadv() { // given final RequestUpdater updater = RequestUpdater.create( - BlockedAttributes.builder().build()); + BlockedAttributes.builder().build()); final BidRequest request = BidRequest.builder() - .badv(singletonList("domain1.com")) - .build(); + .badv(singletonList("domain1.com")) + .build(); // when and then assertThat(updater.update(request)).isEqualTo(BidRequest.builder() - .badv(singletonList("domain1.com")) - .build()); + .badv(singletonList("domain1.com")) + .build()); } @Test public void shouldReplaceBcat() { // given final RequestUpdater updater = RequestUpdater.create( - BlockedAttributes.builder().bcat(asList("cat1", "cat2")).build()); + BlockedAttributes.builder().bcat(asList("cat1", "cat2")).build()); final BidRequest request = BidRequest.builder() - .bcat(singletonList("overriddencat1")) - .build(); + .bcat(singletonList("overriddencat1")) + .build(); // when and then assertThat(updater.update(request)).isEqualTo(BidRequest.builder() - .bcat(asList("cat1", "cat2")) - .build()); + .bcat(asList("cat1", "cat2")) + .build()); } @Test public void shouldKeepBcatWhenNoBlockedBcat() { // given final RequestUpdater updater = RequestUpdater.create( - BlockedAttributes.builder().build()); + BlockedAttributes.builder().build()); + final BidRequest request = BidRequest.builder() + .bcat(singletonList("cat1")) + .build(); + + // when and then + assertThat(updater.update(request)).isEqualTo(BidRequest.builder() + .bcat(singletonList("cat1")) + .build()); + } + + @Test + public void shouldKeepBcatIfPresent() { + // given + final RequestUpdater updater = RequestUpdater.create( + BlockedAttributes.builder().cattaxComplement(2).build()); final BidRequest request = BidRequest.builder() - .bcat(singletonList("cat1")) - .build(); + .cattax(1) + .build(); // when and then assertThat(updater.update(request)).isEqualTo(BidRequest.builder() - .bcat(singletonList("cat1")) - .build()); + .cattax(1) + .build()); + } + + @Test + public void shouldReplaceBcatIfAbsent() { + // given + final RequestUpdater updater = RequestUpdater.create( + BlockedAttributes.builder().cattaxComplement(2).build()); + final BidRequest request = BidRequest.builder().build(); + + // when and then + assertThat(updater.update(request)).isEqualTo(BidRequest.builder() + .cattax(2) + .build()); } @Test public void shouldReplaceBapp() { // given final RequestUpdater updater = RequestUpdater.create( - BlockedAttributes.builder().bapp(asList("app1", "app2")).build()); + BlockedAttributes.builder().bapp(asList("app1", "app2")).build()); final BidRequest request = BidRequest.builder() - .bapp(singletonList("overriddenapp1")) - .build(); + .bapp(singletonList("overriddenapp1")) + .build(); // when and then assertThat(updater.update(request)).isEqualTo(BidRequest.builder() - .bapp(asList("app1", "app2")) - .build()); + .bapp(asList("app1", "app2")) + .build()); } @Test public void shouldKeepBappWhenNoBlockedBapp() { // given final RequestUpdater updater = RequestUpdater.create( - BlockedAttributes.builder().build()); + BlockedAttributes.builder().build()); final BidRequest request = BidRequest.builder() - .bapp(singletonList("app1")) - .build(); + .bapp(singletonList("app1")) + .build(); // when and then assertThat(updater.update(request)).isEqualTo(BidRequest.builder() - .bapp(singletonList("app1")) - .build()); + .bapp(singletonList("app1")) + .build()); } @Test public void shouldReplaceImpBtype() { // given final RequestUpdater updater = RequestUpdater.create( - BlockedAttributes.builder().btype(singletonMap("impId1", asList(1, 2))).build()); + BlockedAttributes.builder().btype(singletonMap("impId1", asList(1, 2))).build()); final BidRequest request = BidRequest.builder() - .imp(singletonList(Imp.builder() - .id("impId1") - .banner(Banner.builder() - .btype(singletonList(123)) - .build()) - .build())) - .build(); + .imp(singletonList(Imp.builder() + .id("impId1") + .banner(Banner.builder() + .btype(singletonList(123)) + .build()) + .build())) + .build(); // when and then assertThat(updater.update(request)).isEqualTo(BidRequest.builder() - .imp(singletonList(Imp.builder() - .id("impId1") - .banner(Banner.builder() - .btype(asList(1, 2)) - .build()) - .build())) - .build()); + .imp(singletonList(Imp.builder() + .id("impId1") + .banner(Banner.builder() + .btype(asList(1, 2)) + .build()) + .build())) + .build()); } @Test public void shouldReplaceImpBattr() { // given final RequestUpdater updater = RequestUpdater.create( - BlockedAttributes.builder().battr(singletonMap("impId1", asList(1, 2))).build()); + BlockedAttributes.builder().battr(singletonMap("impId1", asList(1, 2))).build()); final BidRequest request = BidRequest.builder() - .imp(singletonList(Imp.builder() - .id("impId1") - .banner(Banner.builder() - .battr(singletonList(123)) - .build()) - .build())) - .build(); + .imp(singletonList(Imp.builder() + .id("impId1") + .banner(Banner.builder() + .battr(singletonList(123)) + .build()) + .build())) + .build(); // when and then assertThat(updater.update(request)).isEqualTo(BidRequest.builder() - .imp(singletonList(Imp.builder() - .id("impId1") - .banner(Banner.builder() - .battr(asList(1, 2)) - .build()) - .build())) - .build()); + .imp(singletonList(Imp.builder() + .id("impId1") + .banner(Banner.builder() + .battr(asList(1, 2)) + .build()) + .build())) + .build()); } @Test public void shouldNotChangeImpsWhenNoBlockedBannerTypeAndBlockedBannerAttr() { // given final RequestUpdater updater = RequestUpdater.create( - BlockedAttributes.builder().build()); + BlockedAttributes.builder().build()); final List imps = singletonList(Imp.builder().build()); final BidRequest request = BidRequest.builder() - .imp(imps) - .build(); + .imp(imps) + .build(); // when and then assertThat(updater.update(request).getImp()).isSameAs(imps); @@ -173,14 +201,14 @@ public void shouldNotChangeImpsWhenNoBlockedBannerTypeAndBlockedBannerAttr() { public void shouldNotChangeImpWhenNoBlockedBannerTypeAndBlockedBannerAttrForImp() { // given final RequestUpdater updater = RequestUpdater.create( - BlockedAttributes.builder() - .btype(singletonMap("impId2", singletonList(1))) - .battr(singletonMap("impId2", singletonList(1))) - .build()); + BlockedAttributes.builder() + .btype(singletonMap("impId2", singletonList(1))) + .battr(singletonMap("impId2", singletonList(1))) + .build()); final Imp imp = Imp.builder().build(); final BidRequest request = BidRequest.builder() - .imp(singletonList(imp)) - .build(); + .imp(singletonList(imp)) + .build(); // when and then final BidRequest updatedRequest = updater.update(request); @@ -192,83 +220,83 @@ public void shouldNotChangeImpWhenNoBlockedBannerTypeAndBlockedBannerAttrForImp( public void shouldKeepImpBtypeWhenNoBlockedBannerTypeAndPresentBlockedBannerAttrForImp() { // given final RequestUpdater updater = RequestUpdater.create( - BlockedAttributes.builder() - .battr(singletonMap("impId1", singletonList(1))) - .build()); + BlockedAttributes.builder() + .battr(singletonMap("impId1", singletonList(1))) + .build()); final Imp imp = Imp.builder() - .id("impId1") - .banner(Banner.builder().btype(singletonList(1000)).build()) - .build(); + .id("impId1") + .banner(Banner.builder().btype(singletonList(1000)).build()) + .build(); final BidRequest request = BidRequest.builder() - .imp(singletonList(imp)) - .build(); + .imp(singletonList(imp)) + .build(); // when and then assertThat(updater.update(request)).isEqualTo(BidRequest.builder() - .imp(singletonList(Imp.builder() - .id("impId1") - .banner(Banner.builder() - .btype(singletonList(1000)) - .battr(singletonList(1)) - .build()) - .build())) - .build()); + .imp(singletonList(Imp.builder() + .id("impId1") + .banner(Banner.builder() + .btype(singletonList(1000)) + .battr(singletonList(1)) + .build()) + .build())) + .build()); } @Test public void shouldKeepImpBattrWhenNoBlockedBannerAttrAndPresentBlockedBannerTypeForImp() { // given final RequestUpdater updater = RequestUpdater.create( - BlockedAttributes.builder() - .btype(singletonMap("impId1", singletonList(1))) - .build()); + BlockedAttributes.builder() + .btype(singletonMap("impId1", singletonList(1))) + .build()); final Imp imp = Imp.builder() - .id("impId1") - .banner(Banner.builder().battr(singletonList(1000)).build()) - .build(); + .id("impId1") + .banner(Banner.builder().battr(singletonList(1000)).build()) + .build(); final BidRequest request = BidRequest.builder() - .imp(singletonList(imp)) - .build(); + .imp(singletonList(imp)) + .build(); // when and then assertThat(updater.update(request)).isEqualTo(BidRequest.builder() - .imp(singletonList(Imp.builder() - .id("impId1") - .banner(Banner.builder() - .btype(singletonList(1)) - .battr(singletonList(1000)) - .build()) - .build())) - .build()); + .imp(singletonList(Imp.builder() + .id("impId1") + .banner(Banner.builder() + .btype(singletonList(1)) + .battr(singletonList(1000)) + .build()) + .build())) + .build()); } @Test public void shouldUpdateAllAttributes() { // given final RequestUpdater updater = RequestUpdater.create( - BlockedAttributes.builder() - .badv(asList("domain1.com", "domain2.com")) - .bcat(asList("cat1", "cat2")) - .bapp(asList("app1", "app2")) - .btype(singletonMap("impId1", asList(1, 2))) - .battr(singletonMap("impId1", asList(1, 2))) - .build()); + BlockedAttributes.builder() + .badv(asList("domain1.com", "domain2.com")) + .bcat(asList("cat1", "cat2")) + .bapp(asList("app1", "app2")) + .btype(singletonMap("impId1", asList(1, 2))) + .battr(singletonMap("impId1", asList(1, 2))) + .build()); final BidRequest request = BidRequest.builder() - .imp(singletonList(Imp.builder().id("impId1").build())) - .build(); + .imp(singletonList(Imp.builder().id("impId1").build())) + .build(); // when and then assertThat(updater.update(request)).isEqualTo(BidRequest.builder() - .badv(asList("domain1.com", "domain2.com")) - .bcat(asList("cat1", "cat2")) - .bapp(asList("app1", "app2")) - .imp(singletonList(Imp.builder() - .id("impId1") - .banner(Banner.builder() - .btype(asList(1, 2)) - .battr(asList(1, 2)) - .build()) - .build())) - .build()); + .badv(asList("domain1.com", "domain2.com")) + .bcat(asList("cat1", "cat2")) + .bapp(asList("app1", "app2")) + .imp(singletonList(Imp.builder() + .id("impId1") + .banner(Banner.builder() + .btype(asList(1, 2)) + .battr(asList(1, 2)) + .build()) + .build())) + .build()); } } diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/ResponseUpdaterTest.java b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/ResponseUpdaterTest.java index 08320e953b8..279201043c5 100644 --- a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/ResponseUpdaterTest.java +++ b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/ResponseUpdaterTest.java @@ -1,7 +1,7 @@ package org.prebid.server.hooks.modules.ortb2.blocking.core; import com.iab.openrtb.response.Bid; -import org.junit.jupiter.api.Test; +import org.junit.Test; import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.hooks.modules.ortb2.blocking.core.model.BlockedBids; import org.prebid.server.proto.openrtb.ext.response.BidType; @@ -12,23 +12,23 @@ import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; -class ResponseUpdaterTest { +public class ResponseUpdaterTest { @Test public void shouldRemoveSpecifiedBids() { // given final ResponseUpdater updater = ResponseUpdater.create(BlockedBids.of(new HashSet<>(asList(1, 2, 4)))); final List bids = asList( - bid("bid1", BidType.banner, "USD"), - bid("bid2", BidType.video, "USD"), - bid("bid3", BidType.audio, "EUR"), - bid("bid4", BidType.xNative, "JPY"), - bid("bid5", BidType.video, "UAH")); + bid("bid1", BidType.banner, "USD"), + bid("bid2", BidType.video, "USD"), + bid("bid3", BidType.audio, "EUR"), + bid("bid4", BidType.xNative, "JPY"), + bid("bid5", BidType.video, "UAH")); // when and then assertThat(updater.update(bids)).isEqualTo(asList( - bid("bid1", BidType.banner, "USD"), - bid("bid4", BidType.xNative, "JPY"))); + bid("bid1", BidType.banner, "USD"), + bid("bid4", BidType.xNative, "JPY"))); } private static BidderBid bid(String id, BidType type, String currency) { diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/model/ModuleContextTest.java b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/model/ModuleContextTest.java index 1a96bbd1b16..3c773aaed45 100644 --- a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/model/ModuleContextTest.java +++ b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/model/ModuleContextTest.java @@ -1,6 +1,7 @@ package org.prebid.server.hooks.modules.ortb2.blocking.model; -import org.junit.jupiter.api.Test; +import org.junit.Test; +import org.prebid.server.auction.versionconverter.OrtbVersion; import org.prebid.server.hooks.modules.ortb2.blocking.core.model.BlockedAttributes; import java.util.List; @@ -8,37 +9,35 @@ import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; -class ModuleContextTest { +public class ModuleContextTest { - @Test - public void shouldCreateContextWithMapping() { - // given - final BlockedAttributes blockedAttributes = attributes(singletonList("domain1.com")); - - // when - final ModuleContext context = ModuleContext.create("bidder1", blockedAttributes); - - // then - assertThat(context.blockedAttributesFor("bidder1")).isSameAs(blockedAttributes); - } + private final ModuleContext emptyContext = ModuleContext.create(); @Test public void shouldCreateContextWithAdditionalMapping() { // given final BlockedAttributes bidder1BlockedAttributes = attributes(singletonList("domain1.com")); - final ModuleContext initialContext = ModuleContext.create("bidder1", bidder1BlockedAttributes); + final ModuleContext initialContext = emptyContext + .with("bidder1", OrtbVersion.ORTB_2_6) + .with("bidder1", bidder1BlockedAttributes); final BlockedAttributes bidder2BlockedAttributes = attributes(singletonList("domain2.com")); // when - final ModuleContext context = initialContext.with("bidder2", bidder2BlockedAttributes); + final ModuleContext context = initialContext + .with("bidder2", OrtbVersion.ORTB_2_5) + .with("bidder2", bidder2BlockedAttributes); // then + assertThat(context.ortbVersionOf("bidder1")).isSameAs(OrtbVersion.ORTB_2_6); assertThat(context.blockedAttributesFor("bidder1")).isSameAs(bidder1BlockedAttributes); + assertThat(context.ortbVersionOf("bidder2")).isSameAs(OrtbVersion.ORTB_2_5); assertThat(context.blockedAttributesFor("bidder2")).isSameAs(bidder2BlockedAttributes); // initial context shouldn't change + assertThat(initialContext.ortbVersionOf("bidder1")).isSameAs(OrtbVersion.ORTB_2_6); assertThat(initialContext.blockedAttributesFor("bidder1")).isSameAs(bidder1BlockedAttributes); + assertThat(initialContext.ortbVersionOf("bidder2")).isNull(); assertThat(initialContext.blockedAttributesFor("bidder2")).isNull(); } @@ -46,17 +45,23 @@ public void shouldCreateContextWithAdditionalMapping() { public void shouldCreateContextWithReplacedMapping() { // given final BlockedAttributes initialBlockedAttributes = attributes(singletonList("domain1.com")); - final ModuleContext initialContext = ModuleContext.create("bidder1", initialBlockedAttributes); + final ModuleContext initialContext = emptyContext + .with("bidder1", OrtbVersion.ORTB_2_5) + .with("bidder1", initialBlockedAttributes); final BlockedAttributes replacementBlockedAttributes = attributes(singletonList("domain2com")); // when - final ModuleContext context = initialContext.with("bidder1", replacementBlockedAttributes); + final ModuleContext context = initialContext + .with("bidder1", OrtbVersion.ORTB_2_6) + .with("bidder1", replacementBlockedAttributes); // then + assertThat(context.ortbVersionOf("bidder1")).isSameAs(OrtbVersion.ORTB_2_6); assertThat(context.blockedAttributesFor("bidder1")).isSameAs(replacementBlockedAttributes); // initial context shouldn't change + assertThat(initialContext.ortbVersionOf("bidder1")).isSameAs(OrtbVersion.ORTB_2_5); assertThat(initialContext.blockedAttributesFor("bidder1")).isSameAs(initialBlockedAttributes); } diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHookTest.java b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHookTest.java index 95982c59e6f..233760cfabc 100644 --- a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHookTest.java +++ b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHookTest.java @@ -3,14 +3,21 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.node.ObjectNode; import com.iab.openrtb.request.BidRequest; import com.iab.openrtb.request.Imp; import com.iab.openrtb.request.Video; import io.vertx.core.Future; import org.assertj.core.api.InstanceOfAssertFactories; -import org.junit.jupiter.api.Test; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.prebid.server.auction.versionconverter.OrtbVersion; +import org.prebid.server.bidder.BidderCatalog; +import org.prebid.server.bidder.BidderInfo; import org.prebid.server.hooks.modules.ortb2.blocking.core.config.ArrayOverride; import org.prebid.server.hooks.modules.ortb2.blocking.core.config.Attribute; import org.prebid.server.hooks.modules.ortb2.blocking.core.config.AttributeActionOverrides; @@ -32,14 +39,30 @@ import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.SoftAssertions.assertSoftly; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; -class Ortb2BlockingBidderRequestHookTest { +public class Ortb2BlockingBidderRequestHookTest { private static final ObjectMapper mapper = new ObjectMapper() .setPropertyNamingStrategy(PropertyNamingStrategies.KEBAB_CASE) .setSerializationInclusion(JsonInclude.Include.NON_NULL); - private final Ortb2BlockingBidderRequestHook hook = new Ortb2BlockingBidderRequestHook(); + @Rule + public final MockitoRule mockitoRule = MockitoJUnit.rule(); + + @Mock + private BidderCatalog bidderCatalog; + + private Ortb2BlockingBidderRequestHook hook; + + @Before + public void setUp() { + given(bidderCatalog.bidderInfoByName(anyString())) + .willReturn(bidderInfo(OrtbVersion.ORTB_2_5)); + + hook = new Ortb2BlockingBidderRequestHook(bidderCatalog); + } @Test public void shouldReturnResultWithNoActionWhenNoBlockingAttributes() { @@ -53,6 +76,7 @@ public void shouldReturnResultWithNoActionWhenNoBlockingAttributes() { assertThat(result.result()).isEqualTo(InvocationResultImpl.builder() .status(InvocationStatus.success) .action(InvocationAction.no_action) + .moduleContext(ModuleContext.create().with("bidder1", OrtbVersion.ORTB_2_5)) .build()); } @@ -72,6 +96,7 @@ public void shouldReturnResultWithNoActionAndErrorWhenInvalidAccountConfig() { assertThat(result.result()).isEqualTo(InvocationResultImpl.builder() .status(InvocationStatus.success) .action(InvocationAction.no_action) + .moduleContext(ModuleContext.create().with("bidder1", OrtbVersion.ORTB_2_5)) .errors(singletonList("attributes field in account configuration is not an object")) .build()); } @@ -92,6 +117,7 @@ public void shouldReturnResultWithNoActionAndNoErrorWhenInvalidAccountConfigAndD assertThat(result.result()).isEqualTo(InvocationResultImpl.builder() .status(InvocationStatus.success) .action(InvocationAction.no_action) + .moduleContext(ModuleContext.create().with("bidder1", OrtbVersion.ORTB_2_5)) .build()); } @@ -122,11 +148,14 @@ public void shouldReturnResultWithModuleContextAndPayloadUpdate() { .isNotNull() .isInstanceOf(ModuleContext.class) .asInstanceOf(InstanceOfAssertFactories.type(ModuleContext.class)) - .satisfies(context -> assertThat(context.blockedAttributesFor("bidder1")) - .isEqualTo(BlockedAttributes.builder() - .badv(singletonList("domain1.com")) - .bcat(singletonList("cat1")) - .build())); + .satisfies(context -> { + assertThat(context.ortbVersionOf("bidder1")).isSameAs(OrtbVersion.ORTB_2_5); + assertThat(context.blockedAttributesFor("bidder1")) + .isEqualTo(BlockedAttributes.builder() + .badv(singletonList("domain1.com")) + .bcat(singletonList("cat1")) + .build()); + }); softly.assertThat(invocationResult.warnings()).isNull(); softly.assertThat(invocationResult.errors()).isNull(); }); @@ -217,6 +246,23 @@ public void shouldReturnResultWithUpdateActionAndNoWarningWhenDebugDisabled() { }); } + private static BidderInfo bidderInfo(OrtbVersion ortbVersion) { + return BidderInfo.create( + true, + ortbVersion, + false, + null, + null, + null, + null, + null, + null, + 0, + false, + false, + null); + } + private static BidRequest emptyRequest() { return BidRequest.builder() .imp(singletonList(Imp.builder().video(Video.builder().build()).build())) diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHookTest.java b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHookTest.java index ffd335e59a0..7407d1d1ba4 100644 --- a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHookTest.java +++ b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHookTest.java @@ -3,11 +3,10 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.node.ObjectNode; import com.iab.openrtb.response.Bid; import io.vertx.core.Future; -import org.junit.jupiter.api.Test; +import org.junit.Test; import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.hooks.modules.ortb2.blocking.core.config.Attribute; import org.prebid.server.hooks.modules.ortb2.blocking.core.config.AttributeActionOverrides; @@ -29,6 +28,7 @@ import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.PayloadUpdate; import org.prebid.server.hooks.v1.bidder.BidderResponsePayload; +import org.prebid.server.json.ObjectMapperProvider; import org.prebid.server.proto.openrtb.ext.response.BidType; import java.util.function.UnaryOperator; @@ -39,13 +39,14 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.SoftAssertions.assertSoftly; -class Ortb2BlockingRawBidderResponseHookTest { +public class Ortb2BlockingRawBidderResponseHookTest { private static final ObjectMapper mapper = new ObjectMapper() .setPropertyNamingStrategy(PropertyNamingStrategies.KEBAB_CASE) .setSerializationInclusion(JsonInclude.Include.NON_NULL); - private final Ortb2BlockingRawBidderResponseHook hook = new Ortb2BlockingRawBidderResponseHook(); + private final Ortb2BlockingRawBidderResponseHook hook = new Ortb2BlockingRawBidderResponseHook( + ObjectMapperProvider.mapper()); @Test public void shouldReturnResultWithNoActionWhenNoBidsBlocked() { @@ -59,6 +60,7 @@ public void shouldReturnResultWithNoActionWhenNoBidsBlocked() { assertThat(result.result()).isEqualTo(InvocationResultImpl.builder() .status(InvocationStatus.success) .action(InvocationAction.no_action) + .moduleContext(ModuleContext.create()) .analyticsTags(TagsImpl.of(singletonList(ActivityImpl.of( "enforce-blocking", "success", @@ -88,6 +90,7 @@ public void shouldReturnResultWithNoActionAndErrorWhenInvalidAccountConfig() { assertThat(result.result()).isEqualTo(InvocationResultImpl.builder() .status(InvocationStatus.success) .action(InvocationAction.no_action) + .moduleContext(ModuleContext.create()) .errors(singletonList("attributes field in account configuration is not an object")) .build()); } @@ -108,6 +111,7 @@ public void shouldReturnResultWithNoActionAndNoErrorWhenInvalidAccountConfigAndD assertThat(result.result()).isEqualTo(InvocationResultImpl.builder() .status(InvocationStatus.success) .action(InvocationAction.no_action) + .moduleContext(ModuleContext.create()) .build()); } @@ -130,7 +134,7 @@ public void shouldReturnResultWithPayloadUpdateAndAnalyticsTags() { BidderInvocationContextImpl.builder() .bidder("bidder1") .accountConfig(accountConfig) - .moduleContext(ModuleContext.create( + .moduleContext(ModuleContext.create().with( "bidder1", BlockedAttributes.builder().badv(singletonList("domain2.com")).build())) .debugEnabled(true) .build()); diff --git a/extra/modules/pom.xml b/extra/modules/pom.xml index 403ea8a205b..c4d104240ee 100644 --- a/extra/modules/pom.xml +++ b/extra/modules/pom.xml @@ -33,6 +33,8 @@ 5.7.2 3.20.2 + 4.13.2 + 4.0.0 3.10.1 2.22.1 @@ -62,6 +64,16 @@ assertj-core ${assertj.version} + + junit + junit + ${junit.version} + + + org.mockito + mockito-core + ${mockito.version} + @@ -85,6 +97,16 @@ assertj-core test + + junit + junit + test + + + org.mockito + mockito-core + test + diff --git a/src/main/java/org/prebid/server/auction/ExchangeService.java b/src/main/java/org/prebid/server/auction/ExchangeService.java index c36c9bb45d8..79609900ed6 100644 --- a/src/main/java/org/prebid/server/auction/ExchangeService.java +++ b/src/main/java/org/prebid/server/auction/ExchangeService.java @@ -40,6 +40,7 @@ import org.prebid.server.auction.model.StoredResponseResult; import org.prebid.server.auction.model.Tuple2; import org.prebid.server.auction.versionconverter.BidRequestOrtbVersionConversionManager; +import org.prebid.server.auction.versionconverter.OrtbVersion; import org.prebid.server.bidder.Bidder; import org.prebid.server.bidder.BidderCatalog; import org.prebid.server.bidder.HttpBidderRequester; @@ -273,12 +274,12 @@ private Future runAuction(AuctionContext receivedContext) { return storedResponseProcessor.getStoredResponseResult(bidRequest.getImp(), timeout) .map(storedResponseResult -> populateStoredResponse(storedResponseResult, storedAuctionResponses)) - .compose(storedResponseResult -> extractAuctionParticipation( + .compose(storedResponseResult -> extractAuctionParticipations( receivedContext, storedResponseResult, aliases, bidderToMultiBid)) - .map(auctionParticipation -> updateRequestMetric( - auctionParticipation, uidsCookie, aliases, account, requestTypeMetric)) - .map(bidderRequests -> maybeLogBidderInteraction(receivedContext, bidderRequests)) + .map(auctionParticipations -> updateRequestMetric( + auctionParticipations, uidsCookie, aliases, account, requestTypeMetric)) + .map(auctionParticipations -> maybeLogBidderInteraction(receivedContext, auctionParticipations)) .compose(auctionParticipations -> CompositeFuture.join( auctionParticipations.stream() .map(auctionParticipation -> invokeHooksAndRequestBids( @@ -483,7 +484,7 @@ private static StoredResponseResult populateStoredResponse(StoredResponseResult * NOTE: the return list will only contain entries for bidders that both have the extension field in at least one * {@link Imp}, and are known to {@link BidderCatalog} or aliases from bidRequest.ext.prebid.aliases. */ - private Future> extractAuctionParticipation( + private Future> extractAuctionParticipations( AuctionContext context, StoredResponseResult storedResponseResult, BidderAliases aliases, @@ -836,6 +837,8 @@ private AuctionParticipation createAuctionParticipation( .build(); } + final OrtbVersion ortbVersion = bidderSupportedOrtbVersion(bidder, bidderAliases); + final List firstPartyDataBidders = firstPartyDataBidders(bidRequest.getExt()); final boolean useFirstPartyData = firstPartyDataBidders == null || firstPartyDataBidders.contains(bidder); @@ -857,7 +860,7 @@ private AuctionParticipation createAuctionParticipation( ? impBidderToStoredBidResponse.get(imps.get(0).getId()).get(bidder) : null; - final BidderRequest bidderRequest = BidderRequest.of(bidder, storedBidResponse, bidRequest.toBuilder() + final BidRequest modifiedBidRequest = bidRequest.toBuilder() // User was already prepared above .user(bidderPrivacyResult.getUser()) .device(bidderPrivacyResult.getDevice()) @@ -866,7 +869,13 @@ private AuctionParticipation createAuctionParticipation( .site(prepareSite(resolvedSite, fpdSite, useFirstPartyData)) .source(prepareSource(bidder, bidRequest)) .ext(prepareExt(bidder, bidderToPrebidBidders, bidderToMultiBid, bidRequest.getExt())) - .build()); + .build(); + + final BidderRequest bidderRequest = BidderRequest.of( + bidder, + ortbVersion, + storedBidResponse, + modifiedBidRequest); return AuctionParticipation.builder() .bidder(bidder) @@ -876,6 +885,10 @@ private AuctionParticipation createAuctionParticipation( .build(); } + private OrtbVersion bidderSupportedOrtbVersion(String bidder, BidderAliases aliases) { + return bidderCatalog.bidderInfoByName(aliases.resolveBidder(bidder)).getOrtbVersion(); + } + /** * For each given imp creates a new imp with extension crafted to contain only "prebid", "context" and * bidder-specific extension. @@ -1263,8 +1276,8 @@ private Future requestBids(BidderRequest bidderRequest, return Future.succeededFuture(BidderResponse.of(bidderName, bidderSeatBid, 0)); } - final BidRequest convertedBidRequest = ortbVersionConversionManager.convertToBidderSupportedVersion( - mediaTypeProcessingResult.getBidRequest(), resolvedBidderName); + final BidRequest convertedBidRequest = ortbVersionConversionManager.convertFromAuctionSupportedVersion( + mediaTypeProcessingResult.getBidRequest(), bidderRequest.getOrtbVersion()); final BidderRequest modifiedBidderRequest = bidderRequest.with(convertedBidRequest); @@ -1563,6 +1576,7 @@ private List maybeLogBidderInteraction(AuctionContext cont private List updateMetricsFromResponses(List auctionParticipations, Account account, BidderAliases aliases) { + final List bidderResponses = auctionParticipations.stream() .filter(auctionParticipation -> !auctionParticipation.isRequestBlocked()) .map(AuctionParticipation::getBidderResponse) diff --git a/src/main/java/org/prebid/server/auction/model/BidderRequest.java b/src/main/java/org/prebid/server/auction/model/BidderRequest.java index 560837cfd7a..95a31c0a941 100644 --- a/src/main/java/org/prebid/server/auction/model/BidderRequest.java +++ b/src/main/java/org/prebid/server/auction/model/BidderRequest.java @@ -2,6 +2,7 @@ import com.iab.openrtb.request.BidRequest; import lombok.Value; +import org.prebid.server.auction.versionconverter.OrtbVersion; /** * Structure to pass {@link BidRequest} along with the bidder name @@ -11,11 +12,13 @@ public class BidderRequest { String bidder; + OrtbVersion ortbVersion; + String storedResponse; BidRequest bidRequest; public BidderRequest with(BidRequest bidRequest) { - return of(this.bidder, this.storedResponse, bidRequest); + return of(this.bidder, this.ortbVersion, this.storedResponse, bidRequest); } } diff --git a/src/main/java/org/prebid/server/auction/versionconverter/BidRequestOrtbVersionConversionManager.java b/src/main/java/org/prebid/server/auction/versionconverter/BidRequestOrtbVersionConversionManager.java index fc04ac35654..fae8260b1ae 100644 --- a/src/main/java/org/prebid/server/auction/versionconverter/BidRequestOrtbVersionConversionManager.java +++ b/src/main/java/org/prebid/server/auction/versionconverter/BidRequestOrtbVersionConversionManager.java @@ -1,7 +1,6 @@ package org.prebid.server.auction.versionconverter; import com.iab.openrtb.request.BidRequest; -import org.prebid.server.bidder.BidderCatalog; import java.util.Objects; @@ -10,13 +9,9 @@ public class BidRequestOrtbVersionConversionManager { private static final OrtbVersion MINIMAL_SUPPORTED_VERSION = OrtbVersion.ORTB_2_5; private static final OrtbVersion AUCTION_VERSION = OrtbVersion.ORTB_2_6; - private final BidderCatalog bidderCatalog; private final BidRequestOrtbVersionConverterFactory ortbVersionConverterFactory; - public BidRequestOrtbVersionConversionManager(BidderCatalog bidderCatalog, - BidRequestOrtbVersionConverterFactory ortbVersionConverterFactory) { - - this.bidderCatalog = Objects.requireNonNull(bidderCatalog); + public BidRequestOrtbVersionConversionManager(BidRequestOrtbVersionConverterFactory ortbVersionConverterFactory) { this.ortbVersionConverterFactory = Objects.requireNonNull(ortbVersionConverterFactory); } @@ -26,9 +21,9 @@ public BidRequest convertToAuctionSupportedVersion(BidRequest bidRequest) { .convert(bidRequest); } - public BidRequest convertToBidderSupportedVersion(BidRequest bidRequest, String bidderName) { + public BidRequest convertFromAuctionSupportedVersion(BidRequest bidRequest, OrtbVersion ortbVersion) { return ortbVersionConverterFactory - .getConverter(AUCTION_VERSION, bidderCatalog.bidderInfoByName(bidderName).getOrtbVersion()) + .getConverter(AUCTION_VERSION, ortbVersion) .convert(bidRequest); } } diff --git a/src/main/java/org/prebid/server/spring/config/ServiceConfiguration.java b/src/main/java/org/prebid/server/spring/config/ServiceConfiguration.java index 0837d27debd..dee3006e154 100644 --- a/src/main/java/org/prebid/server/spring/config/ServiceConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/ServiceConfiguration.java @@ -246,12 +246,9 @@ BidRequestOrtbVersionConverterFactory bidRequestOrtbVersionConverterFactory(Jack @Bean BidRequestOrtbVersionConversionManager bidRequestOrtbVersionConversionManager( - BidderCatalog bidderCatalog, BidRequestOrtbVersionConverterFactory bidRequestOrtbVersionConverterFactory) { - return new BidRequestOrtbVersionConversionManager( - bidderCatalog, - bidRequestOrtbVersionConverterFactory); + return new BidRequestOrtbVersionConversionManager(bidRequestOrtbVersionConverterFactory); } @Bean diff --git a/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java b/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java index ec9211c4706..85dfbe35fba 100644 --- a/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java +++ b/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java @@ -56,6 +56,7 @@ import org.prebid.server.auction.versionconverter.BidRequestOrtbVersionConversionManager; import org.prebid.server.bidder.Bidder; import org.prebid.server.bidder.BidderCatalog; +import org.prebid.server.bidder.BidderInfo; import org.prebid.server.bidder.HttpBidderRequester; import org.prebid.server.bidder.Usersyncer; import org.prebid.server.bidder.model.BidderBid; @@ -142,6 +143,7 @@ import org.prebid.server.settings.model.Account; import org.prebid.server.settings.model.AccountAuctionConfig; import org.prebid.server.settings.model.AccountEventsConfig; +import org.prebid.server.spring.config.bidder.model.CompressionType; import org.prebid.server.validation.ResponseBidValidator; import org.prebid.server.validation.model.ValidationResult; @@ -284,6 +286,20 @@ public void setUp() { given(bidderCatalog.isValidName(anyString())).willReturn(true); given(bidderCatalog.isActive(anyString())).willReturn(true); given(bidderCatalog.usersyncerByName(anyString())).willReturn(Usersyncer.of("cookieFamily", null, null)); + given(bidderCatalog.bidderInfoByName(anyString())).willReturn(BidderInfo.create( + true, + null, + false, + null, + null, + null, + null, + null, + null, + 0, + false, + false, + CompressionType.NONE)); given(privacyEnforcementService.mask(any(), argThat(MapUtils::isNotEmpty), any(), any())) .willAnswer(inv -> @@ -342,7 +358,7 @@ public void setUp() { given(criteriaLogManager.traceResponse(any(), any(), any(), anyBoolean())) .willAnswer(inv -> inv.getArgument(1)); - given(ortbVersionConversionManager.convertToBidderSupportedVersion(any(), anyString())) + given(ortbVersionConversionManager.convertFromAuctionSupportedVersion(any(), any())) .willAnswer(invocation -> invocation.getArgument(0)); clock = Clock.fixed(Instant.now(), ZoneId.systemDefault()); @@ -1012,7 +1028,7 @@ public void shouldTolerateBidderResultWithoutBids() { public void shouldReturnSeparateSeatBidsForTheSameBidderIfBiddersAliasAndBidderWereUsedWithinSingleImp() { // given given(httpBidderRequester.requestBids(any(), - eq(BidderRequest.of("bidder", null, givenBidRequest( + eq(BidderRequest.of("bidder", null, null, givenBidRequest( singletonList(givenImp( null, builder -> builder.ext(mapper.valueToTree( @@ -1025,7 +1041,7 @@ public void shouldReturnSeparateSeatBidsForTheSameBidderIfBiddersAliasAndBidderW givenBid(Bid.builder().impid("impId1").price(BigDecimal.ONE).build()))))); given(httpBidderRequester.requestBids(any(), - eq(BidderRequest.of("bidderAlias", null, givenBidRequest( + eq(BidderRequest.of("bidderAlias", null, null, givenBidRequest( singletonList(givenImp( null, builder -> builder.ext(mapper.valueToTree( @@ -4382,7 +4398,7 @@ public void shouldResponseWithEmptySeatBidIfBidderNotSupportProvidedMediaTypes() @Test public void shouldConvertBidRequestOpenRTBVersionToConfiguredByBidder() { // given - given(ortbVersionConversionManager.convertToBidderSupportedVersion(any(), anyString())).willAnswer( + given(ortbVersionConversionManager.convertFromAuctionSupportedVersion(any(), any())).willAnswer( invocation -> ((BidRequest) invocation.getArgument(0)) .toBuilder() .source(null) diff --git a/src/test/java/org/prebid/server/auction/StoredResponseProcessorTest.java b/src/test/java/org/prebid/server/auction/StoredResponseProcessorTest.java index 64bc4acd97f..ca2bc656025 100644 --- a/src/test/java/org/prebid/server/auction/StoredResponseProcessorTest.java +++ b/src/test/java/org/prebid/server/auction/StoredResponseProcessorTest.java @@ -361,7 +361,7 @@ public void updateStoredBidResponseShouldTolerateMissingBidImpId() { final BidRequest bidRequest = BidRequest.builder() .imp(singletonList(Imp.builder().id("imp1").build())) .build(); - final BidderRequest bidderRequest = BidderRequest.of("rubicon", "storedresponse", bidRequest); + final BidderRequest bidderRequest = BidderRequest.of("rubicon", null, "storedresponse", bidRequest); final BidderResponse bidderResponse = BidderResponse.of( "rubicon", @@ -389,7 +389,7 @@ public void updateStoredBidResponseShouldNotModifyParticipationWithMoreThanOneIm final BidRequest bidRequest = BidRequest.builder() .imp(List.of(Imp.builder().build(), Imp.builder().build())) .build(); - final BidderRequest bidderRequest = BidderRequest.of("rubicon", "storedresponse", bidRequest); + final BidderRequest bidderRequest = BidderRequest.of("rubicon", null, "storedresponse", bidRequest); final BidderResponse bidderResponse = BidderResponse.of( "rubicon", @@ -417,7 +417,7 @@ public void updateStoredBidResponseShouldReplaceAllBidImpIdMacrosForStoredRespon final BidRequest bidRequest = BidRequest.builder() .imp(singletonList(Imp.builder().id("impId").build())) .build(); - final BidderRequest bidderRequest = BidderRequest.of("rubicon", "storedresponse", bidRequest); + final BidderRequest bidderRequest = BidderRequest.of("rubicon", null, "storedresponse", bidRequest); final List bids = List.of( BidderBid.of(Bid.builder().impid("##PBSIMPID##").build(), BidType.banner, "USD"), diff --git a/src/test/java/org/prebid/server/auction/versionconverter/BidRequestConversionManagerTest.java b/src/test/java/org/prebid/server/auction/versionconverter/BidRequestConversionManagerTest.java index 411360b3480..fba8b4b076e 100644 --- a/src/test/java/org/prebid/server/auction/versionconverter/BidRequestConversionManagerTest.java +++ b/src/test/java/org/prebid/server/auction/versionconverter/BidRequestConversionManagerTest.java @@ -8,9 +8,6 @@ import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.prebid.server.VertxTest; -import org.prebid.server.bidder.BidderCatalog; -import org.prebid.server.bidder.BidderInfo; -import org.prebid.server.spring.config.bidder.model.CompressionType; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.eq; @@ -21,8 +18,6 @@ public class BidRequestConversionManagerTest extends VertxTest { @Rule public final MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private BidderCatalog bidderCatalog; @Mock private BidRequestOrtbVersionConverterFactory ortbVersionConverterFactory; @@ -35,8 +30,7 @@ public void setUp() { given(ortbVersionConverterFactory.getConverter(eq(OrtbVersion.ORTB_2_5), eq(OrtbVersion.ORTB_2_6))) .willReturn(bidRequest -> bidRequest.toBuilder().id("2.6").build()); - ortbVersionConversionManager = new BidRequestOrtbVersionConversionManager( - bidderCatalog, ortbVersionConverterFactory); + ortbVersionConversionManager = new BidRequestOrtbVersionConversionManager(ortbVersionConverterFactory); } @Test @@ -54,28 +48,13 @@ public void convertToAuctionSupportedVersionShouldConvertToExpectedVersion() { } @Test - public void convertToBidderSupportedVersionShouldConvertToExpectedVersion() { + public void convertFromAuctionSupportedVersionShouldConvertToExpectedVersion() { // given - given(bidderCatalog.bidderInfoByName(eq("bidder"))) - .willReturn(BidderInfo.create( - true, - OrtbVersion.ORTB_2_5, - false, - null, - null, - null, - null, - null, - null, - 0, - false, - false, - CompressionType.NONE)); - final BidRequest bidRequest = BidRequest.builder().build(); // when - final BidRequest result = ortbVersionConversionManager.convertToBidderSupportedVersion(bidRequest, "bidder"); + final BidRequest result = ortbVersionConversionManager + .convertFromAuctionSupportedVersion(bidRequest, OrtbVersion.ORTB_2_5); // then assertThat(result) diff --git a/src/test/java/org/prebid/server/bidder/HttpBidderRequesterTest.java b/src/test/java/org/prebid/server/bidder/HttpBidderRequesterTest.java index 09bc12105ca..084d1df8f8a 100644 --- a/src/test/java/org/prebid/server/bidder/HttpBidderRequesterTest.java +++ b/src/test/java/org/prebid/server/bidder/HttpBidderRequesterTest.java @@ -113,7 +113,7 @@ public void shouldReturnFailedToRequestBidsErrorWhenBidderReturnsEmptyHttpReques // given given(bidder.makeHttpRequests(any())).willReturn(Result.of(emptyList(), emptyList())); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, BidRequest.builder().build()); // when final BidderSeatBid bidderSeatBid = @@ -134,7 +134,7 @@ public void shouldTolerateBidderReturningErrorsAndNoHttpRequests() { given(bidder.makeHttpRequests(any())).willReturn(Result.of(emptyList(), asList(BidderError.badInput("error1"), BidderError.badInput("error2")))); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, BidRequest.builder().build()); // when final BidderSeatBid bidderSeatBid = @@ -166,7 +166,8 @@ public void shouldPassStoredResponseToBidderMakeBidsMethodAndReturnSeatBids() { final List bids = asList(BidderBid.of(null, null, null), BidderBid.of(null, null, null)); given(bidder.makeBids(any(), any())).willReturn(Result.of(bids, emptyList())); - final BidderRequest bidderRequest = BidderRequest.of("bidder", "storedResponse", BidRequest.builder().build()); + final BidderRequest bidderRequest = BidderRequest.of( + "bidder", null, "storedResponse", BidRequest.builder().build()); // when final BidderSeatBid bidderSeatBid = httpBidderRequester @@ -206,7 +207,8 @@ public void shouldMakeRequestToBidderWhenStoredResponseDefinedButBidderCreatesMo .build()), emptyList())); - final BidderRequest bidderRequest = BidderRequest.of("bidder", "storedResponse", BidRequest.builder().build()); + final BidderRequest bidderRequest = BidderRequest.of( + "bidder", null, "storedResponse", BidRequest.builder().build()); // when httpBidderRequester.requestBids(bidder, bidderRequest, timeout, CaseInsensitiveMultiMap.empty(), false); @@ -227,7 +229,7 @@ public void shouldSendPopulatedGetRequestWithoutBody() { .build()), emptyList())); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, BidRequest.builder().build()); // when httpBidderRequester.requestBids(bidder, bidderRequest, timeout, CaseInsensitiveMultiMap.empty(), false); @@ -257,7 +259,7 @@ public void shouldSendMultipleRequests() throws JsonProcessingException { .build()), emptyList())); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, BidRequest.builder().build()); // when httpBidderRequester.requestBids(bidder, bidderRequest, timeout, CaseInsensitiveMultiMap.empty(), false); @@ -283,7 +285,7 @@ public void shouldReturnBidsCreatedByBidder() { final List bids = asList(BidderBid.of(null, null, null), BidderBid.of(null, null, null)); given(bidder.makeBids(any(), any())).willReturn(Result.of(bids, emptyList())); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, BidRequest.builder().build()); // when final BidderSeatBid bidderSeatBid = @@ -310,7 +312,7 @@ public void shouldCompressRequestBodyIfContentEncodingHeaderIsGzip() { given(requestEnricher.enrichHeaders(anyString(), any(), any(), any())).willReturn(headers); givenHttpClientResponse(200, "responseBody"); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, BidRequest.builder().build()); // when httpBidderRequester.requestBids(bidder, bidderRequest, timeout, CaseInsensitiveMultiMap.empty(), false) @@ -329,7 +331,7 @@ public void shouldNotWaitForResponsesWhenAllDealsIsGathered() throws JsonProcess bidderErrorNotifier, requestEnricher, jacksonMapper); final BidRequest bidRequest = bidRequestWithDeals("deal1", "deal2"); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, bidRequest); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, bidRequest); final BidRequest firstRequest = givenBidRequest(bidRequestBuilder -> bidRequestBuilder.id("r1")); final byte[] firstRequestBody = mapper.writeValueAsBytes(firstRequest); final BidRequest secondRequest = givenBidRequest(bidRequestBuilder -> bidRequestBuilder.id("r2")); @@ -408,7 +410,7 @@ public void shouldNotWaitForResponsesWhenAllDealsIsGathered() throws JsonProcess public void shouldFinishWhenAllDealRequestsAreFinishedAndNoDealsProvided() { // given final BidRequest bidRequest = bidRequestWithDeals("deal1", "deal2", "deal2"); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, bidRequest); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, bidRequest); given(bidder.makeHttpRequests(any())).willReturn(Result.of(Arrays.asList( HttpRequest.builder() @@ -491,7 +493,7 @@ public void shouldReturnFullDebugInfoIfDebugEnabled() throws JsonProcessingExcep given(bidder.makeBids(any(), any())).willReturn(Result.of(emptyList(), emptyList())); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, BidRequest.builder().build()); // when final BidderSeatBid bidderSeatBid = @@ -535,7 +537,7 @@ public void shouldNotReturnSensitiveHeadersInFullDebugInfo() { givenHttpClientReturnsResponses( HttpClientResponse.of(200, null, "responseBody1")); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, BidRequest.builder().build()); // when final BidderSeatBid bidderSeatBid = @@ -567,7 +569,7 @@ public void shouldReturnPartialDebugInfoIfDebugEnabledAndGlobalTimeoutAlreadyExp given(requestEnricher.enrichHeaders(anyString(), any(), any(), any())).willReturn(headers); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, BidRequest.builder().build()); // when final BidderSeatBid bidderSeatBid = @@ -602,7 +604,7 @@ public void shouldReturnPartialDebugInfoIfDebugEnabledAndHttpErrorOccurs() throw givenHttpClientProducesException(new RuntimeException("Request exception")); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, BidRequest.builder().build()); // when final BidderSeatBid bidderSeatBid = @@ -637,7 +639,7 @@ public void shouldReturnFullDebugInfoIfDebugEnabledAndErrorStatus() throws JsonP givenHttpClientReturnsResponses(HttpClientResponse.of(500, null, "responseBody1")); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, BidRequest.builder().build()); // when final BidderSeatBid bidderSeatBid = @@ -670,7 +672,7 @@ public void shouldTolerateAlreadyExpiredGlobalTimeout() { .build()), emptyList())); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, BidRequest.builder().build()); // when final BidderSeatBid bidderSeatBid = @@ -699,7 +701,7 @@ public void shouldNotifyBidderOfTimeout() { // bidder request .willReturn(Future.failedFuture(new TimeoutException("Timeout exception"))); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, BidRequest.builder().build()); // when httpBidderRequester.requestBids(bidder, bidderRequest, timeout, CaseInsensitiveMultiMap.empty(), false); @@ -775,7 +777,7 @@ public void shouldTolerateMultipleErrors() { Result.of(singletonList(BidderBid.of(Bid.builder().impid("123").build(), null, null)), singletonList(BidderError.badServerResponse("makeBidsError")))); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, BidRequest.builder().build()); // when final BidderSeatBid bidderSeatBid = httpBidderRequester @@ -809,7 +811,8 @@ public void shouldNotMakeBidsIfResponseStatusIs204() { givenHttpClientResponse(204, EMPTY); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().test(1).build()); + final BidderRequest bidderRequest = BidderRequest.of( + "bidder", null, null, BidRequest.builder().test(1).build()); // when httpBidderRequester.requestBids(bidder, bidderRequest, timeout, CaseInsensitiveMultiMap.empty(), false); diff --git a/src/test/java/org/prebid/server/deals/simulation/SimulationAwareHttpBidderRequesterTest.java b/src/test/java/org/prebid/server/deals/simulation/SimulationAwareHttpBidderRequesterTest.java index 67b3beb4434..6a3023c6034 100644 --- a/src/test/java/org/prebid/server/deals/simulation/SimulationAwareHttpBidderRequesterTest.java +++ b/src/test/java/org/prebid/server/deals/simulation/SimulationAwareHttpBidderRequesterTest.java @@ -101,7 +101,7 @@ public void requestBidsShouldReturnBidderSeatBidWithOneBidAndFilterOutOne() { singletonList(Format.builder().w(100).h(100).build()), null)))) .build())).build()).build())) .build(); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, bidRequest); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, bidRequest); // when final Future result = bidderRequester.requestBids(null, bidderRequest, null, requestHeaders, @@ -134,7 +134,7 @@ public void requestBidsShouldFilterBidderSeatBidForWhichImpPmpIsNull() { .build())).build()).build(), Imp.builder().id("impId2").build())) .build(); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, bidRequest); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, bidRequest); // when final Future result = bidderRequester.requestBids(null, bidderRequest, null, requestHeaders, @@ -167,7 +167,7 @@ public void requestBidsShouldSetSizesAsZeroIfExtDealsLinesDoesNotHaveSizes() { .ext(mapper.valueToTree(ExtDeal.of(ExtDealLine.of("lineItemId1", null, null, null)))) .build())).build()).build())) .build(); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, bidRequest); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, bidRequest); // when final Future result = bidderRequester.requestBids(null, bidderRequest, null, requestHeaders, @@ -200,7 +200,7 @@ public void requestBidsShouldThrowPrebidExceptionWhenExtDealsInvalidFormat() { .ext(mapper.createObjectNode().set("line", new IntNode(5))) .build())).build()).build())) .build(); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, bidRequest); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, bidRequest); // when and then assertThatThrownBy(() -> bidderRequester.requestBids(null, bidderRequest, null, requestHeaders, false)) @@ -217,7 +217,7 @@ public void requestBidsShouldReturnBidderSeatBidWithoutBidderBidsAndWithError() Imp.builder().id("impId1").pmp(Pmp.builder().deals(singletonList(Deal.builder() .id("dealId1").build())).build()).build())) .build(); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, bidRequest); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, bidRequest); // when final Future result = bidderRequester.requestBids(null, bidderRequest, null, requestHeaders, @@ -244,7 +244,7 @@ public void requestBidsShouldThrowPrebidExceptionWhenBidRatesForLineItemWereNotF .ext(mapper.valueToTree(ExtDeal.of(ExtDealLine.of("lineItemId2", null, null, null)))) .build())).build()).build())) .build(); - final BidderRequest bidderRequest = BidderRequest.of("bidder", null, bidRequest); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, null, bidRequest); // when assertThatThrownBy(() -> bidderRequester.requestBids(null, bidderRequest, null, requestHeaders, false)) diff --git a/src/test/java/org/prebid/server/floors/BasicPriceFloorEnforcerTest.java b/src/test/java/org/prebid/server/floors/BasicPriceFloorEnforcerTest.java index f3d08fdc3f4..6d8c83c5502 100644 --- a/src/test/java/org/prebid/server/floors/BasicPriceFloorEnforcerTest.java +++ b/src/test/java/org/prebid/server/floors/BasicPriceFloorEnforcerTest.java @@ -622,6 +622,7 @@ private static AuctionParticipation givenAuctionParticipation( .bidderRequest(BidderRequest.of( "bidder", null, + null, bidRequestCustomizer.apply(BidRequest.builder() .ext(ExtRequest.of(ExtRequestPrebid.builder() .floors(PriceFloorRules.builder() diff --git a/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java b/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java index 67a092f7798..ef583819b05 100644 --- a/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java +++ b/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java @@ -1937,10 +1937,10 @@ public void shouldExecuteBidderRequestHooksHappyPath(TestContext context) { // when final Future> future1 = executor.executeBidderRequestStage( - BidderRequest.of("bidder1", null, BidRequest.builder().build()), + BidderRequest.of("bidder1", null, null, BidRequest.builder().build()), auctionContext); final Future> future2 = executor.executeBidderRequestStage( - BidderRequest.of("bidder2", null, BidRequest.builder().build()), + BidderRequest.of("bidder2", null, null, BidRequest.builder().build()), auctionContext); // then @@ -1988,7 +1988,7 @@ public void shouldExecuteBidderRequestHooksAndPassBidderInvocationContext(TestCo // when final Future> future = executor.executeBidderRequestStage( - BidderRequest.of("bidder1", null, BidRequest.builder().build()), + BidderRequest.of("bidder1", null, null, BidRequest.builder().build()), AuctionContext.builder() .bidRequest(BidRequest.builder().build()) .account(Account.builder() @@ -2353,7 +2353,7 @@ public void shouldExecuteBidderRequestHooksWhenRequestIsRejected(TestContext con // when final Future> future = executor.executeBidderRequestStage( - BidderRequest.of("bidder1", null, BidRequest.builder().build()), + BidderRequest.of("bidder1", null, null, BidRequest.builder().build()), AuctionContext.builder() .account(Account.empty("accountId")) .hookExecutionContext(hookExecutionContext) diff --git a/src/test/java/org/prebid/server/log/HttpInteractionLoggerTest.java b/src/test/java/org/prebid/server/log/HttpInteractionLoggerTest.java index bcb3a44e545..49a65d69e20 100644 --- a/src/test/java/org/prebid/server/log/HttpInteractionLoggerTest.java +++ b/src/test/java/org/prebid/server/log/HttpInteractionLoggerTest.java @@ -455,6 +455,6 @@ private static BidderRequest givenBidderRequest( UnaryOperator bidRequestBuilderCustomizer) { final BidRequest bidRequest = bidRequestBuilderCustomizer.apply(BidRequest.builder()).build(); - return BidderRequest.of("bidderName", null, bidRequest); + return BidderRequest.of("bidderName", null, null, bidRequest); } }