From 79f73eb5a089ca0e0a0748558ffea7996bc466bf Mon Sep 17 00:00:00 2001 From: Alex Maltsev Date: Thu, 23 Jul 2026 16:56:53 +0300 Subject: [PATCH 1/8] HttpClient: Rename `http-client.use-compression` to `http-client.use-decompression` (#4574) --- docs/config-app.md | 2 +- .../org/prebid/server/spring/config/ServiceConfiguration.java | 2 +- .../prebid/server/spring/config/model/HttpClientProperties.java | 2 +- src/main/resources/application.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/config-app.md b/docs/config-app.md index dec2ce563b7..5df4cb13239 100644 --- a/docs/config-app.md +++ b/docs/config-app.md @@ -52,7 +52,7 @@ This parameter exists to allow to change the location of the directory Vert.x wi - `http-client.circuit-breaker.opening-interval-ms` - time interval for opening the circuit breaker if failures count reached. (Must be a multiple of 1000) - `http-client.circuit-breaker.closing-interval-ms` - time spent in open state before attempting to re-try. - `http-client.circuit-breaker.idle-expire-hours` - idle time to clean the circuit breaker up. -- `http-client.use-compression` - if equals to `true` httpclient compression is enabled for requests (see [also](https://vertx.io/docs/apidocs/io/vertx/core/http/HttpClientOptions.html#setTryUseCompression-boolean-)) +- `http-client.use-decompression` - if equals to `true` httpclient compression is enabled for requests (see [also](https://vertx.io/docs/apidocs/io/vertx/core/http/HttpClientOptions.html#setDecompressionSupported(boolean))) - `http-client.max-redirects` - set the maximum amount of HTTP redirections to follow. A value of 0 (the default) prevents redirections from being followed. - `http-client.ssl` - enable SSL/TLS support. - `http-client.jks-path` - path to the java keystore (if ssl is enabled). 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 2dd8389de83..7967cdd19f9 100644 --- a/src/main/java/org/prebid/server/spring/config/ServiceConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/ServiceConfiguration.java @@ -685,7 +685,7 @@ private static BasicHttpClient createBasicHttpClient(Vertx vertx, HttpClientProp final HttpClientOptions options = new HttpClientOptions() .setIdleTimeoutUnit(TimeUnit.MILLISECONDS) .setIdleTimeout(httpClientProperties.getIdleTimeoutMs()) - .setDecompressionSupported(httpClientProperties.getUseCompression()) + .setDecompressionSupported(httpClientProperties.getUseDecompression()) .setConnectTimeout(httpClientProperties.getConnectTimeoutMs()) // Vert.x's HttpClientRequest needs this value to be 2 for redirections to be followed once, // 3 for twice, and so on diff --git a/src/main/java/org/prebid/server/spring/config/model/HttpClientProperties.java b/src/main/java/org/prebid/server/spring/config/model/HttpClientProperties.java index 06ec12bac87..98b253ebae1 100644 --- a/src/main/java/org/prebid/server/spring/config/model/HttpClientProperties.java +++ b/src/main/java/org/prebid/server/spring/config/model/HttpClientProperties.java @@ -23,7 +23,7 @@ public class HttpClientProperties { @Min(1) private Integer connectTimeoutMs; - private Boolean useCompression; + private Boolean useDecompression; @NotNull private Integer maxRedirects; diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 86526b803b2..1422ed73353 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -78,7 +78,7 @@ http-client: idle-timeout-ms: 0 pool-cleaner-period-ms: 1000 connect-timeout-ms: 2500 - use-compression: true + use-decompression: true max-redirects: 0 ssl: false jks-path: From f4286d5ea39de96726221fc9261d433299d7693b Mon Sep 17 00:00:00 2001 From: Dubyk Danylo <45672370+CTMBNara@users.noreply.github.com> Date: Thu, 23 Jul 2026 16:10:01 +0200 Subject: [PATCH 2/8] Remove PAAPI related code (#4514) --- .../server/auction/BidResponseCreator.java | 223 +----- .../prebid/server/auction/ImpAdjuster.java | 25 - .../server/auction/model/PaaFormat.java | 12 - .../Ortb2ImplicitParametersResolver.java | 26 +- .../java/org/prebid/server/bidder/Bidder.java | 17 - .../server/bidder/HttpBidderRequester.java | 44 +- .../bidder/consumable/ConsumableBidder.java | 17 +- .../bidder/criteo/CriteoBidResponse.java | 27 - .../server/bidder/criteo/CriteoBidder.java | 30 +- .../bidder/criteo/CriteoExtBidResponse.java | 12 - .../org/prebid/server/bidder/ix/IxBidder.java | 44 +- .../response/AuctionConfigExtBidResponse.java | 14 - .../ix/model/response/IxBidResponse.java | 26 - .../ix/model/response/IxExtBidResponse.java | 14 - .../bidder/medianet/MedianetBidder.java | 47 +- .../response/InterestGroupAuctionBuyer.java | 23 - .../response/InterestGroupAuctionIntent.java | 15 - .../response/InterestGroupAuctionSeller.java | 16 - .../model/response/MedianetBidResponse.java | 26 - .../response/MedianetBidResponseExt.java | 11 - .../server/bidder/model/BidderSeatBid.java | 9 - .../bidder/model/BidderSeatBidInfo.java | 11 +- .../bidder/model/CompositeBidderResponse.java | 39 -- .../server/bidder/openx/OpenxBidder.java | 52 +- .../bidder/openx/proto/OpenxBidResponse.java | 22 - .../openx/proto/OpenxBidResponseExt.java | 14 - .../bidder/pubmatic/PubmaticBidder.java | 71 +- .../model/request/PubmaticBidderImpExt.java | 2 - .../model/response/PubmaticBidResponse.java | 27 - .../response/PubmaticExtBidResponse.java | 15 - .../server/proto/openrtb/ext/ExtPrebid.java | 11 - .../ext/request/ExtImpAuctionEnvironment.java | 25 - .../openrtb/ext/request/ExtRequestPrebid.java | 7 - .../openrtb/ext/response/ExtBidResponse.java | 5 - .../ext/response/ExtBidResponseFledge.java | 16 - .../ext/response/ExtBidResponsePrebid.java | 5 - .../proto/openrtb/ext/response/ExtIgi.java | 20 - .../proto/openrtb/ext/response/ExtIgiIgb.java | 22 - .../proto/openrtb/ext/response/ExtIgiIgs.java | 18 - .../openrtb/ext/response/ExtIgiIgsExt.java | 11 - .../ext/response/FledgeAuctionConfig.java | 23 - .../settings/model/AccountAuctionConfig.java | 4 - .../spring/config/ServiceConfiguration.java | 4 - .../model/config/AccountAuctionConfig.groovy | 2 - .../request/auction/AuctionEnvironment.groovy | 18 - .../model/request/auction/ImpExt.groovy | 4 - .../InterestGroupAuctionSupport.groovy | 11 - .../model/request/auction/PaaFormat.groovy | 13 - .../model/request/auction/Prebid.groovy | 1 - .../response/auction/BidResponseExt.groovy | 3 - .../response/auction/BidResponsePrebid.groovy | 1 - .../auction/ExtBidResponseFledge.groovy | 12 - .../auction/FledgeAuctionConfig.groovy | 15 - .../auction/InterestGroupAuctionBuyer.groovy | 17 - .../InterestGroupAuctionBuyerExt.groovy | 10 - .../auction/InterestGroupAuctionIntent.groovy | 18 - .../InterestGroupAuctionIntentExt.groovy | 11 - .../auction/InterestGroupAuctionSeller.groovy | 14 - .../InterestGroupAuctionSellerExt.groovy | 10 - .../response/auction/OpenxBidResponse.groovy | 20 - .../auction/OpenxBidResponseExt.groovy | 11 - .../functional/tests/BidderParamsSpec.groovy | 73 +- .../tests/bidder/openx/OpenxSpec.groovy | 581 ---------------- .../auction/BidResponseCreatorTest.java | 636 +----------------- .../server/auction/ExchangeServiceTest.java | 54 -- .../server/auction/ImpAdjusterTest.java | 74 -- .../bidder/HttpBidderRequesterTest.java | 333 +++------ .../consumable/ConsumableBidderTest.java | 78 +-- .../bidder/criteo/CriteoBidderTest.java | 103 +-- .../bidder/epsilon/EpsilonBidderTest.java | 27 +- .../prebid/server/bidder/ix/IxBidderTest.java | 155 ++--- .../bidder/medianet/MedianetBidderTest.java | 124 +--- .../server/bidder/ogury/OguryBidderTest.java | 67 +- .../server/bidder/openx/OpenxBidderTest.java | 123 +--- .../bidder/pubmatic/PubmaticBidderTest.java | 182 ++--- .../openrtb2/ix/test-auction-ix-request.json | 1 - .../it/openrtb2/ix/test-ix-bid-request.json | 4 - .../test-auction-pubmatic-request.json | 1 - .../pubmatic/test-pubmatic-bid-request.json | 1 - 79 files changed, 480 insertions(+), 3430 deletions(-) delete mode 100644 src/main/java/org/prebid/server/auction/model/PaaFormat.java delete mode 100644 src/main/java/org/prebid/server/bidder/criteo/CriteoBidResponse.java delete mode 100644 src/main/java/org/prebid/server/bidder/criteo/CriteoExtBidResponse.java delete mode 100644 src/main/java/org/prebid/server/bidder/ix/model/response/AuctionConfigExtBidResponse.java delete mode 100644 src/main/java/org/prebid/server/bidder/ix/model/response/IxBidResponse.java delete mode 100644 src/main/java/org/prebid/server/bidder/ix/model/response/IxExtBidResponse.java delete mode 100644 src/main/java/org/prebid/server/bidder/medianet/model/response/InterestGroupAuctionBuyer.java delete mode 100644 src/main/java/org/prebid/server/bidder/medianet/model/response/InterestGroupAuctionIntent.java delete mode 100644 src/main/java/org/prebid/server/bidder/medianet/model/response/InterestGroupAuctionSeller.java delete mode 100644 src/main/java/org/prebid/server/bidder/medianet/model/response/MedianetBidResponse.java delete mode 100644 src/main/java/org/prebid/server/bidder/medianet/model/response/MedianetBidResponseExt.java delete mode 100644 src/main/java/org/prebid/server/bidder/model/CompositeBidderResponse.java delete mode 100644 src/main/java/org/prebid/server/bidder/openx/proto/OpenxBidResponse.java delete mode 100644 src/main/java/org/prebid/server/bidder/openx/proto/OpenxBidResponseExt.java delete mode 100644 src/main/java/org/prebid/server/bidder/pubmatic/model/response/PubmaticBidResponse.java delete mode 100644 src/main/java/org/prebid/server/bidder/pubmatic/model/response/PubmaticExtBidResponse.java delete mode 100644 src/main/java/org/prebid/server/proto/openrtb/ext/request/ExtImpAuctionEnvironment.java delete mode 100644 src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidResponseFledge.java delete mode 100644 src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtIgi.java delete mode 100644 src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtIgiIgb.java delete mode 100644 src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtIgiIgs.java delete mode 100644 src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtIgiIgsExt.java delete mode 100644 src/main/java/org/prebid/server/proto/openrtb/ext/response/FledgeAuctionConfig.java delete mode 100644 src/test/groovy/org/prebid/server/functional/model/request/auction/AuctionEnvironment.groovy delete mode 100644 src/test/groovy/org/prebid/server/functional/model/request/auction/InterestGroupAuctionSupport.groovy delete mode 100644 src/test/groovy/org/prebid/server/functional/model/request/auction/PaaFormat.groovy delete mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/ExtBidResponseFledge.groovy delete mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/FledgeAuctionConfig.groovy delete mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionBuyer.groovy delete mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionBuyerExt.groovy delete mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionIntent.groovy delete mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionIntentExt.groovy delete mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionSeller.groovy delete mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionSellerExt.groovy delete mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/OpenxBidResponse.groovy delete mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/OpenxBidResponseExt.groovy delete mode 100644 src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy diff --git a/src/main/java/org/prebid/server/auction/BidResponseCreator.java b/src/main/java/org/prebid/server/auction/BidResponseCreator.java index b2c364d6a54..68c187d8f74 100644 --- a/src/main/java/org/prebid/server/auction/BidResponseCreator.java +++ b/src/main/java/org/prebid/server/auction/BidResponseCreator.java @@ -18,7 +18,6 @@ import io.vertx.core.CompositeFuture; import io.vertx.core.Future; import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.collections4.ListUtils; import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.ObjectUtils; @@ -35,7 +34,6 @@ import org.prebid.server.auction.model.CachedDebugLog; import org.prebid.server.auction.model.CategoryMappingResult; import org.prebid.server.auction.model.MultiBidConfig; -import org.prebid.server.auction.model.PaaFormat; import org.prebid.server.auction.model.Rejection; import org.prebid.server.auction.model.TargetingInfo; import org.prebid.server.auction.model.debug.DebugContext; @@ -63,13 +61,7 @@ import org.prebid.server.identity.IdGenerator; import org.prebid.server.json.DecodeException; import org.prebid.server.json.JacksonMapper; -import org.prebid.server.log.ConditionalLogger; -import org.prebid.server.log.Logger; -import org.prebid.server.log.LoggerFactory; -import org.prebid.server.metric.MetricName; -import org.prebid.server.metric.Metrics; import org.prebid.server.proto.openrtb.ext.request.ExtImp; -import org.prebid.server.proto.openrtb.ext.request.ExtImpAuctionEnvironment; import org.prebid.server.proto.openrtb.ext.request.ExtImpPrebid; import org.prebid.server.proto.openrtb.ext.request.ExtMediaTypePriceGranularity; import org.prebid.server.proto.openrtb.ext.request.ExtOptions; @@ -85,19 +77,13 @@ import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidMeta; import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidVideo; import org.prebid.server.proto.openrtb.ext.response.ExtBidResponse; -import org.prebid.server.proto.openrtb.ext.response.ExtBidResponseFledge; import org.prebid.server.proto.openrtb.ext.response.ExtBidResponsePrebid; import org.prebid.server.proto.openrtb.ext.response.ExtBidderError; import org.prebid.server.proto.openrtb.ext.response.ExtDebugTrace; import org.prebid.server.proto.openrtb.ext.response.ExtHttpCall; -import org.prebid.server.proto.openrtb.ext.response.ExtIgi; -import org.prebid.server.proto.openrtb.ext.response.ExtIgiIgb; -import org.prebid.server.proto.openrtb.ext.response.ExtIgiIgs; -import org.prebid.server.proto.openrtb.ext.response.ExtIgiIgsExt; import org.prebid.server.proto.openrtb.ext.response.ExtResponseCache; import org.prebid.server.proto.openrtb.ext.response.ExtResponseDebug; import org.prebid.server.proto.openrtb.ext.response.ExtTraceActivityInfrastructure; -import org.prebid.server.proto.openrtb.ext.response.FledgeAuctionConfig; import org.prebid.server.proto.openrtb.ext.response.seatnonbid.NonBid; import org.prebid.server.proto.openrtb.ext.response.seatnonbid.SeatNonBid; import org.prebid.server.settings.model.Account; @@ -133,9 +119,6 @@ public class BidResponseCreator { - private static final Logger logger = LoggerFactory.getLogger(BidResponseCreator.class); - private static final ConditionalLogger conditionalLogger = new ConditionalLogger(logger); - private static final String CACHE = "cache"; private static final String PREBID_EXT = "prebid"; private static final Integer DEFAULT_BID_LIMIT_MIN = 1; @@ -146,7 +129,6 @@ public class BidResponseCreator { private static final String TARGETING_ENV_AMP_VALUE = "amp"; private static final int MIN_BID_ID_LENGTH = 17; - private final double logSamplingRate; private final CoreCacheService coreCacheService; private final BidderCatalog bidderCatalog; private final VastModifier vastModifier; @@ -161,7 +143,6 @@ public class BidResponseCreator { private final boolean enforceRandomBidId; private final Clock clock; private final JacksonMapper mapper; - private final Metrics metrics; private final CacheTtl mediaTypeCacheTtl; private final CacheDefaultTtlProperties cacheDefaultProperties; @@ -169,8 +150,7 @@ public class BidResponseCreator { private final String cachePath; private final String cacheAssetUrlTemplate; - public BidResponseCreator(double logSamplingRate, - CoreCacheService coreCacheService, + public BidResponseCreator(CoreCacheService coreCacheService, BidderCatalog bidderCatalog, VastModifier vastModifier, EventsService eventsService, @@ -184,7 +164,6 @@ public BidResponseCreator(double logSamplingRate, boolean enforceRandomBidId, Clock clock, JacksonMapper mapper, - Metrics metrics, CacheTtl mediaTypeCacheTtl, CacheDefaultTtlProperties cacheDefaultProperties) { @@ -204,8 +183,6 @@ public BidResponseCreator(double logSamplingRate, this.mapper = Objects.requireNonNull(mapper); this.mediaTypeCacheTtl = Objects.requireNonNull(mediaTypeCacheTtl); this.cacheDefaultProperties = Objects.requireNonNull(cacheDefaultProperties); - this.metrics = Objects.requireNonNull(metrics); - this.logSamplingRate = logSamplingRate; cacheAssetUrlTemplate = Objects.requireNonNull(coreCacheService.getCachedAssetURLTemplate()); cacheHost = Objects.requireNonNull(coreCacheService.getEndpointHost()); @@ -428,9 +405,7 @@ private List toBidderResponseInfos(CategoryMappingResult cat Collections.emptyList(), seatBid.getHttpCalls(), seatBid.getErrors(), - seatBid.getWarnings(), - seatBid.getFledgeAuctionConfigs(), - seatBid.getIgi()); + seatBid.getWarnings()); result.add(BidderResponseInfo.of( bidder, @@ -472,9 +447,7 @@ private List toBidderResponseInfos(CategoryMappingResult cat bidInfos, seatBid.getHttpCalls(), seatBid.getErrors(), - seatBid.getWarnings(), - seatBid.getFledgeAuctionConfigs(), - seatBid.getIgi()); + seatBid.getWarnings()); result.add(BidderResponseInfo.of( bidder, @@ -663,8 +636,8 @@ private Future cacheBidsAndCreateResponse(List final Set winningBidInfos = targeting == null ? null : bidInfos.stream() - .filter(bidInfo -> bidInfo.getTargetingInfo().isWinningBid()) - .collect(Collectors.toSet()); + .filter(bidInfo -> bidInfo.getTargetingInfo().isWinningBid()) + .collect(Collectors.toSet()); final Set bidsToCache = cacheInfo.isShouldCacheWinningBidsOnly() ? winningBidInfos : bidInfos; @@ -837,10 +810,6 @@ private ExtBidResponse toExtBidResponse(List bidderResponseI final DebugContext debugContext = auctionContext.getDebugContext(); final boolean debugEnabled = debugContext.isDebugEnabled(); - final PaaResult paaResult = toPaaOutput(bidderResponseInfos, auctionContext); - final List igi = paaResult.igis(); - final ExtBidResponseFledge fledge = paaResult.fledge(); - final ExtResponseDebug extResponseDebug = toExtResponseDebug( bidderResponseInfos, auctionContext, cacheResult, debugEnabled); final Map> errors = toExtBidderErrors( @@ -850,8 +819,7 @@ private ExtBidResponse toExtBidResponse(List bidderResponseI final Map responseTimeMillis = toResponseTimes(bidderResponseInfos, cacheResult); - final ExtBidResponsePrebid prebid = toExtBidResponsePrebid( - auctionTimestamp, auctionContext.getBidRequest(), fledge); + final ExtBidResponsePrebid prebid = toExtBidResponsePrebid(auctionTimestamp, auctionContext.getBidRequest()); return ExtBidResponse.builder() .debug(extResponseDebug) @@ -859,15 +827,11 @@ private ExtBidResponse toExtBidResponse(List bidderResponseI .warnings(warnings) .responsetimemillis(responseTimeMillis) .tmaxrequest(auctionContext.getBidRequest().getTmax()) - .igi(igi) .prebid(prebid) .build(); } - private ExtBidResponsePrebid toExtBidResponsePrebid(long auctionTimestamp, - BidRequest bidRequest, - ExtBidResponseFledge extBidResponseFledge) { - + private ExtBidResponsePrebid toExtBidResponsePrebid(long auctionTimestamp, BidRequest bidRequest) { final JsonNode passThrough = Optional.ofNullable(bidRequest) .map(BidRequest::getExt) .map(ExtRequest::getPrebid) @@ -877,165 +841,6 @@ private ExtBidResponsePrebid toExtBidResponsePrebid(long auctionTimestamp, return ExtBidResponsePrebid.builder() .auctiontimestamp(auctionTimestamp) .passthrough(passThrough) - .fledge(extBidResponseFledge) - .build(); - } - - private PaaResult toPaaOutput(List bidderResponseInfos, AuctionContext auctionContext) { - - final PaaFormat paaFormat = resolvePaaFormat(auctionContext); - final List igis = extractIgis(bidderResponseInfos, auctionContext); - final List extIgi = paaFormat == PaaFormat.IAB && !igis.isEmpty() ? igis : null; - - final List fledgeConfigs = paaFormat == PaaFormat.ORIGINAL - ? toOriginalFledgeFormat(igis) - : Collections.emptyList(); - - // TODO: Remove after transition period - final List imps = auctionContext.getBidRequest().getImp(); - final List deprecatedFledgeConfigs = bidderResponseInfos.stream() - .flatMap(bidderResponseInfo -> toDeprecatedFledgeConfigs(bidderResponseInfo, imps)) - .toList(); - - final List combinedFledgeConfigs = ListUtils.union(deprecatedFledgeConfigs, fledgeConfigs); - final ExtBidResponseFledge extBidResponseFledge = combinedFledgeConfigs.isEmpty() - ? null - : ExtBidResponseFledge.of(combinedFledgeConfigs); - - return new PaaResult(extIgi, extBidResponseFledge); - } - - private List extractIgis(List bidderResponseInfos, AuctionContext auctionContext) { - return bidderResponseInfos.stream() - .flatMap(responseInfo -> responseInfo.getSeatBid().getIgi().stream() - .map(igi -> prepareExtIgi( - igi, - responseInfo.getSeat(), - responseInfo.getAdapterCode(), - auctionContext))) - .filter(Objects::nonNull) - .toList(); - } - - private ExtIgi prepareExtIgi(ExtIgi igi, - String seat, - String adapterCode, - AuctionContext auctionContext) { - if (igi == null) { - return null; - } - - final boolean shouldDropIgb = StringUtils.isEmpty(igi.getImpid()) && CollectionUtils.isNotEmpty(igi.getIgb()); - if (shouldDropIgb) { - final String warning = "ExtIgi with absent impId from bidder: " + seat; - if (auctionContext.getDebugContext().isDebugEnabled()) { - auctionContext.getDebugWarnings().add(warning); - } - conditionalLogger.warn(warning, logSamplingRate); - metrics.updateAlertsMetrics(MetricName.general); - } - - final List updatedIgs = prepareExtIgiIgs(igi.getIgs(), seat, adapterCode, auctionContext); - final List preparedIgs = updatedIgs.isEmpty() ? null : updatedIgs; - final List preparedIgb = shouldDropIgb ? null : igi.getIgb(); - - return ObjectUtils.anyNotNull(preparedIgs, preparedIgb) - ? igi.toBuilder().igs(preparedIgs).igb(preparedIgb).build() - : null; - } - - private List prepareExtIgiIgs(List igiIgs, - String seat, - String adapterCode, - AuctionContext auctionContext) { - - if (igiIgs == null) { - return Collections.emptyList(); - } - - final boolean debugEnabled = auctionContext.getDebugContext().isDebugEnabled(); - final List preparedIgiIgs = new ArrayList<>(); - for (ExtIgiIgs extIgiIgs : igiIgs) { - if (extIgiIgs == null) { - continue; - } - - if (StringUtils.isEmpty(extIgiIgs.getImpId())) { - final String warning = "ExtIgiIgs with absent impId from bidder: " + seat; - if (debugEnabled) { - auctionContext.getDebugWarnings().add(warning); - } - conditionalLogger.warn(warning, logSamplingRate); - metrics.updateAlertsMetrics(MetricName.general); - continue; - } - - if (extIgiIgs.getConfig() == null) { - final String warning = "ExtIgiIgs with absent config from bidder: " + seat; - if (debugEnabled) { - auctionContext.getDebugWarnings().add(warning); - } - conditionalLogger.warn(warning, logSamplingRate); - metrics.updateAlertsMetrics(MetricName.general); - continue; - } - - final ExtIgiIgs preparedExtIgiIgs = extIgiIgs.toBuilder() - .ext(ExtIgiIgsExt.of(seat, adapterCode)) - .build(); - - preparedIgiIgs.add(preparedExtIgiIgs); - } - - return preparedIgiIgs; - } - - private List toOriginalFledgeFormat(List igis) { - return igis.stream() - .map(ExtIgi::getIgs) - .flatMap(Collection::stream) - .map(BidResponseCreator::extIgiIgsToFledgeConfig) - .toList(); - } - - private static FledgeAuctionConfig extIgiIgsToFledgeConfig(ExtIgiIgs extIgiIgs) { - return FledgeAuctionConfig.builder() - .bidder(extIgiIgs.getExt().getBidder()) - .adapter(extIgiIgs.getExt().getAdapter()) - .impId(extIgiIgs.getImpId()) - .config(extIgiIgs.getConfig()) - .build(); - } - - private Stream toDeprecatedFledgeConfigs(BidderResponseInfo bidderResponseInfo, - List imps) { - - return Optional.ofNullable(bidderResponseInfo.getSeatBid().getFledgeAuctionConfigs()) - .stream() - .flatMap(Collection::stream) - .filter(fledgeConfig -> validateFledgeConfig(fledgeConfig, imps)) - .map(fledgeConfig -> fledgeConfigWithBidder( - fledgeConfig, - bidderResponseInfo.getSeat(), - bidderResponseInfo.getAdapterCode())); - } - - private boolean validateFledgeConfig(FledgeAuctionConfig fledgeAuctionConfig, List imps) { - final ExtImpAuctionEnvironment fledgeEnabled = correspondingImp(fledgeAuctionConfig.getImpId(), imps) - .map(Imp::getExt) - .map(ext -> convertValue(ext, "ae", ExtImpAuctionEnvironment.class)) - .orElse(ExtImpAuctionEnvironment.SERVER_SIDE_AUCTION); - - return fledgeEnabled == ExtImpAuctionEnvironment.ON_DEVICE_IG_AUCTION_FLEDGE; - } - - private FledgeAuctionConfig fledgeConfigWithBidder(FledgeAuctionConfig fledgeConfig, - String seat, - String adapterCode) { - - return fledgeConfig.toBuilder() - .bidder(seat) - .adapter(adapterCode) .build(); } @@ -1353,17 +1158,6 @@ private static Map toResponseTimes(Collection Optional.ofNullable(auctionContext.getAccount()) - .map(Account::getAuction) - .map(AccountAuctionConfig::getPaaFormat)) - .orElse(PaaFormat.ORIGINAL); - } - /** * Returns {@link BidResponse} based on list of {@link BidderResponse}s and {@link CacheServiceResult}. */ @@ -2003,7 +1797,4 @@ private T convertValue(JsonNode jsonNode, String key, Class typeClass) { return null; } } - - private record PaaResult(List igis, ExtBidResponseFledge fledge) { - } } diff --git a/src/main/java/org/prebid/server/auction/ImpAdjuster.java b/src/main/java/org/prebid/server/auction/ImpAdjuster.java index 738622e6a86..27fe98930a7 100644 --- a/src/main/java/org/prebid/server/auction/ImpAdjuster.java +++ b/src/main/java/org/prebid/server/auction/ImpAdjuster.java @@ -1,7 +1,6 @@ package org.prebid.server.auction; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.IntNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.iab.openrtb.request.Imp; import org.apache.commons.lang3.StringUtils; @@ -17,8 +16,6 @@ public class ImpAdjuster { private static final String IMP_EXT = "ext"; - private static final String EXT_AE = "ae"; - private static final String EXT_IGS = "igs"; private static final String EXT_PREBID = "prebid"; private static final String EXT_PREBID_BIDDER = "bidder"; private static final String EXT_PREBID_IMP = "imp"; @@ -37,8 +34,6 @@ public ImpAdjuster(JacksonMapper jacksonMapper, } public Imp adjust(Imp originalImp, String bidder, List debugMessages) { - setAeParams(originalImp.getExt()); - final JsonNode impExtPrebidImp = bidderParamsFromImpExtPrebidImp(originalImp.getExt()); if (impExtPrebidImp == null) { return originalImp; @@ -71,26 +66,6 @@ public Imp adjust(Imp originalImp, String bidder, List debugMessages) { } } - private void setAeParams(ObjectNode ext) { - final int extAe = Optional.ofNullable(ext) - .map(extNode -> extNode.get(EXT_AE)) - .filter(JsonNode::isInt) - .map(JsonNode::asInt) - .orElse(-1); - - final boolean extIgsAePresent = Optional.ofNullable(ext) - .map(extNode -> extNode.get(EXT_IGS)) - .map(igsNode -> igsNode.get(EXT_AE)) - .isPresent(); - - if (!extIgsAePresent && (extAe == 0 || extAe == 1)) { - final ObjectNode igsNode = jacksonMapper.mapper().createObjectNode() - .set(EXT_AE, IntNode.valueOf(extAe)); - - ext.set(EXT_IGS, igsNode); - } - } - private static JsonNode bidderParamsFromImpExtPrebidImp(ObjectNode ext) { return Optional.ofNullable(ext) .map(extNode -> extNode.get(EXT_PREBID)) diff --git a/src/main/java/org/prebid/server/auction/model/PaaFormat.java b/src/main/java/org/prebid/server/auction/model/PaaFormat.java deleted file mode 100644 index 8367b61c0f2..00000000000 --- a/src/main/java/org/prebid/server/auction/model/PaaFormat.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.prebid.server.auction.model; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public enum PaaFormat { - - @JsonProperty("original") - ORIGINAL, - - @JsonProperty("iab") - IAB -} diff --git a/src/main/java/org/prebid/server/auction/requestfactory/Ortb2ImplicitParametersResolver.java b/src/main/java/org/prebid/server/auction/requestfactory/Ortb2ImplicitParametersResolver.java index 90c049db606..4371fd9c3e9 100644 --- a/src/main/java/org/prebid/server/auction/requestfactory/Ortb2ImplicitParametersResolver.java +++ b/src/main/java/org/prebid/server/auction/requestfactory/Ortb2ImplicitParametersResolver.java @@ -24,12 +24,12 @@ import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; -import org.prebid.server.auction.aliases.BidderAliases; import org.prebid.server.auction.ImplicitParametersExtractor; import org.prebid.server.auction.IpAddressHelper; import org.prebid.server.auction.PriceGranularity; import org.prebid.server.auction.SecBrowsingTopicsResolver; import org.prebid.server.auction.TimeoutResolver; +import org.prebid.server.auction.aliases.BidderAliases; import org.prebid.server.auction.model.AuctionContext; import org.prebid.server.auction.model.Endpoint; import org.prebid.server.auction.model.IpAddress; @@ -89,7 +89,7 @@ public class Ortb2ImplicitParametersResolver { private static final String BIDDER_EXT = "bidder"; private static final Set IMP_EXT_NON_BIDDER_FIELDS = - Set.of(PREBID_EXT, "context", "all", "general", "skadn", "data", "gpid", "tid", "ae"); + Set.of(PREBID_EXT, "context", "all", "general", "skadn", "data", "gpid", "tid"); private static final String OVERRIDE_SOURCE_ID_TEMPLATE = "{{UUID}}"; private final boolean shouldCacheOnlyWinningBids; @@ -521,10 +521,10 @@ private User populateUser(User user, CaseInsensitiveMultiMap headers, boolean de return populatedData != null ? Optional.ofNullable(user) - .map(User::toBuilder) - .orElseGet(User::builder) - .data(populatedData) - .build() + .map(User::toBuilder) + .orElseGet(User::builder) + .data(populatedData) + .build() : null; } @@ -625,9 +625,9 @@ private static Set newSegmentsIds(List segments, Set ne ? SetUtils.difference( newIds, CollectionUtils.emptyIfNull(segments).stream() - .filter(Objects::nonNull) - .map(Segment::getId) - .collect(Collectors.toSet())) + .filter(Objects::nonNull) + .map(Segment::getId) + .collect(Collectors.toSet())) : newIds; } @@ -1030,10 +1030,10 @@ private Imp populateImp(Imp imp, return ObjectUtils.anyNotNull(populatedImpId, populatedImpSecure, populatedImpExt) ? imp.toBuilder() - .id(populatedImpId != null ? populatedImpId : impId) - .secure(populatedImpSecure != null ? populatedImpSecure : impSecure) - .ext(populatedImpExt != null ? populatedImpExt : impExt) - .build() + .id(populatedImpId != null ? populatedImpId : impId) + .secure(populatedImpSecure != null ? populatedImpSecure : impSecure) + .ext(populatedImpExt != null ? populatedImpExt : impExt) + .build() : null; } diff --git a/src/main/java/org/prebid/server/bidder/Bidder.java b/src/main/java/org/prebid/server/bidder/Bidder.java index 4a357da0a54..9dae888c4b9 100644 --- a/src/main/java/org/prebid/server/bidder/Bidder.java +++ b/src/main/java/org/prebid/server/bidder/Bidder.java @@ -4,7 +4,6 @@ import com.iab.openrtb.request.BidRequest; import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.bidder.model.BidderCall; -import org.prebid.server.bidder.model.CompositeBidderResponse; import org.prebid.server.bidder.model.HttpRequest; import org.prebid.server.bidder.model.Result; @@ -33,22 +32,6 @@ public interface Bidder { */ Result> makeBids(BidderCall httpCall, BidRequest bidRequest); - /** - * Compound Bidder response with bids and other data to be passed back. - *

- * The errors should contain a list of errors which explain why this bidder's bids will be - * "subpar" in some way. For example: the server response didn't have the expected format. - */ - default CompositeBidderResponse makeBidderResponse(BidderCall httpCall, BidRequest bidRequest) { - final var result = makeBids(httpCall, bidRequest); - return result != null - ? CompositeBidderResponse.builder() - .bids(result.getValue()) - .errors(result.getErrors()) - .build() - : null; - } - /** * Extracts targeting from bidder-specific extension. It is safe to assume that {@code ext} is not null. */ diff --git a/src/main/java/org/prebid/server/bidder/HttpBidderRequester.java b/src/main/java/org/prebid/server/bidder/HttpBidderRequester.java index 61e074ecb26..13cc63a666c 100644 --- a/src/main/java/org/prebid/server/bidder/HttpBidderRequester.java +++ b/src/main/java/org/prebid/server/bidder/HttpBidderRequester.java @@ -8,8 +8,8 @@ import io.vertx.core.MultiMap; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import org.prebid.server.auction.aliases.BidderAliases; import org.prebid.server.auction.ExchangeService; +import org.prebid.server.auction.aliases.BidderAliases; import org.prebid.server.auction.model.BidRejectionReason; import org.prebid.server.auction.model.BidRejectionTracker; import org.prebid.server.auction.model.BidderRequest; @@ -18,7 +18,6 @@ import org.prebid.server.bidder.model.BidderCallType; import org.prebid.server.bidder.model.BidderError; import org.prebid.server.bidder.model.BidderSeatBid; -import org.prebid.server.bidder.model.CompositeBidderResponse; import org.prebid.server.bidder.model.HttpRequest; import org.prebid.server.bidder.model.HttpResponse; import org.prebid.server.bidder.model.Result; @@ -30,8 +29,6 @@ import org.prebid.server.log.LoggerFactory; import org.prebid.server.model.CaseInsensitiveMultiMap; import org.prebid.server.proto.openrtb.ext.response.ExtHttpCall; -import org.prebid.server.proto.openrtb.ext.response.ExtIgi; -import org.prebid.server.proto.openrtb.ext.response.FledgeAuctionConfig; import org.prebid.server.util.HttpUtil; import org.prebid.server.vertx.httpclient.HttpClient; import org.prebid.server.vertx.httpclient.model.HttpClientResponse; @@ -191,9 +188,7 @@ private Future emptyBidderSeatBidWithErrors(List bid "The bidder failed to generate any bid requests, but also failed to generate an error")) : bidderErrors; - return Future.succeededFuture(BidderSeatBid.builder() - .errors(errors) - .build()); + return Future.succeededFuture(BidderSeatBid.builder().errors(errors).build()); } /** @@ -296,10 +291,7 @@ private Void processHttpCall(Bidder bidder, return null; } - /** - * Returns result based on response status code, list of {@link BidderBid}s and other data from bidder. - */ - private static CompositeBidderResponse makeBids(Bidder bidder, + private static Result> makeBids(Bidder bidder, BidderCall httpCall, BidRequest bidRequest) { @@ -309,13 +301,13 @@ private static CompositeBidderResponse makeBids(Bidder bidder, final int statusCode = httpCall.getResponse().getStatusCode(); if (statusCode == HttpResponseStatus.NO_CONTENT.code()) { - return CompositeBidderResponse.empty(); + return Result.empty(); } if (statusCode != HttpResponseStatus.OK.code()) { return null; } - return bidder.makeBidderResponse(toHttpCallWithSafeResponseBody(httpCall), bidRequest); + return bidder.makeBids(toHttpCallWithSafeResponseBody(httpCall), bidRequest); } /** @@ -346,8 +338,6 @@ private static class ResultBuilder { private final Map, BidderCall> bidderCallsRecorded = new HashMap<>(); private final List bidsRecorded = new ArrayList<>(); private final List errorsRecorded = new ArrayList<>(); - private final List igiRecorded = new ArrayList<>(); - private final List fledgeRecorded = new ArrayList<>(); ResultBuilder(List> httpRequests, List previousErrors, @@ -362,17 +352,15 @@ private static class ResultBuilder { this.mapper = mapper; } - void addHttpCall(BidderCall bidderCall, CompositeBidderResponse bidderResponse) { + void addHttpCall(BidderCall bidderCall, Result> bidderResponse) { bidderCallsRecorded.put(bidderCall.getRequest(), bidderCall); handleBids(bidderResponse); handleBidderErrors(bidderResponse); handleBidderCallError(bidderCall); - handleIgis(bidderResponse); - handleFledgeAuctionConfigs(bidderResponse); } - private void handleBids(CompositeBidderResponse bidderResponse) { - final List bids = bidderResponse != null ? bidderResponse.getBids() : null; + private void handleBids(Result> bidderResponse) { + final List bids = bidderResponse != null ? bidderResponse.getValue() : null; if (bids != null) { bidsRecorded.addAll(bids); completionTracker.processBids(bids); @@ -380,7 +368,7 @@ private void handleBids(CompositeBidderResponse bidderResponse) { } } - private void handleBidderErrors(CompositeBidderResponse bidderResponse) { + private void handleBidderErrors(Result> bidderResponse) { final List bidderErrors = bidderResponse != null ? bidderResponse.getErrors() : null; if (bidderErrors != null) { errorsRecorded.addAll(bidderErrors); @@ -425,18 +413,6 @@ private void handleBidderCallError(BidderCall bidderCall) { bidRejectionTracker.rejectImps(requestedImpIds, reason); } - private void handleFledgeAuctionConfigs(CompositeBidderResponse bidderResponse) { - Optional.ofNullable(bidderResponse) - .map(CompositeBidderResponse::getFledgeAuctionConfigs) - .ifPresent(fledgeRecorded::addAll); - } - - private void handleIgis(CompositeBidderResponse bidderResponse) { - Optional.ofNullable(bidderResponse) - .map(CompositeBidderResponse::getIgi) - .ifPresent(igiRecorded::addAll); - } - BidderSeatBid toBidderSeatBid(boolean debugEnabled) { final List> httpCalls = new ArrayList<>(bidderCallsRecorded.values()); httpRequests.stream() @@ -454,8 +430,6 @@ BidderSeatBid toBidderSeatBid(boolean debugEnabled) { .bids(bidsRecorded) .httpCalls(extHttpCalls) .errors(errors) - .igi(igiRecorded) - .fledgeAuctionConfigs(fledgeRecorded) .build(); } diff --git a/src/main/java/org/prebid/server/bidder/consumable/ConsumableBidder.java b/src/main/java/org/prebid/server/bidder/consumable/ConsumableBidder.java index 605abaf6331..31b75e4980f 100644 --- a/src/main/java/org/prebid/server/bidder/consumable/ConsumableBidder.java +++ b/src/main/java/org/prebid/server/bidder/consumable/ConsumableBidder.java @@ -17,7 +17,6 @@ import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.bidder.model.BidderCall; import org.prebid.server.bidder.model.BidderError; -import org.prebid.server.bidder.model.CompositeBidderResponse; import org.prebid.server.bidder.model.HttpRequest; import org.prebid.server.bidder.model.Result; import org.prebid.server.exception.PreBidException; @@ -116,23 +115,13 @@ private static MultiMap resolveHeaders() { } @Override - @Deprecated(since = "Not used, since Bidder.makeBidderResponse(...) was overridden.") public Result> makeBids(BidderCall httpCall, BidRequest bidRequest) { - return Result.withError(BidderError.generic("Invalid method call")); - } - - @Override - public CompositeBidderResponse makeBidderResponse(BidderCall httpCall, BidRequest bidRequest) { try { - final BidResponse bidResponse = mapper.decodeValue(httpCall.getResponse().getBody(), BidResponse.class); final List errors = new ArrayList<>(); - - return CompositeBidderResponse.builder() - .bids(extractConsumableBids(bidRequest, bidResponse, errors)) - .errors(errors) - .build(); + final BidResponse bidResponse = mapper.decodeValue(httpCall.getResponse().getBody(), BidResponse.class); + return Result.of(extractConsumableBids(bidRequest, bidResponse, errors), errors); } catch (DecodeException e) { - return CompositeBidderResponse.withError(BidderError.badServerResponse(e.getMessage())); + return Result.withError(BidderError.badServerResponse(e.getMessage())); } } diff --git a/src/main/java/org/prebid/server/bidder/criteo/CriteoBidResponse.java b/src/main/java/org/prebid/server/bidder/criteo/CriteoBidResponse.java deleted file mode 100644 index d6f43ef4c86..00000000000 --- a/src/main/java/org/prebid/server/bidder/criteo/CriteoBidResponse.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.prebid.server.bidder.criteo; - -import com.iab.openrtb.response.SeatBid; -import lombok.Builder; -import lombok.Value; - -import java.util.List; - -@Builder(toBuilder = true) -@Value -public class CriteoBidResponse { - - String id; - - List seatbid; - - String bidid; - - String cur; - - String customdata; - - Integer nbr; - - CriteoExtBidResponse ext; - -} diff --git a/src/main/java/org/prebid/server/bidder/criteo/CriteoBidder.java b/src/main/java/org/prebid/server/bidder/criteo/CriteoBidder.java index 9bf68e89e24..1afc5d9fa98 100644 --- a/src/main/java/org/prebid/server/bidder/criteo/CriteoBidder.java +++ b/src/main/java/org/prebid/server/bidder/criteo/CriteoBidder.java @@ -4,13 +4,13 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.iab.openrtb.request.BidRequest; import com.iab.openrtb.response.Bid; +import com.iab.openrtb.response.BidResponse; import com.iab.openrtb.response.SeatBid; import org.apache.commons.collections4.CollectionUtils; import org.prebid.server.bidder.Bidder; import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.bidder.model.BidderCall; import org.prebid.server.bidder.model.BidderError; -import org.prebid.server.bidder.model.CompositeBidderResponse; import org.prebid.server.bidder.model.HttpRequest; import org.prebid.server.bidder.model.Result; import org.prebid.server.exception.PreBidException; @@ -19,7 +19,6 @@ import org.prebid.server.proto.openrtb.ext.response.BidType; import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebid; import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidMeta; -import org.prebid.server.proto.openrtb.ext.response.ExtIgi; import org.prebid.server.util.BidderUtil; import org.prebid.server.util.HttpUtil; @@ -45,27 +44,18 @@ public Result>> makeHttpRequests(BidRequest bidRequ } @Override - @Deprecated(forRemoval = true) public Result> makeBids(BidderCall httpCall, BidRequest bidRequest) { - return Result.withError(BidderError.generic("Deprecated adapter method invoked")); - } - - @Override - public CompositeBidderResponse makeBidderResponse(BidderCall httpCall, BidRequest bidRequest) { try { - final CriteoBidResponse bidResponse = mapper.decodeValue( - httpCall.getResponse().getBody(), CriteoBidResponse.class); + final BidResponse bidResponse = mapper.decodeValue( + httpCall.getResponse().getBody(), BidResponse.class); - return CompositeBidderResponse.builder() - .bids(extractBids(bidResponse)) - .igi(extractIgi(bidResponse)) - .build(); + return Result.withValues(extractBids(bidResponse)); } catch (DecodeException | PreBidException e) { - return CompositeBidderResponse.withError(BidderError.badServerResponse(e.getMessage())); + return Result.withError(BidderError.badServerResponse(e.getMessage())); } } - private List extractBids(CriteoBidResponse bidResponse) { + private List extractBids(BidResponse bidResponse) { if (bidResponse == null || CollectionUtils.isEmpty(bidResponse.getSeatbid())) { return Collections.emptyList(); } @@ -106,12 +96,4 @@ private ObjectNode makeExt(String networkName) { .meta(ExtBidPrebidMeta.builder().networkName(networkName).build()) .build()); } - - private static List extractIgi(CriteoBidResponse bidResponse) { - return Optional.ofNullable(bidResponse) - .map(CriteoBidResponse::getExt) - .map(CriteoExtBidResponse::getIgi) - .filter(CollectionUtils::isNotEmpty) - .orElse(Collections.emptyList()); - } } diff --git a/src/main/java/org/prebid/server/bidder/criteo/CriteoExtBidResponse.java b/src/main/java/org/prebid/server/bidder/criteo/CriteoExtBidResponse.java deleted file mode 100644 index dda26a73ef7..00000000000 --- a/src/main/java/org/prebid/server/bidder/criteo/CriteoExtBidResponse.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.prebid.server.bidder.criteo; - -import lombok.Value; -import org.prebid.server.proto.openrtb.ext.response.ExtIgi; - -import java.util.List; - -@Value(staticConstructor = "of") -public class CriteoExtBidResponse { - - List igi; -} diff --git a/src/main/java/org/prebid/server/bidder/ix/IxBidder.java b/src/main/java/org/prebid/server/bidder/ix/IxBidder.java index fcfc8a729a3..7c0ad863a34 100644 --- a/src/main/java/org/prebid/server/bidder/ix/IxBidder.java +++ b/src/main/java/org/prebid/server/bidder/ix/IxBidder.java @@ -15,19 +15,17 @@ import com.iab.openrtb.request.ntv.EventTrackingMethod; import com.iab.openrtb.request.ntv.EventType; import com.iab.openrtb.response.Bid; +import com.iab.openrtb.response.BidResponse; import com.iab.openrtb.response.EventTracker; import com.iab.openrtb.response.Response; import com.iab.openrtb.response.SeatBid; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.prebid.server.bidder.Bidder; -import org.prebid.server.bidder.ix.model.response.IxBidResponse; -import org.prebid.server.bidder.ix.model.response.IxExtBidResponse; import org.prebid.server.bidder.ix.model.response.NativeV11Wrapper; import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.bidder.model.BidderCall; import org.prebid.server.bidder.model.BidderError; -import org.prebid.server.bidder.model.CompositeBidderResponse; import org.prebid.server.bidder.model.HttpRequest; import org.prebid.server.bidder.model.Result; import org.prebid.server.exception.PreBidException; @@ -41,8 +39,6 @@ import org.prebid.server.proto.openrtb.ext.request.ix.ExtImpIx; import org.prebid.server.proto.openrtb.ext.response.BidType; import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidVideo; -import org.prebid.server.proto.openrtb.ext.response.ExtIgi; -import org.prebid.server.proto.openrtb.ext.response.ExtIgiIgs; import org.prebid.server.util.BidderUtil; import org.prebid.server.util.HttpUtil; import org.prebid.server.util.ObjectUtil; @@ -243,29 +239,18 @@ private ObjectNode makeDiagData(ExtRequest extRequest, Set siteIds) { } @Override - @Deprecated(since = "Not used, since Bidder.makeBidderResponse(...) was overridden.") public Result> makeBids(BidderCall httpCall, BidRequest bidRequest) { - return Result.withError(BidderError.generic("Invalid method call")); - } - - @Override - public CompositeBidderResponse makeBidderResponse(BidderCall httpCall, BidRequest bidRequest) { try { - final IxBidResponse bidResponse = mapper.decodeValue(httpCall.getResponse().getBody(), IxBidResponse.class); final List errors = new ArrayList<>(); - - return CompositeBidderResponse.builder() - .bids(extractBids(bidRequest, bidResponse, errors)) - .igi(extractIgi(bidResponse)) - .errors(errors) - .build(); + final BidResponse bidResponse = mapper.decodeValue(httpCall.getResponse().getBody(), BidResponse.class); + return Result.of(extractBids(bidRequest, bidResponse, errors), errors); } catch (DecodeException e) { - return CompositeBidderResponse.withError(BidderError.badServerResponse(e.getMessage())); + return Result.withError(BidderError.badServerResponse(e.getMessage())); } } private List extractBids(BidRequest bidRequest, - IxBidResponse bidResponse, + BidResponse bidResponse, List errors) { if (bidResponse == null || CollectionUtils.isEmpty(bidResponse.getSeatbid())) { @@ -283,7 +268,7 @@ private List extractBids(BidRequest bidRequest, .toList(); } - private BidderBid toBidderBid(Bid bid, BidRequest bidRequest, IxBidResponse bidResponse, List errors) { + private BidderBid toBidderBid(Bid bid, BidRequest bidRequest, BidResponse bidResponse, List errors) { final BidType bidType; try { bidType = getBidType(bid, bidRequest.getImp()); @@ -368,8 +353,8 @@ private ExtBidPrebidVideo parseBidExtPrebidVideo(ObjectNode bidExt) { private Bid updateBidWithVideoAttributes(Bid bid, ExtBidPrebidVideo extBidPrebidVideo) { return CollectionUtils.isEmpty(bid.getCat()) && extBidPrebidVideo != null ? bid.toBuilder() - .cat(Collections.singletonList(extBidPrebidVideo.getPrimaryCategory())) - .build() + .cat(Collections.singletonList(extBidPrebidVideo.getPrimaryCategory())) + .build() : bid; } @@ -428,17 +413,4 @@ private static ExtBidPrebidVideo videoInfo(ExtBidPrebidVideo extBidPrebidVideo) ? ExtBidPrebidVideo.of(extBidPrebidVideo.getDuration(), null) : null; } - - private List extractIgi(IxBidResponse bidResponse) { - final List igs = Optional.ofNullable(bidResponse) - .map(IxBidResponse::getExt) - .map(IxExtBidResponse::getProtectedAudienceAuctionConfigs) - .orElse(Collections.emptyList()) - .stream() - .filter(Objects::nonNull) - .map(config -> ExtIgiIgs.builder().impId(config.getBidId()).config(config.getConfig()).build()) - .toList(); - - return igs.isEmpty() ? null : Collections.singletonList(ExtIgi.builder().igs(igs).build()); - } } diff --git a/src/main/java/org/prebid/server/bidder/ix/model/response/AuctionConfigExtBidResponse.java b/src/main/java/org/prebid/server/bidder/ix/model/response/AuctionConfigExtBidResponse.java deleted file mode 100644 index 709fab87429..00000000000 --- a/src/main/java/org/prebid/server/bidder/ix/model/response/AuctionConfigExtBidResponse.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.prebid.server.bidder.ix.model.response; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.node.ObjectNode; -import lombok.Value; - -@Value(staticConstructor = "of") -public class AuctionConfigExtBidResponse { - - @JsonProperty("bidId") - String bidId; - - ObjectNode config; -} diff --git a/src/main/java/org/prebid/server/bidder/ix/model/response/IxBidResponse.java b/src/main/java/org/prebid/server/bidder/ix/model/response/IxBidResponse.java deleted file mode 100644 index 0bbbace5f81..00000000000 --- a/src/main/java/org/prebid/server/bidder/ix/model/response/IxBidResponse.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.prebid.server.bidder.ix.model.response; - -import com.iab.openrtb.response.SeatBid; -import lombok.Builder; -import lombok.Value; - -import java.util.List; - -@Builder(toBuilder = true) -@Value -public class IxBidResponse { - - String id; - - List seatbid; - - String bidid; - - String cur; - - String customdata; - - Integer nbr; - - IxExtBidResponse ext; -} diff --git a/src/main/java/org/prebid/server/bidder/ix/model/response/IxExtBidResponse.java b/src/main/java/org/prebid/server/bidder/ix/model/response/IxExtBidResponse.java deleted file mode 100644 index c586817df2c..00000000000 --- a/src/main/java/org/prebid/server/bidder/ix/model/response/IxExtBidResponse.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.prebid.server.bidder.ix.model.response; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Value; - -import java.util.List; - -@Value(staticConstructor = "of") -public class IxExtBidResponse { - - @JsonProperty("protectedAudienceAuctionConfigs") - List protectedAudienceAuctionConfigs; - -} diff --git a/src/main/java/org/prebid/server/bidder/medianet/MedianetBidder.java b/src/main/java/org/prebid/server/bidder/medianet/MedianetBidder.java index a82d6a72e63..adb208364ab 100644 --- a/src/main/java/org/prebid/server/bidder/medianet/MedianetBidder.java +++ b/src/main/java/org/prebid/server/bidder/medianet/MedianetBidder.java @@ -3,24 +3,19 @@ import com.iab.openrtb.request.BidRequest; import com.iab.openrtb.request.Imp; import com.iab.openrtb.response.Bid; +import com.iab.openrtb.response.BidResponse; import com.iab.openrtb.response.SeatBid; import org.apache.commons.collections4.CollectionUtils; import org.prebid.server.bidder.Bidder; -import org.prebid.server.bidder.medianet.model.response.InterestGroupAuctionIntent; -import org.prebid.server.bidder.medianet.model.response.MedianetBidResponse; -import org.prebid.server.bidder.medianet.model.response.MedianetBidResponseExt; import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.bidder.model.BidderCall; import org.prebid.server.bidder.model.BidderError; -import org.prebid.server.bidder.model.CompositeBidderResponse; import org.prebid.server.bidder.model.HttpRequest; import org.prebid.server.bidder.model.Result; import org.prebid.server.exception.PreBidException; import org.prebid.server.json.DecodeException; import org.prebid.server.json.JacksonMapper; import org.prebid.server.proto.openrtb.ext.response.BidType; -import org.prebid.server.proto.openrtb.ext.response.ExtIgi; -import org.prebid.server.proto.openrtb.ext.response.ExtIgiIgs; import org.prebid.server.util.BidderUtil; import org.prebid.server.util.HttpUtil; @@ -29,7 +24,6 @@ import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.Optional; public class MedianetBidder implements Bidder { @@ -46,34 +40,23 @@ public Result>> makeHttpRequests(BidRequest bidRequ return Result.withValue(BidderUtil.defaultRequest(bidRequest, endpointUrl, mapper)); } - /** - * @deprecated for this bidder in favor of @link{makeBidderResponse} which supports additional response data - */ @Override - @Deprecated(forRemoval = true) public Result> makeBids(BidderCall httpCall, BidRequest bidRequest) { - return Result.withError(BidderError.generic("Deprecated adapter method invoked")); - } - - @Override - public final CompositeBidderResponse makeBidderResponse(BidderCall httpCall, BidRequest bidRequest) { - final MedianetBidResponse bidResponse; + final BidResponse bidResponse; try { - bidResponse = mapper.decodeValue(httpCall.getResponse().getBody(), MedianetBidResponse.class); + bidResponse = mapper.decodeValue(httpCall.getResponse().getBody(), BidResponse.class); } catch (DecodeException e) { - return CompositeBidderResponse.withError(BidderError.badServerResponse(e.getMessage())); + return Result.withError(BidderError.badServerResponse(e.getMessage())); } final List errors = new ArrayList<>(); - return CompositeBidderResponse.builder() - .bids(extractBids(httpCall.getRequest().getPayload(), bidResponse, errors)) - .igi(extractIgi(bidResponse)) - .errors(errors) - .build(); + return Result.of(extractBids(httpCall.getRequest().getPayload(), bidResponse, errors), errors); } - private static List extractBids(BidRequest bidRequest, MedianetBidResponse bidResponse, + private static List extractBids(BidRequest bidRequest, + BidResponse bidResponse, List errors) { + if (bidResponse == null || CollectionUtils.isEmpty(bidResponse.getSeatbid())) { return Collections.emptyList(); } @@ -135,18 +118,4 @@ private static BidType resolveBidTypeFromImpId(String impId, List imps) { return BidType.banner; } - - private static List extractIgi(MedianetBidResponse bidResponse) { - final List igs = Optional.ofNullable(bidResponse) - .map(MedianetBidResponse::getExt) - .map(MedianetBidResponseExt::getIgi) - .orElse(Collections.emptyList()) - .stream() - .map(InterestGroupAuctionIntent::getIgs) - .flatMap(Collection::stream) - .map(igiIgs -> ExtIgiIgs.builder().impId(igiIgs.getImpId()).config(igiIgs.getConfig()).build()) - .toList(); - - return igs.isEmpty() ? null : Collections.singletonList(ExtIgi.builder().igs(igs).build()); - } } diff --git a/src/main/java/org/prebid/server/bidder/medianet/model/response/InterestGroupAuctionBuyer.java b/src/main/java/org/prebid/server/bidder/medianet/model/response/InterestGroupAuctionBuyer.java deleted file mode 100644 index 04340fd8321..00000000000 --- a/src/main/java/org/prebid/server/bidder/medianet/model/response/InterestGroupAuctionBuyer.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.prebid.server.bidder.medianet.model.response; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.node.ObjectNode; -import lombok.Value; - -@Value -public class InterestGroupAuctionBuyer { - - String origin; - - @JsonProperty("maxbid") - Double maxBid; - - @JsonProperty("cur") - String currency; - - @JsonProperty("pbs") - String buyerSignals; - - @JsonProperty("ps") - ObjectNode prioritySignals; -} diff --git a/src/main/java/org/prebid/server/bidder/medianet/model/response/InterestGroupAuctionIntent.java b/src/main/java/org/prebid/server/bidder/medianet/model/response/InterestGroupAuctionIntent.java deleted file mode 100644 index e060c1fb5dd..00000000000 --- a/src/main/java/org/prebid/server/bidder/medianet/model/response/InterestGroupAuctionIntent.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.prebid.server.bidder.medianet.model.response; - -import lombok.Builder; -import lombok.Value; - -import java.util.List; - -@Builder -@Value -public class InterestGroupAuctionIntent { - - List igb; - - List igs; -} diff --git a/src/main/java/org/prebid/server/bidder/medianet/model/response/InterestGroupAuctionSeller.java b/src/main/java/org/prebid/server/bidder/medianet/model/response/InterestGroupAuctionSeller.java deleted file mode 100644 index 15ae3ade13b..00000000000 --- a/src/main/java/org/prebid/server/bidder/medianet/model/response/InterestGroupAuctionSeller.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.prebid.server.bidder.medianet.model.response; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.node.ObjectNode; -import lombok.Builder; -import lombok.Value; - -@Builder -@Value -public class InterestGroupAuctionSeller { - - @JsonProperty(value = "impid") - String impId; - - ObjectNode config; -} diff --git a/src/main/java/org/prebid/server/bidder/medianet/model/response/MedianetBidResponse.java b/src/main/java/org/prebid/server/bidder/medianet/model/response/MedianetBidResponse.java deleted file mode 100644 index 4677294e6fc..00000000000 --- a/src/main/java/org/prebid/server/bidder/medianet/model/response/MedianetBidResponse.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.prebid.server.bidder.medianet.model.response; - -import com.iab.openrtb.response.SeatBid; -import lombok.Builder; -import lombok.Value; - -import java.util.List; - -@Value -@Builder -public class MedianetBidResponse { - - String id; - - List seatbid; - - String bidid; - - String cur; - - String customdata; - - Integer nbr; - - MedianetBidResponseExt ext; -} diff --git a/src/main/java/org/prebid/server/bidder/medianet/model/response/MedianetBidResponseExt.java b/src/main/java/org/prebid/server/bidder/medianet/model/response/MedianetBidResponseExt.java deleted file mode 100644 index 2ce5775704c..00000000000 --- a/src/main/java/org/prebid/server/bidder/medianet/model/response/MedianetBidResponseExt.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.prebid.server.bidder.medianet.model.response; - -import lombok.Value; - -import java.util.List; - -@Value(staticConstructor = "of") -public class MedianetBidResponseExt { - - List igi; -} diff --git a/src/main/java/org/prebid/server/bidder/model/BidderSeatBid.java b/src/main/java/org/prebid/server/bidder/model/BidderSeatBid.java index 8022b8667f1..4b760c40cd5 100644 --- a/src/main/java/org/prebid/server/bidder/model/BidderSeatBid.java +++ b/src/main/java/org/prebid/server/bidder/model/BidderSeatBid.java @@ -4,8 +4,6 @@ import lombok.Value; import org.prebid.server.bidder.Bidder; import org.prebid.server.proto.openrtb.ext.response.ExtHttpCall; -import org.prebid.server.proto.openrtb.ext.response.ExtIgi; -import org.prebid.server.proto.openrtb.ext.response.FledgeAuctionConfig; import java.util.Collections; import java.util.List; @@ -54,13 +52,6 @@ public class BidderSeatBid { @Builder.Default List warnings = Collections.emptyList(); - @Deprecated - @Builder.Default - List fledgeAuctionConfigs = Collections.emptyList(); - - @Builder.Default - List igi = Collections.emptyList(); - public BidderSeatBid with(List bids) { return toBuilder().bids(bids).build(); } diff --git a/src/main/java/org/prebid/server/bidder/model/BidderSeatBidInfo.java b/src/main/java/org/prebid/server/bidder/model/BidderSeatBidInfo.java index 38c9f86433c..9186e03f04b 100644 --- a/src/main/java/org/prebid/server/bidder/model/BidderSeatBidInfo.java +++ b/src/main/java/org/prebid/server/bidder/model/BidderSeatBidInfo.java @@ -3,8 +3,6 @@ import lombok.Value; import org.prebid.server.auction.model.BidInfo; import org.prebid.server.proto.openrtb.ext.response.ExtHttpCall; -import org.prebid.server.proto.openrtb.ext.response.ExtIgi; -import org.prebid.server.proto.openrtb.ext.response.FledgeAuctionConfig; import java.util.List; @@ -19,18 +17,11 @@ public class BidderSeatBidInfo { List warnings; - @Deprecated(forRemoval = true) - List fledgeAuctionConfigs; - - List igi; - public BidderSeatBidInfo with(List bids) { return BidderSeatBidInfo.of( bids, this.httpCalls, this.errors, - this.warnings, - this.fledgeAuctionConfigs, - this.igi); + this.warnings); } } diff --git a/src/main/java/org/prebid/server/bidder/model/CompositeBidderResponse.java b/src/main/java/org/prebid/server/bidder/model/CompositeBidderResponse.java deleted file mode 100644 index 75a71e0864a..00000000000 --- a/src/main/java/org/prebid/server/bidder/model/CompositeBidderResponse.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.prebid.server.bidder.model; - -import lombok.Builder; -import lombok.Value; -import org.prebid.server.bidder.Bidder; -import org.prebid.server.proto.openrtb.ext.response.ExtIgi; -import org.prebid.server.proto.openrtb.ext.response.FledgeAuctionConfig; - -import java.util.Collections; -import java.util.List; - -/** - * Composite bidder response (bids + other data) returned by a {@link Bidder}. - */ -@Value -@Builder(toBuilder = true) -public class CompositeBidderResponse { - - @Builder.Default - List bids = Collections.emptyList(); - - @Builder.Default - List errors = Collections.emptyList(); - - /** - * FLEDGE interest group bids passback - */ - List fledgeAuctionConfigs; - - List igi; - - public static CompositeBidderResponse empty() { - return builder().build(); - } - - public static CompositeBidderResponse withError(BidderError error) { - return builder().errors(Collections.singletonList(error)).build(); - } -} diff --git a/src/main/java/org/prebid/server/bidder/openx/OpenxBidder.java b/src/main/java/org/prebid/server/bidder/openx/OpenxBidder.java index 00a8c8dc3fb..6483b491a61 100644 --- a/src/main/java/org/prebid/server/bidder/openx/OpenxBidder.java +++ b/src/main/java/org/prebid/server/bidder/openx/OpenxBidder.java @@ -5,6 +5,7 @@ import com.iab.openrtb.request.BidRequest; import com.iab.openrtb.request.Imp; import com.iab.openrtb.response.Bid; +import com.iab.openrtb.response.BidResponse; import com.iab.openrtb.response.SeatBid; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; @@ -13,13 +14,10 @@ import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.bidder.model.BidderCall; import org.prebid.server.bidder.model.BidderError; -import org.prebid.server.bidder.model.CompositeBidderResponse; import org.prebid.server.bidder.model.HttpRequest; import org.prebid.server.bidder.model.Result; import org.prebid.server.bidder.openx.model.OpenxImpType; import org.prebid.server.bidder.openx.proto.OpenxBidExt; -import org.prebid.server.bidder.openx.proto.OpenxBidResponse; -import org.prebid.server.bidder.openx.proto.OpenxBidResponseExt; import org.prebid.server.bidder.openx.proto.OpenxRequestExt; import org.prebid.server.bidder.openx.proto.OpenxVideoExt; import org.prebid.server.exception.PreBidException; @@ -33,8 +31,6 @@ import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebid; import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidMeta; import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidVideo; -import org.prebid.server.proto.openrtb.ext.response.ExtIgi; -import org.prebid.server.proto.openrtb.ext.response.ExtIgiIgs; import org.prebid.server.util.BidderUtil; import org.prebid.server.util.HttpUtil; @@ -45,7 +41,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -90,29 +85,15 @@ public Result>> makeHttpRequests(BidRequest bidRequ } @Override - public CompositeBidderResponse makeBidderResponse(BidderCall httpCall, BidRequest bidRequest) { + public Result> makeBids(BidderCall httpCall, BidRequest bidRequest) { try { - final OpenxBidResponse bidResponse = mapper.decodeValue( - httpCall.getResponse().getBody(), OpenxBidResponse.class); - - return CompositeBidderResponse.builder() - .bids(extractBids(bidRequest, bidResponse)) - .igi(extractIgi(bidResponse)) - .build(); + final BidResponse bidResponse = mapper.decodeValue(httpCall.getResponse().getBody(), BidResponse.class); + return Result.withValues(extractBids(bidRequest, bidResponse)); } catch (DecodeException e) { - return CompositeBidderResponse.withError(BidderError.badServerResponse(e.getMessage())); + return Result.withError(BidderError.badServerResponse(e.getMessage())); } } - /** - * @deprecated for this bidder in favor of @link{makeBidderResponse} which supports additional response data - */ - @Override - @Deprecated(forRemoval = true) - public Result> makeBids(BidderCall httpCall, BidRequest bidRequest) { - return Result.withError(BidderError.generic("Deprecated adapter method invoked")); - } - private List makeRequests( BidRequest bidRequest, List bannerImps, @@ -206,9 +187,9 @@ private BidRequest createSingleRequest(List imps, BidRequest bidRequest, Li return CollectionUtils.isNotEmpty(processedImps) ? bidRequest.toBuilder() - .imp(processedImps) - .ext(makeReqExt(imps.getFirst())) - .build() + .imp(processedImps) + .ext(makeReqExt(imps.getFirst())) + .build() : null; } @@ -273,13 +254,13 @@ private ObjectNode makeImpExt(ObjectNode impExt, boolean addCustomParams) { return openxImpExt; } - private List extractBids(BidRequest bidRequest, OpenxBidResponse bidResponse) { + private List extractBids(BidRequest bidRequest, BidResponse bidResponse) { return bidResponse == null || CollectionUtils.isEmpty(bidResponse.getSeatbid()) ? Collections.emptyList() : bidsFromResponse(bidRequest, bidResponse); } - private List bidsFromResponse(BidRequest bidRequest, OpenxBidResponse bidResponse) { + private List bidsFromResponse(BidRequest bidRequest, BidResponse bidResponse) { final Map impIdToBidType = impIdToBidType(bidRequest); final String bidCurrency = StringUtils.isNotBlank(bidResponse.getCur()) @@ -325,19 +306,6 @@ private static BidType getBidType(Bid bid, Map impIdToBidType) }; } - private static List extractIgi(OpenxBidResponse bidResponse) { - final List igs = Optional.ofNullable(bidResponse) - .map(OpenxBidResponse::getExt) - .map(OpenxBidResponseExt::getFledgeAuctionConfigs) - .orElse(Collections.emptyMap()) - .entrySet() - .stream() - .map(ext -> ExtIgiIgs.builder().impId(ext.getKey()).config(ext.getValue()).build()) - .toList(); - - return igs.isEmpty() ? null : Collections.singletonList(ExtIgi.builder().igs(igs).build()); - } - private ObjectNode getBidExt(Bid bid) { final ObjectNode ext = bid.getExt(); if (ext == null) { diff --git a/src/main/java/org/prebid/server/bidder/openx/proto/OpenxBidResponse.java b/src/main/java/org/prebid/server/bidder/openx/proto/OpenxBidResponse.java deleted file mode 100644 index 9be5a61e30d..00000000000 --- a/src/main/java/org/prebid/server/bidder/openx/proto/OpenxBidResponse.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.prebid.server.bidder.openx.proto; - -import com.iab.openrtb.response.SeatBid; -import lombok.Builder; -import lombok.Value; - -import java.util.List; - -@Value -@Builder -public class OpenxBidResponse { - - String id; - - List seatbid; - - String cur; - - Integer nbr; - - OpenxBidResponseExt ext; -} diff --git a/src/main/java/org/prebid/server/bidder/openx/proto/OpenxBidResponseExt.java b/src/main/java/org/prebid/server/bidder/openx/proto/OpenxBidResponseExt.java deleted file mode 100644 index c52ad9ef9c4..00000000000 --- a/src/main/java/org/prebid/server/bidder/openx/proto/OpenxBidResponseExt.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.prebid.server.bidder.openx.proto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.node.ObjectNode; -import lombok.Value; - -import java.util.Map; - -@Value(staticConstructor = "of") -public class OpenxBidResponseExt { - - @JsonProperty("fledge_auction_configs") - Map fledgeAuctionConfigs; -} diff --git a/src/main/java/org/prebid/server/bidder/pubmatic/PubmaticBidder.java b/src/main/java/org/prebid/server/bidder/pubmatic/PubmaticBidder.java index 7b8be79fa7d..16c3f27e2f5 100644 --- a/src/main/java/org/prebid/server/bidder/pubmatic/PubmaticBidder.java +++ b/src/main/java/org/prebid/server/bidder/pubmatic/PubmaticBidder.java @@ -11,6 +11,7 @@ import com.iab.openrtb.request.Publisher; import com.iab.openrtb.request.Site; import com.iab.openrtb.response.Bid; +import com.iab.openrtb.response.BidResponse; import com.iab.openrtb.response.SeatBid; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; @@ -23,7 +24,6 @@ import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.bidder.model.BidderCall; import org.prebid.server.bidder.model.BidderError; -import org.prebid.server.bidder.model.CompositeBidderResponse; import org.prebid.server.bidder.model.HttpRequest; import org.prebid.server.bidder.model.Result; import org.prebid.server.bidder.pubmatic.model.request.PubmaticBidderImpExt; @@ -31,8 +31,6 @@ import org.prebid.server.bidder.pubmatic.model.request.PubmaticMarketplace; import org.prebid.server.bidder.pubmatic.model.request.PubmaticWrapper; import org.prebid.server.bidder.pubmatic.model.response.PubmaticBidExt; -import org.prebid.server.bidder.pubmatic.model.response.PubmaticBidResponse; -import org.prebid.server.bidder.pubmatic.model.response.PubmaticExtBidResponse; import org.prebid.server.bidder.pubmatic.model.response.VideoCreativeInfo; import org.prebid.server.exception.PreBidException; import org.prebid.server.json.DecodeException; @@ -48,8 +46,6 @@ import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebid; import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidMeta; import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidVideo; -import org.prebid.server.proto.openrtb.ext.response.ExtIgi; -import org.prebid.server.proto.openrtb.ext.response.ExtIgiIgs; import org.prebid.server.util.BidderUtil; import org.prebid.server.util.HttpUtil; import org.prebid.server.util.StreamUtil; @@ -79,7 +75,6 @@ public class PubmaticBidder implements Bidder { private static final String ACAT_EXT_REQUEST = "acat"; private static final String WRAPPER_EXT_REQUEST = "wrapper"; private static final String BIDDER_NAME = "pubmatic"; - private static final String AE = "ae"; private static final String GP_ID = "gpid"; private static final String SKADN = "skadn"; private static final String IMP_EXT_PBADSLOT = "pbadslot"; @@ -182,8 +177,8 @@ private List extractAcat(JsonNode bidderParams) { return acatNode != null && acatNode.isArray() ? Arrays.stream(mapper.mapper().convertValue(acatNode, String[].class)) - .map(StringUtils::stripToEmpty) - .toList() + .map(StringUtils::stripToEmpty) + .toList() : null; } @@ -330,9 +325,6 @@ private ObjectNode makeKeywords(PubmaticBidderImpExt impExt) { putExtBidderKeywords(keywordsNode, extBidder); putExtDataKeywords(keywordsNode, impExt.getData(), extBidder.getDctr()); - if (impExt.getAe() != null) { - keywordsNode.put(AE, impExt.getAe()); - } if (impExt.getGpId() != null) { keywordsNode.put(GP_ID, impExt.getGpId()); } @@ -393,9 +385,9 @@ private static String buildDctrPart(Map.Entry dctrPart) { : null; final String arrayAsString = valueAsString == null && value.isArray() ? StreamUtil.asStream(value.elements()) - .map(JsonNode::asText) - .map(StringUtils::trim) - .collect(Collectors.joining(",")) + .map(JsonNode::asText) + .map(StringUtils::trim) + .collect(Collectors.joining(",")) : null; final String valuePart = ObjectUtils.firstNonNull(valueAsString, arrayAsString); @@ -417,8 +409,8 @@ private String extractAdUnitCode(ObjectNode extData) { return AD_SERVER_GAM.equals(adServerName) && StringUtils.isNotEmpty(adServerAdSlot) ? adServerAdSlot : Optional.ofNullable(extData.get(IMP_EXT_PBADSLOT)) - .map(JsonNode::asText) - .orElse(null); + .map(JsonNode::asText) + .orElse(null); } private PubmaticExtDataAdServer extractAdServer(ObjectNode extData) { @@ -492,16 +484,16 @@ private BidRequest modifyBidRequest(BidRequest request, private static Site modifySite(Site site, String publisherId) { return publisherId != null && site != null ? site.toBuilder() - .publisher(modifyPublisher(site.getPublisher(), publisherId)) - .build() + .publisher(modifyPublisher(site.getPublisher(), publisherId)) + .build() : site; } private static App modifyApp(App app, String publisherId) { return publisherId != null && app != null ? app.toBuilder() - .publisher(modifyPublisher(app.getPublisher(), publisherId)) - .build() + .publisher(modifyPublisher(app.getPublisher(), publisherId)) + .build() : app; } @@ -536,39 +528,25 @@ private HttpRequest makeHttpRequest(BidRequest request) { return BidderUtil.defaultRequest(request, endpointUrl, mapper); } - /** - * @deprecated for this bidder in favor of @link{makeBidderResponse} which supports additional response data - */ @Override - @Deprecated(forRemoval = true) public Result> makeBids(BidderCall httpCall, BidRequest bidRequest) { - return Result.withError(BidderError.generic("Deprecated adapter method invoked")); - } - - @Override - public CompositeBidderResponse makeBidderResponse(BidderCall httpCall, BidRequest bidRequest) { try { - final PubmaticBidResponse bidResponse = mapper.decodeValue( - httpCall.getResponse().getBody(), PubmaticBidResponse.class); final List errors = new ArrayList<>(); - - return CompositeBidderResponse.builder() - .bids(extractBids(bidResponse, errors)) - .igi(extractIgi(bidResponse)) - .errors(errors) - .build(); + final BidResponse bidResponse = mapper.decodeValue( + httpCall.getResponse().getBody(), BidResponse.class); + return Result.of(extractBids(bidResponse, errors), errors); } catch (DecodeException | PreBidException e) { - return CompositeBidderResponse.withError(BidderError.badServerResponse(e.getMessage())); + return Result.withError(BidderError.badServerResponse(e.getMessage())); } } - private List extractBids(PubmaticBidResponse bidResponse, List bidderErrors) { + private List extractBids(BidResponse bidResponse, List bidderErrors) { return bidResponse == null || CollectionUtils.isEmpty(bidResponse.getSeatbid()) ? Collections.emptyList() : bidsFromResponse(bidResponse, bidderErrors); } - private List bidsFromResponse(PubmaticBidResponse bidResponse, List bidderErrors) { + private List bidsFromResponse(BidResponse bidResponse, List bidderErrors) { return bidResponse.getSeatbid().stream() .filter(Objects::nonNull) .map(SeatBid::getBid) @@ -686,17 +664,4 @@ private static Integer getDealPriority(PubmaticBidExt bidExt) { .map(PubmaticBidExt::getPrebidDealPriority) .orElse(null); } - - private static List extractIgi(PubmaticBidResponse bidResponse) { - final List igs = Optional.ofNullable(bidResponse) - .map(PubmaticBidResponse::getExt) - .map(PubmaticExtBidResponse::getFledgeAuctionConfigs) - .orElse(Collections.emptyMap()) - .entrySet() - .stream() - .map(config -> ExtIgiIgs.builder().impId(config.getKey()).config(config.getValue()).build()) - .toList(); - - return igs.isEmpty() ? null : Collections.singletonList(ExtIgi.builder().igs(igs).build()); - } } diff --git a/src/main/java/org/prebid/server/bidder/pubmatic/model/request/PubmaticBidderImpExt.java b/src/main/java/org/prebid/server/bidder/pubmatic/model/request/PubmaticBidderImpExt.java index 0a248ff8a5b..ef58f131a04 100644 --- a/src/main/java/org/prebid/server/bidder/pubmatic/model/request/PubmaticBidderImpExt.java +++ b/src/main/java/org/prebid/server/bidder/pubmatic/model/request/PubmaticBidderImpExt.java @@ -12,8 +12,6 @@ public class PubmaticBidderImpExt { ObjectNode data; - Integer ae; - @JsonProperty("gpid") String gpId; diff --git a/src/main/java/org/prebid/server/bidder/pubmatic/model/response/PubmaticBidResponse.java b/src/main/java/org/prebid/server/bidder/pubmatic/model/response/PubmaticBidResponse.java deleted file mode 100644 index b421e7f1b4a..00000000000 --- a/src/main/java/org/prebid/server/bidder/pubmatic/model/response/PubmaticBidResponse.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.prebid.server.bidder.pubmatic.model.response; - -import com.iab.openrtb.response.SeatBid; -import lombok.Builder; -import lombok.Value; - -import java.util.List; - -@Builder(toBuilder = true) -@Value -public class PubmaticBidResponse { - - String id; - - List seatbid; - - String bidid; - - String cur; - - String customdata; - - Integer nbr; - - PubmaticExtBidResponse ext; - -} diff --git a/src/main/java/org/prebid/server/bidder/pubmatic/model/response/PubmaticExtBidResponse.java b/src/main/java/org/prebid/server/bidder/pubmatic/model/response/PubmaticExtBidResponse.java deleted file mode 100644 index d2c531a23b5..00000000000 --- a/src/main/java/org/prebid/server/bidder/pubmatic/model/response/PubmaticExtBidResponse.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.prebid.server.bidder.pubmatic.model.response; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.node.ObjectNode; -import lombok.Value; - -import java.util.Map; - -@Value(staticConstructor = "of") -public class PubmaticExtBidResponse { - - @JsonProperty("fledge_auction_configs") - Map fledgeAuctionConfigs; - -} diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/ExtPrebid.java b/src/main/java/org/prebid/server/proto/openrtb/ext/ExtPrebid.java index 9b656fc180c..b2203113322 100644 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/ExtPrebid.java +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/ExtPrebid.java @@ -1,10 +1,7 @@ package org.prebid.server.proto.openrtb.ext; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Value; import org.prebid.server.bidder.Bidder; -import org.prebid.server.proto.openrtb.ext.request.ExtImpAuctionEnvironment; /** * Defines the contract for any extension that has "prebid" and "bidder" fields. @@ -25,12 +22,4 @@ public class ExtPrebid { * Bidder implementations may safely assume that this extension has been validated by their parameters' schema. */ B bidder; - - @JsonProperty("ae") - @JsonInclude(value = JsonInclude.Include.NON_DEFAULT) - ExtImpAuctionEnvironment auctionEnvironment; - - public static ExtPrebid of(P prebid, B bidder) { - return of(prebid, bidder, null); - } } diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/request/ExtImpAuctionEnvironment.java b/src/main/java/org/prebid/server/proto/openrtb/ext/request/ExtImpAuctionEnvironment.java deleted file mode 100644 index d5249c3d9b1..00000000000 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/request/ExtImpAuctionEnvironment.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.prebid.server.proto.openrtb.ext.request; - -import com.fasterxml.jackson.annotation.JsonFormat; - -/** - * AuctionEnvironment is a Google Privacy Sandbox flag indicating where the auction may take place - */ -@JsonFormat(shape = JsonFormat.Shape.NUMBER_INT) -public enum ExtImpAuctionEnvironment { - - /** - * 0 Standard server-side auction - */ - SERVER_SIDE_AUCTION, - - /** - * 1 On-device interest group auction (FLEDGE) - */ - ON_DEVICE_IG_AUCTION_FLEDGE, - - /** - * 2 Server-side with interest group simulation - */ - SERVER_SIDE_WITH_IG_SIMULATION -} diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/request/ExtRequestPrebid.java b/src/main/java/org/prebid/server/proto/openrtb/ext/request/ExtRequestPrebid.java index 2c30e3a516d..174a3e7a101 100644 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/request/ExtRequestPrebid.java +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/request/ExtRequestPrebid.java @@ -6,7 +6,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.Builder; import lombok.Value; -import org.prebid.server.auction.model.PaaFormat; import org.prebid.server.floors.model.PriceFloorRules; import org.prebid.server.json.deserializer.IntegerFlagDeserializer; @@ -191,12 +190,6 @@ public class ExtRequestPrebid { */ ExtRequestPrebidSdk sdk; - /** - * Defines the contract for bidrequest.ext.prebid.paaformat - */ - @JsonProperty("paaformat") - PaaFormat paaFormat; - @JsonProperty("alternatebiddercodes") ExtRequestPrebidAlternateBidderCodes alternateBidderCodes; diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidResponse.java b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidResponse.java index 6f4b3904fd7..115ce7b3ff9 100644 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidResponse.java +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidResponse.java @@ -48,11 +48,6 @@ public class ExtBidResponse { */ Map usersync; - /** - * Defines the contract for bidresponse.ext.igi - */ - List igi; - /** * Defines the contract for bidresponse.ext.prebid */ diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidResponseFledge.java b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidResponseFledge.java deleted file mode 100644 index 452c3feb0c4..00000000000 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidResponseFledge.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.prebid.server.proto.openrtb.ext.response; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Value; - -import java.util.List; - -/** - * Defines the contract for bidresponse.ext.prebid.fledge (.auctionconfigs[]) - */ -@Value(staticConstructor = "of") -public class ExtBidResponseFledge { - - @JsonProperty("auctionconfigs") - List auctionConfigs; -} diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidResponsePrebid.java b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidResponsePrebid.java index fbf368e5e97..4a9fbf0dacd 100644 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidResponsePrebid.java +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidResponsePrebid.java @@ -25,11 +25,6 @@ public class ExtBidResponsePrebid { ExtAnalytics analytics; - /** - * FLEDGE response as bidresponse.ext.prebid.fledge.auctionconfigs[] - */ - ExtBidResponseFledge fledge; - /** * Additional targeting key/values for the bid response (only used for AMP) * Set targeting options here that will occur in the bidResponse no matter if diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtIgi.java b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtIgi.java deleted file mode 100644 index a68ed9cdf6a..00000000000 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtIgi.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.prebid.server.proto.openrtb.ext.response; - -import lombok.Builder; -import lombok.Value; - -import java.util.List; - -/** - * Defines the contract for bidresponse.ext.igi - */ -@Builder(toBuilder = true) -@Value -public class ExtIgi { - - String impid; - - List igb; - - List igs; -} diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtIgiIgb.java b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtIgiIgb.java deleted file mode 100644 index aca3758c7aa..00000000000 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtIgiIgb.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.prebid.server.proto.openrtb.ext.response; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import lombok.Builder; -import lombok.Value; - -@Value -@Builder -public class ExtIgiIgb { - - String origin; - - Double maxbid; - - @Builder.Default - String cur = "USD"; - - JsonNode pbs; - - ObjectNode ps; -} diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtIgiIgs.java b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtIgiIgs.java deleted file mode 100644 index 305d211a4b5..00000000000 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtIgiIgs.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.prebid.server.proto.openrtb.ext.response; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.node.ObjectNode; -import lombok.Builder; -import lombok.Value; - -@Builder(toBuilder = true) -@Value -public class ExtIgiIgs { - - @JsonProperty("impid") - String impId; - - ObjectNode config; - - ExtIgiIgsExt ext; -} diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtIgiIgsExt.java b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtIgiIgsExt.java deleted file mode 100644 index 979b7fe6e13..00000000000 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtIgiIgsExt.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.prebid.server.proto.openrtb.ext.response; - -import lombok.Value; - -@Value(staticConstructor = "of") -public class ExtIgiIgsExt { - - String bidder; - - String adapter; -} diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/response/FledgeAuctionConfig.java b/src/main/java/org/prebid/server/proto/openrtb/ext/response/FledgeAuctionConfig.java deleted file mode 100644 index c0d2c6730f0..00000000000 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/response/FledgeAuctionConfig.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.prebid.server.proto.openrtb.ext.response; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.node.ObjectNode; -import lombok.Builder; -import lombok.Value; - -/** - * Defines the contract for bidresponse.ext.prebid.fledge.auctionconfigs[] elements - */ -@Value -@Builder(toBuilder = true) -public class FledgeAuctionConfig { - - @JsonProperty("impid") - String impId; - - String bidder; - - String adapter; - - ObjectNode config; -} diff --git a/src/main/java/org/prebid/server/settings/model/AccountAuctionConfig.java b/src/main/java/org/prebid/server/settings/model/AccountAuctionConfig.java index 4ccea419082..6bc85570ec6 100644 --- a/src/main/java/org/prebid/server/settings/model/AccountAuctionConfig.java +++ b/src/main/java/org/prebid/server/settings/model/AccountAuctionConfig.java @@ -5,7 +5,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.Builder; import lombok.Value; -import org.prebid.server.auction.model.PaaFormat; import org.prebid.server.spring.config.bidder.model.MediaType; import java.util.Map; @@ -55,9 +54,6 @@ public class AccountAuctionConfig { @JsonProperty("privacysandbox") AccountPrivacySandboxConfig privacySandbox; - @JsonProperty("paaformat") - PaaFormat paaFormat; - AccountCacheConfig cache; AccountBidRankingConfig ranking; 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 7967cdd19f9..9426c810038 100644 --- a/src/main/java/org/prebid/server/spring/config/ServiceConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/ServiceConfiguration.java @@ -898,7 +898,6 @@ CacheDefaultTtlProperties cacheDefaultTtlProperties( @Bean BidResponseCreator bidResponseCreator( - @Value("${logging.sampling-rate:0.01}") double logSamplingRate, CoreCacheService coreCacheService, BidderCatalog bidderCatalog, VastModifier vastModifier, @@ -912,13 +911,11 @@ BidResponseCreator bidResponseCreator( @Value("${auction.enforce-random-bid-id:false}") boolean enforceRandomBidId, Clock clock, JacksonMapper mapper, - Metrics metrics, @Value("${cache.banner-ttl-seconds:#{null}}") Integer bannerCacheTtl, @Value("${cache.video-ttl-seconds:#{null}}") Integer videoCacheTtl, CacheDefaultTtlProperties cacheDefaultTtlProperties) { return new BidResponseCreator( - logSamplingRate, coreCacheService, bidderCatalog, vastModifier, @@ -933,7 +930,6 @@ BidResponseCreator bidResponseCreator( enforceRandomBidId, clock, mapper, - metrics, CacheTtl.of(bannerCacheTtl, videoCacheTtl), cacheDefaultTtlProperties); } diff --git a/src/test/groovy/org/prebid/server/functional/model/config/AccountAuctionConfig.groovy b/src/test/groovy/org/prebid/server/functional/model/config/AccountAuctionConfig.groovy index a270bfc4545..00544c987e3 100644 --- a/src/test/groovy/org/prebid/server/functional/model/config/AccountAuctionConfig.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/config/AccountAuctionConfig.groovy @@ -7,7 +7,6 @@ import groovy.transform.ToString import org.prebid.server.functional.model.bidder.BidderName import org.prebid.server.functional.model.request.auction.BidAdjustment import org.prebid.server.functional.model.request.auction.BidRounding -import org.prebid.server.functional.model.request.auction.PaaFormat import org.prebid.server.functional.model.request.auction.Targeting import org.prebid.server.functional.model.response.auction.MediaType @@ -28,7 +27,6 @@ class AccountAuctionConfig { AccountPriceFloorsConfig priceFloors AccountProfilesConfigs profiles Targeting targeting - PaaFormat paaformat @JsonProperty("preferredmediatype") Map preferredMediaType @JsonProperty("privacysandbox") diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/AuctionEnvironment.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/AuctionEnvironment.groovy deleted file mode 100644 index 1530e4de21d..00000000000 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/AuctionEnvironment.groovy +++ /dev/null @@ -1,18 +0,0 @@ -package org.prebid.server.functional.model.request.auction - -import com.fasterxml.jackson.annotation.JsonValue - -enum AuctionEnvironment { - - NOT_SUPPORTED(0), - DEVICE_ORCHESTRATED(1), - SERVER_ORCHESTRATED(3), - UNKNOWN(Integer.MAX_VALUE) - - @JsonValue - final int value - - AuctionEnvironment(Integer value) { - this.value = value - } -} diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy index e66d0137c5e..ebd963b0737 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/ImpExt.groovy @@ -25,13 +25,9 @@ class ImpExt { String tid String gpid String sid - @JsonProperty("ae") - AuctionEnvironment auctionEnvironment String all String skadn String general - @JsonProperty("igs") - InterestGroupAuctionSupport interestGroupAuctionSupports AnyUnsupportedBidder anyUnsupportedBidder GeneralBidderAdapter bidder Rp rp diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/InterestGroupAuctionSupport.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/InterestGroupAuctionSupport.groovy deleted file mode 100644 index 31d3628587d..00000000000 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/InterestGroupAuctionSupport.groovy +++ /dev/null @@ -1,11 +0,0 @@ -package org.prebid.server.functional.model.request.auction - -import com.fasterxml.jackson.annotation.JsonProperty -import groovy.transform.ToString - -@ToString(includeNames = true, ignoreNulls = true) -class InterestGroupAuctionSupport { - - @JsonProperty("ae") - AuctionEnvironment auctionEnvironment -} diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/PaaFormat.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/PaaFormat.groovy deleted file mode 100644 index 79f41e953fe..00000000000 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/PaaFormat.groovy +++ /dev/null @@ -1,13 +0,0 @@ -package org.prebid.server.functional.model.request.auction - -import com.fasterxml.jackson.annotation.JsonValue - -enum PaaFormat { - - ORIGINAL, IAB, INVALID - - @JsonValue - String getValue() { - name().toLowerCase() - } -} diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/Prebid.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/Prebid.groovy index 80256327d0d..54304597ebc 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/Prebid.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/Prebid.groovy @@ -44,7 +44,6 @@ class Prebid { PrebidModulesConfig modules PrebidAnalytics analytics StoredAuctionResponse storedAuctionResponse - PaaFormat paaFormat @JsonProperty("alternatebiddercodes") AlternateBidderCodes alternateBidderCodes @JsonProperty("profiles") diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/BidResponseExt.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/BidResponseExt.groovy index d1d282d663a..3ccb3384e89 100644 --- a/src/test/groovy/org/prebid/server/functional/model/response/auction/BidResponseExt.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/BidResponseExt.groovy @@ -1,6 +1,5 @@ package org.prebid.server.functional.model.response.auction -import com.fasterxml.jackson.annotation.JsonProperty import groovy.transform.ToString import org.prebid.server.functional.model.response.BidderError import org.prebid.server.functional.model.response.Debug @@ -16,6 +15,4 @@ class BidResponseExt { Map usersync BidResponsePrebid prebid Map> warnings - @JsonProperty("igi") - List interestGroupAuctionIntent } diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/BidResponsePrebid.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/BidResponsePrebid.groovy index aee9daf7783..77cb8274e38 100644 --- a/src/test/groovy/org/prebid/server/functional/model/response/auction/BidResponsePrebid.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/BidResponsePrebid.groovy @@ -10,7 +10,6 @@ class BidResponsePrebid { Long auctionTimeStamp Map passThrough - ExtBidResponseFledge fledge ExtModule modules AnalyticsPrebid analytics } diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/ExtBidResponseFledge.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/ExtBidResponseFledge.groovy deleted file mode 100644 index 0da143b94ba..00000000000 --- a/src/test/groovy/org/prebid/server/functional/model/response/auction/ExtBidResponseFledge.groovy +++ /dev/null @@ -1,12 +0,0 @@ -package org.prebid.server.functional.model.response.auction - -import com.fasterxml.jackson.databind.PropertyNamingStrategies -import com.fasterxml.jackson.databind.annotation.JsonNaming -import groovy.transform.ToString - -@ToString(includeNames = true, ignoreNulls = true) -@JsonNaming(PropertyNamingStrategies.LowerCaseStrategy) -class ExtBidResponseFledge { - - List auctionConfigs -} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/FledgeAuctionConfig.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/FledgeAuctionConfig.groovy deleted file mode 100644 index 9864610ec20..00000000000 --- a/src/test/groovy/org/prebid/server/functional/model/response/auction/FledgeAuctionConfig.groovy +++ /dev/null @@ -1,15 +0,0 @@ -package org.prebid.server.functional.model.response.auction - -import com.fasterxml.jackson.databind.PropertyNamingStrategies -import com.fasterxml.jackson.databind.annotation.JsonNaming -import groovy.transform.ToString - -@ToString(includeNames = true, ignoreNulls = true) -@JsonNaming(PropertyNamingStrategies.LowerCaseStrategy) -class FledgeAuctionConfig { - - String impId - String bidder - String adapter - Map config -} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionBuyer.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionBuyer.groovy deleted file mode 100644 index b8d1bf80d38..00000000000 --- a/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionBuyer.groovy +++ /dev/null @@ -1,17 +0,0 @@ -package org.prebid.server.functional.model.response.auction - -import com.fasterxml.jackson.databind.PropertyNamingStrategies -import com.fasterxml.jackson.databind.annotation.JsonNaming -import groovy.transform.ToString -import org.prebid.server.functional.model.Currency - -@ToString(includeNames = true, ignoreNulls = true) -@JsonNaming(PropertyNamingStrategies.LowerCaseStrategy) -class InterestGroupAuctionBuyer { - - String origin - BigDecimal maxBid - Currency cur - Map pbs - InterestGroupAuctionBuyerExt ext -} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionBuyerExt.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionBuyerExt.groovy deleted file mode 100644 index 4404491246c..00000000000 --- a/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionBuyerExt.groovy +++ /dev/null @@ -1,10 +0,0 @@ -package org.prebid.server.functional.model.response.auction - -import groovy.transform.ToString - -@ToString(includeNames = true, ignoreNulls = true) -class InterestGroupAuctionBuyerExt { - - String bidder - String adapter -} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionIntent.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionIntent.groovy deleted file mode 100644 index 29ff15d4eeb..00000000000 --- a/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionIntent.groovy +++ /dev/null @@ -1,18 +0,0 @@ -package org.prebid.server.functional.model.response.auction - -import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.databind.PropertyNamingStrategies -import com.fasterxml.jackson.databind.annotation.JsonNaming -import groovy.transform.ToString - -@ToString(includeNames = true, ignoreNulls = true) -@JsonNaming(PropertyNamingStrategies.LowerCaseStrategy) -class InterestGroupAuctionIntent { - - String impId - @JsonProperty("igb") - List interestGroupAuctionBuyer - @JsonProperty("igs") - List interestGroupAuctionSeller - InterestGroupAuctionIntentExt ext -} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionIntentExt.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionIntentExt.groovy deleted file mode 100644 index 29aeaf980da..00000000000 --- a/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionIntentExt.groovy +++ /dev/null @@ -1,11 +0,0 @@ -package org.prebid.server.functional.model.response.auction - -import groovy.transform.ToString -import org.prebid.server.functional.model.bidder.BidderName - -@ToString(includeNames = true, ignoreNulls = true) -class InterestGroupAuctionIntentExt { - - BidderName bidder - BidderName adapter -} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionSeller.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionSeller.groovy deleted file mode 100644 index 192f5c2f611..00000000000 --- a/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionSeller.groovy +++ /dev/null @@ -1,14 +0,0 @@ -package org.prebid.server.functional.model.response.auction - -import com.fasterxml.jackson.databind.PropertyNamingStrategies -import com.fasterxml.jackson.databind.annotation.JsonNaming -import groovy.transform.ToString - -@ToString(includeNames = true, ignoreNulls = true) -@JsonNaming(PropertyNamingStrategies.LowerCaseStrategy) -class InterestGroupAuctionSeller { - - String impId - Map config - InterestGroupAuctionSellerExt ext -} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionSellerExt.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionSellerExt.groovy deleted file mode 100644 index fcecf1b5480..00000000000 --- a/src/test/groovy/org/prebid/server/functional/model/response/auction/InterestGroupAuctionSellerExt.groovy +++ /dev/null @@ -1,10 +0,0 @@ -package org.prebid.server.functional.model.response.auction - -import groovy.transform.ToString - -@ToString(includeNames = true, ignoreNulls = true) -class InterestGroupAuctionSellerExt { - - String bidder - String adapter -} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/OpenxBidResponse.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/OpenxBidResponse.groovy deleted file mode 100644 index b5d5289d5a6..00000000000 --- a/src/test/groovy/org/prebid/server/functional/model/response/auction/OpenxBidResponse.groovy +++ /dev/null @@ -1,20 +0,0 @@ -package org.prebid.server.functional.model.response.auction - -import groovy.transform.ToString -import org.prebid.server.functional.model.request.auction.BidRequest - -import static org.prebid.server.functional.model.bidder.BidderName.OPENX - -@ToString(includeNames = true, ignoreNulls = true) -class OpenxBidResponse extends BidResponse { - - OpenxBidResponseExt ext - - static OpenxBidResponse getDefaultBidResponse(BidRequest bidRequest) { - def openxBidResponse = new OpenxBidResponse(id: bidRequest.id) - def bids = Bid.getDefaultBids(bidRequest.imp) - def seatBid = new SeatBid(bid: bids, seat: OPENX) - openxBidResponse.seatbid = [seatBid] - openxBidResponse - } -} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/OpenxBidResponseExt.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/OpenxBidResponseExt.groovy deleted file mode 100644 index d373d2e73d6..00000000000 --- a/src/test/groovy/org/prebid/server/functional/model/response/auction/OpenxBidResponseExt.groovy +++ /dev/null @@ -1,11 +0,0 @@ -package org.prebid.server.functional.model.response.auction - -import com.fasterxml.jackson.annotation.JsonProperty -import groovy.transform.ToString - -@ToString(includeNames = true, ignoreNulls = true) -class OpenxBidResponseExt extends BidResponseExt { - - @JsonProperty("fledge_auction_configs") - Map fledgeAuctionConfigs -} diff --git a/src/test/groovy/org/prebid/server/functional/tests/BidderParamsSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/BidderParamsSpec.groovy index d030fe173d2..2a33e6921a7 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/BidderParamsSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/BidderParamsSpec.groovy @@ -9,7 +9,6 @@ import org.prebid.server.functional.model.db.StoredRequest import org.prebid.server.functional.model.request.amp.AmpRequest import org.prebid.server.functional.model.request.auction.Adrino import org.prebid.server.functional.model.request.auction.Amx -import org.prebid.server.functional.model.request.auction.AuctionEnvironment import org.prebid.server.functional.model.request.auction.Banner import org.prebid.server.functional.model.request.auction.BidRequest import org.prebid.server.functional.model.request.auction.Device @@ -19,7 +18,6 @@ import org.prebid.server.functional.model.request.auction.Imp import org.prebid.server.functional.model.request.auction.ImpExt import org.prebid.server.functional.model.request.auction.ImpExtContext import org.prebid.server.functional.model.request.auction.ImpExtContextData -import org.prebid.server.functional.model.request.auction.InterestGroupAuctionSupport import org.prebid.server.functional.model.request.auction.Native import org.prebid.server.functional.model.request.auction.PrebidOptions import org.prebid.server.functional.model.request.auction.PrebidStoredRequest @@ -47,10 +45,6 @@ import static org.prebid.server.functional.model.bidder.BidderName.OPENX import static org.prebid.server.functional.model.bidder.CompressionType.GZIP import static org.prebid.server.functional.model.bidder.CompressionType.NONE import static org.prebid.server.functional.model.request.auction.Asset.titleAsset -import static org.prebid.server.functional.model.request.auction.AuctionEnvironment.DEVICE_ORCHESTRATED -import static org.prebid.server.functional.model.request.auction.AuctionEnvironment.NOT_SUPPORTED -import static org.prebid.server.functional.model.request.auction.AuctionEnvironment.SERVER_ORCHESTRATED -import static org.prebid.server.functional.model.request.auction.AuctionEnvironment.UNKNOWN import static org.prebid.server.functional.model.request.auction.DistributionChannel.APP import static org.prebid.server.functional.model.request.auction.DistributionChannel.DOOH import static org.prebid.server.functional.model.request.auction.DistributionChannel.SITE @@ -870,7 +864,6 @@ class BidderParamsSpec extends BaseSpec { prebid.bidder.generic = null prebid.adUnitCode = PBSUtils.randomString generic = new Generic() - auctionEnvironment = PBSUtils.getRandomEnum(AuctionEnvironment, [AuctionEnvironment.SERVER_ORCHESTRATED, AuctionEnvironment.UNKNOWN]) all = PBSUtils.randomNumber context = new ImpExtContext(data: new ImpExtContextData()) data = new ImpExtContextData(pbAdSlot: PBSUtils.randomString) @@ -896,7 +889,6 @@ class BidderParamsSpec extends BaseSpec { def bidderRequest = bidder.getBidderRequest(bidRequest.id) verifyAll(bidderRequest.imp[0].ext) { it.bidder == impExt.generic - it.auctionEnvironment == impExt.auctionEnvironment it.all == impExt.all it.context == impExt.context it.data == impExt.data @@ -959,8 +951,7 @@ class BidderParamsSpec extends BaseSpec { given: "Default bid request with populated ext.prebid.bidderParams" def genericBidderParams = PBSUtils.randomString def bidRequest = BidRequest.defaultBidRequest.tap { - ext.prebid.bidderParams = [ae : PBSUtils.randomString, - all : PBSUtils.randomString, + ext.prebid.bidderParams = [all : PBSUtils.randomString, context : PBSUtils.randomString, data : PBSUtils.randomString, general : PBSUtils.randomString, @@ -1238,68 +1229,6 @@ class BidderParamsSpec extends BaseSpec { pbsServiceFactory.removeContainer(pbsConfig) } - def "PBS should add auction environment to imp.ext.igs when it is present in imp.ext and imp.ext.igs is empty"() { - given: "Default bid request with populated imp.ext" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.tap { - auctionEnvironment = requestedAuctionEnvironment - interestGroupAuctionSupports = new InterestGroupAuctionSupport(auctionEnvironment: null) - } - } - - when: "PBS processes auction request" - defaultPbsService.sendAuctionRequest(bidRequest) - - then: "Bidder request should imp[].{ae/ext.igs.ae} same value as requested" - def bidderRequest = bidder.getBidderRequest(bidRequest.id) - assert bidderRequest.imp[0].ext.auctionEnvironment == requestedAuctionEnvironment - assert bidderRequest.imp[0].ext.interestGroupAuctionSupports.auctionEnvironment == requestedAuctionEnvironment - - where: - requestedAuctionEnvironment << [NOT_SUPPORTED, DEVICE_ORCHESTRATED] - } - - def "PBS shouldn't add unsupported auction environment to imp.ext.igs when it is present in imp.ext and imp.ext.igs is empty"() { - given: "Default bid request with populated imp.ext" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.tap { - auctionEnvironment = requestedAuctionEnvironment - interestGroupAuctionSupports = new InterestGroupAuctionSupport(auctionEnvironment: null) - } - } - - when: "PBS processes auction request" - defaultPbsService.sendAuctionRequest(bidRequest) - - then: "Bidder request should imp[].ae same value as requested" - def bidderRequest = bidder.getBidderRequest(bidRequest.id) - assert bidderRequest.imp[0].ext.auctionEnvironment == requestedAuctionEnvironment - assert !bidderRequest.imp[0].ext.interestGroupAuctionSupports.auctionEnvironment - - where: - requestedAuctionEnvironment << [SERVER_ORCHESTRATED, UNKNOWN] - } - - def "PBS shouldn't change auction environment in imp.ext.igs when it is present in both imp.ext and imp.ext.igs"() { - given: "Default bid request with populated imp.ext" - def extAuctionEnv = PBSUtils.getRandomEnum(AuctionEnvironment, [SERVER_ORCHESTRATED, UNKNOWN]) - def extIgsAuctionEnv = PBSUtils.getRandomEnum(AuctionEnvironment, [SERVER_ORCHESTRATED, UNKNOWN]) - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.tap { - auctionEnvironment = extAuctionEnv - interestGroupAuctionSupports = new InterestGroupAuctionSupport(auctionEnvironment: extIgsAuctionEnv) - } - } - - when: "PBS processes auction request" - defaultPbsService.sendAuctionRequest(bidRequest) - - then: "Bidder request should imp[].{ae/ext.igs.ae} same value as requested" - def bidderRequest = bidder.getBidderRequest(bidRequest.id) - assert bidderRequest.imp[0].ext.auctionEnvironment == extAuctionEnv - assert bidderRequest.imp[0].ext.interestGroupAuctionSupports.auctionEnvironment == extIgsAuctionEnv - } - def "PBS should reject alias bidders when bidder params from request doesn't satisfy own json-schema"() { given: "Default bid request" def bidRequest = BidRequest.defaultBidRequest.tap { diff --git a/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy deleted file mode 100644 index 97a0015cea5..00000000000 --- a/src/test/groovy/org/prebid/server/functional/tests/bidder/openx/OpenxSpec.groovy +++ /dev/null @@ -1,581 +0,0 @@ -package org.prebid.server.functional.tests.bidder.openx - -import org.prebid.server.functional.model.Currency -import org.prebid.server.functional.model.bidder.Openx -import org.prebid.server.functional.model.config.AccountAuctionConfig -import org.prebid.server.functional.model.config.AccountConfig -import org.prebid.server.functional.model.db.Account -import org.prebid.server.functional.model.request.auction.AuctionEnvironment -import org.prebid.server.functional.model.request.auction.BidRequest -import org.prebid.server.functional.model.request.auction.InterestGroupAuctionSupport -import org.prebid.server.functional.model.request.auction.PaaFormat -import org.prebid.server.functional.model.response.auction.InterestGroupAuctionBuyer -import org.prebid.server.functional.model.response.auction.InterestGroupAuctionBuyerExt -import org.prebid.server.functional.model.response.auction.InterestGroupAuctionIntent -import org.prebid.server.functional.model.response.auction.InterestGroupAuctionSeller -import org.prebid.server.functional.model.response.auction.OpenxBidResponse -import org.prebid.server.functional.model.response.auction.OpenxBidResponseExt -import org.prebid.server.functional.service.PrebidServerException -import org.prebid.server.functional.service.PrebidServerService -import org.prebid.server.functional.tests.BaseSpec -import org.prebid.server.functional.util.PBSUtils -import spock.lang.Shared - -import java.time.Instant - -import static org.prebid.server.functional.model.bidder.BidderName.OPENX -import static org.prebid.server.functional.model.bidder.BidderName.OPENX_ALIAS -import static org.prebid.server.functional.model.bidder.BidderName.WILDCARD -import static org.prebid.server.functional.model.request.auction.AuctionEnvironment.DEVICE_ORCHESTRATED -import static org.prebid.server.functional.model.request.auction.AuctionEnvironment.NOT_SUPPORTED -import static org.prebid.server.functional.model.request.auction.AuctionEnvironment.SERVER_ORCHESTRATED -import static org.prebid.server.functional.model.request.auction.AuctionEnvironment.UNKNOWN -import static org.prebid.server.functional.model.request.auction.PaaFormat.IAB -import static org.prebid.server.functional.model.request.auction.PaaFormat.ORIGINAL -import static org.prebid.server.functional.model.response.auction.ErrorType.PREBID -import static org.prebid.server.functional.testcontainers.Dependencies.networkServiceContainer - -class OpenxSpec extends BaseSpec { - - private static final Map OPENX_CONFIG = ["adapters.openx.enabled" : "true", - "adapters.openx.endpoint": "$networkServiceContainer.rootUri/auction".toString()] - private static final Map OPENX_ALIAS_CONFIG = ["adapters.openx.aliases.openxalias.enabled" : "true", - "adapters.openx.aliases.openxalias.endpoint": "$networkServiceContainer.rootUri/auction".toString()] - - @Shared - PrebidServerService pbsService = pbsServiceFactory.getService(OPENX_CONFIG) - - @Override - def cleanupSpec() { - pbsServiceFactory.removeContainer(OPENX_CONFIG) - pbsServiceFactory.removeContainer(OPENX_CONFIG + OPENX_ALIAS_CONFIG) - } - - def "PBS should populate fledge config by default when bid response with fledge"() { - given: "Default basic BidRequest with ae and openx bidder" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.auctionEnvironment = DEVICE_ORCHESTRATED - imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - } - - and: "Default bid response with fledge config" - def impId = bidRequest.imp[0].id - def fledgeConfig = [(PBSUtils.randomString): PBSUtils.randomString] - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest, OPENX).tap { - ext = new OpenxBidResponseExt().tap { - fledgeAuctionConfigs = [(impId): fledgeConfig] - } - } - - and: "Set bidder response" - bidder.setResponse(bidRequest.id, bidResponse) - - when: "PBS processes auction request" - def response = pbsService.sendAuctionRequest(bidRequest) - - then: "PBS response should contain fledge config" - def auctionConfigs = response.ext?.prebid?.fledge?.auctionConfigs - assert auctionConfigs?.size() == 1 - assert auctionConfigs[0].impId == impId - assert auctionConfigs[0].bidder == bidResponse.seatbid[0].seat.value - assert auctionConfigs[0].adapter == bidResponse.seatbid[0].seat.value - assert auctionConfigs[0].config == fledgeConfig - - and: "PBS response shouldn't contain igb config" - assert !response.ext?.interestGroupAuctionIntent?.interestGroupAuctionBuyer - - and: "PBS response shouldn't contain igs config" - assert !response.ext?.interestGroupAuctionIntent?.interestGroupAuctionSeller - } - - def "PBS should populate fledge config when bid response with fledge and ext.prebid.paaFormat = ORIGINAL"() { - given: "Default basic BidRequest with ae and openx bidder" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.auctionEnvironment = DEVICE_ORCHESTRATED - imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - ext.prebid.paaFormat = ORIGINAL - } - - and: "Default bid response with fledge config" - def impId = bidRequest.imp[0].id - def fledgeConfig = [(PBSUtils.randomString): PBSUtils.randomString] - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest, OPENX).tap { - ext = new OpenxBidResponseExt().tap { - fledgeAuctionConfigs = [(impId): fledgeConfig] - } - } - - and: "Set bidder response" - bidder.setResponse(bidRequest.id, bidResponse) - - when: "PBS processes auction request" - def response = pbsService.sendAuctionRequest(bidRequest) - - then: "PBS response should contain fledge config" - def auctionConfigs = response.ext?.prebid?.fledge?.auctionConfigs - assert auctionConfigs?.size() == 1 - assert auctionConfigs[0].impId == impId - assert auctionConfigs[0].bidder == bidResponse.seatbid[0].seat.value - assert auctionConfigs[0].adapter == bidResponse.seatbid[0].seat.value - assert auctionConfigs[0].config == fledgeConfig - - and: "PBS response shouldn't contain igb config" - assert !response.ext?.interestGroupAuctionIntent?.interestGroupAuctionBuyer - - and: "PBS response shouldn't contain igs config" - assert !response.ext?.interestGroupAuctionIntent?.interestGroupAuctionSeller - } - - def "PBS should take precedence request paa format over account value when both specified"() { - given: "Default bid request with openx" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - ext.prebid.paaFormat = IAB - } - - and: "Default bid response with fledge config" - def impId = bidRequest.imp[0].id - def fledgeConfig = [(PBSUtils.randomString): PBSUtils.randomString] - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { - ext = new OpenxBidResponseExt().tap { - fledgeAuctionConfigs = [(impId): fledgeConfig] - } - } - - and: "Set bidder response" - bidder.setResponse(bidRequest.id, bidResponse) - - and: "Save account in the DB" - def accountConfig = new AccountConfig(auction: new AccountAuctionConfig(paaformat: ORIGINAL)) - def account = new Account(uuid: bidRequest.site.publisher.id, config: accountConfig) - accountDao.save(account) - - when: "PBS processes auction request" - def response = pbsService.sendAuctionRequest(bidRequest) - - then: "PBS response shouldn't contain fledge config" - assert !response.ext?.prebid?.fledge?.auctionConfigs - - and: "PBS response should contain igs config" - def interestGroupAuctionSeller = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] - assert interestGroupAuctionSeller.impId == impId - assert interestGroupAuctionSeller.config == fledgeConfig - assert interestGroupAuctionSeller.ext.bidder == bidResponse.seatbid[0].seat.value - assert interestGroupAuctionSeller.ext.adapter == bidResponse.seatbid[0].seat.value - - and: "PBS response shouldn't contain igb config" - assert !response.ext?.interestGroupAuctionIntent?[0]?.interestGroupAuctionBuyer - } - - def "PBS shouldn't populate fledge config when bid response with fledge and ext.prebid.paaFormat = IAB"() { - given: "Default basic BidRequest without ae" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.auctionEnvironment = NOT_SUPPORTED - imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - ext.prebid.paaFormat = IAB - } - - and: "Default bid response" - def impId = bidRequest.imp[0].id - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { - ext = new OpenxBidResponseExt().tap { - fledgeAuctionConfigs = [(impId): [(PBSUtils.randomString): PBSUtils.randomString]] - } - } - - and: "Set bidder response" - bidder.setResponse(bidRequest.id, bidResponse) - - when: "PBS processes auction request" - def response = pbsService.sendAuctionRequest(bidRequest) - - then: "PBS response shouldn't contain fledge config" - assert !response.ext.prebid.fledge - - and: "PBS response shouldn't contain igb config" - assert !response.ext?.interestGroupAuctionIntent?[0]?.interestGroupAuctionBuyer - - and: "PBS response should contain igs config" - def interestGroupAuctionSeller = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] - assert interestGroupAuctionSeller.impId == impId - assert interestGroupAuctionSeller.config - assert interestGroupAuctionSeller.ext.bidder == bidResponse.seatbid[0].seat.value - assert interestGroupAuctionSeller.ext.adapter == bidResponse.seatbid[0].seat.value - } - - def "PBS shouldn't populate fledge config when bid response didn't return fledge config"() { - given: "Default basic BidRequest without ae" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - } - - and: "Default bid response" - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { - ext = new OpenxBidResponseExt().tap { - fledgeAuctionConfigs = null - } - } - - and: "Set bidder response" - bidder.setResponse(bidRequest.id, bidResponse) - - when: "PBS processes auction request" - def response = pbsService.sendAuctionRequest(bidRequest) - - then: "PBS response shouldn't contain fledge config" - assert !response.ext.prebid.fledge - - and: "PBS response shouldn't contain igi config" - assert !response?.ext?.interestGroupAuctionIntent - } - - def "PBS should populate fledge and iab output config when bid response with fledge and paa formant IAB"() { - given: "Default bid request with openx" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - ext.prebid.paaFormat = requestPaaFormant - } - - and: "Default bid response with fledge config" - def impId = bidRequest.imp[0].id - def fledgeConfig = [(PBSUtils.randomString): PBSUtils.randomString] - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest).tap { - ext = new OpenxBidResponseExt().tap { - fledgeAuctionConfigs = [(impId): fledgeConfig] - } - } - - and: "Set bidder response" - bidder.setResponse(bidRequest.id, bidResponse) - - and: "Save account in the DB" - def accountConfig = new AccountConfig(auction: new AccountAuctionConfig(paaformat: accountPaaFormat)) - def account = new Account(uuid: bidRequest.site.publisher.id, config: accountConfig) - accountDao.save(account) - - when: "PBS processes auction request" - def response = pbsService.sendAuctionRequest(bidRequest) - - then: "PBS response shouldn't contain fledge config" - assert !response.ext?.prebid?.fledge?.auctionConfigs - - and: "PBS response should contain igs config" - def interestGroupAuctionSeller = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] - assert interestGroupAuctionSeller.impId == impId - assert interestGroupAuctionSeller.config == fledgeConfig - assert interestGroupAuctionSeller.ext.bidder == bidResponse.seatbid[0].seat.value - assert interestGroupAuctionSeller.ext.adapter == bidResponse.seatbid[0].seat.value - - and: "PBS response shouldn't contain igb config" - assert !response.ext?.interestGroupAuctionIntent?[0]?.interestGroupAuctionBuyer - - where: - accountPaaFormat | requestPaaFormant - IAB | IAB - null | IAB - IAB | null - } - - def "PBS should populate fledge config by default when bid response with fledge and requested aliases"() { - given: "PBS config with alias config" - def pbsService = pbsServiceFactory.getService(OPENX_CONFIG + OPENX_ALIAS_CONFIG) - - and: "Default basic BidRequest with ae and bidder" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.auctionEnvironment = DEVICE_ORCHESTRATED - imp[0].ext.prebid.bidder.generic = null - imp[0].ext.prebid.bidder.openxAlias = Openx.defaultOpenx - ext.prebid.aliases = [(OPENX_ALIAS.value): OPENX] - } - - and: "Default bid response with fledge config" - def impId = bidRequest.imp[0].id - def fledgeConfig = [(PBSUtils.randomString): PBSUtils.randomString] - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest, OPENX_ALIAS).tap { - ext = new OpenxBidResponseExt().tap { - fledgeAuctionConfigs = [(impId): fledgeConfig] - } - } - - and: "Set bidder response" - bidder.setResponse(bidRequest.id, bidResponse) - - when: "PBS processes auction request" - def response = pbsService.sendAuctionRequest(bidRequest) - - then: "PBS response should contain fledge config" - def auctionConfigs = response.ext?.prebid?.fledge?.auctionConfigs - assert auctionConfigs?.size() == 1 - assert auctionConfigs[0].impId == impId - assert auctionConfigs[0].bidder == OPENX_ALIAS.value - assert auctionConfigs[0].adapter == OPENX_ALIAS.value - assert auctionConfigs[0].config == fledgeConfig - - and: "PBS response shouldn't contain igi config" - assert !response.ext?.interestGroupAuctionIntent - } - - def "PBS should populate iab config when bid response with fledge and requested aliases"() { - given: "PBS config" - def pbsService = pbsServiceFactory.getService(OPENX_CONFIG + OPENX_ALIAS_CONFIG) - - and: "Default basic BidRequest with ae and openx bidder" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.auctionEnvironment = DEVICE_ORCHESTRATED - imp[0].ext.prebid.bidder.generic = null - imp[0].ext.prebid.bidder.openxAlias = Openx.defaultOpenx - ext.prebid.aliases = [(OPENX_ALIAS.value): OPENX] - ext.prebid.paaFormat = IAB - } - - and: "Default bid response with fledge config" - def impId = bidRequest.imp[0].id - def fledgeConfig = [(PBSUtils.randomString): PBSUtils.randomString] - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest, OPENX_ALIAS).tap { - ext = new OpenxBidResponseExt().tap { - fledgeAuctionConfigs = [(impId): fledgeConfig] - } - } - - and: "Set bidder response" - bidder.setResponse(bidRequest.id, bidResponse) - - when: "PBS processes auction request" - def response = pbsService.sendAuctionRequest(bidRequest) - - then: "PBS response shouldn't contain fledge config" - assert !response.ext?.prebid?.fledge?.auctionConfigs - - and: "PBS response should contain igs config" - def interestGroupAuctionSeller = response.ext.interestGroupAuctionIntent[0].interestGroupAuctionSeller[0] - assert interestGroupAuctionSeller.impId == impId - assert interestGroupAuctionSeller.config == fledgeConfig - assert interestGroupAuctionSeller.ext.bidder == OPENX_ALIAS.value - assert interestGroupAuctionSeller.ext.adapter == OPENX_ALIAS.value - - and: "Response should contain seat" - assert response.seatbid[0].seat == OPENX_ALIAS - - and: "Response should contain seat" - assert response.seatbid[0].bid[0].ext.prebid.meta.adapterCode == OPENX_ALIAS - - and: "PBS response shouldn't contain igi config" - assert !response.ext?.interestGroupAuctionIntent?[0].interestGroupAuctionBuyer - } - - def "PBS should populate fledge config by default when bid response with fledge and imp mismatched"() { - given: "Default basic BidRequest with ae and openx bidder" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.auctionEnvironment = DEVICE_ORCHESTRATED - imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - } - - and: "Default bid response with fledge config" - def fledgeConfig = [(PBSUtils.randomString): PBSUtils.randomString] - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest, OPENX).tap { - ext = new OpenxBidResponseExt().tap { - fledgeAuctionConfigs = [(fledgeImpId): fledgeConfig] - } - } - - and: "Set bidder response" - bidder.setResponse(bidRequest.id, bidResponse) - - when: "PBS processes auction request" - def response = pbsService.sendAuctionRequest(bidRequest) - - then: "PBS response should contain fledge config" - def auctionConfigs = response.ext?.prebid?.fledge?.auctionConfigs - assert auctionConfigs?.size() == 1 - assert auctionConfigs[0].impId == fledgeImpId - assert auctionConfigs[0].bidder == bidResponse.seatbid[0].seat.value - assert auctionConfigs[0].adapter == bidResponse.seatbid[0].seat.value - assert auctionConfigs[0].config == fledgeConfig - - and: "PBS response shouldn't contain igi config" - assert !response.ext?.interestGroupAuctionIntent - - where: - fledgeImpId << [PBSUtils.randomString, PBSUtils.randomNumber as String, WILDCARD.value] - } - - def "PBS should log error and not populated fledge impId when bidder respond with not empty config, but an empty impid"() { - given: "Start time" - def startTime = Instant.now() - - and: "Default basic BidRequest with ae and openx bidder" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.auctionEnvironment = DEVICE_ORCHESTRATED - imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - ext.prebid.paaFormat = IAB - } - - and: "Default bid response with fledge config without imp" - def fledgeConfig = [(PBSUtils.randomString): PBSUtils.randomString] - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest, OPENX).tap { - ext = new OpenxBidResponseExt().tap { - fledgeAuctionConfigs = [(""): fledgeConfig] as Map - } - } - - and: "Set bidder response" - bidder.setResponse(bidRequest.id, bidResponse) - - and: "Flush metrics" - flushMetrics(pbsService) - - when: "PBS processes auction request" - def response = pbsService.sendAuctionRequest(bidRequest) - - then: "PBS response shouldn't contain fledge config" - assert !response.ext?.prebid?.fledge?.auctionConfigs - - and: "PBS response shouldn't contain igi config" - assert !response.ext?.interestGroupAuctionIntent - - and: "PBS log should contain error" - def logs = pbsService.getLogsByTime(startTime) - assert getLogsByText(logs, "ExtIgiIgs with absent impId from bidder: ${OPENX.value}") - - and: "Bid response should contain warning" - assert response.ext.warnings[PREBID]?.code == [999] - assert response.ext.warnings[PREBID]?.message == - ["ExtIgiIgs with absent impId from bidder: ${OPENX.value}" as String] - - and: "Alert.general metric should be updated" - def metrics = pbsService.sendCollectedMetricsRequest() - assert metrics[ALERT_GENERAL] == 1 - } - - def "PBS shouldn't populate fledge or igi config when bidder respond with igb"() { - given: "Default basic BidRequest with ae and openx bidder" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.auctionEnvironment = DEVICE_ORCHESTRATED - imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - } - - and: "Default bid response with igb config" - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest, OPENX).tap { - ext = new OpenxBidResponseExt().tap { - interestGroupAuctionIntent = [new InterestGroupAuctionIntent( - interestGroupAuctionBuyer: [new InterestGroupAuctionBuyer( - origin: PBSUtils.randomString, - maxBid: PBSUtils.randomDecimal, - cur: PBSUtils.getRandomEnum(Currency), - pbs: [(PBSUtils.randomString): PBSUtils.randomString], - ext: new InterestGroupAuctionBuyerExt( - bidder: PBSUtils.randomString, - adapter: PBSUtils.randomString - ) - )]) - ] - } - } - - and: "Set bidder response" - bidder.setResponse(bidRequest.id, bidResponse) - - when: "PBS processes auction request" - def response = pbsService.sendAuctionRequest(bidRequest) - - then: "PBS response should contain fledge config" - assert !response.ext?.prebid?.fledge?.auctionConfigs - - and: "PBS response shouldn't contain igi config" - assert !response.ext?.interestGroupAuctionIntent - } - - def "PBS should throw error when requested unknown paa format"() { - given: "Default basic BidRequest with ae and openx bidder" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.auctionEnvironment = DEVICE_ORCHESTRATED - imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - ext.prebid.paaFormat = PaaFormat.INVALID - } - - and: "Default bid response with fledge config" - def impId = bidRequest.imp[0].id - def fledgeConfig = [(PBSUtils.randomString): PBSUtils.randomString] - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest, OPENX).tap { - ext = new OpenxBidResponseExt().tap { - fledgeAuctionConfigs = [(impId): fledgeConfig] - } - } - - and: "Set bidder response" - bidder.setResponse(bidRequest.id, bidResponse) - - when: "PBS processes auction request" - pbsService.sendAuctionRequest(bidRequest) - - then: "Request should fail with error" - def exception = thrown(PrebidServerException) - assert exception.responseBody.startsWith("Invalid request format: Error decoding bidRequest: " + - "Cannot deserialize value of type `org.prebid.server.auction.model.PaaFormat` " + - "from String \"invalid\": not one of the values accepted for Enum class: [original, iab]") - } - - def "PBS shouldn't cause error when igs and igb empty array"() { - given: "Default basic BidRequest with ae and openx bidder" - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.auctionEnvironment = DEVICE_ORCHESTRATED - imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - ext.prebid.paaFormat = paaFormat - } - - and: "Default bid response with igs config" - def bidResponse = OpenxBidResponse.getDefaultBidResponse(bidRequest, OPENX).tap { - ext = new OpenxBidResponseExt().tap { - interestGroupAuctionIntent = [new InterestGroupAuctionIntent( - interestGroupAuctionSeller: interestGroupAuctionSeller, - interestGroupAuctionBuyer: interestGroupAuctionBuyer - )] - } - } - - and: "Set bidder response" - bidder.setResponse(bidRequest.id, bidResponse) - - when: "PBS processes auction request" - def response = pbsService.sendAuctionRequest(bidRequest) - - then: "PBS response should contain fledge config" - assert !response.ext?.prebid?.fledge?.auctionConfigs - - and: "PBS response shouldn't contain igi config" - assert !response.ext?.interestGroupAuctionIntent - - where: - paaFormat | interestGroupAuctionSeller | interestGroupAuctionBuyer - IAB | [new InterestGroupAuctionSeller()] | [new InterestGroupAuctionBuyer()] - ORIGINAL | [] | [] - } - - def "PBS shouldn't change auction environment in imp.ext.igs and not emit a warning when it is present in both imp.ext and imp.ext.igs"() { - given: "Default bid request with populated imp.ext" - def extAuctionEnv = PBSUtils.getRandomEnum(AuctionEnvironment, [SERVER_ORCHESTRATED, UNKNOWN]) - def extIgsAuctionEnv = PBSUtils.getRandomEnum(AuctionEnvironment, [SERVER_ORCHESTRATED, UNKNOWN]) - def bidRequest = BidRequest.defaultBidRequest.tap { - imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx - imp[0].ext.prebid.bidder.generic = null - imp[0].ext.tap { - auctionEnvironment = extAuctionEnv - interestGroupAuctionSupports = new InterestGroupAuctionSupport(auctionEnvironment: extIgsAuctionEnv) - } - } - - when: "PBS processes auction request" - def bidResponse = pbsService.sendAuctionRequest(bidRequest) - - then: "Bidder request should imp[].{ae/ext.igs.ae} same value as requested" - def bidderRequest = bidder.getBidderRequest(bidRequest.id) - assert bidderRequest.imp[0].ext.auctionEnvironment == extAuctionEnv - assert bidderRequest.imp[0].ext.interestGroupAuctionSupports.auctionEnvironment == extIgsAuctionEnv - - and: "Response shouldn't contain errors" - assert !bidResponse.ext.errors - - and: "Response shouldn't contain warnings" - assert !bidResponse.ext.warnings - } -} diff --git a/src/test/java/org/prebid/server/auction/BidResponseCreatorTest.java b/src/test/java/org/prebid/server/auction/BidResponseCreatorTest.java index de671b88440..7d8d939600f 100644 --- a/src/test/java/org/prebid/server/auction/BidResponseCreatorTest.java +++ b/src/test/java/org/prebid/server/auction/BidResponseCreatorTest.java @@ -45,7 +45,6 @@ import org.prebid.server.auction.model.CategoryMappingResult; import org.prebid.server.auction.model.ImpRejection; import org.prebid.server.auction.model.MultiBidConfig; -import org.prebid.server.auction.model.PaaFormat; import org.prebid.server.auction.model.TargetingInfo; import org.prebid.server.auction.model.TimeoutContext; import org.prebid.server.auction.model.debug.DebugContext; @@ -69,8 +68,6 @@ import org.prebid.server.hooks.execution.v1.bidder.AllProcessedBidResponsesPayloadImpl; import org.prebid.server.hooks.execution.v1.bidder.BidderResponsePayloadImpl; import org.prebid.server.identity.IdGenerator; -import org.prebid.server.metric.MetricName; -import org.prebid.server.metric.Metrics; import org.prebid.server.proto.openrtb.ext.ExtIncludeBrandCategory; import org.prebid.server.proto.openrtb.ext.request.ExtDeal; import org.prebid.server.proto.openrtb.ext.request.ExtDealLine; @@ -91,18 +88,12 @@ import org.prebid.server.proto.openrtb.ext.response.CacheAsset; import org.prebid.server.proto.openrtb.ext.response.Events; import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebid; -import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidMeta; import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidVideo; import org.prebid.server.proto.openrtb.ext.response.ExtBidResponse; -import org.prebid.server.proto.openrtb.ext.response.ExtBidResponseFledge; import org.prebid.server.proto.openrtb.ext.response.ExtBidResponsePrebid; import org.prebid.server.proto.openrtb.ext.response.ExtBidderError; import org.prebid.server.proto.openrtb.ext.response.ExtDebugTrace; import org.prebid.server.proto.openrtb.ext.response.ExtHttpCall; -import org.prebid.server.proto.openrtb.ext.response.ExtIgi; -import org.prebid.server.proto.openrtb.ext.response.ExtIgiIgb; -import org.prebid.server.proto.openrtb.ext.response.ExtIgiIgs; -import org.prebid.server.proto.openrtb.ext.response.ExtIgiIgsExt; import org.prebid.server.proto.openrtb.ext.response.ExtResponseCache; import org.prebid.server.proto.openrtb.ext.response.ExtResponseDebug; import org.prebid.server.proto.openrtb.ext.response.ExtTraceActivityInfrastructure; @@ -110,7 +101,6 @@ import org.prebid.server.proto.openrtb.ext.response.ExtTraceActivityInvocationDefaultResult; import org.prebid.server.proto.openrtb.ext.response.ExtTraceActivityInvocationResult; import org.prebid.server.proto.openrtb.ext.response.ExtTraceActivityRule; -import org.prebid.server.proto.openrtb.ext.response.FledgeAuctionConfig; import org.prebid.server.proto.openrtb.ext.response.seatnonbid.NonBid; import org.prebid.server.proto.openrtb.ext.response.seatnonbid.SeatNonBid; import org.prebid.server.settings.model.Account; @@ -206,8 +196,6 @@ public class BidResponseCreatorTest extends VertxTest { private CacheTtl mediaTypeCacheTtl; @Mock(strictness = LENIENT) private CacheDefaultTtlProperties cacheDefaultProperties; - @Mock(strictness = LENIENT) - private Metrics metrics; @Spy private WinningBidComparatorFactory winningBidComparatorFactory; @@ -1970,7 +1958,6 @@ public void shouldTruncateTargetingKeywordsByGlobalConfig() { contextBuilder -> contextBuilder.auctionParticipations(toAuctionParticipant(bidderResponses))); target = new BidResponseCreator( - 0, coreCacheService, bidderCatalog, vastModifier, @@ -1985,7 +1972,6 @@ public void shouldTruncateTargetingKeywordsByGlobalConfig() { false, clock, jacksonMapper, - metrics, mediaTypeCacheTtl, cacheDefaultProperties); @@ -3109,7 +3095,7 @@ public void shouldPopulateBidExpBasedOnCachedResult() { // given final Bid bid = Bid.builder().id("bidId").impid("impId").exp(10).price(BigDecimal.valueOf(5.67)).build(); final Imp imp = Imp.builder().id("impId").exp(20).build(); - final List bidderResponses = asList(BidderResponse.of( + final List bidderResponses = singletonList(BidderResponse.of( "bidder1", givenSeatBid(BidderBid.of(bid, banner, "seat", "USD")), 100)); @@ -3612,7 +3598,7 @@ public void shouldThrowExceptionWhenBidAdmIsParsedButImpNativeNotFound() throws assertThat(bidResponse.getExt()) .extracting(ExtBidResponse::getErrors) .extracting(error -> error.get("seat")) - .extracting(extBidderErrors -> extBidderErrors.getFirst()) + .extracting(List::getFirst) .isEqualTo(ExtBidderError.of(3, "Could not find native imp")); } @@ -3652,7 +3638,7 @@ public void shouldThrowExceptionWhenNativeRequestIsInvalid() throws JsonProcessi assertThat(bidResponse.getExt()) .extracting(ExtBidResponse::getErrors) .extracting(error -> error.get("seat")) - .extracting(extBidderErrors -> extBidderErrors.getFirst()) + .extracting(List::getFirst) .isEqualTo(ExtBidderError.of(3, "No content to map due to end-of-input\n" + " at [Source: (String)\"\"; line: 1, column: 0]")); } @@ -3690,9 +3676,9 @@ public void shouldPopulateBidAdmIfResponseAssetsIsNull() throws JsonProcessingEx // then assertThat(bidResponse) .extracting(BidResponse::getSeatbid) - .extracting(seatBids -> seatBids.getFirst()) + .extracting(List::getFirst) .extracting(SeatBid::getBid) - .extracting(bids -> bids.getFirst()) + .extracting(List::getFirst) .extracting(Bid::getAdm) .isEqualTo(adm); } @@ -3863,579 +3849,6 @@ public void shouldCopyImpExtPrebidPassThroughToResponseBidExtPrebidPassThroughWh .containsExactly(TextNode.valueOf("passthrough")); } - @Test - public void shouldAddExtPrebidFledgeIfAvailable() { - // given - final Imp imp = givenImp("i1").toBuilder() - .ext(mapper.createObjectNode().put("ae", 1)) - .build(); - final BidRequest bidRequest = givenBidRequest(identity(), identity(), imp); - final FledgeAuctionConfig fledgeAuctionConfig = givenFledgeAuctionConfig("i1"); - final Bid bid = Bid.builder() - .id("bidId1") - .price(BigDecimal.valueOf(2.37)) - .impid("i1") - .ext(mapper.createObjectNode().set("prebid", mapper.valueToTree(ExtBidPrebid.builder() - .meta(ExtBidPrebidMeta.builder().adapterCode("adapter1").build()) - .build()))) - .build(); - final List bidderResponses = singletonList( - BidderResponse.of("bidder1", - BidderSeatBid.builder() - .bids(List.of(BidderBid.of(bid, banner, "seat", "USD"))) - .fledgeAuctionConfigs(List.of(fledgeAuctionConfig)) - .build(), 100)); - - final AuctionContext auctionContext = givenAuctionContext( - bidRequest, - contextBuilder -> contextBuilder.auctionParticipations(toAuctionParticipant(bidderResponses))); - - // when - final BidResponse bidResponse = target - .create(auctionContext, CACHE_INFO, MULTI_BIDS) - .result(); - - // then - assertThat(bidResponse.getExt().getPrebid().getFledge().getAuctionConfigs()) - .isNotEmpty() - .first() - .usingRecursiveComparison() - .isEqualTo(fledgeAuctionConfig.toBuilder() - .bidder("seat") - .adapter("adapter1") - .build()); - } - - @Test - public void shouldAddExtIgiIfAvailableAndExtRequestPrebidPaaFormatIsIab() { - // given - final Imp imp = givenImp("i1").toBuilder() - .ext(mapper.createObjectNode().put("ae", 1)) - .build(); - final BidRequest bidRequest = givenBidRequest(identity(), ext -> ext.paaFormat(PaaFormat.IAB), imp); - final ExtIgi igi = ExtIgi.builder() - .impid("impId") - .igs(singletonList(ExtIgiIgs.builder().impId("impId").config(mapper.createObjectNode()).build())) - .build(); - - final Bid bid = Bid.builder() - .id("bidId1") - .price(BigDecimal.valueOf(2.37)) - .impid("i1") - .ext(mapper.createObjectNode().set("prebid", mapper.valueToTree(ExtBidPrebid.builder() - .meta(ExtBidPrebidMeta.builder().adapterCode("adapter1").build()) - .build()))) - .build(); - final List bidderResponses = singletonList( - BidderResponse.of("bidder1", - BidderSeatBid.builder() - .bids(List.of(BidderBid.of(bid, banner, "seat", "USD"))) - .igi(singletonList(igi)) - .build(), 100)); - - final AuctionContext auctionContext = givenAuctionContext( - bidRequest, - contextBuilder -> contextBuilder.auctionParticipations(toAuctionParticipant(bidderResponses))); - - // when - final BidResponse bidResponse = target - .create(auctionContext, CACHE_INFO, MULTI_BIDS) - .result(); - - // then - assertThat(bidResponse.getExt().getIgi()).containsExactly( - ExtIgi.builder() - .impid("impId") - .igs(singletonList(ExtIgiIgs.builder() - .impId("impId") - .config(mapper.createObjectNode()) - .ext(ExtIgiIgsExt.of("seat", "adapter1")) - .build())) - .build()); - } - - @Test - public void shouldAddExtPrebidFledgeIfAvailableAndExtRequestPrebidPaaFormatIsOriginal() { - // given - final Imp imp = givenImp("impId").toBuilder() - .ext(mapper.createObjectNode().put("ae", 1)) - .build(); - final BidRequest bidRequest = givenBidRequest(identity(), ext -> ext.paaFormat(PaaFormat.ORIGINAL), imp); - final ExtIgi igi = ExtIgi.builder() - .impid("impId") - .igs(singletonList(ExtIgiIgs.builder().impId("impId").config(mapper.createObjectNode()).build())) - .build(); - - final Bid bid = Bid.builder() - .id("bidId1") - .price(BigDecimal.valueOf(2.37)) - .ext(mapper.createObjectNode().set("prebid", mapper.valueToTree(ExtBidPrebid.builder() - .meta(ExtBidPrebidMeta.builder().adapterCode("adapter1").build()) - .build()))) - .impid("impId") - .build(); - final List bidderResponses = singletonList( - BidderResponse.of("bidder1", - BidderSeatBid.builder() - .bids(List.of(BidderBid.of(bid, banner, "seat", "USD"))) - .igi(singletonList(igi)) - .build(), 100)); - - final AuctionContext auctionContext = givenAuctionContext( - bidRequest, - contextBuilder -> contextBuilder.auctionParticipations(toAuctionParticipant(bidderResponses))); - - // when - final BidResponse bidResponse = target - .create(auctionContext, CACHE_INFO, MULTI_BIDS) - .result(); - - // then - assertThat(bidResponse.getExt()) - .extracting(ExtBidResponse::getPrebid) - .extracting(ExtBidResponsePrebid::getFledge) - .extracting(ExtBidResponseFledge::getAuctionConfigs) - .asList() - .containsExactly( - FledgeAuctionConfig.builder() - .impId("impId") - .config(mapper.createObjectNode()) - .bidder("seat") - .adapter("adapter1") - .build()); - } - - @Test - public void shouldAddExtIgiIfAvailableAndExtRequestPrebidPaaFormatIsAbsentAndAccountConfigPaaFormatSetToIab() { - // given - final Imp imp = givenImp("impId").toBuilder() - .ext(mapper.createObjectNode().put("ae", 1)) - .build(); - final BidRequest bidRequest = givenBidRequest(identity(), identity(), imp); - final ExtIgi igi = ExtIgi.builder() - .impid("impId") - .igs(singletonList(ExtIgiIgs.builder().impId("impId").config(mapper.createObjectNode()).build())) - .build(); - - final Bid bid = Bid.builder() - .id("bidId1") - .price(BigDecimal.valueOf(2.37)) - .impid("impId") - .ext(mapper.createObjectNode().set("prebid", mapper.valueToTree(ExtBidPrebid.builder() - .meta(ExtBidPrebidMeta.builder().adapterCode("adapter1").build()) - .build()))) - .build(); - final List bidderResponses = singletonList( - BidderResponse.of("bidder1", - BidderSeatBid.builder() - .bids(List.of(BidderBid.of(bid, banner, "seat", "USD"))) - .igi(singletonList(igi)) - .build(), 100)); - - final AuctionContext auctionContext = givenAuctionContext( - bidRequest, - contextBuilder -> contextBuilder - .auctionParticipations(toAuctionParticipant(bidderResponses)) - .account(Account.builder() - .auction(AccountAuctionConfig.builder().paaFormat(PaaFormat.IAB).build()) - .build())); - - // when - final BidResponse bidResponse = target - .create(auctionContext, CACHE_INFO, MULTI_BIDS) - .result(); - - // then - assertThat(bidResponse.getExt().getIgi()).containsExactly( - ExtIgi.builder() - .impid("impId") - .igs(singletonList(ExtIgiIgs.builder() - .impId("impId") - .config(mapper.createObjectNode()) - .ext(ExtIgiIgsExt.of("seat", "adapter1")) - .build())) - .build()); - } - - @Test - public void shouldAddExtPrebidFledgeIfAvailableAndRequestPaaFormatIsAbsentAndAccountConfigPaaFormatSetToOriginal() { - // given - final Imp imp = givenImp("impId").toBuilder() - .ext(mapper.createObjectNode().put("ae", 1)) - .build(); - final BidRequest bidRequest = givenBidRequest(identity(), identity(), imp); - final ExtIgi igi = ExtIgi.builder() - .impid("impId") - .igs(singletonList(ExtIgiIgs.builder().impId("impId").config(mapper.createObjectNode()).build())) - .build(); - - final Bid bid = Bid.builder() - .id("bidId1") - .price(BigDecimal.valueOf(2.37)) - .ext(mapper.createObjectNode().set("prebid", mapper.valueToTree(ExtBidPrebid.builder() - .meta(ExtBidPrebidMeta.builder().adapterCode("adapter1").build()) - .build()))) - .impid("impId") - .build(); - final List bidderResponses = singletonList( - BidderResponse.of("bidder1", - BidderSeatBid.builder() - .bids(List.of(BidderBid.of(bid, banner, "seat", "USD"))) - .igi(singletonList(igi)) - .build(), 100)); - - final AuctionContext auctionContext = givenAuctionContext( - bidRequest, - contextBuilder -> contextBuilder - .auctionParticipations(toAuctionParticipant(bidderResponses)) - .account(Account.builder() - .auction(AccountAuctionConfig.builder().paaFormat(PaaFormat.ORIGINAL).build()) - .build())); - - // when - final BidResponse bidResponse = target - .create(auctionContext, CACHE_INFO, MULTI_BIDS) - .result(); - - // then - assertThat(bidResponse.getExt()) - .extracting(ExtBidResponse::getPrebid) - .extracting(ExtBidResponsePrebid::getFledge) - .extracting(ExtBidResponseFledge::getAuctionConfigs) - .asList() - .containsExactly( - FledgeAuctionConfig.builder() - .impId("impId") - .config(mapper.createObjectNode()) - .bidder("seat") - .adapter("adapter1") - .build()); - } - - @Test - public void shouldDefaultToOriginalPaaFormat() { - // given - final Imp imp = givenImp("impId").toBuilder() - .ext(mapper.createObjectNode().put("ae", 1)) - .build(); - final BidRequest bidRequest = givenBidRequest(identity(), identity(), imp); - final ExtIgi igi = ExtIgi.builder() - .impid("impId") - .igs(singletonList(ExtIgiIgs.builder().impId("impId").config(mapper.createObjectNode()).build())) - .build(); - - final Bid bid = Bid.builder() - .id("bidId1") - .price(BigDecimal.valueOf(2.37)) - .impid("impId") - .ext(mapper.createObjectNode().set("prebid", mapper.valueToTree(ExtBidPrebid.builder() - .meta(ExtBidPrebidMeta.builder().adapterCode("adapter1").build()) - .build()))) - .build(); - final List bidderResponses = singletonList( - BidderResponse.of("bidder1", - BidderSeatBid.builder() - .bids(List.of(BidderBid.of(bid, banner, "seat", "USD"))) - .igi(singletonList(igi)) - .build(), 100)); - - final AuctionContext auctionContext = givenAuctionContext( - bidRequest, - contextBuilder -> contextBuilder.auctionParticipations(toAuctionParticipant(bidderResponses))); - - // when - final BidResponse bidResponse = target - .create(auctionContext, CACHE_INFO, MULTI_BIDS) - .result(); - - // then - assertThat(bidResponse.getExt()) - .extracting(ExtBidResponse::getPrebid) - .extracting(ExtBidResponsePrebid::getFledge) - .extracting(ExtBidResponseFledge::getAuctionConfigs) - .asList() - .containsExactly( - FledgeAuctionConfig.builder() - .impId("impId") - .config(mapper.createObjectNode()) - .bidder("seat") - .adapter("adapter1") - .build()); - } - - @Test - public void shouldDropExtIgiIgbIfAvailableAndExtIgiImpIdIsAbsent() { - // given - final Imp imp = givenImp("impId").toBuilder() - .ext(mapper.createObjectNode().put("ae", 1)) - .build(); - final BidRequest bidRequest = givenBidRequest(identity(), ext -> ext.paaFormat(PaaFormat.IAB), imp); - final ExtIgi igi = ExtIgi.builder() - .igs(singletonList(ExtIgiIgs.builder().impId("impId").config(mapper.createObjectNode()).build())) - .igb(singletonList(ExtIgiIgb.builder().build())) - .build(); - - final Bid bid = Bid.builder() - .id("bidId1") - .price(BigDecimal.valueOf(2.37)) - .impid("impId") - .ext(mapper.createObjectNode().set("prebid", mapper.valueToTree(ExtBidPrebid.builder() - .meta(ExtBidPrebidMeta.builder().adapterCode("adapter1").build()) - .build()))) - .build(); - final List bidderResponses = singletonList( - BidderResponse.of("bidder1", - BidderSeatBid.builder() - .bids(List.of(BidderBid.of(bid, banner, "seat", "USD"))) - .igi(singletonList(igi)) - .build(), 100)); - - final AuctionContext auctionContext = givenAuctionContext( - bidRequest, - contextBuilder -> contextBuilder - .debugContext(DebugContext.of(true, false, null)) - .auctionParticipations(toAuctionParticipant(bidderResponses))); - - // when - final BidResponse bidResponse = target - .create(auctionContext, CACHE_INFO, MULTI_BIDS) - .result(); - - // then - assertThat(bidResponse.getExt()) - .extracting(ExtBidResponse::getIgi) - .asList() - .containsExactly( - ExtIgi.builder() - .igs(singletonList( - ExtIgiIgs.builder() - .impId("impId") - .config(mapper.createObjectNode()) - .ext(ExtIgiIgsExt.of("seat", "adapter1")) - .build())) - .build()); - - assertThat(bidResponse.getExt()) - .extracting(ExtBidResponse::getWarnings) - .extracting(warnings -> warnings.get(PREBID)) - .asList() - .containsExactly( - ExtBidderError.of( - BidderError.Type.generic.getCode(), - "ExtIgi with absent impId from bidder: seat")); - verify(metrics).updateAlertsMetrics(MetricName.general); - } - - @Test - public void shouldDropExtIgiIgsIfAvailableAndExtIgiIgsImpIdIsAbsent() { - // given - final Imp imp = givenImp("impId").toBuilder() - .ext(mapper.createObjectNode().put("ae", 1)) - .build(); - final BidRequest bidRequest = givenBidRequest(identity(), ext -> ext.paaFormat(PaaFormat.IAB), imp); - final ExtIgi igi = ExtIgi.builder() - .impid("impId") - .igs(singletonList(ExtIgiIgs.builder().config(mapper.createObjectNode()).build())) - .igb(singletonList(ExtIgiIgb.builder().build())) - .build(); - - final Bid bid = Bid.builder() - .id("bidId1") - .price(BigDecimal.valueOf(2.37)) - .ext(mapper.createObjectNode().set("prebid", mapper.valueToTree(ExtBidPrebid.builder() - .meta(ExtBidPrebidMeta.builder().adapterCode("adapter1").build()) - .build()))) - .impid("impId").build(); - final List bidderResponses = singletonList( - BidderResponse.of("bidder1", - BidderSeatBid.builder() - .bids(List.of(BidderBid.of(bid, banner, "seat", "USD"))) - .igi(singletonList(igi)) - .build(), 100)); - - final AuctionContext auctionContext = givenAuctionContext( - bidRequest, - contextBuilder -> contextBuilder - .debugContext(DebugContext.of(true, false, null)) - .auctionParticipations(toAuctionParticipant(bidderResponses))); - - // when - final BidResponse bidResponse = target - .create(auctionContext, CACHE_INFO, MULTI_BIDS) - .result(); - - // then - assertThat(bidResponse.getExt()) - .extracting(ExtBidResponse::getIgi) - .asList() - .containsExactly( - ExtIgi.builder() - .impid("impId") - .igb(singletonList(ExtIgiIgb.builder().build())) - .build()); - - assertThat(bidResponse.getExt()) - .extracting(ExtBidResponse::getWarnings) - .extracting(warnings -> warnings.get(PREBID)) - .asList() - .containsExactly( - ExtBidderError.of( - BidderError.Type.generic.getCode(), - "ExtIgiIgs with absent impId from bidder: seat")); - verify(metrics).updateAlertsMetrics(MetricName.general); - } - - @Test - public void shouldDropExtIgiIgsIfAvailableAndExtIgiIgsConfigIsAbsent() { - // given - final Imp imp = givenImp("impId").toBuilder() - .ext(mapper.createObjectNode().put("ae", 1)) - .build(); - final BidRequest bidRequest = givenBidRequest(identity(), ext -> ext.paaFormat(PaaFormat.IAB), imp); - final ExtIgi igi = ExtIgi.builder() - .impid("impId") - .igs(singletonList(ExtIgiIgs.builder().impId("impId").build())) - .igb(singletonList(ExtIgiIgb.builder().build())) - .build(); - - final Bid bid = Bid.builder().id("bidId1").price(BigDecimal.valueOf(2.37)).impid("impId").build(); - final List bidderResponses = singletonList( - BidderResponse.of("bidder1", - BidderSeatBid.builder() - .bids(List.of(BidderBid.of(bid, banner, "seat", "USD"))) - .igi(singletonList(igi)) - .build(), 100)); - - final AuctionContext auctionContext = givenAuctionContext( - bidRequest, - contextBuilder -> contextBuilder - .debugContext(DebugContext.of(true, false, null)) - .auctionParticipations(toAuctionParticipant(bidderResponses))); - - // when - final BidResponse bidResponse = target - .create(auctionContext, CACHE_INFO, MULTI_BIDS) - .result(); - - // then - assertThat(bidResponse.getExt()) - .extracting(ExtBidResponse::getIgi) - .asList() - .containsExactly( - ExtIgi.builder() - .impid("impId") - .igb(singletonList(ExtIgiIgb.builder().build())) - .build()); - - assertThat(bidResponse.getExt()) - .extracting(ExtBidResponse::getWarnings) - .extracting(warnings -> warnings.get(PREBID)) - .asList() - .containsExactly( - ExtBidderError.of( - BidderError.Type.generic.getCode(), - "ExtIgiIgs with absent config from bidder: seat")); - verify(metrics).updateAlertsMetrics(MetricName.general); - } - - @Test - public void shouldDropExtIgiIfAvailableAndExtIgiIgsAndExtIgiIgbAreAbsent() { - // given - final Imp imp = givenImp("impId").toBuilder() - .ext(mapper.createObjectNode().put("ae", 1)) - .build(); - final BidRequest bidRequest = givenBidRequest(identity(), ext -> ext.paaFormat(PaaFormat.IAB), imp); - final ExtIgi igi = ExtIgi.builder() - .impid("impId") - .build(); - - final Bid bid = Bid.builder().id("bidId1").price(BigDecimal.valueOf(2.37)).impid("impId").build(); - final List bidderResponses = singletonList( - BidderResponse.of("bidder1", - BidderSeatBid.builder() - .bids(List.of(BidderBid.of(bid, banner, "seat", "USD"))) - .igi(singletonList(igi)) - .build(), 100)); - - final AuctionContext auctionContext = givenAuctionContext( - bidRequest, - contextBuilder -> contextBuilder - .debugContext(DebugContext.of(true, false, null)) - .auctionParticipations(toAuctionParticipant(bidderResponses))); - - // when - final BidResponse bidResponse = target - .create(auctionContext, CACHE_INFO, MULTI_BIDS) - .result(); - - // then - assertThat(bidResponse.getExt()) - .extracting(ExtBidResponse::getIgi) - .isNull(); - } - - @Test - public void shouldAddExtPrebidFledgeIfAvailableEvenIfBidsEmpty() { - // given - final Imp imp = givenImp("i1").toBuilder() - .ext(mapper.createObjectNode().put("ae", 1)) - .build(); - final BidRequest bidRequest = givenBidRequest(identity(), identity(), imp); - final FledgeAuctionConfig fledgeAuctionConfig = givenFledgeAuctionConfig("i1"); - final List bidderResponses = singletonList( - BidderResponse.of("bidder1", - BidderSeatBid.builder() - .bids(Collections.emptyList()) - .fledgeAuctionConfigs(List.of(fledgeAuctionConfig)) - .build(), 100)); - - final AuctionContext auctionContext = givenAuctionContext( - bidRequest, - contextBuilder -> contextBuilder.auctionParticipations(toAuctionParticipant(bidderResponses))); - - // when - final BidResponse bidResponse = target - .create(auctionContext, CACHE_INFO, MULTI_BIDS) - .result(); - - // then - assertThat(bidResponse.getExt().getPrebid().getFledge().getAuctionConfigs()) - .isNotEmpty() - .first() - .usingRecursiveComparison() - .isEqualTo(fledgeAuctionConfig.toBuilder() - .bidder("bidder1") - .adapter("bidder1") - .build()); - } - - @Test - public void shouldDropFledgeResponsesReferencingUnknownImps() { - // given - final Imp imp = givenImp("i1"); - final BidRequest bidRequest = givenBidRequest(identity(), identity(), imp); - final FledgeAuctionConfig fledgeAuctionConfig = givenFledgeAuctionConfig("i1"); - final List bidderResponses = singletonList( - BidderResponse.of("bidder1", - BidderSeatBid.builder() - .bids(Collections.emptyList()) - .fledgeAuctionConfigs(List.of(fledgeAuctionConfig)) - .build(), 100)); - - final AuctionContext auctionContext = givenAuctionContext( - bidRequest, - contextBuilder -> contextBuilder.auctionParticipations(toAuctionParticipant(bidderResponses))); - - // when - final BidResponse bidResponse = target - .create(auctionContext, CACHE_INFO, MULTI_BIDS) - .result(); - - // then - assertThat(bidResponse.getExt().getPrebid().getFledge()) - .isNull(); - } - @Test public void shouldPopulateExtPrebidSeatNonBidWhenReturnAllBidStatusFlagIsTrue() { // given @@ -4678,7 +4091,7 @@ public void createShouldSendCacheRequestWithExpectedTtlAndSetTtlFromBid() { // given final Bid bid = Bid.builder().id("bidId").impid("impId").exp(10).price(BigDecimal.valueOf(5.67)).build(); final Imp imp = Imp.builder().id("impId").exp(20).build(); - final List bidderResponses = asList(BidderResponse.of( + final List bidderResponses = singletonList(BidderResponse.of( "bidder1", givenSeatBid(BidderBid.of(bid, video, "seat", "USD")), 100)); @@ -4747,7 +4160,7 @@ public void createShouldSendCacheRequestWithExpectedTtlAndSetTtlFromImp() { // given final Bid bid = Bid.builder().id("bidId").impid("impId").exp(null).price(BigDecimal.valueOf(5.67)).build(); final Imp imp = Imp.builder().id("impId").exp(20).build(); - final List bidderResponses = asList(BidderResponse.of( + final List bidderResponses = singletonList(BidderResponse.of( "bidder1", givenSeatBid(BidderBid.of(bid, video, "seat", "USD")), 100)); @@ -4816,7 +4229,7 @@ public void createShouldSendCacheRequestWithExpectedTtlAndSetTtlFromRequest() { // given final Bid bid = Bid.builder().id("bidId").impid("impId").exp(null).price(BigDecimal.valueOf(5.67)).build(); final Imp imp = Imp.builder().id("impId").exp(null).build(); - final List bidderResponses = asList(BidderResponse.of( + final List bidderResponses = singletonList(BidderResponse.of( "bidder1", givenSeatBid(BidderBid.of(bid, video, "seat", "USD")), 100)); @@ -4885,7 +4298,7 @@ public void createShouldSendCacheRequestWithExpectedTtlAndSetTtlFromAccountBanne // given final Bid bid = Bid.builder().id("bidId").impid("impId").exp(null).price(BigDecimal.valueOf(5.67)).build(); final Imp imp = Imp.builder().id("impId").exp(null).build(); - final List bidderResponses = asList(BidderResponse.of( + final List bidderResponses = singletonList(BidderResponse.of( "bidder1", givenSeatBid(BidderBid.of(bid, banner, "seat", "USD")), 100)); @@ -4954,7 +4367,7 @@ public void createShouldSendCacheRequestWithExpectedTtlAndSetTtlFromAccountVideo // given final Bid bid = Bid.builder().id("bidId").impid("impId").exp(null).price(BigDecimal.valueOf(5.67)).build(); final Imp imp = Imp.builder().id("impId").exp(null).build(); - final List bidderResponses = asList(BidderResponse.of( + final List bidderResponses = singletonList(BidderResponse.of( "bidder1", givenSeatBid(BidderBid.of(bid, video, "seat", "USD")), 100)); @@ -5023,7 +4436,7 @@ public void createShouldSendCacheRequestWithExpectedTtlAndSetTtlFromMediaTypeTtl // given final Bid bid = Bid.builder().id("bidId").impid("impId").exp(null).price(BigDecimal.valueOf(5.67)).build(); final Imp imp = Imp.builder().id("impId").exp(null).build(); - final List bidderResponses = asList(BidderResponse.of( + final List bidderResponses = singletonList(BidderResponse.of( "bidder1", givenSeatBid(BidderBid.of(bid, banner, "seat", "USD")), 100)); @@ -5092,7 +4505,7 @@ public void createShouldSendCacheRequestWithExpectedTtlAndSetTtlFromMediaTypeTtl // given final Bid bid = Bid.builder().id("bidId").impid("impId").exp(null).price(BigDecimal.valueOf(5.67)).build(); final Imp imp = Imp.builder().id("impId").exp(null).build(); - final List bidderResponses = asList(BidderResponse.of( + final List bidderResponses = singletonList(BidderResponse.of( "bidder1", givenSeatBid(BidderBid.of(bid, video, "seat", "USD")), 100)); @@ -5161,7 +4574,7 @@ public void createShouldSendCacheRequestWithExpectedTtlAndSetDefaultTtlForBanner // given final Bid bid = Bid.builder().id("bidId").impid("impId").exp(null).price(BigDecimal.valueOf(5.67)).build(); final Imp imp = Imp.builder().id("impId").exp(null).build(); - final List bidderResponses = asList(BidderResponse.of( + final List bidderResponses = singletonList(BidderResponse.of( "bidder1", givenSeatBid(BidderBid.of(bid, banner, "seat", "USD")), 100)); @@ -5230,7 +4643,7 @@ public void createShouldSendCacheRequestWithExpectedTtlAndSetDefaultTtlForVideoB // given final Bid bid = Bid.builder().id("bidId").impid("impId").exp(null).price(BigDecimal.valueOf(5.67)).build(); final Imp imp = Imp.builder().id("impId").exp(null).build(); - final List bidderResponses = asList(BidderResponse.of( + final List bidderResponses = singletonList(BidderResponse.of( "bidder1", givenSeatBid(BidderBid.of(bid, video, "seat", "USD")), 100)); @@ -5299,7 +4712,7 @@ public void createShouldSendCacheRequestWithExpectedTtlAndSetDefaultTtlForAudioB // given final Bid bid = Bid.builder().id("bidId").impid("impId").exp(null).price(BigDecimal.valueOf(5.67)).build(); final Imp imp = Imp.builder().id("impId").exp(null).build(); - final List bidderResponses = asList(BidderResponse.of( + final List bidderResponses = singletonList(BidderResponse.of( "bidder1", givenSeatBid(BidderBid.of(bid, audio, "seat", "USD")), 100)); @@ -5368,7 +4781,7 @@ public void createShouldSendCacheRequestWithExpectedTtlAndSetDefaultTtlForNative // given final Bid bid = Bid.builder().id("bidId").impid("impId").exp(null).price(BigDecimal.valueOf(5.67)).build(); final Imp imp = Imp.builder().id("impId").exp(null).build(); - final List bidderResponses = asList(BidderResponse.of( + final List bidderResponses = singletonList(BidderResponse.of( "bidder1", givenSeatBid(BidderBid.of(bid, xNative, "seat", "USD")), 100)); @@ -5437,7 +4850,7 @@ public void createShouldSendCacheRequestWithTtlFromMediaTypeWhenAccountIsEmpty() // given final Bid bid = Bid.builder().id("bidId").impid("impId").exp(null).price(BigDecimal.valueOf(5.67)).build(); final Imp imp = Imp.builder().id("impId").exp(null).build(); - final List bidderResponses = asList(BidderResponse.of( + final List bidderResponses = singletonList(BidderResponse.of( "bidder1", givenSeatBid(BidderBid.of(bid, banner, "seat", "USD")), 100)); @@ -5495,7 +4908,7 @@ public void createShouldSendCacheRequestWithNoTtlAndSetEmptyTtl() { // given final Bid bid = Bid.builder().id("bidId").impid("impId").exp(null).price(BigDecimal.valueOf(5.67)).build(); final Imp imp = Imp.builder().id("impId").exp(null).build(); - final List bidderResponses = asList(BidderResponse.of( + final List bidderResponses = singletonList(BidderResponse.of( "bidder1", givenSeatBid(BidderBid.of(bid, banner, "seat", "USD")), 100)); @@ -5553,7 +4966,7 @@ public void createShouldSendCacheRequestWithVideoBidWithTtlMaxOfTtlAndVideoTtl() // given final Bid bid = Bid.builder().id("bidId").impid("impId").exp(null).price(BigDecimal.valueOf(5.67)).build(); final Imp imp = Imp.builder().id("impId").exp(null).build(); - final List bidderResponses = asList(BidderResponse.of( + final List bidderResponses = singletonList(BidderResponse.of( "bidder1", givenSeatBid(BidderBid.of(bid, video, "seat", "USD")), 100)); @@ -5612,7 +5025,7 @@ public void createShouldSendCacheRequestWithBannerBidWithTtlMaxOfTtlAndVideoTtl( // given final Bid bid = Bid.builder().id("bidId").impid("impId").exp(null).price(BigDecimal.valueOf(5.67)).build(); final Imp imp = Imp.builder().id("impId").exp(null).build(); - final List bidderResponses = asList(BidderResponse.of( + final List bidderResponses = singletonList(BidderResponse.of( "bidder1", givenSeatBid(BidderBid.of(bid, banner, "seat", "USD")), 100)); @@ -5769,13 +5182,6 @@ private static BidderSeatBid givenSeatBid(BidderBid... bids) { return BidderSeatBid.of(List.of(bids)); } - private static FledgeAuctionConfig givenFledgeAuctionConfig(String impId) { - return FledgeAuctionConfig.builder() - .impId(impId) - .config(mapper.createObjectNode().put("references", impId)) - .build(); - } - private static ExtRequestTargeting givenTargeting() { return ExtRequestTargeting.builder() .pricegranularity(mapper.valueToTree( @@ -5810,7 +5216,6 @@ private static ExtBidPrebid toExtBidPrebid(ObjectNode ext) { private BidResponseCreator givenBidResponseCreator(int truncateAttrChars, boolean enforcedRandomBidId) { return new BidResponseCreator( - 0, coreCacheService, bidderCatalog, vastModifier, @@ -5825,7 +5230,6 @@ private BidResponseCreator givenBidResponseCreator(int truncateAttrChars, boolea enforcedRandomBidId, clock, jacksonMapper, - metrics, mediaTypeCacheTtl, cacheDefaultProperties); } diff --git a/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java b/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java index 23cebedf491..b257da697c6 100644 --- a/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java +++ b/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java @@ -113,7 +113,6 @@ import org.prebid.server.proto.openrtb.ext.request.ExtBidderConfigOrtb; import org.prebid.server.proto.openrtb.ext.request.ExtDooh; import org.prebid.server.proto.openrtb.ext.request.ExtGranularityRange; -import org.prebid.server.proto.openrtb.ext.request.ExtImpAuctionEnvironment; import org.prebid.server.proto.openrtb.ext.request.ExtPriceGranularity; import org.prebid.server.proto.openrtb.ext.request.ExtRequest; import org.prebid.server.proto.openrtb.ext.request.ExtRequestCurrency; @@ -152,7 +151,6 @@ import org.prebid.server.proto.openrtb.ext.response.ExtModulesTraceStage; import org.prebid.server.proto.openrtb.ext.response.ExtModulesTraceStageOutcome; import org.prebid.server.proto.openrtb.ext.response.ExtResponseDebug; -import org.prebid.server.proto.openrtb.ext.response.FledgeAuctionConfig; import org.prebid.server.settings.model.Account; import org.prebid.server.settings.model.AccountAlternateBidderCodes; import org.prebid.server.settings.model.AccountAlternateBidderCodesBidder; @@ -1310,51 +1308,6 @@ public void shouldReturnSeparateSeatBidsForTheSameBidderIfBiddersAliasAndBidderW .containsOnly(1, 1); } - @Test - public void shouldPropagateFledgeResponseWithBidderAlias() { - // given - final FledgeAuctionConfig fledgeAuctionConfig = givenFledgeAuctionConfig("impId"); - given(httpBidderRequester.requestBids(any(), any(), any(), any(), any(), any(), anyBoolean())) - .willReturn(Future.succeededFuture(givenEmptySeatBid() - .toBuilder() - .fledgeAuctionConfigs(List.of(fledgeAuctionConfig)) - .build())); - - final BidRequest bidRequest = givenBidRequest( - singletonList(Imp.builder() - .id("impId") - .ext(mapper.valueToTree( - Map.of("prebid", singletonMap("bidder", singletonMap("bidderAlias", 1)), - "ae", 1))) - .build()), - builder -> builder.ext(ExtRequest.of(ExtRequestPrebid.builder() - .aliases(singletonMap("bidderAlias", "bidder")) - .build()))); - - // when - target.holdAuction(givenRequestContext(bidRequest)); - - verify(httpBidderRequester, times(1)) - .requestBids(any(), any(), any(), any(), any(), any(), anyBoolean()); - - // then - final BidRequest capturedBidRequest = captureBidRequest(); - - assertThat(capturedBidRequest.getImp()) - .extracting(Imp::getExt) - .containsOnly(mapper.valueToTree(ExtPrebid.of(null, 1, - ExtImpAuctionEnvironment.ON_DEVICE_IG_AUCTION_FLEDGE))); - - final List auctionParticipations = captureAuctionParticipations(); - - assertThat(auctionParticipations) - .hasSize(1) - .extracting(AuctionParticipation::getBidderResponse) - .extracting(BidderResponse::getSeatBid) - .extracting(BidderSeatBid::getFledgeAuctionConfigs) - .containsExactly(List.of(fledgeAuctionConfig)); - } - @Test public void shouldOverrideDebugEnabledFlag() { // given @@ -4742,13 +4695,6 @@ private static Bid givenBid(Function bidBuilder) .build(); } - private static FledgeAuctionConfig givenFledgeAuctionConfig(String impId) { - return FledgeAuctionConfig.builder() - .impId(impId) - .config(mapper.createObjectNode().put("references", impId)) - .build(); - } - private static ExtBidPrebid toExtBidPrebid(ObjectNode ext) { try { return mapper.treeToValue(ext.get("prebid"), ExtBidPrebid.class); diff --git a/src/test/java/org/prebid/server/auction/ImpAdjusterTest.java b/src/test/java/org/prebid/server/auction/ImpAdjusterTest.java index e69a6169d77..6f46ad06811 100644 --- a/src/test/java/org/prebid/server/auction/ImpAdjusterTest.java +++ b/src/test/java/org/prebid/server/auction/ImpAdjusterTest.java @@ -1,7 +1,6 @@ package org.prebid.server.auction; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.IntNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.iab.openrtb.request.Deal; import com.iab.openrtb.request.Imp; @@ -69,79 +68,6 @@ public void adjustShouldReturnOriginalImpWhenImpExtPrebidImpIsAbsent() { assertThat(debugMessages).isEmpty(); } - @Test - public void adjustShouldSetImpExtIgsAeWhenImpExtAeIsZero() { - // given - final ObjectNode ext = mapper.createObjectNode(); - ext.set("ae", IntNode.valueOf(0)); - - final Imp givenImp = Imp.builder().ext(ext).build(); - - final List debugMessages = new ArrayList<>(); - - // when - final Imp result = target.adjust(givenImp, "someBidder", debugMessages); - - // then - assertThat(result.getExt().get("igs").get("ae")).isEqualTo(IntNode.valueOf(0)); - assertThat(debugMessages).isEmpty(); - } - - @Test - public void adjustShouldSetImpExtIgsAeWhenImpExtAeIsOne() { - // given - final ObjectNode ext = mapper.createObjectNode(); - ext.set("ae", IntNode.valueOf(1)); - - final Imp givenImp = Imp.builder().ext(ext).build(); - - final List debugMessages = new ArrayList<>(); - - // when - final Imp result = target.adjust(givenImp, "someBidder", debugMessages); - - // then - assertThat(result.getExt().get("igs").get("ae")).isEqualTo(IntNode.valueOf(1)); - assertThat(debugMessages).isEmpty(); - } - - @Test - public void adjustShouldNotSetImpExtIgsAeWhenImpExtAeIsNotZeroOrOne() { - // given - final ObjectNode ext = mapper.createObjectNode(); - ext.set("ae", IntNode.valueOf(3)); - - final Imp givenImp = Imp.builder().ext(ext).build(); - - final List debugMessages = new ArrayList<>(); - - // when - final Imp result = target.adjust(givenImp, "someBidder", debugMessages); - - // then - assertThat(result.getExt().get("igs")).isNull(); - assertThat(debugMessages).isEmpty(); - } - - @Test - public void adjustShouldNotModifyImpExtIgsAeWhenImpExtIgsAePresent() { - // given - final ObjectNode ext = mapper.createObjectNode(); - ext.set("ae", IntNode.valueOf(0)); - ext.set("igs", mapper.createObjectNode().set("ae", IntNode.valueOf(123))); - - final Imp givenImp = Imp.builder().ext(ext).build(); - - final List debugMessages = new ArrayList<>(); - - // when - final Imp result = target.adjust(givenImp, "someBidder", debugMessages); - - // then - assertThat(result.getExt().get("igs").get("ae")).isEqualTo(IntNode.valueOf(123)); - assertThat(debugMessages).isEmpty(); - } - @Test public void adjustShouldRemoveExpImpFromOriginalImpWhenImpExtPrebidImpHasEmptyBidder() { // given diff --git a/src/test/java/org/prebid/server/bidder/HttpBidderRequesterTest.java b/src/test/java/org/prebid/server/bidder/HttpBidderRequesterTest.java index dab0028c791..6db68cc7575 100644 --- a/src/test/java/org/prebid/server/bidder/HttpBidderRequesterTest.java +++ b/src/test/java/org/prebid/server/bidder/HttpBidderRequesterTest.java @@ -30,7 +30,6 @@ import org.prebid.server.bidder.model.BidderCall; import org.prebid.server.bidder.model.BidderError; import org.prebid.server.bidder.model.BidderSeatBid; -import org.prebid.server.bidder.model.CompositeBidderResponse; import org.prebid.server.bidder.model.HttpRequest; import org.prebid.server.bidder.model.HttpResponse; import org.prebid.server.bidder.model.Result; @@ -38,9 +37,6 @@ import org.prebid.server.execution.timeout.TimeoutFactory; import org.prebid.server.model.CaseInsensitiveMultiMap; import org.prebid.server.proto.openrtb.ext.response.ExtHttpCall; -import org.prebid.server.proto.openrtb.ext.response.ExtIgi; -import org.prebid.server.proto.openrtb.ext.response.ExtIgiIgs; -import org.prebid.server.proto.openrtb.ext.response.FledgeAuctionConfig; import org.prebid.server.util.HttpUtil; import org.prebid.server.vertx.httpclient.HttpClient; import org.prebid.server.vertx.httpclient.model.HttpClientResponse; @@ -121,13 +117,12 @@ public void setUp() { target = new HttpBidderRequester( httpClient, null, bidderErrorNotifier, requestEnricher, jacksonMapper, 0.0); - given(bidder.makeBidderResponse(any(BidderCall.class), any(BidRequest.class))).willCallRealMethod(); } @Test public void shouldReturnFailedToRequestBidsErrorWhenBidderReturnsEmptyHttpRequestAndErrorLists() { // given - given(bidder.makeHttpRequests(any())).willReturn(Result.of(emptyList(), emptyList())); + given(bidder.makeHttpRequests(any())).willReturn(Result.empty()); final BidderRequest bidderRequest = BidderRequest.builder() .bidder("bidder") @@ -159,7 +154,7 @@ public void shouldReturnFailedToRequestBidsErrorWhenBidderReturnsEmptyHttpReques @Test public void shouldTolerateBidderReturningErrorsAndNoHttpRequests() { // given - given(bidder.makeHttpRequests(any())).willReturn(Result.of(emptyList(), + given(bidder.makeHttpRequests(any())).willReturn(Result.withErrors( asList(BidderError.badInput("error1"), BidderError.badInput("error2")))); final BidderRequest bidderRequest = BidderRequest.builder() @@ -194,12 +189,11 @@ public void shouldPassStoredResponseToBidderMakeBidsMethodAndReturnSeatBids() { final MultiMap headers = MultiMap.caseInsensitiveMultiMap(); headers.add("header1", "value1"); headers.add("header2", "value2"); - given(bidder.makeHttpRequests(any())).willReturn(Result.of(singletonList( - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder.uri("uri"))), - emptyList())); + given(bidder.makeHttpRequests(any())).willReturn(Result.withValue( + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder.uri("uri")))); final List bids = asList(BidderBid.of(null, null, null), BidderBid.of(null, null, null)); - given(bidder.makeBidderResponse(any(), any())).willReturn(CompositeBidderResponse.builder().bids(bids).build()); + given(bidder.makeBids(any(), any())).willReturn(Result.withValues(bids)); final BidderRequest bidderRequest = BidderRequest.builder() .bidder("bidder") @@ -223,7 +217,7 @@ public void shouldPassStoredResponseToBidderMakeBidsMethodAndReturnSeatBids() { verifyNoInteractions(httpClient); final ArgumentCaptor> httpCallArgumentCaptor = ArgumentCaptor.forClass(BidderCall.class); - verify(bidder).makeBidderResponse(httpCallArgumentCaptor.capture(), any()); + verify(bidder).makeBids(httpCallArgumentCaptor.capture(), any()); assertThat(httpCallArgumentCaptor.getValue().getResponse()) .extracting(HttpResponse::getBody) .isEqualTo("storedResponse"); @@ -240,14 +234,13 @@ public void shouldMakeRequestToBidderWhenStoredResponseDefinedButBidderCreatesMo final MultiMap headers = MultiMap.caseInsensitiveMultiMap(); headers.add("header1", "value1"); headers.add("header2", "value2"); - given(bidder.makeHttpRequests(any())).willReturn(Result.of(asList( - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .uri("uri") - .headers(headers)), - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .uri("uri") - .headers(headers))), - emptyList())); + given(bidder.makeHttpRequests(any())).willReturn(Result.withValues(asList( + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder + .uri("uri") + .headers(headers)), + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder + .uri("uri") + .headers(headers))))); final BidderRequest bidderRequest = BidderRequest.builder() .bidder("bidder") @@ -314,12 +307,9 @@ public void shouldSendMultipleRequests() throws JsonProcessingException { final BidRequest bidRequest = givenBidRequest(identity()); final byte[] body = mapper.writeValueAsBytes(bidRequest); - given(bidder.makeHttpRequests(any())).willReturn(Result.of(asList( - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .body(body)), - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .body(body))), - emptyList())); + given(bidder.makeHttpRequests(any())).willReturn(Result.withValues(asList( + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder.body(body)), + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder.body(body))))); final BidderRequest bidderRequest = BidderRequest.builder() .bidder("bidder") @@ -349,7 +339,7 @@ public void shouldReturnBidsCreatedByBidder() { givenSuccessfulBidderMakeHttpRequests(); final List bids = asList(BidderBid.of(null, null, null), BidderBid.of(null, null, null)); - given(bidder.makeBidderResponse(any(), any())).willReturn(CompositeBidderResponse.builder().bids(bids).build()); + given(bidder.makeBids(any(), any())).willReturn(Result.withValues(bids)); final BidderRequest bidderRequest = BidderRequest.builder() .bidder("bidder") @@ -382,95 +372,7 @@ public void shouldReturnBidsCreatedByMakeBids() { givenSuccessfulBidderMakeHttpRequests(); final List bids = emptyList(); - given(bidder.makeBidderResponse(any(), any())).willReturn(CompositeBidderResponse.builder().bids(bids).build()); - - final BidderRequest bidderRequest = BidderRequest.builder() - .bidder("bidder") - .bidRequest(BidRequest.builder().build()) - .build(); - - // when - final BidderSeatBid bidderSeatBid = - target - .requestBids( - bidder, - bidderRequest, - bidRejectionTracker, - timeout, - CaseInsensitiveMultiMap.empty(), - bidderAliases, - false) - .result(); - - // then - assertThat(bidderSeatBid.getBids()).hasSameElementsAs(bids); - - verify(bidRejectionTracker, never()).reject(any(Rejection.class)); - verify(bidRejectionTracker, never()).rejectImps(anyList(), any()); - } - - @Test - public void shouldReturnFledgeCreatedByBidder() { - // given - givenSuccessfulBidderMakeHttpRequests(); - - final List fledgeAuctionConfigs = List.of( - givenFledgeAuctionConfig("imp-1"), - givenFledgeAuctionConfig("imp-2")); - final List bids = emptyList(); - - given(bidder.makeBidderResponse(any(), any())).willReturn( - CompositeBidderResponse.builder() - .bids(bids) - .fledgeAuctionConfigs(fledgeAuctionConfigs) - .build()); - - final BidderRequest bidderRequest = BidderRequest.builder() - .bidder("bidder") - .bidRequest(BidRequest.builder().build()) - .build(); - - // when - final BidderSeatBid bidderSeatBid = - target - .requestBids( - bidder, - bidderRequest, - bidRejectionTracker, - timeout, - CaseInsensitiveMultiMap.empty(), - bidderAliases, - false) - .result(); - - // then - assertThat(bidderSeatBid.getBids()).hasSameElementsAs(bids); - assertThat(bidderSeatBid.getFledgeAuctionConfigs()).hasSameElementsAs(fledgeAuctionConfigs); - - verify(bidRejectionTracker, never()).reject(any(Rejection.class)); - verify(bidRejectionTracker, never()).rejectImps(anyList(), any()); - } - - @Test - public void shouldReturnExtIgiCreatedByBidder() { - // given - givenSuccessfulBidderMakeHttpRequests(); - - final List igi = List.of( - ExtIgi.builder() - .impid("impId") - .igs(singletonList(ExtIgiIgs.builder() - .config(mapper.createObjectNode()) - .build())) - .build()); - - final List bids = emptyList(); - - given(bidder.makeBidderResponse(any(), any())).willReturn( - CompositeBidderResponse.builder() - .bids(bids) - .igi(igi) - .build()); + given(bidder.makeBids(any(), any())).willReturn(Result.withValues(bids)); final BidderRequest bidderRequest = BidderRequest.builder() .bidder("bidder") @@ -492,7 +394,6 @@ public void shouldReturnExtIgiCreatedByBidder() { // then assertThat(bidderSeatBid.getBids()).hasSameElementsAs(bids); - assertThat(bidderSeatBid.getIgi()).containsExactlyElementsOf(igi); verify(bidRejectionTracker, never()).reject(any(Rejection.class)); verify(bidRejectionTracker, never()).rejectImps(anyList(), any()); @@ -503,9 +404,7 @@ public void shouldCompressRequestBodyIfContentEncodingHeaderIsGzip() { // given final MultiMap headers = MultiMap.caseInsensitiveMultiMap() .add(HttpUtil.CONTENT_ENCODING_HEADER, HttpHeaderValues.GZIP); - given(bidder.makeHttpRequests(any())).willReturn(Result.of( - singletonList(givenSimpleHttpRequest(identity())), - emptyList())); + given(bidder.makeHttpRequests(any())).willReturn(Result.withValue(givenSimpleHttpRequest(identity()))); given(requestEnricher.enrichHeaders(anyString(), any(), any(), any(), any())).willReturn(headers); givenHttpClientResponse(200, "responseBody"); @@ -575,20 +474,19 @@ public void processBids(List bids) { final BidRequest forthRequest = givenBidRequest(bidRequestBuilder -> bidRequestBuilder.id("r4")); final byte[] forthRequestBody = mapper.writeValueAsBytes(forthRequest); - given(bidder.makeHttpRequests(any())).willReturn(Result.of(Arrays.asList( - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .body(firstRequestBody) - .payload(bidRequestWithDeals("deal1"))), - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .body(secondRequestBody) - .payload(bidRequestWithDeals("deal1"))), - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .body(thirdRequestBody) - .payload(bidRequestWithDeals("deal2"))), - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .body(forthRequestBody) - .payload(bidRequestWithDeals("deal1")))), - emptyList())); + given(bidder.makeHttpRequests(any())).willReturn(Result.withValues(asList( + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder + .body(firstRequestBody) + .payload(bidRequestWithDeals("deal1"))), + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder + .body(secondRequestBody) + .payload(bidRequestWithDeals("deal1"))), + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder + .body(thirdRequestBody) + .payload(bidRequestWithDeals("deal2"))), + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder + .body(forthRequestBody) + .payload(bidRequestWithDeals("deal1")))))); final HttpClientResponse respWithDeal1 = HttpClientResponse.of(200, null, "{\"seatbid\":[{\"bid\":[{\"dealid\":\"deal1\"}]}]}"); @@ -606,9 +504,9 @@ public void processBids(List bids) { final BidderBid bidderBidDeal1 = BidderBid.of(Bid.builder().impid("deal1").dealid("deal1").build(), null, null); final BidderBid bidderBidDeal2 = BidderBid.of(Bid.builder().impid("deal2").dealid("deal2").build(), null, null); - given(bidder.makeBidderResponse(any(), any())).willReturn( - CompositeBidderResponse.builder().bids(singletonList(bidderBidDeal1)).build(), - CompositeBidderResponse.builder().bids(singletonList(bidderBidDeal2)).build()); + given(bidder.makeBids(any(), any())).willReturn( + Result.withValue(bidderBidDeal1), + Result.withValue(bidderBidDeal2)); // when final BidderSeatBid bidderSeatBid = target.requestBids( @@ -624,7 +522,7 @@ public void processBids(List bids) { // then verify(bidder).makeHttpRequests(any()); verify(httpClient, times(4)).request(any(), any(), any(), any(byte[].class), anyLong()); - verify(bidder, times(2)).makeBidderResponse(any(), any()); + verify(bidder, times(2)).makeBids(any(), any()); assertThat(bidderSeatBid.getBids()).containsOnly(bidderBidDeal1, bidderBidDeal2); @@ -641,22 +539,20 @@ public void shouldFinishWhenAllDealRequestsAreFinishedAndNoDealsProvided() { .bidRequest(bidRequest) .build(); - given(bidder.makeHttpRequests(any())).willReturn(Result.of(Arrays.asList( - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .payload(bidRequestWithDeals("deal1"))), - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .payload(bidRequestWithDeals("deal2"))), - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .payload(bidRequestWithDeals("deal2"))), - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .payload(bidRequestWithDeals("deal2")))), - emptyList())); + given(bidder.makeHttpRequests(any())).willReturn(Result.withValues(asList( + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder + .payload(bidRequestWithDeals("deal1"))), + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder + .payload(bidRequestWithDeals("deal2"))), + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder + .payload(bidRequestWithDeals("deal2"))), + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder + .payload(bidRequestWithDeals("deal2")))))); givenHttpClientResponse(200, "responseBody"); final BidderBid bidderBid = BidderBid.of(Bid.builder().dealid("deal2").build(), null, null); - given(bidder.makeBidderResponse(any(), any())).willReturn( - CompositeBidderResponse.builder().bids(singletonList(bidderBid)).build()); + given(bidder.makeBids(any(), any())).willReturn(Result.withValue(bidderBid)); // when final BidderSeatBid bidderSeatBid = @@ -673,7 +569,7 @@ public void shouldFinishWhenAllDealRequestsAreFinishedAndNoDealsProvided() { // then verify(bidder).makeHttpRequests(any()); verify(httpClient, times(4)).request(any(), any(), any(), any(byte[].class), anyLong()); - verify(bidder, times(4)).makeBidderResponse(any(), any()); + verify(bidder, times(4)).makeBids(any(), any()); assertThat(bidderSeatBid.getBids()).contains(bidderBid, bidderBid, bidderBid, bidderBid); @@ -689,18 +585,17 @@ public void shouldReturnFullDebugInfoIfDebugEnabled() throws JsonProcessingExcep final BidRequest secondBidRequest = givenBidRequest(bidRequestBuilder -> bidRequestBuilder.id("secondId")); final byte[] firstRequestBody = mapper.writeValueAsBytes(firstBidRequest); final byte[] secondRequestBody = mapper.writeValueAsBytes(secondBidRequest); - given(bidder.makeHttpRequests(any())).willReturn(Result.of(asList( - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .uri("uri1") - .body(firstRequestBody) - .payload(firstBidRequest) - .headers(headers)), - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .uri("uri2") - .body(secondRequestBody) - .payload(secondBidRequest) - .headers(headers))), - emptyList())); + given(bidder.makeHttpRequests(any())).willReturn(Result.withValues(asList( + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder + .uri("uri1") + .body(firstRequestBody) + .payload(firstBidRequest) + .headers(headers)), + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder + .uri("uri2") + .body(secondRequestBody) + .payload(secondBidRequest) + .headers(headers))))); given(requestEnricher.enrichHeaders(anyString(), any(), any(), any(), any())).willReturn(headers); @@ -708,7 +603,7 @@ public void shouldReturnFullDebugInfoIfDebugEnabled() throws JsonProcessingExcep HttpClientResponse.of(200, null, "responseBody1"), HttpClientResponse.of(200, null, "responseBody2")); - given(bidder.makeBidderResponse(any(), any())).willReturn(CompositeBidderResponse.empty()); + given(bidder.makeBids(any(), any())).willReturn(Result.empty()); final BidderRequest bidderRequest = BidderRequest.builder() .bidder("bidder") @@ -788,8 +683,7 @@ public void shouldReturnRecordBidRejections() throws JsonProcessingException { final List secondRequestBids = singletonList(BidderBid.builder() .bid(Bid.builder().impid("2").build()) .build()); - given(bidder.makeBidderResponse(any(), any())) - .willReturn(CompositeBidderResponse.builder().bids(secondRequestBids).build()); + given(bidder.makeBids(any(), any())).willReturn(Result.withValues(secondRequestBids)); final BidderRequest bidderRequest = BidderRequest.builder() .bidder("bidder") @@ -822,13 +716,12 @@ public void shouldNotReturnSensitiveHeadersInFullDebugInfo() headers.add("Authorization", "authorizationValue"); final BidRequest givenBidRequest = givenBidRequest(identity()); final byte[] requestBody = mapper.writeValueAsBytes(givenBidRequest); - given(bidder.makeHttpRequests(any())).willReturn(Result.of(singletonList( - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .uri("uri1") - .headers(headers) - .payload(givenBidRequest) - .body(requestBody))), - emptyList())); + given(bidder.makeHttpRequests(any())).willReturn(Result.withValue( + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder + .uri("uri1") + .headers(headers) + .payload(givenBidRequest) + .body(requestBody)))); given(requestEnricher.enrichHeaders(anyString(), any(), any(), any(), any())).willReturn(headers); @@ -865,15 +758,14 @@ public void shouldReturnPartialDebugInfoIfDebugEnabledAndGlobalTimeoutAlreadyExp final MultiMap headers = MultiMap.caseInsensitiveMultiMap().add("headerKey", "headerValue"); final BidRequest givenBidRequest = givenBidRequest(identity()); final byte[] requestBody = mapper.writeValueAsBytes(givenBidRequest); - given(bidder.makeHttpRequests(any())).willReturn(Result.of(singletonList( - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .uri("uri1") - .headers(headers) - .payload(givenBidRequest) - .body(requestBody) - .impIds(givenBidRequest.getImp().stream().map(Imp::getId) - .collect(Collectors.toSet())))), - emptyList())); + given(bidder.makeHttpRequests(any())).willReturn(Result.withValue( + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder + .uri("uri1") + .headers(headers) + .payload(givenBidRequest) + .body(requestBody) + .impIds(givenBidRequest.getImp().stream().map(Imp::getId) + .collect(Collectors.toSet()))))); given(requestEnricher.enrichHeaders(anyString(), any(), any(), any(), any())).willReturn(headers); @@ -911,14 +803,13 @@ public void shouldReturnPartialDebugInfoIfDebugEnabledAndHttpErrorOccurs() throw final MultiMap headers = MultiMap.caseInsensitiveMultiMap().add("headerKey", "headerValue"); final BidRequest givenBidRequest = givenBidRequest(identity()); final byte[] requestBody = mapper.writeValueAsBytes(givenBidRequest); - given(bidder.makeHttpRequests(any())).willReturn(Result.of(singletonList( - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .uri("uri1") - .headers(headers) - .payload(givenBidRequest) - .impIds(givenBidRequest.getImp().stream().map(Imp::getId).collect(Collectors.toSet())) - .body(requestBody))), - emptyList())); + given(bidder.makeHttpRequests(any())).willReturn(Result.withValue( + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder + .uri("uri1") + .headers(headers) + .payload(givenBidRequest) + .impIds(givenBidRequest.getImp().stream().map(Imp::getId).collect(Collectors.toSet())) + .body(requestBody)))); given(requestEnricher.enrichHeaders(anyString(), any(), any(), any(), any())).willReturn(headers); @@ -959,14 +850,13 @@ public void shouldReturnFullDebugInfoIfDebugEnabledAndErrorStatus() throws JsonP final MultiMap headers = MultiMap.caseInsensitiveMultiMap().add("headerKey", "headerValue"); final BidRequest givenBidRequest = givenBidRequest(identity()); final byte[] requestBody = mapper.writeValueAsBytes(givenBidRequest); - given(bidder.makeHttpRequests(any())).willReturn(Result.of(singletonList( - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .uri("uri1") - .headers(headers) - .payload(givenBidRequest) - .impIds(givenBidRequest.getImp().stream().map(Imp::getId).collect(Collectors.toSet())) - .body(requestBody))), - emptyList())); + given(bidder.makeHttpRequests(any())).willReturn(Result.withValue( + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder + .uri("uri1") + .headers(headers) + .payload(givenBidRequest) + .impIds(givenBidRequest.getImp().stream().map(Imp::getId).collect(Collectors.toSet())) + .body(requestBody)))); given(requestEnricher.enrichHeaders(anyString(), any(), any(), any(), any())).willReturn(headers); @@ -1012,14 +902,13 @@ public void shouldReturnFullDebugInfoIfDebugEnabledAndBidderIsUnreachable() thro final MultiMap headers = MultiMap.caseInsensitiveMultiMap().add("headerKey", "headerValue"); final BidRequest givenBidRequest = givenBidRequest(identity()); final byte[] requestBody = mapper.writeValueAsBytes(givenBidRequest); - given(bidder.makeHttpRequests(any())).willReturn(Result.of(singletonList( - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .uri("uri1") - .headers(headers) - .payload(givenBidRequest) - .impIds(givenBidRequest.getImp().stream().map(Imp::getId).collect(Collectors.toSet())) - .body(requestBody))), - emptyList())); + given(bidder.makeHttpRequests(any())).willReturn(Result.withValue( + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder + .uri("uri1") + .headers(headers) + .payload(givenBidRequest) + .impIds(givenBidRequest.getImp().stream().map(Imp::getId).collect(Collectors.toSet())) + .body(requestBody)))); given(requestEnricher.enrichHeaders(anyString(), any(), any(), any(), any())).willReturn(headers); @@ -1064,13 +953,12 @@ public void shouldTolerateAlreadyExpiredGlobalTimeout() throws JsonProcessingExc // given final BidRequest givenBidRequest = givenBidRequest(identity()); final byte[] requestBody = mapper.writeValueAsBytes(givenBidRequest); - given(bidder.makeHttpRequests(any())).willReturn(Result.of(singletonList( - givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder - .uri("uri1") - .payload(givenBidRequest) - .impIds(givenBidRequest.getImp().stream().map(Imp::getId).collect(Collectors.toSet())) - .body(requestBody))), - emptyList())); + given(bidder.makeHttpRequests(any())).willReturn(Result.withValue( + givenSimpleHttpRequest(httpRequestBuilder -> httpRequestBuilder + .uri("uri1") + .payload(givenBidRequest) + .impIds(givenBidRequest.getImp().stream().map(Imp::getId).collect(Collectors.toSet())) + .body(requestBody)))); final BidderRequest bidderRequest = BidderRequest.builder() .bidder("bidder") .bidRequest(BidRequest.builder().build()) @@ -1164,11 +1052,9 @@ public void shouldTolerateMultipleErrors() { // simulate 200 status .willReturn(Future.succeededFuture(HttpClientResponse.of(200, null, EMPTY))); - given(bidder.makeBidderResponse(any(), any())).willReturn( - CompositeBidderResponse.builder() - .bids(singletonList(BidderBid.of(Bid.builder().impid("123").build(), null, null))) - .errors(singletonList(BidderError.badServerResponse("makeBidsError"))) - .build()); + given(bidder.makeBids(any(), any())).willReturn(Result.of( + singletonList(BidderBid.of(Bid.builder().impid("123").build(), null, null)), + singletonList(BidderError.badServerResponse("makeBidsError")))); final BidderRequest bidderRequest = BidderRequest.builder() .bidder("bidder") @@ -1189,7 +1075,7 @@ public void shouldTolerateMultipleErrors() { // then // only one calls is expected (200) since other requests have failed with errors. - verify(bidder).makeBidderResponse(any(), any()); + verify(bidder).makeBids(any(), any()); assertThat(bidderSeatBid.getBids()).hasSize(1); assertThat(bidderSeatBid.getErrors()).containsOnly( BidderError.badInput("makeHttpRequestsError"), @@ -1236,7 +1122,7 @@ public void shouldNotMakeBidsIfResponseStatusIs204() { false); // then - verify(bidder, never()).makeBidderResponse(any(), any()); + verify(bidder, never()).makeBids(any(), any()); verify(bidder, never()).makeBids(any(), any()); verify(bidRejectionTracker, never()).reject(any(Rejection.class)); @@ -1269,13 +1155,6 @@ private static Imp impWithDeal(String dealId) { .build(); } - private static FledgeAuctionConfig givenFledgeAuctionConfig(String impId) { - return FledgeAuctionConfig.builder() - .impId(impId) - .config(mapper.createObjectNode().put("references", impId)) - .build(); - } - private static HttpRequest givenSimpleHttpRequest( UnaryOperator> customizer) { return customizer.apply(HttpRequest.builder() diff --git a/src/test/java/org/prebid/server/bidder/consumable/ConsumableBidderTest.java b/src/test/java/org/prebid/server/bidder/consumable/ConsumableBidderTest.java index 8c92e56e047..3c193cb2f1b 100644 --- a/src/test/java/org/prebid/server/bidder/consumable/ConsumableBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/consumable/ConsumableBidderTest.java @@ -16,13 +16,11 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.prebid.server.VertxTest; import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.bidder.model.BidderCall; import org.prebid.server.bidder.model.BidderError; -import org.prebid.server.bidder.model.CompositeBidderResponse; import org.prebid.server.bidder.model.HttpRequest; import org.prebid.server.bidder.model.HttpResponse; import org.prebid.server.bidder.model.Result; @@ -32,7 +30,6 @@ import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebid; import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidVideo; import org.prebid.server.util.HttpUtil; -import org.prebid.server.version.PrebidVersionProvider; import java.util.List; import java.util.Map; @@ -49,9 +46,6 @@ public class ConsumableBidderTest extends VertxTest { private static final String ENDPOINT_URL = "http://exchange.org"; - @Mock - private PrebidVersionProvider prebidVersionProvider; - private ConsumableBidder target; @BeforeEach @@ -111,18 +105,18 @@ public void makeHttpRequestsShouldHaveCorrectURIForAppRequest() { } @Test - public void makeBidderResponseShouldReturnBidderBidWithNoErrors() throws JsonProcessingException { + public void makeBidsShouldReturnBidderBidWithNoErrors() throws JsonProcessingException { // given final BidRequest bidRequest = givenSiteBidRequest(identity()); final BidderCall httpCall = givenHttpCall(bidRequest, givenBidResponse(bidBuilder -> bidBuilder.impid("123"))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).isNotEmpty(); + assertThat(result.getValue()).isNotEmpty(); } @Test @@ -169,51 +163,51 @@ public void makeHttpRequestsShouldReturnEmptyListIfRequiredAppParametersAreNotPr } @Test - public void makeBidderResponseShouldReturnErrorIfResponseBodyCouldNotBeParsed() { + public void makeBidsShouldReturnErrorIfResponseBodyCouldNotBeParsed() { // given final BidderCall httpCall = givenHttpCall(null, "invalid"); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).hasSize(1).first().satisfies(error -> { assertThat(error.getMessage()).startsWith("Failed to decode: Unrecognized token"); assertThat(error.getType()).isEqualTo(BidderError.Type.bad_server_response); }); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldReturnEmptyListIfBidResponseIsNull() throws JsonProcessingException { + public void makeBidsShouldReturnEmptyListIfBidResponseIsNull() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall(null, mapper.writeValueAsString(null)); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldReturnEmptyListIfBidResponseSeatBidIsNull() throws JsonProcessingException { + public void makeBidsShouldReturnEmptyListIfBidResponseSeatBidIsNull() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall(null, mapper.writeValueAsString(BidResponse.builder().build())); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldReturnBannerBidIfBannerIsPresent() throws JsonProcessingException { + public void makeBidsShouldReturnBannerBidIfBannerIsPresent() throws JsonProcessingException { // given final BidRequest bidRequest = BidRequest.builder() .imp(singletonList(Imp.builder().id("123").banner(Banner.builder().build()).build())) @@ -223,17 +217,17 @@ public void makeBidderResponseShouldReturnBannerBidIfBannerIsPresent() throws Js givenBidResponse(bidBuilder -> bidBuilder.impid("123"))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getType) .containsExactly(BidType.banner); } @Test - public void makeBidderResponseShouldReturnAudioBidIfAudioIsPresent() throws JsonProcessingException { + public void makeBidsShouldReturnAudioBidIfAudioIsPresent() throws JsonProcessingException { // given final BidRequest bidRequest = BidRequest.builder() .imp(singletonList(Imp.builder().id("123").audio(Audio.builder().build()).build())) @@ -243,17 +237,17 @@ public void makeBidderResponseShouldReturnAudioBidIfAudioIsPresent() throws Json givenBidResponse(bidBuilder -> bidBuilder.impid("123"))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getType) .containsExactly(BidType.audio); } @Test - public void makeBidderResponseShouldReturnErrorIfImpNotMatched() throws JsonProcessingException { + public void makeBidsShouldReturnErrorIfImpNotMatched() throws JsonProcessingException { // given final BidRequest bidRequest = BidRequest.builder() .imp(singletonList(Imp.builder().id("123").build())) @@ -263,15 +257,15 @@ public void makeBidderResponseShouldReturnErrorIfImpNotMatched() throws JsonProc givenBidResponse(bidBuilder -> bidBuilder.impid("489"))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); assertThat(result.getErrors()).containsExactly(BidderError.badServerResponse("Unmatched impression id 489")); } @Test - public void makeBidderResponseShouldReturnBidWithVideoExt() throws JsonProcessingException { + public void makeBidsShouldReturnBidWithVideoExt() throws JsonProcessingException { // given final Video video = Video.builder().build(); final BidRequest bidRequest = BidRequest.builder() @@ -286,18 +280,18 @@ public void makeBidderResponseShouldReturnBidWithVideoExt() throws JsonProcessin .mtype(2))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getVideoInfo) .extracting(ExtBidPrebidVideo::getDuration) .containsExactly(1); } @Test - public void makeBidderResponseShouldReturnBannerBidIfMTypeIsOne() throws JsonProcessingException { + public void makeBidsShouldReturnBannerBidIfMTypeIsOne() throws JsonProcessingException { // given final Banner banner = Banner.builder().w(300).h(200).build(); final Video video = Video.builder().build(); @@ -315,17 +309,17 @@ public void makeBidderResponseShouldReturnBannerBidIfMTypeIsOne() throws JsonPro .mtype(1))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getType) .containsExactly(BidType.banner); } @Test - public void makeBidderResponseShouldReturnVideoBidIfMTypeIsTwo() throws JsonProcessingException { + public void makeBidsShouldReturnVideoBidIfMTypeIsTwo() throws JsonProcessingException { // given final Banner banner = Banner.builder().w(300).h(200).build(); final Video video = Video.builder().build(); @@ -343,17 +337,17 @@ public void makeBidderResponseShouldReturnVideoBidIfMTypeIsTwo() throws JsonProc .mtype(2))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getType) .containsExactly(BidType.video); } @Test - public void makeBidderResponseShouldReturnAudioBidIfMTypeIsThree() throws JsonProcessingException { + public void makeBidsShouldReturnAudioBidIfMTypeIsThree() throws JsonProcessingException { // given final Banner banner = Banner.builder().w(300).h(200).build(); final Video video = Video.builder().build(); @@ -371,17 +365,17 @@ public void makeBidderResponseShouldReturnAudioBidIfMTypeIsThree() throws JsonPr .mtype(3))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getType) .containsExactly(BidType.audio); } @Test - public void makeBidderResponseShouldReturnCorrectTypeExtPrebidTypeInResponse() throws JsonProcessingException { + public void makeBidsShouldReturnCorrectTypeExtPrebidTypeInResponse() throws JsonProcessingException { // given final Banner banner = Banner.builder().w(300).h(200).build(); final Video video = Video.builder().build(); @@ -400,11 +394,11 @@ public void makeBidderResponseShouldReturnCorrectTypeExtPrebidTypeInResponse() t .set("prebid", mapper.createObjectNode().put("type", "video"))))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getType) .containsExactly(BidType.video); } diff --git a/src/test/java/org/prebid/server/bidder/criteo/CriteoBidderTest.java b/src/test/java/org/prebid/server/bidder/criteo/CriteoBidderTest.java index ead9604e70b..05b877c5797 100644 --- a/src/test/java/org/prebid/server/bidder/criteo/CriteoBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/criteo/CriteoBidderTest.java @@ -15,13 +15,10 @@ import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.bidder.model.BidderCall; import org.prebid.server.bidder.model.BidderError; -import org.prebid.server.bidder.model.CompositeBidderResponse; import org.prebid.server.bidder.model.HttpRequest; import org.prebid.server.bidder.model.HttpResponse; import org.prebid.server.bidder.model.Result; import org.prebid.server.proto.openrtb.ext.response.BidType; -import org.prebid.server.proto.openrtb.ext.response.ExtIgi; -import org.prebid.server.proto.openrtb.ext.response.ExtIgiIgs; import java.util.List; import java.util.Set; @@ -79,12 +76,12 @@ public void makeHttpRequestsShouldEncodePassedBidRequest() { } @Test - public void makeBidderResponseShouldReturnErrorIfResponseBodyCouldNotBeParsed() { + public void makeBidsShouldReturnErrorIfResponseBodyCouldNotBeParsed() { // given final BidderCall httpCall = givenHttpCall("invalid"); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).hasSize(1) @@ -92,114 +89,114 @@ public void makeBidderResponseShouldReturnErrorIfResponseBodyCouldNotBeParsed() assertThat(error.getType()).isEqualTo(BidderError.Type.bad_server_response); assertThat(error.getMessage()).startsWith("Failed to decode: Unrecognized token"); }); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldReturnEmptyListIfBidResponseIsNull() throws JsonProcessingException { + public void makeBidsShouldReturnEmptyListIfBidResponseIsNull() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall(mapper.writeValueAsString(null)); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldReturnEmptyListIfBidResponseSeatBidIsNull() throws JsonProcessingException { + public void makeBidsShouldReturnEmptyListIfBidResponseSeatBidIsNull() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall(mapper.writeValueAsString(BidResponse.builder().build())); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldReturnEmptyListIfBidResponseSeatBidIsEmpty() throws JsonProcessingException { + public void makeBidsShouldReturnEmptyListIfBidResponseSeatBidIsEmpty() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( mapper.writeValueAsString(BidResponse.builder().seatbid(emptyList()).build())); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldReturnErrorWhenBidExtPrebidTypeIsNotPresent() throws JsonProcessingException { + public void makeBidsShouldReturnErrorWhenBidExtPrebidTypeIsNotPresent() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( givenBidResponse(bid -> bid.impid("123"))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()) .containsExactly(BidderError.badServerResponse("Missing ext.prebid.type in bid for impression : 123.")); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldReturnBannerBid() throws JsonProcessingException { + public void makeBidsShouldReturnBannerBid() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( givenBidResponse(bid -> bid.ext(givenBidExt(BidType.banner)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getType) .containsExactly(BidType.banner); } @Test - public void makeBidderResponseShouldReturnVideoBid() throws JsonProcessingException { + public void makeBidsShouldReturnVideoBid() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( givenBidResponse(bid -> bid.ext(givenBidExt(BidType.video)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getType) .containsExactly(BidType.video); } @Test - public void makeBidderResponseShouldReturnBidWithCurFromResponse() throws JsonProcessingException { + public void makeBidsShouldReturnBidWithCurFromResponse() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( givenBidResponse(bid -> bid.ext(givenBidExt(BidType.banner)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getBidCurrency) .containsExactly("CUR"); } @Test - public void makeBidderResponseShouldReturnBidWithNetworkNameFromExtPrebid() throws JsonProcessingException { + public void makeBidsShouldReturnBidWithNetworkNameFromExtPrebid() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( givenBidResponse(bid -> bid @@ -207,11 +204,11 @@ public void makeBidderResponseShouldReturnBidWithNetworkNameFromExtPrebid() thro .ext(givenBidExtWithNetwork("anyNetworkName")))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getBid) .extracting(Bid::getExt) .extracting(ext -> ext.get("meta")) @@ -219,64 +216,24 @@ public void makeBidderResponseShouldReturnBidWithNetworkNameFromExtPrebid() thro } @Test - public void makeBidderResponseShouldReturnEmptyNetworkNameWhenBidExtPrebidNotContainNetworkName() + public void makeBidsShouldReturnEmptyNetworkNameWhenBidExtPrebidNotContainNetworkName() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( givenBidResponse(bid -> bid.ext(givenBidExtWithNetwork(null)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getBid) .extracting(Bid::getExt) .extracting(ext -> ext.get("meta")) .doesNotContain(mapper.createObjectNode().put("networkName", "anyNetworkName")); } - @Test - public void makeBidderResponseShouldReturnFledgeConfigs() throws JsonProcessingException { - // given - final List igs = List.of( - ExtIgiIgs.builder().config(mapper.createObjectNode().put("proterty1", "value1")).build(), - ExtIgiIgs.builder().config(mapper.createObjectNode().put("proterty2", "value2")).build()); - - final CriteoBidResponse bidResponseWithFledge = CriteoBidResponse.builder() - .ext(CriteoExtBidResponse.of(List.of( - ExtIgi.builder() - .impid("imp_id1") - .igs(igs) - .build()))) - .build(); - final BidderCall httpCall = givenHttpCall(mapper.writeValueAsString(bidResponseWithFledge)); - - // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); - - // then - final List expectedIgs = List.of( - ExtIgiIgs.builder().config(mapper.createObjectNode().put("proterty1", "value1")).build(), - ExtIgiIgs.builder().config(mapper.createObjectNode().put("proterty2", "value2")).build()); - - assertThat(result.getErrors()).isEmpty(); - assertThat(result.getIgi()).containsExactly(ExtIgi.builder().impid("imp_id1").igs(expectedIgs).build()); - } - - @Test - public void makeBidsShouldFail() throws JsonProcessingException { - //given - final BidderCall httpCall = givenHttpCall(mapper.writeValueAsString(BidResponse.builder().build())); - - // when - final Result> result = target.makeBids(httpCall, null); - - // then - assertThat(result.getErrors()).containsExactly(BidderError.generic("Deprecated adapter method invoked")); - } - private static String givenBidResponse(UnaryOperator bidCustomizer) throws JsonProcessingException { diff --git a/src/test/java/org/prebid/server/bidder/epsilon/EpsilonBidderTest.java b/src/test/java/org/prebid/server/bidder/epsilon/EpsilonBidderTest.java index eeb1a1ce621..ca3f2dfc300 100644 --- a/src/test/java/org/prebid/server/bidder/epsilon/EpsilonBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/epsilon/EpsilonBidderTest.java @@ -22,7 +22,6 @@ import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.bidder.model.BidderCall; import org.prebid.server.bidder.model.BidderError; -import org.prebid.server.bidder.model.CompositeBidderResponse; import org.prebid.server.bidder.model.HttpRequest; import org.prebid.server.bidder.model.HttpResponse; import org.prebid.server.bidder.model.Result; @@ -795,25 +794,25 @@ public void makeBidsShouldReturnResultForNativeBidsWithExpectedFields() throws J final BidderCall httpCall = givenHttpCall(bidRequest, mapper.writeValueAsString(BidResponse.builder() - .seatbid(singletonList(SeatBid.builder() - .bid(singletonList(Bid.builder() - .price(BigDecimal.ONE) - .impid("impid-0") - .adm(nativeResponseString) - .mtype(4) - .cat(singletonList("IAB3")) + .seatbid(singletonList(SeatBid.builder() + .bid(singletonList(Bid.builder() + .price(BigDecimal.ONE) + .impid("impid-0") + .adm(nativeResponseString) + .mtype(4) + .cat(singletonList("IAB3")) + .build())) .build())) - .build())) - .cur("USD") - .ext(ExtBidResponse.builder().build()) - .build())); + .cur("USD") + .ext(ExtBidResponse.builder().build()) + .build())); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).hasSize(1) + assertThat(result.getValue()).hasSize(1) .containsOnly(BidderBid.of( Bid.builder() .impid("impid-0") diff --git a/src/test/java/org/prebid/server/bidder/ix/IxBidderTest.java b/src/test/java/org/prebid/server/bidder/ix/IxBidderTest.java index f1138e83133..b152785844e 100644 --- a/src/test/java/org/prebid/server/bidder/ix/IxBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/ix/IxBidderTest.java @@ -26,14 +26,10 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.prebid.server.VertxTest; -import org.prebid.server.bidder.ix.model.response.AuctionConfigExtBidResponse; -import org.prebid.server.bidder.ix.model.response.IxBidResponse; -import org.prebid.server.bidder.ix.model.response.IxExtBidResponse; import org.prebid.server.bidder.ix.model.response.NativeV11Wrapper; import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.bidder.model.BidderCall; import org.prebid.server.bidder.model.BidderError; -import org.prebid.server.bidder.model.CompositeBidderResponse; import org.prebid.server.bidder.model.HttpRequest; import org.prebid.server.bidder.model.HttpResponse; import org.prebid.server.bidder.model.Result; @@ -45,8 +41,6 @@ import org.prebid.server.proto.openrtb.ext.response.BidType; import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebid; import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidVideo; -import org.prebid.server.proto.openrtb.ext.response.ExtIgi; -import org.prebid.server.proto.openrtb.ext.response.ExtIgiIgs; import org.prebid.server.version.PrebidVersionProvider; import java.util.List; @@ -62,7 +56,6 @@ import static org.assertj.core.api.Assertions.tuple; import static org.mockito.BDDMockito.given; import static org.mockito.Mock.Strictness.LENIENT; -import static org.prebid.server.proto.openrtb.ext.response.BidType.banner; @ExtendWith(MockitoExtension.class) public class IxBidderTest extends VertxTest { @@ -382,50 +375,50 @@ public void makeHttpRequestsShouldNotCreateRequestAppWhenImpExtSiteIdPresentAndS } @Test - public void makeBidderResponseShouldReturnErrorIfResponseBodyCouldNotBeParsed() { + public void makeBidsShouldReturnErrorIfResponseBodyCouldNotBeParsed() { // given final BidderCall httpCall = givenHttpCall(null, "invalid"); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).hasSize(1); assertThat(result.getErrors().getFirst().getMessage()).startsWith("Failed to decode: Unrecognized token"); assertThat(result.getErrors().getFirst().getType()).isEqualTo(BidderError.Type.bad_server_response); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldReturnEmptyListIfBidResponseIsNull() throws JsonProcessingException { + public void makeBidsShouldReturnEmptyListIfBidResponseIsNull() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall(null, mapper.writeValueAsString(null)); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldReturnEmptyListIfBidResponseSeatBidIsNull() throws JsonProcessingException { + public void makeBidsShouldReturnEmptyListIfBidResponseSeatBidIsNull() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall(null, mapper.writeValueAsString(BidResponse.builder().build())); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldReturnBannerBidIfBannerIsPresent() throws JsonProcessingException { + public void makeBidsShouldReturnBannerBidIfBannerIsPresent() throws JsonProcessingException { // given final BidRequest bidRequest = BidRequest.builder() .imp(singletonList(Imp.builder().id("123").banner(Banner.builder().build()).build())) @@ -436,16 +429,16 @@ public void makeBidderResponseShouldReturnBannerBidIfBannerIsPresent() throws Js givenBidResponse(bidBuilder -> bidBuilder.impid("123")))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .containsOnly(BidderBid.of(Bid.builder().impid("123").build(), BidType.banner, "EUR")); } @Test - public void makeBidderResponseShouldReturnNativeBidIfNativeIsPresent() throws JsonProcessingException { + public void makeBidsShouldReturnNativeBidIfNativeIsPresent() throws JsonProcessingException { // given final BidRequest bidRequest = BidRequest.builder() .imp(singletonList(Imp.builder().id("123").xNative(Native.builder().build()).build())) @@ -456,16 +449,16 @@ public void makeBidderResponseShouldReturnNativeBidIfNativeIsPresent() throws Js givenBidResponse(bidBuilder -> bidBuilder.impid("123")))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .containsOnly(BidderBid.of(Bid.builder().impid("123").build(), BidType.xNative, "EUR")); } @Test - public void makeBidderResponseShouldReturnAudioBidIfAudioIsPresent() throws JsonProcessingException { + public void makeBidsShouldReturnAudioBidIfAudioIsPresent() throws JsonProcessingException { // given final BidRequest bidRequest = BidRequest.builder() .imp(singletonList(Imp.builder().id("123").audio(Audio.builder().build()).build())) @@ -476,16 +469,16 @@ public void makeBidderResponseShouldReturnAudioBidIfAudioIsPresent() throws Json givenBidResponse(bidBuilder -> bidBuilder.impid("123")))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .containsOnly(BidderBid.of(Bid.builder().impid("123").build(), BidType.audio, "EUR")); } @Test - public void makeBidderResponseShouldReturnErrorIfImpNotMatched() throws JsonProcessingException { + public void makeBidsShouldReturnErrorIfImpNotMatched() throws JsonProcessingException { // given final BidRequest bidRequest = BidRequest.builder() .imp(singletonList(Imp.builder().id("123").build())) @@ -496,15 +489,15 @@ public void makeBidderResponseShouldReturnErrorIfImpNotMatched() throws JsonProc givenBidResponse(bidBuilder -> bidBuilder.impid("489")))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); assertThat(result.getErrors()).containsExactly(BidderError.badServerResponse("Unmatched impression id 489")); } @Test - public void makeBidderResponseShouldReturnBidWithVideoInfo() throws JsonProcessingException { + public void makeBidsShouldReturnBidWithVideoInfo() throws JsonProcessingException { // given final Video video = Video.builder().build(); final BidRequest bidRequest = BidRequest.builder() @@ -521,18 +514,18 @@ public void makeBidderResponseShouldReturnBidWithVideoInfo() throws JsonProcessi .build()))))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getVideoInfo) .extracting(ExtBidPrebidVideo::getDuration, ExtBidPrebidVideo::getPrimaryCategory) .containsExactly(tuple(1, null)); } @Test - public void makeBidderResponseShouldReturnAdmContainingImageTrackersUrls() throws JsonProcessingException { + public void makeBidsShouldReturnAdmContainingImageTrackersUrls() throws JsonProcessingException { // given final String adm = mapper.writeValueAsString( Response.builder() @@ -553,7 +546,7 @@ public void makeBidderResponseShouldReturnAdmContainingImageTrackersUrls() throw .adm(adm)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then final Response expectedNativeResponse = Response.builder() @@ -565,14 +558,14 @@ public void makeBidderResponseShouldReturnAdmContainingImageTrackersUrls() throw .build(); assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getBid) .extracting(Bid::getAdm) .containsExactly(mapper.writeValueAsString(expectedNativeResponse)); } @Test - public void makeBidderResponseShouldReturnAdmContainingImpTrackersAndEventImpTrackersUrls() + public void makeBidsShouldReturnAdmContainingImpTrackersAndEventImpTrackersUrls() throws JsonProcessingException { // given final String adm = mapper.writeValueAsString( @@ -594,7 +587,7 @@ public void makeBidderResponseShouldReturnAdmContainingImpTrackersAndEventImpTra .adm(adm)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then final Response expectedNativeResponse = Response.builder() @@ -606,14 +599,14 @@ public void makeBidderResponseShouldReturnAdmContainingImpTrackersAndEventImpTra .build(); assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getBid) .extracting(Bid::getAdm) .containsExactly(mapper.writeValueAsString(expectedNativeResponse)); } @Test - public void makeBidderResponseShouldReturnAdmContainingEventImpTrackersUrlsWhenImpTrackersAreNull() + public void makeBidsShouldReturnAdmContainingEventImpTrackersUrlsWhenImpTrackersAreNull() throws JsonProcessingException { // given final String adm = mapper.writeValueAsString( @@ -634,11 +627,11 @@ public void makeBidderResponseShouldReturnAdmContainingEventImpTrackersUrlsWhenI .adm(adm)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then final Response expectedNativeResponse = Response.builder() - .imptrackers(asList("eventUrl")) + .imptrackers(singletonList("eventUrl")) .eventtrackers(singletonList(EventTracker.builder() .event(EventType.IMPRESSION.getValue()) .url("eventUrl") @@ -646,14 +639,14 @@ public void makeBidderResponseShouldReturnAdmContainingEventImpTrackersUrlsWhenI .build(); assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getBid) .extracting(Bid::getAdm) .containsExactly(mapper.writeValueAsString(expectedNativeResponse)); } @Test - public void makeBidderResponseShouldReturnAdmWithoutImpTrackers() + public void makeBidsShouldReturnAdmWithoutImpTrackers() throws JsonProcessingException { // given final String adm = mapper.writeValueAsString( @@ -674,7 +667,7 @@ public void makeBidderResponseShouldReturnAdmWithoutImpTrackers() .adm(adm)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then final Response expectedNativeResponse = Response.builder() @@ -686,14 +679,14 @@ public void makeBidderResponseShouldReturnAdmWithoutImpTrackers() .build(); assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getBid) .extracting(Bid::getAdm) .containsExactly(mapper.writeValueAsString(expectedNativeResponse)); } @Test - public void makeBidderResponseShouldReturnAdmContainingOnlyUniqueImpTrackersUrls() throws JsonProcessingException { + public void makeBidsShouldReturnAdmContainingOnlyUniqueImpTrackersUrls() throws JsonProcessingException { // given final String adm = mapper.writeValueAsString( Response.builder() @@ -718,11 +711,11 @@ public void makeBidderResponseShouldReturnAdmContainingOnlyUniqueImpTrackersUrls .adm(adm)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getBid) .extracting(Bid::getAdm) .extracting(bidAdm -> mapper.readValue(bidAdm, Response.class)) @@ -731,7 +724,7 @@ public void makeBidderResponseShouldReturnAdmContainingOnlyUniqueImpTrackersUrls } @Test - public void makeBidderResponseShouldReturnValidAdmIfNativeIsPresentInImpAndAdm12() throws JsonProcessingException { + public void makeBidsShouldReturnValidAdmIfNativeIsPresentInImpAndAdm12() throws JsonProcessingException { // given final String adm = mapper.writeValueAsString(NativeV11Wrapper.of( Response.builder() @@ -753,7 +746,7 @@ public void makeBidderResponseShouldReturnValidAdmIfNativeIsPresentInImpAndAdm12 .adm(adm)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then final NativeV11Wrapper expectedNativeResponse = NativeV11Wrapper.of(Response.builder() @@ -766,14 +759,14 @@ public void makeBidderResponseShouldReturnValidAdmIfNativeIsPresentInImpAndAdm12 .build()); assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getBid) .extracting(Bid::getAdm) .containsExactly(mapper.writeValueAsString(expectedNativeResponse)); } @Test - public void makeBidderResponseShouldReturnBannerBidIfMTypeIsOne() throws JsonProcessingException { + public void makeBidsShouldReturnBannerBidIfMTypeIsOne() throws JsonProcessingException { // given final Banner banner = Banner.builder().w(300).h(200).build(); final Video video = Video.builder().build(); @@ -792,17 +785,17 @@ public void makeBidderResponseShouldReturnBannerBidIfMTypeIsOne() throws JsonPro .mtype(1)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getType) .containsExactly(BidType.banner); } @Test - public void makeBidderResponseShouldReturnVideoBidIfMTypeIsTwo() throws JsonProcessingException { + public void makeBidsShouldReturnVideoBidIfMTypeIsTwo() throws JsonProcessingException { // given final Banner banner = Banner.builder().w(300).h(200).build(); final Video video = Video.builder().build(); @@ -822,17 +815,17 @@ public void makeBidderResponseShouldReturnVideoBidIfMTypeIsTwo() throws JsonProc .mtype(2)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getType) .containsExactly(BidType.video); } @Test - public void makeBidderResponseShouldReturnAudioBidIfMTypeIsThree() throws JsonProcessingException { + public void makeBidsShouldReturnAudioBidIfMTypeIsThree() throws JsonProcessingException { // given final Banner banner = Banner.builder().w(300).h(200).build(); final Video video = Video.builder().build(); @@ -851,17 +844,17 @@ public void makeBidderResponseShouldReturnAudioBidIfMTypeIsThree() throws JsonPr .mtype(3)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getType) .containsExactly(BidType.audio); } @Test - public void makeBidderResponseShouldReturnNativeBidIfMTypeIsFour() throws JsonProcessingException { + public void makeBidsShouldReturnNativeBidIfMTypeIsFour() throws JsonProcessingException { // given final Banner banner = Banner.builder().w(300).h(200).build(); final Video video = Video.builder().build(); @@ -880,17 +873,17 @@ public void makeBidderResponseShouldReturnNativeBidIfMTypeIsFour() throws JsonPr .mtype(4)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getType) .containsExactly(BidType.xNative); } @Test - public void makeBidderResponseShouldReturnCorrectTypeExtPrebidTypeInResponse() throws JsonProcessingException { + public void makeBidsShouldReturnCorrectTypeExtPrebidTypeInResponse() throws JsonProcessingException { // given final Banner banner = Banner.builder().w(300).h(200).build(); final Video video = Video.builder().build(); @@ -910,47 +903,15 @@ public void makeBidderResponseShouldReturnCorrectTypeExtPrebidTypeInResponse() t .set("prebid", mapper.createObjectNode().put("type", "video")))))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getType) .containsExactly(BidType.video); } - @Test - public void makeBidderResponseShouldReturnFledgeAuctionConfig() throws JsonProcessingException { - // given - final String impId = "imp_id"; - final BidResponse bidResponse = givenBidResponse(bidBuilder -> bidBuilder.impid(impId).mtype(1)); - final ObjectNode auctionConfig = mapper.createObjectNode(); - final BidRequest bidRequest = BidRequest.builder() - .imp(List.of(Imp.builder().id(impId).build())) - .build(); - final IxBidResponse bidResponseWithFledge = IxBidResponse.builder() - .cur(bidResponse.getCur()) - .seatbid(bidResponse.getSeatbid()) - .ext(IxExtBidResponse.of(List.of(AuctionConfigExtBidResponse.of(impId, auctionConfig)))) - .build(); - final BidderCall httpCall = - givenHttpCall(bidRequest, mapper.writeValueAsString(bidResponseWithFledge)); - - // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); - - // then - final ExtIgiIgs igs = ExtIgiIgs.builder() - .impId(impId) - .config(auctionConfig) - .build(); - - assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) - .containsOnly(BidderBid.of(Bid.builder().impid(impId).mtype(1).build(), banner, bidResponse.getCur())); - assertThat(result.getIgi()).containsExactly(ExtIgi.builder().igs(singletonList(igs)).build()); - } - private static ExtRequest givenExtRequest(String pbjsv) { return ExtRequest.of(ExtRequestPrebid.builder() .channel(ExtRequestPrebidChannel.of("pbjs", pbjsv)) diff --git a/src/test/java/org/prebid/server/bidder/medianet/MedianetBidderTest.java b/src/test/java/org/prebid/server/bidder/medianet/MedianetBidderTest.java index 03a3cba66f8..18be44dabbb 100644 --- a/src/test/java/org/prebid/server/bidder/medianet/MedianetBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/medianet/MedianetBidderTest.java @@ -9,26 +9,18 @@ import com.iab.openrtb.response.SeatBid; import org.junit.jupiter.api.Test; import org.prebid.server.VertxTest; -import org.prebid.server.bidder.medianet.model.response.InterestGroupAuctionIntent; -import org.prebid.server.bidder.medianet.model.response.InterestGroupAuctionSeller; -import org.prebid.server.bidder.medianet.model.response.MedianetBidResponse; -import org.prebid.server.bidder.medianet.model.response.MedianetBidResponseExt; import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.bidder.model.BidderCall; import org.prebid.server.bidder.model.BidderError; -import org.prebid.server.bidder.model.CompositeBidderResponse; import org.prebid.server.bidder.model.HttpRequest; import org.prebid.server.bidder.model.HttpResponse; import org.prebid.server.bidder.model.Result; import org.prebid.server.proto.openrtb.ext.ExtPrebid; -import org.prebid.server.proto.openrtb.ext.response.ExtIgi; -import org.prebid.server.proto.openrtb.ext.response.ExtIgiIgs; import java.util.ArrayList; import java.util.List; import java.util.function.Function; -import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; @@ -71,7 +63,7 @@ public void makeBidsShouldReturnErrorIfResponseBodyCouldNotBeParsed() { final BidderCall httpCall = sampleHttpCall(givenBidRequest(), "invalid response"); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).hasSize(1) @@ -86,10 +78,10 @@ public void makeBidsShouldReturnEmptyListIfBidResponseIsNull() throws JsonProces httpCall = sampleHttpCall(givenBidRequest(), mapper.writeValueAsString(null)); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); assertThat(result.getErrors()).isEmpty(); } @@ -100,10 +92,10 @@ public void makeBidsShouldReturnEmptyListIfBidResponseSeatBidIsNull() throws Jso httpCall = sampleHttpCall(null, mapper.writeValueAsString(BidResponse.builder().build())); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); assertThat(result.getErrors()).isEmpty(); } @@ -115,10 +107,10 @@ public void makeBidsShouldReturnBannerBidIfBannerIsPresent() throws JsonProcessi mapper.writeValueAsString(sampleBidResponse(bidBuilder -> bidBuilder.impid("123")))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then - assertThat(result.getBids()) + assertThat(result.getValue()) .containsExactly(BidderBid.of(Bid.builder().impid("123").build(), banner, "USD")); assertThat(result.getErrors()).isEmpty(); } @@ -141,16 +133,16 @@ public void makeBidsShouldReturnCorrespondingMtypesAndAdTypes() throws JsonProce mapper.writeValueAsString(sampleMultiFormatBidResponse(bids))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then - assertThat(result.getBids()).hasSize(4); + assertThat(result.getValue()).hasSize(4); assertThat(result.getErrors()).isEmpty(); final BidderBid bannerBid = BidderBid.of(bid1, banner, "USD"); final BidderBid videoBid = BidderBid.of(bid2, video, "USD"); final BidderBid audioBid = BidderBid.of(bid3, audio, "USD"); final BidderBid xNativeBid = BidderBid.of(bid4, xNative, "USD"); - assertThat(result.getBids()).containsExactlyInAnyOrder(bannerBid, videoBid, audioBid, xNativeBid); + assertThat(result.getValue()).containsExactlyInAnyOrder(bannerBid, videoBid, audioBid, xNativeBid); } @Test @@ -161,13 +153,13 @@ public void makeBidsShouldReturnAdTypeAccordingToImpressionIfMtypeIsAbsent() thr mapper.writeValueAsString(sampleBidResponse(bidBuilder -> bidBuilder.impid("imp_id")))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then - assertThat(result.getBids()).hasSize(1); + assertThat(result.getValue()).hasSize(1); assertThat(result.getErrors()).isEmpty(); final BidderBid videoBid = BidderBid.of(Bid.builder().impid("imp_id").build(), video, "USD"); - assertThat(result.getBids()).containsExactly(videoBid); + assertThat(result.getValue()).containsExactly(videoBid); } @Test @@ -179,13 +171,13 @@ public void makeBidsShouldReturnBannerAdTypeIfMtypeIsAbsentAndIfNoImpressionIdMa mapper.writeValueAsString(sampleBidResponse(bidBuilder -> bidBuilder.impid("imp_id2")))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then - assertThat(result.getBids()).hasSize(1); + assertThat(result.getValue()).hasSize(1); assertThat(result.getErrors()).isEmpty(); final BidderBid bannerBid = BidderBid.of(Bid.builder().impid("imp_id2").build(), banner, "USD"); - assertThat(result.getBids()).containsExactly(bannerBid); + assertThat(result.getValue()).containsExactly(bannerBid); } @Test @@ -196,60 +188,18 @@ public void makeBidsShouldReturnErrorIfMtypeIsWrong() throws JsonProcessingExcep mapper.writeValueAsString(sampleBidResponse(bidBuilder -> bidBuilder.impid("imp_id").mtype(5)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); assertThat(result.getErrors()).hasSize(1); final BidderError error = BidderError.badServerResponse("Unable to fetch mediaType: imp_id"); assertThat(result.getErrors()).containsExactly(error); } - @Test - public void makeBidsShouldReturnFledgeConfigIfBidIsPresent() throws JsonProcessingException { - // given - final BidderCall httpCall = sampleHttpCall( - givenBidRequest(), - mapper.writeValueAsString(sampleBidResponseWithFledgeConfig(bidBuilder -> bidBuilder.impid("imp_id")))); - - // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); - - // then - final ExtIgiIgs igs = ExtIgiIgs.builder() - .impId("imp_id") - .config(mapper.createObjectNode().put("someKey", "someValue")) - .build(); - - assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).hasSize(1); - assertThat(result.getIgi()).containsExactly(ExtIgi.builder().igs(singletonList(igs)).build()); - } - - @Test - public void makeBidsShouldReturnFledgeConfigIfBidIsAbsent() throws JsonProcessingException { - // given - final BidderCall httpCall = sampleHttpCall( - givenBidRequest(), - mapper.writeValueAsString(sampleBidResponseWithoutBidAndWithFledgeConfig("imp_id"))); - - // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); - - // then - final ExtIgiIgs igs = ExtIgiIgs.builder() - .impId("imp_id") - .config(mapper.createObjectNode().put("someKey", "someValue")) - .build(); - - assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).isEmpty(); - assertThat(result.getIgi()).containsExactly(ExtIgi.builder().igs(singletonList(igs)).build()); - } - - private static MedianetBidResponse sampleBidResponse(Function bidCustomizer) { - return MedianetBidResponse.builder() + return BidResponse.builder() .cur("USD") .seatbid(singletonList(SeatBid.builder() .bid(singletonList(bidCustomizer.apply(Bid.builder()).build())) @@ -257,38 +207,8 @@ private static MedianetBidResponse sampleBidResponse(Function bidCustomizer) { - final Bid bid = bidCustomizer.apply(Bid.builder()).build(); - return MedianetBidResponse.builder() - .cur("USD") - .seatbid(singletonList(SeatBid.builder() - .bid(singletonList(bid)) - .build())) - .ext(MedianetBidResponseExt.of(List.of(InterestGroupAuctionIntent.builder() - .igs(List.of(InterestGroupAuctionSeller.builder() - .impId(bid.getImpid()) - .config(mapper.createObjectNode().put("someKey", "someValue")) - .build())) - .build()))) - .build(); - } - - private static MedianetBidResponse sampleBidResponseWithoutBidAndWithFledgeConfig(String impId) { - return MedianetBidResponse.builder() - .cur("USD") - .seatbid(emptyList()) - .ext(MedianetBidResponseExt.of(List.of(InterestGroupAuctionIntent.builder() - .igs(List.of(InterestGroupAuctionSeller.builder() - .impId(impId) - .config(mapper.createObjectNode().put("someKey", "someValue")) - .build())) - .build()))) - .build(); - } - - private static MedianetBidResponse sampleMultiFormatBidResponse(List bids) { - return MedianetBidResponse.builder() + private static BidResponse sampleMultiFormatBidResponse(List bids) { + return BidResponse.builder() .cur("USD") .seatbid(singletonList(SeatBid.builder() .bid(bids) diff --git a/src/test/java/org/prebid/server/bidder/ogury/OguryBidderTest.java b/src/test/java/org/prebid/server/bidder/ogury/OguryBidderTest.java index d8f26170ccb..31c043a4fc9 100644 --- a/src/test/java/org/prebid/server/bidder/ogury/OguryBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/ogury/OguryBidderTest.java @@ -21,7 +21,6 @@ import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.bidder.model.BidderCall; import org.prebid.server.bidder.model.BidderError; -import org.prebid.server.bidder.model.CompositeBidderResponse; import org.prebid.server.bidder.model.HttpRequest; import org.prebid.server.bidder.model.HttpResponse; import org.prebid.server.bidder.model.Result; @@ -406,12 +405,12 @@ public void makeHttpRequestsShouldNotConvertPriceIfFloorIsAbsent() { } @Test - public void makeBidderResponseShouldReturnErrorIfResponseBodyCouldNotBeParsed() { + public void makeBidsShouldReturnErrorIfResponseBodyCouldNotBeParsed() { // given final BidderCall httpCall = givenHttpCall("invalid"); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).hasSize(1) @@ -419,155 +418,155 @@ public void makeBidderResponseShouldReturnErrorIfResponseBodyCouldNotBeParsed() assertThat(error.getType()).isEqualTo(BidderError.Type.bad_server_response); assertThat(error.getMessage()).startsWith("Failed to decode: Unrecognized token"); }); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldNotReturnErrorWhenResponseBodyIsEmpty() throws JsonProcessingException { + public void makeBidsShouldNotReturnErrorWhenResponseBodyIsEmpty() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall(mapper.writeValueAsString(null)); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldReturnEmptyListIfBidResponseSeatBidIsNull() throws JsonProcessingException { + public void makeBidsShouldReturnEmptyListIfBidResponseSeatBidIsNull() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall(mapper.writeValueAsString(BidResponse.builder().build())); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldReturnEmptyListIfBidResponseSeatBidIsEmpty() throws JsonProcessingException { + public void makeBidsShouldReturnEmptyListIfBidResponseSeatBidIsEmpty() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( mapper.writeValueAsString(BidResponse.builder().seatbid(emptyList()).build())); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldReturnErrorWhenBidMTypeIsNotPresent() throws JsonProcessingException { + public void makeBidsShouldReturnErrorWhenBidMTypeIsNotPresent() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( givenBidResponse(bid -> bid.impid("123"))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()) .containsExactly(BidderError.badServerResponse("Missing MType for impression: `123`")); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldReturnErrorWhenBidMTypeIsNotSupported() throws JsonProcessingException { + public void makeBidsShouldReturnErrorWhenBidMTypeIsNotSupported() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( givenBidResponse(bid -> bid.impid("123").mtype(10))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()) .containsExactly(BidderError.badServerResponse("Unsupported MType '10', for impression '123'")); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldReturnBannerBid() throws JsonProcessingException { + public void makeBidsShouldReturnBannerBid() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( givenBidResponse(bid -> bid.mtype(1))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getType) .containsExactly(BidType.banner); } @Test - public void makeBidderResponseShouldReturnVideoBid() throws JsonProcessingException { + public void makeBidsShouldReturnVideoBid() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( givenBidResponse(bid -> bid.mtype(2))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getType) .containsExactly(BidType.video); } @Test - public void makeBidderResponseShouldReturnAudioBid() throws JsonProcessingException { + public void makeBidsShouldReturnAudioBid() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( givenBidResponse(bid -> bid.mtype(3))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getType) .containsExactly(BidType.audio); } @Test - public void makeBidderResponseShouldReturnNativeBid() throws JsonProcessingException { + public void makeBidsShouldReturnNativeBid() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( givenBidResponse(bid -> bid.mtype(4))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getType) .containsExactly(BidType.xNative); } @Test - public void makeBidderResponseShouldReturnBidWithCurFromResponse() throws JsonProcessingException { + public void makeBidsShouldReturnBidWithCurFromResponse() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( givenBidResponse(bid -> bid.mtype(1))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getBidCurrency) .containsExactly("CUR"); } diff --git a/src/test/java/org/prebid/server/bidder/openx/OpenxBidderTest.java b/src/test/java/org/prebid/server/bidder/openx/OpenxBidderTest.java index fab9bedceb7..f5ba6094c17 100644 --- a/src/test/java/org/prebid/server/bidder/openx/OpenxBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/openx/OpenxBidderTest.java @@ -19,13 +19,10 @@ import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.bidder.model.BidderCall; import org.prebid.server.bidder.model.BidderError; -import org.prebid.server.bidder.model.CompositeBidderResponse; import org.prebid.server.bidder.model.HttpRequest; import org.prebid.server.bidder.model.HttpResponse; import org.prebid.server.bidder.model.Result; import org.prebid.server.bidder.openx.proto.OpenxBidExt; -import org.prebid.server.bidder.openx.proto.OpenxBidResponse; -import org.prebid.server.bidder.openx.proto.OpenxBidResponseExt; import org.prebid.server.bidder.openx.proto.OpenxRequestExt; import org.prebid.server.bidder.openx.proto.OpenxVideoExt; import org.prebid.server.proto.openrtb.ext.ExtPrebid; @@ -36,8 +33,6 @@ import org.prebid.server.proto.openrtb.ext.request.openx.ExtImpOpenx; import org.prebid.server.proto.openrtb.ext.response.BidType; import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidVideo; -import org.prebid.server.proto.openrtb.ext.response.ExtIgi; -import org.prebid.server.proto.openrtb.ext.response.ExtIgiIgs; import java.math.BigDecimal; import java.util.Collections; @@ -487,7 +482,6 @@ public void makeHttpRequestsShouldPassThroughImpExt() { .banner(Banner.builder().build()) .ext(mapper.valueToTree( Map.of( - "ae", 1, "bidder", Map.of("customParams", Map.of("param1", "value1")), "data", Map.of("pbadslot", "adslotvalue"), "gpid", "gpidvalue", @@ -502,7 +496,6 @@ public void makeHttpRequestsShouldPassThroughImpExt() { final ObjectNode expectedImpExt = mapper.valueToTree( Map.of( - "ae", 1, "customParams", Map.of("param1", "value1"), "data", Map.of("pbadslot", "adslotvalue"), "gpid", "gpidvalue", @@ -546,30 +539,6 @@ public void makeHttpRequestShouldReturnResultWithCustomBidFloorIfImpBidFloorIsZe .containsExactly(BigDecimal.valueOf(123)); } - @Test - public void makeHttpRequestShouldReturnResultWithAuctionEnvironment() { - // given - final BidRequest bidRequest = BidRequest.builder() - .imp(singletonList( - Imp.builder() - .id("impId2") - .banner(Banner.builder().build()) - .tagid("555555") - .ext(mapper.valueToTree(Map.of("ae", 1, "bidder", Map.of()))) - .build())) - .build(); - - // when - final Result>> result = target.makeHttpRequests(bidRequest); - - // then - assertThat(result.getValue()).hasSize(1) - .extracting(HttpRequest::getPayload) - .flatExtracting(BidRequest::getImp) - .extracting(Imp::getExt) - .contains(mapper.valueToTree(Map.of("ae", 1))); - } - @Test public void makeHttpRequestShouldReturnResultWithCustomBidFloorIfImpBidFloorIsNegative() { // given @@ -599,19 +568,19 @@ public void makeBidsShouldReturnErrorIfResponseBodyCouldNotBeParsed() { final BidderCall httpCall = givenHttpCall("invalid"); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, BidRequest.builder().build()); + final Result> result = target.makeBids(httpCall, BidRequest.builder().build()); // then assertThat(result.getErrors()).hasSize(1) .allMatch(error -> error.getType() == BidderError.Type.bad_server_response && error.getMessage().startsWith("Failed to decode: Unrecognized token 'invalid'")); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test public void makeBidsShouldReturnResultForBannerBidsWithExpectedFields() throws JsonProcessingException { // given - final BidderCall httpCall = givenHttpCall(mapper.writeValueAsString(OpenxBidResponse.builder() + final BidderCall httpCall = givenHttpCall(mapper.writeValueAsString(BidResponse.builder() .seatbid(singletonList(SeatBid.builder() .bid(singletonList(Bid.builder() .w(200) @@ -624,7 +593,6 @@ public void makeBidsShouldReturnResultForBannerBidsWithExpectedFields() throws J .build())) .build())) .cur("UAH") - .ext(OpenxBidResponseExt.of(Map.of("impId1", mapper.createObjectNode().put("somevalue", 1)))) .build())); final BidRequest bidRequest = BidRequest.builder() @@ -636,18 +604,11 @@ public void makeBidsShouldReturnResultForBannerBidsWithExpectedFields() throws J .build(); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then - final ExtIgi igi = ExtIgi.builder() - .igs(singletonList(ExtIgiIgs.builder() - .impId("impId1") - .config(mapper.createObjectNode().put("somevalue", 1)) - .build())) - .build(); - assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).hasSize(1) + assertThat(result.getValue()).hasSize(1) .containsOnly(BidderBid.of( Bid.builder() .impid("impId1") @@ -659,13 +620,12 @@ public void makeBidsShouldReturnResultForBannerBidsWithExpectedFields() throws J .mtype(1) .build(), BidType.banner, "UAH")); - assertThat(result.getIgi()).containsExactly(igi); } @Test public void makeBidsShouldReturnResultForNativeBidsWithExpectedFields() throws JsonProcessingException { // given - final BidderCall httpCall = givenHttpCall(mapper.writeValueAsString(OpenxBidResponse.builder() + final BidderCall httpCall = givenHttpCall(mapper.writeValueAsString(BidResponse.builder() .seatbid(singletonList(SeatBid.builder() .bid(singletonList(Bid.builder() .w(200) @@ -677,7 +637,6 @@ public void makeBidsShouldReturnResultForNativeBidsWithExpectedFields() throws J .build())) .build())) .cur("UAH") - .ext(OpenxBidResponseExt.of(Map.of("impId1", mapper.createObjectNode().put("somevalue", 1)))) .build())); final BidRequest bidRequest = BidRequest.builder() @@ -689,11 +648,11 @@ public void makeBidsShouldReturnResultForNativeBidsWithExpectedFields() throws J .build(); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).hasSize(1) + assertThat(result.getValue()).hasSize(1) .containsOnly(BidderBid.of( Bid.builder() .impid("impId1") @@ -734,11 +693,11 @@ public void makeBidsShouldReturnVideoInfoWhenAvailable() throws JsonProcessingEx .build(); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).hasSize(1) + assertThat(result.getValue()).hasSize(1) .extracting(BidderBid::getVideoInfo) .containsExactly(ExtBidPrebidVideo.of(30, "category1")); } @@ -746,7 +705,7 @@ public void makeBidsShouldReturnVideoInfoWhenAvailable() throws JsonProcessingEx @Test public void makeBidsShouldReturnBidsWithTypeFromImpWhenNoMtype() throws JsonProcessingException { // given - final BidderCall httpCall = givenHttpCall(mapper.writeValueAsString(OpenxBidResponse.builder() + final BidderCall httpCall = givenHttpCall(mapper.writeValueAsString(BidResponse.builder() .seatbid(List.of( SeatBid.builder() .bid(singletonList(Bid.builder() @@ -797,11 +756,11 @@ public void makeBidsShouldReturnBidsWithTypeFromImpWhenNoMtype() throws JsonProc .build(); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).hasSize(3) + assertThat(result.getValue()).hasSize(3) .contains(BidderBid.builder() .bid(Bid.builder() .impid("impId1-banner") @@ -839,38 +798,6 @@ public void makeBidsShouldReturnBidsWithTypeFromImpWhenNoMtype() throws JsonProc .build()); } - @Test - public void makeBidsShouldReturnFledgeConfigEvenIfNoBids() throws JsonProcessingException { - // given - final BidderCall httpCall = givenHttpCall(mapper.writeValueAsString(OpenxBidResponse.builder() - .seatbid(emptyList()) - .ext(OpenxBidResponseExt.of(Map.of("impId1", mapper.createObjectNode().put("somevalue", 1)))) - .build())); - - final BidRequest bidRequest = BidRequest.builder() - .id("bidRequestId") - .imp(singletonList(Imp.builder() - .id("impId1") - .banner(Banner.builder().build()) - .build())) - .build(); - - // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); - - // then - final ExtIgi igi = ExtIgi.builder() - .igs(singletonList(ExtIgiIgs.builder() - .impId("impId1") - .config(mapper.createObjectNode().put("somevalue", 1)) - .build())) - .build(); - - assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).isEmpty(); - assertThat(result.getIgi()).containsExactly(igi); - } - @Test public void makeBidsShouldRespectMtypeWhenBothBannerAndVideoImpWithSameIdExist() throws JsonProcessingException { // given @@ -900,11 +827,11 @@ public void makeBidsShouldRespectMtypeWhenBothBannerAndVideoImpWithSameIdExist() .build(); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).hasSize(1) + assertThat(result.getValue()).hasSize(1) .containsOnly( BidderBid.builder() .bid(Bid.builder() @@ -950,11 +877,11 @@ public void makeBidsShouldRespectBannerImpWhenBothBannerAndVideoImpWithSameIdExi .build(); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).hasSize(1) + assertThat(result.getValue()).hasSize(1) .containsOnly(BidderBid.of( Bid.builder() .impid("impId1") @@ -975,12 +902,12 @@ public void makeBidsShouldReturnResultContainingEmptyValueAndErrorsWhenSeatBidEm mapper.writeValueAsString(BidResponse.builder().build())); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, BidRequest.builder().build()); + final Result> result = target.makeBids(httpCall, BidRequest.builder().build()); // then assertThat(result.getErrors()).isEmpty(); assertThat(result).isNotNull() - .extracting(CompositeBidderResponse::getBids, CompositeBidderResponse::getErrors) + .extracting(Result::getValue, Result::getErrors) .containsOnly(Collections.emptyList(), Collections.emptyList()); } @@ -1018,7 +945,7 @@ public void makeBidShouldReturnBidWithExtPrebidMetaContainingAllFieldsFromBidExt .build(); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then final ObjectNode expectedExtWithBidMeta = mapper.createObjectNode() @@ -1031,7 +958,7 @@ public void makeBidShouldReturnBidWithExtPrebidMetaContainingAllFieldsFromBidExt .put("brandId", 3) .put("networkId", 1))); assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).hasSize(1) + assertThat(result.getValue()).hasSize(1) .extracting(BidderBid::getBid) .extracting(Bid::getExt) .containsExactly(expectedExtWithBidMeta); @@ -1069,7 +996,7 @@ public void makeBidShouldReturnBidWithExtPrebidMetaContainingBrandIdFieldOnly() .build(); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then final ObjectNode expectedExtWithBidMeta = mapper.createObjectNode() @@ -1078,7 +1005,7 @@ public void makeBidShouldReturnBidWithExtPrebidMetaContainingBrandIdFieldOnly() .set("meta", mapper.createObjectNode() .put("brandId", 4))); assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).hasSize(1) + assertThat(result.getValue()).hasSize(1) .extracting(BidderBid::getBid) .extracting(Bid::getExt) .containsExactly(expectedExtWithBidMeta); @@ -1119,7 +1046,7 @@ public void makeBidShouldReturnBidWithExtPrebidMetaNotContainingFieldsWithInvali .build(); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest); + final Result> result = target.makeBids(httpCall, bidRequest); // then final ObjectNode expectedExtWithBidMeta = mapper.createObjectNode() @@ -1127,7 +1054,7 @@ public void makeBidShouldReturnBidWithExtPrebidMetaNotContainingFieldsWithInvali .put("buyer_id", "xyz") .put("brand_id", "cba"); assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).hasSize(1) + assertThat(result.getValue()).hasSize(1) .extracting(BidderBid::getBid) .extracting(Bid::getExt) .containsExactly(expectedExtWithBidMeta); diff --git a/src/test/java/org/prebid/server/bidder/pubmatic/PubmaticBidderTest.java b/src/test/java/org/prebid/server/bidder/pubmatic/PubmaticBidderTest.java index bc4568396c6..e5211193ed9 100644 --- a/src/test/java/org/prebid/server/bidder/pubmatic/PubmaticBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/pubmatic/PubmaticBidderTest.java @@ -25,7 +25,6 @@ import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.bidder.model.BidderCall; import org.prebid.server.bidder.model.BidderError; -import org.prebid.server.bidder.model.CompositeBidderResponse; import org.prebid.server.bidder.model.HttpRequest; import org.prebid.server.bidder.model.HttpResponse; import org.prebid.server.bidder.model.Result; @@ -33,8 +32,6 @@ import org.prebid.server.bidder.pubmatic.model.request.PubmaticExtDataAdServer; import org.prebid.server.bidder.pubmatic.model.request.PubmaticWrapper; import org.prebid.server.bidder.pubmatic.model.response.PubmaticBidExt; -import org.prebid.server.bidder.pubmatic.model.response.PubmaticBidResponse; -import org.prebid.server.bidder.pubmatic.model.response.PubmaticExtBidResponse; import org.prebid.server.bidder.pubmatic.model.response.VideoCreativeInfo; import org.prebid.server.proto.openrtb.ext.ExtPrebid; import org.prebid.server.proto.openrtb.ext.request.ExtApp; @@ -48,8 +45,6 @@ import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebid; import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidMeta; import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidVideo; -import org.prebid.server.proto.openrtb.ext.response.ExtIgi; -import org.prebid.server.proto.openrtb.ext.response.ExtIgiIgs; import org.prebid.server.util.HttpUtil; import java.math.BigDecimal; @@ -719,7 +714,6 @@ public void makeHttpRequestsShouldAddImpExtAddUnitKeyKeyWordFromDataAdSlotIfAdSe ExtImpPubmatic.builder().build(), extData, null, - null, null ))) .build())) @@ -753,7 +747,6 @@ public void makeHttpRequestsShouldAddImpExtAddUnitKeyKeyWordFromAdServerAdSlotIf ExtImpPubmatic.builder().build(), extData, null, - null, null ))) .build())) @@ -788,7 +781,6 @@ public void makeHttpRequestsShouldAddImpExtWithKeyValWithDctrAndExtDataExceptFor ExtImpPubmatic.builder().dctr("dctr").build(), extData, null, - null, null ))) .build())) @@ -826,7 +818,6 @@ public void makeHttpRequestsShouldAddImpExtWithKeyValWithExtDataWhenDctrIsAbsent ExtImpPubmatic.builder().dctr(null).build(), extData, null, - null, null ))) .build())) @@ -846,31 +837,6 @@ public void makeHttpRequestsShouldAddImpExtWithKeyValWithExtDataWhenDctrIsAbsent .containsExactly(expectedImpExt); } - @Test - public void makeHttpRequestsShouldAddImpExtAddAE() { - // given - final BidRequest bidRequest = BidRequest.builder() - .imp(singletonList(Imp.builder() - .id("123") - .banner(Banner.builder().build()) - .ext(mapper.valueToTree(PubmaticBidderImpExt.of( - ExtImpPubmatic.builder().build(), null, 1, null, null))) - .build())) - .build(); - - // when - final Result>> result = target.makeHttpRequests(bidRequest); - - // then - final ObjectNode expectedImpExt = mapper.createObjectNode().put("ae", 1); - assertThat(result.getErrors()).isEmpty(); - assertThat(result.getValue()) - .extracting(HttpRequest::getPayload) - .flatExtracting(BidRequest::getImp) - .extracting(Imp::getExt) - .containsExactly(expectedImpExt); - } - @Test public void makeHttpRequestsShouldAddImpExtAddGpId() { // given @@ -879,7 +845,7 @@ public void makeHttpRequestsShouldAddImpExtAddGpId() { .id("123") .banner(Banner.builder().build()) .ext(mapper.valueToTree(PubmaticBidderImpExt.of( - ExtImpPubmatic.builder().build(), null, null, "gpId", null))) + ExtImpPubmatic.builder().build(), null, "gpId", null))) .build())) .build(); @@ -907,7 +873,7 @@ public void makeHttpRequestsShouldAddImpExtAddSkadn() { .id("123") .banner(Banner.builder().build()) .ext(mapper.valueToTree(PubmaticBidderImpExt.of( - ExtImpPubmatic.builder().build(), null, null, null, skadn))) + ExtImpPubmatic.builder().build(), null, null, skadn))) .build())) .build(); @@ -1249,56 +1215,56 @@ public void makeHttpRequestsShouldReplacePmZoneIDOldKeyNameWithNew() { } @Test - public void makeBidderResponseShouldReturnErrorIfResponseBodyCouldNotBeParsed() { + public void makeBidsShouldReturnErrorIfResponseBodyCouldNotBeParsed() { // given final BidderCall httpCall = givenHttpCall("invalid"); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).hasSize(1); assertThat(result.getErrors().getFirst().getMessage()).startsWith("Failed to decode: Unrecognized token"); assertThat(result.getErrors().getFirst().getType()).isEqualTo(BidderError.Type.bad_server_response); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldReturnEmptyListIfBidResponseIsNull() throws JsonProcessingException { + public void makeBidsShouldReturnEmptyListIfBidResponseIsNull() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( mapper.writeValueAsString(null)); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldReturnEmptyListIfBidResponseSeatBidIsNull() throws JsonProcessingException { + public void makeBidsShouldReturnEmptyListIfBidResponseSeatBidIsNull() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( mapper.writeValueAsString(BidResponse.builder().build())); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()).isEmpty(); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldReturnBannerBid() throws JsonProcessingException { + public void makeBidsShouldReturnBannerBid() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( mapper.writeValueAsString(givenBidResponse(bidBuilder -> bidBuilder.impid("123").mtype(1)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); @@ -1306,12 +1272,12 @@ public void makeBidderResponseShouldReturnBannerBid() throws JsonProcessingExcep final ObjectNode expectedBidExt = mapper.createObjectNode().set("prebid", mapper.createObjectNode() .set("meta", mapper.createObjectNode().put("mediaType", "banner"))); - assertThat(result.getBids()).containsExactly(BidderBid.of( + assertThat(result.getValue()).containsExactly(BidderBid.of( Bid.builder().impid("123").mtype(1).ext(expectedBidExt).build(), banner, "USD")); } @Test - public void makeBidderResponseShouldReturnVideoBidWhenInBannerVideoIsTrue() throws JsonProcessingException { + public void makeBidsShouldReturnVideoBidWhenInBannerVideoIsTrue() throws JsonProcessingException { // given final ObjectNode givenBidExt = mapper.createObjectNode().put("ibv", true); final BidderCall httpCall = givenHttpCall( @@ -1319,7 +1285,7 @@ public void makeBidderResponseShouldReturnVideoBidWhenInBannerVideoIsTrue() thro bidBuilder -> bidBuilder.impid("123").mtype(1).ext(givenBidExt)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); @@ -1329,19 +1295,19 @@ public void makeBidderResponseShouldReturnVideoBidWhenInBannerVideoIsTrue() thro .set("prebid", mapper.createObjectNode() .set("meta", mapper.createObjectNode().put("mediaType", "video"))); - assertThat(result.getBids()).containsExactly(BidderBid.of( + assertThat(result.getValue()).containsExactly(BidderBid.of( Bid.builder().impid("123").mtype(1).ext(expectedBidExt).build(), banner, "USD")); } @Test - public void makeBidderResponseShouldReturnVideoBidIfExtBidContainsMtypeTwo() throws JsonProcessingException { + public void makeBidsShouldReturnVideoBidIfExtBidContainsMtypeTwo() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( mapper.writeValueAsString( givenBidResponse(bidBuilder -> bidBuilder.impid("123").mtype(2)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); @@ -1349,19 +1315,19 @@ public void makeBidderResponseShouldReturnVideoBidIfExtBidContainsMtypeTwo() thr final ObjectNode expectedBidExt = mapper.createObjectNode().set("prebid", mapper.createObjectNode() .set("meta", mapper.createObjectNode().put("mediaType", "video"))); - assertThat(result.getBids()).containsExactly( + assertThat(result.getValue()).containsExactly( BidderBid.of(Bid.builder().impid("123").mtype(2).ext(expectedBidExt).build(), video, "USD")); } @Test - public void makeBidderResponseShouldReturnAudioBidIfExtBidContainsMtype3() throws JsonProcessingException { + public void makeBidsShouldReturnAudioBidIfExtBidContainsMtype3() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( mapper.writeValueAsString( givenBidResponse(bidBuilder -> bidBuilder.impid("123").mtype(3)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); @@ -1369,18 +1335,18 @@ public void makeBidderResponseShouldReturnAudioBidIfExtBidContainsMtype3() throw final ObjectNode expectedBidExt = mapper.createObjectNode().set("prebid", mapper.createObjectNode() .set("meta", mapper.createObjectNode().put("mediaType", "audio"))); - assertThat(result.getBids()).containsExactly( + assertThat(result.getValue()).containsExactly( BidderBid.of(Bid.builder().impid("123").mtype(3).ext(expectedBidExt).build(), audio, "USD")); } @Test - public void makeBidderResponseShouldReturnXNativeBidIfExtBidContainsMtypeFour() throws JsonProcessingException { + public void makeBidsShouldReturnXNativeBidIfExtBidContainsMtypeFour() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( mapper.writeValueAsString(givenBidResponse(bidBuilder -> bidBuilder.impid("123").mtype(4)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); @@ -1388,12 +1354,12 @@ public void makeBidderResponseShouldReturnXNativeBidIfExtBidContainsMtypeFour() final ObjectNode expectedBidExt = mapper.createObjectNode().set("prebid", mapper.createObjectNode() .set("meta", mapper.createObjectNode().put("mediaType", "native"))); - assertThat(result.getBids()).containsExactly( + assertThat(result.getValue()).containsExactly( BidderBid.of(Bid.builder().impid("123").mtype(4).ext(expectedBidExt).build(), xNative, "USD")); } @Test - public void makeBidderResponseShouldFillExtBidPrebidVideoDurationIfDurationIsNotNull() + public void makeBidsShouldFillExtBidPrebidVideoDurationIfDurationIsNotNull() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( @@ -1403,7 +1369,7 @@ public void makeBidderResponseShouldFillExtBidPrebidVideoDurationIfDurationIsNot PubmaticBidExt.of(VideoCreativeInfo.of(1), null, null, null)))))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); @@ -1414,12 +1380,12 @@ public void makeBidderResponseShouldFillExtBidPrebidVideoDurationIfDurationIsNot .meta(ExtBidPrebidMeta.builder().mediaType("video").build()) .video(ExtBidPrebidVideo.of(1, null)) .build())); - assertThat(result.getBids()).containsExactly( + assertThat(result.getValue()).containsExactly( BidderBid.of(Bid.builder().mtype(2).impid("123").ext(bidExt).build(), video, "USD")); } @Test - public void makeBidderResponseShouldNotFillExtBidPrebidVideoDurationIfDurationIsNull() + public void makeBidsShouldNotFillExtBidPrebidVideoDurationIfDurationIsNull() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( @@ -1429,7 +1395,7 @@ public void makeBidderResponseShouldNotFillExtBidPrebidVideoDurationIfDurationIs PubmaticBidExt.of(VideoCreativeInfo.of(null), null, null, null)))))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); @@ -1439,12 +1405,12 @@ public void makeBidderResponseShouldNotFillExtBidPrebidVideoDurationIfDurationIs .meta(ExtBidPrebidMeta.builder().mediaType("banner").build()) .build())); - assertThat(result.getBids()).containsExactly( + assertThat(result.getValue()).containsExactly( BidderBid.of(Bid.builder().impid("123").mtype(1).ext(bidExt).build(), banner, "USD")); } @Test - public void makeBidderResponseShouldNotFillExtBidPrebidVideoDurationIfVideoIsNull() throws JsonProcessingException { + public void makeBidsShouldNotFillExtBidPrebidVideoDurationIfVideoIsNull() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( mapper.writeValueAsString( @@ -1453,19 +1419,19 @@ public void makeBidderResponseShouldNotFillExtBidPrebidVideoDurationIfVideoIsNul PubmaticBidExt.of(null, null, null, null)))))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); final ObjectNode expectedBidExt = mapper.createObjectNode().set("prebid", mapper.createObjectNode() .set("meta", mapper.createObjectNode().put("mediaType", "banner"))); - assertThat(result.getBids()).containsExactly(BidderBid.of( + assertThat(result.getValue()).containsExactly(BidderBid.of( Bid.builder().impid("123").mtype(1).ext(expectedBidExt).build(), banner, "USD")); } @Test - public void makeBidderResponseShouldFillDealPriorityData() throws JsonProcessingException { + public void makeBidsShouldFillDealPriorityData() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( mapper.writeValueAsString( @@ -1474,17 +1440,17 @@ public void makeBidderResponseShouldFillDealPriorityData() throws JsonProcessing PubmaticBidExt.of(null, 12, null, null)))))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getDealPriority) .containsExactly(12); } @Test - public void makeBidderResponseShouldFillSeat() throws JsonProcessingException { + public void makeBidsShouldFillSeat() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( mapper.writeValueAsString( @@ -1493,17 +1459,17 @@ public void makeBidderResponseShouldFillSeat() throws JsonProcessingException { PubmaticBidExt.of(null, 12, "marketplace", null)))))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getSeat) .containsExactly("marketplace"); } @Test - public void makeBidderResponseShouldParseNativeAdmData() throws JsonProcessingException { + public void makeBidsShouldParseNativeAdmData() throws JsonProcessingException { // given final ObjectNode admNode = mapper.createObjectNode(); final ObjectNode nativeNode = mapper.createObjectNode(); @@ -1517,18 +1483,18 @@ public void makeBidderResponseShouldParseNativeAdmData() throws JsonProcessingEx PubmaticBidExt.of(null, 12, null, null)))))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getBid) .extracting(Bid::getAdm) .containsExactly("{\"property1\":\"value1\"}"); } @Test - public void makeBidderResponseShouldTakeOnlyFirstCatElement() throws JsonProcessingException { + public void makeBidsShouldTakeOnlyFirstCatElement() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( mapper.writeValueAsString( @@ -1536,14 +1502,14 @@ public void makeBidderResponseShouldTakeOnlyFirstCatElement() throws JsonProcess .cat(asList("cat1", "cat2"))))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); final ObjectNode expectedBidExt = mapper.createObjectNode().set("prebid", mapper.createObjectNode() .set("meta", mapper.createObjectNode().put("mediaType", "banner"))); - assertThat(result.getBids()).containsExactly(BidderBid.of( + assertThat(result.getValue()).containsExactly(BidderBid.of( Bid.builder() .impid("123") .mtype(1) @@ -1554,52 +1520,22 @@ public void makeBidderResponseShouldTakeOnlyFirstCatElement() throws JsonProcess } @Test - public void makeBidderResponseShouldReturnBannerBidIfExtBidContainsIllegalBidType() throws JsonProcessingException { + public void makeBidsShouldReturnBannerBidIfExtBidContainsIllegalBidType() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( mapper.writeValueAsString(givenBidResponse(bidBuilder -> bidBuilder.impid("123").mtype(100)))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).containsExactly( BidderError.badServerResponse("failed to parse bid mtype (100) for impression id 123")); - assertThat(result.getBids()).isEmpty(); - } - - @Test - public void makeBidderResponseShouldReturnFledgeAuctionConfig() throws JsonProcessingException { - // given - final BidResponse bidResponse = givenBidResponse(bidBuilder -> bidBuilder.impid("imp_id")); - final ObjectNode auctionConfig = mapper.createObjectNode(); - final PubmaticBidResponse bidResponseWithFledge = PubmaticBidResponse.builder() - .cur(bidResponse.getCur()) - .seatbid(bidResponse.getSeatbid()) - .ext(PubmaticExtBidResponse.of(Map.of("imp_id", auctionConfig))) - .build(); - final BidderCall httpCall = givenHttpCall(mapper.writeValueAsString(bidResponseWithFledge)); - - // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); - - // then - assertThat(result.getErrors()).isEmpty(); - final ObjectNode expectedBidExt = mapper.createObjectNode().set("prebid", mapper.createObjectNode() - .set("meta", mapper.createObjectNode().put("mediaType", "banner"))); - - assertThat(result.getBids()).containsExactly(BidderBid.of( - Bid.builder().impid("imp_id").mtype(1).ext(expectedBidExt).build(), banner, "USD")); - - final ExtIgi igi = ExtIgi.builder() - .igs(singletonList(ExtIgiIgs.builder().impId("imp_id").config(auctionConfig).build())) - .build(); - - assertThat(result.getIgi()).containsExactly(igi); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidderResponseShouldNotModifyAdmWhenNativeNodeIsNull() throws JsonProcessingException { + public void makeBidsShouldNotModifyAdmWhenNativeNodeIsNull() throws JsonProcessingException { // given final ObjectNode admNode = mapper.createObjectNode().put("otherField", "value"); final BidderCall httpCall = givenHttpCall( @@ -1610,28 +1546,16 @@ public void makeBidderResponseShouldNotModifyAdmWhenNativeNodeIsNull() throws Js PubmaticBidExt.of(null, 12, null, null)))))); // when - final CompositeBidderResponse result = target.makeBidderResponse(httpCall, null); + final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getBids()) + assertThat(result.getValue()) .extracting(BidderBid::getBid) .extracting(Bid::getAdm) .containsExactly(admNode.toString()); } - @Test - public void makeBidsShouldFail() throws JsonProcessingException { - //given - final BidderCall httpCall = givenHttpCall(mapper.writeValueAsString(BidResponse.builder().build())); - - // when - final Result> result = target.makeBids(httpCall, null); - - // then - assertThat(result.getErrors()).containsExactly(BidderError.generic("Deprecated adapter method invoked")); - } - private ObjectNode givenExtImpWithKadfloor(String kadfloor) { return mapper.valueToTree(ExtPrebid.of(null, ExtImpPubmatic.builder().kadfloor(kadfloor).build())); } diff --git a/src/test/resources/org/prebid/server/it/openrtb2/ix/test-auction-ix-request.json b/src/test/resources/org/prebid/server/it/openrtb2/ix/test-auction-ix-request.json index 6d99b8b6278..4e01ea521fa 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/ix/test-auction-ix-request.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/ix/test-auction-ix-request.json @@ -8,7 +8,6 @@ "h": 250 }, "ext": { - "ae": 1, "ix": { "siteId": "10002" } diff --git a/src/test/resources/org/prebid/server/it/openrtb2/ix/test-ix-bid-request.json b/src/test/resources/org/prebid/server/it/openrtb2/ix/test-ix-bid-request.json index 0b9d5fb0aaf..14a887a39c4 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/ix/test-ix-bid-request.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/ix/test-ix-bid-request.json @@ -15,10 +15,6 @@ "h": 250 }, "ext": { - "ae": 1, - "igs": { - "ae": 1 - }, "tid": "${json-unit.any-string}", "bidder": { "siteId": "10002" diff --git a/src/test/resources/org/prebid/server/it/openrtb2/pubmatic/test-auction-pubmatic-request.json b/src/test/resources/org/prebid/server/it/openrtb2/pubmatic/test-auction-pubmatic-request.json index 3a20b08ce67..c669ad1c3c5 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/pubmatic/test-auction-pubmatic-request.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/pubmatic/test-auction-pubmatic-request.json @@ -11,7 +11,6 @@ "h": 600 }, "ext": { - "ae": 1, "pubmatic": { "adSlot": "slot9@300x250:zzz", "publisherId": " publisherId ", diff --git a/src/test/resources/org/prebid/server/it/openrtb2/pubmatic/test-pubmatic-bid-request.json b/src/test/resources/org/prebid/server/it/openrtb2/pubmatic/test-pubmatic-bid-request.json index a34e904ffe5..b2429422810 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/pubmatic/test-pubmatic-bid-request.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/pubmatic/test-pubmatic-bid-request.json @@ -14,7 +14,6 @@ "tagid": "slot9", "bidfloor": 0.12, "ext": { - "ae": 1, "pmZoneId": "Zone1,Zone2", "preference": "sports,movies", "dfp_ad_unit_code": "thirdPbAdSlot" From d033281e876a50f9e11dc9fbdbf1f167bb77a77e Mon Sep 17 00:00:00 2001 From: Viktor Kryshtal <33136089+Lightwood13@users.noreply.github.com> Date: Thu, 23 Jul 2026 17:30:31 +0300 Subject: [PATCH 3/8] Handle GVL deletions (#4519) --- docs/config-app.md | 3 + docs/metrics.md | 1 + sample/001_banner/configs/config.yaml | 2 + sample/configs/localdev-config.yaml | 2 + sample/configs/prebid-config-db.yaml | 2 + sample/configs/prebid-config-s3.yaml | 2 + sample/configs/prebid-config-with-51d-dd.yaml | 2 + sample/configs/prebid-config-with-module.yaml | 2 + .../configs/prebid-config-with-optable.yaml | 2 + sample/configs/prebid-config-with-wurfl.yaml | 2 + sample/configs/prebid-config.yaml | 2 + src/main/docker/application.yaml | 2 + .../org/prebid/server/metric/Metrics.java | 8 + .../org/prebid/server/metric/TcfMetrics.java | 24 ++ .../server/privacy/gdpr/Tcf2Service.java | 7 +- .../vendorlist/LiveVendorListService.java | 127 ++++++ .../gdpr/vendorlist/VendorListFileStore.java | 124 ++++++ .../gdpr/vendorlist/VendorListResult.java | 14 + .../gdpr/vendorlist/VendorListService.java | 177 +------- .../gdpr/vendorlist/VendorListUtil.java | 56 +++ .../gdpr/vendorlist/VendorListWrapper.java | 33 ++ .../VersionedVendorListService.java | 18 +- .../privacy/gdpr/vendorlist/proto/Vendor.java | 4 + .../config/PrivacyServiceConfiguration.java | 60 ++- src/main/resources/application.yaml | 3 + .../metrics-config/prometheus-labels.yaml | 4 + .../vendorlist/VendorListResponse.groovy | 5 +- .../service/PrebidServerService.groovy | 9 + .../scaffolding/VendorList.groovy | 40 +- .../BidderFieldDisplayBehaviorSpec.groovy | 19 +- .../tests/privacy/PrivacyBaseSpec.groovy | 13 +- .../tests/privacy/gdpr/GdprAuctionSpec.groovy | 282 +++++++++++- .../functional/util/privacy/TcfConsent.groovy | 6 +- .../org/prebid/server/metric/MetricsTest.java | 18 + .../server/privacy/gdpr/Tcf2ServiceTest.java | 4 +- .../vendorlist/LiveVendorListServiceTest.java | 288 +++++++++++++ .../vendorlist/VendorListFileStoreTest.java | 407 ++++++++++++++++++ .../vendorlist/VendorListServiceTest.java | 249 +++++------ .../gdpr/vendorlist/VendorListUtilTest.java | 192 +++++++++ .../VersionedVendorListServiceTest.java | 80 +++- .../server/it/test-application.properties | 1 + 41 files changed, 1920 insertions(+), 376 deletions(-) create mode 100644 src/main/java/org/prebid/server/privacy/gdpr/vendorlist/LiveVendorListService.java create mode 100644 src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListFileStore.java create mode 100644 src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListResult.java create mode 100644 src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListUtil.java create mode 100644 src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListWrapper.java create mode 100644 src/test/java/org/prebid/server/privacy/gdpr/vendorlist/LiveVendorListServiceTest.java create mode 100644 src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListFileStoreTest.java create mode 100644 src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListUtilTest.java diff --git a/docs/config-app.md b/docs/config-app.md index 5df4cb13239..015ac1f398e 100644 --- a/docs/config-app.md +++ b/docs/config-app.md @@ -457,6 +457,9 @@ If not defined in config all other Health Checkers would be disabled and endpoin - `gdpr.special-features.sfN.vendor-exceptions[]` - bidder names that will be treated opposite to `sfN.enforce` value. - `gdpr.purpose-one-treatment-interpretation` - option that allows to skip the Purpose one enforcement workflow. - `gdpr.vendorlist.default-timeout-ms` - default operation timeout for obtaining new vendor list. +- `gdpr.vendorlist.live.url` - URL of the latest TCF GVL used to detect vendors with a past `deletedDate`. Default `https://vendor-list.consensu.org/v3/vendor-list.json`. +- `gdpr.vendorlist.live.refresh-period-ms` - how often to refresh the live GVL deleted-vendor set, in milliseconds. Default `86400000` (24 hours). +- `gdpr.vendorlist.live.startup-cache-dir` - directory for local storage vendor list cache. At startup server will attempt to read latest GVL from this location. - `gdpr.vendorlist.v2.http-endpoint-template` - template string for vendor list url version 2. - `gdpr.vendorlist.v2.refresh-missing-list-period-ms` - time to wait between attempts to fetch vendor list version that previously was reported to be missing by origin. Default `3600000` (one hour). - `gdpr.vendorlist.v2.fallback-vendor-list-path` - location on the file system of the fallback vendor list that will be used in place of missing vendor list versions. Optional. diff --git a/docs/metrics.md b/docs/metrics.md index c07e0660598..4dad9b6effb 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -131,6 +131,7 @@ Following metrics are collected and submitted if account is configured with `det - `privacy.tcf.(v1,v2).in-geo` - number of requests received from TCF-concerned geo region with consent string of particular version - `privacy.tcf.(v1,v2).out-geo` - number of requests received outside of TCF-concerned geo region with consent string of particular version - `privacy.tcf.(v1,v2).vendorlist.(missing|ok|err|fallback)` - number of processed vendor lists of particular version +- `privacy.tcf.vendorlist.live.(ok|err)` - number of successful or failed refreshes of the live GVL used for deleted-vendor detection - `privacy.usp.specified` - number of requests with a valid US Privacy string (CCPA) - `privacy.usp.opt-out` - number of requests that required privacy enforcement according to CCPA rules - `privacy.lmt` - number of requests that required privacy enforcement according to LMT flag diff --git a/sample/001_banner/configs/config.yaml b/sample/001_banner/configs/config.yaml index 1dd053ddb22..ca3496226c2 100755 --- a/sample/001_banner/configs/config.yaml +++ b/sample/001_banner/configs/config.yaml @@ -25,6 +25,8 @@ gdpr: cache-dir: /var/tmp/vendor2 v3: cache-dir: /var/tmp/vendor3 + live: + startup-cache-dir: /var/tmp/vendor3 admin-endpoints: logging-changelevel: enabled: true diff --git a/sample/configs/localdev-config.yaml b/sample/configs/localdev-config.yaml index c2991cdf3b6..9c036f3fdb9 100644 --- a/sample/configs/localdev-config.yaml +++ b/sample/configs/localdev-config.yaml @@ -24,3 +24,5 @@ gdpr: cache-dir: /var/tmp/vendor2 v3: cache-dir: /var/tmp/vendor3 + live: + startup-cache-dir: /var/tmp/vendor3 diff --git a/sample/configs/prebid-config-db.yaml b/sample/configs/prebid-config-db.yaml index 418b6d365df..666ffb69a55 100644 --- a/sample/configs/prebid-config-db.yaml +++ b/sample/configs/prebid-config-db.yaml @@ -43,6 +43,8 @@ gdpr: cache-dir: /var/tmp/vendor2 v3: cache-dir: /var/tmp/vendor3 + live: + startup-cache-dir: /var/tmp/vendor3 admin-endpoints: logging-changelevel: enabled: true diff --git a/sample/configs/prebid-config-s3.yaml b/sample/configs/prebid-config-s3.yaml index 2a01d4f4d43..09620ceec87 100644 --- a/sample/configs/prebid-config-s3.yaml +++ b/sample/configs/prebid-config-s3.yaml @@ -51,6 +51,8 @@ gdpr: cache-dir: /var/tmp/vendor2 v3: cache-dir: /var/tmp/vendor3 + live: + startup-cache-dir: /var/tmp/vendor3 admin-endpoints: logging-changelevel: diff --git a/sample/configs/prebid-config-with-51d-dd.yaml b/sample/configs/prebid-config-with-51d-dd.yaml index 80f73b1a461..1e29ec1d997 100644 --- a/sample/configs/prebid-config-with-51d-dd.yaml +++ b/sample/configs/prebid-config-with-51d-dd.yaml @@ -33,6 +33,8 @@ gdpr: cache-dir: /var/tmp/vendor2 v3: cache-dir: /var/tmp/vendor3 + live: + startup-cache-dir: /var/tmp/vendor3 admin-endpoints: logging-changelevel: enabled: true diff --git a/sample/configs/prebid-config-with-module.yaml b/sample/configs/prebid-config-with-module.yaml index 3619e1cb9fd..959a4cef2af 100644 --- a/sample/configs/prebid-config-with-module.yaml +++ b/sample/configs/prebid-config-with-module.yaml @@ -33,6 +33,8 @@ gdpr: cache-dir: /var/tmp/vendor2 v3: cache-dir: /var/tmp/vendor3 + live: + startup-cache-dir: /var/tmp/vendor3 admin-endpoints: logging-changelevel: enabled: true diff --git a/sample/configs/prebid-config-with-optable.yaml b/sample/configs/prebid-config-with-optable.yaml index 4070cc0aed5..ef2d59037bf 100644 --- a/sample/configs/prebid-config-with-optable.yaml +++ b/sample/configs/prebid-config-with-optable.yaml @@ -39,6 +39,8 @@ gdpr: cache-dir: /var/tmp/vendor2 v3: cache-dir: /var/tmp/vendor3 + live: + startup-cache-dir: /var/tmp/vendor3 admin-endpoints: logging-changelevel: enabled: true diff --git a/sample/configs/prebid-config-with-wurfl.yaml b/sample/configs/prebid-config-with-wurfl.yaml index 55ccd4ffded..9a82d459195 100644 --- a/sample/configs/prebid-config-with-wurfl.yaml +++ b/sample/configs/prebid-config-with-wurfl.yaml @@ -34,6 +34,8 @@ gdpr: cache-dir: /var/tmp/vendor2 v3: cache-dir: /var/tmp/vendor3 + live: + startup-cache-dir: /var/tmp/vendor3 admin-endpoints: logging-changelevel: enabled: true diff --git a/sample/configs/prebid-config.yaml b/sample/configs/prebid-config.yaml index a964c645cc7..f969f25bd60 100644 --- a/sample/configs/prebid-config.yaml +++ b/sample/configs/prebid-config.yaml @@ -34,6 +34,8 @@ gdpr: cache-dir: /var/tmp/vendor2 v3: cache-dir: /var/tmp/vendor3 + live: + startup-cache-dir: /var/tmp/vendor3 admin-endpoints: logging-changelevel: enabled: true diff --git a/src/main/docker/application.yaml b/src/main/docker/application.yaml index 9765fc7ed39..a5e51ed5b4c 100644 --- a/src/main/docker/application.yaml +++ b/src/main/docker/application.yaml @@ -4,3 +4,5 @@ gdpr: cache-dir: /app/prebid-server/data/vendorlist-v2 v3: cache-dir: /app/prebid-server/data/vendorlist-v3 + live: + startup-cache-dir: /app/prebid-server/data/vendorlist-v3 diff --git a/src/main/java/org/prebid/server/metric/Metrics.java b/src/main/java/org/prebid/server/metric/Metrics.java index 372edb9a7df..c6e3394c807 100644 --- a/src/main/java/org/prebid/server/metric/Metrics.java +++ b/src/main/java/org/prebid/server/metric/Metrics.java @@ -554,6 +554,14 @@ public void updatePrivacyTcfVendorListFallbackMetric(int version) { updatePrivacyTcfVendorListMetric(version, MetricName.fallback); } + public void updatePrivacyTcfLiveVendorListOkMetric() { + privacy().tcf().liveVendorList().incCounter(MetricName.ok); + } + + public void updatePrivacyTcfLiveVendorListErrorMetric() { + privacy().tcf().liveVendorList().incCounter(MetricName.err); + } + private void updatePrivacyTcfVendorListMetric(int version, MetricName metricName) { final TcfMetrics tcfMetrics = privacy().tcf(); tcfMetrics.fromVersion(version).vendorList().incCounter(metricName); diff --git a/src/main/java/org/prebid/server/metric/TcfMetrics.java b/src/main/java/org/prebid/server/metric/TcfMetrics.java index 9fd5a811562..72c9a5cd4f6 100644 --- a/src/main/java/org/prebid/server/metric/TcfMetrics.java +++ b/src/main/java/org/prebid/server/metric/TcfMetrics.java @@ -16,6 +16,7 @@ class TcfMetrics extends UpdatableMetrics { private final TcfVersionMetrics tcfVersion1Metrics; private final TcfVersionMetrics tcfVersion2Metrics; + private final LiveVendorListMetrics liveVendorListMetrics; TcfMetrics(MetricRegistry metricRegistry, CounterType counterType, String prefix) { super( @@ -25,6 +26,7 @@ class TcfMetrics extends UpdatableMetrics { tcfVersion1Metrics = new TcfVersionMetrics(metricRegistry, counterType, createTcfPrefix(prefix), "v1"); tcfVersion2Metrics = new TcfVersionMetrics(metricRegistry, counterType, createTcfPrefix(prefix), "v2"); + liveVendorListMetrics = new LiveVendorListMetrics(metricRegistry, counterType, createTcfPrefix(prefix)); } TcfVersionMetrics fromVersion(int version) { @@ -35,6 +37,10 @@ TcfVersionMetrics fromVersion(int version) { }; } + LiveVendorListMetrics liveVendorList() { + return liveVendorListMetrics; + } + private static String createTcfPrefix(String prefix) { return prefix + ".tcf"; } @@ -87,4 +93,22 @@ private static Function nameCreator(String prefix) { return metricName -> "%s.%s".formatted(prefix, metricName); } } + + static class LiveVendorListMetrics extends UpdatableMetrics { + + LiveVendorListMetrics(MetricRegistry metricRegistry, CounterType counterType, String prefix) { + super( + metricRegistry, + counterType, + nameCreator(createLatestPrefix(prefix))); + } + + private static String createLatestPrefix(String prefix) { + return prefix + ".vendorlist.live"; + } + + private static Function nameCreator(String prefix) { + return metricName -> "%s.%s".formatted(prefix, metricName); + } + } } diff --git a/src/main/java/org/prebid/server/privacy/gdpr/Tcf2Service.java b/src/main/java/org/prebid/server/privacy/gdpr/Tcf2Service.java index 8d47b739426..6010ad950e2 100644 --- a/src/main/java/org/prebid/server/privacy/gdpr/Tcf2Service.java +++ b/src/main/java/org/prebid/server/privacy/gdpr/Tcf2Service.java @@ -12,6 +12,7 @@ import org.prebid.server.privacy.gdpr.model.VendorPermissionWithGvl; import org.prebid.server.privacy.gdpr.tcfstrategies.purpose.PurposeStrategy; import org.prebid.server.privacy.gdpr.tcfstrategies.specialfeature.SpecialFeaturesStrategy; +import org.prebid.server.privacy.gdpr.vendorlist.VendorListWrapper; import org.prebid.server.privacy.gdpr.vendorlist.VersionedVendorListService; import org.prebid.server.privacy.gdpr.vendorlist.proto.PurposeCode; import org.prebid.server.privacy.gdpr.vendorlist.proto.Vendor; @@ -114,7 +115,7 @@ private Future> permissionsForInternal(Collection processDowngradedSupportedPurposeStrategies( tcfConsent, - wrapWithGVL(vendorPermissionsByType, Collections.emptyMap()), + wrapWithGVL(vendorPermissionsByType, VendorListWrapper.EMPTY), mergedPurposes, mergedPurposeOneTreatmentInterpretation)) .map(ignored -> enforcePurpose4IfRequired(mergedPurposes, vendorPermissionsByType)) @@ -146,7 +147,7 @@ private static VendorPermissionsByType toVendorPermissionsByTy private static VendorPermissionsByType wrapWithGVL( VendorPermissionsByType vendorPermissionsByType, - Map vendorGvlPermissions) { + VendorListWrapper vendorGvlPermissions) { final List weakPermissions = vendorPermissionsByType.getWeakPermissions().stream() .map(vendorPermission -> wrapWithGVL(vendorPermission, vendorGvlPermissions)) @@ -161,7 +162,7 @@ private static VendorPermissionsByType wrapWithGVL( } private static VendorPermissionWithGvl wrapWithGVL(VendorPermission vendorPermission, - Map vendorGvlPermissions) { + VendorListWrapper vendorGvlPermissions) { final Integer vendorId = vendorPermission.getVendorId(); final Vendor vendorGvlByVendorId = Optional.ofNullable(vendorId) diff --git a/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/LiveVendorListService.java b/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/LiveVendorListService.java new file mode 100644 index 00000000000..49fb8e4e6cb --- /dev/null +++ b/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/LiveVendorListService.java @@ -0,0 +1,127 @@ +package org.prebid.server.privacy.gdpr.vendorlist; + +import io.vertx.core.Future; +import io.vertx.core.Vertx; +import lombok.Getter; +import org.prebid.server.exception.PreBidException; +import org.prebid.server.json.JacksonMapper; +import org.prebid.server.log.Logger; +import org.prebid.server.log.LoggerFactory; +import org.prebid.server.metric.Metrics; +import org.prebid.server.privacy.gdpr.vendorlist.proto.Vendor; +import org.prebid.server.privacy.gdpr.vendorlist.proto.VendorList; +import org.prebid.server.util.HttpUtil; +import org.prebid.server.vertx.Initializable; +import org.prebid.server.vertx.httpclient.HttpClient; +import org.prebid.server.vertx.httpclient.model.HttpClientResponse; + +import java.time.Clock; +import java.time.Instant; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +public class LiveVendorListService implements Initializable { + + private static final Logger logger = LoggerFactory.getLogger(LiveVendorListService.class); + + private final String cacheDir; + private final String liveGvlUrl; + private final long refreshPeriodMs; + private final int defaultTimeoutMs; + private final Vertx vertx; + private final HttpClient httpClient; + private final VendorListFileStore vendorListFileStore; + private final Metrics metrics; + private final JacksonMapper mapper; + private final Clock clock; + + @Getter + private volatile Set deletedVendorIds = Set.of(); + + public LiveVendorListService(String cacheDir, + String liveGvlUrl, + long refreshPeriodMs, + int defaultTimeoutMs, + Vertx vertx, + HttpClient httpClient, + VendorListFileStore vendorListFileStore, + Metrics metrics, + JacksonMapper mapper, + Clock clock) { + + this.cacheDir = Objects.requireNonNull(cacheDir); + this.liveGvlUrl = HttpUtil.validateUrl(Objects.requireNonNull(liveGvlUrl)); + this.refreshPeriodMs = refreshPeriodMs; + this.defaultTimeoutMs = defaultTimeoutMs; + this.vertx = Objects.requireNonNull(vertx); + this.httpClient = Objects.requireNonNull(httpClient); + this.vendorListFileStore = Objects.requireNonNull(vendorListFileStore); + this.metrics = Objects.requireNonNull(metrics); + this.mapper = Objects.requireNonNull(mapper); + this.clock = Objects.requireNonNull(clock); + } + + @Override + public Future initialize() { + initializeWithLatestCachedVersion(); + vertx.setPeriodic(0, refreshPeriodMs, ignored -> refresh()); + return Future.succeededFuture(); + } + + private void initializeWithLatestCachedVersion() { + vendorListFileStore.getLatestVendorListFromCache(cacheDir).ifPresent(vendorList -> { + saveDeletedVendorsFromVendorList(vendorList); + logger.info("Initialized live GVL from cache with version %d".formatted(vendorList.getVendorListVersion())); + }); + } + + void refresh() { + httpClient.get(liveGvlUrl, defaultTimeoutMs) + .map(this::processResponse) + .map(this::saveDeletedVendorsFromVendorList) + .otherwise(this::handleError); + } + + private Void saveDeletedVendorsFromVendorList(VendorList vendorList) { + updateDeletedVendorIds(extractDeletedVendorIds(vendorList)); + return null; + } + + private VendorList processResponse(HttpClientResponse response) { + final int statusCode = response.getStatusCode(); + if (statusCode != 200) { + throw new PreBidException("HTTP status code " + statusCode); + } + + final String body = response.getBody(); + final VendorList vendorList = VendorListUtil.parseVendorList(body, mapper); + + if (!VendorListUtil.vendorListIsValid(vendorList)) { + throw new PreBidException("Fetched vendor list parsed but has invalid data: " + body); + } + + return vendorList; + } + + Set extractDeletedVendorIds(VendorList vendorList) { + final Instant now = clock.instant(); + return vendorList.getVendors().values().stream() + .filter(vendor -> VendorListUtil.vendorIsDeletedAt(vendor, now)) + .map(Vendor::getId) + .filter(Objects::nonNull) + .collect(Collectors.toUnmodifiableSet()); + } + + private Void updateDeletedVendorIds(Set ids) { + deletedVendorIds = ids; + metrics.updatePrivacyTcfLiveVendorListOkMetric(); + return null; + } + + private Void handleError(Throwable exception) { + logger.warn("Error occurred while fetching live GVL", exception); + metrics.updatePrivacyTcfLiveVendorListErrorMetric(); + return null; + } +} diff --git a/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListFileStore.java b/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListFileStore.java new file mode 100644 index 00000000000..e02669c8e26 --- /dev/null +++ b/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListFileStore.java @@ -0,0 +1,124 @@ +package org.prebid.server.privacy.gdpr.vendorlist; + +import io.vertx.core.Future; +import io.vertx.core.buffer.Buffer; +import io.vertx.core.file.FileProps; +import io.vertx.core.file.FileSystem; +import io.vertx.core.file.FileSystemException; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.prebid.server.exception.PreBidException; +import org.prebid.server.json.JacksonMapper; +import org.prebid.server.log.ConditionalLogger; +import org.prebid.server.log.Logger; +import org.prebid.server.log.LoggerFactory; +import org.prebid.server.privacy.gdpr.vendorlist.proto.Vendor; +import org.prebid.server.privacy.gdpr.vendorlist.proto.VendorList; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Comparator; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +public class VendorListFileStore { + + private static final Logger logger = LoggerFactory.getLogger(VendorListFileStore.class); + private static final ConditionalLogger conditionalLogger = new ConditionalLogger(logger); + + private static final String JSON_SUFFIX = ".json"; + + private final double logSamplingRate; + private final FileSystem fileSystem; + private final JacksonMapper mapper; + + public VendorListFileStore(double logSamplingRate, + FileSystem fileSystem, + JacksonMapper mapper) { + + this.logSamplingRate = logSamplingRate; + this.fileSystem = Objects.requireNonNull(fileSystem); + this.mapper = Objects.requireNonNull(mapper); + } + + Map> createCacheFromDisk(String cacheDir) { + createAndCheckWritePermissionsForCacheDir(cacheDir); + final Map versionToFileContent = readFileSystemCache(cacheDir); + + final Map> cache = new ConcurrentHashMap<>(); + + for (Map.Entry versionAndFileContent : versionToFileContent.entrySet()) { + final VendorList vendorList = VendorListUtil.parseVendorList(versionAndFileContent.getValue(), mapper); + + cache.put(versionAndFileContent.getKey(), vendorList.getVendors()); + } + return cache; + } + + private void createAndCheckWritePermissionsForCacheDir(String cacheDir) { + final FileProps props = fileSystem.existsBlocking(cacheDir) ? fileSystem.propsBlocking(cacheDir) : null; + if (props == null || !props.isDirectory()) { + try { + fileSystem.mkdirsBlocking(cacheDir); + } catch (FileSystemException e) { + throw new PreBidException("Cannot create directory: " + cacheDir, e); + } + } else if (!Files.isWritable(Paths.get(cacheDir))) { + throw new PreBidException("No write permissions for directory: " + cacheDir); + } + } + + private Map readFileSystemCache(String cacheDir) { + return fileSystem.readDirBlocking(cacheDir).stream() + .filter(filepath -> filepath.endsWith(JSON_SUFFIX)) + .collect(Collectors.toMap( + VendorListFileStore::parseCachedFileVersion, + filename -> fileSystem.readFileBlocking(filename).toString())); + } + + Optional getLatestVendorListFromCache(String cacheDir) { + createAndCheckWritePermissionsForCacheDir(cacheDir); + return fileSystem.readDirBlocking(cacheDir).stream() + .filter(filepath -> filepath.endsWith(JSON_SUFFIX)) + .max(Comparator.comparing(VendorListFileStore::parseCachedFileVersion)) + .map(fileSystem::readFileBlocking) + .map(Buffer::toString) + .map(content -> VendorListUtil.parseVendorList(content, mapper)); + } + + private static Integer parseCachedFileVersion(String filepath) { + final String filename = new File(filepath).getName(); + final String filenameWithoutExtension = StringUtils.removeEnd(filename, JSON_SUFFIX); + return Integer.valueOf(filenameWithoutExtension); + } + + Future saveToFile(VendorListResult vendorListResult, String cacheDir, String generationVersion) { + final int version = vendorListResult.getVersion(); + final String filepath = new File(cacheDir, version + JSON_SUFFIX).getPath(); + + return fileSystem.writeFile(filepath, Buffer.buffer(vendorListResult.getVendorListAsString())) + .map(vendorListResult) + .onFailure(error -> conditionalLogger.error( + "Could not create new vendor list for version %s.%s, file: %s, trace: %s".formatted( + generationVersion, version, filepath, ExceptionUtils.getStackTrace(error.getCause())), + logSamplingRate)); + } + + Map readFallbackVendorList(String fallbackVendorListPath) { + if (StringUtils.isBlank(fallbackVendorListPath)) { + return null; + } + + final String vendorListContent = fileSystem.readFileBlocking(fallbackVendorListPath).toString(); + final VendorList vendorList = VendorListUtil.parseVendorList(vendorListContent, mapper); + if (!VendorListUtil.vendorListIsValid(vendorList)) { + throw new PreBidException("Fallback vendor list parsed but has invalid data: " + vendorListContent); + } + + return vendorList.getVendors(); + } +} diff --git a/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListResult.java b/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListResult.java new file mode 100644 index 00000000000..827300f90c2 --- /dev/null +++ b/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListResult.java @@ -0,0 +1,14 @@ +package org.prebid.server.privacy.gdpr.vendorlist; + +import lombok.Value; +import org.prebid.server.privacy.gdpr.vendorlist.proto.VendorList; + +@Value(staticConstructor = "of") +class VendorListResult { + + int version; + + String vendorListAsString; + + VendorList vendorList; +} diff --git a/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListService.java b/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListService.java index f04c491683f..fb5fe23932f 100644 --- a/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListService.java +++ b/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListService.java @@ -1,16 +1,8 @@ package org.prebid.server.privacy.gdpr.vendorlist; -import com.github.benmanes.caffeine.cache.Caffeine; import io.netty.handler.codec.http.HttpResponseStatus; import io.vertx.core.Future; import io.vertx.core.Vertx; -import io.vertx.core.buffer.Buffer; -import io.vertx.core.file.FileProps; -import io.vertx.core.file.FileSystem; -import io.vertx.core.file.FileSystemException; -import lombok.Value; -import org.apache.commons.collections4.MapUtils; -import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.prebid.server.exception.PreBidException; import org.prebid.server.json.JacksonMapper; @@ -24,16 +16,10 @@ import org.prebid.server.vertx.httpclient.HttpClient; import org.prebid.server.vertx.httpclient.model.HttpClientResponse; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.Collection; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; /** * Works with GDPR Vendor List. @@ -54,7 +40,6 @@ public class VendorListService { private static final int TCF_VERSION = 2; - private static final String JSON_SUFFIX = ".json"; private static final String VERSION_PLACEHOLDER = "VERSION"; private final double logSamplingRate; @@ -64,21 +49,18 @@ public class VendorListService { private final long refreshMissingListPeriodMs; private final boolean deprecated; private final Vertx vertx; - private final FileSystem fileSystem; private final HttpClient httpClient; private final Metrics metrics; private final String generationVersion; - protected final JacksonMapper mapper; + private final VendorListFetchThrottler fetchThrottler; + private final VendorListFileStore vendorListFileStore; + private final JacksonMapper mapper; - /** - * This is memory/performance optimized model slice: - * map of vendor list version -> map of vendor ID -> Vendors - */ + // Map of vendor list version -> map of vendor ID -> Vendors private final Map> cache; private final Map fallbackVendorList; private final Set versionsToFallback; - private final VendorListFetchThrottler fetchThrottler; public VendorListService(double logSamplingRate, String cacheDir, @@ -88,12 +70,12 @@ public VendorListService(double logSamplingRate, boolean deprecated, String fallbackVendorListPath, Vertx vertx, - FileSystem fileSystem, HttpClient httpClient, Metrics metrics, String generationVersion, - JacksonMapper mapper, - VendorListFetchThrottler fetchThrottler) { + VendorListFetchThrottler fetchThrottler, + VendorListFileStore vendorListFileStore, + JacksonMapper mapper) { this.logSamplingRate = logSamplingRate; this.cacheDir = Objects.requireNonNull(cacheDir); @@ -103,17 +85,15 @@ public VendorListService(double logSamplingRate, this.deprecated = deprecated; this.generationVersion = generationVersion; this.vertx = Objects.requireNonNull(vertx); - this.fileSystem = Objects.requireNonNull(fileSystem); this.httpClient = Objects.requireNonNull(httpClient); this.metrics = Objects.requireNonNull(metrics); - this.mapper = Objects.requireNonNull(mapper); this.fetchThrottler = Objects.requireNonNull(fetchThrottler); + this.vendorListFileStore = Objects.requireNonNull(vendorListFileStore); + this.mapper = Objects.requireNonNull(mapper); - createAndCheckWritePermissionsFor(fileSystem, cacheDir); - cache = Objects.requireNonNull(createCache(fileSystem, cacheDir)); + cache = Objects.requireNonNull(vendorListFileStore.createCacheFromDisk(cacheDir)); - fallbackVendorList = StringUtils.isNotBlank(fallbackVendorListPath) - ? readFallbackVendorList(fallbackVendorListPath) : null; + fallbackVendorList = vendorListFileStore.readFallbackVendorList(fallbackVendorListPath); if (deprecated) { validateFallbackVendorListIfDeprecatedVersion(); } @@ -161,50 +141,6 @@ public Future> forVersion(int version) { .formatted(tcf, generationVersion, version)); } - /** - * Creates vendorList object from string content or throw {@link PreBidException}. - */ - private VendorList toVendorList(String content) { - try { - return mapper.mapper().readValue(content, VendorList.class); - } catch (IOException e) { - final String message = "Cannot parse vendor list from: " + content; - - logger.error(message, e); - throw new PreBidException(message, e); - } - } - - /** - * Returns a Map of vendor id to Vendors. - */ - private Map filterVendorIdToVendors(VendorList vendorList) { - return vendorList.getVendors().entrySet().stream() - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - } - - /** - * Verifies all significant fields of given {@link VendorList} object. - */ - private boolean isValid(VendorList vendorList) { - return vendorList.getVendorListVersion() != null - && vendorList.getLastUpdated() != null - && MapUtils.isNotEmpty(vendorList.getVendors()) - && isValidVendors(vendorList.getVendors().values()); - } - - private static boolean isValidVendors(Collection vendors) { - return vendors.stream() - .allMatch(vendor -> vendor != null - && vendor.getId() != null - && vendor.getPurposes() != null - && vendor.getLegIntPurposes() != null - && vendor.getFlexiblePurposes() != null - && vendor.getSpecialPurposes() != null - && vendor.getFeatures() != null - && vendor.getSpecialFeatures() != null); - } - /** * Returns the version of TCF which {@link VendorListService} implementation deals with. */ @@ -212,62 +148,6 @@ private int getTcfVersion() { return TCF_VERSION; } - /** - * Creates if doesn't exists and checks write permissions for the given directory. - */ - private static void createAndCheckWritePermissionsFor(FileSystem fileSystem, String dir) { - final FileProps props = fileSystem.existsBlocking(dir) ? fileSystem.propsBlocking(dir) : null; - if (props == null || !props.isDirectory()) { - try { - fileSystem.mkdirsBlocking(dir); - } catch (FileSystemException e) { - throw new PreBidException("Cannot create directory: " + dir, e); - } - } else if (!Files.isWritable(Paths.get(dir))) { - throw new PreBidException("No write permissions for directory: " + dir); - } - } - - /** - * Creates the cache from previously downloaded vendor lists. - */ - private Map> createCache(FileSystem fileSystem, String cacheDir) { - final Map versionToFileContent = readFileSystemCache(fileSystem, cacheDir); - - final Map> cache = Caffeine.newBuilder() - .>build() - .asMap(); - - for (Map.Entry versionAndFileContent : versionToFileContent.entrySet()) { - final VendorList vendorList = toVendorList(versionAndFileContent.getValue()); - final Map vendorIdToVendors = filterVendorIdToVendors(vendorList); - - cache.put(Integer.valueOf(versionAndFileContent.getKey()), vendorIdToVendors); - } - return cache; - } - - /** - * Reads files with .json extension in configured directory and - * returns a {@link Map} where key is a file name without .json extension and value is file content. - */ - private Map readFileSystemCache(FileSystem fileSystem, String dir) { - return fileSystem.readDirBlocking(dir).stream() - .filter(filepath -> filepath.endsWith(JSON_SUFFIX)) - .collect(Collectors.toMap(filepath -> StringUtils.removeEnd(new File(filepath).getName(), JSON_SUFFIX), - filename -> fileSystem.readFileBlocking(filename).toString())); - } - - private Map readFallbackVendorList(String fallbackVendorListPath) { - final String vendorListContent = fileSystem.readFileBlocking(fallbackVendorListPath).toString(); - final VendorList vendorList = toVendorList(vendorListContent); - if (!isValid(vendorList)) { - throw new PreBidException("Fallback vendor list parsed but has invalid data: " + vendorListContent); - } - - return filterVendorIdToVendors(vendorList); - } - private boolean shouldFallback(int version) { return deprecated || (versionsToFallback != null && versionsToFallback.contains(version)); } @@ -290,7 +170,7 @@ private void fetchNewVendorListFor(int version) { * and creates {@link Future} with {@link VendorListResult} from body content * or throws {@link PreBidException} in case of errors. */ - private VendorListResult processResponse(HttpClientResponse response, int version) { + private VendorListResult processResponse(HttpClientResponse response, int version) { final int statusCode = response.getStatusCode(); if (statusCode == HttpResponseStatus.NOT_FOUND.code()) { @@ -301,11 +181,11 @@ private VendorListResult processResponse(HttpClientResponse response } final String body = response.getBody(); - final VendorList vendorList = toVendorList(body); + final VendorList vendorList = VendorListUtil.parseVendorList(body, mapper); // we should care on obtained vendor list, because it'll be saved and never be downloaded again // while application is running - if (!isValid(vendorList)) { + if (!VendorListUtil.vendorListIsValid(vendorList)) { throw new PreBidException("Fetched vendor list parsed but has invalid data: " + body); } @@ -313,25 +193,14 @@ private VendorListResult processResponse(HttpClientResponse response return VendorListResult.of(version, body, vendorList); } - /** - * Saves given vendor list on file system. - */ - private Future> saveToFile(VendorListResult vendorListResult) { - final int version = vendorListResult.getVersion(); - final String filepath = new File(cacheDir, version + JSON_SUFFIX).getPath(); - - return fileSystem.writeFile(filepath, Buffer.buffer(vendorListResult.getVendorListAsString())) - .map(vendorListResult) - .onFailure(error -> conditionalLogger.error( - "Could not create new vendor list for version %s.%s, file: %s, trace: %s".formatted( - generationVersion, version, filepath, ExceptionUtils.getStackTrace(error.getCause())), - logSamplingRate)); + private Future saveToFile(VendorListResult vendorListResult) { + return vendorListFileStore.saveToFile(vendorListResult, cacheDir, generationVersion); } - private Void updateCache(VendorListResult vendorListResult) { + private Void updateCache(VendorListResult vendorListResult) { final int version = vendorListResult.getVersion(); - cache.put(version, filterVendorIdToVendors(vendorListResult.getVendorList())); + cache.put(version, vendorListResult.getVendorList().getVendors()); final int tcf = getTcfVersion(); @@ -387,16 +256,6 @@ private void stopUsingFallbackForVersion(int version) { versionsToFallback.remove(version); } - @Value(staticConstructor = "of") - private static class VendorListResult { - - int version; - - String vendorListAsString; - - T vendorList; - } - private static class MissingVendorListException extends RuntimeException { MissingVendorListException(String message) { diff --git a/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListUtil.java b/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListUtil.java new file mode 100644 index 00000000000..371a90e1c55 --- /dev/null +++ b/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListUtil.java @@ -0,0 +1,56 @@ +package org.prebid.server.privacy.gdpr.vendorlist; + +import org.apache.commons.collections4.MapUtils; +import org.prebid.server.exception.PreBidException; +import org.prebid.server.json.JacksonMapper; +import org.prebid.server.log.Logger; +import org.prebid.server.log.LoggerFactory; +import org.prebid.server.privacy.gdpr.vendorlist.proto.Vendor; +import org.prebid.server.privacy.gdpr.vendorlist.proto.VendorList; + +import java.io.IOException; +import java.time.Instant; +import java.util.Collection; + +public class VendorListUtil { + + private static final Logger logger = LoggerFactory.getLogger(VendorListUtil.class); + + private VendorListUtil() { + } + + public static VendorList parseVendorList(String content, JacksonMapper mapper) { + try { + return mapper.mapper().readValue(content, VendorList.class); + } catch (IOException e) { + final String message = "Cannot parse vendor list from: " + content; + + logger.error(message, e); + throw new PreBidException(message, e); + } + } + + public static boolean vendorListIsValid(VendorList vendorList) { + return vendorList.getVendorListVersion() != null + && vendorList.getLastUpdated() != null + && MapUtils.isNotEmpty(vendorList.getVendors()) + && vendorsAreValid(vendorList.getVendors().values()); + } + + private static boolean vendorsAreValid(Collection vendors) { + return vendors.stream() + .allMatch(vendor -> vendor != null + && vendor.getId() != null + && vendor.getPurposes() != null + && vendor.getLegIntPurposes() != null + && vendor.getFlexiblePurposes() != null + && vendor.getSpecialPurposes() != null + && vendor.getFeatures() != null + && vendor.getSpecialFeatures() != null); + } + + public static boolean vendorIsDeletedAt(Vendor vendor, Instant now) { + final Instant deletedDate = vendor.getDeletedDate(); + return deletedDate != null && deletedDate.isBefore(now); + } +} diff --git a/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListWrapper.java b/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListWrapper.java new file mode 100644 index 00000000000..64ce79352b5 --- /dev/null +++ b/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListWrapper.java @@ -0,0 +1,33 @@ +package org.prebid.server.privacy.gdpr.vendorlist; + +import lombok.AllArgsConstructor; +import org.prebid.server.privacy.gdpr.vendorlist.proto.Vendor; + +import java.time.Instant; +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +// The purpose of this wrapper class is to avoid filtering the whole vendor list for deleted vendors +// TODO: move filtering logic to vendor list service +@AllArgsConstructor(staticName = "of") +public class VendorListWrapper { + + public static final VendorListWrapper EMPTY = VendorListWrapper.of( + Collections.emptyMap(), Collections.emptySet(), Instant.EPOCH); + + private final Map vendorList; + private final Set deletedVendorIds; + private final Instant timestamp; + + public Vendor get(Integer key) { + final Vendor vendor = vendorList.get(key); + return isRetained(key, vendor) ? vendor : null; + } + + private boolean isRetained(Integer id, Vendor vendor) { + return vendor != null + && !VendorListUtil.vendorIsDeletedAt(vendor, timestamp) + && !deletedVendorIds.contains(id); + } +} diff --git a/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VersionedVendorListService.java b/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VersionedVendorListService.java index 5e261d9b6b4..0f0a63073ca 100644 --- a/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VersionedVendorListService.java +++ b/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/VersionedVendorListService.java @@ -4,6 +4,7 @@ import io.vertx.core.Future; import org.prebid.server.privacy.gdpr.vendorlist.proto.Vendor; +import java.time.Clock; import java.util.Map; import java.util.Objects; @@ -11,18 +12,29 @@ public class VersionedVendorListService { private final VendorListService vendorListServiceV2; private final VendorListService vendorListServiceV3; + private final LiveVendorListService liveVendorListService; + private final Clock clock; + + public VersionedVendorListService(VendorListService vendorListServiceV2, + VendorListService vendorListServiceV3, + LiveVendorListService liveVendorListService, + Clock clock) { - public VersionedVendorListService(VendorListService vendorListServiceV2, VendorListService vendorListServiceV3) { this.vendorListServiceV2 = Objects.requireNonNull(vendorListServiceV2); this.vendorListServiceV3 = Objects.requireNonNull(vendorListServiceV3); + this.liveVendorListService = Objects.requireNonNull(liveVendorListService); + this.clock = Objects.requireNonNull(clock); } - public Future> forConsent(TCString consent) { + public Future forConsent(TCString consent) { final int tcfPolicyVersion = consent.getTcfPolicyVersion(); final int vendorListVersion = consent.getVendorListVersion(); - return tcfPolicyVersion < 4 + final Future> vendorListFuture = tcfPolicyVersion < 4 ? vendorListServiceV2.forVersion(vendorListVersion) : vendorListServiceV3.forVersion(vendorListVersion); + + return vendorListFuture.map(vendors -> + VendorListWrapper.of(vendors, liveVendorListService.getDeletedVendorIds(), clock.instant())); } } diff --git a/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/proto/Vendor.java b/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/proto/Vendor.java index 6bb2be9dddb..336a5d4cdae 100644 --- a/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/proto/Vendor.java +++ b/src/main/java/org/prebid/server/privacy/gdpr/vendorlist/proto/Vendor.java @@ -6,6 +6,7 @@ import lombok.Data; import lombok.NoArgsConstructor; +import java.time.Instant; import java.util.EnumSet; @AllArgsConstructor @@ -16,6 +17,9 @@ public class Vendor { Integer id; + @JsonProperty("deletedDate") + Instant deletedDate; + EnumSet purposes; @JsonProperty("legIntPurposes") diff --git a/src/main/java/org/prebid/server/spring/config/PrivacyServiceConfiguration.java b/src/main/java/org/prebid/server/spring/config/PrivacyServiceConfiguration.java index b8175828c3b..579dbda2fa6 100644 --- a/src/main/java/org/prebid/server/spring/config/PrivacyServiceConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/PrivacyServiceConfiguration.java @@ -37,7 +37,9 @@ import org.prebid.server.privacy.gdpr.tcfstrategies.purpose.typestrategies.PurposeTwoBasicEnforcePurposeStrategy; import org.prebid.server.privacy.gdpr.tcfstrategies.specialfeature.SpecialFeaturesOneStrategy; import org.prebid.server.privacy.gdpr.tcfstrategies.specialfeature.SpecialFeaturesStrategy; +import org.prebid.server.privacy.gdpr.vendorlist.LiveVendorListService; import org.prebid.server.privacy.gdpr.vendorlist.VendorListFetchThrottler; +import org.prebid.server.privacy.gdpr.vendorlist.VendorListFileStore; import org.prebid.server.privacy.gdpr.vendorlist.VendorListService; import org.prebid.server.privacy.gdpr.vendorlist.VersionedVendorListService; import org.prebid.server.settings.model.GdprConfig; @@ -65,6 +67,15 @@ @Configuration public class PrivacyServiceConfiguration { + @Bean + VendorListFileStore vendorListFileStore( + @Value("${logging.sampling-rate:0.01}") double logSamplingRate, + FileSystem fileSystem, + JacksonMapper mapper) { + + return new VendorListFileStore(logSamplingRate, fileSystem, mapper); + } + @Bean VendorListService vendorListServiceV2( @Value("${logging.sampling-rate:0.01}") double logSamplingRate, @@ -72,9 +83,9 @@ VendorListService vendorListServiceV2( VendorListServiceConfigurationProperties vendorListServiceV2Properties, Vertx vertx, Clock clock, - FileSystem fileSystem, HttpClient httpClient, Metrics metrics, + VendorListFileStore vendorListFileStore, JacksonMapper mapper) { return new VendorListService( @@ -86,12 +97,12 @@ VendorListService vendorListServiceV2( vendorListServiceV2Properties.getDeprecated(), vendorListServiceV2Properties.getFallbackVendorListPath(), vertx, - fileSystem, httpClient, metrics, "v2", - mapper, - new VendorListFetchThrottler(vendorListServiceV2Properties.getRetryPolicy().toPolicy(), clock)); + new VendorListFetchThrottler(vendorListServiceV2Properties.getRetryPolicy().toPolicy(), clock), + vendorListFileStore, + mapper); } @Bean @@ -107,9 +118,9 @@ VendorListService vendorListServiceV3( VendorListServiceConfigurationProperties vendorListServiceV3Properties, Vertx vertx, Clock clock, - FileSystem fileSystem, HttpClient httpClient, Metrics metrics, + VendorListFileStore vendorListFileStore, JacksonMapper mapper) { return new VendorListService( @@ -121,12 +132,12 @@ VendorListService vendorListServiceV3( vendorListServiceV3Properties.getDeprecated(), vendorListServiceV3Properties.getFallbackVendorListPath(), vertx, - fileSystem, httpClient, metrics, "v3", - mapper, - new VendorListFetchThrottler(vendorListServiceV3Properties.getRetryPolicy().toPolicy(), clock)); + new VendorListFetchThrottler(vendorListServiceV3Properties.getRetryPolicy().toPolicy(), clock), + vendorListFileStore, + mapper); } @Bean @@ -135,11 +146,40 @@ VendorListServiceConfigurationProperties vendorListServiceV3Properties() { return new VendorListServiceConfigurationProperties(); } + @Bean + LiveVendorListService liveVendorListService( + @Value("${gdpr.vendorlist.live.startup-cache-dir}") String startupCacheDir, + @Value("${gdpr.vendorlist.live.url}") String liveGvlUrl, + @Value("${gdpr.vendorlist.live.refresh-period-ms}") long refreshPeriodMs, + @Value("${gdpr.vendorlist.default-timeout-ms}") int defaultTimeoutMs, + Vertx vertx, + HttpClient httpClient, + VendorListFileStore vendorListFileStore, + Metrics metrics, + JacksonMapper mapper, + Clock clock) { + + return new LiveVendorListService( + startupCacheDir, + liveGvlUrl, + refreshPeriodMs, + defaultTimeoutMs, + vertx, + httpClient, + vendorListFileStore, + metrics, + mapper, + clock); + } + @Bean VersionedVendorListService versionedVendorListService(VendorListService vendorListServiceV2, - VendorListService vendorListServiceV3) { + VendorListService vendorListServiceV3, + LiveVendorListService liveVendorListService, + Clock clock) { - return new VersionedVendorListService(vendorListServiceV2, vendorListServiceV3); + return new VersionedVendorListService( + vendorListServiceV2, vendorListServiceV3, liveVendorListService, clock); } @Bean diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 1422ed73353..4439533ddc7 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -229,6 +229,9 @@ gdpr: max-delay-millis: 120000 factor: 1.1 jitter: 0.2 + live: + url: https://vendor-list.consensu.org/v3/vendor-list.json + refresh-period-ms: 86400000 purposes: p1: enforce-purpose: full diff --git a/src/main/resources/metrics-config/prometheus-labels.yaml b/src/main/resources/metrics-config/prometheus-labels.yaml index b40139d6a8a..162be432f9d 100644 --- a/src/main/resources/metrics-config/prometheus-labels.yaml +++ b/src/main/resources/metrics-config/prometheus-labels.yaml @@ -85,6 +85,10 @@ mappers: labels: tcf: ${0} status: ${1} + - match: privacy.tcf.vendorlist.live.* + name: privacy.tcf.vendorlist.live + labels: + status: ${0} - match: privacy.tcf.*.* name: privacy.tcf.${1} labels: diff --git a/src/test/groovy/org/prebid/server/functional/model/mock/services/vendorlist/VendorListResponse.groovy b/src/test/groovy/org/prebid/server/functional/model/mock/services/vendorlist/VendorListResponse.groovy index d44755978e4..9e54f4ce7e6 100644 --- a/src/test/groovy/org/prebid/server/functional/model/mock/services/vendorlist/VendorListResponse.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/mock/services/vendorlist/VendorListResponse.groovy @@ -34,6 +34,7 @@ class VendorListResponse { List features List specialFeatures String policyUrl + ZonedDateTime deletedDate Overflow overflow String cookieMaxAgeSeconds Boolean usesCookies @@ -41,9 +42,9 @@ class VendorListResponse { Boolean usesNonCookieAccess Boolean deviceStorageDisclosureUrl - static Vendor getDefaultVendor(int id) { + static Vendor getDefaultVendor(int vendorId) { new Vendor().tap { - it.id = id + it.id = vendorId it.name = PBSUtils.randomString it.purposes = [1, 3, 4, 5] it.legIntPurposes = [2, 7, 10] diff --git a/src/test/groovy/org/prebid/server/functional/service/PrebidServerService.groovy b/src/test/groovy/org/prebid/server/functional/service/PrebidServerService.groovy index 249d6fa3f13..2e0d0765a0f 100644 --- a/src/test/groovy/org/prebid/server/functional/service/PrebidServerService.groovy +++ b/src/test/groovy/org/prebid/server/functional/service/PrebidServerService.groovy @@ -448,6 +448,15 @@ class PrebidServerService implements ObjectMapperWrapper { } } + Boolean isMetricFilled(String metricName) { + try { + PBSUtils.waitUntil({ this.sendCollectedMetricsRequest()[metricName] != 0 }) + true + } catch (IllegalStateException ignored) { + false + } + } + Boolean isContainMetricByValue(String value) { try { PBSUtils.waitUntil({ sendInfluxMetricsRequest()[value] != null }) diff --git a/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/VendorList.groovy b/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/VendorList.groovy index 343a118f53a..29b0060af27 100644 --- a/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/VendorList.groovy +++ b/src/test/groovy/org/prebid/server/functional/testcontainers/scaffolding/VendorList.groovy @@ -4,7 +4,7 @@ import org.mockserver.matchers.TimeToLive import org.mockserver.matchers.Times import org.mockserver.model.Delay import org.mockserver.model.HttpRequest -import org.mockserver.model.HttpResponse +import org.prebid.server.functional.util.privacy.TcfConsent import org.testcontainers.containers.MockServerContainer import static org.mockserver.model.HttpRequest.request @@ -20,10 +20,13 @@ import static org.prebid.server.functional.util.privacy.TcfConsent.TcfPolicyVers class VendorList extends NetworkScaffolding { - private static final String VENDOR_LIST_ENDPOINT = "/v{TCF_POLICY}/vendor-list.json" + private static final String ENDPOINT_TEMPLATE = "/v{TCF_POLICY}/{FILE_NAME}" - VendorList(MockServerContainer mockServerContainer) { - super(mockServerContainer, VENDOR_LIST_ENDPOINT) + private final String fileName + + VendorList(MockServerContainer mockServerContainer, String fileName = "vendor-list.json") { + super(mockServerContainer, ENDPOINT_TEMPLATE.replace("{FILE_NAME}", fileName)) + this.fileName = fileName } @Override @@ -33,29 +36,40 @@ class VendorList extends NetworkScaffolding { @Override protected HttpRequest getRequest() { - request().withPath(VENDOR_LIST_ENDPOINT) + request().withPath(endpoint) } @Override void reset() { - TcfPolicyVersion.values().each { version -> super.reset("/v${version.vendorListVersion}/vendor-list.json") } + TcfPolicyVersion.values().each { + super.reset("/v${it.vendorListVersion}/${fileName}") + } } void setResponse(TcfPolicyVersion tcfPolicyVersion = TCF_POLICY_V2, Delay delay = null, - Map vendors = [(GENERIC_VENDOR_ID): Vendor.getDefaultVendor(GENERIC_VENDOR_ID)]) { + Map vendors = [(GENERIC_VENDOR_ID): Vendor.getDefaultVendor(GENERIC_VENDOR_ID)], + Integer vendorListVersion = TcfConsent.VENDOR_LIST_VERSION, + Times times = Times.unlimited()) { + def prepareEndpoint = endpoint.replace("{TCF_POLICY}", tcfPolicyVersion.vendorListVersion.toString()) def prepareEncodeResponseBody = encode(defaultVendorListResponse.tap { it.tcfPolicyVersion = tcfPolicyVersion.vendorListVersion it.vendors = vendors + it.vendorListVersion = vendorListVersion it.gvlSpecificationVersion = tcfPolicyVersion >= TcfPolicyVersion.TCF_POLICY_V4 ? V3 : V2 }) - mockServerClient.when(request().withPath(prepareEndpoint), Times.unlimited(), TimeToLive.unlimited(), -10) - .respond { request -> - request.withPath(endpoint) - ? response().withStatusCode(OK_200.code()).withDelay(delay).withBody(prepareEncodeResponseBody) - : HttpResponse.notFoundResponse() - } + def mockResponse = response() + .withStatusCode(OK_200.code()) + .withBody(prepareEncodeResponseBody) + + delay?.with { + mockResponse.withDelay(it) + } + + mockServerClient + .when(request().withPath(prepareEndpoint), times, TimeToLive.unlimited(), -10) + .respond(mockResponse) } } diff --git a/src/test/groovy/org/prebid/server/functional/tests/BidderFieldDisplayBehaviorSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/BidderFieldDisplayBehaviorSpec.groovy index bdf0f633626..6acd01d09cd 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/BidderFieldDisplayBehaviorSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/BidderFieldDisplayBehaviorSpec.groovy @@ -21,6 +21,7 @@ import org.prebid.server.functional.model.request.auction.BidderConfigOrtb import org.prebid.server.functional.model.request.auction.ConsentedProvidersSettings import org.prebid.server.functional.model.request.auction.Device import org.prebid.server.functional.model.request.auction.DeviceExt +import org.prebid.server.functional.model.request.auction.DevicePrebid import org.prebid.server.functional.model.request.auction.Dooh import org.prebid.server.functional.model.request.auction.DoohExt import org.prebid.server.functional.model.request.auction.EidPermission @@ -28,9 +29,7 @@ import org.prebid.server.functional.model.request.auction.ExtPrebidBidderConfig import org.prebid.server.functional.model.request.auction.ExtRequestPrebidData import org.prebid.server.functional.model.request.auction.Interstitial import org.prebid.server.functional.model.request.auction.MultiBid -import org.prebid.server.functional.model.request.auction.PaaFormat import org.prebid.server.functional.model.request.auction.PrebidCache -import org.prebid.server.functional.model.request.auction.DevicePrebid import org.prebid.server.functional.model.request.auction.PrebidCurrency import org.prebid.server.functional.model.request.auction.Renderer import org.prebid.server.functional.model.request.auction.RendererData @@ -47,9 +46,9 @@ import org.prebid.server.functional.util.PBSUtils import static org.prebid.server.functional.model.Currency.USD import static org.prebid.server.functional.model.bidder.BidderName.ALIAS +import static org.prebid.server.functional.model.bidder.BidderName.GENERIC import static org.prebid.server.functional.model.bidder.BidderName.OPENX import static org.prebid.server.functional.model.bidder.BidderName.RUBICON -import static org.prebid.server.functional.model.bidder.BidderName.GENERIC import static org.prebid.server.functional.model.mock.services.currencyconversion.CurrencyConversionRatesResponse.defaultConversionRates import static org.prebid.server.functional.model.request.auction.AdjustmentType.MULTIPLIER import static org.prebid.server.functional.model.request.auction.BidAdjustmentMediaType.BANNER @@ -323,20 +322,6 @@ class BidderFieldDisplayBehaviorSpec extends BaseSpec { } } - def "PBS auction should pass ext.prebid.paaformat to bidder request when paaformat specified"() { - given: "Default bid request" - def bidRequest = BidRequest.defaultBidRequest.tap { - ext.prebid.paaFormat = PaaFormat.ORIGINAL - } - - when: "PBS processes auction request" - defaultPbsService.sendAuctionRequest(bidRequest) - - then: "Bidder request should contain paaFormat value same in request" - def bidderRequest = bidder.getBidderRequest(bidRequest.id) - assert bidderRequest.ext.prebid.paaFormat == bidRequest.ext.prebid.paaFormat - } - def "PBS auction shouldn't pass ext.prebid.kvps to bidder request when kvps specified"() { given: "Default bid request with kvps" def bidRequest = BidRequest.defaultBidRequest.tap { diff --git a/src/test/groovy/org/prebid/server/functional/tests/privacy/PrivacyBaseSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/privacy/PrivacyBaseSpec.groovy index 19f9798a9e8..79ed11c5856 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/privacy/PrivacyBaseSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/privacy/PrivacyBaseSpec.groovy @@ -8,10 +8,8 @@ import org.prebid.server.functional.model.config.AccountDsaConfig import org.prebid.server.functional.model.config.AccountGdprConfig import org.prebid.server.functional.model.config.AccountGppConfig import org.prebid.server.functional.model.config.AccountPrivacyConfig -import org.prebid.server.functional.model.config.Purpose import org.prebid.server.functional.model.db.Account import org.prebid.server.functional.model.mock.services.vendorlist.VendorListResponse -import org.prebid.server.functional.model.privacy.EnforcementRequirement import org.prebid.server.functional.model.privacy.gpp.GppDataActivity import org.prebid.server.functional.model.privacy.gpp.UsCaliforniaV1ChildSensitiveData import org.prebid.server.functional.model.privacy.gpp.UsCaliforniaV1SensitiveData @@ -55,12 +53,9 @@ import org.prebid.server.functional.util.privacy.gpp.v1.UsVaV1Consent import static org.prebid.server.functional.model.bidder.BidderName.GENERIC import static org.prebid.server.functional.model.bidder.BidderName.OPENX -import static org.prebid.server.functional.model.config.PurposeEnforcement.BASIC -import static org.prebid.server.functional.model.config.PurposeEnforcement.FULL -import static org.prebid.server.functional.model.config.PurposeEnforcement.NO import static org.prebid.server.functional.model.mock.services.vendorlist.VendorListResponse.getDefaultVendorListResponse -import static org.prebid.server.functional.model.pricefloors.Country.USA import static org.prebid.server.functional.model.pricefloors.Country.BULGARIA +import static org.prebid.server.functional.model.pricefloors.Country.USA import static org.prebid.server.functional.model.request.GppSectionId.US_CA_V1 import static org.prebid.server.functional.model.request.GppSectionId.US_CO_V1 import static org.prebid.server.functional.model.request.GppSectionId.US_CT_V1 @@ -74,10 +69,6 @@ import static org.prebid.server.functional.model.request.auction.TraceLevel.VERB import static org.prebid.server.functional.model.response.cookiesync.UserSyncInfo.Type.REDIRECT import static org.prebid.server.functional.testcontainers.Dependencies.getNetworkServiceContainer import static org.prebid.server.functional.util.privacy.TcfConsent.GENERIC_VENDOR_ID -import static org.prebid.server.functional.util.privacy.TcfConsent.PurposeId.BASIC_ADS -import static org.prebid.server.functional.util.privacy.TcfConsent.RestrictionType.REQUIRE_CONSENT -import static org.prebid.server.functional.util.privacy.TcfConsent.RestrictionType.REQUIRE_LEGITIMATE_INTEREST -import static org.prebid.server.functional.util.privacy.TcfConsent.RestrictionType.UNDEFINED import static org.prebid.server.functional.util.privacy.TcfConsent.TcfPolicyVersion.TCF_POLICY_V2 import static org.prebid.server.functional.util.privacy.model.State.ALABAMA @@ -89,7 +80,7 @@ abstract class PrivacyBaseSpec extends BaseSpec { "adapters.${GENERIC.value}.ortb-version" : "2.6"] private static final Map OPENX_CONFIG = ["adaptrs.${OPENX.value}.enabled" : "true", "adapters.${OPENX.value}.usersync.cookie-family-name": OPENX.value, - "adapters.${OPENX}.ortb-version" : "2.6", + "adapters.${OPENX.value}.ortb-version" : "2.6", "adapters.${OPENX.value}.endpoint" : "$networkServiceContainer.rootUri/auction".toString(), "adapters.${OPENX.value}.enabled" : 'true'] protected static final Map GDPR_VENDOR_LIST_CONFIG = ["gdpr.vendorlist.v2.http-endpoint-template": "$networkServiceContainer.rootUri/v2/vendor-list.json".toString(), diff --git a/src/test/groovy/org/prebid/server/functional/tests/privacy/gdpr/GdprAuctionSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/privacy/gdpr/GdprAuctionSpec.groovy index 21abcb59c6b..545355d3efd 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/privacy/gdpr/GdprAuctionSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/privacy/gdpr/GdprAuctionSpec.groovy @@ -1,5 +1,6 @@ package org.prebid.server.functional.tests.privacy.gdpr +import org.mockserver.matchers.Times import org.mockserver.model.Delay import org.prebid.server.functional.model.ChannelType import org.prebid.server.functional.model.config.AccountGdprConfig @@ -7,25 +8,31 @@ import org.prebid.server.functional.model.config.AccountMetricsConfig import org.prebid.server.functional.model.config.AccountMetricsVerbosityLevel import org.prebid.server.functional.model.config.PurposeConfig import org.prebid.server.functional.model.config.PurposeEnforcement +import org.prebid.server.functional.model.mock.services.vendorlist.VendorListResponse import org.prebid.server.functional.model.pricefloors.Country +import org.prebid.server.functional.model.privacy.EnforcementRequirement import org.prebid.server.functional.model.request.Channel import org.prebid.server.functional.model.request.auction.DistributionChannel import org.prebid.server.functional.model.request.auction.Regs import org.prebid.server.functional.model.request.auction.RegsExt import org.prebid.server.functional.model.response.auction.ErrorType +import org.prebid.server.functional.model.response.auction.NoBidResponse +import org.prebid.server.functional.service.PrebidServerService +import org.prebid.server.functional.testcontainers.scaffolding.VendorList import org.prebid.server.functional.tests.privacy.PrivacyBaseSpec import org.prebid.server.functional.util.PBSUtils import org.prebid.server.functional.util.privacy.BogusConsent import org.prebid.server.functional.util.privacy.TcfConsent +import org.prebid.server.functional.util.privacy.TcfUtils import org.prebid.server.functional.util.privacy.VendorListConsent import spock.lang.PendingFeature import java.time.Instant +import java.time.ZonedDateTime import static org.prebid.server.functional.model.ChannelType.PBJS import static org.prebid.server.functional.model.ChannelType.WEB import static org.prebid.server.functional.model.bidder.BidderName.GENERIC - import static org.prebid.server.functional.model.config.AccountMetricsVerbosityLevel.DETAILED import static org.prebid.server.functional.model.config.Purpose.P1 import static org.prebid.server.functional.model.config.Purpose.P2 @@ -46,6 +53,7 @@ import static org.prebid.server.functional.model.request.auction.PublicCountryIp import static org.prebid.server.functional.model.request.auction.TraceLevel.BASIC import static org.prebid.server.functional.model.request.auction.TraceLevel.VERBOSE import static org.prebid.server.functional.model.response.auction.BidRejectionReason.REQUEST_BLOCKED_PRIVACY +import static org.prebid.server.functional.testcontainers.Dependencies.getNetworkServiceContainer import static org.prebid.server.functional.util.privacy.TcfConsent.GENERIC_VENDOR_ID import static org.prebid.server.functional.util.privacy.TcfConsent.PurposeId.BASIC_ADS import static org.prebid.server.functional.util.privacy.TcfConsent.PurposeId.DEVICE_ACCESS @@ -55,6 +63,21 @@ import static org.prebid.server.functional.util.privacy.TcfConsent.TcfPolicyVers class GdprAuctionSpec extends PrivacyBaseSpec { + private static final String LIVE_GVL_FILE_NAME = "live-gvl-vendor-list.json" + private static final VENDOR_LIST_VERSION = PBSUtils.getRandomNumber(2, 4094) + private static final Map REFRESH_LIVE_VENDOR_LIST_CONFIG = GENERAL_PRIVACY_CONFIG + + ["gdpr.vendorlist.live.url": "$networkServiceContainer.rootUri/v3/$LIVE_GVL_FILE_NAME".toString()] + private static final VendorList liveVendorListResponse = new VendorList(networkServiceContainer, LIVE_GVL_FILE_NAME) + + def setup() { + vendorListResponse.setResponse() + liveVendorListResponse.reset() + } + + def cleanup() { + vendorListResponse.reset() + } + @PendingFeature def "PBS should add debug log for auction request when valid gdpr was passed"() { given: "Default gdpr BidRequest" @@ -1116,4 +1139,261 @@ class GdprAuctionSpec extends PrivacyBaseSpec { assert metrics["adapter.${GENERIC.value}.requests.buyeruid_scrubbed"] == 1 assert metrics["account.${account.uuid}.adapter.${GENERIC.value}.requests.buyeruid_scrubbed"] == 1 } + + def "PBS should treated GVL record as valid when it's don't marked as deleted for GVL file"() { + given: "Vendor list response with not passed delete date for bidder" + def vendorList = VendorListResponse.Vendor.getDefaultVendor(GENERIC_VENDOR_ID).tap { + deletedDate = gvlDeletedDate + } + downloadLiveGvtList(VENDOR_LIST_VERSION, vendorList) + + and: "PBS with proper warmed GVL config" + def pbsWithLiveGvlSetup = pbsServiceFactory.getService(REFRESH_LIVE_VENDOR_LIST_CONFIG) + warmupGvtList(pbsWithLiveGvlSetup, VENDOR_LIST_VERSION) + + and: "Valid tcf full enforcement requirments" + def requirement = EnforcementRequirement.getDefaultFull(GENERIC_VENDOR_ID, VENDOR_LIST_VERSION, P2) + + and: "Tcf consent setup" + def tcfConsent = TcfUtils.getConsentString(requirement) + + and: "Bid request with tcf consent string" + def bidRequest = getGdprBidRequest(tcfConsent) + + and: "Account with tcf config" + def accountGdprConfig = new AccountGdprConfig(purposes: TcfUtils.getPurposeConfigsForPersonalizedAds(requirement)) + def account = getAccountWithGdpr(bidRequest.accountId, accountGdprConfig) + accountDao.save(account) + + and: "Flush metric" + flushMetrics(pbsWithLiveGvlSetup) + + when: "PBS processes auction request" + def response = pbsWithLiveGvlSetup.sendAuctionRequest(bidRequest) + + then: "Response should contain seatBid" + assert response.seatbid.bid.flatten().size() == 1 + + "Response shouldn't contain any nrb, errors and warnings" + assert verifyAll(response) { + !it.noBidResponse + !it.ext.warnings + !it.ext.errors + } + + and: "Bidder request should be valid" + assert bidder.getBidderRequests(bidRequest.id) + + and: "Disallowed metrics shouldn't be updated" + def metrics = pbsWithLiveGvlSetup.sendCollectedMetricsRequest() + assert !metrics[TEMPLATE_ADAPTER_DISALLOWED_COUNT.getValue(bidRequest, FETCH_BIDS)] + + cleanup: "Stop and remove pbs container" + pbsServiceFactory.removeContainer(REFRESH_LIVE_VENDOR_LIST_CONFIG) + + where: + gvlDeletedDate << [null, ZonedDateTime.now().plusYears(1)] + } + + def "PBS should treated GVL record as invalid when it's marked as deleted for GVL file"() { + given: "Vendor list response with passed delete date for bidder" + def vendor = VendorListResponse.Vendor.getDefaultVendor(GENERIC_VENDOR_ID).tap { + deletedDate = liveGvlDeletedDate + } + downloadLiveGvtList(VENDOR_LIST_VERSION, vendor) + + and: "PBS with proper warmed GVL config" + def pbsWithLiveGvlSetup = pbsServiceFactory.getService(REFRESH_LIVE_VENDOR_LIST_CONFIG) + def requestVendor = VendorListResponse.Vendor.getDefaultVendor(GENERIC_VENDOR_ID).tap { + deletedDate = requestGvlDeletedDate + } + warmupGvtList(pbsWithLiveGvlSetup, VENDOR_LIST_VERSION, requestVendor) + + and: "Valid tcf full enforcement requirments" + def requirement = EnforcementRequirement.getDefaultFull(GENERIC_VENDOR_ID, VENDOR_LIST_VERSION, P2) + + and: "Tcf consent setup" + def tcfConsent = TcfUtils.getConsentString(requirement) + + and: "Bid request with tcf consent string" + def bidRequest = getGdprBidRequest(tcfConsent) + + and: "Account with tcf config" + def accountGdprConfig = new AccountGdprConfig(purposes: TcfUtils.getPurposeConfigsForPersonalizedAds(requirement)) + def account = getAccountWithGdpr(bidRequest.accountId, accountGdprConfig) + accountDao.save(account) + + and: "Flush metric" + flushMetrics(pbsWithLiveGvlSetup) + + when: "PBS processes auction request" + def response = pbsWithLiveGvlSetup.sendAuctionRequest(bidRequest) + + then: "Response shouldn't contain any seatBids, errors and warnings" + assert verifyAll(response) { + !it.seatbid.size() + !it.ext.warnings + !it.ext.errors + } + + and: "Response should include nbr" + assert response.noBidResponse == NoBidResponse.UNKNOWN_ERROR + + and: "PBS should cansel request" + assert !bidder.getBidderRequests(bidRequest.id) + + and: "Disallowed metrics should be updated" + def metrics = pbsWithLiveGvlSetup.sendCollectedMetricsRequest() + assert metrics[TEMPLATE_ADAPTER_DISALLOWED_COUNT.getValue(bidRequest, FETCH_BIDS)] == 1 + + cleanup: "Stop and remove pbs container" + pbsServiceFactory.removeContainer(REFRESH_LIVE_VENDOR_LIST_CONFIG) + + where: + liveGvlDeletedDate | requestGvlDeletedDate + ZonedDateTime.now().minusSeconds(1) | ZonedDateTime.now().plusYears(1) + ZonedDateTime.now().plusYears(1) | ZonedDateTime.now().minusSeconds(1) + } + + def "PBS should treated GVL record as invalid when it's marked as deleted for newer GVL file"() { + given: "Newer Vendor list response with passed delete date for bidder" + def vendorList = VendorListResponse.Vendor.getDefaultVendor(GENERIC_VENDOR_ID).tap { + deletedDate = ZonedDateTime.now().minusSeconds(1) + } + downloadLiveGvtList(VENDOR_LIST_VERSION, vendorList) + + and: "PBS with proper warmed older GVL config" + def pbsWithLiveGvlSetup = pbsServiceFactory.getService(REFRESH_LIVE_VENDOR_LIST_CONFIG) + warmupGvtList(pbsWithLiveGvlSetup, VENDOR_LIST_VERSION - 1) + + and: "Valid tcf full enforcement requirments for older gvl list" + def requirement = EnforcementRequirement.getDefaultFull(GENERIC_VENDOR_ID, VENDOR_LIST_VERSION - 1, P2) + + and: "Tcf consent setup" + def tcfConsent = TcfUtils.getConsentString(requirement) + + and: "Bid request with tcf consent string" + def bidRequest = getGdprBidRequest(tcfConsent) + + and: "Account with tcf config" + def accountGdprConfig = new AccountGdprConfig(purposes: TcfUtils.getPurposeConfigsForPersonalizedAds(requirement)) + def account = getAccountWithGdpr(bidRequest.accountId, accountGdprConfig) + accountDao.save(account) + + and: "Flush metric" + flushMetrics(pbsWithLiveGvlSetup) + + when: "PBS processes auction request" + def response = pbsWithLiveGvlSetup.sendAuctionRequest(bidRequest) + + then: "Response shouldn't contain any seatBids, errors and warnings" + assert verifyAll(response) { + !it.seatbid.size() + !it.ext.warnings + !it.ext.errors + } + + and: "Response should include nbr" + assert response.noBidResponse == NoBidResponse.UNKNOWN_ERROR + + and: "PBS should cansel request" + assert !bidder.getBidderRequests(bidRequest.id) + + and: "Disallowed metrics should be updated" + def metrics = pbsWithLiveGvlSetup.sendCollectedMetricsRequest() + assert metrics[TEMPLATE_ADAPTER_DISALLOWED_COUNT.getValue(bidRequest, FETCH_BIDS)] == 1 + + cleanup: "Stop and remove pbs container" + pbsServiceFactory.removeContainer(REFRESH_LIVE_VENDOR_LIST_CONFIG) + } + + def "PBS should treat vendor as valid when deleted only in intermediate GVL versions"() { + given: "Old vendor list response with passed delete date for bidder" + def olderVendorList = VendorListResponse.Vendor.getDefaultVendor(GENERIC_VENDOR_ID).tap { + deletedDate = ZonedDateTime.now().minusSeconds(1) + } + downloadLiveGvtList(VENDOR_LIST_VERSION, olderVendorList, Times.once()) + + and: "PBS with a high-frequency live GVL refresh config" + def config = REFRESH_LIVE_VENDOR_LIST_CONFIG + ['gdpr.vendorlist.live.refresh-period-ms': '1000'] + def pbsWithLiveGvlSetup = pbsServiceFactory.getService(config) + + and: "Flash metrics" + flushMetrics(pbsWithLiveGvlSetup) + + and: "Newer vendor list where bidder is not deleted yet" + def newerVendorList = VendorListResponse.Vendor.getDefaultVendor(GENERIC_VENDOR_ID).tap { + deletedDate = ZonedDateTime.now().plusYears(1) + } + downloadLiveGvtList(VENDOR_LIST_VERSION + 1, newerVendorList, Times.once()) + pbsWithLiveGvlSetup.isContainMetricByValue('privacy.tcf.vendorlist.live.ok') + + and: "GVL list is warmed up for PBS" + warmupGvtList(pbsWithLiveGvlSetup, VENDOR_LIST_VERSION - 1) + + and: "Valid tcf full enforcement requirments for older GVL list" + def requirement = EnforcementRequirement.getDefaultFull(GENERIC_VENDOR_ID, VENDOR_LIST_VERSION - 1, P2) + + and: "Tcf consent setup" + def tcfConsent = TcfUtils.getConsentString(requirement) + + and: "Bid request with tcf consent string" + def bidRequest = getGdprBidRequest(tcfConsent) + + and: "Account with tcf config" + def accountGdprConfig = new AccountGdprConfig(purposes: TcfUtils.getPurposeConfigsForPersonalizedAds(requirement)) + def account = getAccountWithGdpr(bidRequest.accountId, accountGdprConfig) + accountDao.save(account) + + and: "Flush metric" + flushMetrics(pbsWithLiveGvlSetup) + + when: "PBS processes auction request" + def response = pbsWithLiveGvlSetup.sendAuctionRequest(bidRequest) + + then: "Response should contain seatBid" + assert response.seatbid.bid.flatten().size() == 1 + + "Response shouldn't contain any nrb, errors and warnings" + assert verifyAll(response) { + !it.noBidResponse + !it.ext.warnings + !it.ext.errors + } + + and: "Bidder request should be valid" + assert bidder.getBidderRequests(bidRequest.id) + + and: "Disallowed metrics shouldn't be updated" + def metrics = pbsWithLiveGvlSetup.sendCollectedMetricsRequest() + assert metrics[TEMPLATE_ADAPTER_DISALLOWED_COUNT.getValue(bidRequest, FETCH_BIDS)] == 0 + + cleanup: "Stop and remove pbs container" + pbsServiceFactory.removeContainer(config) + } + + private static void downloadLiveGvtList( + Integer vendorListVersion = VENDOR_LIST_VERSION, + VendorListResponse.Vendor vendor = VendorListResponse.Vendor.getDefaultVendor(GENERIC_VENDOR_ID), + Times times = Times.unlimited()) { + + liveVendorListResponse.reset() + liveVendorListResponse.setResponse(TCF_POLICY_V5, null, [(vendor.id): vendor], vendorListVersion, times) + } + + private static void warmupGvtList(PrebidServerService pbsService, + Integer vendorListVersion = VENDOR_LIST_VERSION, + VendorListResponse.Vendor vendor = VendorListResponse.Vendor.getDefaultVendor(GENERIC_VENDOR_ID)) { + + def simpleTcfString = new TcfConsent.Builder() + .setDisclosedVendors([GENERIC_VENDOR_ID]) + .setVendorListVersion(vendorListVersion) + .build() + + vendorList.reset() + vendorList.setResponse(TCF_POLICY_V2, null, [(vendor.id): vendor]) + + def bidRequest = getGdprBidRequest(simpleTcfString) + pbsService.sendAuctionRequest(bidRequest) + } } diff --git a/src/test/groovy/org/prebid/server/functional/util/privacy/TcfConsent.groovy b/src/test/groovy/org/prebid/server/functional/util/privacy/TcfConsent.groovy index d0d9e19512e..363c7eca4bd 100644 --- a/src/test/groovy/org/prebid/server/functional/util/privacy/TcfConsent.groovy +++ b/src/test/groovy/org/prebid/server/functional/util/privacy/TcfConsent.groovy @@ -12,9 +12,9 @@ import static org.prebid.server.functional.util.privacy.TcfConsent.TcfPolicyVers class TcfConsent implements ConsentString { - public static final Integer RUBICON_VENDOR_ID = PBSUtils.getRandomNumber(0, 65534) - public static final Integer GENERIC_VENDOR_ID = PBSUtils.getRandomNumber(0, 65534) - public static final Integer VENDOR_LIST_VERSION = PBSUtils.getRandomNumber(0, 4095) + public static final Integer RUBICON_VENDOR_ID = PBSUtils.getRandomNumber(1, 65534) + public static final Integer GENERIC_VENDOR_ID = PBSUtils.getRandomNumber(1, 65534) + public static final Integer VENDOR_LIST_VERSION = PBSUtils.getRandomNumber(1, 4095) private final TCStringEncoder.Builder tcStringEncoder diff --git a/src/test/java/org/prebid/server/metric/MetricsTest.java b/src/test/java/org/prebid/server/metric/MetricsTest.java index 8a56e279d30..eb0af781a7d 100644 --- a/src/test/java/org/prebid/server/metric/MetricsTest.java +++ b/src/test/java/org/prebid/server/metric/MetricsTest.java @@ -1004,6 +1004,24 @@ public void updatePrivacyTcfVendorListFallbackMetricShouldIncrementMetric() { assertThat(metricRegistry.counter("privacy.tcf.v1.vendorlist.fallback").getCount()).isEqualTo(1); } + @Test + public void updatePrivacyTcfLiveVendorListOkMetricShouldIncrementMetric() { + // when + metrics.updatePrivacyTcfLiveVendorListOkMetric(); + + // then + assertThat(metricRegistry.counter("privacy.tcf.vendorlist.live.ok").getCount()).isOne(); + } + + @Test + public void updatePrivacyTcfLiveVendorListErrorMetricShouldIncrementMetric() { + // when + metrics.updatePrivacyTcfLiveVendorListErrorMetric(); + + // then + assertThat(metricRegistry.counter("privacy.tcf.vendorlist.live.err").getCount()).isOne(); + } + @Test public void shouldNotUpdateAccountMetricsIfVerbosityIsNone() { // given diff --git a/src/test/java/org/prebid/server/privacy/gdpr/Tcf2ServiceTest.java b/src/test/java/org/prebid/server/privacy/gdpr/Tcf2ServiceTest.java index 19c4d034b2d..bc99140d6db 100644 --- a/src/test/java/org/prebid/server/privacy/gdpr/Tcf2ServiceTest.java +++ b/src/test/java/org/prebid/server/privacy/gdpr/Tcf2ServiceTest.java @@ -15,6 +15,7 @@ import org.prebid.server.privacy.gdpr.model.VendorPermissionWithGvl; import org.prebid.server.privacy.gdpr.tcfstrategies.purpose.PurposeStrategy; import org.prebid.server.privacy.gdpr.tcfstrategies.specialfeature.SpecialFeaturesStrategy; +import org.prebid.server.privacy.gdpr.vendorlist.VendorListWrapper; import org.prebid.server.privacy.gdpr.vendorlist.VersionedVendorListService; import org.prebid.server.privacy.gdpr.vendorlist.proto.Vendor; import org.prebid.server.settings.model.AccountGdprConfig; @@ -34,7 +35,6 @@ import static java.util.Arrays.asList; import static java.util.Collections.emptyList; -import static java.util.Collections.emptyMap; import static java.util.Collections.singleton; import static java.util.Collections.singletonList; import static org.apache.commons.collections4.SetUtils.hashSet; @@ -103,7 +103,7 @@ public class Tcf2ServiceTest extends VertxTest { @BeforeEach public void setUp() { - given(vendorListService.forConsent(any())).willReturn(Future.succeededFuture(emptyMap())); + given(vendorListService.forConsent(any())).willReturn(Future.succeededFuture(VendorListWrapper.EMPTY)); given(purposeStrategyOne.getPurpose()).willReturn(ONE); given(purposeStrategyTwo.getPurpose()).willReturn(TWO); diff --git a/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/LiveVendorListServiceTest.java b/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/LiveVendorListServiceTest.java new file mode 100644 index 00000000000..863ac4a978b --- /dev/null +++ b/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/LiveVendorListServiceTest.java @@ -0,0 +1,288 @@ +package org.prebid.server.privacy.gdpr.vendorlist; + +import com.fasterxml.jackson.core.JsonProcessingException; +import io.vertx.core.Future; +import io.vertx.core.Vertx; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.prebid.server.VertxTest; +import org.prebid.server.metric.Metrics; +import org.prebid.server.privacy.gdpr.vendorlist.proto.Feature; +import org.prebid.server.privacy.gdpr.vendorlist.proto.PurposeCode; +import org.prebid.server.privacy.gdpr.vendorlist.proto.SpecialFeature; +import org.prebid.server.privacy.gdpr.vendorlist.proto.SpecialPurpose; +import org.prebid.server.privacy.gdpr.vendorlist.proto.Vendor; +import org.prebid.server.privacy.gdpr.vendorlist.proto.VendorList; +import org.prebid.server.vertx.httpclient.HttpClient; +import org.prebid.server.vertx.httpclient.model.HttpClientResponse; + +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneOffset; +import java.util.Arrays; +import java.util.Date; +import java.util.EnumSet; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.prebid.server.privacy.gdpr.vendorlist.proto.PurposeCode.ONE; +import static org.prebid.server.privacy.gdpr.vendorlist.proto.PurposeCode.TWO; + +@ExtendWith(MockitoExtension.class) +public class LiveVendorListServiceTest extends VertxTest { + + private static final Instant NOW = Instant.parse("2024-06-01T12:00:00Z"); + private static final String CACHE_DIR = "/cache/dir"; + private static final String LIVE_GVL_URL = "https://example.com"; + private static final long REFRESH_PERIOD_MS = 1000; + + @Mock + private Vertx vertx; + @Mock + private HttpClient httpClient; + @Mock + private VendorListFileStore vendorListFileStore; + @Mock + private Metrics metrics; + + private LiveVendorListService target; + + @BeforeEach + public void setUp() { + target = new LiveVendorListService( + CACHE_DIR, + LIVE_GVL_URL, + REFRESH_PERIOD_MS, + 1000, + vertx, + httpClient, + vendorListFileStore, + metrics, + jacksonMapper, + Clock.fixed(NOW, ZoneOffset.UTC)); + } + + @Test + public void getDeletedVendorIdsShouldReturnEmptySetWhenFetchNeverSucceeded() { + // when and then + assertThat(target.getDeletedVendorIds()).isEmpty(); + } + + @Test + public void getDeletedVendorIdsShouldReturnVendorThatIsDeletedInLiveVendorList() throws JsonProcessingException { + // given + final Vendor vendor = givenVendor(42, "2024-01-01T00:00:00Z"); + final String responseBody = mapper.writeValueAsString(givenVendorList(vendor)); + given(httpClient.get(anyString(), anyLong())) + .willReturn(Future.succeededFuture(HttpClientResponse.of(200, null, responseBody))); + + // when + target.refresh(); + + // then + assertThat(target.getDeletedVendorIds()).containsExactly(42); + } + + @Test + public void extractDeletedVendorIdsShouldReturnOnlyVendorsWithPastDeletedDate() { + // given + final VendorList vendorList = givenVendorList( + givenVendor(1, "2024-01-01T00:00:00Z"), + givenVendor(2, null), + givenVendor(3, "2025-01-01T00:00:00Z"), + givenVendor(4, "2024-06-01T12:00:00Z")); + + // when + final var deletedIds = target.extractDeletedVendorIds(vendorList); + + // then + assertThat(deletedIds).containsExactly(1); + } + + @Test + public void refreshShouldUpdateDeletedVendorIdsAndIncrementOkMetric() throws JsonProcessingException { + // given + final Vendor vendor = givenVendor(1, "2024-01-01T00:00:00Z"); + final String responseBody = mapper.writeValueAsString(givenVendorList(vendor)); + givenHttpClientReturnsResponse(200, responseBody); + + // when + target.refresh(); + + // then + assertThat(target.getDeletedVendorIds()).containsExactly(1); + verify(metrics).updatePrivacyTcfLiveVendorListOkMetric(); + verify(metrics, never()).updatePrivacyTcfLiveVendorListErrorMetric(); + } + + @Test + public void refreshShouldReplaceDeletedVendorIdsOnSubsequentSuccessfulFetch() throws JsonProcessingException { + // given + final Vendor vendor = givenVendor(1, "2024-01-01T00:00:00Z"); + final String responseBody = mapper.writeValueAsString(givenVendorList(vendor)); + final Vendor vendor2 = givenVendor(2, "2024-02-01T00:00:00Z"); + final String responseBody2 = mapper.writeValueAsString(givenVendorList(vendor2)); + given(httpClient.get(anyString(), anyLong())) + .willReturn( + Future.succeededFuture(HttpClientResponse.of(200, null, responseBody)), + Future.succeededFuture(HttpClientResponse.of(200, null, responseBody2))); + + // when + target.refresh(); + target.refresh(); + + // then + assertThat(target.getDeletedVendorIds()).containsExactly(2); + } + + @Test + public void refreshShouldIncrementErrorMetricOnHttpFailure() { + // given + given(httpClient.get(anyString(), anyLong())) + .willReturn(Future.failedFuture(new RuntimeException("connection failed"))); + + // when + target.refresh(); + + // then + assertThat(target.getDeletedVendorIds()).isEmpty(); + verify(metrics).updatePrivacyTcfLiveVendorListErrorMetric(); + verify(metrics, never()).updatePrivacyTcfLiveVendorListOkMetric(); + } + + @Test + public void refreshShouldIncrementErrorMetricOnNonOkStatus() { + // given + givenHttpClientReturnsResponse(503, "{}"); + + // when + target.refresh(); + + // then + assertThat(target.getDeletedVendorIds()).isEmpty(); + verify(metrics).updatePrivacyTcfLiveVendorListErrorMetric(); + } + + @Test + public void refreshShouldIncrementErrorMetricOnInvalidJson() { + // given + givenHttpClientReturnsResponse(200, "invalid-json"); + + // when + target.refresh(); + + // then + assertThat(target.getDeletedVendorIds()).isEmpty(); + verify(metrics).updatePrivacyTcfLiveVendorListErrorMetric(); + } + + @Test + public void refreshShouldIncrementErrorMetricOnInvalidVendorList() throws JsonProcessingException { + // given + final Vendor vendor = givenVendor(42, "2024-01-01T00:00:00Z") + .toBuilder().features(null).build(); + final String responseBody = mapper.writeValueAsString(givenVendorList(vendor)); + givenHttpClientReturnsResponse(200, responseBody); + + // when + target.refresh(); + + // then + assertThat(target.getDeletedVendorIds()).isEmpty(); + verify(metrics).updatePrivacyTcfLiveVendorListErrorMetric(); + } + + @Test + public void initializeShouldLoadDeletedVendorsFromCachedVendorList() { + // given + final VendorList vendorList = givenVendorList(givenVendor(42, "2024-01-01T00:00:00Z")); + given(vendorListFileStore.getLatestVendorListFromCache(eq(CACHE_DIR))).willReturn(Optional.of(vendorList)); + + // when + target.initialize(); + + // then + assertThat(target.getDeletedVendorIds()).containsExactly(42); + } + + @Test + public void initializeShouldSchedulePeriodicRefresh() { + // given + given(vendorListFileStore.getLatestVendorListFromCache(eq(CACHE_DIR))).willReturn(Optional.empty()); + + // when + target.initialize(); + + // then + verify(vertx).setPeriodic(eq(0L), eq(REFRESH_PERIOD_MS), any()); + } + + @Test + public void initializeShouldReturnSucceededFuture() { + // given + given(vendorListFileStore.getLatestVendorListFromCache(eq(CACHE_DIR))).willReturn(Optional.empty()); + + // when + final Future result = target.initialize(); + + // then + assertThat(result.succeeded()).isTrue(); + } + + @Test + public void refreshShouldKeepLastGoodSetOnFailureAfterSuccessfulFetch() throws JsonProcessingException { + // given + final Vendor vendor = givenVendor(1, "2024-01-01T00:00:00Z"); + final String responseBody = mapper.writeValueAsString(givenVendorList(vendor)); + given(httpClient.get(anyString(), anyLong())) + .willReturn( + Future.succeededFuture(HttpClientResponse.of(200, null, responseBody)), + Future.failedFuture(new RuntimeException("connection failed"))); + + // when + target.refresh(); + target.refresh(); + + // then + assertThat(target.getDeletedVendorIds()).containsExactly(1); + verify(metrics).updatePrivacyTcfLiveVendorListOkMetric(); + verify(metrics).updatePrivacyTcfLiveVendorListErrorMetric(); + } + + private void givenHttpClientReturnsResponse(int statusCode, String response) { + given(httpClient.get(anyString(), anyLong())) + .willReturn(Future.succeededFuture(HttpClientResponse.of(statusCode, null, response))); + } + + private static Vendor givenVendor(int id, String deletedDate) { + return Vendor.builder() + .id(id) + .deletedDate(deletedDate != null ? Instant.parse(deletedDate) : null) + .purposes(EnumSet.of(ONE)) + .legIntPurposes(EnumSet.of(TWO)) + .flexiblePurposes(EnumSet.noneOf(PurposeCode.class)) + .specialPurposes(EnumSet.noneOf(SpecialPurpose.class)) + .features(EnumSet.noneOf(Feature.class)) + .specialFeatures(EnumSet.noneOf(SpecialFeature.class)) + .build(); + } + + private static VendorList givenVendorList(Vendor... vendors) { + return VendorList.of( + 1, + Date.from(Instant.parse("2020-08-20T16:05:24Z")), + Arrays.stream(vendors).collect(Collectors.toMap(Vendor::getId, Function.identity()))); + } +} diff --git a/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListFileStoreTest.java b/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListFileStoreTest.java new file mode 100644 index 00000000000..dea4c1ce67c --- /dev/null +++ b/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListFileStoreTest.java @@ -0,0 +1,407 @@ +package org.prebid.server.privacy.gdpr.vendorlist; + +import com.fasterxml.jackson.core.JsonProcessingException; +import io.vertx.core.Future; +import io.vertx.core.buffer.Buffer; +import io.vertx.core.file.FileProps; +import io.vertx.core.file.FileSystem; +import io.vertx.core.file.FileSystemException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.io.TempDir; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.prebid.server.VertxTest; +import org.prebid.server.exception.PreBidException; +import org.prebid.server.privacy.gdpr.vendorlist.proto.Feature; +import org.prebid.server.privacy.gdpr.vendorlist.proto.PurposeCode; +import org.prebid.server.privacy.gdpr.vendorlist.proto.SpecialFeature; +import org.prebid.server.privacy.gdpr.vendorlist.proto.SpecialPurpose; +import org.prebid.server.privacy.gdpr.vendorlist.proto.Vendor; +import org.prebid.server.privacy.gdpr.vendorlist.proto.VendorList; + +import java.io.File; +import java.nio.file.Path; +import java.util.Date; +import java.util.EnumSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.prebid.server.privacy.gdpr.vendorlist.proto.PurposeCode.ONE; +import static org.prebid.server.privacy.gdpr.vendorlist.proto.PurposeCode.TWO; + +@ExtendWith(MockitoExtension.class) +public class VendorListFileStoreTest extends VertxTest { + + private static final String CACHE_DIR = "/cache/dir"; + private static final String FALLBACK_VENDOR_LIST_PATH = "fallback.json"; + private static final String GENERATION_VERSION = "v0"; + + @Mock + private FileSystem fileSystem; + + @TempDir + private Path tempDir; + + private VendorListFileStore target; + + @BeforeEach + public void setUp() { + target = new VendorListFileStore(0, fileSystem, jacksonMapper); + } + + @Test + public void createCacheFromDiskShouldCreateCacheDirWhenItDoesNotExist() { + // given + given(fileSystem.existsBlocking(eq(CACHE_DIR))).willReturn(false); + given(fileSystem.readDirBlocking(eq(CACHE_DIR))).willReturn(List.of()); + + // when + target.createCacheFromDisk(CACHE_DIR); + + // then + verify(fileSystem).mkdirsBlocking(eq(CACHE_DIR)); + } + + @Test + public void createCacheFromDiskShouldCreateCacheDirWhenPathExistsButIsNotADirectory() { + // given + final FileProps fileProps = mock(FileProps.class); + given(fileSystem.existsBlocking(eq(CACHE_DIR))).willReturn(true); + given(fileSystem.propsBlocking(eq(CACHE_DIR))).willReturn(fileProps); + given(fileProps.isDirectory()).willReturn(false); + given(fileSystem.readDirBlocking(eq(CACHE_DIR))).willReturn(List.of()); + + // when + target.createCacheFromDisk(CACHE_DIR); + + // then + verify(fileSystem).mkdirsBlocking(eq(CACHE_DIR)); + } + + @Test + public void createCacheFromDiskShouldFailIfCannotCreateCacheDir() { + // given + given(fileSystem.existsBlocking(eq(CACHE_DIR))).willReturn(false); + given(fileSystem.mkdirsBlocking(eq(CACHE_DIR))) + .willThrow(new FileSystemException("dir creation error")); + + // when and then + assertThatThrownBy(() -> target.createCacheFromDisk(CACHE_DIR)) + .isInstanceOf(PreBidException.class) + .hasMessage("Cannot create directory: " + CACHE_DIR); + } + + @Test + public void createCacheFromDiskShouldFailIfCacheDirIsNotWritable() { + // given + final String cacheDir = tempDir.toString(); + tempDir.toFile().setWritable(false, false); + final FileProps fileProps = mock(FileProps.class); + given(fileSystem.existsBlocking(eq(cacheDir))).willReturn(true); + given(fileSystem.propsBlocking(eq(cacheDir))).willReturn(fileProps); + given(fileProps.isDirectory()).willReturn(true); + + // when and then + assertThatThrownBy(() -> target.createCacheFromDisk(cacheDir)) + .isInstanceOf(PreBidException.class) + .hasMessage("No write permissions for directory: " + cacheDir); + } + + @Test + public void createCacheFromDiskShouldNotFailIfCacheDirIsWriable() { + // given + final String cacheDir = tempDir.toString(); + tempDir.toFile().setWritable(true, false); + final FileProps fileProps = mock(FileProps.class); + given(fileSystem.existsBlocking(eq(cacheDir))).willReturn(true); + given(fileSystem.propsBlocking(eq(cacheDir))).willReturn(fileProps); + given(fileProps.isDirectory()).willReturn(true); + + // when and then + assertDoesNotThrow(() -> target.createCacheFromDisk(cacheDir)); + } + + @Test + public void createCacheFromDiskShouldReturnCacheLoadedFromJsonFiles() throws JsonProcessingException { + // given + given(fileSystem.existsBlocking(eq(CACHE_DIR))).willReturn(false); + given(fileSystem.readDirBlocking(eq(CACHE_DIR))).willReturn(List.of("/cache/dir/1.json")); + given(fileSystem.readFileBlocking(eq("/cache/dir/1.json"))) + .willReturn(Buffer.buffer(mapper.writeValueAsString(givenVendorList()))); + + // when + final Map> cache = target.createCacheFromDisk(CACHE_DIR); + + // then + assertThat(cache).isEqualTo(singletonMap(1, givenVendorMap())); + } + + @Test + public void createCacheFromDiskShouldReturnEmptyCacheWhenCacheDirHasNoJsonFiles() { + // given + given(fileSystem.existsBlocking(eq(CACHE_DIR))).willReturn(false); + given(fileSystem.readDirBlocking(eq(CACHE_DIR))).willReturn(List.of()); + + // when + final Map> cache = target.createCacheFromDisk(CACHE_DIR); + + // then + assertThat(cache).isEmpty(); + } + + @Test + public void createCacheFromDiskShouldFailIfCannotReadCacheDir() { + // given + given(fileSystem.existsBlocking(eq(CACHE_DIR))).willReturn(false); + given(fileSystem.readDirBlocking(eq(CACHE_DIR))).willThrow(new RuntimeException("read error")); + + // when and then + assertThatThrownBy(() -> target.createCacheFromDisk(CACHE_DIR)) + .isInstanceOf(RuntimeException.class) + .hasMessage("read error"); + } + + @Test + public void createCacheFromDiskShouldFailIfCannotReadAtLeastOneVendorListFile() { + // given + given(fileSystem.existsBlocking(eq(CACHE_DIR))).willReturn(false); + given(fileSystem.readDirBlocking(eq(CACHE_DIR))).willReturn(List.of("1.json")); + given(fileSystem.readFileBlocking(eq("1.json"))).willThrow(new RuntimeException("read error")); + + // when and then + assertThatThrownBy(() -> target.createCacheFromDisk(CACHE_DIR)) + .isInstanceOf(RuntimeException.class) + .hasMessage("read error"); + } + + @Test + public void createCacheFromDiskShouldFailIfAtLeastOneVendorListFileCannotBeParsed() { + // given + given(fileSystem.existsBlocking(eq(CACHE_DIR))).willReturn(false); + given(fileSystem.readDirBlocking(eq(CACHE_DIR))).willReturn(List.of("1.json")); + given(fileSystem.readFileBlocking(eq("1.json"))).willReturn(Buffer.buffer("invalid")); + + // when and then + assertThatThrownBy(() -> target.createCacheFromDisk(CACHE_DIR)) + .isInstanceOf(PreBidException.class) + .hasMessage("Cannot parse vendor list from: invalid"); + } + + @Test + public void saveToFileShouldCompleteWithVendorListResultWhenWriteSucceeds() throws JsonProcessingException { + // given + final VendorList vendorList = givenVendorList(); + final String vendorListAsString = mapper.writeValueAsString(vendorList); + final VendorListResult vendorListResult = VendorListResult.of(1, vendorListAsString, vendorList); + given(fileSystem.writeFile(anyString(), any(Buffer.class))).willReturn(Future.succeededFuture()); + + // when + final Future future = target.saveToFile(vendorListResult, CACHE_DIR, GENERATION_VERSION); + + // then + org.prebid.server.assertion.FutureAssertion.assertThat(future).succeededWith(vendorListResult); + } + + @Test + public void saveToFileShouldWriteToExpectedPathWithExpectedContent() throws JsonProcessingException { + // given + final VendorList vendorList = givenVendorList(); + final String vendorListAsString = mapper.writeValueAsString(vendorList); + final VendorListResult vendorListResult = VendorListResult.of(1, vendorListAsString, vendorList); + given(fileSystem.writeFile(anyString(), any(Buffer.class))).willReturn(Future.succeededFuture()); + + // when + target.saveToFile(vendorListResult, CACHE_DIR, GENERATION_VERSION); + + // then + final ArgumentCaptor pathCaptor = ArgumentCaptor.forClass(String.class); + final ArgumentCaptor bufferCaptor = ArgumentCaptor.forClass(Buffer.class); + verify(fileSystem).writeFile(pathCaptor.capture(), bufferCaptor.capture()); + assertThat(pathCaptor.getValue()).isEqualTo(new File(CACHE_DIR, "1.json").getPath()); + assertThat(bufferCaptor.getValue().toString()).isEqualTo(vendorListAsString); + } + + @Test + public void saveToFileShouldFailWhenWriteFails() throws JsonProcessingException { + // given + final VendorList vendorList = givenVendorList(); + final String vendorListAsString = mapper.writeValueAsString(vendorList); + final VendorListResult vendorListResult = VendorListResult.of(1, vendorListAsString, vendorList); + final RuntimeException exception = new RuntimeException("write error"); + given(fileSystem.writeFile(anyString(), any(Buffer.class))).willReturn(Future.failedFuture(exception)); + + // when + final Future future = target.saveToFile(vendorListResult, CACHE_DIR, GENERATION_VERSION); + + // then + org.prebid.server.assertion.FutureAssertion.assertThat(future) + .isFailed() + .isInstanceOf(RuntimeException.class) + .hasMessage("write error"); + } + + @Test + public void readFallbackVendorListShouldReturnNullWhenPathIsBlank() { + // when and then + assertThat(target.readFallbackVendorList(null)).isNull(); + assertThat(target.readFallbackVendorList("")).isNull(); + assertThat(target.readFallbackVendorList(" ")).isNull(); + } + + @Test + public void readFallbackVendorListShouldReturnVendorsWhenPathIsValid() throws JsonProcessingException { + // given + given(fileSystem.readFileBlocking(eq(FALLBACK_VENDOR_LIST_PATH))) + .willReturn(Buffer.buffer(mapper.writeValueAsString(givenVendorList()))); + + // when + final Map vendors = target.readFallbackVendorList(FALLBACK_VENDOR_LIST_PATH); + + // then + assertThat(vendors).isEqualTo(givenVendorMap()); + } + + @Test + public void readFallbackVendorListShouldFailIfCannotReadFallbackFile() { + // given + given(fileSystem.readFileBlocking(eq(FALLBACK_VENDOR_LIST_PATH))) + .willThrow(new RuntimeException("read error")); + + // when and then + assertThatThrownBy(() -> target.readFallbackVendorList(FALLBACK_VENDOR_LIST_PATH)) + .isInstanceOf(RuntimeException.class) + .hasMessage("read error"); + } + + @Test + public void readFallbackVendorListShouldFailIfFallbackCannotBeParsed() { + // given + given(fileSystem.readFileBlocking(eq(FALLBACK_VENDOR_LIST_PATH))) + .willReturn(Buffer.buffer("invalid")); + + // when and then + assertThatThrownBy(() -> target.readFallbackVendorList(FALLBACK_VENDOR_LIST_PATH)) + .isInstanceOf(PreBidException.class) + .hasMessage("Cannot parse vendor list from: invalid"); + } + + @Test + public void getLatestVendorListFromCacheShouldReturnEmptyWhenCacheDirHasNoJsonFiles() { + // given + given(fileSystem.existsBlocking(eq(CACHE_DIR))).willReturn(false); + given(fileSystem.readDirBlocking(eq(CACHE_DIR))).willReturn(List.of()); + + // when + final Optional result = target.getLatestVendorListFromCache(CACHE_DIR); + + // then + assertThat(result).isEmpty(); + } + + @Test + public void getLatestVendorListFromCacheShouldReturnVendorListWithHighestVersion() throws JsonProcessingException { + // given + final VendorList vendorList = givenVendorList(10); + given(fileSystem.existsBlocking(eq(CACHE_DIR))).willReturn(false); + given(fileSystem.readDirBlocking(eq(CACHE_DIR))).willReturn(List.of( + "/cache/dir/2.json", + "/cache/dir/10.json")); + given(fileSystem.readFileBlocking(eq("/cache/dir/10.json"))) + .willReturn(Buffer.buffer(mapper.writeValueAsString(vendorList))); + + // when + final Optional result = target.getLatestVendorListFromCache(CACHE_DIR); + + // then + assertThat(result).hasValue(vendorList); + verify(fileSystem, never()).readFileBlocking(eq("/cache/dir/2.json")); + } + + @Test + public void getLatestVendorListFromCacheShouldCreateCacheDirWhenItDoesNotExist() { + // given + given(fileSystem.existsBlocking(eq(CACHE_DIR))).willReturn(false); + given(fileSystem.readDirBlocking(eq(CACHE_DIR))).willReturn(List.of()); + + // when + target.getLatestVendorListFromCache(CACHE_DIR); + + // then + verify(fileSystem).mkdirsBlocking(eq(CACHE_DIR)); + } + + @Test + public void getLatestVendorListFromCacheShouldFailIfCannotReadCacheDir() { + // given + given(fileSystem.existsBlocking(eq(CACHE_DIR))).willReturn(false); + given(fileSystem.readDirBlocking(eq(CACHE_DIR))).willThrow(new RuntimeException("read error")); + + // when and then + assertThatThrownBy(() -> target.getLatestVendorListFromCache(CACHE_DIR)) + .isInstanceOf(RuntimeException.class) + .hasMessage("read error"); + } + + @Test + public void getLatestVendorListFromCacheShouldFailIfLatestVendorListFileCannotBeParsed() { + // given + given(fileSystem.existsBlocking(eq(CACHE_DIR))).willReturn(false); + given(fileSystem.readDirBlocking(eq(CACHE_DIR))).willReturn(List.of("/cache/dir/1.json")); + given(fileSystem.readFileBlocking(eq("/cache/dir/1.json"))).willReturn(Buffer.buffer("invalid")); + + // when and then + assertThatThrownBy(() -> target.getLatestVendorListFromCache(CACHE_DIR)) + .isInstanceOf(PreBidException.class) + .hasMessage("Cannot parse vendor list from: invalid"); + } + + @Test + public void readFallbackVendorListShouldFailIfFallbackHasInvalidData() throws JsonProcessingException { + // given + final VendorList invalidVendorList = VendorList.of(1, new Date(), emptyMap()); + given(fileSystem.readFileBlocking(eq(FALLBACK_VENDOR_LIST_PATH))) + .willReturn(Buffer.buffer(mapper.writeValueAsString(invalidVendorList))); + + // when and then + assertThatThrownBy(() -> target.readFallbackVendorList(FALLBACK_VENDOR_LIST_PATH)) + .isInstanceOf(PreBidException.class) + .hasMessageStartingWith("Fallback vendor list parsed but has invalid data:"); + } + + private static VendorList givenVendorList() { + return givenVendorList(1); + } + + private static VendorList givenVendorList(int version) { + return VendorList.of(version, new Date(), givenVendorMap()); + } + + private static Map givenVendorMap() { + final Vendor vendor = Vendor.builder() + .id(52) + .purposes(EnumSet.of(ONE)) + .legIntPurposes(EnumSet.of(TWO)) + .flexiblePurposes(EnumSet.noneOf(PurposeCode.class)) + .specialPurposes(EnumSet.noneOf(SpecialPurpose.class)) + .features(EnumSet.noneOf(Feature.class)) + .specialFeatures(EnumSet.noneOf(SpecialFeature.class)) + .build(); + return singletonMap(52, vendor); + } +} diff --git a/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListServiceTest.java b/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListServiceTest.java index 3687b1a6129..854db8fcef0 100644 --- a/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListServiceTest.java +++ b/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListServiceTest.java @@ -3,8 +3,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import io.vertx.core.Future; import io.vertx.core.Vertx; -import io.vertx.core.buffer.Buffer; -import io.vertx.core.file.FileSystem; import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -24,7 +22,6 @@ import org.prebid.server.vertx.httpclient.HttpClient; import org.prebid.server.vertx.httpclient.model.HttpClientResponse; -import java.io.File; import java.util.Date; import java.util.EnumSet; import java.util.HashMap; @@ -32,7 +29,6 @@ import static java.util.Collections.emptyMap; import static java.util.Collections.singleton; -import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; @@ -40,9 +36,11 @@ import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.BDDMockito.given; import static org.mockito.Mock.Strictness.LENIENT; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; import static org.prebid.server.assertion.FutureAssertion.assertThat; @@ -59,8 +57,6 @@ public class VendorListServiceTest extends VertxTest { @Mock private Vertx vertx; - @Mock - private FileSystem fileSystem; @Mock(strictness = LENIENT) private HttpClient httpClient; @Mock @@ -69,19 +65,17 @@ public class VendorListServiceTest extends VertxTest { private BidderCatalog bidderCatalog; @Mock(strictness = LENIENT) private VendorListFetchThrottler fetchThrottler; + @Mock(strictness = LENIENT) + private VendorListFileStore vendorListFileStore; private VendorListService target; @BeforeEach public void setUp() throws JsonProcessingException { - given(fileSystem.existsBlocking(anyString())).willReturn(false); // always create cache dir - given(bidderCatalog.knownVendorIds()).willReturn(singleton(52)); - - given(fileSystem.readFileBlocking(eq(FALLBACK_VENDOR_LIST_PATH))) - .willReturn(Buffer.buffer(mapper.writeValueAsString(givenVendorList()))); - given(fetchThrottler.registerFetchAttempt(anyInt())).willReturn(true); + given(vendorListFileStore.readFallbackVendorList(isNull())).willReturn(null); + given(vendorListFileStore.readFallbackVendorList(eq(FALLBACK_VENDOR_LIST_PATH))).willReturn(givenVendorMap()); target = new VendorListService( 0, @@ -92,44 +86,72 @@ public void setUp() throws JsonProcessingException { false, FALLBACK_VENDOR_LIST_PATH, vertx, - fileSystem, httpClient, metrics, GENERATION_VERSION, - jacksonMapper, - fetchThrottler); + fetchThrottler, + vendorListFileStore, + jacksonMapper); } // Creation related tests @Test - public void creationShouldFailsIfCannotCreateCacheDir() { - // given - given(fileSystem.mkdirsBlocking(anyString())).willThrow(new RuntimeException("dir creation error")); + public void creationShouldCreateCacheFromDisk() { + reset(vendorListFileStore); + + // given and when + new VendorListService( + 0, + CACHE_DIR, + "http://vendorlist/{VERSION}", + 0, + REFRESH_MISSING_LIST_PERIOD_MS, + false, + FALLBACK_VENDOR_LIST_PATH, + vertx, + httpClient, + metrics, + GENERATION_VERSION, + fetchThrottler, + vendorListFileStore, + jacksonMapper); // then - assertThatThrownBy( - () -> new VendorListService( - 0, - CACHE_DIR, - "http://vendorlist/{VERSION}", - 0, - REFRESH_MISSING_LIST_PERIOD_MS, - false, - FALLBACK_VENDOR_LIST_PATH, - vertx, - fileSystem, - httpClient, - metrics, - GENERATION_VERSION, - jacksonMapper, - fetchThrottler)) - .hasMessage("dir creation error"); + verify(vendorListFileStore).createCacheFromDisk(eq(CACHE_DIR)); + } + + @Test + public void creationShouldFailIfCannotCreateCache() { + // given + given(vendorListFileStore.createCacheFromDisk(anyString())) + .willThrow(new RuntimeException("error creating cache")); + + // when and then + assertThatThrownBy(() -> new VendorListService( + 0, + CACHE_DIR, + "http://vendorlist/{VERSION}", + 0, + REFRESH_MISSING_LIST_PERIOD_MS, + true, + null, + vertx, + httpClient, + metrics, + GENERATION_VERSION, + fetchThrottler, + vendorListFileStore, + jacksonMapper)) + .isInstanceOf(RuntimeException.class) + .hasMessage("error creating cache"); } @Test public void shouldStartUsingFallbackVersionIfDeprecatedIsTrue() { // given + given(vendorListFileStore.readFallbackVendorList(anyString())).willReturn(givenVendorMap()); + target = new VendorListService( 0, CACHE_DIR, @@ -139,12 +161,12 @@ public void shouldStartUsingFallbackVersionIfDeprecatedIsTrue() { true, FALLBACK_VENDOR_LIST_PATH, vertx, - fileSystem, httpClient, metrics, GENERATION_VERSION, - jacksonMapper, - fetchThrottler); + fetchThrottler, + vendorListFileStore, + jacksonMapper); // when final Future> future = target.forVersion(1); @@ -175,96 +197,16 @@ public void shouldThrowExceptionIfVersionIsDeprecatedAndNoFallbackPresent() { true, null, vertx, - fileSystem, httpClient, metrics, GENERATION_VERSION, - jacksonMapper, - fetchThrottler)) + fetchThrottler, + vendorListFileStore, + jacksonMapper)) .isInstanceOf(PreBidException.class) .hasMessage("No fallback vendorList for deprecated version present"); } - @Test - public void creationShouldFailsIfCannotReadFiles() { - // given - given(fileSystem.readDirBlocking(anyString())).willThrow(new RuntimeException("read error")); - - // then - assertThatThrownBy( - () -> new VendorListService( - 0, - CACHE_DIR, - "http://vendorlist/{VERSION}", - 0, - REFRESH_MISSING_LIST_PERIOD_MS, - false, - FALLBACK_VENDOR_LIST_PATH, - vertx, - fileSystem, - httpClient, - metrics, - GENERATION_VERSION, - jacksonMapper, - fetchThrottler)) - .isInstanceOf(RuntimeException.class) - .hasMessage("read error"); - } - - @Test - public void creationShouldFailsIfCannotReadAtLeastOneVendorListFile() { - // given - given(fileSystem.readDirBlocking(anyString())).willReturn(singletonList("1.json")); - given(fileSystem.readFileBlocking(anyString())).willThrow(new RuntimeException("read error")); - - // then - assertThatThrownBy( - () -> new VendorListService( - 0, - CACHE_DIR, - "http://vendorlist/{VERSION}", - 0, - REFRESH_MISSING_LIST_PERIOD_MS, - false, - FALLBACK_VENDOR_LIST_PATH, - vertx, - fileSystem, - httpClient, - metrics, - GENERATION_VERSION, - jacksonMapper, - fetchThrottler)) - .isInstanceOf(RuntimeException.class) - .hasMessage("read error"); - } - - @Test - public void creationShouldFailsIfAtLeastOneVendorListFileCannotBeParsed() { - // given - given(fileSystem.readDirBlocking(anyString())).willReturn(singletonList("1.json")); - given(fileSystem.readFileBlocking(anyString())).willReturn(Buffer.buffer("invalid")); - - // then - assertThatThrownBy( - () -> new VendorListService( - 0, - CACHE_DIR, - "http://vendorlist/{VERSION}", - 0, - REFRESH_MISSING_LIST_PERIOD_MS, - false, - FALLBACK_VENDOR_LIST_PATH, - vertx, - fileSystem, - httpClient, - metrics, - GENERATION_VERSION, - jacksonMapper, - fetchThrottler)) - .isInstanceOf(PreBidException.class) - .hasMessage("Cannot parse vendor list from: invalid"); - } - // Http related tests @Test @@ -291,11 +233,11 @@ public void shouldNotPerformHttpRequestIfVendorListNotFoundAndFetchNotAllowed() // then verify(httpClient, never()).get(anyString(), anyLong()); - verify(fileSystem, never()).writeFile(any(), any()); + verify(vendorListFileStore, never()).saveToFile(any(), anyString(), anyString()); } @Test - public void shouldNotAskToSaveFileIfReadingHttpResponseFails() { + public void shouldNotTryToSaveFileIfReadingHttpResponseFails() { // given givenHttpClientProducesException(new RuntimeException("Response exception")); @@ -304,11 +246,11 @@ public void shouldNotAskToSaveFileIfReadingHttpResponseFails() { // then verify(httpClient).get(anyString(), anyLong()); - verify(fileSystem, never()).writeFile(any(), any()); + verify(vendorListFileStore, never()).saveToFile(any(), anyString(), anyString()); } @Test - public void shouldNotAskToSaveFileIfResponseCodeIsNot200() { + public void shouldNotTryToSaveFileIfResponseCodeIsNot200() { // given givenHttpClientReturnsResponse(503, null); @@ -317,11 +259,11 @@ public void shouldNotAskToSaveFileIfResponseCodeIsNot200() { // then verify(httpClient).get(anyString(), anyLong()); - verify(fileSystem, never()).writeFile(any(), any()); + verify(vendorListFileStore, never()).saveToFile(any(), anyString(), anyString()); } @Test - public void shouldNotAskToSaveFileIfResponseBodyCouldNotBeParsed() { + public void shouldNotTryToSaveFileIfResponseBodyCouldNotBeParsed() { // given givenHttpClientReturnsResponse(200, "response"); @@ -330,11 +272,11 @@ public void shouldNotAskToSaveFileIfResponseBodyCouldNotBeParsed() { // then verify(httpClient).get(anyString(), anyLong()); - verify(fileSystem, never()).writeFile(any(), any()); + verify(vendorListFileStore, never()).saveToFile(any(), anyString(), anyString()); } @Test - public void shouldNotAskToSaveFileIfFetchedVendorListHasInvalidVendorListVersion() throws JsonProcessingException { + public void shouldNotTryToSaveFileIfFetchedVendorListHasInvalidVendorListVersion() throws JsonProcessingException { // given final VendorList vendorList = VendorList.of(null, null, null); givenHttpClientReturnsResponse(200, mapper.writeValueAsString(vendorList)); @@ -344,11 +286,11 @@ public void shouldNotAskToSaveFileIfFetchedVendorListHasInvalidVendorListVersion // then verify(httpClient).get(anyString(), anyLong()); - verify(fileSystem, never()).writeFile(any(), any()); + verify(vendorListFileStore, never()).saveToFile(any(), anyString(), anyString()); } @Test - public void shouldNotAskToSaveFileIfFetchedVendorListHasInvalidLastUpdated() throws JsonProcessingException { + public void shouldNotTryToSaveFileIfFetchedVendorListHasInvalidLastUpdated() throws JsonProcessingException { // given final VendorList vendorList = VendorList.of(1, null, null); givenHttpClientReturnsResponse(200, mapper.writeValueAsString(vendorList)); @@ -358,11 +300,11 @@ public void shouldNotAskToSaveFileIfFetchedVendorListHasInvalidLastUpdated() thr // then verify(httpClient).get(anyString(), anyLong()); - verify(fileSystem, never()).writeFile(any(), any()); + verify(vendorListFileStore, never()).saveToFile(any(), anyString(), anyString()); } @Test - public void shouldNotAskToSaveFileIfFetchedVendorListHasNoVendors() throws JsonProcessingException { + public void shouldNotTryToSaveFileIfFetchedVendorListHasNoVendors() throws JsonProcessingException { // given final VendorList vendorList = VendorList.of(1, new Date(), null); givenHttpClientReturnsResponse(200, mapper.writeValueAsString(vendorList)); @@ -372,11 +314,11 @@ public void shouldNotAskToSaveFileIfFetchedVendorListHasNoVendors() throws JsonP // then verify(httpClient).get(anyString(), anyLong()); - verify(fileSystem, never()).writeFile(any(), any()); + verify(vendorListFileStore, never()).saveToFile(any(), anyString(), anyString()); } @Test - public void shouldNotAskToSaveFileIfFetchedVendorListHasEmptyVendors() throws JsonProcessingException { + public void shouldNotTryToSaveFileIfFetchedVendorListHasEmptyVendors() throws JsonProcessingException { // given final VendorList vendorList = VendorList.of(1, new Date(), emptyMap()); givenHttpClientReturnsResponse(200, mapper.writeValueAsString(vendorList)); @@ -386,11 +328,11 @@ public void shouldNotAskToSaveFileIfFetchedVendorListHasEmptyVendors() throws Js // then verify(httpClient).get(anyString(), anyLong()); - verify(fileSystem, never()).writeFile(any(), any()); + verify(vendorListFileStore, never()).saveToFile(any(), anyString(), anyString()); } @Test - public void shouldNotAskToSaveFileIfFetchedVendorListHasAtLeastOneInvalidVendor() throws JsonProcessingException { + public void shouldNotTryToSaveFileIfFetchedVendorListHasAtLeastOneInvalidVendor() throws JsonProcessingException { // given final VendorList vendorList = VendorList.of(1, new Date(), singletonMap(1, Vendor.builder().build())); givenHttpClientReturnsResponse(200, mapper.writeValueAsString(vendorList)); @@ -400,7 +342,7 @@ public void shouldNotAskToSaveFileIfFetchedVendorListHasAtLeastOneInvalidVendor( // then verify(httpClient).get(anyString(), anyLong()); - verify(fileSystem, never()).writeFile(any(), any()); + verify(vendorListFileStore, never()).saveToFile(any(), anyString(), anyString()); } // File system related tests @@ -408,16 +350,20 @@ public void shouldNotAskToSaveFileIfFetchedVendorListHasAtLeastOneInvalidVendor( @Test public void shouldSaveFileWithExpectedPathAndContentIfVendorListNotFound() throws JsonProcessingException { // given - final String vendorListAsString = mapper.writeValueAsString(givenVendorList()); + final VendorList vendorList = givenVendorList(); + final String vendorListAsString = mapper.writeValueAsString(vendorList); givenHttpClientReturnsResponse(200, vendorListAsString); - // generate file path to avoid conflicts with path separators in different OS - final String filePath = new File("/cache/dir/1.json").getPath(); + given(vendorListFileStore.saveToFile(any(), anyString(), anyString())) + .willAnswer(inv -> Future.succeededFuture(inv.getArgument(0))); // when target.forVersion(1); // then - verify(fileSystem).writeFile(eq(filePath), eq(Buffer.buffer(vendorListAsString))); + verify(vendorListFileStore).saveToFile( + eq(VendorListResult.of(1, vendorListAsString, vendorList)), + eq(CACHE_DIR), + eq(GENERATION_VERSION)); } // In-memory cache related tests @@ -454,7 +400,8 @@ public void shouldReturnVendorListFromCache() throws JsonProcessingException { // given givenHttpClientReturnsResponse(200, mapper.writeValueAsString(givenVendorList())); - given(fileSystem.writeFile(anyString(), any())).willReturn(Future.succeededFuture()); + given(vendorListFileStore.saveToFile(any(), anyString(), anyString())) + .willAnswer(inv -> Future.succeededFuture(inv.getArgument(0))); // when target.forVersion(1); // populate cache @@ -501,8 +448,8 @@ public void shouldKeepPurposesForAllVendors() throws JsonProcessingException { final VendorList vendorList = VendorList.of(1, new Date(), idToVendor); givenHttpClientReturnsResponse(200, mapper.writeValueAsString(vendorList)); - given(fileSystem.writeFile(anyString(), any())) - .willReturn(Future.succeededFuture()); + given(vendorListFileStore.saveToFile(any(), anyString(), anyString())) + .willAnswer(inv -> Future.succeededFuture(inv.getArgument(0))); // when target.forVersion(1); // populate cache @@ -569,7 +516,8 @@ public void shouldIncrementVendorListErrorMetricWhenFileIsNotSaved() throws Json // given givenHttpClientReturnsResponse(200, mapper.writeValueAsString(givenVendorList())); - given(fileSystem.writeFile(anyString(), any())).willReturn(Future.failedFuture("error")); + given(vendorListFileStore.saveToFile(any(), anyString(), anyString())) + .willReturn(Future.failedFuture("error")); // when target.forVersion(1); @@ -583,7 +531,8 @@ public void shouldIncrementVendorListOkMetric() throws JsonProcessingException { // given givenHttpClientReturnsResponse(200, mapper.writeValueAsString(givenVendorList())); - given(fileSystem.writeFile(anyString(), any())).willReturn(Future.succeededFuture()); + given(vendorListFileStore.saveToFile(any(), anyString(), anyString())) + .willAnswer(inv -> Future.succeededFuture(inv.getArgument(0))); // when target.forVersion(1); @@ -609,6 +558,10 @@ public void shouldIncrementVendorListFallbackMetric() { } private static VendorList givenVendorList() { + return VendorList.of(1, new Date(), givenVendorMap()); + } + + private static Map givenVendorMap() { final Vendor vendor = Vendor.builder() .id(52) .purposes(EnumSet.of(ONE)) @@ -618,7 +571,7 @@ private static VendorList givenVendorList() { .features(EnumSet.noneOf(Feature.class)) .specialFeatures(EnumSet.noneOf(SpecialFeature.class)) .build(); - return VendorList.of(1, new Date(), singletonMap(52, vendor)); + return singletonMap(52, vendor); } private void givenHttpClientReturnsResponse(int statusCode, String response) { diff --git a/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListUtilTest.java b/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListUtilTest.java new file mode 100644 index 00000000000..8ff016e924b --- /dev/null +++ b/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListUtilTest.java @@ -0,0 +1,192 @@ +package org.prebid.server.privacy.gdpr.vendorlist; + +import com.fasterxml.jackson.core.JsonProcessingException; +import org.junit.jupiter.api.Test; +import org.prebid.server.VertxTest; +import org.prebid.server.exception.PreBidException; +import org.prebid.server.privacy.gdpr.vendorlist.proto.Feature; +import org.prebid.server.privacy.gdpr.vendorlist.proto.PurposeCode; +import org.prebid.server.privacy.gdpr.vendorlist.proto.SpecialFeature; +import org.prebid.server.privacy.gdpr.vendorlist.proto.SpecialPurpose; +import org.prebid.server.privacy.gdpr.vendorlist.proto.Vendor; +import org.prebid.server.privacy.gdpr.vendorlist.proto.VendorList; + +import java.util.Date; +import java.util.EnumSet; +import java.util.Map; + +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.prebid.server.privacy.gdpr.vendorlist.proto.PurposeCode.ONE; +import static org.prebid.server.privacy.gdpr.vendorlist.proto.PurposeCode.TWO; + +public class VendorListUtilTest extends VertxTest { + + @Test + public void parseVendorListShouldReturnVendorListWhenContentIsValid() throws JsonProcessingException { + // given + final VendorList vendorList = givenVendorList(); + final String content = mapper.writeValueAsString(vendorList); + + // when + final VendorList result = VendorListUtil.parseVendorList(content, jacksonMapper); + + // then + assertThat(result).isEqualTo(vendorList); + } + + @Test + public void parseVendorListShouldThrowExceptionWhenContentCannotBeParsed() { + // when and then + assertThatThrownBy(() -> VendorListUtil.parseVendorList("invalid", jacksonMapper)) + .isInstanceOf(PreBidException.class) + .hasMessage("Cannot parse vendor list from: invalid"); + } + + @Test + public void vendorListIsValidShouldReturnTrueWhenVendorListIsValid() { + // when and then + assertThat(VendorListUtil.vendorListIsValid(givenVendorList())).isTrue(); + } + + @Test + public void vendorListIsValidShouldReturnFalseWhenVendorListVersionIsNull() { + // given + final VendorList vendorList = VendorList.of(null, new Date(), givenVendorMap()); + + // when and then + assertThat(VendorListUtil.vendorListIsValid(vendorList)).isFalse(); + } + + @Test + public void vendorListIsValidShouldReturnFalseWhenLastUpdatedIsNull() { + // given + final VendorList vendorList = VendorList.of(1, null, givenVendorMap()); + + // when and then + assertThat(VendorListUtil.vendorListIsValid(vendorList)).isFalse(); + } + + @Test + public void vendorListIsValidShouldReturnFalseWhenVendorsIsNull() { + // given + final VendorList vendorList = VendorList.of(1, new Date(), null); + + // when and then + assertThat(VendorListUtil.vendorListIsValid(vendorList)).isFalse(); + } + + @Test + public void vendorListIsValidShouldReturnFalseWhenVendorsIsEmpty() { + // given + final VendorList vendorList = VendorList.of(1, new Date(), emptyMap()); + + // when and then + assertThat(VendorListUtil.vendorListIsValid(vendorList)).isFalse(); + } + + @Test + public void vendorListIsValidShouldReturnFalseWhenVendorIsNull() { + // given + final VendorList vendorList = VendorList.of(1, new Date(), singletonMap(1, null)); + + // when and then + assertThat(VendorListUtil.vendorListIsValid(vendorList)).isFalse(); + } + + @Test + public void vendorListIsValidShouldReturnFalseWhenVendorIdIsNull() { + // given + final Vendor vendor = givenVendor().toBuilder().id(null).build(); + final VendorList vendorList = givenVendorListWithVendor(vendor); + + // when and then + assertThat(VendorListUtil.vendorListIsValid(vendorList)).isFalse(); + } + + @Test + public void vendorListIsValidShouldReturnFalseWhenVendorPurposesIsNull() { + // given + final Vendor vendor = givenVendor().toBuilder().purposes(null).build(); + final VendorList vendorList = givenVendorListWithVendor(vendor); + + // when and then + assertThat(VendorListUtil.vendorListIsValid(vendorList)).isFalse(); + } + + @Test + public void vendorListIsValidShouldReturnFalseWhenVendorLegIntPurposesIsNull() { + // given + final Vendor vendor = givenVendor().toBuilder().legIntPurposes(null).build(); + final VendorList vendorList = givenVendorListWithVendor(vendor); + + // when and then + assertThat(VendorListUtil.vendorListIsValid(vendorList)).isFalse(); + } + + @Test + public void vendorListIsValidShouldReturnFalseWhenVendorFlexiblePurposesIsNull() { + // given + final Vendor vendor = givenVendor().toBuilder().flexiblePurposes(null).build(); + final VendorList vendorList = givenVendorListWithVendor(vendor); + + // when and then + assertThat(VendorListUtil.vendorListIsValid(vendorList)).isFalse(); + } + + @Test + public void vendorListIsValidShouldReturnFalseWhenVendorSpecialPurposesIsNull() { + // given + final Vendor vendor = givenVendor().toBuilder().specialPurposes(null).build(); + final VendorList vendorList = givenVendorListWithVendor(vendor); + + // when and then + assertThat(VendorListUtil.vendorListIsValid(vendorList)).isFalse(); + } + + @Test + public void vendorListIsValidShouldReturnFalseWhenVendorFeaturesIsNull() { + // given + final Vendor vendor = givenVendor().toBuilder().features(null).build(); + final VendorList vendorList = givenVendorListWithVendor(vendor); + + // when and then + assertThat(VendorListUtil.vendorListIsValid(vendorList)).isFalse(); + } + + @Test + public void vendorListIsValidShouldReturnFalseWhenVendorSpecialFeaturesIsNull() { + // given + final Vendor vendor = givenVendor().toBuilder().specialFeatures(null).build(); + final VendorList vendorList = givenVendorListWithVendor(vendor); + + // when and then + assertThat(VendorListUtil.vendorListIsValid(vendorList)).isFalse(); + } + + private static VendorList givenVendorList() { + return VendorList.of(1, new Date(), givenVendorMap()); + } + + private static VendorList givenVendorListWithVendor(Vendor vendor) { + return VendorList.of(1, new Date(), singletonMap(vendor.getId() != null ? vendor.getId() : 1, vendor)); + } + + private static Map givenVendorMap() { + return singletonMap(52, givenVendor()); + } + + private static Vendor givenVendor() { + return Vendor.builder() + .id(52) + .purposes(EnumSet.of(ONE)) + .legIntPurposes(EnumSet.of(TWO)) + .flexiblePurposes(EnumSet.noneOf(PurposeCode.class)) + .specialPurposes(EnumSet.noneOf(SpecialPurpose.class)) + .features(EnumSet.noneOf(Feature.class)) + .specialFeatures(EnumSet.noneOf(SpecialFeature.class)) + .build(); + } +} diff --git a/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VersionedVendorListServiceTest.java b/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VersionedVendorListServiceTest.java index 8437698b9f0..4ca880f61e0 100644 --- a/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VersionedVendorListServiceTest.java +++ b/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VersionedVendorListServiceTest.java @@ -2,29 +2,47 @@ import com.iabtcf.decoder.TCString; import com.iabtcf.encoder.TCStringEncoder; +import io.vertx.core.Future; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.prebid.server.privacy.gdpr.vendorlist.proto.Vendor; +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneOffset; +import java.util.Map; import java.util.concurrent.ThreadLocalRandom; +import static java.util.Collections.emptyMap; +import static java.util.Collections.emptySet; +import static java.util.Collections.singleton; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.verify; +import static org.prebid.server.assertion.FutureAssertion.assertThat; @ExtendWith(MockitoExtension.class) public class VersionedVendorListServiceTest { - private VersionedVendorListService versionedVendorListService; + private static final Instant NOW = Instant.parse("2024-06-01T12:00:00Z"); + + private VersionedVendorListService target; @Mock private VendorListService vendorListServiceV2; @Mock private VendorListService vendorListServiceV3; + @Mock + private LiveVendorListService liveVendorListService; @BeforeEach public void setUp() { - versionedVendorListService = new VersionedVendorListService(vendorListServiceV2, vendorListServiceV3); + target = new VersionedVendorListService( + vendorListServiceV2, vendorListServiceV3, liveVendorListService, Clock.fixed(NOW, ZoneOffset.UTC)); } @Test @@ -36,9 +54,10 @@ public void versionedVendorListServiceShouldTreatTcfPolicyLessThanFourAsVendorLi .tcfPolicyVersion(tcfPolicyVersion) .vendorListVersion(12) .toTCString(); + given(vendorListServiceV2.forVersion(anyInt())).willReturn(Future.succeededFuture(emptyMap())); // when - versionedVendorListService.forConsent(consent); + target.forConsent(consent); // then verify(vendorListServiceV2).forVersion(12); @@ -53,11 +72,64 @@ public void versionedVendorListServiceShouldTreatTcfPolicyGreaterOrEqualFourAsVe .tcfPolicyVersion(tcfPolicyVersion) .vendorListVersion(12) .toTCString(); + given(vendorListServiceV3.forVersion(anyInt())).willReturn(Future.succeededFuture(emptyMap())); // when - versionedVendorListService.forConsent(consent); + target.forConsent(consent); // then verify(vendorListServiceV3).forVersion(12); } + + @Test + public void forConsentShouldRemoveVendorsMarkedDeletedInRequestedGvl() { + // given + final Vendor deletedVendor = Vendor.empty(2).toBuilder() + .deletedDate(Instant.parse("2024-01-01T00:00:00Z")) + .build(); + final Vendor activeVendor = Vendor.empty(52); + final Map vendorList = Map.of(2, deletedVendor, 52, activeVendor); + final TCString consent = TCStringEncoder.newBuilder() + .version(2) + .tcfPolicyVersion(3) + .vendorListVersion(12) + .toTCString(); + + given(vendorListServiceV2.forVersion(anyInt())).willReturn(Future.succeededFuture(vendorList)); + given(liveVendorListService.getDeletedVendorIds()).willReturn(emptySet()); + + // when and then + assertThat(target.forConsent(consent)) + .isSucceeded() + .unwrap() + .satisfies(result -> { + assertThat(result.get(2)).isNull(); + assertThat(result.get(52)).isSameAs(activeVendor); + }); + } + + @Test + public void forConsentShouldRemoveVendorsMarkedDeletedInLiveGvl() { + // given + final Vendor deletedVendor = Vendor.empty(1); + final Vendor activeVendor = Vendor.empty(52); + final Map vendorList = Map.of(1, deletedVendor, 52, activeVendor); + final TCString consent = TCStringEncoder.newBuilder() + .version(2) + .tcfPolicyVersion(3) + .vendorListVersion(12) + .toTCString(); + + given(vendorListServiceV2.forVersion(anyInt())).willReturn(Future.succeededFuture(vendorList)); + given(liveVendorListService.getDeletedVendorIds()).willReturn(singleton(1)); + + // when and then + assertThat(target.forConsent(consent)) + .isSucceeded() + .unwrap() + .satisfies(result -> { + assertThat(result.get(1)).isNull(); + assertThat(result.get(52)).isSameAs(activeVendor); + }); + } } diff --git a/src/test/resources/org/prebid/server/it/test-application.properties b/src/test/resources/org/prebid/server/it/test-application.properties index 9df120154d8..8c73beb8da8 100644 --- a/src/test/resources/org/prebid/server/it/test-application.properties +++ b/src/test/resources/org/prebid/server/it/test-application.properties @@ -759,4 +759,5 @@ gdpr.host-vendor-id=1 gdpr.default-value=1 gdpr.vendorlist.v2.cache-dir=src/test/resources/org/prebid/server/it/gdpr-vendorlist2 gdpr.vendorlist.v3.cache-dir=src/test/resources/org/prebid/server/it/gdpr-vendorlist3 +gdpr.vendorlist.live.startup-cache-dir=src/test/resources/org/prebid/server/it/gdpr-vendorlist3 ccpa.enforce=false From eb4ee8267e5166506055488bec1cfcf8a29a063c Mon Sep 17 00:00:00 2001 From: Dubyk Danylo <45672370+CTMBNara@users.noreply.github.com> Date: Thu, 23 Jul 2026 16:35:59 +0200 Subject: [PATCH 4/8] Modularity: Add support for endpoints with same path but different method (#4372) --- .../v1/model/BidderInvocationContextImpl.java | 3 + .../requestfactory/AmpRequestFactory.java | 3 +- .../requestfactory/AuctionRequestFactory.java | 3 +- .../requestfactory/Ortb2RequestFactory.java | 4 +- .../requestfactory/VideoRequestFactory.java | 9 +- .../hooks/execution/HookStageExecutor.java | 82 ++++--- .../hooks/execution/model/ExecutionPlan.java | 6 +- .../execution/model/HookExecutionContext.java | 5 +- .../execution/model/HookHttpEndpoint.java | 35 +++ .../execution/v1/InvocationContextImpl.java | 3 + .../server/hooks/v1/InvocationContext.java | 3 + ...cutionPlanEndpointsConfigDeserializer.java | 133 +++++++++++ .../org/prebid/server/model/Endpoint.java | 3 +- .../EnrichingApplicationSettings.java | 2 +- .../LiveintentAnalyticsReporterTest.java | 4 +- .../server/auction/ExchangeServiceTest.java | 26 +-- .../auction/HooksMetricsServiceTest.java | 6 +- .../requestfactory/AmpRequestFactoryTest.java | 13 +- .../Ortb2RequestFactoryTest.java | 8 +- .../handler/openrtb2/AmpHandlerTest.java | 12 +- .../handler/openrtb2/AuctionHandlerTest.java | 12 +- .../handler/openrtb2/VideoHandlerTest.java | 4 +- .../execution/HookStageExecutorTest.java | 215 +++++++++--------- .../abtest/ABTestHookProviderTest.java | 10 +- ...onPlanEndpointsConfigDeserializerTest.java | 171 ++++++++++++++ .../EnrichingApplicationSettingsTest.java | 3 +- 26 files changed, 559 insertions(+), 219 deletions(-) create mode 100644 src/main/java/org/prebid/server/hooks/execution/model/HookHttpEndpoint.java create mode 100644 src/main/java/org/prebid/server/json/deserializer/ExecutionPlanEndpointsConfigDeserializer.java create mode 100644 src/test/java/org/prebid/server/json/deserializer/ExecutionPlanEndpointsConfigDeserializerTest.java diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/model/BidderInvocationContextImpl.java b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/model/BidderInvocationContextImpl.java index 5812885d88d..c64e3a4b2f6 100644 --- a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/model/BidderInvocationContextImpl.java +++ b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/model/BidderInvocationContextImpl.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.iab.openrtb.request.BidRequest; +import io.vertx.core.http.HttpMethod; import lombok.Builder; import lombok.Value; import lombok.experimental.Accessors; @@ -21,6 +22,8 @@ public class BidderInvocationContextImpl implements BidderInvocationContext { Timeout timeout; + HttpMethod httpMethod; + Endpoint endpoint; AuctionContext auctionContext; diff --git a/src/main/java/org/prebid/server/auction/requestfactory/AmpRequestFactory.java b/src/main/java/org/prebid/server/auction/requestfactory/AmpRequestFactory.java index 96c5539eaee..1dd2c18c921 100644 --- a/src/main/java/org/prebid/server/auction/requestfactory/AmpRequestFactory.java +++ b/src/main/java/org/prebid/server/auction/requestfactory/AmpRequestFactory.java @@ -31,6 +31,7 @@ import org.prebid.server.auction.privacy.contextfactory.AmpPrivacyContextFactory; import org.prebid.server.auction.versionconverter.BidRequestOrtbVersionConversionManager; import org.prebid.server.exception.InvalidRequestException; +import org.prebid.server.hooks.execution.model.HookHttpEndpoint; import org.prebid.server.json.JacksonMapper; import org.prebid.server.metric.MetricName; import org.prebid.server.model.CaseInsensitiveMultiMap; @@ -142,7 +143,7 @@ public Future fromRequest(RoutingContext routingContext, long st final String body = routingContext.body().asString(); final AuctionContext initialAuctionContext = ortb2RequestFactory.createAuctionContext( - Endpoint.openrtb2_amp, MetricName.amp); + HookHttpEndpoint.AMP, MetricName.amp); return ortb2RequestFactory.executeEntrypointHooks(routingContext, body, initialAuctionContext) .compose(httpRequest -> parseBidRequest(initialAuctionContext, httpRequest) diff --git a/src/main/java/org/prebid/server/auction/requestfactory/AuctionRequestFactory.java b/src/main/java/org/prebid/server/auction/requestfactory/AuctionRequestFactory.java index d873af3e696..7e6810e173c 100644 --- a/src/main/java/org/prebid/server/auction/requestfactory/AuctionRequestFactory.java +++ b/src/main/java/org/prebid/server/auction/requestfactory/AuctionRequestFactory.java @@ -21,6 +21,7 @@ import org.prebid.server.bidadjustments.BidAdjustmentsEnricher; import org.prebid.server.cookie.CookieDeprecationService; import org.prebid.server.exception.InvalidRequestException; +import org.prebid.server.hooks.execution.model.HookHttpEndpoint; import org.prebid.server.json.JacksonMapper; import org.prebid.server.metric.MetricName; import org.prebid.server.model.Endpoint; @@ -104,7 +105,7 @@ public Future parseRequest(RoutingContext routingContext, long s } final AuctionContext initialAuctionContext = ortb2RequestFactory.createAuctionContext( - Endpoint.openrtb2_auction, MetricName.openrtb2web); + HookHttpEndpoint.POST_AUCTION, MetricName.openrtb2web); return ortb2RequestFactory.executeEntrypointHooks(routingContext, body, initialAuctionContext) .compose(httpRequest -> parseBidRequest(httpRequest, initialAuctionContext.getPrebidErrors()) diff --git a/src/main/java/org/prebid/server/auction/requestfactory/Ortb2RequestFactory.java b/src/main/java/org/prebid/server/auction/requestfactory/Ortb2RequestFactory.java index 2eaa340509c..e7d42855464 100644 --- a/src/main/java/org/prebid/server/auction/requestfactory/Ortb2RequestFactory.java +++ b/src/main/java/org/prebid/server/auction/requestfactory/Ortb2RequestFactory.java @@ -42,6 +42,7 @@ import org.prebid.server.geolocation.model.GeoInfo; import org.prebid.server.hooks.execution.HookStageExecutor; import org.prebid.server.hooks.execution.model.HookExecutionContext; +import org.prebid.server.hooks.execution.model.HookHttpEndpoint; import org.prebid.server.hooks.execution.model.HookStageExecutionResult; import org.prebid.server.hooks.v1.auction.AuctionRequestPayload; import org.prebid.server.hooks.v1.entrypoint.EntrypointPayload; @@ -51,7 +52,6 @@ import org.prebid.server.metric.MetricName; import org.prebid.server.metric.Metrics; import org.prebid.server.model.CaseInsensitiveMultiMap; -import org.prebid.server.model.Endpoint; import org.prebid.server.model.HttpRequestContext; import org.prebid.server.model.UpdateResult; import org.prebid.server.privacy.model.PrivacyContext; @@ -147,7 +147,7 @@ public Ortb2RequestFactory(int timeoutAdjustmentFactor, this.metrics = Objects.requireNonNull(metrics); } - public AuctionContext createAuctionContext(Endpoint endpoint, MetricName requestTypeMetric) { + public AuctionContext createAuctionContext(HookHttpEndpoint endpoint, MetricName requestTypeMetric) { return AuctionContext.builder() .requestTypeMetric(requestTypeMetric) .prebidErrors(new ArrayList<>()) diff --git a/src/main/java/org/prebid/server/auction/requestfactory/VideoRequestFactory.java b/src/main/java/org/prebid/server/auction/requestfactory/VideoRequestFactory.java index 811db804fb9..9c663bd55d7 100644 --- a/src/main/java/org/prebid/server/auction/requestfactory/VideoRequestFactory.java +++ b/src/main/java/org/prebid/server/auction/requestfactory/VideoRequestFactory.java @@ -25,6 +25,7 @@ import org.prebid.server.auction.privacy.contextfactory.AuctionPrivacyContextFactory; import org.prebid.server.auction.versionconverter.BidRequestOrtbVersionConversionManager; import org.prebid.server.exception.InvalidRequestException; +import org.prebid.server.hooks.execution.model.HookHttpEndpoint; import org.prebid.server.json.DecodeException; import org.prebid.server.json.JacksonMapper; import org.prebid.server.metric.MetricName; @@ -105,7 +106,7 @@ public Future> fromRequest(RoutingContext routingC final List podErrors = new ArrayList<>(); final AuctionContext initialAuctionContext = ortb2RequestFactory.createAuctionContext( - Endpoint.openrtb2_video, MetricName.video); + HookHttpEndpoint.VIDEO, MetricName.video); return ortb2RequestFactory.executeEntrypointHooks(routingContext, body, initialAuctionContext) .compose(httpRequest -> createBidRequest(httpRequest) @@ -120,9 +121,9 @@ public Future> fromRequest(RoutingContext routingC .map(auctionContext -> auctionContext.with(debugResolver.debugContextFrom(auctionContext))) .compose(auctionContext -> ortb2RequestFactory.limitImpressions( - auctionContext.getAccount(), - auctionContext.getBidRequest(), - auctionContext.getDebugWarnings()) + auctionContext.getAccount(), + auctionContext.getBidRequest(), + auctionContext.getDebugWarnings()) .map(auctionContext::with)) .compose(auctionContext -> ortb2RequestFactory.validateRequest( diff --git a/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java b/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java index 4f8a1f3f209..1761e402351 100644 --- a/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java +++ b/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java @@ -26,6 +26,7 @@ import org.prebid.server.hooks.execution.model.ExecutionGroup; import org.prebid.server.hooks.execution.model.ExecutionPlan; import org.prebid.server.hooks.execution.model.HookExecutionContext; +import org.prebid.server.hooks.execution.model.HookHttpEndpoint; import org.prebid.server.hooks.execution.model.HookId; import org.prebid.server.hooks.execution.model.HookStageExecutionResult; import org.prebid.server.hooks.execution.model.Stage; @@ -57,7 +58,6 @@ import org.prebid.server.json.DecodeException; import org.prebid.server.json.JacksonMapper; import org.prebid.server.model.CaseInsensitiveMultiMap; -import org.prebid.server.model.Endpoint; import org.prebid.server.settings.model.Account; import org.prebid.server.settings.model.AccountHooksConfiguration; import org.prebid.server.settings.model.HooksAdminConfig; @@ -193,7 +193,7 @@ public Future> executeEntrypointStag AuctionContext auctionContext) { final HookExecutionContext context = auctionContext.getHookExecutionContext(); - final Endpoint endpoint = context.getEndpoint(); + final HookHttpEndpoint endpoint = context.getEndpoint(); return stageExecutor(StageWithHookType.ENTRYPOINT, ENTITY_HTTP_REQUEST, context) .withExecutionPlan(planForEntrypointStage(endpoint)) @@ -212,12 +212,9 @@ public Future> executeRawAuction final BidRequest bidRequest = auctionContext.getBidRequest(); final Account account = auctionContext.getAccount(); final HookExecutionContext context = auctionContext.getHookExecutionContext(); + final HookHttpEndpoint endpoint = context.getEndpoint(); - final Endpoint endpoint = context.getEndpoint(); - - return this - .stageExecutor( - StageWithHookType.RAW_AUCTION_REQUEST, ENTITY_AUCTION_REQUEST, context, account, endpoint) + return stageExecutor(StageWithHookType.RAW_AUCTION_REQUEST, ENTITY_AUCTION_REQUEST, context, account, endpoint) .withInitialPayload(AuctionRequestPayloadImpl.of(bidRequest)) .withInvocationContextProvider(auctionInvocationContextProvider(endpoint, auctionContext)) .withRejectAllowed(true) @@ -231,12 +228,10 @@ public Future> executeProcessedA final BidRequest bidRequest = auctionContext.getBidRequest(); final Account account = auctionContext.getAccount(); final HookExecutionContext context = auctionContext.getHookExecutionContext(); + final HookHttpEndpoint endpoint = context.getEndpoint(); - final Endpoint endpoint = context.getEndpoint(); - - return this - .stageExecutor( - StageWithHookType.PROCESSED_AUCTION_REQUEST, ENTITY_AUCTION_REQUEST, context, account, endpoint) + return stageExecutor( + StageWithHookType.PROCESSED_AUCTION_REQUEST, ENTITY_AUCTION_REQUEST, context, account, endpoint) .withInitialPayload(AuctionRequestPayloadImpl.of(bidRequest)) .withInvocationContextProvider(auctionInvocationContextProvider(endpoint, auctionContext)) .withRejectAllowed(true) @@ -245,17 +240,16 @@ public Future> executeProcessedA } public Future> executeBidderRequestStage( - BidderRequest bidderRequest, AuctionContext auctionContext) { + BidderRequest bidderRequest, + AuctionContext auctionContext) { final Account account = auctionContext.getAccount(); final HookExecutionContext context = auctionContext.getHookExecutionContext(); + final HookHttpEndpoint endpoint = context.getEndpoint(); final String bidder = bidderRequest.getBidder(); - final Endpoint endpoint = context.getEndpoint(); - - return this - .stageExecutor(StageWithHookType.BIDDER_REQUEST, bidder, context, account, endpoint) + return stageExecutor(StageWithHookType.BIDDER_REQUEST, bidder, context, account, endpoint) .withInitialPayload(BidderRequestPayloadImpl.of(bidderRequest.getBidRequest())) .withInvocationContextProvider(bidderInvocationContextProvider(endpoint, auctionContext, bidder)) .withRejectAllowed(true) @@ -269,14 +263,12 @@ public Future> executeRawBidderR final Account account = auctionContext.getAccount(); final HookExecutionContext context = auctionContext.getHookExecutionContext(); + final HookHttpEndpoint endpoint = context.getEndpoint(); final List bids = bidderResponse.getSeatBid().getBids(); final String bidder = bidderResponse.getBidder(); - final Endpoint endpoint = context.getEndpoint(); - - return this - .stageExecutor(StageWithHookType.RAW_BIDDER_RESPONSE, bidder, context, account, endpoint) + return stageExecutor(StageWithHookType.RAW_BIDDER_RESPONSE, bidder, context, account, endpoint) .withInitialPayload(BidderResponsePayloadImpl.of(bids)) .withInvocationContextProvider(bidderInvocationContextProvider(endpoint, auctionContext, bidder)) .withRejectAllowed(true) @@ -290,12 +282,11 @@ public Future> executeProcessedB final Account account = auctionContext.getAccount(); final HookExecutionContext context = auctionContext.getHookExecutionContext(); + final HookHttpEndpoint endpoint = context.getEndpoint(); final List bids = bidderResponse.getSeatBid().getBids(); final String bidder = bidderResponse.getBidder(); - final Endpoint endpoint = context.getEndpoint(); - return stageExecutor(StageWithHookType.PROCESSED_BIDDER_RESPONSE, bidder, context, account, endpoint) .withInitialPayload(BidderResponsePayloadImpl.of(bids)) .withInvocationContextProvider(bidderInvocationContextProvider(endpoint, auctionContext, bidder)) @@ -310,12 +301,14 @@ public Future> execute final Account account = auctionContext.getAccount(); final HookExecutionContext context = auctionContext.getHookExecutionContext(); - - final Endpoint endpoint = context.getEndpoint(); + final HookHttpEndpoint endpoint = context.getEndpoint(); return stageExecutor( - StageWithHookType.ALL_PROCESSED_BID_RESPONSES, ENTITY_ALL_PROCESSED_BID_RESPONSES, - context, account, endpoint) + StageWithHookType.ALL_PROCESSED_BID_RESPONSES, + ENTITY_ALL_PROCESSED_BID_RESPONSES, + context, + account, + endpoint) .withInitialPayload(AllProcessedBidResponsesPayloadImpl.of(bidderResponses)) .withInvocationContextProvider(auctionInvocationContextProvider(endpoint, auctionContext)) .withRejectAllowed(false) @@ -329,8 +322,7 @@ public Future> executeAuctionRe final Account account = ObjectUtils.defaultIfNull(auctionContext.getAccount(), EMPTY_ACCOUNT); final HookExecutionContext context = auctionContext.getHookExecutionContext(); - - final Endpoint endpoint = context.getEndpoint(); + final HookHttpEndpoint endpoint = context.getEndpoint(); return stageExecutor(StageWithHookType.AUCTION_RESPONSE, ENTITY_AUCTION_RESPONSE, context, account, endpoint) .withInitialPayload(AuctionResponsePayloadImpl.of(bidResponse)) @@ -345,8 +337,7 @@ public Future> executeExitpointStage( final Account account = ObjectUtils.defaultIfNull(auctionContext.getAccount(), EMPTY_ACCOUNT); final HookExecutionContext context = auctionContext.getHookExecutionContext(); - - final Endpoint endpoint = context.getEndpoint(); + final HookHttpEndpoint endpoint = context.getEndpoint(); return stageExecutor(StageWithHookType.EXITPOINT, ENTITY_HTTP_RESPONSE, context, account, endpoint) .withInitialPayload(ExitpointPayloadImpl.of(responseHeaders, responseBody)) @@ -371,7 +362,7 @@ private StageExecutor modulesExecutionForAccount(Account account) { return DefaultedMap.defaultedMap(resultModulesExecution, !isConfigToInvokeRequired); } - private StageExecutionPlan planForEntrypointStage(Endpoint endpoint) { + private StageExecutionPlan planForEntrypointStage(HookHttpEndpoint endpoint) { return effectiveStagePlanFrom(ExecutionPlan.empty(), endpoint, Stage.entrypoint); } - private StageExecutionPlan planForStage(Account account, Endpoint endpoint, Stage stage) { + private StageExecutionPlan planForStage(Account account, HookHttpEndpoint endpoint, Stage stage) { return effectiveStagePlanFrom(effectiveExecutionPlanFor(account), endpoint, stage); } - private StageExecutionPlan effectiveStagePlanFrom( - ExecutionPlan accountExecutionPlan, Endpoint endpoint, Stage stage) { + private StageExecutionPlan effectiveStagePlanFrom(ExecutionPlan accountExecutionPlan, + HookHttpEndpoint endpoint, + Stage stage) { final StageExecutionPlan hostStageExecutionPlan = stagePlanFrom(hostExecutionPlan, endpoint, stage); final StageExecutionPlan accountStageExecutionPlan = stagePlanFrom(accountExecutionPlan, endpoint, stage); @@ -428,7 +420,10 @@ private StageExecutionPlan effectiveStagePlanFrom( return StageExecutionPlan.of(combinedGroups); } - private static StageExecutionPlan stagePlanFrom(ExecutionPlan executionPlan, Endpoint endpoint, Stage stage) { + private static StageExecutionPlan stagePlanFrom(ExecutionPlan executionPlan, + HookHttpEndpoint endpoint, + Stage stage) { + return MapUtils.emptyIfNull(executionPlan.getEndpoints()) .getOrDefault(endpoint, EndpointExecutionPlan.empty()) .getStages() @@ -471,23 +466,23 @@ private HookProvider hookCatalog.hookById(hookId, stage); } - private InvocationContextProvider invocationContextProvider(Endpoint endpoint) { + private InvocationContextProvider invocationContextProvider(HookHttpEndpoint endpoint) { return (timeout, hookId, moduleContext) -> invocationContext(endpoint, timeout); } - private InvocationContextImpl invocationContext(Endpoint endpoint, Long timeout) { - return InvocationContextImpl.of(createTimeout(timeout), endpoint); + private InvocationContextImpl invocationContext(HookHttpEndpoint endpoint, Long timeout) { + return InvocationContextImpl.of(createTimeout(timeout), endpoint.httpMethod(), endpoint.endpoint()); } private InvocationContextProvider auctionInvocationContextProvider( - Endpoint endpoint, + HookHttpEndpoint endpoint, AuctionContext auctionContext) { return (timeout, hookId, moduleContext) -> auctionInvocationContext( endpoint, timeout, auctionContext, hookId, moduleContext); } - private AuctionInvocationContextImpl auctionInvocationContext(Endpoint endpoint, + private AuctionInvocationContextImpl auctionInvocationContext(HookHttpEndpoint endpoint, Long timeout, AuctionContext auctionContext, HookId hookId, @@ -502,7 +497,7 @@ private AuctionInvocationContextImpl auctionInvocationContext(Endpoint endpoint, } private InvocationContextProvider bidderInvocationContextProvider( - Endpoint endpoint, + HookHttpEndpoint endpoint, AuctionContext auctionContext, String bidder) { @@ -561,7 +556,6 @@ private static boolean isABTestApplicable(ABTest abTest, String account) { } //todo: should it be more strict? e.g. allowing rejecting only imps/bids on the particular stages - private HookStageExecutionResult rejectAll(AuctionContext auctionContext, HookStageExecutionResult result) { diff --git a/src/main/java/org/prebid/server/hooks/execution/model/ExecutionPlan.java b/src/main/java/org/prebid/server/hooks/execution/model/ExecutionPlan.java index 7137cef162d..f9407738165 100644 --- a/src/main/java/org/prebid/server/hooks/execution/model/ExecutionPlan.java +++ b/src/main/java/org/prebid/server/hooks/execution/model/ExecutionPlan.java @@ -1,8 +1,9 @@ package org.prebid.server.hooks.execution.model; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import lombok.Value; -import org.prebid.server.model.Endpoint; +import org.prebid.server.json.deserializer.ExecutionPlanEndpointsConfigDeserializer; import java.util.List; import java.util.Map; @@ -15,7 +16,8 @@ public class ExecutionPlan { @JsonProperty("abtests") List abTests; - Map endpoints; + @JsonDeserialize(using = ExecutionPlanEndpointsConfigDeserializer.class) + Map endpoints; public static ExecutionPlan empty() { return EMPTY; diff --git a/src/main/java/org/prebid/server/hooks/execution/model/HookExecutionContext.java b/src/main/java/org/prebid/server/hooks/execution/model/HookExecutionContext.java index 32129252d41..27bae4d1c4e 100644 --- a/src/main/java/org/prebid/server/hooks/execution/model/HookExecutionContext.java +++ b/src/main/java/org/prebid/server/hooks/execution/model/HookExecutionContext.java @@ -1,7 +1,6 @@ package org.prebid.server.hooks.execution.model; import lombok.Value; -import org.prebid.server.model.Endpoint; import java.util.EnumMap; import java.util.HashMap; @@ -11,13 +10,13 @@ @Value(staticConstructor = "of") public class HookExecutionContext { - Endpoint endpoint; + HookHttpEndpoint endpoint; EnumMap> stageOutcomes; Map moduleContexts = new HashMap<>(); - public static HookExecutionContext of(Endpoint endpoint) { + public static HookExecutionContext of(HookHttpEndpoint endpoint) { return of(endpoint, new EnumMap<>(Stage.class)); } } diff --git a/src/main/java/org/prebid/server/hooks/execution/model/HookHttpEndpoint.java b/src/main/java/org/prebid/server/hooks/execution/model/HookHttpEndpoint.java new file mode 100644 index 00000000000..67e76a513ce --- /dev/null +++ b/src/main/java/org/prebid/server/hooks/execution/model/HookHttpEndpoint.java @@ -0,0 +1,35 @@ +package org.prebid.server.hooks.execution.model; + +import com.fasterxml.jackson.annotation.JsonValue; +import io.vertx.core.http.HttpMethod; +import org.prebid.server.model.Endpoint; + +public enum HookHttpEndpoint { + + POST_AUCTION(HttpMethod.POST, Endpoint.openrtb2_auction), + AMP(HttpMethod.GET, Endpoint.openrtb2_amp), + VIDEO(HttpMethod.POST, Endpoint.openrtb2_video); + + private final HttpMethod httpMethod; + + private final Endpoint endpoint; + + HookHttpEndpoint(HttpMethod httpMethod, Endpoint endpoint) { + this.httpMethod = httpMethod; + this.endpoint = endpoint; + } + + public HttpMethod httpMethod() { + return httpMethod; + } + + public Endpoint endpoint() { + return endpoint; + } + + @JsonValue + @Override + public String toString() { + return httpMethod.name() + " " + endpoint.value(); + } +} diff --git a/src/main/java/org/prebid/server/hooks/execution/v1/InvocationContextImpl.java b/src/main/java/org/prebid/server/hooks/execution/v1/InvocationContextImpl.java index 99399d5ba6b..84ea304caee 100644 --- a/src/main/java/org/prebid/server/hooks/execution/v1/InvocationContextImpl.java +++ b/src/main/java/org/prebid/server/hooks/execution/v1/InvocationContextImpl.java @@ -1,5 +1,6 @@ package org.prebid.server.hooks.execution.v1; +import io.vertx.core.http.HttpMethod; import lombok.Value; import lombok.experimental.Accessors; import org.prebid.server.execution.timeout.Timeout; @@ -12,5 +13,7 @@ public class InvocationContextImpl implements InvocationContext { Timeout timeout; + HttpMethod httpMethod; + Endpoint endpoint; } diff --git a/src/main/java/org/prebid/server/hooks/v1/InvocationContext.java b/src/main/java/org/prebid/server/hooks/v1/InvocationContext.java index 22493ea8a07..45eba0ce959 100644 --- a/src/main/java/org/prebid/server/hooks/v1/InvocationContext.java +++ b/src/main/java/org/prebid/server/hooks/v1/InvocationContext.java @@ -1,5 +1,6 @@ package org.prebid.server.hooks.v1; +import io.vertx.core.http.HttpMethod; import org.prebid.server.execution.timeout.Timeout; import org.prebid.server.model.Endpoint; @@ -7,5 +8,7 @@ public interface InvocationContext { Timeout timeout(); + HttpMethod httpMethod(); + Endpoint endpoint(); } diff --git a/src/main/java/org/prebid/server/json/deserializer/ExecutionPlanEndpointsConfigDeserializer.java b/src/main/java/org/prebid/server/json/deserializer/ExecutionPlanEndpointsConfigDeserializer.java new file mode 100644 index 00000000000..837163ea6bc --- /dev/null +++ b/src/main/java/org/prebid/server/json/deserializer/ExecutionPlanEndpointsConfigDeserializer.java @@ -0,0 +1,133 @@ +package org.prebid.server.json.deserializer; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import io.vertx.core.http.HttpMethod; +import org.prebid.server.hooks.execution.model.EndpointExecutionPlan; +import org.prebid.server.hooks.execution.model.HookHttpEndpoint; +import org.prebid.server.log.Logger; +import org.prebid.server.log.LoggerFactory; +import org.prebid.server.model.Endpoint; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; + +public class ExecutionPlanEndpointsConfigDeserializer + extends StdDeserializer> { + + private static final Logger logger = LoggerFactory.getLogger(ExecutionPlanEndpointsConfigDeserializer.class); + private static final TypeReference> TEMP_MAP_REFERENCE = + new TypeReference<>() { + }; + + protected ExecutionPlanEndpointsConfigDeserializer() { + super(Map.class); + } + + @Override + public Map deserialize(JsonParser parser, DeserializationContext context) + throws IOException { + + final Map tempMap = parser.readValueAs(TEMP_MAP_REFERENCE); + if (tempMap == null) { + return null; + } + if (tempMap.isEmpty()) { + return Collections.emptyMap(); + } + + return Collections.unmodifiableMap(convertKeys(unpack(tempMap), context)); + } + + private static Map unpack(Map map) { + final Map unpacked = new HashMap<>(map); + for (ConfigKey key : map.keySet()) { + final HttpMethod httpMethod = key.httpMethod(); + if (httpMethod != null) { + continue; + } + + final Endpoint endpoint = key.endpoint(); + final EndpointExecutionPlan value = unpacked.remove(key); + + Arrays.stream(HookHttpEndpoint.values()) + .filter(httpEndpoint -> httpEndpoint.endpoint() == endpoint) + .map(HookHttpEndpoint::httpMethod) + .forEach(newHttpMethod -> putOrLogWarn(unpacked, new ConfigKey(newHttpMethod, endpoint), value)); + } + + return unpacked; + } + + private static void putOrLogWarn(Map map, + ConfigKey key, + EndpointExecutionPlan value) { + + final Object old = map.putIfAbsent(key, value); + if (old != null) { + logger.warn(""" + Combination of old and new config for EndpointExecutionPlan found. + Replace old config with new one for endpoint: {}""", key.endpoint()); + } + } + + private static Map convertKeys(Map map, + DeserializationContext context) + throws JsonMappingException { + + final Map result = new EnumMap<>(HookHttpEndpoint.class); + for (Map.Entry entry : map.entrySet()) { + result.put(convertKey(entry.getKey(), context), entry.getValue()); + } + + return result; + } + + private static HookHttpEndpoint convertKey(ConfigKey configKey, DeserializationContext context) + throws JsonMappingException { + + return Arrays.stream(HookHttpEndpoint.values()) + .filter(endpoint -> endpoint.endpoint() == configKey.endpoint() + && endpoint.httpMethod().equals(configKey.httpMethod())) + .findFirst() + .orElseThrow(() -> context.weirdStringException( + configKey.toString(), + HookHttpEndpoint.class, + "not one of the values accepted for Enum class: %s" + .formatted(Arrays.toString(HookHttpEndpoint.values())))); + } + + private record ConfigKey(HttpMethod httpMethod, Endpoint endpoint) { + + @SuppressWarnings("unused") + @JsonCreator + public static ConfigKey fromString(String value) { + if (value == null) { + return null; + } + + final int delimiterIndex = value.indexOf(' '); + final HttpMethod httpMethod = delimiterIndex != -1 + ? HttpMethod.valueOf(value.substring(0, delimiterIndex)) + : null; + final String endpoint = delimiterIndex != -1 + ? value.substring(delimiterIndex + 1) + : value; + + return new ConfigKey(httpMethod, Endpoint.fromString(endpoint)); + } + + @Override + public String toString() { + return httpMethod.name() + " " + endpoint.value(); + } + } +} diff --git a/src/main/java/org/prebid/server/model/Endpoint.java b/src/main/java/org/prebid/server/model/Endpoint.java index 71131b0b85b..421af763264 100644 --- a/src/main/java/org/prebid/server/model/Endpoint.java +++ b/src/main/java/org/prebid/server/model/Endpoint.java @@ -37,11 +37,10 @@ public String value() { return value; } - @SuppressWarnings("unused") @JsonCreator public static Endpoint fromString(String value) { return Arrays.stream(values()) - .filter(endpoint -> endpoint.value.equals(value)) + .filter(endpoint -> endpoint.value().equals(value)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("Unknown endpoint")); } diff --git a/src/main/java/org/prebid/server/settings/EnrichingApplicationSettings.java b/src/main/java/org/prebid/server/settings/EnrichingApplicationSettings.java index 5d1875c742c..6e6c74a0b8e 100644 --- a/src/main/java/org/prebid/server/settings/EnrichingApplicationSettings.java +++ b/src/main/java/org/prebid/server/settings/EnrichingApplicationSettings.java @@ -39,8 +39,8 @@ public EnrichingApplicationSettings(boolean enforceValidAccount, JacksonMapper mapper) { this.enforceValidAccount = enforceValidAccount; - this.activitiesConfigResolver = Objects.requireNonNull(activitiesConfigResolver); this.priceFloorsConfigResolver = Objects.requireNonNull(priceFloorsConfigResolver); + this.activitiesConfigResolver = Objects.requireNonNull(activitiesConfigResolver); this.delegate = Objects.requireNonNull(delegate); this.jsonMerger = Objects.requireNonNull(jsonMerger); diff --git a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java index ffd5158c8f2..85e2570bfe6 100644 --- a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java +++ b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java @@ -25,6 +25,7 @@ import org.prebid.server.hooks.execution.model.GroupExecutionOutcome; import org.prebid.server.hooks.execution.model.HookExecutionContext; import org.prebid.server.hooks.execution.model.HookExecutionOutcome; +import org.prebid.server.hooks.execution.model.HookHttpEndpoint; import org.prebid.server.hooks.execution.model.HookId; import org.prebid.server.hooks.execution.model.Stage; import org.prebid.server.hooks.execution.model.StageExecutionOutcome; @@ -33,7 +34,6 @@ import org.prebid.server.hooks.execution.v1.analytics.ResultImpl; import org.prebid.server.hooks.execution.v1.analytics.TagsImpl; import org.prebid.server.json.ObjectMapperProvider; -import org.prebid.server.model.Endpoint; import org.prebid.server.util.ListUtil; import org.prebid.server.vertx.httpclient.HttpClient; import org.prebid.server.vertx.httpclient.model.HttpClientResponse; @@ -208,7 +208,7 @@ private AuctionEvent buildEvent(Boolean isEnriched, Boolean withTags) { .build())) .build())) .build()) - .hookExecutionContext(HookExecutionContext.of(Endpoint.openrtb2_auction, stageOutcomes)) + .hookExecutionContext(HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION, stageOutcomes)) .build()) .build(); } diff --git a/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java b/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java index b257da697c6..b5036c497c3 100644 --- a/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java +++ b/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java @@ -87,6 +87,7 @@ import org.prebid.server.hooks.execution.model.GroupExecutionOutcome; import org.prebid.server.hooks.execution.model.HookExecutionContext; import org.prebid.server.hooks.execution.model.HookExecutionOutcome; +import org.prebid.server.hooks.execution.model.HookHttpEndpoint; import org.prebid.server.hooks.execution.model.HookId; import org.prebid.server.hooks.execution.model.HookStageExecutionResult; import org.prebid.server.hooks.execution.model.Stage; @@ -103,7 +104,6 @@ import org.prebid.server.metric.MetricName; import org.prebid.server.metric.Metrics; import org.prebid.server.model.CaseInsensitiveMultiMap; -import org.prebid.server.model.Endpoint; import org.prebid.server.model.HttpRequestContext; import org.prebid.server.model.UpdateResult; import org.prebid.server.proto.openrtb.ext.ExtPrebid; @@ -3316,7 +3316,7 @@ public void shouldReturnBidResponseModifiedByAuctionResponseHooks() { public void shouldReturnEmptyBidResponseWhenRequestIsRejected() { // given final AuctionContext auctionContext = AuctionContext.builder() - .hookExecutionContext(HookExecutionContext.of(Endpoint.openrtb2_auction)) + .hookExecutionContext(HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION)) .debugContext(DebugContext.empty()) .requestRejected(true) .build(); @@ -3343,7 +3343,7 @@ public void shouldReturnBidResponseWithHooksDebugInfoWhenAuctionHappened() { final BidRequest bidRequest = givenBidRequest(givenSingleImp(singletonMap("bidder", 2))); final AuctionContext auctionContext = givenRequestContext(bidRequest).toBuilder() .hookExecutionContext(HookExecutionContext.of( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, stageOutcomes(givenAppliedToImpl(identity())))) .debugContext(DebugContext.of(true, true, null)) .build(); @@ -3411,7 +3411,7 @@ public void shouldReturnBidResponseWithHooksBasicTraceInfoWhenAuctionHappened() final BidRequest bidRequest = givenBidRequest(givenSingleImp(singletonMap("bidder", 2))); final AuctionContext auctionContext = givenRequestContext(bidRequest).toBuilder() .hookExecutionContext(HookExecutionContext.of( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, stageOutcomes(givenAppliedToImpl(identity())))) .debugContext(DebugContext.of(false, false, TraceLevel.basic)) .build(); @@ -3505,7 +3505,7 @@ public void shouldReturnBidResponseWithHooksVerboseTraceInfoWhenAuctionHappened( final BidRequest bidRequest = givenBidRequest(givenSingleImp(singletonMap("bidder", 2))); final AuctionContext auctionContext = givenRequestContext(bidRequest).toBuilder() .hookExecutionContext(HookExecutionContext.of( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, stageOutcomes(givenAppliedToImpl(identity())))) .debugContext(DebugContext.of(false, false, TraceLevel.verbose)) .build(); @@ -3543,7 +3543,7 @@ public void shouldReturnProperBidResponseWithAppliedToIfResultImplAppliedToIsPre final BidRequest bidRequest = givenBidRequest(givenSingleImp(singletonMap("bidder", 2))); final AuctionContext auctionContext = givenRequestContext(bidRequest).toBuilder() .hookExecutionContext(HookExecutionContext.of( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, stageOutcomes(givenAppliedToImpl(appliedToImplBuilder -> appliedToImplBuilder .impIds(asList("impId1", "impId2")) .response(true) @@ -3590,7 +3590,7 @@ public void shouldReturnBidResponseAppliedToRequestNullIfResultImplAppliedToIsNu final BidRequest bidRequest = givenBidRequest(givenSingleImp(singletonMap("bidder", 2))); final AuctionContext auctionContext = givenRequestContext(bidRequest).toBuilder() .hookExecutionContext(HookExecutionContext.of( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, stageOutcomes(null))) .debugContext(DebugContext.of(false, false, TraceLevel.verbose)) .build(); @@ -3628,7 +3628,7 @@ public void shouldReturnBidResponseWithHooksDebugAndTraceInfoWhenAuctionHappened final BidRequest bidRequest = givenBidRequest(givenSingleImp(singletonMap("bidder", 2))); final AuctionContext auctionContext = givenRequestContext(bidRequest).toBuilder() .hookExecutionContext(HookExecutionContext.of( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, stageOutcomes(givenAppliedToImpl(identity())))) .debugContext(DebugContext.of(true, true, TraceLevel.basic)) .build(); @@ -3650,7 +3650,7 @@ public void shouldReturnBidResponseWithHooksDebugAndTraceInfoWhenRequestIsReject // given final AuctionContext auctionContext = AuctionContext.builder() .hookExecutionContext(HookExecutionContext.of( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, stageOutcomes(givenAppliedToImpl(identity())))) .debugContext(DebugContext.of(true, true, TraceLevel.basic)) .requestRejected(true) @@ -3677,7 +3677,7 @@ public void shouldReturnBidResponseWithoutHooksTraceInfoWhenNoHooksExecuted() { final BidRequest bidRequest = givenBidRequest(givenSingleImp(singletonMap("bidder", 2))); final AuctionContext auctionContext = givenRequestContext(bidRequest).toBuilder() .hookExecutionContext(HookExecutionContext.of( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, new EnumMap<>(singletonMap( Stage.entrypoint, singletonList(StageExecutionOutcome.of("http-request", emptyList())))))) @@ -3714,7 +3714,7 @@ public void shouldReturnBidResponseWithAnalyticsTagsWhenRequested() { .build(); final AuctionContext auctionContext = givenRequestContext(bidRequest, account).toBuilder() .hookExecutionContext(HookExecutionContext.of( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, stageOutcomes(givenAppliedToImpl(identity())))) .build(); @@ -3753,7 +3753,7 @@ public void shouldReturnBidResponseWithWarningWhenAnalyticsTagsDisabledAndReques .build()))); final AuctionContext auctionContext = givenRequestContext(bidRequest).toBuilder() .hookExecutionContext(HookExecutionContext.of( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, stageOutcomes(givenAppliedToImpl(identity())))) .build(); @@ -4600,7 +4600,7 @@ private AuctionContext givenRequestContext(BidRequest bidRequest, Account accoun .account(account) .requestTypeMetric(MetricName.openrtb2web) .timeoutContext(TimeoutContext.of(clock.millis(), timeout, 90)) - .hookExecutionContext(HookExecutionContext.of(Endpoint.openrtb2_auction)) + .hookExecutionContext(HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION)) .debugContext(DebugContext.empty()) .bidRejectionTrackers(new HashMap<>()) .activityInfrastructure(activityInfrastructure) diff --git a/src/test/java/org/prebid/server/auction/HooksMetricsServiceTest.java b/src/test/java/org/prebid/server/auction/HooksMetricsServiceTest.java index 4d90cc637d7..314cea9a327 100644 --- a/src/test/java/org/prebid/server/auction/HooksMetricsServiceTest.java +++ b/src/test/java/org/prebid/server/auction/HooksMetricsServiceTest.java @@ -13,6 +13,7 @@ import org.prebid.server.hooks.execution.model.GroupExecutionOutcome; import org.prebid.server.hooks.execution.model.HookExecutionContext; import org.prebid.server.hooks.execution.model.HookExecutionOutcome; +import org.prebid.server.hooks.execution.model.HookHttpEndpoint; import org.prebid.server.hooks.execution.model.HookId; import org.prebid.server.hooks.execution.model.Stage; import org.prebid.server.hooks.execution.model.StageExecutionOutcome; @@ -21,7 +22,6 @@ import org.prebid.server.hooks.execution.v1.analytics.ResultImpl; import org.prebid.server.hooks.execution.v1.analytics.TagsImpl; import org.prebid.server.metric.Metrics; -import org.prebid.server.model.Endpoint; import org.prebid.server.settings.model.Account; import org.prebid.server.settings.model.AccountAuctionConfig; import org.prebid.server.settings.model.AccountEventsConfig; @@ -59,7 +59,7 @@ public void shouldIncrementHooksGlobalMetrics() { // given final AuctionContext auctionContext = AuctionContext.builder() .hookExecutionContext(HookExecutionContext.of( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, stageOutcomes(givenAppliedToImpl()))) .debugContext(DebugContext.empty()) .requestRejected(true) @@ -121,7 +121,7 @@ public void shouldIncrementHooksGlobalAndAccountMetrics() { // given final AuctionContext auctionContext = AuctionContext.builder() .hookExecutionContext(HookExecutionContext.of( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, stageOutcomes(givenAppliedToImpl()))) .debugContext(DebugContext.empty()) .requestRejected(true) diff --git a/src/test/java/org/prebid/server/auction/requestfactory/AmpRequestFactoryTest.java b/src/test/java/org/prebid/server/auction/requestfactory/AmpRequestFactoryTest.java index bb0420f580a..ad2c84c4669 100644 --- a/src/test/java/org/prebid/server/auction/requestfactory/AmpRequestFactoryTest.java +++ b/src/test/java/org/prebid/server/auction/requestfactory/AmpRequestFactoryTest.java @@ -39,9 +39,9 @@ import org.prebid.server.auction.versionconverter.BidRequestOrtbVersionConversionManager; import org.prebid.server.exception.InvalidRequestException; import org.prebid.server.geolocation.model.GeoInfo; +import org.prebid.server.hooks.execution.model.HookHttpEndpoint; import org.prebid.server.metric.MetricName; import org.prebid.server.model.CaseInsensitiveMultiMap; -import org.prebid.server.model.Endpoint; import org.prebid.server.model.HttpRequestContext; import org.prebid.server.privacy.ccpa.Ccpa; import org.prebid.server.privacy.gdpr.TcfDefinerService; @@ -160,10 +160,11 @@ public void setUp() { given(httpRequest.headers()).willReturn(MultiMap.caseInsensitiveMultiMap()); given(httpRequest.remoteAddress()).willReturn(new SocketAddressImpl(1234, "host")); - given(ortb2RequestFactory.createAuctionContext(any(), eq(MetricName.amp))).willReturn(AuctionContext.builder() - .prebidErrors(new ArrayList<>()) - .debugWarnings(new ArrayList<>()) - .build()); + given(ortb2RequestFactory.createAuctionContext(any(), eq(MetricName.amp))) + .willReturn(AuctionContext.builder() + .prebidErrors(new ArrayList<>()) + .debugWarnings(new ArrayList<>()) + .build()); given(ortb2RequestFactory.executeEntrypointHooks(any(), any(), any())) .willAnswer(invocation -> toHttpRequest(invocation.getArgument(0), invocation.getArgument(1))); given(ortb2RequestFactory.restoreResultFromRejection(any())) @@ -1654,7 +1655,7 @@ public void shouldPassAmpEndpointAndRequestMetricType() { target.fromRequest(routingContext, 0L); // then - verify(ortb2RequestFactory).createAuctionContext(eq(Endpoint.openrtb2_amp), eq(MetricName.amp)); + verify(ortb2RequestFactory).createAuctionContext(eq(HookHttpEndpoint.AMP), eq(MetricName.amp)); } @Test diff --git a/src/test/java/org/prebid/server/auction/requestfactory/Ortb2RequestFactoryTest.java b/src/test/java/org/prebid/server/auction/requestfactory/Ortb2RequestFactoryTest.java index c6b62cf9186..6273b2b3117 100644 --- a/src/test/java/org/prebid/server/auction/requestfactory/Ortb2RequestFactoryTest.java +++ b/src/test/java/org/prebid/server/auction/requestfactory/Ortb2RequestFactoryTest.java @@ -48,13 +48,13 @@ import org.prebid.server.geolocation.model.GeoInfo; import org.prebid.server.hooks.execution.HookStageExecutor; import org.prebid.server.hooks.execution.model.HookExecutionContext; +import org.prebid.server.hooks.execution.model.HookHttpEndpoint; import org.prebid.server.hooks.execution.model.HookStageExecutionResult; import org.prebid.server.hooks.execution.v1.auction.AuctionRequestPayloadImpl; import org.prebid.server.hooks.execution.v1.entrypoint.EntrypointPayloadImpl; import org.prebid.server.metric.MetricName; import org.prebid.server.metric.Metrics; import org.prebid.server.model.CaseInsensitiveMultiMap; -import org.prebid.server.model.Endpoint; import org.prebid.server.model.HttpRequestContext; import org.prebid.server.privacy.ccpa.Ccpa; import org.prebid.server.privacy.gdpr.model.TcfContext; @@ -149,7 +149,7 @@ public void setUp() { httpRequest = HttpRequestContext.builder() .headers(CaseInsensitiveMultiMap.empty()) .build(); - hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); given(timeoutResolver.limitToMax(any())).willReturn(2000L); @@ -596,7 +596,9 @@ public void shouldFetchAccountFromProfileIfStoredLookupIsTrueAndAccountIsNotFoun @Test public void createAuctionContextShouldReturnExpectedAuctionContext() { // when - final AuctionContext result = target.createAuctionContext(Endpoint.openrtb2_auction, MetricName.openrtb2app); + final AuctionContext result = target.createAuctionContext( + HookHttpEndpoint.POST_AUCTION, + MetricName.openrtb2app); // then assertThat(result).isEqualTo(AuctionContext.builder() diff --git a/src/test/java/org/prebid/server/handler/openrtb2/AmpHandlerTest.java b/src/test/java/org/prebid/server/handler/openrtb2/AmpHandlerTest.java index 72ea07c12da..933a9654ee6 100644 --- a/src/test/java/org/prebid/server/handler/openrtb2/AmpHandlerTest.java +++ b/src/test/java/org/prebid/server/handler/openrtb2/AmpHandlerTest.java @@ -48,6 +48,7 @@ import org.prebid.server.hooks.execution.model.GroupExecutionOutcome; import org.prebid.server.hooks.execution.model.HookExecutionContext; import org.prebid.server.hooks.execution.model.HookExecutionOutcome; +import org.prebid.server.hooks.execution.model.HookHttpEndpoint; import org.prebid.server.hooks.execution.model.HookId; import org.prebid.server.hooks.execution.model.HookStageExecutionResult; import org.prebid.server.hooks.execution.model.Stage; @@ -61,7 +62,6 @@ import org.prebid.server.metric.MetricName; import org.prebid.server.metric.Metrics; import org.prebid.server.model.CaseInsensitiveMultiMap; -import org.prebid.server.model.Endpoint; import org.prebid.server.model.HttpRequestContext; import org.prebid.server.proto.openrtb.ext.ExtPrebid; import org.prebid.server.proto.openrtb.ext.request.ExtRequest; @@ -1125,9 +1125,7 @@ public void shouldPassSuccessfulEventToAnalyticsReporterWhenExitpointHookChanges public void shouldReturnSendAmpEventWithAuctionContextBidResponseDebugInfoHoldingExitpointHookOutcome() { // given final AuctionContext auctionContext = givenAuctionContext(identity()).toBuilder() - .hookExecutionContext(HookExecutionContext.of( - Endpoint.openrtb2_amp, - stageOutcomes())) + .hookExecutionContext(HookExecutionContext.of(HookHttpEndpoint.AMP, stageOutcomes())) .build(); given(ampRequestFactory.fromRequest(any(), anyLong())) @@ -1239,9 +1237,7 @@ public void shouldReturnSendAmpEventWithAuctionContextBidResponseAnalyticsTagsHo request -> request.ext(ExtRequest.of(ExtRequestPrebid.builder() .analytics(analyticsNode) .build()))).toBuilder() - .hookExecutionContext(HookExecutionContext.of( - Endpoint.openrtb2_amp, - stageOutcomes())) + .hookExecutionContext(HookExecutionContext.of(HookHttpEndpoint.AMP, stageOutcomes())) .build(); given(ampRequestFactory.fromRequest(any(), anyLong())) @@ -1353,7 +1349,7 @@ private AuctionContext givenAuctionContext( .requestTypeMetric(MetricName.amp) .timeoutContext(TimeoutContext.of(0, timeout, 0)) .debugContext(DebugContext.of(true, false, TraceLevel.verbose)) - .hookExecutionContext(HookExecutionContext.of(Endpoint.openrtb2_amp)) + .hookExecutionContext(HookExecutionContext.of(HookHttpEndpoint.AMP)) .build(); } diff --git a/src/test/java/org/prebid/server/handler/openrtb2/AuctionHandlerTest.java b/src/test/java/org/prebid/server/handler/openrtb2/AuctionHandlerTest.java index 0210095affd..0c133c2bc7d 100644 --- a/src/test/java/org/prebid/server/handler/openrtb2/AuctionHandlerTest.java +++ b/src/test/java/org/prebid/server/handler/openrtb2/AuctionHandlerTest.java @@ -42,6 +42,7 @@ import org.prebid.server.hooks.execution.model.GroupExecutionOutcome; import org.prebid.server.hooks.execution.model.HookExecutionContext; import org.prebid.server.hooks.execution.model.HookExecutionOutcome; +import org.prebid.server.hooks.execution.model.HookHttpEndpoint; import org.prebid.server.hooks.execution.model.HookId; import org.prebid.server.hooks.execution.model.HookStageExecutionResult; import org.prebid.server.hooks.execution.model.Stage; @@ -55,7 +56,6 @@ import org.prebid.server.metric.MetricName; import org.prebid.server.metric.Metrics; import org.prebid.server.model.CaseInsensitiveMultiMap; -import org.prebid.server.model.Endpoint; import org.prebid.server.model.HttpRequestContext; import org.prebid.server.proto.openrtb.ext.request.ExtGranularityRange; import org.prebid.server.proto.openrtb.ext.request.ExtMediaTypePriceGranularity; @@ -1004,9 +1004,7 @@ public void shouldSkipAuction() { public void shouldReturnSendAuctionEventWithAuctionContextBidResponseDebugInfoHoldingExitpointHookOutcome() { // given final AuctionContext auctionContext = givenAuctionContext(identity()).toBuilder() - .hookExecutionContext(HookExecutionContext.of( - Endpoint.openrtb2_amp, - stageOutcomes())) + .hookExecutionContext(HookExecutionContext.of(HookHttpEndpoint.AMP, stageOutcomes())) .build(); given(auctionRequestFactory.parseRequest(any(), anyLong())) @@ -1120,9 +1118,7 @@ public void shouldReturnSendAuctionEventWithAuctionContextBidResponseAnalyticsTa request -> request.ext(ExtRequest.of(ExtRequestPrebid.builder() .analytics(analyticsNode) .build()))).toBuilder() - .hookExecutionContext(HookExecutionContext.of( - Endpoint.openrtb2_amp, - stageOutcomes())) + .hookExecutionContext(HookExecutionContext.of(HookHttpEndpoint.AMP, stageOutcomes())) .build(); given(auctionRequestFactory.parseRequest(any(), anyLong())) @@ -1257,7 +1253,7 @@ private AuctionContext givenAuctionContext( .bidRequest(bidRequest) .requestTypeMetric(MetricName.openrtb2web) .debugContext(DebugContext.of(true, false, TraceLevel.verbose)) - .hookExecutionContext(HookExecutionContext.of(Endpoint.openrtb2_auction)) + .hookExecutionContext(HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION)) .timeoutContext(TimeoutContext.of(0, timeout, 0)); return auctionContextCustomizer.apply(auctionContextBuilder) diff --git a/src/test/java/org/prebid/server/handler/openrtb2/VideoHandlerTest.java b/src/test/java/org/prebid/server/handler/openrtb2/VideoHandlerTest.java index 2e89435181b..3be7f7a60b1 100644 --- a/src/test/java/org/prebid/server/handler/openrtb2/VideoHandlerTest.java +++ b/src/test/java/org/prebid/server/handler/openrtb2/VideoHandlerTest.java @@ -35,10 +35,10 @@ import org.prebid.server.execution.timeout.TimeoutFactory; import org.prebid.server.hooks.execution.HookStageExecutor; import org.prebid.server.hooks.execution.model.HookExecutionContext; +import org.prebid.server.hooks.execution.model.HookHttpEndpoint; import org.prebid.server.hooks.execution.model.HookStageExecutionResult; import org.prebid.server.hooks.execution.v1.exitpoint.ExitpointPayloadImpl; import org.prebid.server.metric.Metrics; -import org.prebid.server.model.Endpoint; import org.prebid.server.proto.openrtb.ext.request.TraceLevel; import org.prebid.server.proto.response.VideoResponse; import org.prebid.server.settings.model.Account; @@ -461,7 +461,7 @@ private WithPodErrors givenAuctionContext( .bidRequest(bidRequest) .timeoutContext(TimeoutContext.of(0, timeout, 0)) .debugContext(DebugContext.of(true, false, TraceLevel.verbose)) - .hookExecutionContext(HookExecutionContext.of(Endpoint.openrtb2_video)) + .hookExecutionContext(HookExecutionContext.of(HookHttpEndpoint.VIDEO)) .build(); return WithPodErrors.of(auctionContext, errors); 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 fc67149a747..e54bc9b6a09 100644 --- a/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java +++ b/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java @@ -26,10 +26,10 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.prebid.server.VertxTest; import org.prebid.server.auction.model.AuctionContext; +import org.prebid.server.auction.model.BidRejection; import org.prebid.server.auction.model.BidRejectionTracker; import org.prebid.server.auction.model.BidderRequest; import org.prebid.server.auction.model.BidderResponse; -import org.prebid.server.auction.model.BidRejection; import org.prebid.server.auction.model.ImpRejection; import org.prebid.server.auction.model.debug.DebugContext; import org.prebid.server.bidder.model.BidderBid; @@ -44,6 +44,7 @@ import org.prebid.server.hooks.execution.model.GroupExecutionOutcome; import org.prebid.server.hooks.execution.model.HookExecutionContext; import org.prebid.server.hooks.execution.model.HookExecutionOutcome; +import org.prebid.server.hooks.execution.model.HookHttpEndpoint; import org.prebid.server.hooks.execution.model.HookId; import org.prebid.server.hooks.execution.model.HookStageExecutionResult; import org.prebid.server.hooks.execution.model.Stage; @@ -163,7 +164,7 @@ public void creationShouldFailWhenExecutionPlanIsInvalid() { @Test public void creationShouldFailWhenHostExecutionPlanHasUnknownHook() { final String hostPlan = executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.entrypoint, StageExecutionPlan.of(singletonList( ExecutionGroup.of( @@ -186,7 +187,7 @@ public void creationShouldFailWhenHostExecutionPlanHasUnknownHook() { @Test public void creationShouldFailWhenDefaultAccountExecutionPlanHasUnknownHook() { final String defaultAccountPlan = executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.entrypoint, StageExecutionPlan.of(singletonList( ExecutionGroup.of( @@ -216,7 +217,7 @@ public void shouldTolerateMissingHostAndDefaultAccountExecutionPlans() { final String body = "body"; final AuctionContext givenAuctionContext = AuctionContext.builder() - .hookExecutionContext(HookExecutionContext.of(Endpoint.openrtb2_auction)) + .hookExecutionContext(HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION)) .build(); // when @@ -243,7 +244,7 @@ public void shouldTolerateMissingAllExecutionPlans() { AuctionContext.builder() .bidRequest(bidRequest) .account(Account.empty("accountId")) - .hookExecutionContext(HookExecutionContext.of(Endpoint.openrtb2_auction)) + .hookExecutionContext(HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION)) .debugContext(DebugContext.empty()) .build()); @@ -287,10 +288,10 @@ public void shouldExecuteEntrypointHooksHappyPath(VertxTestContext context) { final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap(Stage.entrypoint, execPlanTwoGroupsTwoHooksEach()))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); final AuctionContext givenAuctionContext = AuctionContext.builder() .hookExecutionContext(hookExecutionContext) .build(); @@ -375,7 +376,7 @@ public void shouldBypassEntrypointHooksWhenNoPlanForEndpoint(VertxTestContext co final HookStageExecutor executor = createExecutor( executionPlan(emptyMap())); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_amp); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.AMP); final AuctionContext givenAuctionContext = AuctionContext.builder() .hookExecutionContext(hookExecutionContext) .build(); @@ -406,11 +407,9 @@ public void shouldBypassEntrypointHooksWhenNoPlanForEndpoint(VertxTestContext co public void shouldBypassEntrypointHooksWhenNoPlanForStage(VertxTestContext context) { // given final HookStageExecutor executor = createExecutor( - executionPlan(singletonMap( - Endpoint.openrtb2_auction, - EndpointExecutionPlan.of(emptyMap())))); + executionPlan(singletonMap(HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(emptyMap())))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); final AuctionContext givenAuctionContext = AuctionContext.builder() .hookExecutionContext(hookExecutionContext) .build(); @@ -470,7 +469,7 @@ public void shouldBypassEntrypointHooksThatAreDisabled(VertxTestContext context) final HookStageExecutor executor = HookStageExecutor.create( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap(Stage.entrypoint, execPlanTwoGroupsTwoHooksEach())))), null, Map.of("module-alpha", false), @@ -482,7 +481,7 @@ public void shouldBypassEntrypointHooksThatAreDisabled(VertxTestContext context) false, 0.0); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); final AuctionContext givenAuctionContext = AuctionContext.builder() .hookExecutionContext(hookExecutionContext) .build(); @@ -536,10 +535,10 @@ public void shouldExecuteEntrypointHooksToleratingMisbehavingHooks(VertxTestCont final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap(Stage.entrypoint, execPlanTwoGroupsTwoHooksEach()))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); final AuctionContext givenAuctionContext = AuctionContext.builder() .hookExecutionContext(hookExecutionContext) .build(); @@ -649,14 +648,14 @@ public void shouldExecuteEntrypointHooksToleratingTimeoutAndFailedFuture(VertxTe immediateHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-jkl")))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); final AuctionContext givenAuctionContext = AuctionContext.builder() .hookExecutionContext(hookExecutionContext) .build(); final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap(Stage.entrypoint, execPlanTwoGroupsTwoHooksEach()))))); // when @@ -753,10 +752,10 @@ public void shouldExecuteEntrypointHooksHonoringStatusAndAction(VertxTestContext final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap(Stage.entrypoint, execPlanTwoGroupsTwoHooksEach()))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); final AuctionContext givenAuctionContext = AuctionContext.builder() .hookExecutionContext(hookExecutionContext) .build(); @@ -837,7 +836,7 @@ public void shouldExecuteEntrypointHooksWhenRequestIsRejectedByFirstGroup(VertxT final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.entrypoint, StageExecutionPlan.of(singletonList( @@ -847,7 +846,7 @@ public void shouldExecuteEntrypointHooksWhenRequestIsRejectedByFirstGroup(VertxT HookId.of("module-alpha", "hook-a"), HookId.of("module-beta", "hook-a")))))))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); final AuctionContext givenAuctionContext = AuctionContext.builder() .hookExecutionContext(hookExecutionContext) .build(); @@ -924,10 +923,10 @@ public void shouldExecuteEntrypointHooksWhenRequestIsRejectedBySecondGroup(Vertx final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap(Stage.entrypoint, execPlanTwoGroupsTwoHooksEach()))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); final AuctionContext givenAuctionContext = AuctionContext.builder() .hookExecutionContext(hookExecutionContext) .build(); @@ -1027,10 +1026,10 @@ public void shouldExecuteEntrypointHooksToleratingMisbehavingInvocationResult(Ve final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap(Stage.entrypoint, execPlanTwoGroupsTwoHooksEach()))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); final AuctionContext givenAuctionContext = AuctionContext.builder() .hookExecutionContext(hookExecutionContext) .build(); @@ -1123,11 +1122,11 @@ public void shouldExecuteEntrypointHooksAndStoreResultInExecutionContext(VertxTe final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.entrypoint, execPlanOneGroupOneHook("module-alpha", "hook-a")))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); final AuctionContext givenAuctionContext = AuctionContext.builder() .hookExecutionContext(hookExecutionContext) .build(); @@ -1181,10 +1180,10 @@ public void shouldExecuteEntrypointHooksAndPassInvocationContext(VertxTestContex final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap(Stage.entrypoint, execPlanTwoGroupsTwoHooksEach()))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); final AuctionContext givenAuctionContext = AuctionContext.builder() .hookExecutionContext(hookExecutionContext) .build(); @@ -1240,17 +1239,17 @@ public void shouldExecuteRawAuctionRequestHooksWhenNoExecutionPlanInAccount(Vert .willReturn(hookImpl); final String hostPlan = executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.raw_auction_request, execPlanOneGroupOneHook("module-alpha", "hook-a"))))); final String defaultAccountPlan = executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.raw_auction_request, execPlanOneGroupOneHook("module-alpha", "hook-b"))))); final HookStageExecutor executor = createExecutor(hostPlan, defaultAccountPlan); final BidRequest bidRequest = BidRequest.builder().build(); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = executor.executeRawAuctionRequestStage( @@ -1285,12 +1284,12 @@ public void shouldExecuteRawAuctionRequestHooksWhenAccountOverridesExecutionPlan .willReturn(hookImpl); final String hostPlan = executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.raw_auction_request, execPlanOneGroupOneHook("module-alpha", "hook-a"))))); final String defaultAccountPlan = executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.raw_auction_request, execPlanOneGroupOneHook("module-alpha", "hook-b"))))); @@ -1298,7 +1297,7 @@ public void shouldExecuteRawAuctionRequestHooksWhenAccountOverridesExecutionPlan final BidRequest bidRequest = BidRequest.builder().build(); final ExecutionPlan accountPlan = ExecutionPlan.of(emptyList(), singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.raw_auction_request, execPlanOneGroupOneHook("module-beta", "hook-b"))))); @@ -1306,7 +1305,7 @@ public void shouldExecuteRawAuctionRequestHooksWhenAccountOverridesExecutionPlan .id("accountId") .hooks(AccountHooksConfiguration.of(accountPlan, null, null)) .build(); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = executor.executeRawAuctionRequestStage( @@ -1349,7 +1348,7 @@ public void shouldExecuteRawAuctionRequestHooksToleratingUnknownHookInAccountPla final HookStageExecutor executor = createExecutor(null, null); final ExecutionPlan accountPlan = ExecutionPlan.of(emptyList(), singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.raw_auction_request, StageExecutionPlan.of(singletonList( @@ -1362,7 +1361,7 @@ public void shouldExecuteRawAuctionRequestHooksToleratingUnknownHookInAccountPla .id("accountId") .hooks(AccountHooksConfiguration.of(accountPlan, null, null)) .build(); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = executor.executeRawAuctionRequestStage( @@ -1469,7 +1468,7 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsNotRequired HookId.of("module-zeta", "hook-b"))))); final String hostExecutionPlan = executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap(Stage.raw_auction_request, stageExecutionPlan)))); final HookStageExecutor executor = HookStageExecutor.create( @@ -1484,7 +1483,7 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsNotRequired false, 0.0); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final BidRequest givenBidRequest = BidRequest.builder().build(); @@ -1587,7 +1586,7 @@ public void shouldExecuteRawAuctionRequestHooksWhenAccountConfigIsRequired(Vertx HookId.of("module-zeta", "hook-b"))))); final String hostExecutionPlan = executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap(Stage.raw_auction_request, stageExecutionPlan)))); final HookStageExecutor executor = HookStageExecutor.create( @@ -1602,7 +1601,7 @@ public void shouldExecuteRawAuctionRequestHooksWhenAccountConfigIsRequired(Vertx true, 0.0); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final BidRequest givenBidRequest = BidRequest.builder().build(); @@ -1679,12 +1678,12 @@ public void shouldExecuteRawAuctionRequestHooksHappyPath(VertxTestContext contex final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.raw_auction_request, execPlanTwoGroupsTwoHooksEach()))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = executor.executeRawAuctionRequestStage( @@ -1767,12 +1766,12 @@ public void shouldExecuteRawAuctionRequestHooksWithAllRejectionsPopulated(VertxT final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.raw_auction_request, execPlanTwoGroupsTwoHooksEach()))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final AuctionContext givenAuctionContext = AuctionContext.builder() @@ -1847,7 +1846,7 @@ public void shouldExecuteRawAuctionRequestHooksAndPassAuctionInvocationContext(V final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.raw_auction_request, execPlanTwoGroupsTwoHooksEach()))))); @@ -1858,7 +1857,7 @@ public void shouldExecuteRawAuctionRequestHooksAndPassAuctionInvocationContext(V accountModulesConfiguration.put("module-alpha", moduleAlphaConfiguration); accountModulesConfiguration.put("module-beta", moduleBetaConfiguration); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = executor.executeRawAuctionRequestStage( @@ -1941,7 +1940,7 @@ public void shouldExecuteRawAuctionRequestHooksAndPassModuleContextBetweenHooks( final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.raw_auction_request, StageExecutionPlan.of(asList( @@ -1958,7 +1957,7 @@ public void shouldExecuteRawAuctionRequestHooksAndPassModuleContextBetweenHooks( HookId.of("module-alpha", "hook-b"), HookId.of("module-beta", "hook-c")))))))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = executor.executeRawAuctionRequestStage( @@ -2012,11 +2011,11 @@ public void shouldExecuteRawAuctionRequestHooksWhenRequestIsRejected(VertxTestCo final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.raw_auction_request, execPlanOneGroupOneHook("module-alpha", "hook-a")))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = executor.executeRawAuctionRequestStage( @@ -2064,12 +2063,12 @@ public void shouldExecuteProcessedAuctionRequestHooksHappyPath(VertxTestContext final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.processed_auction_request, execPlanTwoGroupsTwoHooksEach()))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = @@ -2120,7 +2119,7 @@ public void shouldExecuteProcessedAuctionRequestHooksAndPassAuctionInvocationCon final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.processed_auction_request, execPlanTwoGroupsTwoHooksEach()))))); @@ -2131,7 +2130,7 @@ public void shouldExecuteProcessedAuctionRequestHooksAndPassAuctionInvocationCon accountModulesConfiguration.put("module-alpha", moduleAlphaConfiguration); accountModulesConfiguration.put("module-beta", moduleBetaConfiguration); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = @@ -2215,7 +2214,7 @@ public void shouldExecuteProcessedAuctionRequestHooksAndPassModuleContextBetween final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.processed_auction_request, StageExecutionPlan.of(asList( @@ -2232,7 +2231,7 @@ public void shouldExecuteProcessedAuctionRequestHooksAndPassModuleContextBetween HookId.of("module-alpha", "hook-b"), HookId.of("module-beta", "hook-c")))))))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = @@ -2287,12 +2286,12 @@ public void shouldExecuteProcessedAuctionRequestHooksWhenRequestIsRejected(Vertx final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.processed_auction_request, execPlanOneGroupOneHook("module-alpha", "hook-a")))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = @@ -2342,12 +2341,12 @@ public void shouldExecuteBidderRequestHooksHappyPath(VertxTestContext context) { final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.bidder_request, execPlanTwoGroupsTwoHooksEach()))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); final AuctionContext auctionContext = AuctionContext.builder() .bidRequest(BidRequest.builder().build()) .account(Account.empty("accountId")) @@ -2410,11 +2409,11 @@ public void shouldExecuteBidderRequestHooksAndPassBidderInvocationContext(VertxT final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.bidder_request, execPlanOneGroupOneHook("module-alpha", "hook-a")))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = executor.executeBidderRequestStage( @@ -2498,12 +2497,12 @@ public void shouldExecuteRawBidderResponseHooksHappyPath(VertxTestContext contex final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.raw_bidder_response, execPlanTwoGroupsTwoHooksEach()))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); final AuctionContext auctionContext = AuctionContext.builder() .bidRequest(BidRequest.builder().build()) .account(Account.empty("accountId")) @@ -2565,11 +2564,11 @@ public void shouldExecuteRawBidderResponseHooksAndPassBidderInvocationContext(Ve final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap(Stage.raw_bidder_response, execPlanOneGroupOneHook( "module-alpha", "hook-a")))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = executor.executeRawBidderResponseStage( @@ -2653,12 +2652,12 @@ public void shouldExecuteProcessedBidderResponseHooksHappyPath(VertxTestContext final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.processed_bidder_response, execPlanTwoGroupsTwoHooksEach()))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); final AuctionContext auctionContext = AuctionContext.builder() .bidRequest(BidRequest.builder().build()) .account(Account.empty("accountId")) @@ -2723,12 +2722,12 @@ public void shouldExecuteProcessedBidderResponseHooksAndPassBidderInvocationCont final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.processed_bidder_response, execPlanOneGroupOneHook("module-alpha", "hook-a")))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = @@ -2828,12 +2827,12 @@ public void shouldExecuteAllProcessedBidResponsesHooksHappyPath() { final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.all_processed_bid_responses, execPlanTwoGroupsTwoHooksEach()))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); final AuctionContext auctionContext = AuctionContext.builder() .bidRequest(BidRequest.builder().build()) .account(Account.empty("accountId")) @@ -2967,7 +2966,7 @@ public void shouldExecuteAllProcessedBidResponsesHooksRejectionAllIgnoringUnknow final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.all_processed_bid_responses, execPlanTwoGroupsTwoHooksEach()))))); @@ -2977,7 +2976,7 @@ public void shouldExecuteAllProcessedBidResponsesHooksRejectionAllIgnoringUnknow bidRejectionTrackers.put("bidderB", new BidRejectionTracker("bidderB", Set.of("impId"), 0.0)); bidRejectionTrackers.put("bidderC", new BidRejectionTracker("bidderC", Set.of("impId"), 0.0)); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); final AuctionContext auctionContext = AuctionContext.builder() .bidRequest(BidRequest.builder().build()) .account(Account.empty("accountId")) @@ -3011,20 +3010,20 @@ public void shouldExecuteAllProcessedBidResponsesHooksRejectionAllIgnoringUnknow assertThat(bidRejectionTrackers.keySet()).containsOnly("bidderA", "bidderB", "bidderC"); assertThat(bidRejectionTrackers.get("bidderA").getAllRejected().get("impId")).containsOnly( - BidRejection.of(bidderABid1, REQUEST_BLOCKED_OPTIMIZED), - BidRejection.of(bidderABid1, REQUEST_BLOCKED_UNSUPPORTED_MEDIA_TYPE), - BidRejection.of(bidderABid2, REQUEST_BLOCKED_GENERAL), - BidRejection.of(bidderABid2, REQUEST_BLOCKED_GENERAL)); + BidRejection.of(bidderABid1, REQUEST_BLOCKED_OPTIMIZED), + BidRejection.of(bidderABid1, REQUEST_BLOCKED_UNSUPPORTED_MEDIA_TYPE), + BidRejection.of(bidderABid2, REQUEST_BLOCKED_GENERAL), + BidRejection.of(bidderABid2, REQUEST_BLOCKED_GENERAL)); assertThat(bidRejectionTrackers.get("bidderB").getAllRejected().get("impId")).containsOnly( - BidRejection.of(bidderBBid3, REQUEST_BLOCKED_UNACCEPTABLE_CURRENCY), - BidRejection.of(bidderBBid3, REQUEST_BLOCKED_PRIVACY), - BidRejection.of(bidderBBid4, REQUEST_BLOCKED_GENERAL), - BidRejection.of(bidderBBid4, REQUEST_BLOCKED_GENERAL)); + BidRejection.of(bidderBBid3, REQUEST_BLOCKED_UNACCEPTABLE_CURRENCY), + BidRejection.of(bidderBBid3, REQUEST_BLOCKED_PRIVACY), + BidRejection.of(bidderBBid4, REQUEST_BLOCKED_GENERAL), + BidRejection.of(bidderBBid4, REQUEST_BLOCKED_GENERAL)); assertThat(bidRejectionTrackers.get("bidderC").getAllRejected().get("impId")).containsOnly( - BidRejection.of(bidderCBid5, REQUEST_BLOCKED_GENERAL), - BidRejection.of(bidderCBid5, REQUEST_BLOCKED_GENERAL), - BidRejection.of(bidderCBid5, REQUEST_BLOCKED_GENERAL), - BidRejection.of(bidderCBid5, REQUEST_BLOCKED_GENERAL)); + BidRejection.of(bidderCBid5, REQUEST_BLOCKED_GENERAL), + BidRejection.of(bidderCBid5, REQUEST_BLOCKED_GENERAL), + BidRejection.of(bidderCBid5, REQUEST_BLOCKED_GENERAL), + BidRejection.of(bidderCBid5, REQUEST_BLOCKED_GENERAL)); } @Test @@ -3037,12 +3036,12 @@ public void shouldExecuteAllProcessedBidResponsesHooksAndPassAuctionInvocationCo final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.all_processed_bid_responses, execPlanOneGroupOneHook("module-alpha", "hook-a")))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = @@ -3088,11 +3087,11 @@ public void shouldExecuteBidderRequestHooksWhenRequestIsRejected(VertxTestContex final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.bidder_request, execPlanOneGroupOneHook("module-alpha", "hook-a")))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = executor.executeBidderRequestStage( @@ -3143,12 +3142,12 @@ public void shouldExecuteAuctionResponseHooksHappyPath(VertxTestContext context) final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.auction_response, execPlanTwoGroupsTwoHooksEach()))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = executor.executeAuctionResponseStage( @@ -3185,11 +3184,11 @@ public void shouldExecuteAuctionResponseHooksAndPassAuctionInvocationContext(Ver final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.auction_response, execPlanOneGroupOneHook("module-alpha", "hook-a")))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = executor.executeAuctionResponseStage( @@ -3230,11 +3229,11 @@ public void shouldExecuteAuctionResponseHooksAndTolerateNullAccount(VertxTestCon final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.auction_response, execPlanOneGroupOneHook("module-alpha", "hook-a")))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = executor.executeAuctionResponseStage( @@ -3272,11 +3271,11 @@ public void shouldExecuteAuctionResponseHooksAndIgnoreRejection(VertxTestContext final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.auction_response, execPlanOneGroupOneHook("module-alpha", "hook-a")))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = executor.executeAuctionResponseStage( @@ -3351,12 +3350,12 @@ public void shouldExecuteExitpointHooksHappyPath(VertxTestContext context) { final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.exitpoint, execPlanTwoGroupsTwoHooksEach()))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = executor.executeExitpointStage( @@ -3400,11 +3399,11 @@ public void shouldExecuteExitpointHooksAndPassAuctionInvocationContext(VertxTest final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.exitpoint, execPlanOneGroupOneHook("module-alpha", "hook-a")))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = executor.executeExitpointStage( @@ -3446,11 +3445,11 @@ public void shouldExecuteExitpointHooksAndIgnoreRejection(VertxTestContext conte final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( - Endpoint.openrtb2_auction, + HookHttpEndpoint.POST_AUCTION, EndpointExecutionPlan.of(singletonMap( Stage.exitpoint, execPlanOneGroupOneHook("module-alpha", "hook-a")))))); - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); // when final Future> future = executor.executeExitpointStage( @@ -3569,7 +3568,7 @@ public void abTestsShouldReturnEnabledTestsFromHost() { ABTest.builder().enabled(true).build()); } - private String executionPlan(Map endpoints) { + private String executionPlan(Map endpoints) { return jacksonMapper.encodeToString(ExecutionPlan.of(null, endpoints)); } diff --git a/src/test/java/org/prebid/server/hooks/execution/provider/abtest/ABTestHookProviderTest.java b/src/test/java/org/prebid/server/hooks/execution/provider/abtest/ABTestHookProviderTest.java index fa6f3291267..98e8d22466a 100644 --- a/src/test/java/org/prebid/server/hooks/execution/provider/abtest/ABTestHookProviderTest.java +++ b/src/test/java/org/prebid/server/hooks/execution/provider/abtest/ABTestHookProviderTest.java @@ -13,13 +13,13 @@ import org.prebid.server.hooks.execution.model.GroupExecutionOutcome; import org.prebid.server.hooks.execution.model.HookExecutionContext; import org.prebid.server.hooks.execution.model.HookExecutionOutcome; +import org.prebid.server.hooks.execution.model.HookHttpEndpoint; import org.prebid.server.hooks.execution.model.HookId; import org.prebid.server.hooks.execution.model.Stage; import org.prebid.server.hooks.execution.model.StageExecutionOutcome; import org.prebid.server.hooks.execution.provider.HookProvider; import org.prebid.server.hooks.v1.Hook; import org.prebid.server.hooks.v1.InvocationContext; -import org.prebid.server.model.Endpoint; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; @@ -50,7 +50,7 @@ public void applyShouldReturnOriginalHookIfNoABTestFound() { final HookProvider target = new ABTestHookProvider<>( innerHookProvider, singletonList(ABTest.builder().moduleCode("otherModule").build()), - HookExecutionContext.of(Endpoint.openrtb2_auction), + HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION), mapper); // when @@ -68,7 +68,7 @@ public void applyShouldReturnWrappedHook() { final HookProvider target = new ABTestHookProvider<>( innerHookProvider, singletonList(ABTest.builder().moduleCode("module").build()), - HookExecutionContext.of(Endpoint.openrtb2_auction), + HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION), mapper); // when @@ -83,7 +83,7 @@ public void applyShouldReturnWrappedHook() { @Test public void shouldInvokeHookShouldReturnTrueIfThereIsAPreviousInvocation() { // given - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); hookExecutionContext.getStageOutcomes().put(Stage.entrypoint, singletonList( StageExecutionOutcome.of("entity", singletonList(GroupExecutionOutcome.of(singletonList( HookExecutionOutcome.builder() @@ -106,7 +106,7 @@ public void shouldInvokeHookShouldReturnTrueIfThereIsAPreviousInvocation() { @Test public void shouldInvokeHookShouldReturnFalseIfThereIsAPreviousExecutionWithoutInvocation() { // given - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(HookHttpEndpoint.POST_AUCTION); hookExecutionContext.getStageOutcomes().put(Stage.entrypoint, singletonList( StageExecutionOutcome.of("entity", singletonList(GroupExecutionOutcome.of(singletonList( HookExecutionOutcome.builder() diff --git a/src/test/java/org/prebid/server/json/deserializer/ExecutionPlanEndpointsConfigDeserializerTest.java b/src/test/java/org/prebid/server/json/deserializer/ExecutionPlanEndpointsConfigDeserializerTest.java new file mode 100644 index 00000000000..f3acd3978f3 --- /dev/null +++ b/src/test/java/org/prebid/server/json/deserializer/ExecutionPlanEndpointsConfigDeserializerTest.java @@ -0,0 +1,171 @@ +package org.prebid.server.json.deserializer; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.exc.InvalidFormatException; +import com.fasterxml.jackson.databind.exc.MismatchedInputException; +import org.junit.jupiter.api.Test; +import org.prebid.server.VertxTest; +import org.prebid.server.hooks.execution.model.EndpointExecutionPlan; +import org.prebid.server.hooks.execution.model.ExecutionGroup; +import org.prebid.server.hooks.execution.model.ExecutionPlan; +import org.prebid.server.hooks.execution.model.HookHttpEndpoint; +import org.prebid.server.hooks.execution.model.HookId; +import org.prebid.server.hooks.execution.model.Stage; +import org.prebid.server.hooks.execution.model.StageExecutionPlan; +import org.prebid.server.model.Endpoint; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.prebid.server.hooks.execution.model.HookHttpEndpoint.POST_AUCTION; + +public class ExecutionPlanEndpointsConfigDeserializerTest extends VertxTest { + + @Test + public void deserializeShouldReturnNullOnNull() throws JsonProcessingException { + // given + final String executionPlan = givenExecutionPlan((Map) null); + + // when + final ExecutionPlan result = mapper.readValue(executionPlan, ExecutionPlan.class); + + // then + assertThat(result.getEndpoints()).isNull(); + } + + @Test + public void deserializeShouldReturnEmptyOnEmpty() throws JsonProcessingException { + // given + final String executionPlan = givenExecutionPlan(Collections.emptyMap()); + + // when + final ExecutionPlan result = mapper.readValue(executionPlan, ExecutionPlan.class); + + // then + assertThat(result.getEndpoints()).isEmpty(); + } + + @Test + public void deserializeShouldReadAllPossibleEndpoints() throws JsonProcessingException { + // given + final String executionPlan = givenExecutionPlan(allEndpoints()); + + // when + final ExecutionPlan result = mapper.readValue(executionPlan, ExecutionPlan.class); + + // then + assertThat(result.getEndpoints()).containsExactlyInAnyOrderEntriesOf(allEndpoints()); + } + + @Test + public void deserializeShouldFailOnInvalidEndpointExecutionPlan() { + // given + final String executionPlan = """ + { + "endpoints": { + "POST /openrtb2/auction": "invalid" + } + }"""; + + // when and then + assertThatExceptionOfType(MismatchedInputException.class) + .isThrownBy(() -> mapper.readValue(executionPlan, ExecutionPlan.class)) + .withMessageContaining("Cannot construct instance of") + .withMessageContaining("deserialize from String value ('invalid')"); + } + + @Test + public void deserializeShouldFailOnInvalidEndpoint() throws JsonProcessingException { + // given + final String executionPlan = givenExecutionPlan("/invalid" + Endpoint.openrtb2_auction.value()); + + // when and then + assertThatExceptionOfType(InvalidFormatException.class) + .isThrownBy(() -> mapper.readValue(executionPlan, ExecutionPlan.class)) + .withMessageContaining("Cannot deserialize Map key of type") + .withMessageContaining("from String \"/invalid/openrtb2/auction\": not a valid representation"); + } + + @Test + public void deserializeShouldFailOnInvalidHttpHookEndpoint() throws JsonProcessingException { + // given + final String executionPlan = givenExecutionPlan("INVALID " + Endpoint.openrtb2_auction.value()); + + // when and then + assertThatExceptionOfType(InvalidFormatException.class) + .isThrownBy(() -> mapper.readValue(executionPlan, ExecutionPlan.class)) + .withMessageContaining("Cannot deserialize value of type") + .withMessageContaining(""" + from String "INVALID /openrtb2/auction": \ + not one of the values accepted for Enum class"""); + } + + @Test + public void deserializeShouldCorrectlyUnpackAllEndpointsWithoutMethod() throws JsonProcessingException { + // given + final String[] endpointsWithoutMethod = Arrays.stream(HookHttpEndpoint.values()) + .map(HookHttpEndpoint::endpoint) + .map(Endpoint::value) + .distinct() + .toArray(String[]::new); + final String executionPlan = givenExecutionPlan(endpointsWithoutMethod); + + // when + final ExecutionPlan result = mapper.readValue(executionPlan, ExecutionPlan.class); + + // then + assertThat(result.getEndpoints()).containsExactlyInAnyOrderEntriesOf( + Arrays.stream(HookHttpEndpoint.values()) + .collect(Collectors.toMap( + Function.identity(), + key -> givenEndpointExecutionPlan(key.endpoint().value())))); + } + + @Test + public void deserializeShouldNotOverrideInitialConfigAfterUnpacking() throws JsonProcessingException { + // given + final String executionPlan = givenExecutionPlan( + POST_AUCTION.toString(), + POST_AUCTION.endpoint().value()); + + // when + final ExecutionPlan result = mapper.readValue(executionPlan, ExecutionPlan.class); + + // then + assertThat(result.getEndpoints()).containsExactlyInAnyOrderEntriesOf( + Map.of(POST_AUCTION, givenEndpointExecutionPlan(POST_AUCTION.toString()))); + } + + private static Map allEndpoints() { + return Arrays.stream(HookHttpEndpoint.values()) + .collect(Collectors.toMap( + Function.identity(), + key -> givenEndpointExecutionPlan(key.toString()))); + } + + private static EndpointExecutionPlan givenEndpointExecutionPlan(String id) { + return EndpointExecutionPlan.of(Map.of(Stage.entrypoint, StageExecutionPlan.of( + singletonList(ExecutionGroup.of(0L, singletonList(HookId.of(id, id))))))); + } + + private static String givenExecutionPlan(Map endpoints) + throws JsonProcessingException { + + return mapper.writeValueAsString(ExecutionPlan.of(null, endpoints)); + } + + private static String givenExecutionPlan(String... hookHttpEndpointsAsStrings) throws JsonProcessingException { + final Map endpoints = Arrays.stream(hookHttpEndpointsAsStrings) + .collect(Collectors.toMap( + Function.identity(), + ExecutionPlanEndpointsConfigDeserializerTest::givenEndpointExecutionPlan)); + + return mapper.writeValueAsString(Map.of("endpoints", endpoints)); + } +} diff --git a/src/test/java/org/prebid/server/settings/EnrichingApplicationSettingsTest.java b/src/test/java/org/prebid/server/settings/EnrichingApplicationSettingsTest.java index f3180d3651e..0a843de8ff6 100644 --- a/src/test/java/org/prebid/server/settings/EnrichingApplicationSettingsTest.java +++ b/src/test/java/org/prebid/server/settings/EnrichingApplicationSettingsTest.java @@ -83,7 +83,8 @@ public void getAccountByIdShouldSuccessfullyMergeWhenDefaultAccountIsEmpty() { "{}", delegate, priceFloorsConfigResolver, - activitiesConfigResolver, jsonMerger, + activitiesConfigResolver, + jsonMerger, jacksonMapper); final Account returnedAccount = Account.builder().build(); From 2346d97a5677c6afb019128c41ad14d468a5846b Mon Sep 17 00:00:00 2001 From: Viktor Kryshtal <33136089+Lightwood13@users.noreply.github.com> Date: Thu, 23 Jul 2026 17:41:47 +0300 Subject: [PATCH 5/8] Update setuid metrics to use bidder name instead of cookie family name (#4571) --- .../prebid/server/handler/SetuidHandler.java | 9 ++++--- .../org/prebid/server/metric/Metrics.java | 24 +++++++++---------- .../functional/tests/CookieSyncSpec.groovy | 4 ++-- .../server/functional/tests/SetUidSpec.groovy | 6 ++--- .../tests/privacy/gdpr/GdprSetUidSpec.groovy | 6 ++--- 5 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/prebid/server/handler/SetuidHandler.java b/src/main/java/org/prebid/server/handler/SetuidHandler.java index e1c8cf8a890..0771e55fa31 100644 --- a/src/main/java/org/prebid/server/handler/SetuidHandler.java +++ b/src/main/java/org/prebid/server/handler/SetuidHandler.java @@ -230,7 +230,7 @@ private void validateSetuidContext(SetuidContext setuidContext) { final TcfContext tcfContext = setuidContext.getPrivacyContext().getTcfContext(); if (tcfContext.isInGdprScope() && !tcfContext.isConsentValid()) { - metrics.updateUserSyncTcfInvalidMetric(usersyncer.getCookieFamilyName()); + metrics.updateUserSyncTcfInvalidMetric(setuidContext.getBidder()); throw new InvalidRequestException("Consent string is invalid"); } @@ -254,7 +254,6 @@ private void respondByTcfResponse(AsyncResult hostTcfResponseRe final TcfContext tcfContext = setuidContext.getPrivacyContext().getTcfContext(); final RoutingContext routingContext = setuidContext.getRoutingContext(); - final String cookieFamilyName = setuidContext.getUsersyncer().getCookieFamilyName(); if (hostTcfResponseResult.succeeded()) { final CompositeFuture compositeFuture = hostTcfResponseResult.result(); @@ -272,7 +271,7 @@ private void respondByTcfResponse(AsyncResult hostTcfResponseRe if (hostVendorTcfResponse.isVendorAllowed() && isBidderVendorAllowed) { respondWithCookie(setuidContext); } else { - metrics.updateUserSyncTcfBlockedMetric(cookieFamilyName); + metrics.updateUserSyncTcfBlockedMetric(setuidContext.getBidder()); final HttpResponseStatus status = new HttpResponseStatus(UNAVAILABLE_FOR_LEGAL_REASONS, "Unavailable for legal reasons"); @@ -287,7 +286,7 @@ private void respondByTcfResponse(AsyncResult hostTcfResponseRe } } else { final Throwable error = hostTcfResponseResult.cause(); - metrics.updateUserSyncTcfBlockedMetric(cookieFamilyName); + metrics.updateUserSyncTcfBlockedMetric(setuidContext.getBidder()); handleErrors(error, routingContext, tcfContext); } } @@ -304,7 +303,7 @@ private void respondWithCookie(SetuidContext setuidContext) { .forEach(routingContext.response()::addCookie); if (uidsCookieUpdateResult.isUpdated()) { - metrics.updateUserSyncSetsMetric(cookieFamilyName); + metrics.updateUserSyncSetsMetric(setuidContext.getBidder()); } final int statusCode = HttpResponseStatus.OK.code(); HttpUtil.executeSafely(routingContext, Endpoint.setuid, buildCookieResponseConsumer(setuidContext, statusCode)); diff --git a/src/main/java/org/prebid/server/metric/Metrics.java b/src/main/java/org/prebid/server/metric/Metrics.java index c6e3394c807..06c31bb1895 100644 --- a/src/main/java/org/prebid/server/metric/Metrics.java +++ b/src/main/java/org/prebid/server/metric/Metrics.java @@ -400,28 +400,28 @@ public void updateUserSyncBadRequestMetric() { userSync().incCounter(MetricName.bad_requests); } - public void updateUserSyncSetsMetric(String cookieFamilyName) { - userSync().forBidder(cookieFamilyName).incCounter(MetricName.sets); + public void updateUserSyncSetsMetric(String bidder) { + userSync().forBidder(bidder).incCounter(MetricName.sets); } - public void updateUserSyncTcfBlockedMetric(String cookieFamilyName) { - userSync().forBidder(cookieFamilyName).tcf().incCounter(MetricName.blocked); + public void updateUserSyncTcfBlockedMetric(String bidder) { + userSync().forBidder(bidder).tcf().incCounter(MetricName.blocked); } - public void updateUserSyncSizeBlockedMetric(String cookieFamilyName) { - userSync().forBidder(cookieFamilyName).incCounter(MetricName.sizeblocked); + public void updateUserSyncTcfInvalidMetric() { + updateUserSyncTcfInvalidMetric(ALL_REQUEST_BIDDERS); } - public void updateUserSyncSizedOutMetric(String cookieFamilyName) { - userSync().forBidder(cookieFamilyName).incCounter(MetricName.sizedout); + public void updateUserSyncTcfInvalidMetric(String bidder) { + userSync().forBidder(bidder).tcf().incCounter(MetricName.invalid); } - public void updateUserSyncTcfInvalidMetric(String cookieFamilyName) { - userSync().forBidder(cookieFamilyName).tcf().incCounter(MetricName.invalid); + public void updateUserSyncSizeBlockedMetric(String cookieFamilyName) { + userSync().forBidder(cookieFamilyName).incCounter(MetricName.sizeblocked); } - public void updateUserSyncTcfInvalidMetric() { - updateUserSyncTcfInvalidMetric(ALL_REQUEST_BIDDERS); + public void updateUserSyncSizedOutMetric(String cookieFamilyName) { + userSync().forBidder(cookieFamilyName).incCounter(MetricName.sizedout); } public void updateCookieSyncFilteredMetric(String bidder) { diff --git a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy index a08ca0e6c2d..9dfee8ae272 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CookieSyncSpec.groovy @@ -374,7 +374,7 @@ class CookieSyncSpec extends BaseSpec { def bidderStatus = response.getBidderUserSync(GENERIC) assert bidderStatus.error == "Rejected by TCF" - and: "Metric should contain cookie_sync.FAMILY.tcf.blocked" + and: "Metric should contain cookie_sync.BIDDER.tcf.blocked" def metric = this.prebidServerService.sendCollectedMetricsRequest() assert metric["cookie_sync.generic.tcf.blocked"] == 1 } @@ -1382,7 +1382,7 @@ class CookieSyncSpec extends BaseSpec { def bidderStatus = response.getBidderUserSync(GENERIC) assert bidderStatus.error == "Rejected by TCF" - and: "Metric should contain cookie_sync.FAMILY.tcf.blocked" + and: "Metric should contain cookie_sync.BIDDER.tcf.blocked" def metric = prebidServerService.sendCollectedMetricsRequest() assert metric["cookie_sync.generic.tcf.blocked"] == 1 } diff --git a/src/test/groovy/org/prebid/server/functional/tests/SetUidSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/SetUidSpec.groovy index 65a1a8650fc..f7f8594f95f 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/SetUidSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/SetUidSpec.groovy @@ -123,7 +123,7 @@ class SetUidSpec extends BaseSpec { assert response.responseBody == ResourceUtil.readByteArrayFromClassPath("org/prebid/server/functional/tracking-pixel.png") - and: "usersync.FAMILY.sets metric should be updated" + and: "usersync.BIDDER.sets metric should be updated" def metrics = singleCookiesPbsService.sendCollectedMetricsRequest() assert metrics["usersync.${GENERIC.value}.sets"] == 1 } @@ -280,7 +280,7 @@ class SetUidSpec extends BaseSpec { assert exception.statusCode == UNAVAILABLE_FOR_LEGAL_REASONS_CODE assert exception.responseBody == TCF_ERROR_MESSAGE - and: "usersync.FAMILY.tcf.blocked metric should be updated" + and: "usersync.BIDDER.tcf.blocked metric should be updated" def metric = prebidServerService.sendCollectedMetricsRequest() assert metric["usersync.${RUBICON.value}.tcf.blocked"] == 1 @@ -357,7 +357,7 @@ class SetUidSpec extends BaseSpec { def metricsRequest = prebidServerService.sendCollectedMetricsRequest() assert metricsRequest["usersync.${APPNEXUS.value}.sizeblocked"] == 1 - and: "usersync.FAMILY.sets metric should be updated" + and: "usersync.BIDDER.sets metric should be updated" assert metricsRequest["usersync.${OPENX.value}.sets"] == 1 cleanup: "Stop and remove pbs container" diff --git a/src/test/groovy/org/prebid/server/functional/tests/privacy/gdpr/GdprSetUidSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/privacy/gdpr/GdprSetUidSpec.groovy index 21e67d65062..a4ff12f45bd 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/privacy/gdpr/GdprSetUidSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/privacy/gdpr/GdprSetUidSpec.groovy @@ -161,7 +161,7 @@ class GdprSetUidSpec extends PrivacyBaseSpec { assert exception.statusCode == UNAVAILABLE_FOR_LEGAL_REASONS_CODE assert exception.responseBody == TCF_ERROR_MESSAGE - and: "Metric should be increased usersync.FAMILY.tcf.blocked" + and: "Metric should be increased usersync.BIDDER.tcf.blocked" def metric = prebidServerService.sendCollectedMetricsRequest() assert metric["usersync.${GENERIC.value}.tcf.blocked"] == 1 } @@ -203,7 +203,7 @@ class GdprSetUidSpec extends PrivacyBaseSpec { assert exception.statusCode == UNAVAILABLE_FOR_LEGAL_REASONS_CODE assert exception.responseBody == TCF_ERROR_MESSAGE - and: "Metric should be increased usersync.FAMILY.tcf.blocked" + and: "Metric should be increased usersync.BIDDER.tcf.blocked" def metric = prebidServerService.sendCollectedMetricsRequest() assert metric["usersync.${GENERIC.value}.tcf.blocked"] == 1 } @@ -249,7 +249,7 @@ class GdprSetUidSpec extends PrivacyBaseSpec { assert exception.statusCode == UNAVAILABLE_FOR_LEGAL_REASONS_CODE assert exception.responseBody == TCF_ERROR_MESSAGE - and: "Metric should be increased usersync.FAMILY.tcf.blocked" + and: "Metric should be increased usersync.BIDDER.tcf.blocked" def metric = prebidServerService.sendCollectedMetricsRequest() assert metric["usersync.${GENERIC.value}.tcf.blocked"] == 1 From d615756723b47f4112b87b84afc8df5116f8244c Mon Sep 17 00:00:00 2001 From: Dubyk Danylo <45672370+CTMBNara@users.noreply.github.com> Date: Thu, 23 Jul 2026 16:47:30 +0200 Subject: [PATCH 6/8] Add `http_method` field to `ExtRequestPrebidServer` (#4378) --- .../Ortb2ImplicitParametersResolver.java | 6 +- .../ext/request/ExtRequestPrebidServer.java | 5 +- .../model/request/auction/Server.groovy | 1 + .../server/functional/tests/AmpSpec.groovy | 26 ++++ .../functional/tests/AuctionSpec.groovy | 6 +- .../Ortb2ImplicitParametersResolverTest.java | 12 +- .../bidder/appnexus/AppnexusBidderTest.java | 29 +++- .../server/bidder/msft/MsftBidderTest.java | 42 ++++-- .../bidder/nativery/NativeryBidderTest.java | 3 +- .../NextMillenniumBidderTest.java | 1 + .../bidder/smaato/SmaatoBidderTest.java | 9 +- .../bidder/taboola/TaboolaBidderTest.java | 2 +- .../it/amp/test-generic-bid-request.json | 1 + .../it/amp/test-genericAlias-bid-request.json | 1 + .../update/test-generic-bid-request1.json | 1 + .../test-genericAlias-bid-request2.json | 1 + .../reject/test-generic-bid-request.json | 1 + .../test-auction-generic-response.json | 1 + .../test-generic-bid-request.json | 1 + .../152media/test-152media-bid-request.json | 1 + .../test-360playvid-bid-request.json | 1 + .../it/openrtb2/aax/test-aax-bid-request.json | 1 + .../aceex/test-aceex-bid-request.json | 1 + .../acuityads/test-acuityads-bid-request.json | 1 + .../adagio/test-adagio-bid-request.json | 1 + .../addigi/test-addigi-bid-request.json | 1 + .../adelement/test-adelement-bid-request.json | 1 + .../it/openrtb2/adf/test-adf-bid-request.json | 1 + .../adhese/test-adhese-bid-request.json | 3 +- .../adinify/test-adinify-bid-request.json | 1 + .../adipolo/test-adipolo-bid-request.json | 1 + .../adkernel/test-adkernel-bid-request.json | 1 + .../test-adkerneladn-bid-request.json | 1 + .../adman/test-adman-bid-request.json | 1 + .../admatic/test-admatic-bid-request.json | 1 + .../admaticde/test-admaticde-bid-request.json | 1 + .../admixer/test-admixer-bid-request.json | 1 + .../openrtb2/adot/test-adot-bid-request.json | 1 + .../adpone/test-adpone-bid-request.json | 1 + .../adprime/test-adprime-bid-request.json | 1 + .../adrino/test-adrino-bid-request.json | 1 + .../adsmovil/test-adsmovil-bid-request.json | 1 + .../it/openrtb2/adt/test-adt-bid-request.json | 1 + .../adtarget/test-adtarget-bid-request-1.json | 1 + .../test-adtelligent-bid-request.json | 1 + .../adtonos/test-adtonos-bid-request.json | 1 + .../adtrgtme/test-adtrgtme-bid-request.json | 1 + .../aduptech/test-aduptech-bid-request.json | 1 + .../test-advangelists-bid-request.json | 1 + .../adview/test-adview-bid-request.json | 1 + .../adxcg/test-adxcg-bid-request.json | 1 + .../adyoulike/test-adyoulike-bid-request.json | 1 + .../afront/test-afront-bid-request.json | 1 + .../aidem/test-aidem-bid-request.json | 1 + .../it/openrtb2/aja/test-aja-bid-request.json | 1 + .../akcelo/test-akcelo-bid-request.json | 3 +- .../algorix/test-algorix-bid-request.json | 1 + .../alkimi/test-alkimi-bid-request.json | 1 + .../it/openrtb2/amx/test-amx-bid-request.json | 1 + .../apacdex/test-apacdex-bid-request.json | 1 + .../test-video-appnexus-bid-request-1.json | 1 + .../test-video-appnexus-bid-request-2.json | 1 + .../test-appstockssp-bid-request.json | 1 + .../appush/test-appush-bid-request.json | 3 +- .../test-artechnology-bid-request.json | 1 + .../it/openrtb2/aso/test-aso-bid-request.json | 1 + .../automatad/test-automatad-bid-request.json | 1 + .../avocet/test-avocet-bid-request-1.json | 1 + .../openrtb2/axis/test-axis-bid-request.json | 1 + .../axonix/test-axonix-bid-request.json | 1 + .../bcmint/test-bcmint-bid-request.json | 1 + .../beintoo/test-beintoo-bid-request.json | 1 + .../test-bematterfull-bid-request.json | 1 + .../openrtb2/beop/test-beop-bid-request.json | 1 + .../between/test-between-bid-request.json | 1 + .../test-beyondmedia-bid-request.json | 1 + .../bidagency/test-bidagency-bid-request.json | 1 + .../bidfuse/test-bidfuse-bid-request.json | 1 + .../test-bidmachine-bid-request.json | 1 + .../bidmatic/test-bidmatic-bid-request.json | 1 + .../bidmyadz/test-bidmyadz-bid-request.json | 1 + .../bidscube/test-bidscube-bid-request.json | 1 + .../bidstack/test-bidstack-bid-request.json | 1 + .../test-bidtheatre-bid-request.json | 1 + .../bigoad/test-bigoad-bid-request.json | 1 + .../blasto/test-blasto-bid-request.json | 1 + .../bliink/test-bliink-bid-request.json | 1 + .../openrtb2/blis/test-blis-bid-request.json | 1 + .../openrtb2/blue/test-blue-bid-request.json | 1 + .../bluesea/test-bluesea-bid-request.json | 1 + .../openrtb2/bmtm/test-bmtm-bid-request.json | 1 + .../boldwin/test-boldwin-bid-request.json | 1 + .../test-boldwinrapid-bid-request.json | 1 + .../brave/test-brave-bid-request.json | 1 + .../it/openrtb2/bwx/test-bwx-bid-request.json | 1 + .../test-cadentaperturemx-bid-request.json | 1 + .../it/openrtb2/ccx/test-ccx-bid-request.json | 1 + .../clydo/test-clydo-bid-request.json | 1 + .../test-cointraffic-bid-request.json | 1 + .../coinzilla/test-coinzilla-bid-request.json | 1 + .../colossus/test-colossus-bid-request.json | 1 + .../test-colossusssp-bid-request.json | 1 + .../compass/test-compass-bid-request.json | 1 + .../concert/test-concert-bid-request.json | 1 + .../test-banner-connatix-bid-request.json | 1 + .../connectad/test-connectad-bid-request.json | 1 + .../connektai/test-connektai-bid-request.json | 1 + .../test-consumable-bid-request.json | 1 + .../contxtful/test-contxtful-bid-request.json | 1 + .../copper6/test-copper6-bid-request.json | 1 + .../test-copper6ssp-bid-request.json | 1 + .../cpmstar/test-cpmstar-bid-request.json | 1 + .../criteo/test-criteo-bid-request.json | 1 + .../cwire/test-cwire-bid-request.json | 1 + .../test-datablocks-bid-request.json | 1 + .../test-decenterads-bid-request.json | 1 + .../test-deepintent-bid-request.json | 1 + .../test-definemedia-bid-request.json | 1 + .../dianomi/test-dianomi-bid-request.json | 1 + .../displayio/test-displayio-bid-request.json | 1 + .../it/openrtb2/dmx/test-dmx-bid-request.json | 1 + .../test-driftpixel-bid-request.json | 1 + .../edge226/test-edge226-bid-request.json | 1 + .../test-elementaltv-bid-request-1.json | 1 + .../openrtb2/emtv/test-emtv-bid-request.json | 1 + .../test-emxdigital-bid-request.json | 1 + .../epom/test-epom-bid-request-1.json | 1 + .../alias/test-epsilon-bid-request.json | 1 + .../epsilon/test-epsilon-bid-request.json | 1 + .../equativ/test-equativ-bid-request.json | 1 + .../escalax/test-escalax-bid-request.json | 1 + .../evolution/test-evolution-bid-request.json | 1 + .../openrtb2/exco/test-exco-bid-request.json | 1 + .../feedad/test-feedad-bid-request.json | 1 + .../felixads/test-felixads-bid-request.json | 1 + .../finative/test-finative-bid-request.json | 1 + .../flatads/test-flatads-bid-request.json | 1 + .../floors/floors-test-bid-request-1.json | 1 + .../floors/floors-test-bid-request-2.json | 1 + .../floors-test-bid-request-no-signal.json | 1 + .../test-freewheelssp-bid-request.json | 1 + .../frvradn/test-frvradn-bid-request.json | 1 + .../fwssp/test-fwssp-bid-request.json | 1 + .../gamoshi/test-gamoshi-bid-request.json | 1 + .../generic/test-generic-bid-request.json | 1 + .../test-generic-bid-request.json | 3 +- .../globalsun/test-globalsun-bid-request.json | 1 + .../gothamads/test-gothamads-bid-request.json | 1 + .../gravite/test-gravite-bid-request.json | 1 + .../gumgum/test-gumgum-bid-request.json | 1 + .../harion/test-harion-bid-request.json | 1 + .../impactify/test-impactify-bid-request.json | 1 + .../test-improvedigital-bid-request.json | 1 + .../indicue/test-indicue-bid-request.json | 1 + .../infytv/test-infytv-bid-request-1.json | 1 + .../inmobi/test-inmobi-bid-request.json | 1 + .../test-insticator-bid-request.json | 1 + .../intenze/test-intenze-bid-request.json | 1 + .../test-interactiveoffers-bid-request.json | 1 + .../it/openrtb2/iqx/test-iqx-bid-request.json | 1 + .../iqzone/test-iqzone-bid-request.json | 1 + .../it/openrtb2/ix/test-ix-bid-request.json | 1 + .../jambojar/test-jambojar-bid-request.json | 1 + .../jdpmedia/test-jdpmedia-bid-request.json | 1 + .../jixie/test-jixie-bid-request.json | 1 + .../kargo/test-kargo-bid-request.json | 1 + .../kayzen/test-kayzen-bid-request.json | 1 + .../kidoz/test-kidoz-bid-request.json | 1 + .../kiviads/test-kiviads-bid-request.json | 1 + .../kobler/test-kobler-bid-request.json | 1 + .../test-krushmedia-bid-request.json | 1 + .../kuantyx/test-kuantyx-bid-request.json | 1 + .../kueezrtb/test-kueezrtb-bid-request.json | 1 + .../test-lemmaDigital-bid-request.json | 1 + .../liftoff/test-liftoff-bid-request.json | 1 + .../lmkiviads/test-lmkiviads-bid-request.json | 1 + .../test-lockerdome-bid-request.json | 1 + .../logan/test-logan-bid-request.json | 1 + .../logicad/test-logicad-bid-request.json | 1 + .../loopme/test-loopme-bid-request.json | 1 + .../loyal/test-loyal-bid-request.json | 1 + .../lunamedia/test-lunamedia-bid-request.json | 1 + .../mabidder/test-mabidder-bid-request.json | 1 + .../madsense/test-madsense-bid-request.json | 1 + .../test-madvertise-bid-request.json | 1 + .../markapp/test-markapp-bid-request.json | 1 + .../marsmedia/test-marsmedia-bid-request.json | 1 + .../mediago/test-mediago-bid-request.json | 1 + .../medianet/test-medianet-bid-request.json | 1 + .../melozen/test-melozen-bid-request.json | 1 + .../metax/test-metax-bid-request.json | 1 + .../openrtb2/mgid/test-mgid-bid-request.json | 1 + .../mgidx/test-mgidx-bid-request.json | 3 +- .../test-minutemedia-bid-request.json | 1 + .../missena/test-missena-bid-request.json | 105 +++++++------- .../mobfoxpb/test-mobfoxpb-bid-request.json | 1 + .../test-mobilefuse-bid-request.json | 1 + .../mobkoi/test-mobkoi-bid-request.json | 1 + .../test-monetixads-bid-request.json | 1 + .../motorik/test-motorik-bid-request.json | 1 + .../openrtb2/msft/test-msft-bid-request.json | 1 + .../multi_bid/test-generic-bid-request-1.json | 1 + .../test-genericAlias-bid-request-1.json | 1 + .../test-mycodemedia-bid-request.json | 1 + .../test-auction-nativery-request.json | 1 + .../nativery/test-nativery-bid-request.json | 1 + .../nativo/test-nativo-bid-request.json | 1 + .../test-netaddiction-bid-request.json | 1 + .../test-nextmillennium-bid-request.json | 1 + .../nobid/test-nobid-bid-request.json | 1 + .../ogury/test-ogury-bid-request.json | 1 + .../omnidex/test-omnidex-bid-request.json | 1 + .../it/openrtb2/oms/test-oms-bid-request.json | 1 + .../onetag/test-onetag-bid-request.json | 1 + .../openweb/test-openweb-bid-request.json | 1 + .../operaads/test-operaads-bid-request.json | 1 + .../test-optidigital-bid-request.json | 1 + .../oraki/test-oraki-bid-request.json | 1 + .../orbidder/test-orbidder-bid-request.json | 1 + .../outbrain/test-outbrain-bid-request.json | 1 + .../ownadx/test-ownadx-bid-request.json | 1 + .../pangle/test-pangle-bid-request.json | 1 + .../openrtb2/pgam/test-pgam-bid-request.json | 1 + .../pgamssp/test-pgamssp-bid-request.json | 1 + .../pinklion/test-pinklion-bid-request.json | 1 + .../pixad/test-pixad-bid-request.json | 1 + .../playdigo/test-playdigo-bid-request.json | 1 + .../preciso/test-preciso-bid-request.json | 1 + .../progx/test-progx-bid-request.json | 1 + .../pubnative/test-pubnative-bid-request.json | 1 + .../pubrise/test-pubrise-bid-request.json | 1 + ...lsepoint-bid-request-params-as-string.json | 1 + .../test-pulsepoint-bid-request.json | 1 + .../pwbid/test-pwbid-bid-request.json | 1 + .../it/openrtb2/qt/test-qt-bid-request.json | 1 + .../test-radianfusion-bid-request.json | 1 + .../readpeak/test-readpeak-bid-request.json | 1 + .../rediads/test-rediads-bid-request.json | 1 + .../test-relevantdigital-bid-request.json | 1 + .../test-resetdigital-bid-request.json | 1 + .../test-revcontent-bid-request.json | 1 + .../test-richaudience-bid-request.json | 1 + .../openrtb2/rise/test-rise-bid-request.json | 1 + .../rocketlab/test-rocketlab-bid-request.json | 1 + .../roulax/test-roulax-bid-request.json | 1 + .../rtbhouse/test-rtbhouse-bid-request.json | 1 + .../rxnetwork/test-rxnetwork-bid-request.json | 1 + .../test-salunamedia-bid-request.json | 1 + .../test-screencore-bid-request.json | 1 + .../test-seedingAlliance-bid-request.json | 1 + .../seedtag/test-seedtag-bid-request.json | 1 + .../test-sharethrough-bid-request.json | 1 + .../test-showheroes-bid-request.json | 1 + .../test-showheroes-bid-request.json | 1 + .../test-showheroes-bid-request.json | 1 + .../silvermob/test-silvermob-bid-request.json | 1 + .../test-smartadserver-bid-request.json | 1 + .../smarthub/test-smarthub-bid-request.json | 1 + .../smartrtb/test-smartrtb-bid-request.json | 1 + .../smartx/test-smartx-bid-request.json | 1 + .../smartyads/test-smartyads-bid-request.json | 1 + .../test-smilewanted-bid-request.json | 1 + .../smoot/test-smoot-bid-request.json | 1 + .../test-smrtconnect-bid-request.json | 1 + .../sonobi/test-sonobi-bid-request.json | 1 + .../sovrn/test-sovrn-bid-request.json | 1 + .../sovrnxsp/test-sovrnxsp-bid-request.json | 1 + .../sparteo/test-sparteo-bid-request.json | 137 +++++++++--------- .../sspbc/test-sspbc-bid-request.json | 7 +- .../startio/test-startio-bid-request.json | 1 + .../test-stroeercore-bid-request.json | 1 + .../test-suntContent-bid-request.json | 1 + .../test-taboola-bid-request-banner.json | 1 + .../test-taboola-bid-request-native.json | 1 + .../tagoras/test-tagoras-bid-request.json | 1 + .../teads/test-teads-bid-request.json | 1 + .../openrtb2/teal/test-teal-bid-request.json | 1 + .../teqblaze/test-teqblaze-bid-request.json | 1 + .../theadx/test-theadx-bid-request.json | 1 + .../test-thetradedesk-bid-request.json | 1 + .../openrtb2/tpmn/test-tpmn-bid-request.json | 1 + .../tradplus/test-tradplus-bid-request.json | 1 + .../test-trafficgate-bid-request.json | 1 + .../tredio/test-tredio-bid-request.json | 1 + .../test-triplelift-bid-request.json | 1 + .../test-triplelift-native-bid-request.json | 1 + .../test-trustedstack-bid-request.json | 1 + .../trustx/test-trustx-bid-request.json | 1 + .../ucfunnel/test-ucfunnel-bid-request.json | 1 + .../unicorn/test-unicorn-bid-request.json | 1 + .../unruly/test-unruly-bid-request.json | 1 + .../vidazoo/test-vidazoo-bid-request.json | 1 + .../videobyte/test-videobyte-bid-request.json | 1 + .../test-videoheroes-bid-request.json | 1 + .../vidoomy/test-vidoomy-bid-request.json | 1 + .../test-visiblemeasures-bid-request.json | 1 + .../openrtb2/visx/test-visx-bid-request.json | 1 + .../it/openrtb2/vox/test-vox-bid-request.json | 1 + .../vrtcal/test-vrtcal-bid-request.json | 1 + .../vungle/test-vungle-bid-request.json | 1 + .../xapads/test-xapads-bid-request.json | 1 + .../xeworks/test-xeworks-bid-request.json | 1 + .../yahooads/test-yahooads-bid-request.json | 1 + .../yandex/test-yandex-bid-request.json | 1 + .../yeahmobi/test-yeahmobi-bid-request.json | 1 + .../yearxero/test-yearxero-bid-request.json | 1 + .../yieldmo/test-yieldmo-bid-request.json | 1 + .../yieldone/test-yieldone-bid-request.json | 1 + .../yobee/test-yobee-bid-request.json | 1 + .../zentotem/test-zentotem-bid-request.json | 1 + .../test-zeroclickfraud-bid-request.json | 1 + .../test-zeta_global_ssp-bid-request.json | 1 + .../zmaticoo/test-zmaticoo-bid-request.json | 1 + .../test-amp-stored-request.json | 1 + 314 files changed, 552 insertions(+), 148 deletions(-) diff --git a/src/main/java/org/prebid/server/auction/requestfactory/Ortb2ImplicitParametersResolver.java b/src/main/java/org/prebid/server/auction/requestfactory/Ortb2ImplicitParametersResolver.java index 4371fd9c3e9..a26b1a0433b 100644 --- a/src/main/java/org/prebid/server/auction/requestfactory/Ortb2ImplicitParametersResolver.java +++ b/src/main/java/org/prebid/server/auction/requestfactory/Ortb2ImplicitParametersResolver.java @@ -126,7 +126,7 @@ public Ortb2ImplicitParametersResolver(boolean shouldCacheOnlyWinningBids, this.generateBidRequestId = generateBidRequestId; this.adServerCurrency = validateCurrency(Objects.requireNonNull(adServerCurrency)); this.blocklistedApps = Objects.requireNonNull(blocklistedApps); - this.serverInfo = ExtRequestPrebidServer.of(externalUrl, hostVendorId, datacenterRegion, null); + this.serverInfo = ExtRequestPrebidServer.of(externalUrl, hostVendorId, datacenterRegion, null, null); this.bidderCatalog = Objects.requireNonNull(bidderCatalog); this.paramsExtractor = Objects.requireNonNull(paramsExtractor); this.timeoutResolver = Objects.requireNonNull(timeoutResolver); @@ -192,6 +192,7 @@ public BidRequest resolve(BidRequest bidRequest, ext, bidRequest, ObjectUtils.defaultIfNull(populatedImps, imps), + auctionContext.getHttpRequest().getHttpMethod().name(), endpoint, auctionContext.getAccount()); @@ -722,6 +723,7 @@ private static boolean isUniqueIds(List imps) { private ExtRequest populateRequestExt(ExtRequest ext, BidRequest bidRequest, List imps, + String httpMethod, String endpoint, Account account) { @@ -742,7 +744,7 @@ private ExtRequest populateRequestExt(ExtRequest ext, ObjectUtil.getIfNotNull(prebid, ExtRequestPrebid::getCache))) .channel(ObjectUtils.defaultIfNull(updatedChannel, ObjectUtil.getIfNotNull(prebid, ExtRequestPrebid::getChannel))) - .server(serverInfo.with(endpoint)) + .server(serverInfo.with(httpMethod, endpoint)) .build()); final Map extProperties = ObjectUtil.getIfNotNull(ext, ExtRequest::getProperties); diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/request/ExtRequestPrebidServer.java b/src/main/java/org/prebid/server/proto/openrtb/ext/request/ExtRequestPrebidServer.java index 8a874fcf32e..2a6c75bc918 100644 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/request/ExtRequestPrebidServer.java +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/request/ExtRequestPrebidServer.java @@ -14,13 +14,16 @@ public class ExtRequestPrebidServer { String datacenter; + String httpMethod; + String endpoint; - public ExtRequestPrebidServer with(String endpoint) { + public ExtRequestPrebidServer with(String httpMethod, String endpoint) { return ExtRequestPrebidServer.of( this.externalUrl, this.gvlId, this.datacenter, + httpMethod, endpoint); } } diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/Server.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/Server.groovy index 280ef3c7550..c088163b38b 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/Server.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/Server.groovy @@ -12,4 +12,5 @@ class Server { Integer gvlId String datacenter String endpoint + String httpMethod } diff --git a/src/test/groovy/org/prebid/server/functional/tests/AmpSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/AmpSpec.groovy index 47e08555828..805204139ae 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/AmpSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/AmpSpec.groovy @@ -1,5 +1,6 @@ package org.prebid.server.functional.tests +import org.apache.http.client.methods.HttpGet import org.prebid.server.functional.model.db.StoredRequest import org.prebid.server.functional.model.db.StoredResponse import org.prebid.server.functional.model.request.amp.AmpRequest @@ -15,6 +16,7 @@ import org.prebid.server.functional.service.PrebidServerException import org.prebid.server.functional.util.PBSUtils import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST +import static org.prebid.server.functional.model.bidder.BidderName.GENERIC import static org.prebid.server.functional.util.SystemProperties.PBS_VERSION class AmpSpec extends BaseSpec { @@ -258,4 +260,28 @@ class AmpSpec extends BaseSpec { assert !bidderRequest.user.ext.consentedProvidersSettingsCamelCase.consentedProviders assert !bidderRequest.user.ext.consentedProvidersSettings.consentedProviders } + + def "PBS should move endpoint metadata to ext.prebid.server and strip aliases in bidder request"() { + given: "Default amp request" + def ampRequest = AmpRequest.defaultAmpRequest + + and: "Save storedRequest into DB" + def ampStoredRequest = BidRequest.defaultBidRequest.tap { + ext.prebid.aliases = [(PBSUtils.randomString): GENERIC] + } + def storedRequest = StoredRequest.getStoredRequest(ampRequest, ampStoredRequest) + storedRequestDao.save(storedRequest) + + when: "PBS processes amp request" + defaultPbsService.sendAmpRequest(ampRequest) + + then: "BidderRequest should contain endpoint in ext.prebid.server.endpoint instead of ext.prebid.pbs.endpoint" + def bidderRequest = bidder.getBidderRequest(ampStoredRequest.id) + assert bidderRequest?.ext?.prebid?.server?.endpoint == "/openrtb2/amp" + assert bidderRequest?.ext?.prebid?.server?.httpMethod == HttpGet.METHOD_NAME + assert !bidderRequest?.ext?.prebid?.pbs?.endpoint + + and: "BidderRequest shouldn't populate aliases field" + assert !bidderRequest.ext.prebid.aliases + } } diff --git a/src/test/groovy/org/prebid/server/functional/tests/AuctionSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/AuctionSpec.groovy index 6ca6bc42177..378c1ddd5e6 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/AuctionSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/AuctionSpec.groovy @@ -1,5 +1,6 @@ package org.prebid.server.functional.tests +import org.apache.http.client.methods.HttpPost import org.prebid.server.functional.model.UidsCookie import org.prebid.server.functional.model.bidder.Generic import org.prebid.server.functional.model.config.AccountAuctionConfig @@ -286,7 +287,7 @@ class AuctionSpec extends BaseSpec { assert !bidderRequest.user } - def "PBS should move and not populate certain fields when debug enabled"() { + def "PBS should move endpoint metadata to ext.prebid.server and strip aliases in bidder request"() { given: "Default bid request with aliases" def bidRequest = BidRequest.defaultBidRequest.tap { ext.prebid.aliases = [(PBSUtils.randomString): GENERIC] @@ -298,9 +299,10 @@ class AuctionSpec extends BaseSpec { then: "BidderRequest should contain endpoint in ext.prebid.server.endpoint instead of ext.prebid.pbs.endpoint" def bidderRequest = bidder.getBidderRequest(bidRequest.id) assert bidderRequest?.ext?.prebid?.server?.endpoint == "/openrtb2/auction" + assert bidderRequest?.ext?.prebid?.server?.httpMethod == HttpPost.METHOD_NAME assert !bidderRequest?.ext?.prebid?.pbs?.endpoint - and: "BidderRequest shouldn't populate fields" + and: "BidderRequest shouldn't populate aliases field" assert !bidderRequest.ext.prebid.aliases } diff --git a/src/test/java/org/prebid/server/auction/requestfactory/Ortb2ImplicitParametersResolverTest.java b/src/test/java/org/prebid/server/auction/requestfactory/Ortb2ImplicitParametersResolverTest.java index 41fa98842e7..d930a489c72 100644 --- a/src/test/java/org/prebid/server/auction/requestfactory/Ortb2ImplicitParametersResolverTest.java +++ b/src/test/java/org/prebid/server/auction/requestfactory/Ortb2ImplicitParametersResolverTest.java @@ -18,6 +18,7 @@ import com.iab.openrtb.request.SupplyChain; import com.iab.openrtb.request.User; import com.iab.openrtb.request.Video; +import io.vertx.core.http.HttpMethod; import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -138,6 +139,7 @@ public void setUp() { defaultBidRequest = BidRequest.builder().build(); auctionContext = givenAuctionContext(HttpRequestContext.builder() + .httpMethod(HttpMethod.POST) .headers(CaseInsensitiveMultiMap.empty()) .build()); @@ -299,6 +301,7 @@ public void shouldNotImplicitlyResolveIpIfIpv6IsPassed() { public void shouldNotSetDeviceDntIfHeaderHasInvalidValue() { // given final HttpRequestContext httpRequest = HttpRequestContext.builder() + .httpMethod(HttpMethod.POST) .headers(CaseInsensitiveMultiMap.builder() .add("DNT", "invalid") .build()) @@ -316,6 +319,7 @@ public void shouldNotSetDeviceDntIfHeaderHasInvalidValue() { public void shouldSetDeviceDntIfHeaderExists() { // given final HttpRequestContext httpRequest = HttpRequestContext.builder() + .httpMethod(HttpMethod.POST) .headers(CaseInsensitiveMultiMap.builder() .add("DNT", "1") .build()) @@ -333,6 +337,7 @@ public void shouldSetDeviceDntIfHeaderExists() { public void shouldOverrideDeviceDntIfHeaderExists() { // given final HttpRequestContext httpRequest = HttpRequestContext.builder() + .httpMethod(HttpMethod.POST) .headers(CaseInsensitiveMultiMap.builder() .add("DNT", "0") .build()) @@ -2547,7 +2552,12 @@ public void shouldPassExtPrebidServer() { .extracting(BidRequest::getExt) .extracting(ExtRequest::getPrebid) .extracting(ExtRequestPrebid::getServer) - .isEqualTo(ExtRequestPrebidServer.of("https://external.url/", 0, "datacenter-region", ENDPOINT)); + .isEqualTo(ExtRequestPrebidServer.of( + "https://external.url/", + 0, + "datacenter-region", + HttpMethod.POST.name(), + ENDPOINT)); } @Test diff --git a/src/test/java/org/prebid/server/bidder/appnexus/AppnexusBidderTest.java b/src/test/java/org/prebid/server/bidder/appnexus/AppnexusBidderTest.java index b1d01c2fa68..feb2ee68436 100644 --- a/src/test/java/org/prebid/server/bidder/appnexus/AppnexusBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/appnexus/AppnexusBidderTest.java @@ -13,6 +13,7 @@ import com.iab.openrtb.response.Bid; import com.iab.openrtb.response.BidResponse; import com.iab.openrtb.response.SeatBid; +import io.vertx.core.http.HttpMethod; import org.junit.jupiter.api.Test; import org.prebid.server.VertxTest; import org.prebid.server.bidder.appnexus.proto.AppnexusBidExt; @@ -553,7 +554,12 @@ public void makeHttpRequestsShouldUpdateExtAppnexusIfAmpRequest() { // given final BidRequest bidRequest = givenBidRequest( request -> request.ext(ExtRequest.of(ExtRequestPrebid.builder() - .server(ExtRequestPrebidServer.of(null, null, null, openrtb2_amp.value())) + .server(ExtRequestPrebidServer.of( + null, + null, + null, + HttpMethod.GET.name(), + openrtb2_amp.value())) .build())), givenImp(givenExt(identity()))); @@ -578,7 +584,12 @@ public void makeHttpRequestsShouldUpdateExtAppnexusIfVideoRequest() { // given final BidRequest bidRequest = givenBidRequest( request -> request.ext(ExtRequest.of(ExtRequestPrebid.builder() - .server(ExtRequestPrebidServer.of(null, null, null, openrtb2_video.value())) + .server(ExtRequestPrebidServer.of( + null, + null, + null, + HttpMethod.POST.name(), + openrtb2_video.value())) .build())), givenImp(givenExt(identity()))); @@ -624,7 +635,12 @@ public void makeHttpRequestsShouldSplitImpsByPods() { // given final BidRequest bidRequest = givenBidRequest( request -> request.ext(ExtRequest.of(ExtRequestPrebid.builder() - .server(ExtRequestPrebidServer.of(null, null, null, openrtb2_video.value())) + .server(ExtRequestPrebidServer.of( + null, + null, + null, + HttpMethod.POST.name(), + openrtb2_video.value())) .build())), IntStream.range(0, 42) .mapToObj(i -> givenImp( @@ -650,7 +666,12 @@ public void makeHttpRequestsShouldGenerateProperAdPodIds() { // given final BidRequest bidRequest = givenBidRequest( request -> request.ext(ExtRequest.of(ExtRequestPrebid.builder() - .server(ExtRequestPrebidServer.of(null, null, null, openrtb2_video.value())) + .server(ExtRequestPrebidServer.of( + null, + null, + null, + HttpMethod.POST.name(), + openrtb2_video.value())) .build())), givenImp(imp -> imp.id("1_random"), givenExt(ext -> ext.generateAdPodId(true))), givenImp(imp -> imp.id("1_random"), givenExt(ext -> ext.generateAdPodId(true))), diff --git a/src/test/java/org/prebid/server/bidder/msft/MsftBidderTest.java b/src/test/java/org/prebid/server/bidder/msft/MsftBidderTest.java index bc42c57ab9b..2174e7d4cfd 100644 --- a/src/test/java/org/prebid/server/bidder/msft/MsftBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/msft/MsftBidderTest.java @@ -344,7 +344,7 @@ public void makeHttpRequestsShouldSetDisplayManagerVersionIfItIsAbsent() { public void makeHttpRequestsShouldNotReplaceDisplayManagerVersionIfItIsPresent() { // given final BidRequest bidRequest = givenBidRequest(request -> request.app( - App.builder().ext(ExtApp.of(ExtAppPrebid.of("testSource", "testVersion"), null)).build()), + App.builder().ext(ExtApp.of(ExtAppPrebid.of("testSource", "testVersion"), null)).build()), givenImp(imp -> imp.displaymanagerver("testDisplayManagerVersion").ext(givenImpExt()))); // when @@ -488,8 +488,14 @@ public void makeHttpRequestsShouldPreserveBrandCategoryFieldsIfIncludeBrandCateg @Test public void makeHttpRequestsShouldSetIsAmpToOneIfRequestComesFromAmpEndpoint() { // given - final ExtRequest extRequest = ExtRequest.of(ExtRequestPrebid.builder().server(ExtRequestPrebidServer.of( - "testExternalUrl", 1, "testDatacenter", Endpoint.openrtb2_amp.value())).build()); + final ExtRequest extRequest = ExtRequest.of(ExtRequestPrebid.builder() + .server(ExtRequestPrebidServer.of( + "testExternalUrl", + 1, + "testDatacenter", + HttpMethod.GET.name(), + Endpoint.openrtb2_amp.value())) + .build()); final BidRequest bidRequest = givenBidRequest(request -> request.ext(extRequest), givenImp()); // when @@ -506,8 +512,14 @@ public void makeHttpRequestsShouldSetIsAmpToOneIfRequestComesFromAmpEndpoint() { @Test public void makeHttpRequestsShouldSetIsAmpToZeroIfRequestDoesNotComeFromAmpEndpoint() { // given - final ExtRequest extRequest = ExtRequest.of(ExtRequestPrebid.builder().server(ExtRequestPrebidServer.of( - "testExternalUrl", 1, "testDatacenter", Endpoint.openrtb2_video.value())).build()); + final ExtRequest extRequest = ExtRequest.of(ExtRequestPrebid.builder() + .server(ExtRequestPrebidServer.of( + "testExternalUrl", + 1, + "testDatacenter", + HttpMethod.POST.name(), + Endpoint.openrtb2_video.value())) + .build()); final BidRequest bidRequest = givenBidRequest(request -> request.ext(extRequest), givenImp()); // when @@ -524,8 +536,14 @@ public void makeHttpRequestsShouldSetIsAmpToZeroIfRequestDoesNotComeFromAmpEndpo @Test public void makeHttpRequestsShouldSetHbSourceToHbSourceVideoValueIfRequestComesFromVideoEndpoint() { // given - final ExtRequest extRequest = ExtRequest.of(ExtRequestPrebid.builder().server(ExtRequestPrebidServer.of( - "testExternalUrl", 1, "testDatacenter", Endpoint.openrtb2_video.value())).build()); + final ExtRequest extRequest = ExtRequest.of(ExtRequestPrebid.builder() + .server(ExtRequestPrebidServer.of( + "testExternalUrl", + 1, + "testDatacenter", + HttpMethod.POST.name(), + Endpoint.openrtb2_video.value())) + .build()); final BidRequest bidRequest = givenBidRequest(request -> request.ext(extRequest), givenImp()); // when @@ -542,8 +560,14 @@ public void makeHttpRequestsShouldSetHbSourceToHbSourceVideoValueIfRequestComesF @Test public void makeHttpRequestsShouldSetHbSourceToDefaultValueIfRequestDoesNotComeFromVideoEndpoint() { // given - final ExtRequest extRequest = ExtRequest.of(ExtRequestPrebid.builder().server(ExtRequestPrebidServer.of( - "testExternalUrl", 1, "testDatacenter", Endpoint.openrtb2_amp.value())).build()); + final ExtRequest extRequest = ExtRequest.of(ExtRequestPrebid.builder() + .server(ExtRequestPrebidServer.of( + "testExternalUrl", + 1, + "testDatacenter", + HttpMethod.GET.name(), + Endpoint.openrtb2_amp.value())) + .build()); final BidRequest bidRequest = givenBidRequest(request -> request.ext(extRequest), givenImp()); // when diff --git a/src/test/java/org/prebid/server/bidder/nativery/NativeryBidderTest.java b/src/test/java/org/prebid/server/bidder/nativery/NativeryBidderTest.java index ffc0a8a1d9f..707fd40d27a 100644 --- a/src/test/java/org/prebid/server/bidder/nativery/NativeryBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/nativery/NativeryBidderTest.java @@ -8,6 +8,7 @@ import com.iab.openrtb.response.Bid; import com.iab.openrtb.response.BidResponse; import com.iab.openrtb.response.SeatBid; +import io.vertx.core.http.HttpMethod; import org.junit.jupiter.api.Test; import org.prebid.server.VertxTest; import org.prebid.server.auction.model.Endpoint; @@ -140,7 +141,7 @@ public void makeHttpRequestsShouldPreserveOriginalExtFields() { public void makeHttpRequestsShouldSetExtWithAmpTrue() { // given final ExtRequestPrebidServer server = ExtRequestPrebidServer.of( - null, null, null, Endpoint.openrtb2_amp.value()); + null, null, null, HttpMethod.POST.name(), Endpoint.openrtb2_amp.value()); final ExtRequestPrebid prebid = ExtRequestPrebid.builder() .server(server) .build(); diff --git a/src/test/java/org/prebid/server/bidder/nextmillennium/NextMillenniumBidderTest.java b/src/test/java/org/prebid/server/bidder/nextmillennium/NextMillenniumBidderTest.java index 84a31090509..5a4821c1dc2 100644 --- a/src/test/java/org/prebid/server/bidder/nextmillennium/NextMillenniumBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/nextmillennium/NextMillenniumBidderTest.java @@ -466,6 +466,7 @@ public void makeHttpRequestsShouldPreserveExtPrebidServer() { "http://localhost:8080", 1, "dc-test", + "POST", "/openrtb2/auction"); final ExtRequest extRequest = ExtRequest.of(ExtRequestPrebid.builder() diff --git a/src/test/java/org/prebid/server/bidder/smaato/SmaatoBidderTest.java b/src/test/java/org/prebid/server/bidder/smaato/SmaatoBidderTest.java index d34fd2812a0..88a3e2b159e 100644 --- a/src/test/java/org/prebid/server/bidder/smaato/SmaatoBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/smaato/SmaatoBidderTest.java @@ -18,6 +18,7 @@ import com.iab.openrtb.response.BidResponse; import com.iab.openrtb.response.SeatBid; import io.vertx.core.MultiMap; +import io.vertx.core.http.HttpMethod; import org.apache.commons.lang3.ObjectUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -941,6 +942,7 @@ private static BidRequest givenVideoBidRequest(UnaryOperator imp private static BidRequest givenVideoBidRequest( UnaryOperator bidRequestCustomizer, UnaryOperator... impCustomizers) { + return bidRequestCustomizer.apply(BidRequest.builder() .site(Site.builder().build()) .app(App.builder().build()) @@ -948,7 +950,12 @@ private static BidRequest givenVideoBidRequest( .map(SmaatoBidderTest::givenVideoImp) .toList())) .ext(ExtRequest.of(ExtRequestPrebid.builder() - .server(ExtRequestPrebidServer.of(null, null, null, Endpoint.openrtb2_video.value())) + .server(ExtRequestPrebidServer.of( + null, + null, + null, + HttpMethod.POST.name(), + Endpoint.openrtb2_video.value())) .build())) .build(); } diff --git a/src/test/java/org/prebid/server/bidder/taboola/TaboolaBidderTest.java b/src/test/java/org/prebid/server/bidder/taboola/TaboolaBidderTest.java index c966a3fbcc1..e484f4ca0d4 100644 --- a/src/test/java/org/prebid/server/bidder/taboola/TaboolaBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/taboola/TaboolaBidderTest.java @@ -606,7 +606,7 @@ private static BidRequest givenBidRequest(UnaryOperator Date: Thu, 23 Jul 2026 18:07:17 +0300 Subject: [PATCH 7/8] Modules: Rename open-source modules and align hook suffixes (#4427) --- extra/bundle/pom.xml | 2 +- .../fiftyone-devicedetection/README.md | 2 +- ...alTimeDataProcessedAuctionRequestHook.java | 2 +- .../README.md | 2 +- ...elIdentityProcessedAuctionRequestHook.java | 2 +- .../README.md | 0 .../pom.xml | 4 +- .../blocking/core/AccountConfigReader.java | 0 .../ortb2/blocking/core/BidsBlocker.java | 0 .../core/BlockedAttributesResolver.java | 0 .../ortb2/blocking/core/RequestUpdater.java | 0 .../ortb2/blocking/core/ResponseUpdater.java | 0 .../InvalidAccountConfigurationException.java | 0 .../blocking/core/model/AnalyticsResult.java | 0 .../model/BidAttributeBlockingConfig.java | 0 .../core/model/BlockedAttributes.java | 0 .../blocking/core/model/BlockedBids.java | 0 .../blocking/core/model/ExecutionResult.java | 0 .../core/model/ResponseBlockingConfig.java | 0 .../ortb2/blocking/core/model/Result.java | 0 .../ortb2/blocking/core/util/MergeUtils.java | 0 .../ortb2/blocking/model/ModuleContext.java | 0 .../Ortb2BlockingModuleConfiguration.java | 0 .../v1/Ortb2BlockingBidderRequestHook.java | 2 +- .../blocking/v1/Ortb2BlockingModule.java | 2 +- .../Ortb2BlockingRawBidderResponseHook.java | 2 +- .../core/AccountConfigReaderTest.java | 0 .../ortb2/blocking/core/BidsBlockerTest.java | 0 .../core/BlockedAttributesResolverTest.java | 0 .../blocking/core/RequestUpdaterTest.java | 0 .../blocking/core/ResponseUpdaterTest.java | 0 .../core/config/AllowedForDealsOverride.java | 0 .../blocking/core/config/ArrayOverride.java | 0 .../ortb2/blocking/core/config/Attribute.java | 0 .../core/config/AttributeActionOverrides.java | 0 .../blocking/core/config/Attributes.java | 0 .../blocking/core/config/BooleanOverride.java | 0 .../blocking/core/config/Conditions.java | 0 .../blocking/core/config/DealsConditions.java | 0 .../blocking/core/config/ModuleConfig.java | 0 .../blocking/model/ModuleContextTest.java | 0 .../Ortb2BlockingBidderRequestHookTest.java | 0 ...rtb2BlockingRawBidderResponseHookTest.java | 0 .../v1/model/BidderInvocationContextImpl.java | 0 ...RequestCorrectionProcessedAuctionHook.java | 2 +- ...orrectionAllProcessedBidResponsesHook.java | 2 +- ...RuleEngineProcessedAuctionRequestHook.java | 2 +- extra/modules/pom.xml | 11 +- .../LiveIntentAnalyticsReporter.java | 2 +- .../model/config/AdminConfig.groovy | 1 - .../model/config/EndpointExecutionPlan.groovy | 1 - .../model/config/ExecutionGroup.groovy | 3 +- .../model/config/ExecutionPlan.groovy | 1 - .../config/ModuleHookImplementation.groovy | 27 -- .../model/{ => config}/ModuleName.groovy | 8 +- .../model/config/PbsModulesConfig.groovy | 4 +- .../model/config/StageExecutionPlan.groovy | 1 - .../model/response/auction/ModuleError.groovy | 2 +- .../model/response/auction/ModuleValue.groovy | 2 +- .../response/auction/ModuleWarning.groovy | 2 +- .../tests/module/AbTestingModuleSpec.groovy | 356 +++++++++--------- .../tests/module/GeneralModuleSpec.groovy | 178 +++++---- .../tests/module/ModuleBaseSpec.groovy | 42 ++- .../AnalyticsTagsModuleSpec.groovy | 28 +- .../optabletargeting/CacheStorageSpec.groovy | 2 +- .../PbOrtb2BlockingSpec.groovy} | 17 +- .../PbResponseCorrectionSpec.groovy} | 4 +- .../PbRichMediaFilterSpec.groovy} | 6 +- ...ec.groovy => PbRuleEngineAliasSpec.groovy} | 4 +- ...pec.groovy => PbRuleEngineBaseSpec.groovy} | 8 +- ....groovy => PbRuleEngineContextSpec.groovy} | 4 +- ...pec.groovy => PbRuleEngineCoreSpec.groovy} | 9 +- ...c.groovy => PbRuleEngineDeviceSpec.groovy} | 5 +- ... => PbRuleEngineInfrastructureSpec.groovy} | 4 +- ....groovy => PbRuleEnginePrivacySpec.groovy} | 4 +- ....groovy => PbRuleEngineSpecialSpec.groovy} | 4 +- ...pec.groovy => PbRuleEngineSyncSpec.groovy} | 4 +- ...oovy => PbRuleEngineValidationSpec.groovy} | 14 +- .../LiveintentAnalyticsReporterTest.java | 4 +- 79 files changed, 378 insertions(+), 410 deletions(-) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/README.md (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/pom.xml (86%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/AccountConfigReader.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BidsBlocker.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BlockedAttributesResolver.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/RequestUpdater.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/ResponseUpdater.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/exception/InvalidAccountConfigurationException.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/AnalyticsResult.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BidAttributeBlockingConfig.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BlockedAttributes.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BlockedBids.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/ExecutionResult.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/ResponseBlockingConfig.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/Result.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/util/MergeUtils.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/model/ModuleContext.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/spring/config/Ortb2BlockingModuleConfiguration.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHook.java (98%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingModule.java (94%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHook.java (98%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/AccountConfigReaderTest.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BidsBlockerTest.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BlockedAttributesResolverTest.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/RequestUpdaterTest.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/ResponseUpdaterTest.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/AllowedForDealsOverride.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/ArrayOverride.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/Attribute.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/AttributeActionOverrides.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/Attributes.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/BooleanOverride.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/Conditions.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/DealsConditions.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/ModuleConfig.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/model/ModuleContextTest.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHookTest.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHookTest.java (100%) rename extra/modules/{ortb2-blocking => pb-ortb2-blocking}/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/model/BidderInvocationContextImpl.java (100%) delete mode 100644 src/test/groovy/org/prebid/server/functional/model/config/ModuleHookImplementation.groovy rename src/test/groovy/org/prebid/server/functional/model/{ => config}/ModuleName.groovy (65%) rename src/test/groovy/org/prebid/server/functional/tests/module/{ortb2blocking/Ortb2BlockingSpec.groovy => pbortb2blocking/PbOrtb2BlockingSpec.groovy} (99%) rename src/test/groovy/org/prebid/server/functional/tests/module/{responsecorrenction/ResponseCorrectionSpec.groovy => pbresponsecorrenction/PbResponseCorrectionSpec.groovy} (99%) rename src/test/groovy/org/prebid/server/functional/tests/module/{richmedia/RichMediaFilterSpec.groovy => pbrichmedia/PbRichMediaFilterSpec.groovy} (99%) rename src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/{RuleEngineAliasSpec.groovy => PbRuleEngineAliasSpec.groovy} (98%) rename src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/{RuleEngineBaseSpec.groovy => PbRuleEngineBaseSpec.groovy} (91%) rename src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/{RuleEngineContextSpec.groovy => PbRuleEngineContextSpec.groovy} (99%) rename src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/{RuleEngineCoreSpec.groovy => PbRuleEngineCoreSpec.groovy} (99%) rename src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/{RuleEngineDeviceSpec.groovy => PbRuleEngineDeviceSpec.groovy} (99%) rename src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/{RuleEngineInfrastructureSpec.groovy => PbRuleEngineInfrastructureSpec.groovy} (98%) rename src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/{RuleEnginePrivacySpec.groovy => PbRuleEnginePrivacySpec.groovy} (99%) rename src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/{RuleEngineSpecialSpec.groovy => PbRuleEngineSpecialSpec.groovy} (98%) rename src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/{RuleEngineSyncSpec.groovy => PbRuleEngineSyncSpec.groovy} (98%) rename src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/{RuleEngineValidationSpec.groovy => PbRuleEngineValidationSpec.groovy} (96%) diff --git a/extra/bundle/pom.xml b/extra/bundle/pom.xml index d49f160f9af..7f125eb231c 100644 --- a/extra/bundle/pom.xml +++ b/extra/bundle/pom.xml @@ -32,7 +32,7 @@ org.prebid.server.hooks.modules - ortb2-blocking + pb-ortb2-blocking ${project.version} diff --git a/extra/modules/fiftyone-devicedetection/README.md b/extra/modules/fiftyone-devicedetection/README.md index fbe254b28c1..cf6d22d1843 100644 --- a/extra/modules/fiftyone-devicedetection/README.md +++ b/extra/modules/fiftyone-devicedetection/README.md @@ -178,4 +178,4 @@ curl http://localhost:8080/openrtb2/auction --data @extra/modules/fiftyone-devic Any suggestions or questions can be directed to [support@51degrees.com](support@51degrees.com) e-mail. -Or just open new [issue](https://github.com/prebid/prebid-server-java/issues/new) or [pull request](https://github.com/prebid/prebid-server-java/pulls) in this repository. \ No newline at end of file +Or just open new [issue](https://github.com/prebid/prebid-server-java/issues/new) or [pull request](https://github.com/prebid/prebid-server-java/pulls) in this repository. diff --git a/extra/modules/greenbids-real-time-data/src/main/java/org/prebid/server/hooks/modules/greenbids/real/time/data/v1/GreenbidsRealTimeDataProcessedAuctionRequestHook.java b/extra/modules/greenbids-real-time-data/src/main/java/org/prebid/server/hooks/modules/greenbids/real/time/data/v1/GreenbidsRealTimeDataProcessedAuctionRequestHook.java index f0bd5467d0e..121c9f6c3a3 100644 --- a/extra/modules/greenbids-real-time-data/src/main/java/org/prebid/server/hooks/modules/greenbids/real/time/data/v1/GreenbidsRealTimeDataProcessedAuctionRequestHook.java +++ b/extra/modules/greenbids-real-time-data/src/main/java/org/prebid/server/hooks/modules/greenbids/real/time/data/v1/GreenbidsRealTimeDataProcessedAuctionRequestHook.java @@ -53,7 +53,7 @@ public class GreenbidsRealTimeDataProcessedAuctionRequestHook implements ProcessedAuctionRequestHook { private static final String BID_REQUEST_ANALYTICS_EXTENSION_NAME = "greenbids-rtd"; - private static final String CODE = "greenbids-real-time-data-processed-auction-request"; + private static final String CODE = "greenbids-real-time-data-processed-auction-request-hook"; private static final String ACTIVITY = "greenbids-filter"; private static final String SUCCESS_STATUS = "success"; diff --git a/extra/modules/live-intent-omni-channel-identity/README.md b/extra/modules/live-intent-omni-channel-identity/README.md index a8a3ce5b113..04594d0816d 100644 --- a/extra/modules/live-intent-omni-channel-identity/README.md +++ b/extra/modules/live-intent-omni-channel-identity/README.md @@ -29,7 +29,7 @@ hooks: "hook-sequence": [ { "module-code": "liveintent-omni-channel-identity", - "hook-impl-code": "liveintent-omni-channel-identity-enrichment-hook" + "hook-impl-code": "liveintent-omni-channel-identity-processed-auction-request-hook" } ] } diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java index 67c843ca882..13e7d48bea8 100644 --- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java +++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java @@ -55,7 +55,7 @@ public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHook implements private static final ConditionalLogger conditionalLogger = new ConditionalLogger(LoggerFactory.getLogger( LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.class)); - private static final String CODE = "liveintent-omni-channel-identity-enrichment-hook"; + private static final String CODE = "liveintent-omni-channel-identity-processed-auction-request-hook"; private static final String INSERTER = "s2s.liveintent.com"; diff --git a/extra/modules/ortb2-blocking/README.md b/extra/modules/pb-ortb2-blocking/README.md similarity index 100% rename from extra/modules/ortb2-blocking/README.md rename to extra/modules/pb-ortb2-blocking/README.md diff --git a/extra/modules/ortb2-blocking/pom.xml b/extra/modules/pb-ortb2-blocking/pom.xml similarity index 86% rename from extra/modules/ortb2-blocking/pom.xml rename to extra/modules/pb-ortb2-blocking/pom.xml index 1d3c7056f57..efd600c964e 100644 --- a/extra/modules/ortb2-blocking/pom.xml +++ b/extra/modules/pb-ortb2-blocking/pom.xml @@ -8,8 +8,8 @@ 3.44.0-SNAPSHOT - ortb2-blocking + pb-ortb2-blocking - ortb2-blocking + pb-ortb2-blocking OpenRTB2 Blocking module diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/AccountConfigReader.java b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/AccountConfigReader.java similarity index 100% rename from extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/AccountConfigReader.java rename to extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/AccountConfigReader.java diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BidsBlocker.java b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BidsBlocker.java similarity index 100% rename from extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BidsBlocker.java rename to extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BidsBlocker.java diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BlockedAttributesResolver.java b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BlockedAttributesResolver.java similarity index 100% rename from extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BlockedAttributesResolver.java rename to extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BlockedAttributesResolver.java diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/RequestUpdater.java b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/RequestUpdater.java similarity index 100% rename from extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/RequestUpdater.java rename to extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/RequestUpdater.java diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/ResponseUpdater.java b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/ResponseUpdater.java similarity index 100% rename from extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/ResponseUpdater.java rename to extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/ResponseUpdater.java diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/exception/InvalidAccountConfigurationException.java b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/exception/InvalidAccountConfigurationException.java similarity index 100% rename from extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/exception/InvalidAccountConfigurationException.java rename to extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/exception/InvalidAccountConfigurationException.java diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/AnalyticsResult.java b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/AnalyticsResult.java similarity index 100% rename from extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/AnalyticsResult.java rename to extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/AnalyticsResult.java diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BidAttributeBlockingConfig.java b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BidAttributeBlockingConfig.java similarity index 100% rename from extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BidAttributeBlockingConfig.java rename to extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BidAttributeBlockingConfig.java diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BlockedAttributes.java b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BlockedAttributes.java similarity index 100% rename from extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BlockedAttributes.java rename to extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BlockedAttributes.java diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BlockedBids.java b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BlockedBids.java similarity index 100% rename from extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BlockedBids.java rename to extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BlockedBids.java diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/ExecutionResult.java b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/ExecutionResult.java similarity index 100% rename from extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/ExecutionResult.java rename to extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/ExecutionResult.java diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/ResponseBlockingConfig.java b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/ResponseBlockingConfig.java similarity index 100% rename from extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/ResponseBlockingConfig.java rename to extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/ResponseBlockingConfig.java diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/Result.java b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/Result.java similarity index 100% rename from extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/Result.java rename to extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/Result.java diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/util/MergeUtils.java b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/util/MergeUtils.java similarity index 100% rename from extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/util/MergeUtils.java rename to extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/util/MergeUtils.java diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/model/ModuleContext.java b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/model/ModuleContext.java similarity index 100% rename from extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/model/ModuleContext.java rename to extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/model/ModuleContext.java diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/spring/config/Ortb2BlockingModuleConfiguration.java b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/spring/config/Ortb2BlockingModuleConfiguration.java similarity index 100% rename from extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/spring/config/Ortb2BlockingModuleConfiguration.java rename to extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/spring/config/Ortb2BlockingModuleConfiguration.java diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHook.java b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHook.java similarity index 98% rename from extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHook.java rename to extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHook.java index e13deb60d3d..ca2dfb9fabb 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHook.java +++ b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHook.java @@ -26,7 +26,7 @@ public class Ortb2BlockingBidderRequestHook implements BidderRequestHook { - private static final String CODE = "ortb2-blocking-bidder-request"; + private static final String CODE = "pb-ortb2-blocking-bidder-request-hook"; private final BidderCatalog bidderCatalog; diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingModule.java b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingModule.java similarity index 94% rename from extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingModule.java rename to extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingModule.java index 747728c0d40..aa432e263ac 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingModule.java +++ b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingModule.java @@ -12,7 +12,7 @@ public class Ortb2BlockingModule implements Module { - public static final String CODE = "ortb2-blocking"; + public static final String CODE = "pb-ortb2-blocking"; private final List> hooks; diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHook.java b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHook.java similarity index 98% rename from extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHook.java rename to extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHook.java index 94271ff7ca5..015c653250d 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHook.java +++ b/extra/modules/pb-ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHook.java @@ -34,7 +34,7 @@ public class Ortb2BlockingRawBidderResponseHook implements RawBidderResponseHook { - private static final String CODE = "ortb2-blocking-raw-bidder-response"; + private static final String CODE = "pb-ortb2-blocking-raw-bidder-response-hook"; private static final String ENFORCE_BLOCKING_ACTIVITY = "enforce-blocking"; private static final String SUCCESS_STATUS = "success"; diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/AccountConfigReaderTest.java b/extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/AccountConfigReaderTest.java similarity index 100% rename from extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/AccountConfigReaderTest.java rename to extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/AccountConfigReaderTest.java diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BidsBlockerTest.java b/extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BidsBlockerTest.java similarity index 100% rename from extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BidsBlockerTest.java rename to extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BidsBlockerTest.java diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BlockedAttributesResolverTest.java b/extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BlockedAttributesResolverTest.java similarity index 100% rename from extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BlockedAttributesResolverTest.java rename to extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BlockedAttributesResolverTest.java diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/RequestUpdaterTest.java b/extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/RequestUpdaterTest.java similarity index 100% rename from extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/RequestUpdaterTest.java rename to extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/RequestUpdaterTest.java diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/ResponseUpdaterTest.java b/extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/ResponseUpdaterTest.java similarity index 100% rename from extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/ResponseUpdaterTest.java rename to extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/ResponseUpdaterTest.java diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/AllowedForDealsOverride.java b/extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/AllowedForDealsOverride.java similarity index 100% rename from extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/AllowedForDealsOverride.java rename to extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/AllowedForDealsOverride.java diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/ArrayOverride.java b/extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/ArrayOverride.java similarity index 100% rename from extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/ArrayOverride.java rename to extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/ArrayOverride.java diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/Attribute.java b/extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/Attribute.java similarity index 100% rename from extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/Attribute.java rename to extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/Attribute.java diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/AttributeActionOverrides.java b/extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/AttributeActionOverrides.java similarity index 100% rename from extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/AttributeActionOverrides.java rename to extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/AttributeActionOverrides.java diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/Attributes.java b/extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/Attributes.java similarity index 100% rename from extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/Attributes.java rename to extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/Attributes.java diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/BooleanOverride.java b/extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/BooleanOverride.java similarity index 100% rename from extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/BooleanOverride.java rename to extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/BooleanOverride.java diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/Conditions.java b/extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/Conditions.java similarity index 100% rename from extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/Conditions.java rename to extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/Conditions.java diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/DealsConditions.java b/extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/DealsConditions.java similarity index 100% rename from extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/DealsConditions.java rename to extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/DealsConditions.java diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/ModuleConfig.java b/extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/ModuleConfig.java similarity index 100% rename from extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/ModuleConfig.java rename to extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/core/config/ModuleConfig.java diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/model/ModuleContextTest.java b/extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/model/ModuleContextTest.java similarity index 100% rename from extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/model/ModuleContextTest.java rename to extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/model/ModuleContextTest.java diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHookTest.java b/extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHookTest.java similarity index 100% rename from extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHookTest.java rename to extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHookTest.java diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHookTest.java b/extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHookTest.java similarity index 100% rename from extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHookTest.java rename to extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHookTest.java diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/model/BidderInvocationContextImpl.java b/extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/model/BidderInvocationContextImpl.java similarity index 100% rename from extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/model/BidderInvocationContextImpl.java rename to extra/modules/pb-ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/model/BidderInvocationContextImpl.java diff --git a/extra/modules/pb-request-correction/src/main/java/org/prebid/server/hooks/modules/pb/request/correction/v1/RequestCorrectionProcessedAuctionHook.java b/extra/modules/pb-request-correction/src/main/java/org/prebid/server/hooks/modules/pb/request/correction/v1/RequestCorrectionProcessedAuctionHook.java index 215e9795110..13e28483778 100644 --- a/extra/modules/pb-request-correction/src/main/java/org/prebid/server/hooks/modules/pb/request/correction/v1/RequestCorrectionProcessedAuctionHook.java +++ b/extra/modules/pb-request-correction/src/main/java/org/prebid/server/hooks/modules/pb/request/correction/v1/RequestCorrectionProcessedAuctionHook.java @@ -23,7 +23,7 @@ public class RequestCorrectionProcessedAuctionHook implements ProcessedAuctionRequestHook { - private static final String CODE = "pb-request-correction-processed-auction-request"; + private static final String CODE = "pb-request-correction-processed-auction-request-hook"; private final RequestCorrectionProvider requestCorrectionProvider; private final ObjectMapper mapper; diff --git a/extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/ResponseCorrectionAllProcessedBidResponsesHook.java b/extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/ResponseCorrectionAllProcessedBidResponsesHook.java index 11c740e9771..40dc1c0a3d0 100644 --- a/extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/ResponseCorrectionAllProcessedBidResponsesHook.java +++ b/extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/ResponseCorrectionAllProcessedBidResponsesHook.java @@ -24,7 +24,7 @@ public class ResponseCorrectionAllProcessedBidResponsesHook implements AllProcessedBidResponsesHook { - private static final String CODE = "pb-response-correction-all-processed-bid-responses"; + private static final String CODE = "pb-response-correction-all-processed-bid-responses-hook"; private final ResponseCorrectionProvider responseCorrectionProvider; private final ObjectMapper mapper; diff --git a/extra/modules/pb-rule-engine/src/main/java/org/prebid/server/hooks/modules/rule/engine/v1/PbRuleEngineProcessedAuctionRequestHook.java b/extra/modules/pb-rule-engine/src/main/java/org/prebid/server/hooks/modules/rule/engine/v1/PbRuleEngineProcessedAuctionRequestHook.java index 2f20d25ffa6..8d405568266 100644 --- a/extra/modules/pb-rule-engine/src/main/java/org/prebid/server/hooks/modules/rule/engine/v1/PbRuleEngineProcessedAuctionRequestHook.java +++ b/extra/modules/pb-rule-engine/src/main/java/org/prebid/server/hooks/modules/rule/engine/v1/PbRuleEngineProcessedAuctionRequestHook.java @@ -30,7 +30,7 @@ public class PbRuleEngineProcessedAuctionRequestHook implements ProcessedAuctionRequestHook { - private static final String CODE = "pb-rule-engine-processed-auction-request"; + private static final String CODE = "pb-rule-engine-processed-auction-request-hook"; private final RuleParser ruleParser; private final String datacenter; diff --git a/extra/modules/pom.xml b/extra/modules/pom.xml index fe2b772d668..77cad1828ff 100644 --- a/extra/modules/pom.xml +++ b/extra/modules/pom.xml @@ -17,17 +17,18 @@ Umbrellas all PBS modules - ortb2-blocking - confiant-ad-quality + pb-ortb2-blocking pb-richmedia-filter - fiftyone-devicedetection pb-response-correction - greenbids-real-time-data pb-request-correction + pb-rule-engine + + confiant-ad-quality + fiftyone-devicedetection + greenbids-real-time-data optable-targeting wurfl-devicedetection live-intent-omni-channel-identity - pb-rule-engine diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java index cc6ab99d3d5..a8fe3bc22a5 100644 --- a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java +++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java @@ -34,7 +34,7 @@ public class LiveIntentAnalyticsReporter implements AnalyticsReporter { - private static final String LIVEINTENT_HOOK_ID = "liveintent-omni-channel-identity-enrichment-hook"; + private static final String LIVEINTENT_HOOK_ID = "liveintent-omni-channel-identity-processed-auction-request-hook"; private final HttpClient httpClient; private final LiveIntentAnalyticsProperties properties; diff --git a/src/test/groovy/org/prebid/server/functional/model/config/AdminConfig.groovy b/src/test/groovy/org/prebid/server/functional/model/config/AdminConfig.groovy index 755a47bcbaa..6b0b82f6015 100644 --- a/src/test/groovy/org/prebid/server/functional/model/config/AdminConfig.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/config/AdminConfig.groovy @@ -3,7 +3,6 @@ package org.prebid.server.functional.model.config import com.fasterxml.jackson.databind.PropertyNamingStrategies import com.fasterxml.jackson.databind.annotation.JsonNaming import groovy.transform.ToString -import org.prebid.server.functional.model.ModuleName @ToString(includeNames = true, ignoreNulls = true) @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy) diff --git a/src/test/groovy/org/prebid/server/functional/model/config/EndpointExecutionPlan.groovy b/src/test/groovy/org/prebid/server/functional/model/config/EndpointExecutionPlan.groovy index 9ded40849d0..918a6bc8c91 100644 --- a/src/test/groovy/org/prebid/server/functional/model/config/EndpointExecutionPlan.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/config/EndpointExecutionPlan.groovy @@ -1,7 +1,6 @@ package org.prebid.server.functional.model.config import groovy.transform.ToString -import org.prebid.server.functional.model.ModuleName @ToString(includeNames = true, ignoreNulls = true) class EndpointExecutionPlan { diff --git a/src/test/groovy/org/prebid/server/functional/model/config/ExecutionGroup.groovy b/src/test/groovy/org/prebid/server/functional/model/config/ExecutionGroup.groovy index eb32b75e729..496f0c3ed52 100644 --- a/src/test/groovy/org/prebid/server/functional/model/config/ExecutionGroup.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/config/ExecutionGroup.groovy @@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.databind.PropertyNamingStrategies import com.fasterxml.jackson.databind.annotation.JsonNaming import groovy.transform.ToString -import org.prebid.server.functional.model.ModuleName @ToString(includeNames = true, ignoreNulls = true) @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy) @@ -19,7 +18,7 @@ class ExecutionGroup { static ExecutionGroup getModuleExecutionGroup(ModuleName name, Stage stage) { new ExecutionGroup().tap { timeout = 1000 - hookSequence = [new HookId(moduleCode: name.code, hookImplCode: ModuleHookImplementation.forValue(name, stage).code)] + hookSequence = [new HookId(moduleCode: name.code, hookImplCode: "${name.code}-$stage-hook")] } } } diff --git a/src/test/groovy/org/prebid/server/functional/model/config/ExecutionPlan.groovy b/src/test/groovy/org/prebid/server/functional/model/config/ExecutionPlan.groovy index 653f8c8cbea..81e103d68f3 100644 --- a/src/test/groovy/org/prebid/server/functional/model/config/ExecutionPlan.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/config/ExecutionPlan.groovy @@ -3,7 +3,6 @@ package org.prebid.server.functional.model.config import com.fasterxml.jackson.databind.PropertyNamingStrategies import com.fasterxml.jackson.databind.annotation.JsonNaming import groovy.transform.ToString -import org.prebid.server.functional.model.ModuleName @ToString(includeNames = true, ignoreNulls = true) @JsonNaming(PropertyNamingStrategies.LowerCaseStrategy) diff --git a/src/test/groovy/org/prebid/server/functional/model/config/ModuleHookImplementation.groovy b/src/test/groovy/org/prebid/server/functional/model/config/ModuleHookImplementation.groovy deleted file mode 100644 index af7bf670c95..00000000000 --- a/src/test/groovy/org/prebid/server/functional/model/config/ModuleHookImplementation.groovy +++ /dev/null @@ -1,27 +0,0 @@ -package org.prebid.server.functional.model.config - -import com.fasterxml.jackson.annotation.JsonValue -import org.prebid.server.functional.model.ModuleName - -//TODO remove if module hooks implementation codes will become consistent -enum ModuleHookImplementation { - - PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES("pb-richmedia-filter-all-processed-bid-responses-hook"), - RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES("pb-response-correction-all-processed-bid-responses"), - ORTB2_BLOCKING_BIDDER_REQUEST("ortb2-blocking-bidder-request"), - ORTB2_BLOCKING_RAW_BIDDER_RESPONSE("ortb2-blocking-raw-bidder-response"), - PB_REQUEST_CORRECTION_PROCESSED_AUCTION_REQUEST("pb-request-correction-processed-auction-request"), - OPTABLE_TARGETING_PROCESSED_AUCTION_REQUEST("optable-targeting-processed-auction-request-hook"), - PB_RULES_ENGINE_PROCESSED_AUCTION_REQUEST("pb-rule-engine-processed-auction-request") - - @JsonValue - final String code - - ModuleHookImplementation(String code) { - this.code = code - } - - static ModuleHookImplementation forValue(ModuleName name, Stage stage) { - values().find { it.code.contains(name.code) && it.code.contains(stage.value) } - } -} diff --git a/src/test/groovy/org/prebid/server/functional/model/ModuleName.groovy b/src/test/groovy/org/prebid/server/functional/model/config/ModuleName.groovy similarity index 65% rename from src/test/groovy/org/prebid/server/functional/model/ModuleName.groovy rename to src/test/groovy/org/prebid/server/functional/model/config/ModuleName.groovy index 19a29ae0058..cc4f9710d03 100644 --- a/src/test/groovy/org/prebid/server/functional/model/ModuleName.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/config/ModuleName.groovy @@ -1,4 +1,4 @@ -package org.prebid.server.functional.model +package org.prebid.server.functional.model.config import com.fasterxml.jackson.annotation.JsonValue @@ -6,10 +6,10 @@ enum ModuleName { PB_RICHMEDIA_FILTER("pb-richmedia-filter"), PB_RESPONSE_CORRECTION ("pb-response-correction"), - ORTB2_BLOCKING("ortb2-blocking"), + PB_ORTB2_BLOCKING("pb-ortb2-blocking"), PB_REQUEST_CORRECTION('pb-request-correction'), - OPTABLE_TARGETING('optable-targeting'), - PB_RULE_ENGINE('pb-rule-engine') + PB_RULE_ENGINE('pb-rule-engine'), + OPTABLE_TARGETING('optable-targeting') @JsonValue final String code diff --git a/src/test/groovy/org/prebid/server/functional/model/config/PbsModulesConfig.groovy b/src/test/groovy/org/prebid/server/functional/model/config/PbsModulesConfig.groovy index ac2685742b6..0c42cc36950 100644 --- a/src/test/groovy/org/prebid/server/functional/model/config/PbsModulesConfig.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/config/PbsModulesConfig.groovy @@ -10,9 +10,9 @@ import org.prebid.server.functional.model.request.auction.RichmediaFilter class PbsModulesConfig { RichmediaFilter pbRichmediaFilter - Ortb2BlockingConfig ortb2Blocking + Ortb2BlockingConfig pbOrtb2Blocking PbResponseCorrection pbResponseCorrection PbRequestCorrectionConfig pbRequestCorrection - OptableTargetingConfig optableTargeting PbRulesEngine pbRuleEngine + OptableTargetingConfig optableTargeting } diff --git a/src/test/groovy/org/prebid/server/functional/model/config/StageExecutionPlan.groovy b/src/test/groovy/org/prebid/server/functional/model/config/StageExecutionPlan.groovy index b2fab91c200..84124956bbf 100644 --- a/src/test/groovy/org/prebid/server/functional/model/config/StageExecutionPlan.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/config/StageExecutionPlan.groovy @@ -1,7 +1,6 @@ package org.prebid.server.functional.model.config import groovy.transform.ToString -import org.prebid.server.functional.model.ModuleName @ToString(includeNames = true, ignoreNulls = true) class StageExecutionPlan { diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/ModuleError.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/ModuleError.groovy index 138b5e40507..b722d2988ac 100644 --- a/src/test/groovy/org/prebid/server/functional/model/response/auction/ModuleError.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/ModuleError.groovy @@ -8,5 +8,5 @@ import groovy.transform.ToString @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy) class ModuleError { - Map> ortb2Blocking + Map> pbOrtb2Blocking } diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/ModuleValue.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/ModuleValue.groovy index c780efaa422..d0368344098 100644 --- a/src/test/groovy/org/prebid/server/functional/model/response/auction/ModuleValue.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/ModuleValue.groovy @@ -3,7 +3,7 @@ package org.prebid.server.functional.model.response.auction import com.fasterxml.jackson.annotation.JsonProperty import groovy.transform.EqualsAndHashCode import groovy.transform.ToString -import org.prebid.server.functional.model.ModuleName +import org.prebid.server.functional.model.config.ModuleName import org.prebid.server.functional.model.bidder.BidderName @ToString(includeNames = true, ignoreNulls = true) diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/ModuleWarning.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/ModuleWarning.groovy index 5c6d4ebed44..18931b0c053 100644 --- a/src/test/groovy/org/prebid/server/functional/model/response/auction/ModuleWarning.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/ModuleWarning.groovy @@ -8,5 +8,5 @@ import groovy.transform.ToString @JsonNaming(PropertyNamingStrategies.KebabCaseStrategy) class ModuleWarning { - Map> ortb2Blocking + Map> pbOrtb2Blocking } diff --git a/src/test/groovy/org/prebid/server/functional/tests/module/AbTestingModuleSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/module/AbTestingModuleSpec.groovy index 1582f3b200d..041e41d4e26 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/module/AbTestingModuleSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/module/AbTestingModuleSpec.groovy @@ -1,6 +1,6 @@ package org.prebid.server.functional.tests.module -import org.prebid.server.functional.model.ModuleName +import org.prebid.server.functional.model.config.ModuleName import org.prebid.server.functional.model.config.AbTest import org.prebid.server.functional.model.config.AccountConfig import org.prebid.server.functional.model.config.AccountHooksConfiguration @@ -15,11 +15,8 @@ import org.prebid.server.functional.model.response.auction.InvocationResult import org.prebid.server.functional.service.PrebidServerService import org.prebid.server.functional.util.PBSUtils -import static org.prebid.server.functional.model.ModuleName.PB_RESPONSE_CORRECTION +import static org.prebid.server.functional.model.config.ModuleName.PB_RESPONSE_CORRECTION import static org.prebid.server.functional.model.config.Endpoint.OPENRTB2_AUCTION -import static org.prebid.server.functional.model.config.ModuleHookImplementation.ORTB2_BLOCKING_BIDDER_REQUEST -import static org.prebid.server.functional.model.config.ModuleHookImplementation.ORTB2_BLOCKING_RAW_BIDDER_RESPONSE -import static org.prebid.server.functional.model.config.ModuleHookImplementation.RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES import static org.prebid.server.functional.model.config.Stage.ALL_PROCESSED_BID_RESPONSES import static org.prebid.server.functional.model.config.Stage.BIDDER_REQUEST import static org.prebid.server.functional.model.config.Stage.RAW_BIDDER_RESPONSE @@ -33,15 +30,12 @@ import static org.prebid.server.functional.model.response.auction.ResponseAction class AbTestingModuleSpec extends ModuleBaseSpec { - private final static String NO_INVOCATION_METRIC = "modules.module.%s.stage.%s.hook.%s.success.no-invocation" - private final static String CALL_METRIC = "modules.module.%s.stage.%s.hook.%s.call" - private final static String EXECUTION_ERROR_METRIC = "modules.module.%s.stage.%s.hook.%s.execution-error" private final static Integer MIN_PERCENT_AB = 0 private final static Integer MAX_PERCENT_AB = 100 private final static String INVALID_HOOK_MESSAGE = "Hook implementation does not exist or disabled" - private final static Map> ORTB_STAGES = [(BIDDER_REQUEST) : [ModuleName.ORTB2_BLOCKING], - (RAW_BIDDER_RESPONSE): [ModuleName.ORTB2_BLOCKING]] + private final static Map> ORTB_STAGES = [(BIDDER_REQUEST) : [ModuleName.PB_ORTB2_BLOCKING], + (RAW_BIDDER_RESPONSE): [ModuleName.PB_ORTB2_BLOCKING]] private final static Map> RESPONSE_STAGES = [(ALL_PROCESSED_BID_RESPONSES): [PB_RESPONSE_CORRECTION]] private final static Map> MODULES_STAGES = ORTB_STAGES + RESPONSE_STAGES @@ -64,7 +58,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { flushMetrics(ortbModulePbsService) and: "Save account with ab test config" - def abTest = AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code).tap { + def abTest = AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code).tap { enabled = false } def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB_STAGES).tap { @@ -89,13 +83,13 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Metric for specified module should be as default call" def metrics = ortbModulePbsService.sendCollectedMetricsRequest() - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 - assert !metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] - assert !metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] + assert !metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] + assert !metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] } def "PBS shouldn't apply valid a/b test config when module is disabled"() { @@ -111,7 +105,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Save account with ab test config" def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB_STAGES).tap { - abTests = [AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code)] + abTests = [AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code)] } def accountConfig = new AccountConfig(hooks: new AccountHooksConfiguration(executionPlan: executionPlan)) def account = new Account(uuid: bidRequest.getAccountId(), config: accountConfig) @@ -131,15 +125,15 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Metric for specified module should be with error call" def metrics = prebidServerService.sendCollectedMetricsRequest() - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - assert metrics[EXECUTION_ERROR_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[EXECUTION_ERROR_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 + assert metrics[EXECUTION_ERROR_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[EXECUTION_ERROR_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 - assert !metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] - assert !metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] + assert !metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] + assert !metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] cleanup: "Stop and remove pbs container" pbsServiceFactory.removeContainer(pbsConfig) @@ -175,16 +169,16 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Metric for specified module should be as default call" def metrics = ortbModulePbsService.sendCollectedMetricsRequest() - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 - assert !metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] - assert !metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] + assert !metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] + assert !metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] where: - moduleName << [ModuleName.ORTB2_BLOCKING.code.toUpperCase(), PBSUtils.randomString] + moduleName << [ModuleName.PB_ORTB2_BLOCKING.code.toUpperCase(), PBSUtils.randomString] } def "PBS should apply a/b test config for each module when multiple config are presents and set to allow modules"() { @@ -195,7 +189,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { flushMetrics(pbsServiceWithMultipleModules) and: "Save account with ab test config" - def ortb2AbTestConfig = AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code).tap { + def ortb2AbTestConfig = AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code).tap { it.percentActive = MAX_PERCENT_AB } def richMediaAbTestConfig = AbTest.getDefault(PB_RESPONSE_CORRECTION.code).tap { @@ -213,14 +207,14 @@ class AbTestingModuleSpec extends ModuleBaseSpec { then: "PBS should apply ab test config for specified module" def invocationResults = response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List - def ortbBlockingInvocationResults = filterInvocationResultsByModule(invocationResults, ModuleName.ORTB2_BLOCKING) + def ortbBlockingInvocationResults = filterInvocationResultsByModule(invocationResults, ModuleName.PB_ORTB2_BLOCKING) verifyAll(ortbBlockingInvocationResults) { it.status == [SUCCESS, SUCCESS] it.action == [NO_ACTION, NO_ACTION] it.analyticsTags.activities.name.flatten().sort() == [ORTB2_BLOCKING, AB_TESTING, AB_TESTING].value.sort() it.analyticsTags.activities.status.flatten().sort() == [FetchStatus.SUCCESS, FetchStatus.SUCCESS, FetchStatus.SUCCESS].sort() it.analyticsTags.activities.results.status.flatten().sort() == [FetchStatus.SUCCESS_ALLOW, FetchStatus.RUN, FetchStatus.RUN].sort() - it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.ORTB2_BLOCKING, ModuleName.ORTB2_BLOCKING] + it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.PB_ORTB2_BLOCKING, ModuleName.PB_ORTB2_BLOCKING] } and: "PBS should not apply ab test config for other module" @@ -234,18 +228,18 @@ class AbTestingModuleSpec extends ModuleBaseSpec { it.analyticsTags.activities.results.values.module.flatten() == [PB_RESPONSE_CORRECTION] } - and: "Metric for allowed to run ortb2blocking module should be updated based on ab test config" + and: "Metric for allowed to run pb-ortb2blocking module should be updated based on ab test config" def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] - - and: "Metric for allowed to run response-correction module should be updated based on ab test config" - assert metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 - assert metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 + assert !metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] + assert !metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] + + and: "Metric for allowed to run pb-response-correction module should be updated based on ab test config" + assert metrics[CALL_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 + assert metrics[CALL_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 + assert !metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] + assert !metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] } def "PBS should apply a/b test config for each module when multiple config are presents and set to skip modules"() { @@ -256,7 +250,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { flushMetrics(pbsServiceWithMultipleModules) and: "Save account with ab test config" - def ortb2AbTestConfig = AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code).tap { + def ortb2AbTestConfig = AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code).tap { it.percentActive = MIN_PERCENT_AB } def richMediaAbTestConfig = AbTest.getDefault(PB_RESPONSE_CORRECTION.code).tap { @@ -274,17 +268,17 @@ class AbTestingModuleSpec extends ModuleBaseSpec { then: "PBS should apply ab test config for ortb2blocking module" def invocationResults = response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List - def ortbBlockingInvocationResults = filterInvocationResultsByModule(invocationResults, ModuleName.ORTB2_BLOCKING) + def ortbBlockingInvocationResults = filterInvocationResultsByModule(invocationResults, ModuleName.PB_ORTB2_BLOCKING) verifyAll(ortbBlockingInvocationResults) { it.status == [SUCCESS, SUCCESS] it.action == [NO_INVOCATION, NO_INVOCATION] it.analyticsTags.activities.name.flatten() == [AB_TESTING, AB_TESTING].value it.analyticsTags.activities.status.flatten() == [FetchStatus.SUCCESS, FetchStatus.SUCCESS] it.analyticsTags.activities.results.status.flatten() == [FetchStatus.SKIPPED, FetchStatus.SKIPPED] - it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.ORTB2_BLOCKING, ModuleName.ORTB2_BLOCKING] + it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.PB_ORTB2_BLOCKING, ModuleName.PB_ORTB2_BLOCKING] } - and: "PBS should apply ab test config for response-correction module" + and: "PBS should apply ab test config for pb-response-correction module" def responseCorrectionInvocationResults = filterInvocationResultsByModule(invocationResults, PB_RESPONSE_CORRECTION) verifyAll(responseCorrectionInvocationResults) { it.status == [SUCCESS] @@ -295,18 +289,18 @@ class AbTestingModuleSpec extends ModuleBaseSpec { it.analyticsTags.activities.results.values.module.flatten() == [PB_RESPONSE_CORRECTION] } - and: "Metric for skipped ortb2blocking module should be updated based on ab test config" + and: "Metric for skipped pb-ortb2blocking module should be updated based on ab test config" def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() - assert !metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] - assert !metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] - assert metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 - assert metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 - - and: "Metric for skipped response-correction module should be updated based on ab test config" - assert !metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] - assert !metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] - assert metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 - assert metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 + assert !metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] + assert !metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] + assert metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 + assert metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 + + and: "Metric for skipped pb-response-correction module should be updated based on ab test config" + assert !metrics[CALL_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] + assert !metrics[CALL_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] + assert metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 + assert metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 } def "PBS should apply a/b test config for each module when multiple config are presents with different percentage"() { @@ -317,7 +311,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { flushMetrics(pbsServiceWithMultipleModules) and: "Save account with ab test config" - def ortb2AbTestConfig = AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code).tap { + def ortb2AbTestConfig = AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code).tap { it.percentActive = MIN_PERCENT_AB } def richMediaAbTestConfig = AbTest.getDefault(PB_RESPONSE_CORRECTION.code).tap { @@ -335,17 +329,17 @@ class AbTestingModuleSpec extends ModuleBaseSpec { then: "PBS should apply ab test config for ortb2blocking module" def invocationResults = response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List - def ortbBlockingInvocationResults = filterInvocationResultsByModule(invocationResults, ModuleName.ORTB2_BLOCKING) + def ortbBlockingInvocationResults = filterInvocationResultsByModule(invocationResults, ModuleName.PB_ORTB2_BLOCKING) verifyAll(ortbBlockingInvocationResults) { it.status == [SUCCESS, SUCCESS] it.action == [NO_INVOCATION, NO_INVOCATION] it.analyticsTags.activities.name.flatten() == [AB_TESTING, AB_TESTING].value it.analyticsTags.activities.status.flatten() == [FetchStatus.SUCCESS, FetchStatus.SUCCESS] it.analyticsTags.activities.results.status.flatten() == [FetchStatus.SKIPPED, FetchStatus.SKIPPED] - it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.ORTB2_BLOCKING, ModuleName.ORTB2_BLOCKING] + it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.PB_ORTB2_BLOCKING, ModuleName.PB_ORTB2_BLOCKING] } - and: "PBS should not apply ab test config for response-correction module" + and: "PBS should not apply ab test config for pb-response-correction module" def responseCorrectionInvocationResults = filterInvocationResultsByModule(invocationResults, PB_RESPONSE_CORRECTION) verifyAll(responseCorrectionInvocationResults) { it.status == [SUCCESS] @@ -358,14 +352,14 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Metric for skipped ortb2blocking module should be updated based on ab test config" def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - - and: "Metric for allowed to run response-correction module should be updated based on ab test config" - assert metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 - assert metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 + + and: "Metric for allowed to run pb-response-correction module should be updated based on ab test config" + assert metrics[CALL_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 + assert metrics[CALL_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 + assert !metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] + assert !metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] } def "PBS should ignore accounts property for a/b test config when ab test config specialize for specific account"() { @@ -377,7 +371,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Save account with ab test config" def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB_STAGES).tap { - abTests = [AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code, [PBSUtils.randomNumber]).tap { + abTests = [AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code, [PBSUtils.randomNumber]).tap { percentActive = MIN_PERCENT_AB }] } @@ -396,13 +390,13 @@ class AbTestingModuleSpec extends ModuleBaseSpec { it.analyticsTags.activities.name.flatten() == [AB_TESTING, AB_TESTING].value it.analyticsTags.activities.status.flatten() == [FetchStatus.SUCCESS, FetchStatus.SUCCESS] it.analyticsTags.activities.results.status.flatten() == [FetchStatus.SKIPPED, FetchStatus.SKIPPED] - it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.ORTB2_BLOCKING, ModuleName.ORTB2_BLOCKING] + it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.PB_ORTB2_BLOCKING, ModuleName.PB_ORTB2_BLOCKING] } and: "Metric for specified module should be updated based on ab test config" def metrics = ortbModulePbsService.sendCollectedMetricsRequest() - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 } def "PBS should apply a/b test config and run module when config is on max percentage or default value"() { @@ -414,7 +408,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Save account with ab test config" def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB_STAGES).tap { - abTests = [AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code).tap { + abTests = [AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code).tap { it.percentActive = percentActive it.percentActiveSnakeCase = percentActiveSnakeCase }] @@ -434,18 +428,18 @@ class AbTestingModuleSpec extends ModuleBaseSpec { it.analyticsTags.activities.name.flatten().sort() == [ORTB2_BLOCKING, AB_TESTING, AB_TESTING].value.sort() it.analyticsTags.activities.status.flatten().sort() == [FetchStatus.SUCCESS, FetchStatus.SUCCESS, FetchStatus.SUCCESS].sort() it.analyticsTags.activities.results.status.flatten().sort() == [FetchStatus.SUCCESS_ALLOW, FetchStatus.RUN, FetchStatus.RUN].sort() - it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.ORTB2_BLOCKING, ModuleName.ORTB2_BLOCKING] + it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.PB_ORTB2_BLOCKING, ModuleName.PB_ORTB2_BLOCKING] } and: "Metric for specified module should be as default call" def metrics = ortbModulePbsService.sendCollectedMetricsRequest() - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 - assert !metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] - assert !metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] + assert !metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] + assert !metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] where: percentActive | percentActiveSnakeCase @@ -463,7 +457,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Save account with ab test config" def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB_STAGES).tap { - abTests = [AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code).tap { + abTests = [AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code).tap { it.percentActive = percentActive it.percentActiveSnakeCase = percentActiveSnakeCase }] @@ -483,13 +477,13 @@ class AbTestingModuleSpec extends ModuleBaseSpec { it.analyticsTags.activities.name.flatten() == [AB_TESTING, AB_TESTING].value it.analyticsTags.activities.status.flatten() == [FetchStatus.SUCCESS, FetchStatus.SUCCESS] it.analyticsTags.activities.results.status.flatten() == [FetchStatus.SKIPPED, FetchStatus.SKIPPED] - it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.ORTB2_BLOCKING, ModuleName.ORTB2_BLOCKING] + it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.PB_ORTB2_BLOCKING, ModuleName.PB_ORTB2_BLOCKING] } and: "Metric for specified module should be updated based on ab test config" def metrics = ortbModulePbsService.sendCollectedMetricsRequest() - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 where: percentActive | percentActiveSnakeCase @@ -506,7 +500,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Save account with ab test config" def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB_STAGES).tap { - abTests = [AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code).tap { + abTests = [AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code).tap { it.percentActive = percentActive it.percentActiveSnakeCase = percentActiveSnakeCase }] @@ -530,13 +524,13 @@ class AbTestingModuleSpec extends ModuleBaseSpec { it.analyticsTags.activities.name.flatten() == [AB_TESTING, AB_TESTING].value it.analyticsTags.activities.status.flatten() == [FetchStatus.SUCCESS, FetchStatus.SUCCESS] it.analyticsTags.activities.results.status.flatten() == [FetchStatus.SKIPPED, FetchStatus.SKIPPED] - it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.ORTB2_BLOCKING, ModuleName.ORTB2_BLOCKING] + it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.PB_ORTB2_BLOCKING, ModuleName.PB_ORTB2_BLOCKING] } and: "Metric for specified module should be updated based on ab test config" def metrics = ortbModulePbsService.sendCollectedMetricsRequest() - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 where: percentActive | percentActiveSnakeCase @@ -553,7 +547,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Save account with ab test config" def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB_STAGES).tap { - abTests = [AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code).tap { + abTests = [AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code).tap { it.percentActive = percentActive it.percentActiveSnakeCase = percentActiveSnakeCase }] @@ -578,18 +572,18 @@ class AbTestingModuleSpec extends ModuleBaseSpec { it.analyticsTags.activities.name.flatten().sort() == [ORTB2_BLOCKING, AB_TESTING, AB_TESTING].value.sort() it.analyticsTags.activities.status.flatten().sort() == [FetchStatus.SUCCESS, FetchStatus.SUCCESS, FetchStatus.SUCCESS].sort() it.analyticsTags.activities.results.status.flatten().sort() == [FetchStatus.SUCCESS_ALLOW, FetchStatus.RUN, FetchStatus.RUN].sort() - it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.ORTB2_BLOCKING, ModuleName.ORTB2_BLOCKING] + it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.PB_ORTB2_BLOCKING, ModuleName.PB_ORTB2_BLOCKING] } and: "Metric for specified module should be as default call" def metrics = ortbModulePbsService.sendCollectedMetricsRequest() - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 - assert !metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] - assert !metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] + assert !metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] + assert !metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] where: percentActive | percentActiveSnakeCase @@ -606,7 +600,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Save account with ab test config" def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB_STAGES).tap { - abTests = [AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code).tap { + abTests = [AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code).tap { percentActive = MIN_PERCENT_AB it.logAnalyticsTag = logAnalyticsTag it.logAnalyticsTagSnakeCase = logAnalyticsTagSnakeCase @@ -627,13 +621,13 @@ class AbTestingModuleSpec extends ModuleBaseSpec { it.analyticsTags.activities.name.flatten() == [AB_TESTING, AB_TESTING].value it.analyticsTags.activities.status.flatten() == [FetchStatus.SUCCESS, FetchStatus.SUCCESS] it.analyticsTags.activities.results.status.flatten() == [FetchStatus.SKIPPED, FetchStatus.SKIPPED] - it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.ORTB2_BLOCKING, ModuleName.ORTB2_BLOCKING] + it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.PB_ORTB2_BLOCKING, ModuleName.PB_ORTB2_BLOCKING] } and: "Metric for specified module should be updated based on ab test config" def metrics = ortbModulePbsService.sendCollectedMetricsRequest() - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 where: logAnalyticsTag | logAnalyticsTagSnakeCase @@ -651,7 +645,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Save account with ab test config" def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB_STAGES).tap { - abTests = [AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code).tap { + abTests = [AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code).tap { percentActive = MIN_PERCENT_AB it.logAnalyticsTag = logAnalyticsTag it.logAnalyticsTagSnakeCase = logAnalyticsTagSnakeCase @@ -676,8 +670,8 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Metric for specified module should be updated based on ab test config" def metrics = ortbModulePbsService.sendCollectedMetricsRequest() - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 where: logAnalyticsTag | logAnalyticsTagSnakeCase @@ -694,7 +688,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Save account with ab test config" def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB_STAGES).tap { - abTests = [AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code).tap { + abTests = [AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code).tap { percentActive = MAX_PERCENT_AB it.logAnalyticsTag = logAnalyticsTag it.logAnalyticsTagSnakeCase = logAnalyticsTagSnakeCase @@ -719,13 +713,13 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Metric for specified module should be as default call" def metrics = ortbModulePbsService.sendCollectedMetricsRequest() - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 - assert !metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] - assert !metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] + assert !metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] + assert !metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] where: logAnalyticsTag | logAnalyticsTagSnakeCase @@ -742,7 +736,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Save account with ab test config" def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB_STAGES).tap { - abTests = [AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code).tap { + abTests = [AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code).tap { percentActive = PBSUtils.getRandomNumber(MIN_PERCENT_AB, MAX_PERCENT_AB) }] } @@ -772,7 +766,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { def "PBS should apply a/b test config from host config when accounts is not specified when account config and default account doesn't include a/b test config"() { given: "PBS service with specific ab test config" def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, MODULES_STAGES).tap { - abTests = [AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code, accouns).tap { + abTests = [AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code, accouns).tap { percentActive = MIN_PERCENT_AB }] } @@ -790,14 +784,14 @@ class AbTestingModuleSpec extends ModuleBaseSpec { then: "PBS should apply ab test config for specified module" def invocationResults = response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List - def ortbBlockingInvocationResults = filterInvocationResultsByModule(invocationResults, ModuleName.ORTB2_BLOCKING) + def ortbBlockingInvocationResults = filterInvocationResultsByModule(invocationResults, ModuleName.PB_ORTB2_BLOCKING) verifyAll(ortbBlockingInvocationResults) { it.status == [SUCCESS, SUCCESS] it.action == [NO_INVOCATION, NO_INVOCATION] it.analyticsTags.activities.name.flatten() == [AB_TESTING, AB_TESTING].value it.analyticsTags.activities.status.flatten() == [FetchStatus.SUCCESS, FetchStatus.SUCCESS] it.analyticsTags.activities.results.status.flatten() == [FetchStatus.SKIPPED, FetchStatus.SKIPPED] - it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.ORTB2_BLOCKING, ModuleName.ORTB2_BLOCKING] + it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.PB_ORTB2_BLOCKING, ModuleName.PB_ORTB2_BLOCKING] } and: "PBS should not apply ab test config for other module" @@ -811,15 +805,15 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Metric for specified module should be updated based on ab test config" def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 and: "Metric for non specified module should be as default call" - assert metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 - assert metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 + assert metrics[CALL_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 + assert metrics[CALL_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] + assert !metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] + assert !metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] cleanup: "Stop and remove pbs container" pbsServiceFactory.removeContainer(pbsConfig) @@ -832,7 +826,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { given: "PBS service with specific ab test config" def accountId = PBSUtils.randomNumber def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, MODULES_STAGES).tap { - abTests = [AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code, [PBSUtils.randomNumber, accountId]).tap { + abTests = [AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code, [PBSUtils.randomNumber, accountId]).tap { percentActive = MIN_PERCENT_AB }] } @@ -853,14 +847,14 @@ class AbTestingModuleSpec extends ModuleBaseSpec { then: "PBS should apply ab test config for specified module" def invocationResults = response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List - def ortbBlockingInvocationResults = filterInvocationResultsByModule(invocationResults, ModuleName.ORTB2_BLOCKING) + def ortbBlockingInvocationResults = filterInvocationResultsByModule(invocationResults, ModuleName.PB_ORTB2_BLOCKING) verifyAll(ortbBlockingInvocationResults) { it.status == [SUCCESS, SUCCESS] it.action == [NO_INVOCATION, NO_INVOCATION] it.analyticsTags.activities.name.flatten() == [AB_TESTING, AB_TESTING].value it.analyticsTags.activities.status.flatten() == [FetchStatus.SUCCESS, FetchStatus.SUCCESS] it.analyticsTags.activities.results.status.flatten() == [FetchStatus.SKIPPED, FetchStatus.SKIPPED] - it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.ORTB2_BLOCKING, ModuleName.ORTB2_BLOCKING] + it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.PB_ORTB2_BLOCKING, ModuleName.PB_ORTB2_BLOCKING] } and: "PBS should not apply ab test config for other module" @@ -874,15 +868,15 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Metric for specified module should be updated based on ab test config" def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 and: "Metric for non specified module should be as default call" - assert metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 - assert metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 + assert metrics[CALL_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 + assert metrics[CALL_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] + assert !metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] + assert !metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] cleanup: "Stop and remove pbs container" pbsServiceFactory.removeContainer(pbsConfig) @@ -891,7 +885,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { def "PBS should apply a/b test config from host config for specific account and general config when account config and default account doesn't include a/b test config"() { given: "PBS service with specific ab test config" def accountId = PBSUtils.randomNumber - def ortb2AbTestConfig = AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code, []).tap { + def ortb2AbTestConfig = AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code, []).tap { it.percentActive = MIN_PERCENT_AB } def richMediaAbTestConfig = AbTest.getDefault(PB_RESPONSE_CORRECTION.code, [accountId]).tap { @@ -917,17 +911,17 @@ class AbTestingModuleSpec extends ModuleBaseSpec { then: "PBS should apply ab test config for ortb2blocking module" def invocationResults = response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List - def ortbBlockingInvocationResults = filterInvocationResultsByModule(invocationResults, ModuleName.ORTB2_BLOCKING) + def ortbBlockingInvocationResults = filterInvocationResultsByModule(invocationResults, ModuleName.PB_ORTB2_BLOCKING) verifyAll(ortbBlockingInvocationResults) { it.status == [SUCCESS, SUCCESS] it.action == [NO_INVOCATION, NO_INVOCATION] it.analyticsTags.activities.name.flatten() == [AB_TESTING, AB_TESTING].value it.analyticsTags.activities.status.flatten() == [FetchStatus.SUCCESS, FetchStatus.SUCCESS] it.analyticsTags.activities.results.status.flatten() == [FetchStatus.SKIPPED, FetchStatus.SKIPPED] - it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.ORTB2_BLOCKING, ModuleName.ORTB2_BLOCKING] + it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.PB_ORTB2_BLOCKING, ModuleName.PB_ORTB2_BLOCKING] } - and: "PBS should apply ab test config for response-correction module" + and: "PBS should apply ab test config for pb-response-correction module" def responseCorrectionInvocationResults = filterInvocationResultsByModule(invocationResults, PB_RESPONSE_CORRECTION) verifyAll(responseCorrectionInvocationResults) { it.status == [SUCCESS] @@ -938,18 +932,18 @@ class AbTestingModuleSpec extends ModuleBaseSpec { it.analyticsTags.activities.results.values.module.flatten() == [PB_RESPONSE_CORRECTION] } - and: "Metric for skipped ortb2blocking module should be updated based on ab test config" + and: "Metric for skipped pb-ortb2blocking module should be updated based on ab test config" def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() - assert !metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] - assert !metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] - assert metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 - assert metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 + assert !metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] + assert !metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] + assert metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 + assert metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 - and: "Metric for skipped response-correction module should be updated based on ab test config" - assert !metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] - assert !metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] - assert metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 - assert metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 + and: "Metric for skipped pb-response-correction module should be updated based on ab test config" + assert !metrics[CALL_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] + assert !metrics[CALL_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] + assert metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 + assert metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 cleanup: "Stop and remove pbs container" pbsServiceFactory.removeContainer(pbsConfig) @@ -958,7 +952,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { def "PBS shouldn't apply a/b test config from host config for non specified accounts when account config and default account doesn't include a/b test config"() { given: "PBS service with specific ab test config" def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, MODULES_STAGES).tap { - abTests = [AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code, [PBSUtils.randomNumber]).tap { + abTests = [AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code, [PBSUtils.randomNumber]).tap { percentActive = MIN_PERCENT_AB }] } @@ -976,7 +970,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { then: "PBS should apply ab test config for specified module" def invocationResults = response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List - def ortbBlockingInvocationResults = filterInvocationResultsByModule(invocationResults, ModuleName.ORTB2_BLOCKING) + def ortbBlockingInvocationResults = filterInvocationResultsByModule(invocationResults, ModuleName.PB_ORTB2_BLOCKING) verifyAll(ortbBlockingInvocationResults) { it.status == [SUCCESS, SUCCESS] it.action == [NO_ACTION, NO_ACTION] @@ -998,20 +992,20 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Metric for specified module should be as default call" def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 - assert !metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] - assert !metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] + assert !metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] + assert !metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] and: "Metric for non specified module should be as default call" - assert metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 - assert metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 + assert metrics[CALL_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 + assert metrics[CALL_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] + assert !metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] + assert !metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] cleanup: "Stop and remove pbs container" pbsServiceFactory.removeContainer(pbsConfig) @@ -1020,7 +1014,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { def "PBS should prioritise a/b test config from default account and only specified module when host and default account contains a/b test configs"() { given: "PBS service with specific ab test config" def accountExecutionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, MODULES_STAGES).tap { - abTests = [AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code).tap { + abTests = [AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code).tap { percentActive = MIN_PERCENT_AB }] } @@ -1029,7 +1023,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { } def hostExecutionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, MODULES_STAGES).tap { - abTests = [AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code)] + abTests = [AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code)] } def pbsConfig = MULTI_MODULE_CONFIG + ['hooks.host-execution-plan': encode(hostExecutionPlan)] + ["settings.default-account-config": encode(defaultAccountConfigSettings)] @@ -1046,14 +1040,14 @@ class AbTestingModuleSpec extends ModuleBaseSpec { then: "PBS should apply ab test config for specified module and call it based on all execution plans" def invocationResults = response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List - def ortbBlockingInvocationResults = filterInvocationResultsByModule(invocationResults, ModuleName.ORTB2_BLOCKING) + def ortbBlockingInvocationResults = filterInvocationResultsByModule(invocationResults, ModuleName.PB_ORTB2_BLOCKING) verifyAll(ortbBlockingInvocationResults) { it.status == [SUCCESS, SUCCESS, SUCCESS, SUCCESS] it.action == [NO_INVOCATION, NO_INVOCATION, NO_INVOCATION, NO_INVOCATION] it.analyticsTags.activities.name.flatten() == [AB_TESTING, AB_TESTING, AB_TESTING, AB_TESTING].value it.analyticsTags.activities.status.flatten() == [FetchStatus.SUCCESS, FetchStatus.SUCCESS, FetchStatus.SUCCESS, FetchStatus.SUCCESS] it.analyticsTags.activities.results.status.flatten() == [FetchStatus.SKIPPED, FetchStatus.SKIPPED, FetchStatus.SKIPPED, FetchStatus.SKIPPED] - it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.ORTB2_BLOCKING, ModuleName.ORTB2_BLOCKING, ModuleName.ORTB2_BLOCKING, ModuleName.ORTB2_BLOCKING] + it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.PB_ORTB2_BLOCKING, ModuleName.PB_ORTB2_BLOCKING, ModuleName.PB_ORTB2_BLOCKING, ModuleName.PB_ORTB2_BLOCKING] } and: "PBS should not apply ab test config for other modules and call them based on all execution plans" @@ -1067,15 +1061,15 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Metric for specified module should be updated based on ab test config" def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 2 - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 2 + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 2 + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 2 and: "Metric for non specified module should be as default call" - assert metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 2 - assert metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 2 + assert metrics[CALL_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 2 + assert metrics[CALL_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 2 - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] + assert !metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] + assert !metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] cleanup: "Stop and remove pbs container" pbsServiceFactory.removeContainer(pbsConfig) @@ -1083,7 +1077,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { def "PBS should prioritise a/b test config from account over default account and only specified module when specific account and default account contains a/b test configs"() { given: "PBS service with specific ab test config" - def accountExecutionPlan = new ExecutionPlan(abTests: [AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code)]) + def accountExecutionPlan = new ExecutionPlan(abTests: [AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code)]) def defaultAccountConfigSettings = AccountConfig.defaultAccountConfig.tap { hooks = new AccountHooksConfiguration(executionPlan: accountExecutionPlan) } @@ -1100,7 +1094,7 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Save account with ab test config" def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, MODULES_STAGES).tap { - abTests = [AbTest.getDefault(ModuleName.ORTB2_BLOCKING.code).tap { + abTests = [AbTest.getDefault(ModuleName.PB_ORTB2_BLOCKING.code).tap { percentActive = MIN_PERCENT_AB }] } @@ -1115,14 +1109,14 @@ class AbTestingModuleSpec extends ModuleBaseSpec { def invocationResults = response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List and: "PBS should apply ab test config for specified module" - def ortbBlockingInvocationResults = filterInvocationResultsByModule(invocationResults, ModuleName.ORTB2_BLOCKING) + def ortbBlockingInvocationResults = filterInvocationResultsByModule(invocationResults, ModuleName.PB_ORTB2_BLOCKING) verifyAll(ortbBlockingInvocationResults) { it.status == [SUCCESS, SUCCESS] it.action == [NO_INVOCATION, NO_INVOCATION] it.analyticsTags.activities.name.flatten() == [AB_TESTING, AB_TESTING].value it.analyticsTags.activities.status.flatten() == [FetchStatus.SUCCESS, FetchStatus.SUCCESS] it.analyticsTags.activities.results.status.flatten() == [FetchStatus.SKIPPED, FetchStatus.SKIPPED] - it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.ORTB2_BLOCKING, ModuleName.ORTB2_BLOCKING] + it.analyticsTags.activities.results.values.module.flatten() == [ModuleName.PB_ORTB2_BLOCKING, ModuleName.PB_ORTB2_BLOCKING] } and: "PBS should not apply ab test config for other module" @@ -1136,15 +1130,15 @@ class AbTestingModuleSpec extends ModuleBaseSpec { and: "Metric for specified module should be updated based on ab test config" def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[NO_INVOCATION_METRIC.formatted(ModuleName.ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[NO_INVOCATION_METRIC(ModuleName.PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 and: "Metric for non specified module should be as default call" - assert metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 - assert metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 + assert metrics[CALL_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 + assert metrics[CALL_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] == 1 - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] + assert !metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] + assert !metrics[NO_INVOCATION_METRIC(PB_RESPONSE_CORRECTION, ALL_PROCESSED_BID_RESPONSES)] cleanup: "Stop and remove pbs container" pbsServiceFactory.removeContainer(pbsConfig) diff --git a/src/test/groovy/org/prebid/server/functional/tests/module/GeneralModuleSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/module/GeneralModuleSpec.groovy index 23316766a7d..a8868878bd8 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/module/GeneralModuleSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/module/GeneralModuleSpec.groovy @@ -1,6 +1,6 @@ package org.prebid.server.functional.tests.module -import org.prebid.server.functional.model.ModuleName +import org.prebid.server.functional.model.config.ModuleName import org.prebid.server.functional.model.config.AccountConfig import org.prebid.server.functional.model.config.AccountHooksConfiguration import org.prebid.server.functional.model.config.AdminConfig @@ -16,12 +16,9 @@ import org.prebid.server.functional.model.response.auction.InvocationResult import org.prebid.server.functional.service.PrebidServerService import org.prebid.server.functional.util.PBSUtils -import static org.prebid.server.functional.model.ModuleName.ORTB2_BLOCKING -import static org.prebid.server.functional.model.ModuleName.PB_RICHMEDIA_FILTER +import static org.prebid.server.functional.model.config.ModuleName.PB_ORTB2_BLOCKING +import static org.prebid.server.functional.model.config.ModuleName.PB_RICHMEDIA_FILTER import static org.prebid.server.functional.model.config.Endpoint.OPENRTB2_AUCTION -import static org.prebid.server.functional.model.config.ModuleHookImplementation.ORTB2_BLOCKING_BIDDER_REQUEST -import static org.prebid.server.functional.model.config.ModuleHookImplementation.ORTB2_BLOCKING_RAW_BIDDER_RESPONSE -import static org.prebid.server.functional.model.config.ModuleHookImplementation.PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES import static org.prebid.server.functional.model.config.Stage.ALL_PROCESSED_BID_RESPONSES import static org.prebid.server.functional.model.config.Stage.BIDDER_REQUEST import static org.prebid.server.functional.model.config.Stage.RAW_BIDDER_RESPONSE @@ -31,14 +28,11 @@ import static org.prebid.server.functional.model.response.auction.ResponseAction class GeneralModuleSpec extends ModuleBaseSpec { - private final static String CALL_METRIC = "modules.module.%s.stage.%s.hook.%s.call" - private final static String NOOP_METRIC = "modules.module.%s.stage.%s.hook.%s.success.noop" - private final static Map DISABLED_INVOKE_CONFIG = ['settings.modules.require-config-to-invoke': 'false'] private final static Map ENABLED_INVOKE_CONFIG = ['settings.modules.require-config-to-invoke': 'true'] - private final static Map> ORTB_STAGES = [(BIDDER_REQUEST) : [ORTB2_BLOCKING], - (RAW_BIDDER_RESPONSE): [ORTB2_BLOCKING]] + private final static Map> ORTB_STAGES = [(BIDDER_REQUEST) : [PB_ORTB2_BLOCKING], + (RAW_BIDDER_RESPONSE): [PB_ORTB2_BLOCKING]] private final static Map> RESPONSE_STAGES = [(ALL_PROCESSED_BID_RESPONSES): [PB_RICHMEDIA_FILTER]] private final static Map> MODULES_STAGES = ORTB_STAGES + RESPONSE_STAGES private final static Map MULTI_MODULE_CONFIG = getRichMediaFilterSettings(PBSUtils.randomString) + @@ -74,19 +68,19 @@ class GeneralModuleSpec extends ModuleBaseSpec { verifyAll(response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List) { it.status == [SUCCESS, SUCCESS, SUCCESS] it.action == [NO_ACTION, NO_ACTION, NO_ACTION] - it.hookId.moduleCode.sort() == [ORTB2_BLOCKING, ORTB2_BLOCKING, PB_RICHMEDIA_FILTER].code.sort() + it.hookId.moduleCode.sort() == [PB_ORTB2_BLOCKING, PB_ORTB2_BLOCKING, PB_RICHMEDIA_FILTER].code.sort() } and: "Ortb2blocking module call metrics should be updated" def metrics = pbsServiceWithMultipleModule.sendCollectedMetricsRequest() - assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[CALL_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 + assert metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 and: "RB-Richmedia-Filter module call metrics should be updated" - assert metrics[CALL_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 - assert metrics[NOOP_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 + assert metrics[CALL_METRIC(PB_RICHMEDIA_FILTER, ALL_PROCESSED_BID_RESPONSES)] == 1 + assert metrics[NOOP_METRIC(PB_RICHMEDIA_FILTER, ALL_PROCESSED_BID_RESPONSES)] == 1 where: modulesConfig << [null, new PbsModulesConfig()] @@ -114,19 +108,19 @@ class GeneralModuleSpec extends ModuleBaseSpec { verifyAll(response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List) { it.status == [SUCCESS, SUCCESS, SUCCESS] it.action == [NO_ACTION, NO_ACTION, NO_ACTION] - it.hookId.moduleCode.sort() == [PB_RICHMEDIA_FILTER, ORTB2_BLOCKING, ORTB2_BLOCKING].code.sort() + it.hookId.moduleCode.sort() == [PB_RICHMEDIA_FILTER, PB_ORTB2_BLOCKING, PB_ORTB2_BLOCKING].code.sort() } and: "Ortb2blocking module call metrics should be updated" def metrics = pbsServiceWithMultipleModule.sendCollectedMetricsRequest() - assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[CALL_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 + assert metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 and: "RB-Richmedia-Filter module call metrics should be updated" - assert metrics[CALL_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 - assert metrics[NOOP_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 + assert metrics[CALL_METRIC(PB_RICHMEDIA_FILTER, ALL_PROCESSED_BID_RESPONSES)] == 1 + assert metrics[NOOP_METRIC(PB_RICHMEDIA_FILTER, ALL_PROCESSED_BID_RESPONSES)] == 1 where: pbRichmediaFilterConfig | pbResponseCorrectionConfig @@ -139,7 +133,7 @@ class GeneralModuleSpec extends ModuleBaseSpec { def "PBS should call all modules and traces response when default-account includes modules config and require-config-to-invoke is enabled"() { given: "PBS service with module config" - def pbsModulesConfig = new PbsModulesConfig(pbRichmediaFilter: new RichmediaFilter(), ortb2Blocking: new Ortb2BlockingConfig()) + def pbsModulesConfig = new PbsModulesConfig(pbRichmediaFilter: new RichmediaFilter(), pbOrtb2Blocking: new Ortb2BlockingConfig()) def defaultAccountConfigSettings = AccountConfig.defaultAccountConfig.tap { hooks = new AccountHooksConfiguration(modules: pbsModulesConfig) } @@ -162,19 +156,19 @@ class GeneralModuleSpec extends ModuleBaseSpec { verifyAll(response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List) { it.status == [SUCCESS, SUCCESS, SUCCESS] it.action == [NO_ACTION, NO_ACTION, NO_ACTION] - it.hookId.moduleCode.sort() == [PB_RICHMEDIA_FILTER, ORTB2_BLOCKING, ORTB2_BLOCKING].code.sort() + it.hookId.moduleCode.sort() == [PB_RICHMEDIA_FILTER, PB_ORTB2_BLOCKING, PB_ORTB2_BLOCKING].code.sort() } and: "Ortb2blocking module call metrics should be updated" def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() - assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[CALL_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 + assert metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 and: "RB-Richmedia-Filter module call metrics should be updated" - assert metrics[CALL_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 - assert metrics[NOOP_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 + assert metrics[CALL_METRIC(PB_RICHMEDIA_FILTER, ALL_PROCESSED_BID_RESPONSES)] == 1 + assert metrics[NOOP_METRIC(PB_RICHMEDIA_FILTER, ALL_PROCESSED_BID_RESPONSES)] == 1 cleanup: "Stop and remove pbs container" pbsServiceFactory.removeContainer(pbsConfig) @@ -187,7 +181,7 @@ class GeneralModuleSpec extends ModuleBaseSpec { } and: "Save account with enabled response correction module" - def pbsModulesConfig = new PbsModulesConfig(pbRichmediaFilter: pbRichmediaFilterConfig, ortb2Blocking: ortb2BlockingConfig) + def pbsModulesConfig = new PbsModulesConfig(pbRichmediaFilter: pbRichmediaFilterConfig, pbOrtb2Blocking: ortb2BlockingConfig) def accountConfig = new AccountConfig(hooks: new AccountHooksConfiguration(modules: pbsModulesConfig)) def account = new Account(uuid: bidRequest.getAccountId(), config: accountConfig) accountDao.save(account) @@ -202,19 +196,19 @@ class GeneralModuleSpec extends ModuleBaseSpec { verifyAll(response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List) { it.status == [SUCCESS, SUCCESS, SUCCESS] it.action == [NO_ACTION, NO_ACTION, NO_ACTION] - it.hookId.moduleCode.sort() == [PB_RICHMEDIA_FILTER, ORTB2_BLOCKING, ORTB2_BLOCKING].code.sort() + it.hookId.moduleCode.sort() == [PB_RICHMEDIA_FILTER, PB_ORTB2_BLOCKING, PB_ORTB2_BLOCKING].code.sort() } and: "Ortb2blocking module call metrics should be updated" def metrics = pbsServiceWithMultipleModuleWithRequireInvoke.sendCollectedMetricsRequest() - assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[CALL_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 + assert metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 and: "RB-Richmedia-Filter module call metrics should be updated" - assert metrics[CALL_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 - assert metrics[NOOP_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 + assert metrics[CALL_METRIC(PB_RICHMEDIA_FILTER, ALL_PROCESSED_BID_RESPONSES)] == 1 + assert metrics[NOOP_METRIC(PB_RICHMEDIA_FILTER, ALL_PROCESSED_BID_RESPONSES)] == 1 where: pbRichmediaFilterConfig | ortb2BlockingConfig @@ -252,14 +246,14 @@ class GeneralModuleSpec extends ModuleBaseSpec { and: "Ortb2blocking module call metrics should be updated" def metrics = pbsServiceWithMultipleModuleWithRequireInvoke.sendCollectedMetricsRequest() - assert !metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] - assert !metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] - assert !metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] - assert !metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] + assert !metrics[CALL_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] + assert !metrics[CALL_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] + assert !metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] + assert !metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] and: "RB-Richmedia-Filter module call metrics should be updated" - assert metrics[CALL_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 - assert metrics[NOOP_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 + assert metrics[CALL_METRIC(PB_RICHMEDIA_FILTER, ALL_PROCESSED_BID_RESPONSES)] == 1 + assert metrics[NOOP_METRIC(PB_RICHMEDIA_FILTER, ALL_PROCESSED_BID_RESPONSES)] == 1 } def "PBS shouldn't call any modules and traces that in response when account config is empty and require-config-to-invoke is enabled"() { @@ -284,14 +278,14 @@ class GeneralModuleSpec extends ModuleBaseSpec { and: "Ortb2blocking module call metrics shouldn't be updated" def metrics = pbsServiceWithMultipleModuleWithRequireInvoke.sendCollectedMetricsRequest() - assert !metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] - assert !metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] - assert !metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] - assert !metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] + assert !metrics[CALL_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] + assert !metrics[CALL_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] + assert !metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] + assert !metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] and: "RB-Richmedia-Filter module call metrics shouldn't be updated" - assert !metrics[CALL_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] - assert !metrics[NOOP_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] + assert !metrics[CALL_METRIC(PB_RICHMEDIA_FILTER, ALL_PROCESSED_BID_RESPONSES)] + assert !metrics[NOOP_METRIC(PB_RICHMEDIA_FILTER, ALL_PROCESSED_BID_RESPONSES)] where: modulesConfig << [null, new PbsModulesConfig()] @@ -300,7 +294,7 @@ class GeneralModuleSpec extends ModuleBaseSpec { def "PBS should call all modules without account config when modules enabled in module-execution host config"() { given: "PBS service with module-execution config" def pbsConfig = MULTI_MODULE_CONFIG + ENABLED_INVOKE_CONFIG + - [("hooks.admin.module-execution.${ORTB2_BLOCKING.code}".toString()): 'true'] + [("hooks.admin.module-execution.${PB_ORTB2_BLOCKING.code}".toString()): 'true'] def pbsServiceWithMultipleModules = pbsServiceFactory.getService(pbsConfig) and: "Default bid request with verbose trace" @@ -318,15 +312,15 @@ class GeneralModuleSpec extends ModuleBaseSpec { verifyAll(response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List) { it.status == [SUCCESS, SUCCESS] it.action == [NO_ACTION, NO_ACTION] - it.hookId.moduleCode.sort() == [ORTB2_BLOCKING, ORTB2_BLOCKING].code.sort() + it.hookId.moduleCode.sort() == [PB_ORTB2_BLOCKING, PB_ORTB2_BLOCKING].code.sort() } and: "Ortb2blocking module call metrics should be updated" def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() - assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[CALL_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 + assert metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 cleanup: "Stop and remove pbs container" pbsServiceFactory.removeContainer(pbsConfig) @@ -335,7 +329,7 @@ class GeneralModuleSpec extends ModuleBaseSpec { def "PBS shouldn't call any module without account config when modules disabled in module-execution host config"() { given: "PBS service with module-execution config" def pbsConfig = MULTI_MODULE_CONFIG + ENABLED_INVOKE_CONFIG + - [("hooks.admin.module-execution.${ORTB2_BLOCKING.code}".toString()): 'false'] + [("hooks.admin.module-execution.${PB_ORTB2_BLOCKING.code}".toString()): 'false'] def pbsServiceWithMultipleModules = pbsServiceFactory.getService(pbsConfig) and: "Default bid request with verbose trace" @@ -354,10 +348,10 @@ class GeneralModuleSpec extends ModuleBaseSpec { and: "Ortb2blocking module call metrics shouldn't be updated" def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() - assert !metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] - assert !metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] - assert !metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] - assert !metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] + assert !metrics[CALL_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] + assert !metrics[CALL_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] + assert !metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] + assert !metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] cleanup: "Stop and remove pbs container" pbsServiceFactory.removeContainer(pbsConfig) @@ -366,10 +360,10 @@ class GeneralModuleSpec extends ModuleBaseSpec { def "PBS shouldn't call module and not override host config when default-account module-execution config enabled module"() { given: "PBS service with module-execution and default account configs" def defaultAccountConfigSettings = AccountConfig.defaultAccountConfig.tap { - hooks = new AccountHooksConfiguration(admin: new AdminConfig(moduleExecution: [(ORTB2_BLOCKING): true])) + hooks = new AccountHooksConfiguration(admin: new AdminConfig(moduleExecution: [(PB_ORTB2_BLOCKING): true])) } def pbsConfig = MULTI_MODULE_CONFIG + ENABLED_INVOKE_CONFIG + ["settings.default-account-config": encode(defaultAccountConfigSettings)] + - [("hooks.admin.module-execution.${ORTB2_BLOCKING.code}".toString()): 'false'] + [("hooks.admin.module-execution.${PB_ORTB2_BLOCKING.code}".toString()): 'false'] def pbsServiceWithMultipleModules = pbsServiceFactory.getService(pbsConfig) and: "Default bid request with verbose trace" @@ -393,10 +387,10 @@ class GeneralModuleSpec extends ModuleBaseSpec { and: "Ortb2blocking module call metrics shouldn't be updated" def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() - assert !metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] - assert !metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] - assert !metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] - assert !metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] + assert !metrics[CALL_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] + assert !metrics[CALL_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] + assert !metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] + assert !metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] cleanup: "Stop and remove pbs container" pbsServiceFactory.removeContainer(pbsConfig) @@ -405,7 +399,7 @@ class GeneralModuleSpec extends ModuleBaseSpec { def "PBS should call module without account module config when default-account module-execution config enabling module"() { given: "PBS service with module-execution and default account configs" def defaultAccountConfigSettings = AccountConfig.defaultAccountConfig.tap { - hooks = new AccountHooksConfiguration(admin: new AdminConfig(moduleExecution: [(ORTB2_BLOCKING): true])) + hooks = new AccountHooksConfiguration(admin: new AdminConfig(moduleExecution: [(PB_ORTB2_BLOCKING): true])) } def pbsConfig = MULTI_MODULE_CONFIG + ENABLED_INVOKE_CONFIG + ["settings.default-account-config": encode(defaultAccountConfigSettings)] def pbsServiceWithMultipleModules = pbsServiceFactory.getService(pbsConfig) @@ -430,15 +424,15 @@ class GeneralModuleSpec extends ModuleBaseSpec { verifyAll(response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List) { it.status == [SUCCESS, SUCCESS] it.action == [NO_ACTION, NO_ACTION] - it.hookId.moduleCode.sort() == [ORTB2_BLOCKING, ORTB2_BLOCKING].code.sort() + it.hookId.moduleCode.sort() == [PB_ORTB2_BLOCKING, PB_ORTB2_BLOCKING].code.sort() } and: "Ortb2blocking module call metrics should be updated" def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() - assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[CALL_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 + assert metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 cleanup: "Stop and remove pbs container" pbsServiceFactory.removeContainer(pbsConfig) @@ -447,7 +441,7 @@ class GeneralModuleSpec extends ModuleBaseSpec { def "PBS shouldn't call any modules without account config when default-account module-execution config not enabling module"() { given: "PBS service with module-execution and default account configs" def defaultAccountConfigSettings = AccountConfig.defaultAccountConfig.tap { - hooks = new AccountHooksConfiguration(admin: new AdminConfig(moduleExecution: [(ORTB2_BLOCKING): moduleExecutionStatus])) + hooks = new AccountHooksConfiguration(admin: new AdminConfig(moduleExecution: [(PB_ORTB2_BLOCKING): moduleExecutionStatus])) } def pbsConfig = MULTI_MODULE_CONFIG + ENABLED_INVOKE_CONFIG + ["settings.default-account-config": encode(defaultAccountConfigSettings)] def pbsServiceWithMultipleModules = pbsServiceFactory.getService(pbsConfig) @@ -473,14 +467,14 @@ class GeneralModuleSpec extends ModuleBaseSpec { and: "Ortb2blocking module call metrics shouldn't be updated" def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() - assert !metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] - assert !metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] - assert !metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] - assert !metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] + assert !metrics[CALL_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] + assert !metrics[CALL_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] + assert !metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] + assert !metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] and: "RB-Richmedia-Filter module call metrics shouldn't be updated" - assert !metrics[CALL_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] - assert !metrics[NOOP_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] + assert !metrics[CALL_METRIC(PB_RICHMEDIA_FILTER, ALL_PROCESSED_BID_RESPONSES)] + assert !metrics[NOOP_METRIC(PB_RICHMEDIA_FILTER, ALL_PROCESSED_BID_RESPONSES)] cleanup: "Stop and remove pbs container" pbsServiceFactory.removeContainer(pbsConfig) @@ -492,7 +486,7 @@ class GeneralModuleSpec extends ModuleBaseSpec { def "PBS should prioritize specific account module-execution config over default-account module-execution config when both are present"() { given: "PBS service with default account config" def defaultAccountConfigSettings = AccountConfig.defaultAccountConfig.tap { - hooks = new AccountHooksConfiguration(admin: new AdminConfig(moduleExecution: [(ORTB2_BLOCKING): false])) + hooks = new AccountHooksConfiguration(admin: new AdminConfig(moduleExecution: [(PB_ORTB2_BLOCKING): false])) } def pbsConfig = MULTI_MODULE_CONFIG + ENABLED_INVOKE_CONFIG + ["settings.default-account-config": encode(defaultAccountConfigSettings)] def pbsServiceWithMultipleModules = pbsServiceFactory.getService(pbsConfig) @@ -503,7 +497,7 @@ class GeneralModuleSpec extends ModuleBaseSpec { } and: "Save account without modules config" - def accountConfig = new AccountConfig(hooks: new AccountHooksConfiguration(admin: new AdminConfig(moduleExecution: [(ORTB2_BLOCKING): true]))) + def accountConfig = new AccountConfig(hooks: new AccountHooksConfiguration(admin: new AdminConfig(moduleExecution: [(PB_ORTB2_BLOCKING): true]))) def account = new Account(uuid: bidRequest.getAccountId(), config: accountConfig) accountDao.save(account) @@ -517,19 +511,19 @@ class GeneralModuleSpec extends ModuleBaseSpec { verifyAll(response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List) { it.status == [SUCCESS, SUCCESS] it.action == [NO_ACTION, NO_ACTION] - it.hookId.moduleCode.sort() == [ORTB2_BLOCKING, ORTB2_BLOCKING].code.sort() + it.hookId.moduleCode.sort() == [PB_ORTB2_BLOCKING, PB_ORTB2_BLOCKING].code.sort() } and: "Ortb2blocking module call metrics should be updated" def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() - assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 - assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[CALL_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[CALL_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 + assert metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, BIDDER_REQUEST)] == 1 + assert metrics[NOOP_METRIC(PB_ORTB2_BLOCKING, RAW_BIDDER_RESPONSE)] == 1 and: "RB-Richmedia-Filter module call metrics shouldn't be updated" - assert !metrics[CALL_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] - assert !metrics[NOOP_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] + assert !metrics[CALL_METRIC(PB_RICHMEDIA_FILTER, ALL_PROCESSED_BID_RESPONSES)] + assert !metrics[NOOP_METRIC(PB_RICHMEDIA_FILTER, ALL_PROCESSED_BID_RESPONSES)] cleanup: "Stop and remove pbs container" pbsServiceFactory.removeContainer(pbsConfig) diff --git a/src/test/groovy/org/prebid/server/functional/tests/module/ModuleBaseSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/module/ModuleBaseSpec.groovy index c0933a238e7..d509d0ac44b 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/module/ModuleBaseSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/module/ModuleBaseSpec.groovy @@ -1,20 +1,20 @@ package org.prebid.server.functional.tests.module +import org.prebid.server.functional.model.config.ModuleName import org.prebid.server.functional.model.config.Endpoint import org.prebid.server.functional.model.config.ExecutionPlan import org.prebid.server.functional.model.config.Stage import org.prebid.server.functional.model.response.auction.AnalyticResult import org.prebid.server.functional.model.response.auction.BidResponse -import org.prebid.server.functional.model.response.auction.InvocationResult import org.prebid.server.functional.tests.BaseSpec import org.prebid.server.functional.util.PBSUtils -import static org.prebid.server.functional.model.ModuleName.OPTABLE_TARGETING -import static org.prebid.server.functional.model.ModuleName.ORTB2_BLOCKING -import static org.prebid.server.functional.model.ModuleName.PB_RESPONSE_CORRECTION -import static org.prebid.server.functional.model.ModuleName.PB_RICHMEDIA_FILTER -import static org.prebid.server.functional.model.ModuleName.PB_REQUEST_CORRECTION -import static org.prebid.server.functional.model.ModuleName.PB_RULE_ENGINE +import static org.prebid.server.functional.model.config.ModuleName.OPTABLE_TARGETING +import static org.prebid.server.functional.model.config.ModuleName.PB_ORTB2_BLOCKING +import static org.prebid.server.functional.model.config.ModuleName.PB_REQUEST_CORRECTION +import static org.prebid.server.functional.model.config.ModuleName.PB_RESPONSE_CORRECTION +import static org.prebid.server.functional.model.config.ModuleName.PB_RICHMEDIA_FILTER +import static org.prebid.server.functional.model.config.ModuleName.PB_RULE_ENGINE import static org.prebid.server.functional.model.config.Endpoint.OPENRTB2_AUCTION import static org.prebid.server.functional.model.config.Stage.ALL_PROCESSED_BID_RESPONSES import static org.prebid.server.functional.model.config.Stage.PROCESSED_AUCTION_REQUEST @@ -33,6 +33,22 @@ class ModuleBaseSpec extends BaseSpec { repository.removeAllDatabaseData() } + protected final static Closure CALL_METRIC = { ModuleName module, Stage stage -> + "modules.module.${module.code}.stage.${stage.metricValue}.hook.${module.code}-${stage.value}-hook.call" + } + protected final static Closure UPDATE_METRIC = { ModuleName module, Stage stage -> + "modules.module.${module.code}.stage.${stage.metricValue}.hook.${module.code}-${stage.value}-hook.success.update" + } + protected final static Closure NOOP_METRIC = { ModuleName module, Stage stage -> + "modules.module.${module.code}.stage.${stage.metricValue}.hook.${module.code}-${stage.value}-hook.success.noop" + } + protected final static Closure NO_INVOCATION_METRIC = { ModuleName module, Stage stage -> + "modules.module.${module.code}.stage.${stage.metricValue}.hook.${module.code}-${stage.value}-hook.success.no-invocation" + } + protected final static Closure EXECUTION_ERROR_METRIC = { ModuleName module, Stage stage -> + "modules.module.${module.code}.stage.${stage.metricValue}.hook.${module.code}-${stage.value}-hook.execution-error" + } + protected static Map getResponseCorrectionConfig(Endpoint endpoint = OPENRTB2_AUCTION) { ["hooks.${PB_RESPONSE_CORRECTION.code}.enabled": true, "hooks.host-execution-plan" : encode(ExecutionPlan.getSingleEndpointExecutionPlan(endpoint, [(ALL_PROCESSED_BID_RESPONSES): [PB_RESPONSE_CORRECTION]]))] @@ -60,16 +76,16 @@ class ModuleBaseSpec extends BaseSpec { } protected static Map getOptableTargetingSettings(boolean isEnabled = true, Endpoint endpoint = OPENRTB2_AUCTION) { - ["hooks.${OPTABLE_TARGETING.code}.enabled": isEnabled as String, - "hooks.modules.${OPTABLE_TARGETING.code}.api-endpoint" : "$networkServiceContainer.rootUri/stored-cache".toString(), - "hooks.modules.${OPTABLE_TARGETING.code}.tenant" : PBSUtils.randomString, - "hooks.modules.${OPTABLE_TARGETING.code}.origin" : PBSUtils.randomString, - "hooks.host-execution-plan" : encode(ExecutionPlan.getSingleEndpointExecutionPlan(endpoint, [(PROCESSED_AUCTION_REQUEST): [OPTABLE_TARGETING]]))] + ["hooks.${OPTABLE_TARGETING.code}.enabled" : isEnabled as String, + "hooks.modules.${OPTABLE_TARGETING.code}.api-endpoint": "$networkServiceContainer.rootUri/stored-cache".toString(), + "hooks.modules.${OPTABLE_TARGETING.code}.tenant" : PBSUtils.randomString, + "hooks.modules.${OPTABLE_TARGETING.code}.origin" : PBSUtils.randomString, + "hooks.host-execution-plan" : encode(ExecutionPlan.getSingleEndpointExecutionPlan(endpoint, [(PROCESSED_AUCTION_REQUEST): [OPTABLE_TARGETING]]))] .collectEntries { key, value -> [(key.toString()): value.toString()] } } protected static Map getOrtb2BlockingSettings(boolean isEnabled = true) { - ["hooks.${ORTB2_BLOCKING.code}.enabled": isEnabled as String] + ["hooks.${PB_ORTB2_BLOCKING.code}.enabled": isEnabled as String] } protected static Map getRequestCorrectionSettings(Endpoint endpoint = OPENRTB2_AUCTION, Stage stage = PROCESSED_AUCTION_REQUEST) { diff --git a/src/test/groovy/org/prebid/server/functional/tests/module/analyticstag/AnalyticsTagsModuleSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/module/analyticstag/AnalyticsTagsModuleSpec.groovy index 82355a47996..05815a64158 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/module/analyticstag/AnalyticsTagsModuleSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/module/analyticstag/AnalyticsTagsModuleSpec.groovy @@ -19,8 +19,8 @@ import org.prebid.server.functional.service.PrebidServerService import org.prebid.server.functional.tests.module.ModuleBaseSpec import org.prebid.server.functional.util.PBSUtils -import static org.prebid.server.functional.model.ModuleName.ORTB2_BLOCKING -import static org.prebid.server.functional.model.ModuleName.PB_RICHMEDIA_FILTER +import static org.prebid.server.functional.model.config.ModuleName.PB_ORTB2_BLOCKING +import static org.prebid.server.functional.model.config.ModuleName.PB_RICHMEDIA_FILTER import static org.prebid.server.functional.model.bidder.BidderName.GENERIC import static org.prebid.server.functional.model.config.Endpoint.OPENRTB2_AUCTION import static org.prebid.server.functional.model.config.Stage.ALL_PROCESSED_BID_RESPONSES @@ -36,14 +36,14 @@ class AnalyticsTagsModuleSpec extends ModuleBaseSpec { pbsServiceFactory.removeContainer(getOrtb2BlockingSettings()) } - def "PBS should include analytics tag for ortb2-blocking module in response when request and account allow client details"() { + def "PBS should include analytics tag for pb-ortb2-blocking module in response when request and account allow client details"() { given: "Default account with module config" def bidRequest = BidRequest.defaultBidRequest.tap { it.ext.prebid.analytics = new PrebidAnalytics(options: new AnalyticsOptions(enableClientDetails: true)) } and: "Account in the DB" - def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB2_BLOCKING, [RAW_BIDDER_RESPONSE]) + def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, PB_ORTB2_BLOCKING, [RAW_BIDDER_RESPONSE]) def hooksConfiguration = new AccountHooksConfiguration(executionPlan: executionPlan) def accountConfig = new AccountConfig(hooks: hooksConfiguration, analytics: new AccountAnalyticsConfig(allowClientDetails: true)) def account = new Account(uuid: bidRequest.accountId, config: accountConfig) @@ -55,7 +55,7 @@ class AnalyticsTagsModuleSpec extends ModuleBaseSpec { then: "Bid response should contain ext.prebid.analyticsTags with module record" def analyticsTagPrebid = bidResponse.ext.prebid.analytics.tags.first assert analyticsTagPrebid.stage == RAW_BIDDER_RESPONSE.value - assert analyticsTagPrebid.module == ORTB2_BLOCKING.code + assert analyticsTagPrebid.module == PB_ORTB2_BLOCKING.code and: "Analytics tag should contain results with name and success status" def analyticResult = analyticsTagPrebid.analyticsTags.activities.first @@ -122,7 +122,7 @@ class AnalyticsTagsModuleSpec extends ModuleBaseSpec { def "PBS should include analytics tag in response when request and default account allow client details"() { given: "Default account with module config" - def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB2_BLOCKING, [RAW_BIDDER_RESPONSE]) + def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, PB_ORTB2_BLOCKING, [RAW_BIDDER_RESPONSE]) def hooksConfiguration = new AccountHooksConfiguration(executionPlan: executionPlan) def accountConfig = new AccountConfig(hooks: hooksConfiguration, analytics: new AccountAnalyticsConfig(allowClientDetails: true)) @@ -141,7 +141,7 @@ class AnalyticsTagsModuleSpec extends ModuleBaseSpec { then: "Bid response should contain ext.prebid.analyticsTags with module record" def analyticsTagPrebid = bidResponse.ext.prebid.analytics.tags.first assert analyticsTagPrebid.stage == RAW_BIDDER_RESPONSE.value - assert analyticsTagPrebid.module == ORTB2_BLOCKING.code + assert analyticsTagPrebid.module == PB_ORTB2_BLOCKING.code and: "Analytics tag should contain results with name and success status" def analyticResult = analyticsTagPrebid.analyticsTags.activities.first @@ -161,7 +161,7 @@ class AnalyticsTagsModuleSpec extends ModuleBaseSpec { def "PBS should include analytics tag in response when request and account allow client details but default doesn't"() { given: "Default account with module config" - def defaultExecutionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB2_BLOCKING, [RAW_BIDDER_RESPONSE]) + def defaultExecutionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, PB_ORTB2_BLOCKING, [RAW_BIDDER_RESPONSE]) def defaultHooksConfiguration = new AccountHooksConfiguration(executionPlan: defaultExecutionPlan) def defaultAccountConfig = new AccountConfig(hooks: defaultHooksConfiguration, analytics: new AccountAnalyticsConfig(allowClientDetails: false)) @@ -175,7 +175,7 @@ class AnalyticsTagsModuleSpec extends ModuleBaseSpec { } and: "Account in the DB" - def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB2_BLOCKING, [RAW_BIDDER_RESPONSE]) + def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, PB_ORTB2_BLOCKING, [RAW_BIDDER_RESPONSE]) def hooksConfiguration = new AccountHooksConfiguration(executionPlan: executionPlan) def accountConfig = new AccountConfig(hooks: hooksConfiguration, analytics: new AccountAnalyticsConfig(allowClientDetails: true)) def account = new Account(uuid: bidRequest.accountId, config: accountConfig) @@ -187,7 +187,7 @@ class AnalyticsTagsModuleSpec extends ModuleBaseSpec { then: "Bid response should contain ext.prebid.analyticsTags with module record" def analyticsTagPrebid = bidResponse.ext.prebid.analytics.tags.first assert analyticsTagPrebid.stage == RAW_BIDDER_RESPONSE.value - assert analyticsTagPrebid.module == ORTB2_BLOCKING.code + assert analyticsTagPrebid.module == PB_ORTB2_BLOCKING.code and: "Analytics tag should contain results with name and success status" def analyticResult = analyticsTagPrebid.analyticsTags.activities.first @@ -212,7 +212,7 @@ class AnalyticsTagsModuleSpec extends ModuleBaseSpec { } and: "Account in the DB" - def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB2_BLOCKING, [RAW_BIDDER_RESPONSE]) + def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, PB_ORTB2_BLOCKING, [RAW_BIDDER_RESPONSE]) def hooksConfiguration = new AccountHooksConfiguration(executionPlan: executionPlan) def accountConfig = new AccountConfig(hooks: hooksConfiguration, analytics: new AccountAnalyticsConfig(allowClientDetails: true)) def account = new Account(uuid: bidRequest.accountId, config: accountConfig) @@ -235,7 +235,7 @@ class AnalyticsTagsModuleSpec extends ModuleBaseSpec { } and: "Account in the DB" - def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB2_BLOCKING, [RAW_BIDDER_RESPONSE]) + def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, PB_ORTB2_BLOCKING, [RAW_BIDDER_RESPONSE]) def hooksConfiguration = new AccountHooksConfiguration(executionPlan: executionPlan) def accountConfig = new AccountConfig(hooks: hooksConfiguration, analytics: new AccountAnalyticsConfig(allowClientDetails: true)) def account = new Account(uuid: bidRequest.accountId, config: accountConfig) @@ -258,7 +258,7 @@ class AnalyticsTagsModuleSpec extends ModuleBaseSpec { } and: "Account in the DB" - def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB2_BLOCKING, [RAW_BIDDER_RESPONSE]) + def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, PB_ORTB2_BLOCKING, [RAW_BIDDER_RESPONSE]) def hooksConfiguration = new AccountHooksConfiguration(executionPlan: executionPlan) def accountConfig = new AccountConfig(hooks: hooksConfiguration, analytics: new AccountAnalyticsConfig(allowClientDetails: false)) def account = new Account(uuid: bidRequest.accountId, config: accountConfig) @@ -282,7 +282,7 @@ class AnalyticsTagsModuleSpec extends ModuleBaseSpec { } and: "Account in the DB" - def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB2_BLOCKING, [RAW_BIDDER_RESPONSE]) + def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, PB_ORTB2_BLOCKING, [RAW_BIDDER_RESPONSE]) def hooksConfiguration = new AccountHooksConfiguration(executionPlan: executionPlan) def accountConfig = new AccountConfig(hooks: hooksConfiguration, analytics: new AccountAnalyticsConfig(allowClientDetails: false)) def account = new Account(uuid: bidRequest.accountId, config: accountConfig) diff --git a/src/test/groovy/org/prebid/server/functional/tests/module/optabletargeting/CacheStorageSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/module/optabletargeting/CacheStorageSpec.groovy index 5f00d0765d3..e9e7c2928db 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/module/optabletargeting/CacheStorageSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/module/optabletargeting/CacheStorageSpec.groovy @@ -21,7 +21,7 @@ import org.prebid.server.functional.util.PBSUtils import static org.apache.commons.codec.binary.Base64.encodeBase64 import static org.mockserver.model.HttpStatusCode.NOT_FOUND_404 -import static org.prebid.server.functional.model.ModuleName.OPTABLE_TARGETING +import static org.prebid.server.functional.model.config.ModuleName.OPTABLE_TARGETING import static org.prebid.server.functional.testcontainers.Dependencies.getNetworkServiceContainer class CacheStorageSpec extends ModuleBaseSpec { diff --git a/src/test/groovy/org/prebid/server/functional/tests/module/ortb2blocking/Ortb2BlockingSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/module/pbortb2blocking/PbOrtb2BlockingSpec.groovy similarity index 99% rename from src/test/groovy/org/prebid/server/functional/tests/module/ortb2blocking/Ortb2BlockingSpec.groovy rename to src/test/groovy/org/prebid/server/functional/tests/module/pbortb2blocking/PbOrtb2BlockingSpec.groovy index a7a97bc8816..59b2f30d90b 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/module/ortb2blocking/Ortb2BlockingSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/module/pbortb2blocking/PbOrtb2BlockingSpec.groovy @@ -1,4 +1,4 @@ -package org.prebid.server.functional.tests.module.ortb2blocking +package org.prebid.server.functional.tests.module.pbortb2blocking import org.prebid.server.functional.model.bidder.BidderName import org.prebid.server.functional.model.bidder.Generic @@ -27,14 +27,13 @@ import org.prebid.server.functional.model.response.auction.Adm import org.prebid.server.functional.model.response.auction.Bid import org.prebid.server.functional.model.response.auction.BidMediaType import org.prebid.server.functional.model.response.auction.BidResponse -import org.prebid.server.functional.model.response.auction.ErrorType import org.prebid.server.functional.model.response.auction.MediaType import org.prebid.server.functional.model.response.auction.SeatBid import org.prebid.server.functional.service.PrebidServerService import org.prebid.server.functional.tests.module.ModuleBaseSpec import org.prebid.server.functional.util.PBSUtils -import static org.prebid.server.functional.model.ModuleName.ORTB2_BLOCKING +import static org.prebid.server.functional.model.config.ModuleName.PB_ORTB2_BLOCKING import static org.prebid.server.functional.model.bidder.BidderName.ALIAS import static org.prebid.server.functional.model.bidder.BidderName.GENERIC import static org.prebid.server.functional.model.bidder.BidderName.IX @@ -54,7 +53,7 @@ import static org.prebid.server.functional.model.response.auction.MediaType.BANN import static org.prebid.server.functional.model.response.auction.MediaType.VIDEO import static org.prebid.server.functional.testcontainers.Dependencies.getNetworkServiceContainer -class Ortb2BlockingSpec extends ModuleBaseSpec { +class PbOrtb2BlockingSpec extends ModuleBaseSpec { private static final String WILDCARD = '*' private static final Map IX_CONFIG = ["adapters.ix.enabled" : "true", @@ -285,7 +284,7 @@ class Ortb2BlockingSpec extends ModuleBaseSpec { def response = pbsServiceWithEnabledOrtb2Blocking.sendAuctionRequest(bidRequest) then: "PBS response should contain seatNonBid for the called bidder" - assert response.ext.prebid.modules.errors.ortb2Blocking["ortb2-blocking-bidder-request"].first + assert response.ext.prebid.modules.errors.pbOrtb2Blocking["${PB_ORTB2_BLOCKING.code}-${BIDDER_REQUEST.value}-hook"].first .contains("field in account configuration is not an array") and: "PBS response shouldn't contain any module warning" @@ -318,7 +317,7 @@ class Ortb2BlockingSpec extends ModuleBaseSpec { def response = pbsServiceWithEnabledOrtb2Blocking.sendAuctionRequest(bidRequest) then: "PBS response should contain seatNonBid for the called bidder" - assert response.ext.prebid.modules.errors.ortb2Blocking["ortb2-blocking-bidder-request"].first + assert response.ext.prebid.modules.errors.pbOrtb2Blocking["${PB_ORTB2_BLOCKING.code}-${BIDDER_REQUEST.value}-hook"].first .contains("field in account configuration has unexpected type") and: "PBS response shouldn't contain any module warning" @@ -1309,7 +1308,7 @@ class Ortb2BlockingSpec extends ModuleBaseSpec { assert !response?.ext?.prebid?.modules?.errors and: "PBS response should contain proper warning" - assert response?.ext?.prebid?.modules?.warnings?.ortb2Blocking["ortb2-blocking-bidder-request"] == + assert response?.ext?.prebid?.modules?.warnings?.pbOrtb2Blocking["${PB_ORTB2_BLOCKING.code}-${BIDDER_REQUEST.value}-hook"] == ["More than one conditions matches request. Bidder: generic, request media types: [${bidRequest.imp[0].mediaTypes[0].value}]"] where: @@ -1532,8 +1531,8 @@ class Ortb2BlockingSpec extends ModuleBaseSpec { private static Account getAccountWithOrtb2BlockingConfig(String accountId, Map attributes) { def blockingConfig = new Ortb2BlockingConfig(attributes: attributes) - def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, ORTB2_BLOCKING, [BIDDER_REQUEST, RAW_BIDDER_RESPONSE]) - def moduleConfig = new PbsModulesConfig(ortb2Blocking: blockingConfig) + def executionPlan = ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, PB_ORTB2_BLOCKING, [BIDDER_REQUEST, RAW_BIDDER_RESPONSE]) + def moduleConfig = new PbsModulesConfig(pbOrtb2Blocking: blockingConfig) def accountHooksConfig = new AccountHooksConfiguration(executionPlan: executionPlan, modules: moduleConfig) def accountConfig = new AccountConfig(hooks: accountHooksConfig) new Account(uuid: accountId, config: accountConfig) diff --git a/src/test/groovy/org/prebid/server/functional/tests/module/responsecorrenction/ResponseCorrectionSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/module/pbresponsecorrenction/PbResponseCorrectionSpec.groovy similarity index 99% rename from src/test/groovy/org/prebid/server/functional/tests/module/responsecorrenction/ResponseCorrectionSpec.groovy rename to src/test/groovy/org/prebid/server/functional/tests/module/pbresponsecorrenction/PbResponseCorrectionSpec.groovy index 4d24d199113..fb7ca93eb9f 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/module/responsecorrenction/ResponseCorrectionSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/module/pbresponsecorrenction/PbResponseCorrectionSpec.groovy @@ -1,4 +1,4 @@ -package org.prebid.server.functional.tests.module.responsecorrenction +package org.prebid.server.functional.tests.module.pbresponsecorrenction import org.prebid.server.functional.model.config.AccountAuctionConfig import org.prebid.server.functional.model.config.AccountCacheConfig @@ -32,7 +32,7 @@ import static org.prebid.server.functional.model.response.auction.MediaType.BANN import static org.prebid.server.functional.model.response.auction.MediaType.NATIVE import static org.prebid.server.functional.model.response.auction.MediaType.VIDEO -class ResponseCorrectionSpec extends ModuleBaseSpec { +class PbResponseCorrectionSpec extends ModuleBaseSpec { private final static int OPTIMAL_MAX_LENGTH = 20 private static final Map PBS_CONFIG = ["adapter-defaults.modifying-vast-xml-allowed": "false", diff --git a/src/test/groovy/org/prebid/server/functional/tests/module/richmedia/RichMediaFilterSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/module/pbrichmedia/PbRichMediaFilterSpec.groovy similarity index 99% rename from src/test/groovy/org/prebid/server/functional/tests/module/richmedia/RichMediaFilterSpec.groovy rename to src/test/groovy/org/prebid/server/functional/tests/module/pbrichmedia/PbRichMediaFilterSpec.groovy index 517da393668..a4b2b6b6047 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/module/richmedia/RichMediaFilterSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/module/pbrichmedia/PbRichMediaFilterSpec.groovy @@ -1,4 +1,4 @@ -package org.prebid.server.functional.tests.module.richmedia +package org.prebid.server.functional.tests.module.pbrichmedia import org.prebid.server.functional.model.config.AccountConfig import org.prebid.server.functional.model.config.AccountHooksConfiguration @@ -17,13 +17,13 @@ import org.prebid.server.functional.tests.module.ModuleBaseSpec import org.prebid.server.functional.util.PBSUtils import static org.prebid.server.functional.model.response.auction.BidRejectionReason.RESPONSE_REJECTED_INVALID_CREATIVE -import static org.prebid.server.functional.model.ModuleName.PB_RICHMEDIA_FILTER +import static org.prebid.server.functional.model.config.ModuleName.PB_RICHMEDIA_FILTER import static org.prebid.server.functional.model.bidder.BidderName.GENERIC import static org.prebid.server.functional.model.config.Endpoint.OPENRTB2_AUCTION import static org.prebid.server.functional.model.config.Stage.ALL_PROCESSED_BID_RESPONSES import static org.prebid.server.functional.model.request.auction.TraceLevel.VERBOSE -class RichMediaFilterSpec extends ModuleBaseSpec { +class PbRichMediaFilterSpec extends ModuleBaseSpec { private static final String PATTERN_NAME = PBSUtils.randomString private static final String PATTERN_NAME_ACCOUNT = PBSUtils.randomString diff --git a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineAliasSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineAliasSpec.groovy similarity index 98% rename from src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineAliasSpec.groovy rename to src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineAliasSpec.groovy index 4477e6d9d38..9eb712715d5 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineAliasSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineAliasSpec.groovy @@ -2,7 +2,7 @@ package org.prebid.server.functional.tests.module.pbruleengine import org.prebid.server.functional.model.request.auction.Imp -import static org.prebid.server.functional.model.ModuleName.PB_RULE_ENGINE +import static org.prebid.server.functional.model.config.ModuleName.PB_RULE_ENGINE import static org.prebid.server.functional.model.bidder.BidderName.ALIAS import static org.prebid.server.functional.model.bidder.BidderName.AMX import static org.prebid.server.functional.model.bidder.BidderName.GENERIC @@ -14,7 +14,7 @@ import static org.prebid.server.functional.model.config.RuleEngineModelRuleResul import static org.prebid.server.functional.model.request.auction.FetchStatus.SUCCESS import static org.prebid.server.functional.model.response.auction.BidRejectionReason.REQUEST_BIDDER_REMOVED_BY_RULE_ENGINE_MODULE -class RuleEngineAliasSpec extends RuleEngineBaseSpec { +class PbRuleEngineAliasSpec extends PbRuleEngineBaseSpec { def "PBS should leave only hard alias bidder at imps when hard alias bidder include in account config"() { given: "Bid request with multiply imps bidders" diff --git a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineBaseSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineBaseSpec.groovy similarity index 91% rename from src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineBaseSpec.groovy rename to src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineBaseSpec.groovy index d77288da086..b277753183f 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineBaseSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineBaseSpec.groovy @@ -21,14 +21,11 @@ import org.prebid.server.functional.tests.module.ModuleBaseSpec import org.prebid.server.functional.util.PBSUtils import spock.lang.Retry -import static org.prebid.server.functional.model.ModuleName.PB_RULE_ENGINE import static org.prebid.server.functional.model.bidder.BidderName.ALIAS import static org.prebid.server.functional.model.bidder.BidderName.AMX import static org.prebid.server.functional.model.bidder.BidderName.GENERIC import static org.prebid.server.functional.model.bidder.BidderName.OPENX import static org.prebid.server.functional.model.bidder.BidderName.OPENX_ALIAS -import static org.prebid.server.functional.model.config.ModuleHookImplementation.PB_RULES_ENGINE_PROCESSED_AUCTION_REQUEST -import static org.prebid.server.functional.model.config.Stage.PROCESSED_AUCTION_REQUEST import static org.prebid.server.functional.model.pricefloors.Country.USA import static org.prebid.server.functional.model.request.auction.DistributionChannel.APP import static org.prebid.server.functional.model.request.auction.DistributionChannel.DOOH @@ -42,16 +39,13 @@ import static org.prebid.server.functional.testcontainers.Dependencies.getNetwor import static org.prebid.server.functional.util.privacy.TcfConsent.GENERIC_VENDOR_ID @Retry //TODO remove in 3.34+ -abstract class RuleEngineBaseSpec extends ModuleBaseSpec { +abstract class PbRuleEngineBaseSpec extends ModuleBaseSpec { protected static final List MULTI_BID_ADAPTERS = [GENERIC, OPENX, AMX].sort() protected static final Integer OPENX_VENDOR_ID = PBSUtils.getRandomNumber(0, 65534) protected static final Integer AMX_VENDOR_ID = PBSUtils.getRandomNumber(0, 65534) protected static final String APPLIED_FOR_ALL_IMPS = "*" protected static final String DEFAULT_CONDITIONS = "default" - protected final static String CALL_METRIC = "modules.module.${PB_RULE_ENGINE.code}.stage.${PROCESSED_AUCTION_REQUEST.metricValue}.hook.${PB_RULES_ENGINE_PROCESSED_AUCTION_REQUEST.code}.call" - protected final static String NOOP_METRIC = "modules.module.${PB_RULE_ENGINE.code}.stage.${PROCESSED_AUCTION_REQUEST.metricValue}.hook.${PB_RULES_ENGINE_PROCESSED_AUCTION_REQUEST.code}.success.noop" - protected final static String UPDATE_METRIC = "modules.module.${PB_RULE_ENGINE.code}.stage.${PROCESSED_AUCTION_REQUEST.metricValue}.hook.${PB_RULES_ENGINE_PROCESSED_AUCTION_REQUEST.code}.success.update" protected final static Closure INVALID_CONFIGURATION_FOR_STRINGS_LOG_WARNING = { accountId, functionType -> "Failed to parse rule-engine config for account $accountId: " + "Function '$functionType' configuration is invalid: " + diff --git a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineContextSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineContextSpec.groovy similarity index 99% rename from src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineContextSpec.groovy rename to src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineContextSpec.groovy index 5bea040218e..02820762c87 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineContextSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineContextSpec.groovy @@ -16,7 +16,7 @@ import org.prebid.server.functional.util.PBSUtils import java.time.Instant import static org.prebid.server.functional.model.ChannelType.WEB -import static org.prebid.server.functional.model.ModuleName.PB_RULE_ENGINE +import static org.prebid.server.functional.model.config.ModuleName.PB_RULE_ENGINE import static org.prebid.server.functional.model.bidder.BidderName.AMX import static org.prebid.server.functional.model.bidder.BidderName.GENERIC import static org.prebid.server.functional.model.bidder.BidderName.OPENX @@ -40,7 +40,7 @@ import static org.prebid.server.functional.model.request.auction.ImpUnitCode.STO import static org.prebid.server.functional.model.request.auction.ImpUnitCode.TAG_ID import static org.prebid.server.functional.model.response.auction.BidRejectionReason.REQUEST_BIDDER_REMOVED_BY_RULE_ENGINE_MODULE -class RuleEngineContextSpec extends RuleEngineBaseSpec { +class PbRuleEngineContextSpec extends PbRuleEngineBaseSpec { def "PBS should exclude bidder when channel match with condition"() { given: "Bid request with multiply bidders" diff --git a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineCoreSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineCoreSpec.groovy similarity index 99% rename from src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineCoreSpec.groovy rename to src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineCoreSpec.groovy index 8e9de1807c9..ab986d3bc3a 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineCoreSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineCoreSpec.groovy @@ -1,5 +1,6 @@ package org.prebid.server.functional.tests.module.pbruleengine + import org.prebid.server.functional.model.config.RuleEngineModelDefault import org.prebid.server.functional.model.config.RuleEngineModelDefaultArgs import org.prebid.server.functional.model.config.RuleSet @@ -8,7 +9,7 @@ import org.prebid.server.functional.model.config.Stage import org.prebid.server.functional.model.request.auction.Imp import org.prebid.server.functional.util.PBSUtils -import static org.prebid.server.functional.model.ModuleName.PB_RULE_ENGINE +import static org.prebid.server.functional.model.config.ModuleName.PB_RULE_ENGINE import static org.prebid.server.functional.model.bidder.BidderName.AMX import static org.prebid.server.functional.model.bidder.BidderName.GENERIC import static org.prebid.server.functional.model.bidder.BidderName.OPENX @@ -25,7 +26,7 @@ import static org.prebid.server.functional.model.request.auction.TraceLevel.VERB import static org.prebid.server.functional.model.response.auction.BidRejectionReason.ERROR_NO_BID import static org.prebid.server.functional.model.response.auction.BidRejectionReason.REQUEST_BIDDER_REMOVED_BY_RULE_ENGINE_MODULE -class RuleEngineCoreSpec extends RuleEngineBaseSpec { +class PbRuleEngineCoreSpec extends PbRuleEngineBaseSpec { def "PBS should remove bidder and not update analytics when bidder matched with conditions and without analytics key"() { given: "Bid request with multiply bidders" @@ -64,8 +65,8 @@ class RuleEngineCoreSpec extends RuleEngineBaseSpec { and: "PBs should populate call and update metrics" def metrics = pbsServiceWithRulesEngineModule.sendCollectedMetricsRequest() - assert metrics[CALL_METRIC] == 1 - assert metrics[UPDATE_METRIC] == 1 + assert metrics[CALL_METRIC(PB_RULE_ENGINE, PROCESSED_AUCTION_REQUEST)] == 1 + assert metrics[UPDATE_METRIC(PB_RULE_ENGINE, PROCESSED_AUCTION_REQUEST)] == 1 and: "Response should seatNon bid with code 203" assert bidResponse.ext.seatnonbid.size() == 1 diff --git a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineDeviceSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineDeviceSpec.groovy similarity index 99% rename from src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineDeviceSpec.groovy rename to src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineDeviceSpec.groovy index 229e54a0ff0..fabcab27548 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineDeviceSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineDeviceSpec.groovy @@ -6,11 +6,10 @@ import org.prebid.server.functional.model.pricefloors.Country import org.prebid.server.functional.model.request.auction.Device import org.prebid.server.functional.model.request.auction.DeviceType import org.prebid.server.functional.util.PBSUtils -import spock.lang.RepeatUntilFailure import java.time.Instant -import static org.prebid.server.functional.model.ModuleName.PB_RULE_ENGINE +import static org.prebid.server.functional.model.config.ModuleName.PB_RULE_ENGINE import static org.prebid.server.functional.model.bidder.BidderName.AMX import static org.prebid.server.functional.model.bidder.BidderName.GENERIC import static org.prebid.server.functional.model.bidder.BidderName.OPENX @@ -23,7 +22,7 @@ import static org.prebid.server.functional.model.pricefloors.Country.USA import static org.prebid.server.functional.model.request.auction.FetchStatus.SUCCESS import static org.prebid.server.functional.model.response.auction.BidRejectionReason.REQUEST_BIDDER_REMOVED_BY_RULE_ENGINE_MODULE -class RuleEngineDeviceSpec extends RuleEngineBaseSpec { +class PbRuleEngineDeviceSpec extends PbRuleEngineBaseSpec { def "PBS should exclude bidder when deviceCountry match with condition"() { given: "Bid request with multiply bidders" diff --git a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineInfrastructureSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineInfrastructureSpec.groovy similarity index 98% rename from src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineInfrastructureSpec.groovy rename to src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineInfrastructureSpec.groovy index f710ba39f93..ba125f07a3a 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineInfrastructureSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineInfrastructureSpec.groovy @@ -6,7 +6,7 @@ import org.prebid.server.functional.util.PBSUtils import java.time.Instant -import static org.prebid.server.functional.model.ModuleName.PB_RULE_ENGINE +import static org.prebid.server.functional.model.config.ModuleName.PB_RULE_ENGINE import static org.prebid.server.functional.model.bidder.BidderName.AMX import static org.prebid.server.functional.model.bidder.BidderName.GENERIC import static org.prebid.server.functional.model.bidder.BidderName.OPENX @@ -16,7 +16,7 @@ import static org.prebid.server.functional.model.config.RuleEngineFunction.DATA_ import static org.prebid.server.functional.model.request.auction.FetchStatus.SUCCESS import static org.prebid.server.functional.model.response.auction.BidRejectionReason.REQUEST_BIDDER_REMOVED_BY_RULE_ENGINE_MODULE -class RuleEngineInfrastructureSpec extends RuleEngineBaseSpec { +class PbRuleEngineInfrastructureSpec extends PbRuleEngineBaseSpec { def "PBS should reject processing rule engine when dataCenterIn schema function args contain invalid data"() { given: "Test start time" diff --git a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEnginePrivacySpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEnginePrivacySpec.groovy similarity index 99% rename from src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEnginePrivacySpec.groovy rename to src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEnginePrivacySpec.groovy index 578d88b2130..25804dc614e 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEnginePrivacySpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEnginePrivacySpec.groovy @@ -19,7 +19,7 @@ import org.prebid.server.functional.util.privacy.TcfConsent import java.time.Instant -import static org.prebid.server.functional.model.ModuleName.PB_RULE_ENGINE +import static org.prebid.server.functional.model.config.ModuleName.PB_RULE_ENGINE import static org.prebid.server.functional.model.bidder.BidderName.AMX import static org.prebid.server.functional.model.bidder.BidderName.GENERIC import static org.prebid.server.functional.model.bidder.BidderName.OPENX @@ -37,7 +37,7 @@ import static org.prebid.server.functional.model.response.auction.BidRejectionRe import static org.prebid.server.functional.util.privacy.TcfConsent.GENERIC_VENDOR_ID import static org.prebid.server.functional.util.privacy.TcfConsent.PurposeId.BASIC_ADS -class RuleEnginePrivacySpec extends RuleEngineBaseSpec { +class PbRuleEnginePrivacySpec extends PbRuleEngineBaseSpec { def "PBS should exclude bidder when eidAvailable match with condition"() { given: "Bid request with multiply bidders" diff --git a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineSpecialSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineSpecialSpec.groovy similarity index 98% rename from src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineSpecialSpec.groovy rename to src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineSpecialSpec.groovy index cce9631e1b9..8d9a53d13f0 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineSpecialSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineSpecialSpec.groovy @@ -5,7 +5,7 @@ import org.prebid.server.functional.util.PBSUtils import java.time.Instant -import static org.prebid.server.functional.model.ModuleName.PB_RULE_ENGINE +import static org.prebid.server.functional.model.config.ModuleName.PB_RULE_ENGINE import static org.prebid.server.functional.model.bidder.BidderName.AMX import static org.prebid.server.functional.model.bidder.BidderName.GENERIC import static org.prebid.server.functional.model.bidder.BidderName.OPENX @@ -15,7 +15,7 @@ import static org.prebid.server.functional.model.config.RuleEngineFunction.PREBI import static org.prebid.server.functional.model.request.auction.FetchStatus.SUCCESS import static org.prebid.server.functional.model.response.auction.BidRejectionReason.REQUEST_BIDDER_REMOVED_BY_RULE_ENGINE_MODULE -class RuleEngineSpecialSpec extends RuleEngineBaseSpec { +class PbRuleEngineSpecialSpec extends PbRuleEngineBaseSpec { def "PBS should reject processing rule engine when percent schema function args contain invalid data"() { given: "Test start time" diff --git a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineSyncSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineSyncSpec.groovy similarity index 98% rename from src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineSyncSpec.groovy rename to src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineSyncSpec.groovy index 881a8211ca4..3128e047aae 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineSyncSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineSyncSpec.groovy @@ -3,7 +3,7 @@ package org.prebid.server.functional.tests.module.pbruleengine import org.prebid.server.functional.model.UidsCookie import org.prebid.server.functional.util.HttpUtil -import static org.prebid.server.functional.model.ModuleName.PB_RULE_ENGINE +import static org.prebid.server.functional.model.config.ModuleName.PB_RULE_ENGINE import static org.prebid.server.functional.model.bidder.BidderName.AMX import static org.prebid.server.functional.model.bidder.BidderName.GENERIC import static org.prebid.server.functional.model.bidder.BidderName.OPENX @@ -13,7 +13,7 @@ import static org.prebid.server.functional.model.config.RuleEngineModelRuleResul import static org.prebid.server.functional.model.request.auction.FetchStatus.SUCCESS import static org.prebid.server.functional.model.response.auction.BidRejectionReason.REQUEST_BIDDER_REMOVED_BY_RULE_ENGINE_MODULE -class RuleEngineSyncSpec extends RuleEngineBaseSpec { +class PbRuleEngineSyncSpec extends PbRuleEngineBaseSpec { def "PBS should remove bidder from imps when bidder has ID in the uids cookie and bidder excluded and ifSyncedId=true in account config"() { given: "Bid request with multiply bidders" diff --git a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineValidationSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineValidationSpec.groovy similarity index 96% rename from src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineValidationSpec.groovy rename to src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineValidationSpec.groovy index dbf7395c1f0..d43a5114f5d 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/RuleEngineValidationSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/module/pbruleengine/PbRuleEngineValidationSpec.groovy @@ -5,6 +5,7 @@ import org.prebid.server.functional.util.PBSUtils import java.time.Instant +import static org.prebid.server.functional.model.config.ModuleName.PB_RULE_ENGINE import static org.prebid.server.functional.model.config.PbRulesEngine.createRulesEngineWithRule import static org.prebid.server.functional.model.config.RuleEngineFunction.AD_UNIT_CODE import static org.prebid.server.functional.model.config.RuleEngineFunction.BUNDLE @@ -17,9 +18,10 @@ import static org.prebid.server.functional.model.config.RuleEngineFunction.FPD_A import static org.prebid.server.functional.model.config.RuleEngineFunction.GPP_SID_AVAILABLE import static org.prebid.server.functional.model.config.RuleEngineFunction.TCF_IN_SCOPE import static org.prebid.server.functional.model.config.RuleEngineFunction.USER_FPD_AVAILABLE +import static org.prebid.server.functional.model.config.Stage.PROCESSED_AUCTION_REQUEST import static org.prebid.server.functional.model.pricefloors.Country.BULGARIA -class RuleEngineValidationSpec extends RuleEngineBaseSpec { +class PbRuleEngineValidationSpec extends PbRuleEngineBaseSpec { def "PBS shouldn't remove bidder when rule engine not fully configured in account"() { given: "Bid request with multiply bidders" @@ -58,11 +60,11 @@ class RuleEngineValidationSpec extends RuleEngineBaseSpec { and: "PBs should populate call and noop metrics" def metrics = pbsServiceWithRulesEngineModule.sendCollectedMetricsRequest() - assert metrics[CALL_METRIC] == 1 - assert metrics[NOOP_METRIC] == 1 + assert metrics[CALL_METRIC(PB_RULE_ENGINE, PROCESSED_AUCTION_REQUEST)] == 1 + assert metrics[NOOP_METRIC(PB_RULE_ENGINE,PROCESSED_AUCTION_REQUEST)] == 1 and: "PBs should populate update metrics" - assert !metrics[UPDATE_METRIC] + assert !metrics[UPDATE_METRIC(PB_RULE_ENGINE,PROCESSED_AUCTION_REQUEST)] where: pbRulesEngine << [ @@ -112,7 +114,7 @@ class RuleEngineValidationSpec extends RuleEngineBaseSpec { and: "PBs should populate noop metrics" def metrics = pbsServiceWithRulesEngineModule.sendCollectedMetricsRequest() - assert metrics[NOOP_METRIC] == 1 + assert metrics[NOOP_METRIC(PB_RULE_ENGINE,PROCESSED_AUCTION_REQUEST)] == 1 } def "PBS shouldn't remove bidder and emit a warning when args rule engine not fully configured in account"() { @@ -150,7 +152,7 @@ class RuleEngineValidationSpec extends RuleEngineBaseSpec { and: "PBs should populate failer metrics" def metrics = pbsServiceWithRulesEngineModule.sendCollectedMetricsRequest() - assert metrics[NOOP_METRIC] == 1 + assert metrics[NOOP_METRIC(PB_RULE_ENGINE,PROCESSED_AUCTION_REQUEST)] == 1 } def "PBS shouldn't remove bidder and emit a warning when model group rule engine not fully configured in account"() { diff --git a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java index 85e2570bfe6..28413d6d9fd 100644 --- a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java +++ b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java @@ -164,8 +164,8 @@ private AuctionEvent buildEvent(Boolean isEnriched) { } private AuctionEvent buildEvent(Boolean isEnriched, Boolean withTags) { - final HookId hookId = HookId.of("liveintent-omni-channel-identity-enrichment-hook", - "liveintent-omni-channel-identity-enrichment-hook"); + final HookId hookId = HookId.of("liveintent-omni-channel-identity-processed-auction-request-hook", + "liveintent-omni-channel-identity-processed-auction-request-hook"); final ObjectNode treatmentRateNode = ObjectMapperProvider.mapper().createObjectNode().put("treatmentRate", 0.5f); From 0e6584ff17ca1bb56feec58c93445a9e4c4cda33 Mon Sep 17 00:00:00 2001 From: Viktor Kryshtal <33136089+Lightwood13@users.noreply.github.com> Date: Thu, 23 Jul 2026 22:14:55 +0300 Subject: [PATCH 8/8] Fix VendorListFileStoreTest (#4575) --- .../vendorlist/VendorListFileStoreTest.java | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListFileStoreTest.java b/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListFileStoreTest.java index dea4c1ce67c..e69ede0e836 100644 --- a/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListFileStoreTest.java +++ b/src/test/java/org/prebid/server/privacy/gdpr/vendorlist/VendorListFileStoreTest.java @@ -9,9 +9,9 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.io.TempDir; import org.mockito.ArgumentCaptor; import org.mockito.Mock; +import org.mockito.MockedStatic; import org.mockito.junit.jupiter.MockitoExtension; import org.prebid.server.VertxTest; import org.prebid.server.exception.PreBidException; @@ -23,7 +23,8 @@ import org.prebid.server.privacy.gdpr.vendorlist.proto.VendorList; import java.io.File; -import java.nio.file.Path; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Date; import java.util.EnumSet; import java.util.List; @@ -40,6 +41,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.prebid.server.privacy.gdpr.vendorlist.proto.PurposeCode.ONE; @@ -55,9 +57,6 @@ public class VendorListFileStoreTest extends VertxTest { @Mock private FileSystem fileSystem; - @TempDir - private Path tempDir; - private VendorListFileStore target; @BeforeEach @@ -110,31 +109,37 @@ public void createCacheFromDiskShouldFailIfCannotCreateCacheDir() { @Test public void createCacheFromDiskShouldFailIfCacheDirIsNotWritable() { // given - final String cacheDir = tempDir.toString(); - tempDir.toFile().setWritable(false, false); final FileProps fileProps = mock(FileProps.class); - given(fileSystem.existsBlocking(eq(cacheDir))).willReturn(true); - given(fileSystem.propsBlocking(eq(cacheDir))).willReturn(fileProps); + given(fileSystem.existsBlocking(eq(CACHE_DIR))).willReturn(true); + given(fileSystem.propsBlocking(eq(CACHE_DIR))).willReturn(fileProps); given(fileProps.isDirectory()).willReturn(true); - // when and then - assertThatThrownBy(() -> target.createCacheFromDisk(cacheDir)) - .isInstanceOf(PreBidException.class) - .hasMessage("No write permissions for directory: " + cacheDir); + try (MockedStatic filesMock = mockStatic(Files.class)) { + filesMock.when(() -> Files.isWritable(eq(Paths.get(CACHE_DIR)))).thenReturn(false); + + // when and then + assertThatThrownBy(() -> target.createCacheFromDisk(CACHE_DIR)) + .isInstanceOf(PreBidException.class) + .hasMessage("No write permissions for directory: " + CACHE_DIR); + } + } @Test - public void createCacheFromDiskShouldNotFailIfCacheDirIsWriable() { + public void createCacheFromDiskShouldNotFailIfCacheDirExistsAndIsWritable() { // given - final String cacheDir = tempDir.toString(); - tempDir.toFile().setWritable(true, false); final FileProps fileProps = mock(FileProps.class); - given(fileSystem.existsBlocking(eq(cacheDir))).willReturn(true); - given(fileSystem.propsBlocking(eq(cacheDir))).willReturn(fileProps); + given(fileSystem.existsBlocking(eq(CACHE_DIR))).willReturn(true); + given(fileSystem.propsBlocking(eq(CACHE_DIR))).willReturn(fileProps); given(fileProps.isDirectory()).willReturn(true); - // when and then - assertDoesNotThrow(() -> target.createCacheFromDisk(cacheDir)); + try (MockedStatic filesMock = mockStatic(Files.class)) { + filesMock.when(() -> Files.isWritable(eq(Paths.get(CACHE_DIR)))).thenReturn(true); + + // when and then + assertDoesNotThrow(() -> target.createCacheFromDisk(CACHE_DIR)); + } + } @Test