diff --git a/extra/modules/greenbids-real-time-data/src/main/java/org/prebid/server/hooks/modules/greenbids/real/time/data/core/GreenbidsInvocationService.java b/extra/modules/greenbids-real-time-data/src/main/java/org/prebid/server/hooks/modules/greenbids/real/time/data/core/GreenbidsInvocationService.java index 47da698c627..f7a067c731d 100644 --- a/extra/modules/greenbids-real-time-data/src/main/java/org/prebid/server/hooks/modules/greenbids/real/time/data/core/GreenbidsInvocationService.java +++ b/extra/modules/greenbids-real-time-data/src/main/java/org/prebid/server/hooks/modules/greenbids/real/time/data/core/GreenbidsInvocationService.java @@ -40,13 +40,10 @@ public GreenbidsInvocationResult createGreenbidsInvocationResult( final InvocationAction invocationAction = isExploration ? InvocationAction.no_action : InvocationAction.update; - final Map> impsBiddersFilterMapToAnalyticsTag = isExploration - ? keepAllBiddersForAnalyticsResult(impsBiddersFilterMap) - : impsBiddersFilterMap; final Map ort2ImpExtResultMap = createOrtb2ImpExtForImps( - bidRequest, impsBiddersFilterMapToAnalyticsTag, greenbidsId, isExploration); + bidRequest, impsBiddersFilterMap, greenbidsId, isExploration); final AnalyticsResult analyticsResult = AnalyticsResult.of( - "success", ort2ImpExtResultMap, null, null); + "success", ort2ImpExtResultMap); return GreenbidsInvocationResult.of(updatedBidRequest, invocationAction, analyticsResult); } @@ -83,16 +80,6 @@ private ObjectNode updateImpExt(ObjectNode impExt, Map bidderFi return updatedExt; } - private Map> keepAllBiddersForAnalyticsResult( - Map> impsBiddersFilterMap) { - - return impsBiddersFilterMap.entrySet().stream() - .collect(Collectors.toMap( - Map.Entry::getKey, - entry -> entry.getValue().entrySet().stream() - .collect(Collectors.toMap(Map.Entry::getKey, e -> true)))); - } - private Map createOrtb2ImpExtForImps( BidRequest bidRequest, Map> impsBiddersFilterMap, diff --git a/extra/modules/greenbids-real-time-data/src/main/java/org/prebid/server/hooks/modules/greenbids/real/time/data/model/result/AnalyticsResult.java b/extra/modules/greenbids-real-time-data/src/main/java/org/prebid/server/hooks/modules/greenbids/real/time/data/model/result/AnalyticsResult.java index 9d175b5b4b3..f324ac195db 100644 --- a/extra/modules/greenbids-real-time-data/src/main/java/org/prebid/server/hooks/modules/greenbids/real/time/data/model/result/AnalyticsResult.java +++ b/extra/modules/greenbids-real-time-data/src/main/java/org/prebid/server/hooks/modules/greenbids/real/time/data/model/result/AnalyticsResult.java @@ -11,8 +11,4 @@ public class AnalyticsResult { String status; Map values; - - String bidder; - - String impId; } 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 5188b756ddc..3ad8106e141 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 @@ -7,6 +7,8 @@ import com.iab.openrtb.request.BidRequest; import io.vertx.core.Future; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; +import org.prebid.server.analytics.reporter.greenbids.model.ExplorationResult; import org.prebid.server.analytics.reporter.greenbids.model.Ortb2ImpExtResult; import org.prebid.server.auction.model.AuctionContext; import org.prebid.server.exception.PreBidException; @@ -38,6 +40,7 @@ import org.prebid.server.settings.model.Account; import org.prebid.server.settings.model.AccountHooksConfiguration; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; @@ -155,29 +158,25 @@ private InvocationResult toInvocationResult( AnalyticsResult analyticsResult, InvocationAction action) { - final List analyticsResults = analyticsResult != null - ? Collections.singletonList(analyticsResult) - : Collections.emptyList(); - return switch (action) { case InvocationAction.update -> InvocationResultImpl .builder() .status(InvocationStatus.success) .action(action) .payloadUpdate(payload -> AuctionRequestPayloadImpl.of(bidRequest)) - .analyticsTags(toAnalyticsTags(analyticsResults)) + .analyticsTags(toAnalyticsTags(analyticsResult)) .build(); default -> InvocationResultImpl .builder() .status(InvocationStatus.success) .action(action) - .analyticsTags(toAnalyticsTags(analyticsResults)) + .analyticsTags(toAnalyticsTags(analyticsResult)) .build(); }; } - private Tags toAnalyticsTags(List analyticsResults) { - if (CollectionUtils.isEmpty(analyticsResults)) { + private Tags toAnalyticsTags(AnalyticsResult analyticsResults) { + if (analyticsResults == null) { return null; } @@ -187,23 +186,35 @@ private Tags toAnalyticsTags(List analyticsResults) { toResults(analyticsResults)))); } - private List toResults(List analyticsResults) { - return analyticsResults.stream() - .map(this::toResult) + private List toResults(AnalyticsResult analyticsResult) { + return analyticsResult.getValues().entrySet().stream() + .map(entry -> toResult(analyticsResult.getStatus(), entry)) .toList(); } - private Result toResult(AnalyticsResult analyticsResult) { + private Result toResult(String status, Map.Entry entry) { + final String impId = entry.getKey(); + final Ortb2ImpExtResult ortb2ImpExtResult = entry.getValue(); + final List removedBidders = Optional.ofNullable(ortb2ImpExtResult) + .map(Ortb2ImpExtResult::getGreenbids) + .map(ExplorationResult::getKeptInAuction) + .map(Map::entrySet) + .stream() + .flatMap(Collection::stream) + .filter(e -> BooleanUtils.isFalse(e.getValue())) + .map(Map.Entry::getKey) + .toList(); + return ResultImpl.of( - analyticsResult.getStatus(), - toObjectNode(analyticsResult.getValues()), + status, + toObjectNode(entry), AppliedToImpl.builder() - .bidders(Collections.singletonList(analyticsResult.getBidder())) - .impIds(Collections.singletonList(analyticsResult.getImpId())) + .impIds(Collections.singletonList(impId)) + .bidders(removedBidders.isEmpty() ? null: removedBidders) .build()); } - private ObjectNode toObjectNode(Map values) { + private ObjectNode toObjectNode(Map.Entry values) { return values != null ? mapper.valueToTree(values) : null; } diff --git a/extra/modules/greenbids-real-time-data/src/test/java/org/prebid/server/hooks/modules/greenbids/real/time/data/core/GreenbidsInvocationServiceTest.java b/extra/modules/greenbids-real-time-data/src/test/java/org/prebid/server/hooks/modules/greenbids/real/time/data/core/GreenbidsInvocationServiceTest.java index 8af8b6e2a03..c46d46c6b50 100644 --- a/extra/modules/greenbids-real-time-data/src/test/java/org/prebid/server/hooks/modules/greenbids/real/time/data/core/GreenbidsInvocationServiceTest.java +++ b/extra/modules/greenbids-real-time-data/src/test/java/org/prebid/server/hooks/modules/greenbids/real/time/data/core/GreenbidsInvocationServiceTest.java @@ -104,8 +104,8 @@ public void createGreenbidsInvocationResultShouldReturnNoActionWhenExploration() assertThat(ortb2ImpExtResult.getGreenbids().getIsExploration()).isTrue(); assertThat(ortb2ImpExtResult.getGreenbids().getFingerprint()).isNotNull(); assertThat(keptInAuction.get("rubicon")).isTrue(); - assertThat(keptInAuction.get("appnexus")).isTrue(); - assertThat(keptInAuction.get("pubmatic")).isTrue(); + assertThat(keptInAuction.get("appnexus")).isFalse(); + assertThat(keptInAuction.get("pubmatic")).isFalse(); } private Map> givenImpsBiddersFilterMap() { diff --git a/extra/modules/greenbids-real-time-data/src/test/java/org/prebid/server/hooks/modules/greenbids/real/time/data/v1/GreenbidsRealTimeDataProcessedAuctionRequestHookTest.java b/extra/modules/greenbids-real-time-data/src/test/java/org/prebid/server/hooks/modules/greenbids/real/time/data/v1/GreenbidsRealTimeDataProcessedAuctionRequestHookTest.java index 07f13d519f4..36e9300d83e 100644 --- a/extra/modules/greenbids-real-time-data/src/test/java/org/prebid/server/hooks/modules/greenbids/real/time/data/v1/GreenbidsRealTimeDataProcessedAuctionRequestHookTest.java +++ b/extra/modules/greenbids-real-time-data/src/test/java/org/prebid/server/hooks/modules/greenbids/real/time/data/v1/GreenbidsRealTimeDataProcessedAuctionRequestHookTest.java @@ -52,8 +52,6 @@ import org.prebid.server.hooks.v1.auction.AuctionInvocationContext; import org.prebid.server.hooks.v1.auction.AuctionRequestPayload; import org.prebid.server.model.HttpRequestContext; -import org.prebid.server.settings.model.Account; -import org.prebid.server.settings.model.AccountHooksConfiguration; import java.io.IOException; import java.net.InetAddress; @@ -216,7 +214,7 @@ public void callShouldFilterBiddersWhenPartnerActivatedInBidRequest() } @Test - public void callShouldNotFilterBiddersAndReturnAnalyticsTagWhenExploration() throws OrtException, IOException { + public void callShouldFilterBiddersAndReturnAnalyticsTagWhenExploration() throws OrtException, IOException { // given final Banner banner = givenBanner(); @@ -238,7 +236,7 @@ public void callShouldNotFilterBiddersAndReturnAnalyticsTagWhenExploration() thr when(thresholdsCacheWithExpiration.getIfPresent("throttlingThresholds_test-pbuid")) .thenReturn(givenThrottlingThresholds()); - final AnalyticsResult expectedAnalyticsResult = expectedAnalyticsResult(true, true); + final AnalyticsResult expectedAnalyticsResult = expectedAnalyticsResult(true, false); // when final Future> future = target @@ -471,9 +469,7 @@ private BidRequest expectedUpdatedBidRequest( private AnalyticsResult expectedAnalyticsResult(Boolean isExploration, Boolean isKeptInAuction) { return AnalyticsResult.of( "success", - Map.of("adunitcodevalue", expectedOrtb2ImpExtResult(isExploration, isKeptInAuction)), - null, - null); + Map.of("adunitcodevalue", expectedOrtb2ImpExtResult(isExploration, isKeptInAuction))); } private Ortb2ImpExtResult expectedOrtb2ImpExtResult(Boolean isExploration, Boolean isKeptInAuction) { @@ -507,8 +503,8 @@ private Result toResult(AnalyticsResult analyticsResult) { analyticsResult.getStatus(), toObjectNode(analyticsResult.getValues()), AppliedToImpl.builder() - .bidders(Collections.singletonList(analyticsResult.getBidder())) - .impIds(Collections.singletonList(analyticsResult.getImpId())) + .impIds(Collections.singletonList("adunitcodevalue")) + .bidders(List.of("appnexus", "pubmatic", "rubicon")) .build()); } diff --git a/src/main/java/org/prebid/server/analytics/reporter/greenbids/GreenbidsAnalyticsReporter.java b/src/main/java/org/prebid/server/analytics/reporter/greenbids/GreenbidsAnalyticsReporter.java index d4b0a4f8711..f8326efb81f 100644 --- a/src/main/java/org/prebid/server/analytics/reporter/greenbids/GreenbidsAnalyticsReporter.java +++ b/src/main/java/org/prebid/server/analytics/reporter/greenbids/GreenbidsAnalyticsReporter.java @@ -58,6 +58,7 @@ import org.prebid.server.settings.model.Account; import org.prebid.server.settings.model.AccountAnalyticsConfig; import org.prebid.server.util.HttpUtil; +import org.prebid.server.util.StreamUtil; import org.prebid.server.version.PrebidVersionProvider; import org.prebid.server.vertx.httpclient.HttpClient; import org.prebid.server.vertx.httpclient.model.HttpClientResponse; @@ -65,8 +66,6 @@ import java.time.Clock; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; @@ -229,8 +228,7 @@ private Map extractAnalyticsResultFromAnalyticsTag(Au .flatMap(Collection::stream) .filter(activity -> "greenbids-filter".equals(activity.name())) .map(Activity::results) - .map(List::getFirst) - .map(Result::values) + .flatMap(Collection::stream) .map(this::parseAnalyticsResult) .flatMap(map -> map.entrySet().stream()) .collect(Collectors.toMap( @@ -239,21 +237,20 @@ private Map extractAnalyticsResultFromAnalyticsTag(Au (existing, replacement) -> existing)); } - private Map parseAnalyticsResult(ObjectNode analyticsResult) { + private Map parseAnalyticsResult(Result result) { + return Optional.ofNullable(result) + .map(Result::values) + .stream() + .flatMap(valuesNode -> StreamUtil.asStream(valuesNode.fields())) + .collect(Collectors.toMap( + Map.Entry::getKey, + entry -> parseOrtb2ImpExtResult(entry.getValue()), + (existing, replacement) -> existing)); + } + + private Ortb2ImpExtResult parseOrtb2ImpExtResult(JsonNode node) { try { - final Map parsedAnalyticsResult = new HashMap<>(); - final Iterator> fields = analyticsResult.fields(); - - while (fields.hasNext()) { - final Map.Entry field = fields.next(); - final String impId = field.getKey(); - final JsonNode explorationResultNode = field.getValue(); - final Ortb2ImpExtResult ortb2ImpExtResult = jacksonMapper.mapper() - .treeToValue(explorationResultNode, Ortb2ImpExtResult.class); - parsedAnalyticsResult.put(impId, ortb2ImpExtResult); - } - - return parsedAnalyticsResult; + return jacksonMapper.mapper().treeToValue(node, Ortb2ImpExtResult.class); } catch (JsonProcessingException e) { throw new PreBidException("Analytics result parsing error", e); } diff --git a/src/test/java/org/prebid/server/analytics/reporter/greenbids/GreenbidsAnalyticsReporterTest.java b/src/test/java/org/prebid/server/analytics/reporter/greenbids/GreenbidsAnalyticsReporterTest.java index 82cae87406e..4683dc5370e 100644 --- a/src/test/java/org/prebid/server/analytics/reporter/greenbids/GreenbidsAnalyticsReporterTest.java +++ b/src/test/java/org/prebid/server/analytics/reporter/greenbids/GreenbidsAnalyticsReporterTest.java @@ -47,8 +47,10 @@ import org.prebid.server.hooks.execution.model.Stage; import org.prebid.server.hooks.execution.model.StageExecutionOutcome; import org.prebid.server.hooks.execution.v1.analytics.ActivityImpl; +import org.prebid.server.hooks.execution.v1.analytics.AppliedToImpl; import org.prebid.server.hooks.execution.v1.analytics.ResultImpl; import org.prebid.server.hooks.execution.v1.analytics.TagsImpl; +import org.prebid.server.hooks.v1.analytics.AppliedTo; import org.prebid.server.json.EncodeException; import org.prebid.server.json.JacksonMapper; import org.prebid.server.model.HttpRequestContext; @@ -733,11 +735,16 @@ private static HookExecutionContext givenHookExecutionContextWithAnalyticsTag() "adunitcodevalue", createAnalyticsResultNode())); + final AppliedTo appliedTo = AppliedToImpl.builder() + .impIds(Collections.singletonList("adunitcodevalue")) + .bidders(Collections.singletonList("seat1")) + .build(); + final ActivityImpl activity = ActivityImpl.of( "greenbids-filter", "success", Collections.singletonList( - ResultImpl.of("success", analyticsResultNode, null))); + ResultImpl.of("success", analyticsResultNode, appliedTo))); final TagsImpl tags = TagsImpl.of(Collections.singletonList(activity));