From 6ef0cabb60bc5248e573eccf7e2235fdd18bfeb3 Mon Sep 17 00:00:00 2001 From: Dubyk Danylo <45672370+CTMBNara@users.noreply.github.com> Date: Tue, 14 Nov 2023 12:01:18 +0200 Subject: [PATCH] Core: Activity Infrastructure: Add trace log (#2568) --- ...ConfiantAdQualityBidResponsesScanHook.java | 12 +- .../infrastructure/ActivityCallResult.java | 11 - .../infrastructure/ActivityController.java | 21 +- .../ActivityInfrastructure.java | 52 +-- .../ActivityInfrastructureCreator.java | 48 ++- .../USCustomLogicModuleCreator.java | 5 +- .../privacy/usnat/USNatModuleCreator.java | 5 +- .../debug/ActivityDebugUtils.java | 29 ++ .../debug/ActivityInfrastructureDebug.java | 101 +++++ .../infrastructure/debug/Loggable.java | 9 + ...ad.java => ActivityInvocationPayload.java} | 5 +- .../payload/GeoActivityCallPayload.java | 8 - .../payload/GeoActivityInvocationPayload.java | 12 + .../payload/GpcActivityCallPayload.java | 6 - .../payload/GpcActivityInvocationPayload.java | 9 + ...ava => ActivityInvocationPayloadImpl.java} | 4 +- ... BidRequestActivityInvocationPayload.java} | 10 +- ...mentServiceActivityInvocationPayload.java} | 14 +- ... TcfContextActivityInvocationPayload.java} | 8 +- .../privacy/AndPrivacyModules.java | 29 ++ .../uscustomlogic/USCustomLogicModule.java | 18 +- .../privacy/usnat/USNatModule.java | 17 +- .../usnat/debug/USNatModuleLogEntry.java | 27 ++ .../privacy/usnat/inner/USNatDefault.java | 20 +- .../privacy/usnat/inner/USNatSyncUser.java | 18 +- .../privacy/usnat/inner/USNatTransmitGeo.java | 18 +- .../usnat/inner/USNatTransmitUfpd.java | 18 +- .../rule/AbstractMatchRule.java | 8 +- .../activity/infrastructure/rule/AndRule.java | 23 +- .../infrastructure/rule/ComponentRule.java | 23 +- .../activity/infrastructure/rule/GeoRule.java | 57 ++- .../activity/infrastructure/rule/Rule.java | 4 +- .../reporter/AnalyticsReporterDelegator.java | 42 +- .../server/auction/BidResponseCreator.java | 40 +- .../server/auction/ExchangeService.java | 36 +- .../auction/PrivacyEnforcementService.java | 27 +- .../requestfactory/Ortb2RequestFactory.java | 2 +- .../server/cookie/CookieSyncService.java | 8 +- .../server/handler/CookieSyncHandler.java | 2 +- .../handler/NotificationEventHandler.java | 3 +- .../prebid/server/handler/SetuidHandler.java | 15 +- .../org/prebid/server/metric/Metrics.java | 8 +- .../openrtb/ext/response/ExtDebugTrace.java | 2 + .../ExtTraceActivityInfrastructure.java | 13 + .../response/ExtTraceActivityInvocation.java | 15 + ...tTraceActivityInvocationDefaultResult.java | 11 + .../ExtTraceActivityInvocationResult.java | 14 + .../ext/response/ExtTraceActivityRule.java | 15 + .../ActivityInfrastructureConfiguration.java | 6 +- .../functional/model/response/Debug.groovy | 2 + .../auction/ActivityInfrastructure.groovy | 23 ++ .../auction/ActivityInvocationPayload.groovy | 18 + .../model/response/auction/And.groovy | 11 + .../model/response/auction/GeoCode.groovy | 12 + .../response/auction/RuleConfiguration.groovy | 22 + .../model/response/auction/Trace.groovy | 12 + .../tests/privacy/ActivityTraceLogSpec.groovy | 388 ++++++++++++++++++ .../ActivityControllerTest.java | 59 ++- .../ActivityInfrastructureTest.java | 111 ++--- .../ActivityInfrastructureCreatorTest.java | 37 +- .../rule/ComponentRuleCreatorTest.java | 4 +- .../creator/rule/GeoRuleCreatorTest.java | 22 +- .../debug/ActivityDebugUtilsTest.java | 73 ++++ .../ActivityInfrastructureDebugTest.java | 252 ++++++++++++ .../privacy/TestPrivacyModule.java | 4 +- .../USCustomLogicModuleTest.java | 23 +- .../privacy/usnat/USNatModuleTest.java | 34 ++ .../usnat/debug/USNatModuleLogEntryTest.java | 52 +++ .../privacy/usnat/inner/USNatDefaultTest.java | 2 +- .../infrastructure/rule/AndRuleTest.java | 22 +- .../rule/ComponentRuleTest.java | 37 +- .../infrastructure/rule/GeoRuleTest.java | 80 +++- .../infrastructure/rule/TestRule.java | 25 +- .../auction/BidResponseCreatorTest.java | 63 ++- .../org/prebid/server/metric/MetricsTest.java | 8 +- ...est-auction-first-and-second-response.json | 72 +++- .../test-auction-first-bid-only-response.json | 72 +++- .../test-auction-in-order-response.json | 72 +++- ...est-auction-in-reverse-order-response.json | 72 +++- ...test-auction-second-bid-only-response.json | 72 +++- ...est-auction-third-and-second-response.json | 72 +++- .../test-auction-third-bid-only-response.json | 72 +++- .../simulation/test-auction-response-1.json | 72 +++- .../simulation/test-auction-response-2.json | 72 +++- .../it/deals/test-auction-response.json | 123 +++++- 85 files changed, 2651 insertions(+), 424 deletions(-) delete mode 100644 src/main/java/org/prebid/server/activity/infrastructure/ActivityCallResult.java create mode 100644 src/main/java/org/prebid/server/activity/infrastructure/debug/ActivityDebugUtils.java create mode 100644 src/main/java/org/prebid/server/activity/infrastructure/debug/ActivityInfrastructureDebug.java create mode 100644 src/main/java/org/prebid/server/activity/infrastructure/debug/Loggable.java rename src/main/java/org/prebid/server/activity/infrastructure/payload/{ActivityCallPayload.java => ActivityInvocationPayload.java} (56%) delete mode 100644 src/main/java/org/prebid/server/activity/infrastructure/payload/GeoActivityCallPayload.java create mode 100644 src/main/java/org/prebid/server/activity/infrastructure/payload/GeoActivityInvocationPayload.java delete mode 100644 src/main/java/org/prebid/server/activity/infrastructure/payload/GpcActivityCallPayload.java create mode 100644 src/main/java/org/prebid/server/activity/infrastructure/payload/GpcActivityInvocationPayload.java rename src/main/java/org/prebid/server/activity/infrastructure/payload/impl/{ActivityCallPayloadImpl.java => ActivityInvocationPayloadImpl.java} (77%) rename src/main/java/org/prebid/server/activity/infrastructure/payload/impl/{BidRequestActivityCallPayload.java => BidRequestActivityInvocationPayload.java} (85%) rename src/main/java/org/prebid/server/activity/infrastructure/payload/impl/{PrivacyEnforcementServiceActivityCallPayload.java => PrivacyEnforcementServiceActivityInvocationPayload.java} (63%) rename src/main/java/org/prebid/server/activity/infrastructure/payload/impl/{TcfContextActivityCallPayload.java => TcfContextActivityInvocationPayload.java} (84%) create mode 100644 src/main/java/org/prebid/server/activity/infrastructure/privacy/AndPrivacyModules.java create mode 100644 src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/debug/USNatModuleLogEntry.java create mode 100644 src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityInfrastructure.java create mode 100644 src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityInvocation.java create mode 100644 src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityInvocationDefaultResult.java create mode 100644 src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityInvocationResult.java create mode 100644 src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityRule.java create mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/ActivityInfrastructure.groovy create mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/ActivityInvocationPayload.groovy create mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/And.groovy create mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/GeoCode.groovy create mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/RuleConfiguration.groovy create mode 100644 src/test/groovy/org/prebid/server/functional/model/response/auction/Trace.groovy create mode 100644 src/test/groovy/org/prebid/server/functional/tests/privacy/ActivityTraceLogSpec.groovy create mode 100644 src/test/java/org/prebid/server/activity/infrastructure/debug/ActivityDebugUtilsTest.java create mode 100644 src/test/java/org/prebid/server/activity/infrastructure/debug/ActivityInfrastructureDebugTest.java create mode 100644 src/test/java/org/prebid/server/activity/infrastructure/privacy/usnat/USNatModuleTest.java create mode 100644 src/test/java/org/prebid/server/activity/infrastructure/privacy/usnat/debug/USNatModuleLogEntryTest.java diff --git a/extra/modules/confiant-ad-quality/src/main/java/org/prebid/server/hooks/modules/com/confiant/adquality/v1/ConfiantAdQualityBidResponsesScanHook.java b/extra/modules/confiant-ad-quality/src/main/java/org/prebid/server/hooks/modules/com/confiant/adquality/v1/ConfiantAdQualityBidResponsesScanHook.java index 2894393d5ce..2eb93a0ffab 100644 --- a/extra/modules/confiant-ad-quality/src/main/java/org/prebid/server/hooks/modules/com/confiant/adquality/v1/ConfiantAdQualityBidResponsesScanHook.java +++ b/extra/modules/confiant-ad-quality/src/main/java/org/prebid/server/hooks/modules/com/confiant/adquality/v1/ConfiantAdQualityBidResponsesScanHook.java @@ -6,9 +6,9 @@ import io.vertx.core.Future; import org.prebid.server.activity.Activity; import org.prebid.server.activity.ComponentType; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; -import org.prebid.server.activity.infrastructure.payload.impl.ActivityCallPayloadImpl; -import org.prebid.server.activity.infrastructure.payload.impl.BidRequestActivityCallPayload; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.payload.impl.ActivityInvocationPayloadImpl; +import org.prebid.server.activity.infrastructure.payload.impl.BidRequestActivityInvocationPayload; import org.prebid.server.auction.PrivacyEnforcementService; import org.prebid.server.auction.model.AuctionContext; import org.prebid.server.auction.model.BidderResponse; @@ -55,11 +55,11 @@ public Future> call( private BidRequest getBidRequest(AuctionInvocationContext auctionInvocationContext) { final AuctionContext auctionContext = auctionInvocationContext.auctionContext(); final BidRequest bidRequest = auctionContext.getBidRequest(); - final ActivityCallPayload activityCallPayload = BidRequestActivityCallPayload.of( - ActivityCallPayloadImpl.of(ComponentType.GENERAL_MODULE, ConfiantAdQualityModule.CODE), + final ActivityInvocationPayload activityInvocationPayload = BidRequestActivityInvocationPayload.of( + ActivityInvocationPayloadImpl.of(ComponentType.GENERAL_MODULE, ConfiantAdQualityModule.CODE), bidRequest); final boolean disallowTransmitGeo = !auctionContext.getActivityInfrastructure() - .isAllowed(Activity.TRANSMIT_GEO, activityCallPayload); + .isAllowed(Activity.TRANSMIT_GEO, activityInvocationPayload); final User maskedUser = privacyEnforcementService .maskUserConsideringActivityRestrictions(bidRequest.getUser(), true, disallowTransmitGeo); diff --git a/src/main/java/org/prebid/server/activity/infrastructure/ActivityCallResult.java b/src/main/java/org/prebid/server/activity/infrastructure/ActivityCallResult.java deleted file mode 100644 index bbdba273e62..00000000000 --- a/src/main/java/org/prebid/server/activity/infrastructure/ActivityCallResult.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.prebid.server.activity.infrastructure; - -import lombok.Value; - -@Value(staticConstructor = "of") -public class ActivityCallResult { - - boolean isAllowed; - - int processedRulesCount; -} diff --git a/src/main/java/org/prebid/server/activity/infrastructure/ActivityController.java b/src/main/java/org/prebid/server/activity/infrastructure/ActivityController.java index ea1dd27ad5a..36227b12731 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/ActivityController.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/ActivityController.java @@ -1,6 +1,7 @@ package org.prebid.server.activity.infrastructure; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; +import org.prebid.server.activity.infrastructure.debug.ActivityInfrastructureDebug; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; import org.prebid.server.activity.infrastructure.rule.Rule; import java.util.List; @@ -10,30 +11,32 @@ public class ActivityController { private final boolean allowByDefault; private final List rules; + private final ActivityInfrastructureDebug debug; - private ActivityController(boolean allowByDefault, List rules) { + private ActivityController(boolean allowByDefault, List rules, ActivityInfrastructureDebug debug) { this.allowByDefault = allowByDefault; this.rules = Objects.requireNonNull(rules); + this.debug = Objects.requireNonNull(debug); } - public static ActivityController of(boolean allowByDefault, List rules) { - return new ActivityController(allowByDefault, rules); + public static ActivityController of(boolean allowByDefault, List rules, ActivityInfrastructureDebug debug) { + return new ActivityController(allowByDefault, rules, debug); } - public ActivityCallResult isAllowed(ActivityCallPayload activityCallPayload) { - int processedRulesCount = 0; + public boolean isAllowed(ActivityInvocationPayload activityInvocationPayload) { + debug.emitActivityInvocationDefaultResult(allowByDefault); boolean result = allowByDefault; for (Rule rule : rules) { - processedRulesCount++; + final Rule.Result ruleResult = rule.proceed(activityInvocationPayload); + debug.emitProcessedRule(rule, ruleResult); - final Rule.Result ruleResult = rule.proceed(activityCallPayload); if (ruleResult != Rule.Result.ABSTAIN) { result = ruleResult == Rule.Result.ALLOW; break; } } - return ActivityCallResult.of(result, processedRulesCount); + return result; } } diff --git a/src/main/java/org/prebid/server/activity/infrastructure/ActivityInfrastructure.java b/src/main/java/org/prebid/server/activity/infrastructure/ActivityInfrastructure.java index d41246441dd..220e46ab9ca 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/ActivityInfrastructure.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/ActivityInfrastructure.java @@ -2,11 +2,11 @@ package org.prebid.server.activity.infrastructure; import org.prebid.server.activity.Activity; -import org.prebid.server.activity.ComponentType; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; -import org.prebid.server.metric.Metrics; -import org.prebid.server.proto.openrtb.ext.request.TraceLevel; +import org.prebid.server.activity.infrastructure.debug.ActivityInfrastructureDebug; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; +import org.prebid.server.proto.openrtb.ext.response.ExtTraceActivityInfrastructure; +import java.util.List; import java.util.Map; import java.util.Objects; @@ -14,22 +14,16 @@ public class ActivityInfrastructure { public static final boolean ALLOW_ACTIVITY_BY_DEFAULT = true; - private final String accountId; private final Map activitiesControllers; - private final TraceLevel traceLevel; - private final Metrics metrics; + private final ActivityInfrastructureDebug debug; - public ActivityInfrastructure(String accountId, - Map activitiesControllers, - TraceLevel traceLevel, - Metrics metrics) { + public ActivityInfrastructure(Map activitiesControllers, + ActivityInfrastructureDebug debug) { validate(activitiesControllers); - this.accountId = accountId; this.activitiesControllers = activitiesControllers; - this.traceLevel = Objects.requireNonNull(traceLevel); - this.metrics = Objects.requireNonNull(metrics); + this.debug = Objects.requireNonNull(debug); } private static void validate(Map activitiesControllers) { @@ -38,29 +32,15 @@ private static void validate(Map activitiesControl } } - public boolean isAllowed(Activity activity, ActivityCallPayload activityCallPayload) { - final ActivityCallResult result = activitiesControllers.get(activity).isAllowed(activityCallPayload); - updateMetrics(activity, activityCallPayload, result); - return result.isAllowed(); - } + public boolean isAllowed(Activity activity, ActivityInvocationPayload activityInvocationPayload) { + debug.emitActivityInvocation(activity, activityInvocationPayload); + final boolean result = activitiesControllers.get(activity).isAllowed(activityInvocationPayload); + debug.emitActivityInvocationResult(activity, activityInvocationPayload, result); - private void updateMetrics(Activity activity, ActivityCallPayload activityCallPayload, ActivityCallResult result) { - final int processedRulesCount = result.getProcessedRulesCount(); - if (processedRulesCount > 0) { - metrics.updateRequestsActivityProcessedRulesCount(processedRulesCount); - if (traceLevel == TraceLevel.verbose) { - metrics.updateAccountActivityProcessedRulesCount(accountId, processedRulesCount); - } - } + return result; + } - if (!result.isAllowed()) { - metrics.updateRequestsActivityDisallowedCount(activity); - if (traceLevel == TraceLevel.verbose) { - metrics.updateAccountActivityDisallowedCount(accountId, activity); - } - if (activityCallPayload.componentType() == ComponentType.BIDDER) { - metrics.updateAdapterActivityDisallowedCount(activityCallPayload.componentName(), activity); - } - } + public List debugTrace() { + return debug.trace(); } } diff --git a/src/main/java/org/prebid/server/activity/infrastructure/creator/ActivityInfrastructureCreator.java b/src/main/java/org/prebid/server/activity/infrastructure/creator/ActivityInfrastructureCreator.java index 1330608f327..290a81810d9 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/creator/ActivityInfrastructureCreator.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/creator/ActivityInfrastructureCreator.java @@ -6,9 +6,11 @@ import org.prebid.server.activity.Activity; import org.prebid.server.activity.infrastructure.ActivityController; import org.prebid.server.activity.infrastructure.ActivityInfrastructure; +import org.prebid.server.activity.infrastructure.debug.ActivityInfrastructureDebug; import org.prebid.server.activity.infrastructure.privacy.PrivacyModuleQualifier; import org.prebid.server.activity.infrastructure.rule.Rule; import org.prebid.server.auction.gpp.model.GppContext; +import org.prebid.server.json.JacksonMapper; import org.prebid.server.metric.MetricName; import org.prebid.server.metric.Metrics; import org.prebid.server.proto.openrtb.ext.request.TraceLevel; @@ -35,21 +37,27 @@ public class ActivityInfrastructureCreator { private final ActivityRuleFactory activityRuleFactory; private final Metrics metrics; + private final JacksonMapper jacksonMapper; + + public ActivityInfrastructureCreator(ActivityRuleFactory activityRuleFactory, + Metrics metrics, + JacksonMapper jacksonMapper) { - public ActivityInfrastructureCreator(ActivityRuleFactory activityRuleFactory, Metrics metrics) { this.activityRuleFactory = Objects.requireNonNull(activityRuleFactory); this.metrics = Objects.requireNonNull(metrics); + this.jacksonMapper = Objects.requireNonNull(jacksonMapper); } public ActivityInfrastructure create(Account account, GppContext gppContext, TraceLevel traceLevel) { - return new ActivityInfrastructure( - account.getId(), - parse(account, gppContext), - traceLevel, - metrics); + final ActivityInfrastructureDebug debug = debugWheel(account, traceLevel); + return new ActivityInfrastructure(parse(account, gppContext, debug), debug); + } + + private ActivityInfrastructureDebug debugWheel(Account account, TraceLevel traceLevel) { + return new ActivityInfrastructureDebug(account.getId(), traceLevel, metrics, jacksonMapper); } - Map parse(Account account, GppContext gppContext) { + Map parse(Account account, GppContext gppContext, ActivityInfrastructureDebug debug) { final Optional accountPrivacyConfig = Optional.ofNullable(account.getPrivacy()); final Map activitiesConfiguration = accountPrivacyConfig @@ -64,12 +72,16 @@ Map parse(Account account, GppContext gppContext) UnaryOperator.identity(), takeFirstAndLogDuplicates(account.getId()))); - return Arrays.stream(Activity.values()) - .collect(Collectors.toMap( - UnaryOperator.identity(), - activity -> from(activity, activitiesConfiguration.get(activity), modulesConfigs, gppContext), - (oldValue, newValue) -> newValue, - enumMapFactory())); + return Arrays.stream(Activity.values()).collect(Collectors.toMap( + UnaryOperator.identity(), + activity -> from( + activity, + activitiesConfiguration.get(activity), + modulesConfigs, + gppContext, + debug), + (oldValue, newValue) -> oldValue, + enumMapFactory())); } private BinaryOperator takeFirstAndLogDuplicates(String accountId) { @@ -85,10 +97,14 @@ private BinaryOperator takeFirstAndLogDuplicates(Str private ActivityController from(Activity activity, AccountActivityConfiguration activityConfiguration, Map modulesConfigs, - GppContext gppContext) { + GppContext gppContext, + ActivityInfrastructureDebug debug) { if (activityConfiguration == null) { - return ActivityController.of(ActivityInfrastructure.ALLOW_ACTIVITY_BY_DEFAULT, Collections.emptyList()); + return ActivityController.of( + ActivityInfrastructure.ALLOW_ACTIVITY_BY_DEFAULT, + Collections.emptyList(), + debug); } final ActivityControllerCreationContext creationContext = ActivityControllerCreationContext.of( @@ -102,7 +118,7 @@ private ActivityController from(Activity activity, .map(ruleConfiguration -> activityRuleFactory.from(ruleConfiguration, creationContext)) .toList(); - return ActivityController.of(allow, rules); + return ActivityController.of(allow, rules, debug); } private static boolean allowFromConfig(Boolean configValue) { diff --git a/src/main/java/org/prebid/server/activity/infrastructure/creator/privacy/uscustomlogic/USCustomLogicModuleCreator.java b/src/main/java/org/prebid/server/activity/infrastructure/creator/privacy/uscustomlogic/USCustomLogicModuleCreator.java index acd860aa0b9..6d8a308fc1a 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/creator/privacy/uscustomlogic/USCustomLogicModuleCreator.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/creator/privacy/uscustomlogic/USCustomLogicModuleCreator.java @@ -7,12 +7,12 @@ import org.prebid.server.activity.Activity; import org.prebid.server.activity.infrastructure.creator.PrivacyModuleCreationContext; import org.prebid.server.activity.infrastructure.creator.privacy.PrivacyModuleCreator; +import org.prebid.server.activity.infrastructure.privacy.AndPrivacyModules; import org.prebid.server.activity.infrastructure.privacy.PrivacyModule; import org.prebid.server.activity.infrastructure.privacy.PrivacyModuleQualifier; import org.prebid.server.activity.infrastructure.privacy.PrivacySection; import org.prebid.server.activity.infrastructure.privacy.uscustomlogic.USCustomLogicDataSupplier; import org.prebid.server.activity.infrastructure.privacy.uscustomlogic.USCustomLogicModule; -import org.prebid.server.activity.infrastructure.rule.AndRule; import org.prebid.server.auction.gpp.model.GppContext; import org.prebid.server.exception.InvalidAccountConfigException; import org.prebid.server.json.DecodeException; @@ -79,8 +79,7 @@ public PrivacyModule from(PrivacyModuleCreationContext creationContext) { .toList() : Collections.emptyList(); - final AndRule andRule = new AndRule(innerPrivacyModules); - return andRule::proceed; + return new AndPrivacyModules(innerPrivacyModules); } private static AccountUSCustomLogicModuleConfig moduleConfig(PrivacyModuleCreationContext creationContext) { diff --git a/src/main/java/org/prebid/server/activity/infrastructure/creator/privacy/usnat/USNatModuleCreator.java b/src/main/java/org/prebid/server/activity/infrastructure/creator/privacy/usnat/USNatModuleCreator.java index 819f1041334..012d913707d 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/creator/privacy/usnat/USNatModuleCreator.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/creator/privacy/usnat/USNatModuleCreator.java @@ -5,11 +5,11 @@ import org.prebid.server.activity.Activity; import org.prebid.server.activity.infrastructure.creator.PrivacyModuleCreationContext; import org.prebid.server.activity.infrastructure.creator.privacy.PrivacyModuleCreator; +import org.prebid.server.activity.infrastructure.privacy.AndPrivacyModules; import org.prebid.server.activity.infrastructure.privacy.PrivacyModule; import org.prebid.server.activity.infrastructure.privacy.PrivacyModuleQualifier; import org.prebid.server.activity.infrastructure.privacy.PrivacySection; import org.prebid.server.activity.infrastructure.privacy.usnat.USNatModule; -import org.prebid.server.activity.infrastructure.rule.AndRule; import org.prebid.server.auction.gpp.model.GppContext; import org.prebid.server.settings.model.activity.privacy.AccountUSNatModuleConfig; @@ -46,8 +46,7 @@ public PrivacyModule from(PrivacyModuleCreationContext creationContext) { .map(sectionId -> forSection(creationContext.getActivity(), sectionId, scope.getGppModel())) .toList(); - final AndRule andRule = new AndRule(innerPrivacyModules); - return andRule::proceed; + return new AndPrivacyModules(innerPrivacyModules); } private static AccountUSNatModuleConfig moduleConfig(PrivacyModuleCreationContext creationContext) { diff --git a/src/main/java/org/prebid/server/activity/infrastructure/debug/ActivityDebugUtils.java b/src/main/java/org/prebid/server/activity/infrastructure/debug/ActivityDebugUtils.java new file mode 100644 index 00000000000..f09965c7ee7 --- /dev/null +++ b/src/main/java/org/prebid/server/activity/infrastructure/debug/ActivityDebugUtils.java @@ -0,0 +1,29 @@ +package org.prebid.server.activity.infrastructure.debug; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.TextNode; + +import java.util.List; + +public class ActivityDebugUtils { + + private ActivityDebugUtils() { + } + + public static JsonNode asLogEntry(Object object, ObjectMapper mapper) { + return object instanceof Loggable loggable + ? loggable.asLogEntry(mapper) + : TextNode.valueOf(object.toString()); + } + + public static ArrayNode asLogEntry(List objects, ObjectMapper mapper) { + final ArrayNode arrayNode = mapper.createArrayNode(); + objects.stream() + .map(object -> asLogEntry(object, mapper)) + .forEach(arrayNode::add); + + return arrayNode; + } +} diff --git a/src/main/java/org/prebid/server/activity/infrastructure/debug/ActivityInfrastructureDebug.java b/src/main/java/org/prebid/server/activity/infrastructure/debug/ActivityInfrastructureDebug.java new file mode 100644 index 00000000000..578d4fc22b6 --- /dev/null +++ b/src/main/java/org/prebid/server/activity/infrastructure/debug/ActivityInfrastructureDebug.java @@ -0,0 +1,101 @@ +package org.prebid.server.activity.infrastructure.debug; + +import org.prebid.server.activity.Activity; +import org.prebid.server.activity.ComponentType; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.rule.Rule; +import org.prebid.server.json.JacksonMapper; +import org.prebid.server.metric.Metrics; +import org.prebid.server.proto.openrtb.ext.request.TraceLevel; +import org.prebid.server.proto.openrtb.ext.response.ExtTraceActivityInfrastructure; +import org.prebid.server.proto.openrtb.ext.response.ExtTraceActivityInvocation; +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 java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +public class ActivityInfrastructureDebug { + + private final String accountId; + private final TraceLevel traceLevel; + private final List traceLog; + private final Metrics metrics; + private final JacksonMapper jacksonMapper; + + public ActivityInfrastructureDebug(String accountId, + TraceLevel traceLevel, + Metrics metrics, + JacksonMapper jacksonMapper) { + + this.accountId = accountId; + this.traceLevel = traceLevel; + this.traceLog = new ArrayList<>(); + this.metrics = Objects.requireNonNull(metrics); + this.jacksonMapper = Objects.requireNonNull(jacksonMapper); + } + + public void emitActivityInvocation(Activity activity, ActivityInvocationPayload activityInvocationPayload) { + if (atLeast(TraceLevel.basic)) { + traceLog.add(ExtTraceActivityInvocation.of( + "Invocation of Activity Infrastructure.", + activity, + atLeast(TraceLevel.verbose) ? activityInvocationPayload : null)); + } + } + + public void emitActivityInvocationDefaultResult(boolean defaultResult) { + if (atLeast(TraceLevel.basic)) { + traceLog.add(ExtTraceActivityInvocationDefaultResult.of( + "Setting the default invocation result.", + defaultResult)); + } + } + + public void emitProcessedRule(Rule rule, Rule.Result result) { + if (atLeast(TraceLevel.basic)) { + traceLog.add(ExtTraceActivityRule.of( + "Processing rule.", + atLeast(TraceLevel.verbose) ? ActivityDebugUtils.asLogEntry(rule, jacksonMapper.mapper()) : null, + result)); + } + + metrics.updateRequestsActivityProcessedRulesCount(); + if (atLeast(TraceLevel.verbose)) { + metrics.updateAccountActivityProcessedRulesCount(accountId); + } + } + + public void emitActivityInvocationResult(Activity activity, + ActivityInvocationPayload activityInvocationPayload, + boolean result) { + + if (atLeast(TraceLevel.basic)) { + traceLog.add(ExtTraceActivityInvocationResult.of( + "Activity Infrastructure invocation result.", + activity, + result)); + } + + if (!result) { + metrics.updateRequestsActivityDisallowedCount(activity); + if (atLeast(TraceLevel.verbose)) { + metrics.updateAccountActivityDisallowedCount(accountId, activity); + } + if (activityInvocationPayload.componentType() == ComponentType.BIDDER) { + metrics.updateAdapterActivityDisallowedCount(activityInvocationPayload.componentName(), activity); + } + } + } + + public List trace() { + return Collections.unmodifiableList(traceLog); + } + + private boolean atLeast(TraceLevel minTraceLevel) { + return traceLevel != null && traceLevel.ordinal() >= minTraceLevel.ordinal(); + } +} diff --git a/src/main/java/org/prebid/server/activity/infrastructure/debug/Loggable.java b/src/main/java/org/prebid/server/activity/infrastructure/debug/Loggable.java new file mode 100644 index 00000000000..dc90c4fe83e --- /dev/null +++ b/src/main/java/org/prebid/server/activity/infrastructure/debug/Loggable.java @@ -0,0 +1,9 @@ +package org.prebid.server.activity.infrastructure.debug; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +public interface Loggable { + + JsonNode asLogEntry(ObjectMapper mapper); +} diff --git a/src/main/java/org/prebid/server/activity/infrastructure/payload/ActivityCallPayload.java b/src/main/java/org/prebid/server/activity/infrastructure/payload/ActivityInvocationPayload.java similarity index 56% rename from src/main/java/org/prebid/server/activity/infrastructure/payload/ActivityCallPayload.java rename to src/main/java/org/prebid/server/activity/infrastructure/payload/ActivityInvocationPayload.java index b904cff0857..2014b7ab81f 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/payload/ActivityCallPayload.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/payload/ActivityInvocationPayload.java @@ -1,10 +1,13 @@ package org.prebid.server.activity.infrastructure.payload; +import com.fasterxml.jackson.annotation.JsonProperty; import org.prebid.server.activity.ComponentType; -public interface ActivityCallPayload { +public interface ActivityInvocationPayload { + @JsonProperty ComponentType componentType(); + @JsonProperty String componentName(); } diff --git a/src/main/java/org/prebid/server/activity/infrastructure/payload/GeoActivityCallPayload.java b/src/main/java/org/prebid/server/activity/infrastructure/payload/GeoActivityCallPayload.java deleted file mode 100644 index c8262696132..00000000000 --- a/src/main/java/org/prebid/server/activity/infrastructure/payload/GeoActivityCallPayload.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.prebid.server.activity.infrastructure.payload; - -public interface GeoActivityCallPayload extends ActivityCallPayload { - - String country(); - - String region(); -} diff --git a/src/main/java/org/prebid/server/activity/infrastructure/payload/GeoActivityInvocationPayload.java b/src/main/java/org/prebid/server/activity/infrastructure/payload/GeoActivityInvocationPayload.java new file mode 100644 index 00000000000..54d115615e7 --- /dev/null +++ b/src/main/java/org/prebid/server/activity/infrastructure/payload/GeoActivityInvocationPayload.java @@ -0,0 +1,12 @@ +package org.prebid.server.activity.infrastructure.payload; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public interface GeoActivityInvocationPayload extends ActivityInvocationPayload { + + @JsonProperty + String country(); + + @JsonProperty + String region(); +} diff --git a/src/main/java/org/prebid/server/activity/infrastructure/payload/GpcActivityCallPayload.java b/src/main/java/org/prebid/server/activity/infrastructure/payload/GpcActivityCallPayload.java deleted file mode 100644 index 5f3f92b7a64..00000000000 --- a/src/main/java/org/prebid/server/activity/infrastructure/payload/GpcActivityCallPayload.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.prebid.server.activity.infrastructure.payload; - -public interface GpcActivityCallPayload extends ActivityCallPayload { - - String gpc(); -} diff --git a/src/main/java/org/prebid/server/activity/infrastructure/payload/GpcActivityInvocationPayload.java b/src/main/java/org/prebid/server/activity/infrastructure/payload/GpcActivityInvocationPayload.java new file mode 100644 index 00000000000..981324a40ea --- /dev/null +++ b/src/main/java/org/prebid/server/activity/infrastructure/payload/GpcActivityInvocationPayload.java @@ -0,0 +1,9 @@ +package org.prebid.server.activity.infrastructure.payload; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public interface GpcActivityInvocationPayload extends ActivityInvocationPayload { + + @JsonProperty + String gpc(); +} diff --git a/src/main/java/org/prebid/server/activity/infrastructure/payload/impl/ActivityCallPayloadImpl.java b/src/main/java/org/prebid/server/activity/infrastructure/payload/impl/ActivityInvocationPayloadImpl.java similarity index 77% rename from src/main/java/org/prebid/server/activity/infrastructure/payload/impl/ActivityCallPayloadImpl.java rename to src/main/java/org/prebid/server/activity/infrastructure/payload/impl/ActivityInvocationPayloadImpl.java index 5572bed6d78..9008a0e020a 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/payload/impl/ActivityCallPayloadImpl.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/payload/impl/ActivityInvocationPayloadImpl.java @@ -3,11 +3,11 @@ import lombok.Value; import lombok.experimental.Accessors; import org.prebid.server.activity.ComponentType; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; @Accessors(fluent = true) @Value(staticConstructor = "of") -public class ActivityCallPayloadImpl implements ActivityCallPayload { +public class ActivityInvocationPayloadImpl implements ActivityInvocationPayload { ComponentType componentType; diff --git a/src/main/java/org/prebid/server/activity/infrastructure/payload/impl/BidRequestActivityCallPayload.java b/src/main/java/org/prebid/server/activity/infrastructure/payload/impl/BidRequestActivityInvocationPayload.java similarity index 85% rename from src/main/java/org/prebid/server/activity/infrastructure/payload/impl/BidRequestActivityCallPayload.java rename to src/main/java/org/prebid/server/activity/infrastructure/payload/impl/BidRequestActivityInvocationPayload.java index 1b62c5abd98..81de2b34075 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/payload/impl/BidRequestActivityCallPayload.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/payload/impl/BidRequestActivityInvocationPayload.java @@ -7,19 +7,19 @@ import lombok.Value; import lombok.experimental.Accessors; import lombok.experimental.Delegate; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; -import org.prebid.server.activity.infrastructure.payload.GeoActivityCallPayload; -import org.prebid.server.activity.infrastructure.payload.GpcActivityCallPayload; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.payload.GeoActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.payload.GpcActivityInvocationPayload; import org.prebid.server.proto.openrtb.ext.request.ExtRegs; import java.util.Optional; @Accessors(fluent = true) @Value(staticConstructor = "of") -public class BidRequestActivityCallPayload implements GeoActivityCallPayload, GpcActivityCallPayload { +public class BidRequestActivityInvocationPayload implements GeoActivityInvocationPayload, GpcActivityInvocationPayload { @Delegate - ActivityCallPayload componentInfo; + ActivityInvocationPayload componentInfo; BidRequest bidRequest; diff --git a/src/main/java/org/prebid/server/activity/infrastructure/payload/impl/PrivacyEnforcementServiceActivityCallPayload.java b/src/main/java/org/prebid/server/activity/infrastructure/payload/impl/PrivacyEnforcementServiceActivityInvocationPayload.java similarity index 63% rename from src/main/java/org/prebid/server/activity/infrastructure/payload/impl/PrivacyEnforcementServiceActivityCallPayload.java rename to src/main/java/org/prebid/server/activity/infrastructure/payload/impl/PrivacyEnforcementServiceActivityInvocationPayload.java index 42d3a04c7a5..50dc0235612 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/payload/impl/PrivacyEnforcementServiceActivityCallPayload.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/payload/impl/PrivacyEnforcementServiceActivityInvocationPayload.java @@ -3,18 +3,18 @@ import lombok.Value; import lombok.experimental.Accessors; import lombok.experimental.Delegate; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; -import org.prebid.server.activity.infrastructure.payload.GeoActivityCallPayload; -import org.prebid.server.activity.infrastructure.payload.GpcActivityCallPayload; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.payload.GeoActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.payload.GpcActivityInvocationPayload; @Accessors(fluent = true) @Value(staticConstructor = "of") -public class PrivacyEnforcementServiceActivityCallPayload implements - GeoActivityCallPayload, - GpcActivityCallPayload { +public class PrivacyEnforcementServiceActivityInvocationPayload implements + GeoActivityInvocationPayload, + GpcActivityInvocationPayload { @Delegate - ActivityCallPayload activityCallPayload; + ActivityInvocationPayload activityInvocationPayload; String country; diff --git a/src/main/java/org/prebid/server/activity/infrastructure/payload/impl/TcfContextActivityCallPayload.java b/src/main/java/org/prebid/server/activity/infrastructure/payload/impl/TcfContextActivityInvocationPayload.java similarity index 84% rename from src/main/java/org/prebid/server/activity/infrastructure/payload/impl/TcfContextActivityCallPayload.java rename to src/main/java/org/prebid/server/activity/infrastructure/payload/impl/TcfContextActivityInvocationPayload.java index ab4a2b495d7..4dbfeb4269d 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/payload/impl/TcfContextActivityCallPayload.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/payload/impl/TcfContextActivityInvocationPayload.java @@ -3,8 +3,8 @@ import lombok.Value; import lombok.experimental.Accessors; import lombok.experimental.Delegate; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; -import org.prebid.server.activity.infrastructure.payload.GeoActivityCallPayload; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.payload.GeoActivityInvocationPayload; import org.prebid.server.geolocation.model.GeoInfo; import org.prebid.server.privacy.gdpr.model.TcfContext; @@ -12,10 +12,10 @@ @Accessors(fluent = true) @Value(staticConstructor = "of") -public class TcfContextActivityCallPayload implements GeoActivityCallPayload { +public class TcfContextActivityInvocationPayload implements GeoActivityInvocationPayload { @Delegate - ActivityCallPayload componentInfo; + ActivityInvocationPayload componentInfo; TcfContext tcfContext; diff --git a/src/main/java/org/prebid/server/activity/infrastructure/privacy/AndPrivacyModules.java b/src/main/java/org/prebid/server/activity/infrastructure/privacy/AndPrivacyModules.java new file mode 100644 index 00000000000..8f2b376e3eb --- /dev/null +++ b/src/main/java/org/prebid/server/activity/infrastructure/privacy/AndPrivacyModules.java @@ -0,0 +1,29 @@ +package org.prebid.server.activity.infrastructure.privacy; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.prebid.server.activity.infrastructure.debug.ActivityDebugUtils; +import org.prebid.server.activity.infrastructure.debug.Loggable; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.rule.AndRule; + +import java.util.List; + +public class AndPrivacyModules implements PrivacyModule, Loggable { + + private final AndRule and; + + public AndPrivacyModules(List privacyModules) { + and = new AndRule(privacyModules); + } + + @Override + public Result proceed(ActivityInvocationPayload activityInvocationPayload) { + return and.proceed(activityInvocationPayload); + } + + @Override + public JsonNode asLogEntry(ObjectMapper mapper) { + return ActivityDebugUtils.asLogEntry(and, mapper); + } +} diff --git a/src/main/java/org/prebid/server/activity/infrastructure/privacy/uscustomlogic/USCustomLogicModule.java b/src/main/java/org/prebid/server/activity/infrastructure/privacy/uscustomlogic/USCustomLogicModule.java index e8d685ff01c..0b741ecd3f1 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/privacy/uscustomlogic/USCustomLogicModule.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/privacy/uscustomlogic/USCustomLogicModule.java @@ -1,8 +1,12 @@ package org.prebid.server.activity.infrastructure.privacy.uscustomlogic; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.TextNode; import io.github.jamsesso.jsonlogic.ast.JsonLogicNode; import io.github.jamsesso.jsonlogic.evaluator.JsonLogicEvaluationException; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; +import org.prebid.server.activity.infrastructure.debug.Loggable; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; import org.prebid.server.activity.infrastructure.privacy.PrivacyModule; import org.prebid.server.exception.PreBidException; import org.prebid.server.json.JsonLogic; @@ -10,7 +14,7 @@ import java.util.Map; import java.util.function.Supplier; -public class USCustomLogicModule implements PrivacyModule { +public class USCustomLogicModule implements PrivacyModule, Loggable { private final Result result; @@ -28,7 +32,15 @@ public USCustomLogicModule(JsonLogic jsonLogic, } @Override - public Result proceed(ActivityCallPayload activityCallPayload) { + public Result proceed(ActivityInvocationPayload activityInvocationPayload) { return result; } + + @Override + public JsonNode asLogEntry(ObjectMapper mapper) { + return TextNode.valueOf( + "%s. Precomputed result: %s.".formatted( + this.getClass().getSimpleName(), + result)); + } } diff --git a/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/USNatModule.java b/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/USNatModule.java index 2ef8af285e8..b3eb1a00b8e 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/USNatModule.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/USNatModule.java @@ -1,7 +1,11 @@ package org.prebid.server.activity.infrastructure.privacy.usnat; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import org.prebid.server.activity.Activity; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; +import org.prebid.server.activity.infrastructure.debug.ActivityDebugUtils; +import org.prebid.server.activity.infrastructure.debug.Loggable; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; import org.prebid.server.activity.infrastructure.privacy.PrivacyModule; import org.prebid.server.activity.infrastructure.privacy.usnat.inner.USNatDefault; import org.prebid.server.activity.infrastructure.privacy.usnat.inner.USNatSyncUser; @@ -10,7 +14,7 @@ import java.util.Objects; -public class USNatModule implements PrivacyModule { +public class USNatModule implements PrivacyModule, Loggable { private final PrivacyModule innerModule; @@ -31,7 +35,12 @@ private static PrivacyModule innerModule(Activity activity, USNatGppReader gppRe } @Override - public Result proceed(ActivityCallPayload activityCallPayload) { - return innerModule.proceed(activityCallPayload); + public Result proceed(ActivityInvocationPayload activityInvocationPayload) { + return innerModule.proceed(activityInvocationPayload); + } + + @Override + public JsonNode asLogEntry(ObjectMapper mapper) { + return ActivityDebugUtils.asLogEntry(innerModule, mapper); } } diff --git a/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/debug/USNatModuleLogEntry.java b/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/debug/USNatModuleLogEntry.java new file mode 100644 index 00000000000..57345439a0d --- /dev/null +++ b/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/debug/USNatModuleLogEntry.java @@ -0,0 +1,27 @@ +package org.prebid.server.activity.infrastructure.privacy.usnat.debug; + +import com.fasterxml.jackson.databind.node.TextNode; +import org.prebid.server.activity.infrastructure.privacy.PrivacyModule; +import org.prebid.server.activity.infrastructure.privacy.usnat.USNatGppReader; +import org.prebid.server.activity.infrastructure.rule.Rule; + +public class USNatModuleLogEntry { + + private USNatModuleLogEntry() { + } + + public static TextNode from(PrivacyModule privacyModule, USNatGppReader gppReader, Rule.Result precomputedResult) { + return TextNode.valueOf( + "%s with %s. Precomputed result: %s.".formatted( + privacyModule.getClass().getSimpleName(), + gppReader.getClass().getSimpleName(), + precomputedResult)); + } + + public static TextNode from(PrivacyModule privacyModule, Rule.Result precomputedResult) { + return TextNode.valueOf( + "%s. Precomputed result: %s.".formatted( + privacyModule.getClass().getSimpleName(), + precomputedResult)); + } +} diff --git a/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatDefault.java b/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatDefault.java index 8d2aa28faae..e96b2ebf989 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatDefault.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatDefault.java @@ -1,18 +1,30 @@ package org.prebid.server.activity.infrastructure.privacy.usnat.inner; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.prebid.server.activity.infrastructure.debug.Loggable; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; import org.prebid.server.activity.infrastructure.privacy.PrivacyModule; +import org.prebid.server.activity.infrastructure.privacy.usnat.debug.USNatModuleLogEntry; -public class USNatDefault implements PrivacyModule { +public class USNatDefault implements PrivacyModule, Loggable { private static final USNatDefault INSTANCE = new USNatDefault(); - public static PrivacyModule instance() { + private USNatDefault() { + } + + public static USNatDefault instance() { return INSTANCE; } @Override - public Result proceed(ActivityCallPayload activityCallPayload) { + public Result proceed(ActivityInvocationPayload activityInvocationPayload) { return Result.ABSTAIN; } + + @Override + public JsonNode asLogEntry(ObjectMapper mapper) { + return USNatModuleLogEntry.from(this, Result.ABSTAIN); + } } diff --git a/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatSyncUser.java b/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatSyncUser.java index 0e79bd57319..77a6bfea09b 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatSyncUser.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatSyncUser.java @@ -1,8 +1,12 @@ package org.prebid.server.activity.infrastructure.privacy.usnat.inner; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.prebid.server.activity.infrastructure.debug.Loggable; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; import org.prebid.server.activity.infrastructure.privacy.PrivacyModule; import org.prebid.server.activity.infrastructure.privacy.usnat.USNatGppReader; +import org.prebid.server.activity.infrastructure.privacy.usnat.debug.USNatModuleLogEntry; import org.prebid.server.activity.infrastructure.privacy.usnat.inner.model.Gpc; import org.prebid.server.activity.infrastructure.privacy.usnat.inner.model.KnownChildSensitiveDataConsent; import org.prebid.server.activity.infrastructure.privacy.usnat.inner.model.MspaServiceProviderMode; @@ -19,16 +23,19 @@ import java.util.List; import java.util.Objects; -public class USNatSyncUser implements PrivacyModule { +public class USNatSyncUser implements PrivacyModule, Loggable { + private final USNatGppReader gppReader; private final Result result; public USNatSyncUser(USNatGppReader gppReader) { + this.gppReader = gppReader; + result = disallow(gppReader) ? Result.DISALLOW : Result.ALLOW; } @Override - public Result proceed(ActivityCallPayload activityCallPayload) { + public Result proceed(ActivityInvocationPayload activityInvocationPayload) { return result; } @@ -91,4 +98,9 @@ private static boolean equalsAtIndex(USNatField expectedValue, List li private static boolean equals(T providedValue, USNatField expectedValue) { return Objects.equals(providedValue, expectedValue.value()); } + + @Override + public JsonNode asLogEntry(ObjectMapper mapper) { + return USNatModuleLogEntry.from(this, gppReader, result); + } } diff --git a/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatTransmitGeo.java b/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatTransmitGeo.java index 8e8f7e241fc..dba489b2f0c 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatTransmitGeo.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatTransmitGeo.java @@ -1,8 +1,12 @@ package org.prebid.server.activity.infrastructure.privacy.usnat.inner; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.prebid.server.activity.infrastructure.debug.Loggable; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; import org.prebid.server.activity.infrastructure.privacy.PrivacyModule; import org.prebid.server.activity.infrastructure.privacy.usnat.USNatGppReader; +import org.prebid.server.activity.infrastructure.privacy.usnat.debug.USNatModuleLogEntry; import org.prebid.server.activity.infrastructure.privacy.usnat.inner.model.Gpc; import org.prebid.server.activity.infrastructure.privacy.usnat.inner.model.KnownChildSensitiveDataConsent; import org.prebid.server.activity.infrastructure.privacy.usnat.inner.model.MspaServiceProviderMode; @@ -15,16 +19,19 @@ import java.util.List; import java.util.Objects; -public class USNatTransmitGeo implements PrivacyModule { +public class USNatTransmitGeo implements PrivacyModule, Loggable { + private final USNatGppReader gppReader; private final Result result; public USNatTransmitGeo(USNatGppReader gppReader) { + this.gppReader = gppReader; + result = disallow(gppReader) ? Result.DISALLOW : Result.ALLOW; } @Override - public Result proceed(ActivityCallPayload activityCallPayload) { + public Result proceed(ActivityInvocationPayload activityInvocationPayload) { return result; } @@ -64,4 +71,9 @@ private static boolean equalsAtIndex(USNatField expectedValue, List li private static boolean equals(T providedValue, USNatField expectedValue) { return Objects.equals(providedValue, expectedValue.value()); } + + @Override + public JsonNode asLogEntry(ObjectMapper mapper) { + return USNatModuleLogEntry.from(this, gppReader, result); + } } diff --git a/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatTransmitUfpd.java b/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatTransmitUfpd.java index 80287586528..248c9705e09 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatTransmitUfpd.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatTransmitUfpd.java @@ -1,8 +1,12 @@ package org.prebid.server.activity.infrastructure.privacy.usnat.inner; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.prebid.server.activity.infrastructure.debug.Loggable; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; import org.prebid.server.activity.infrastructure.privacy.PrivacyModule; import org.prebid.server.activity.infrastructure.privacy.usnat.USNatGppReader; +import org.prebid.server.activity.infrastructure.privacy.usnat.debug.USNatModuleLogEntry; import org.prebid.server.activity.infrastructure.privacy.usnat.inner.model.Gpc; import org.prebid.server.activity.infrastructure.privacy.usnat.inner.model.KnownChildSensitiveDataConsent; import org.prebid.server.activity.infrastructure.privacy.usnat.inner.model.MspaServiceProviderMode; @@ -23,20 +27,23 @@ import java.util.Objects; import java.util.Set; -public class USNatTransmitUfpd implements PrivacyModule { +public class USNatTransmitUfpd implements PrivacyModule, Loggable { private static final Set SENSITIVE_DATA_INDICES_SET_1 = Set.of(0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11); private static final Set SENSITIVE_DATA_INDICES_SET_2 = Set.of(0, 1, 2, 3, 4, 10); private static final Set SENSITIVE_DATA_INDICES_SET_3 = Set.of(5, 6, 8, 9, 11); + private final USNatGppReader gppReader; private final Result result; public USNatTransmitUfpd(USNatGppReader gppReader) { + this.gppReader = gppReader; + result = disallow(gppReader) ? Result.DISALLOW : Result.ALLOW; } @Override - public Result proceed(ActivityCallPayload activityCallPayload) { + public Result proceed(ActivityInvocationPayload activityInvocationPayload) { return result; } @@ -131,4 +138,9 @@ private static boolean equalsAtIndex(USNatField expectedValue, List li private static boolean equals(T providedValue, USNatField expectedValue) { return Objects.equals(providedValue, expectedValue.value()); } + + @Override + public JsonNode asLogEntry(ObjectMapper mapper) { + return USNatModuleLogEntry.from(this, gppReader, result); + } } diff --git a/src/main/java/org/prebid/server/activity/infrastructure/rule/AbstractMatchRule.java b/src/main/java/org/prebid/server/activity/infrastructure/rule/AbstractMatchRule.java index eb6b4d17d7d..69af77e95a5 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/rule/AbstractMatchRule.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/rule/AbstractMatchRule.java @@ -1,19 +1,19 @@ package org.prebid.server.activity.infrastructure.rule; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; public abstract class AbstractMatchRule implements Rule { @Override - public Result proceed(ActivityCallPayload activityCallPayload) { - if (!matches(activityCallPayload)) { + public Result proceed(ActivityInvocationPayload activityInvocationPayload) { + if (!matches(activityInvocationPayload)) { return Result.ABSTAIN; } return allowed() ? Result.ALLOW : Result.DISALLOW; } - public abstract boolean matches(ActivityCallPayload activityCallPayload); + public abstract boolean matches(ActivityInvocationPayload activityInvocationPayload); public abstract boolean allowed(); } diff --git a/src/main/java/org/prebid/server/activity/infrastructure/rule/AndRule.java b/src/main/java/org/prebid/server/activity/infrastructure/rule/AndRule.java index d9e0c666d3b..40585181541 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/rule/AndRule.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/rule/AndRule.java @@ -1,11 +1,17 @@ package org.prebid.server.activity.infrastructure.rule; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.prebid.server.activity.infrastructure.debug.ActivityDebugUtils; +import org.prebid.server.activity.infrastructure.debug.Loggable; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; import java.util.List; import java.util.Objects; -public class AndRule implements Rule { +public class AndRule implements Rule, Loggable { private final List rules; @@ -14,11 +20,11 @@ public AndRule(List rules) { } @Override - public Result proceed(ActivityCallPayload activityCallPayload) { + public Result proceed(ActivityInvocationPayload activityInvocationPayload) { Result result = Result.ABSTAIN; for (Rule rule : rules) { - final Result ruleResult = rule.proceed(activityCallPayload); + final Result ruleResult = rule.proceed(activityInvocationPayload); if (ruleResult != Result.ABSTAIN) { result = ruleResult; } @@ -30,4 +36,13 @@ public Result proceed(ActivityCallPayload activityCallPayload) { return result; } + + @Override + public JsonNode asLogEntry(ObjectMapper mapper) { + final ObjectNode andNode = mapper.createObjectNode(); + final ArrayNode arrayNode = andNode.putArray("and"); + arrayNode.addAll(ActivityDebugUtils.asLogEntry(rules, mapper)); + + return andNode; + } } diff --git a/src/main/java/org/prebid/server/activity/infrastructure/rule/ComponentRule.java b/src/main/java/org/prebid/server/activity/infrastructure/rule/ComponentRule.java index 742f62a4638..b45cbfa887c 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/rule/ComponentRule.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/rule/ComponentRule.java @@ -1,11 +1,14 @@ package org.prebid.server.activity.infrastructure.rule; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import org.prebid.server.activity.ComponentType; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; +import org.prebid.server.activity.infrastructure.debug.Loggable; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; import java.util.Set; -public final class ComponentRule extends AbstractMatchRule { +public final class ComponentRule extends AbstractMatchRule implements Loggable { private final Set componentTypes; private final Set componentNames; @@ -21,13 +24,23 @@ public ComponentRule(Set componentTypes, } @Override - public boolean matches(ActivityCallPayload activityCallPayload) { - return (componentTypes == null || componentTypes.contains(activityCallPayload.componentType())) - && (componentNames == null || componentNames.contains(activityCallPayload.componentName())); + public boolean matches(ActivityInvocationPayload activityInvocationPayload) { + return (componentTypes == null || componentTypes.contains(activityInvocationPayload.componentType())) + && (componentNames == null || componentNames.contains(activityInvocationPayload.componentName())); } @Override public boolean allowed() { return allowed; } + + @Override + public JsonNode asLogEntry(ObjectMapper mapper) { + return mapper.valueToTree(new ComponentRuleLogEntry(componentTypes, componentNames, allowed)); + } + + private record ComponentRuleLogEntry(Set componentTypes, + Set componentNames, + boolean allow) { + } } diff --git a/src/main/java/org/prebid/server/activity/infrastructure/rule/GeoRule.java b/src/main/java/org/prebid/server/activity/infrastructure/rule/GeoRule.java index 6665bce7c30..fd08072b00b 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/rule/GeoRule.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/rule/GeoRule.java @@ -1,18 +1,22 @@ package org.prebid.server.activity.infrastructure.rule; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import lombok.Value; import org.apache.commons.lang3.StringUtils; import org.prebid.server.activity.ComponentType; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; -import org.prebid.server.activity.infrastructure.payload.GeoActivityCallPayload; -import org.prebid.server.activity.infrastructure.payload.GpcActivityCallPayload; +import org.prebid.server.activity.infrastructure.debug.Loggable; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.payload.GeoActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.payload.GpcActivityInvocationPayload; import java.util.List; import java.util.Set; -public final class GeoRule extends AbstractMatchRule { +public final class GeoRule extends AbstractMatchRule implements Loggable { - private final ComponentRule componentRule; + private final Set componentTypes; + private final Set componentNames; private final boolean sidsMatched; private final List geoCodes; private final String gpc; @@ -25,7 +29,8 @@ public GeoRule(Set componentTypes, String gpc, boolean allowed) { - this.componentRule = new ComponentRule(componentTypes, componentNames, allowed); + this.componentTypes = componentTypes; + this.componentNames = componentNames; this.sidsMatched = sidsMatched; this.geoCodes = geoCodes; this.gpc = gpc; @@ -33,30 +38,31 @@ public GeoRule(Set componentTypes, } @Override - public boolean matches(ActivityCallPayload activityCallPayload) { + public boolean matches(ActivityInvocationPayload activityInvocationPayload) { return sidsMatched - && (geoCodes == null || matchesOneOfGeoCodes(activityCallPayload)) - && (gpc == null || matchesGpc(activityCallPayload)) - && componentRule.matches(activityCallPayload); + && (geoCodes == null || matchesOneOfGeoCodes(activityInvocationPayload)) + && (gpc == null || matchesGpc(activityInvocationPayload)) + && (componentTypes == null || componentTypes.contains(activityInvocationPayload.componentType())) + && (componentNames == null || componentNames.contains(activityInvocationPayload.componentName())); } - private boolean matchesOneOfGeoCodes(ActivityCallPayload activityCallPayload) { - if (activityCallPayload instanceof GeoActivityCallPayload geoPayload) { + private boolean matchesOneOfGeoCodes(ActivityInvocationPayload activityInvocationPayload) { + if (activityInvocationPayload instanceof GeoActivityInvocationPayload geoPayload) { return geoCodes.stream().anyMatch(geoCode -> matchesGeoCode(geoCode, geoPayload)); } return true; } - private static boolean matchesGeoCode(GeoCode geoCode, GeoActivityCallPayload geoPayload) { + private static boolean matchesGeoCode(GeoCode geoCode, GeoActivityInvocationPayload geoPayload) { final String region = geoCode.getRegion(); return StringUtils.equalsIgnoreCase(geoCode.getCountry(), geoPayload.country()) && (region == null || StringUtils.equalsIgnoreCase(region, geoPayload.region())); } - private boolean matchesGpc(ActivityCallPayload activityCallPayload) { - if (activityCallPayload instanceof GpcActivityCallPayload gpcActivityCallPayload) { - return gpc.equals(gpcActivityCallPayload.gpc()); + private boolean matchesGpc(ActivityInvocationPayload activityInvocationPayload) { + if (activityInvocationPayload instanceof GpcActivityInvocationPayload gpcActivityInvocationPayload) { + return gpc.equals(gpcActivityInvocationPayload.gpc()); } return true; @@ -67,6 +73,17 @@ public boolean allowed() { return allowed; } + @Override + public JsonNode asLogEntry(ObjectMapper mapper) { + return mapper.valueToTree(new GeoRuleLogEntry( + componentTypes, + componentNames, + sidsMatched, + geoCodes, + gpc, + allowed)); + } + @Value(staticConstructor = "of") public static class GeoCode { @@ -74,4 +91,12 @@ public static class GeoCode { String region; } + + private record GeoRuleLogEntry(Set componentTypes, + Set componentNames, + boolean gppSidsMatched, + List geoCodes, + String gpc, + boolean allow) { + } } diff --git a/src/main/java/org/prebid/server/activity/infrastructure/rule/Rule.java b/src/main/java/org/prebid/server/activity/infrastructure/rule/Rule.java index 1bd9364ec40..106f18674ac 100644 --- a/src/main/java/org/prebid/server/activity/infrastructure/rule/Rule.java +++ b/src/main/java/org/prebid/server/activity/infrastructure/rule/Rule.java @@ -1,10 +1,10 @@ package org.prebid.server.activity.infrastructure.rule; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; public interface Rule { - Result proceed(ActivityCallPayload activityCallPayload); + Result proceed(ActivityInvocationPayload activityInvocationPayload); enum Result { diff --git a/src/main/java/org/prebid/server/analytics/reporter/AnalyticsReporterDelegator.java b/src/main/java/org/prebid/server/analytics/reporter/AnalyticsReporterDelegator.java index 37082e4d684..a1e66811e36 100644 --- a/src/main/java/org/prebid/server/analytics/reporter/AnalyticsReporterDelegator.java +++ b/src/main/java/org/prebid/server/analytics/reporter/AnalyticsReporterDelegator.java @@ -16,9 +16,9 @@ import org.prebid.server.activity.Activity; import org.prebid.server.activity.ComponentType; import org.prebid.server.activity.infrastructure.ActivityInfrastructure; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; -import org.prebid.server.activity.infrastructure.payload.impl.ActivityCallPayloadImpl; -import org.prebid.server.activity.infrastructure.payload.impl.BidRequestActivityCallPayload; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.payload.impl.ActivityInvocationPayloadImpl; +import org.prebid.server.activity.infrastructure.payload.impl.BidRequestActivityInvocationPayload; import org.prebid.server.analytics.AnalyticsReporter; import org.prebid.server.analytics.model.AmpEvent; import org.prebid.server.analytics.model.AuctionEvent; @@ -162,32 +162,36 @@ private static boolean isNotEmptyObjectNode(JsonNode analytics) { private static boolean isAllowedAdapter(T event, String adapter) { final ActivityInfrastructure activityInfrastructure; - final ActivityCallPayload activityCallPayload; + final ActivityInvocationPayload activityInvocationPayload; if (event instanceof AuctionEvent auctionEvent) { final AuctionContext auctionContext = auctionEvent.getAuctionContext(); activityInfrastructure = auctionContext != null ? auctionContext.getActivityInfrastructure() : null; - activityCallPayload = auctionContext != null - ? BidRequestActivityCallPayload.of(activityCallPayload(adapter), auctionContext.getBidRequest()) + activityInvocationPayload = auctionContext != null + ? BidRequestActivityInvocationPayload.of( + activityInvocationPayload(adapter), + auctionContext.getBidRequest()) : null; } else if (event instanceof AmpEvent ampEvent) { final AuctionContext auctionContext = ampEvent.getAuctionContext(); activityInfrastructure = auctionContext != null ? auctionContext.getActivityInfrastructure() : null; - activityCallPayload = auctionContext != null - ? BidRequestActivityCallPayload.of(activityCallPayload(adapter), auctionContext.getBidRequest()) + activityInvocationPayload = auctionContext != null + ? BidRequestActivityInvocationPayload.of( + activityInvocationPayload(adapter), + auctionContext.getBidRequest()) : null; } else if (event instanceof NotificationEvent notificationEvent) { activityInfrastructure = notificationEvent.getActivityInfrastructure(); - activityCallPayload = activityCallPayload(adapter); + activityInvocationPayload = activityInvocationPayload(adapter); } else { activityInfrastructure = null; - activityCallPayload = null; + activityInvocationPayload = null; } - return isAllowedActivity(activityInfrastructure, Activity.REPORT_ANALYTICS, activityCallPayload); + return isAllowedActivity(activityInfrastructure, Activity.REPORT_ANALYTICS, activityInvocationPayload); } - private static ActivityCallPayload activityCallPayload(String adapterName) { - return ActivityCallPayloadImpl.of(ComponentType.ANALYTICS, adapterName); + private static ActivityInvocationPayload activityInvocationPayload(String adapterName) { + return ActivityInvocationPayloadImpl.of(ComponentType.ANALYTICS, adapterName); } private T updateEvent(T event, String adapter) { @@ -222,14 +226,14 @@ private BidRequest updateBidRequest(BidRequest bidRequest, String adapter, ActivityInfrastructure infrastructure) { - final ActivityCallPayload activityCallPayload = BidRequestActivityCallPayload.of( - activityCallPayload(adapter), + final ActivityInvocationPayload activityInvocationPayload = BidRequestActivityInvocationPayload.of( + activityInvocationPayload(adapter), bidRequest); final boolean disallowTransmitUfpd = !isAllowedActivity( - infrastructure, Activity.TRANSMIT_UFPD, activityCallPayload); + infrastructure, Activity.TRANSMIT_UFPD, activityInvocationPayload); final boolean disallowTransmitGeo = !isAllowedActivity( - infrastructure, Activity.TRANSMIT_GEO, activityCallPayload); + infrastructure, Activity.TRANSMIT_GEO, activityInvocationPayload); final User user = bidRequest != null ? bidRequest.getUser() : null; final User resolvedUser = privacyEnforcementService @@ -253,10 +257,10 @@ private BidRequest updateBidRequest(BidRequest bidRequest, private static boolean isAllowedActivity(ActivityInfrastructure activityInfrastructure, Activity activity, - ActivityCallPayload activityCallPayload) { + ActivityInvocationPayload activityInvocationPayload) { return activityInfrastructure != null - ? activityInfrastructure.isAllowed(activity, activityCallPayload) + ? activityInfrastructure.isAllowed(activity, activityInvocationPayload) : ActivityInfrastructure.ALLOW_ACTIVITY_BY_DEFAULT; } diff --git a/src/main/java/org/prebid/server/auction/BidResponseCreator.java b/src/main/java/org/prebid/server/auction/BidResponseCreator.java index e8ba23f669a..dd59ceaa6b7 100644 --- a/src/main/java/org/prebid/server/auction/BidResponseCreator.java +++ b/src/main/java/org/prebid/server/auction/BidResponseCreator.java @@ -86,6 +86,7 @@ import org.prebid.server.proto.openrtb.ext.response.ExtHttpCall; 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.ExtTraceDeal; import org.prebid.server.proto.openrtb.ext.response.FledgeAuctionConfig; import org.prebid.server.proto.openrtb.ext.response.seatnonbid.NonBid; @@ -841,8 +842,6 @@ private static ExtResponseDebug toExtResponseDebug(List bidd CacheServiceResult cacheResult, boolean debugEnabled) { - final DeepDebugLog deepDebugLog = auctionContext.getDeepDebugLog(); - final Map> httpCalls = debugEnabled ? toExtHttpCalls(bidderResponseInfos, cacheResult, auctionContext.getDebugHttpCalls()) : null; @@ -851,7 +850,7 @@ private static ExtResponseDebug toExtResponseDebug(List bidd final ExtDebugPgmetrics extDebugPgmetrics = debugEnabled ? toExtDebugPgmetrics( auctionContext.getTxnLog()) : null; - final ExtDebugTrace extDebugTrace = deepDebugLog.isDeepDebugEnabled() ? toExtDebugTrace(deepDebugLog) : null; + final ExtDebugTrace extDebugTrace = toExtDebugTrace(auctionContext); return ObjectUtils.anyNotNull(httpCalls, bidRequest, extDebugPgmetrics, extDebugTrace) ? ExtResponseDebug.of(httpCalls, bidRequest, extDebugPgmetrics, extDebugTrace) @@ -976,19 +975,36 @@ private static ExtDebugPgmetrics toExtDebugPgmetrics(TxnLog txnLog) { return extDebugPgmetrics.equals(ExtDebugPgmetrics.EMPTY) ? null : extDebugPgmetrics; } - private static ExtDebugTrace toExtDebugTrace(DeepDebugLog deepDebugLog) { - final List entries = deepDebugLog.entries(); + private static ExtDebugTrace toExtDebugTrace(AuctionContext auctionContext) { + final DeepDebugLog deepDebugLog = auctionContext.getDeepDebugLog(); + + final boolean dealsTraceEnabled = deepDebugLog.isDeepDebugEnabled(); + final boolean activityInfrastructureTraceEnabled = auctionContext.getDebugContext().getTraceLevel() != null; + if (!dealsTraceEnabled && !activityInfrastructureTraceEnabled) { + return null; + } - final List dealsTrace = entries.stream() + final List entries = dealsTraceEnabled ? deepDebugLog.entries() : null; + final List dealsTrace = dealsTraceEnabled + ? entries.stream() .filter(extTraceDeal -> StringUtils.isEmpty(extTraceDeal.getLineItemId())) - .toList(); - final Map> lineItemsTrace = entries.stream() + .toList() + : null; + final Map> lineItemsTrace = dealsTraceEnabled + ? entries.stream() .filter(extTraceDeal -> StringUtils.isNotEmpty(extTraceDeal.getLineItemId())) - .collect(Collectors.groupingBy(ExtTraceDeal::getLineItemId, Collectors.toList())); + .collect(Collectors.groupingBy(ExtTraceDeal::getLineItemId, Collectors.toList())) + : null; + + final List activityInfrastructureTrace = activityInfrastructureTraceEnabled + ? new ArrayList<>(auctionContext.getActivityInfrastructure().debugTrace()) + : null; - return CollectionUtils.isNotEmpty(entries) - ? ExtDebugTrace.of(CollectionUtils.isEmpty(dealsTrace) ? null : dealsTrace, - MapUtils.isEmpty(lineItemsTrace) ? null : lineItemsTrace) + return CollectionUtils.isNotEmpty(entries) || CollectionUtils.isNotEmpty(activityInfrastructureTrace) + ? ExtDebugTrace.of( + CollectionUtils.isEmpty(dealsTrace) ? null : dealsTrace, + MapUtils.isEmpty(lineItemsTrace) ? null : lineItemsTrace, + CollectionUtils.isEmpty(activityInfrastructureTrace) ? null : activityInfrastructureTrace) : null; } diff --git a/src/main/java/org/prebid/server/auction/ExchangeService.java b/src/main/java/org/prebid/server/auction/ExchangeService.java index 8702ced897d..769ac37f55b 100644 --- a/src/main/java/org/prebid/server/auction/ExchangeService.java +++ b/src/main/java/org/prebid/server/auction/ExchangeService.java @@ -31,9 +31,9 @@ import org.prebid.server.activity.Activity; import org.prebid.server.activity.ComponentType; import org.prebid.server.activity.infrastructure.ActivityInfrastructure; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; -import org.prebid.server.activity.infrastructure.payload.impl.ActivityCallPayloadImpl; -import org.prebid.server.activity.infrastructure.payload.impl.BidRequestActivityCallPayload; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.payload.impl.ActivityInvocationPayloadImpl; +import org.prebid.server.activity.infrastructure.payload.impl.BidRequestActivityInvocationPayload; import org.prebid.server.auction.adjustment.BidAdjustmentFactorResolver; import org.prebid.server.auction.mediatypeprocessor.MediaTypeProcessingResult; import org.prebid.server.auction.mediatypeprocessor.MediaTypeProcessor; @@ -478,8 +478,8 @@ private Map makeBidRejectionTrackers(BidRequest bid } return bidderToImpIds.entrySet().stream().collect(Collectors.toMap( - Map.Entry::getKey, - entry -> new BidRejectionTracker(entry.getKey(), entry.getValue(), logSamplingRate))); + Map.Entry::getKey, + entry -> new BidRejectionTracker(entry.getKey(), entry.getValue(), logSamplingRate))); } /** @@ -564,13 +564,13 @@ private boolean isValidBidder(String bidder, BidderAliases aliases) { private static boolean isBidderCallActivityAllowed(String bidder, AuctionContext auctionContext) { final ActivityInfrastructure activityInfrastructure = auctionContext.getActivityInfrastructure(); - final ActivityCallPayload activityCallPayload = BidRequestActivityCallPayload.of( - ActivityCallPayloadImpl.of(ComponentType.BIDDER, bidder), + final ActivityInvocationPayload activityInvocationPayload = BidRequestActivityInvocationPayload.of( + ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, bidder), auctionContext.getBidRequest()); return activityInfrastructure.isAllowed( Activity.CALL_BIDDER, - activityCallPayload); + activityInvocationPayload); } /** @@ -941,8 +941,8 @@ private static boolean transmitTransactionId(String bidder, AuctionContext conte .orElse(null); if (createTids == null) { - final ActivityCallPayload payload = BidRequestActivityCallPayload.of( - ActivityCallPayloadImpl.of(ComponentType.BIDDER, bidder), + final ActivityInvocationPayload payload = BidRequestActivityInvocationPayload.of( + ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, bidder), bidRequest); return context.getActivityInfrastructure().isAllowed(Activity.TRANSMIT_TID, payload); @@ -1191,14 +1191,14 @@ private ExtRequest prepareExt(String bidder, .orElse(ExtRequestPrebid.builder()); return ExtRequest.of(extPrebidBuilder - .multibid(resolveExtRequestMultiBids(bidderToMultiBid.get(bidder), bidder)) - .bidders(bidders) - .bidderparams(prepareBidderParameters(extPrebid, bidder)) - .schains(null) - .data(null) - .bidderconfig(null) - .aliases(null) - .build()); + .multibid(resolveExtRequestMultiBids(bidderToMultiBid.get(bidder), bidder)) + .bidders(bidders) + .bidderparams(prepareBidderParameters(extPrebid, bidder)) + .schains(null) + .data(null) + .bidderconfig(null) + .aliases(null) + .build()); } private List resolveExtRequestMultiBids(MultiBidConfig multiBidConfig, diff --git a/src/main/java/org/prebid/server/auction/PrivacyEnforcementService.java b/src/main/java/org/prebid/server/auction/PrivacyEnforcementService.java index 4b0d1c4c0fc..efa24cf805e 100644 --- a/src/main/java/org/prebid/server/auction/PrivacyEnforcementService.java +++ b/src/main/java/org/prebid/server/auction/PrivacyEnforcementService.java @@ -16,9 +16,9 @@ import org.prebid.server.activity.Activity; import org.prebid.server.activity.ComponentType; import org.prebid.server.activity.infrastructure.ActivityInfrastructure; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; -import org.prebid.server.activity.infrastructure.payload.impl.ActivityCallPayloadImpl; -import org.prebid.server.activity.infrastructure.payload.impl.PrivacyEnforcementServiceActivityCallPayload; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.payload.impl.ActivityInvocationPayloadImpl; +import org.prebid.server.activity.infrastructure.payload.impl.PrivacyEnforcementServiceActivityInvocationPayload; import org.prebid.server.auction.model.AuctionContext; import org.prebid.server.auction.model.BidderPrivacyResult; import org.prebid.server.auction.model.IpAddress; @@ -700,19 +700,20 @@ private BidderPrivacyResult applyActivityRestrictions(BidderPrivacyResult bidder final Device device = bidderPrivacyResult.getDevice(); final Geo geo = device != null ? device.getGeo() : null; - final ActivityCallPayload activityCallPayload = PrivacyEnforcementServiceActivityCallPayload.of( - ActivityCallPayloadImpl.of(ComponentType.BIDDER, bidder), - geo != null ? geo.getCountry() : null, - geo != null ? geo.getRegion() : null, - Optional.ofNullable(auctionContext.getBidRequest().getRegs()) - .map(Regs::getExt) - .map(ExtRegs::getGpc) - .orElse(null)); + final ActivityInvocationPayload activityInvocationPayload = + PrivacyEnforcementServiceActivityInvocationPayload.of( + ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, bidder), + geo != null ? geo.getCountry() : null, + geo != null ? geo.getRegion() : null, + Optional.ofNullable(auctionContext.getBidRequest().getRegs()) + .map(Regs::getExt) + .map(ExtRegs::getGpc) + .orElse(null)); final boolean disallowTransmitUfpd = !activityInfrastructure.isAllowed( - Activity.TRANSMIT_UFPD, activityCallPayload); + Activity.TRANSMIT_UFPD, activityInvocationPayload); final boolean disallowTransmitGeo = !activityInfrastructure.isAllowed( - Activity.TRANSMIT_GEO, activityCallPayload); + Activity.TRANSMIT_GEO, activityInvocationPayload); final User resolvedUser = disallowTransmitUfpd || disallowTransmitGeo ? maskUserConsideringActivityRestrictions(user, disallowTransmitUfpd, disallowTransmitGeo) 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 44e65e0e5f2..02c8e2b2908 100644 --- a/src/main/java/org/prebid/server/auction/requestfactory/Ortb2RequestFactory.java +++ b/src/main/java/org/prebid/server/auction/requestfactory/Ortb2RequestFactory.java @@ -188,7 +188,7 @@ public Future activityInfrastructureFrom(AuctionContext return Future.succeededFuture(activityInfrastructureCreator.create( auctionContext.getAccount(), auctionContext.getGppContext(), - ObjectUtils.defaultIfNull(auctionContext.getDebugContext().getTraceLevel(), TraceLevel.basic))); + auctionContext.getDebugContext().getTraceLevel())); } public Future validateRequest(BidRequest bidRequest, diff --git a/src/main/java/org/prebid/server/cookie/CookieSyncService.java b/src/main/java/org/prebid/server/cookie/CookieSyncService.java index ca05904c4a8..8f935738ae9 100644 --- a/src/main/java/org/prebid/server/cookie/CookieSyncService.java +++ b/src/main/java/org/prebid/server/cookie/CookieSyncService.java @@ -9,8 +9,8 @@ import org.apache.commons.lang3.StringUtils; import org.prebid.server.activity.Activity; import org.prebid.server.activity.ComponentType; -import org.prebid.server.activity.infrastructure.payload.impl.ActivityCallPayloadImpl; -import org.prebid.server.activity.infrastructure.payload.impl.TcfContextActivityCallPayload; +import org.prebid.server.activity.infrastructure.payload.impl.ActivityInvocationPayloadImpl; +import org.prebid.server.activity.infrastructure.payload.impl.TcfContextActivityInvocationPayload; import org.prebid.server.auction.PrivacyEnforcementService; import org.prebid.server.bidder.BidderCatalog; import org.prebid.server.bidder.BidderInfo; @@ -330,8 +330,8 @@ private CookieSyncContext filterDisallowedActivities(CookieSyncContext cookieSyn cookieSyncContext, bidder -> !cookieSyncContext.getActivityInfrastructure().isAllowed( Activity.SYNC_USER, - TcfContextActivityCallPayload.of( - ActivityCallPayloadImpl.of(ComponentType.BIDDER, bidder), + TcfContextActivityInvocationPayload.of( + ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, bidder), tcfContext)), RejectionReason.DISALLOWED_ACTIVITY); } diff --git a/src/main/java/org/prebid/server/handler/CookieSyncHandler.java b/src/main/java/org/prebid/server/handler/CookieSyncHandler.java index 196554c7655..6b96c22c408 100644 --- a/src/main/java/org/prebid/server/handler/CookieSyncHandler.java +++ b/src/main/java/org/prebid/server/handler/CookieSyncHandler.java @@ -169,7 +169,7 @@ private CookieSyncContext fillWithActivityInfrastructure(CookieSyncContext cooki .activityInfrastructure(activityInfrastructureCreator.create( cookieSyncContext.getAccount(), cookieSyncContext.getGppContext(), - TraceLevel.basic)) + cookieSyncContext.isDebug() ? TraceLevel.verbose : null)) .build(); } diff --git a/src/main/java/org/prebid/server/handler/NotificationEventHandler.java b/src/main/java/org/prebid/server/handler/NotificationEventHandler.java index 34406afcc24..383b0cf7455 100644 --- a/src/main/java/org/prebid/server/handler/NotificationEventHandler.java +++ b/src/main/java/org/prebid/server/handler/NotificationEventHandler.java @@ -27,7 +27,6 @@ import org.prebid.server.execution.TimeoutFactory; import org.prebid.server.model.Endpoint; import org.prebid.server.model.HttpRequestContext; -import org.prebid.server.proto.openrtb.ext.request.TraceLevel; import org.prebid.server.settings.ApplicationSettings; import org.prebid.server.settings.model.Account; import org.prebid.server.settings.model.AccountAuctionConfig; @@ -198,7 +197,7 @@ private ActivityInfrastructure activityInfrastructure(Account account) { return activityInfrastructureCreator.create( account, GppContextCreator.from(null, null).build().getGppContext(), - TraceLevel.basic); + null); } private void respondWithOk(RoutingContext routingContext, boolean respondWithPixel) { diff --git a/src/main/java/org/prebid/server/handler/SetuidHandler.java b/src/main/java/org/prebid/server/handler/SetuidHandler.java index cfa7e8160df..f2ee07f03f2 100644 --- a/src/main/java/org/prebid/server/handler/SetuidHandler.java +++ b/src/main/java/org/prebid/server/handler/SetuidHandler.java @@ -17,9 +17,9 @@ import org.prebid.server.activity.ComponentType; import org.prebid.server.activity.infrastructure.ActivityInfrastructure; import org.prebid.server.activity.infrastructure.creator.ActivityInfrastructureCreator; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; -import org.prebid.server.activity.infrastructure.payload.impl.ActivityCallPayloadImpl; -import org.prebid.server.activity.infrastructure.payload.impl.TcfContextActivityCallPayload; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.payload.impl.ActivityInvocationPayloadImpl; +import org.prebid.server.activity.infrastructure.payload.impl.TcfContextActivityInvocationPayload; import org.prebid.server.analytics.model.SetuidEvent; import org.prebid.server.analytics.reporter.AnalyticsReporterDelegator; import org.prebid.server.auction.PrivacyEnforcementService; @@ -47,7 +47,6 @@ import org.prebid.server.privacy.gdpr.model.PrivacyEnforcementAction; import org.prebid.server.privacy.gdpr.model.TcfContext; import org.prebid.server.privacy.gdpr.model.TcfResponse; -import org.prebid.server.proto.openrtb.ext.request.TraceLevel; import org.prebid.server.settings.ApplicationSettings; import org.prebid.server.settings.model.Account; import org.prebid.server.util.HttpUtil; @@ -167,7 +166,7 @@ private SetuidContext fillWithActivityInfrastructure(SetuidContext setuidContext .activityInfrastructure(activityInfrastructureCreator.create( setuidContext.getAccount(), setuidContext.getGppContext(), - TraceLevel.basic)) + null)) .build(); } @@ -214,11 +213,11 @@ private void validateSetuidContext(SetuidContext setuidContext, String bidder) { } final ActivityInfrastructure activityInfrastructure = setuidContext.getActivityInfrastructure(); - final ActivityCallPayload activityCallPayload = TcfContextActivityCallPayload.of( - ActivityCallPayloadImpl.of(ComponentType.BIDDER, bidder), + final ActivityInvocationPayload activityInvocationPayload = TcfContextActivityInvocationPayload.of( + ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, bidder), tcfContext); - if (!activityInfrastructure.isAllowed(Activity.SYNC_USER, activityCallPayload)) { + if (!activityInfrastructure.isAllowed(Activity.SYNC_USER, activityInvocationPayload)) { throw new UnavailableForLegalReasonsException(); } } diff --git a/src/main/java/org/prebid/server/metric/Metrics.java b/src/main/java/org/prebid/server/metric/Metrics.java index 30ac75993b0..52952734938 100644 --- a/src/main/java/org/prebid/server/metric/Metrics.java +++ b/src/main/java/org/prebid/server/metric/Metrics.java @@ -716,11 +716,11 @@ public void updateAdapterActivityDisallowedCount(String adapter, Activity activi forAdapter(adapter).activities().forActivity(activity).incCounter(MetricName.disallowed_count); } - public void updateRequestsActivityProcessedRulesCount(int count) { - requests().activities().incCounter(MetricName.processed_rules_count, count); + public void updateRequestsActivityProcessedRulesCount() { + requests().activities().incCounter(MetricName.processed_rules_count); } - public void updateAccountActivityProcessedRulesCount(String account, int count) { - forAccount(account).activities().incCounter(MetricName.processed_rules_count, count); + public void updateAccountActivityProcessedRulesCount(String account) { + forAccount(account).activities().incCounter(MetricName.processed_rules_count); } } diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtDebugTrace.java b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtDebugTrace.java index f672e3d89c7..e1b047beac1 100644 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtDebugTrace.java +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtDebugTrace.java @@ -25,4 +25,6 @@ public class ExtDebugTrace { @JsonProperty("lineitems") Map> lineItems; + + List activityInfrastructure; } diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityInfrastructure.java b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityInfrastructure.java new file mode 100644 index 00000000000..155397d8050 --- /dev/null +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityInfrastructure.java @@ -0,0 +1,13 @@ +package org.prebid.server.proto.openrtb.ext.response; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public sealed interface ExtTraceActivityInfrastructure permits + ExtTraceActivityInvocation, + ExtTraceActivityInvocationDefaultResult, + ExtTraceActivityRule, + ExtTraceActivityInvocationResult { + + @JsonProperty(index = 0) + String getDescription(); +} diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityInvocation.java b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityInvocation.java new file mode 100644 index 00000000000..dca4007cf9e --- /dev/null +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityInvocation.java @@ -0,0 +1,15 @@ +package org.prebid.server.proto.openrtb.ext.response; + +import lombok.Value; +import org.prebid.server.activity.Activity; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; + +@Value(staticConstructor = "of") +public class ExtTraceActivityInvocation implements ExtTraceActivityInfrastructure { + + String description; + + Activity activity; + + ActivityInvocationPayload activityInvocationPayload; +} diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityInvocationDefaultResult.java b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityInvocationDefaultResult.java new file mode 100644 index 00000000000..d972f0de7de --- /dev/null +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityInvocationDefaultResult.java @@ -0,0 +1,11 @@ +package org.prebid.server.proto.openrtb.ext.response; + +import lombok.Value; + +@Value(staticConstructor = "of") +public class ExtTraceActivityInvocationDefaultResult implements ExtTraceActivityInfrastructure { + + String description; + + boolean allowByDefault; +} diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityInvocationResult.java b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityInvocationResult.java new file mode 100644 index 00000000000..cca8fa99f4e --- /dev/null +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityInvocationResult.java @@ -0,0 +1,14 @@ +package org.prebid.server.proto.openrtb.ext.response; + +import lombok.Value; +import org.prebid.server.activity.Activity; + +@Value(staticConstructor = "of") +public class ExtTraceActivityInvocationResult implements ExtTraceActivityInfrastructure { + + String description; + + Activity activity; + + boolean allowed; +} diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityRule.java b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityRule.java new file mode 100644 index 00000000000..d3882e18f6a --- /dev/null +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtTraceActivityRule.java @@ -0,0 +1,15 @@ +package org.prebid.server.proto.openrtb.ext.response; + +import com.fasterxml.jackson.databind.JsonNode; +import lombok.Value; +import org.prebid.server.activity.infrastructure.rule.Rule; + +@Value(staticConstructor = "of") +public class ExtTraceActivityRule implements ExtTraceActivityInfrastructure { + + String description; + + JsonNode ruleConfiguration; + + Rule.Result result; +} diff --git a/src/main/java/org/prebid/server/spring/config/ActivityInfrastructureConfiguration.java b/src/main/java/org/prebid/server/spring/config/ActivityInfrastructureConfiguration.java index 03a249b0652..d54fdabb066 100644 --- a/src/main/java/org/prebid/server/spring/config/ActivityInfrastructureConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/ActivityInfrastructureConfiguration.java @@ -11,6 +11,7 @@ import org.prebid.server.activity.infrastructure.creator.rule.GeoRuleCreator; import org.prebid.server.activity.infrastructure.creator.rule.PrivacyModulesRuleCreator; import org.prebid.server.activity.infrastructure.creator.rule.RuleCreator; +import org.prebid.server.json.JacksonMapper; import org.prebid.server.json.JsonLogic; import org.prebid.server.metric.Metrics; import org.springframework.beans.factory.annotation.Value; @@ -86,8 +87,9 @@ ActivityRuleFactory activityRuleFactory(List> ruleCreators) { @Bean ActivityInfrastructureCreator activityInfrastructureCreator(ActivityRuleFactory activityRuleFactory, - Metrics metrics) { + Metrics metrics, + JacksonMapper jacksonMapper) { - return new ActivityInfrastructureCreator(activityRuleFactory, metrics); + return new ActivityInfrastructureCreator(activityRuleFactory, metrics, jacksonMapper); } } diff --git a/src/test/groovy/org/prebid/server/functional/model/response/Debug.groovy b/src/test/groovy/org/prebid/server/functional/model/response/Debug.groovy index 221036460c4..d18f15880ab 100644 --- a/src/test/groovy/org/prebid/server/functional/model/response/Debug.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/response/Debug.groovy @@ -7,6 +7,7 @@ import org.prebid.server.functional.model.request.auction.BidRequest import org.prebid.server.functional.model.request.auction.PgMetrics import org.prebid.server.functional.model.response.auction.DebugPrivacy import org.prebid.server.functional.model.response.auction.BidderCall +import org.prebid.server.functional.model.response.auction.Trace @ToString(includeNames = true, ignoreNulls = true) @JsonNaming(PropertyNamingStrategies.LowerCaseStrategy) @@ -16,6 +17,7 @@ class Debug { BidRequest resolvedRequest DebugPrivacy privacy PgMetrics pgmetrics + Trace trace Map> getBidders() { def result = httpcalls?.findAll { it.key != "cache" } diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/ActivityInfrastructure.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/ActivityInfrastructure.groovy new file mode 100644 index 00000000000..08c716baa67 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/ActivityInfrastructure.groovy @@ -0,0 +1,23 @@ +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 groovy.transform.EqualsAndHashCode +import org.prebid.server.functional.model.request.auction.ActivityType + +@ToString(includeNames = true, ignoreNulls = true) +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy) +@EqualsAndHashCode +class ActivityInfrastructure { + + String description + ActivityType activity + ActivityInvocationPayload activityInvocationPayload + RuleConfiguration ruleConfiguration + Boolean allowByDefault + Boolean allowed + String result + String region + String country +} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/ActivityInvocationPayload.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/ActivityInvocationPayload.groovy new file mode 100644 index 00000000000..960f23af5e9 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/ActivityInvocationPayload.groovy @@ -0,0 +1,18 @@ +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 groovy.transform.EqualsAndHashCode + +@ToString(includeNames = true, ignoreNulls = true) +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy) +@EqualsAndHashCode +class ActivityInvocationPayload { + + String componentType + String componentName + String gpc + String region + String country +} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/And.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/And.groovy new file mode 100644 index 00000000000..4072d3e1f62 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/And.groovy @@ -0,0 +1,11 @@ +package org.prebid.server.functional.model.response.auction + +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +@EqualsAndHashCode +class And { + + List and +} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/GeoCode.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/GeoCode.groovy new file mode 100644 index 00000000000..539a0eabc51 --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/GeoCode.groovy @@ -0,0 +1,12 @@ +package org.prebid.server.functional.model.response.auction + +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString + +@ToString(includeNames = true, ignoreNulls = true) +@EqualsAndHashCode +class GeoCode { + + String country + String region +} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/RuleConfiguration.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/RuleConfiguration.groovy new file mode 100644 index 00000000000..5cf09375f1e --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/RuleConfiguration.groovy @@ -0,0 +1,22 @@ +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 groovy.transform.EqualsAndHashCode + +import static org.prebid.server.functional.model.request.auction.Condition.ConditionType + +@ToString(includeNames = true, ignoreNulls = true) +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy) +@EqualsAndHashCode +class RuleConfiguration { + + List componentNames + List componentTypes + Boolean allow + Boolean gppSidsMatched + String gpc + List geoCodes + List and +} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/Trace.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/Trace.groovy new file mode 100644 index 00000000000..b4e194cd87b --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/Trace.groovy @@ -0,0 +1,12 @@ +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.SnakeCaseStrategy) +class Trace { + + List activityInfrastructure +} diff --git a/src/test/groovy/org/prebid/server/functional/tests/privacy/ActivityTraceLogSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/privacy/ActivityTraceLogSpec.groovy new file mode 100644 index 00000000000..278d6753f9b --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/tests/privacy/ActivityTraceLogSpec.groovy @@ -0,0 +1,388 @@ +package org.prebid.server.functional.tests.privacy + +import org.prebid.server.functional.model.config.AccountGppConfig +import org.prebid.server.functional.model.request.auction.Activity +import org.prebid.server.functional.model.request.auction.ActivityRule +import org.prebid.server.functional.model.request.auction.ActivityType +import org.prebid.server.functional.model.request.auction.AllowActivities +import org.prebid.server.functional.model.request.auction.BidRequest +import org.prebid.server.functional.model.request.auction.Condition +import org.prebid.server.functional.model.request.auction.Device +import org.prebid.server.functional.model.request.auction.Geo +import org.prebid.server.functional.model.response.auction.ActivityInfrastructure +import org.prebid.server.functional.model.response.auction.ActivityInvocationPayload +import org.prebid.server.functional.model.response.auction.And +import org.prebid.server.functional.model.response.auction.GeoCode +import org.prebid.server.functional.model.response.auction.RuleConfiguration +import org.prebid.server.functional.util.PBSUtils +import org.prebid.server.functional.util.privacy.gpp.UspNatV1Consent + +import static org.prebid.server.functional.model.bidder.BidderName.GENERIC +import static org.prebid.server.functional.model.pricefloors.Country.CAN +import static org.prebid.server.functional.model.pricefloors.Country.USA +import static org.prebid.server.functional.model.request.GppSectionId.USP_CA_V1 +import static org.prebid.server.functional.model.request.GppSectionId.USP_CO_V1 +import static org.prebid.server.functional.model.request.auction.ActivityType.FETCH_BIDS +import static org.prebid.server.functional.model.request.auction.ActivityType.TRANSMIT_PRECISE_GEO +import static org.prebid.server.functional.model.request.auction.ActivityType.TRANSMIT_TID +import static org.prebid.server.functional.model.request.auction.ActivityType.TRANSMIT_UFPD +import static org.prebid.server.functional.model.request.auction.Condition.ConditionType.BIDDER +import static org.prebid.server.functional.model.request.auction.PrivacyModule.IAB_US_GENERAL +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.util.privacy.model.State.ALABAMA +import static org.prebid.server.functional.util.privacy.model.State.ARIZONA + +class ActivityTraceLogSpec extends PrivacyBaseSpec { + + + private static final def TRIGGERING_ACTIVITY_TRACE = ["Invocation of Activity Infrastructure.", + "Setting the default invocation result.", + "Activity Infrastructure invocation result."] + + private static final def PROCESSING_ACTIVITY_TRACE = ["Processing rule."] + + def "PBS auction shouldn't log info about activity in response when ext.prebid.trace=null"() { + given: "Default basic generic BidRequest" + def accountId = PBSUtils.randomNumber as String + def bidRequest = BidRequest.defaultBidRequest.tap { + ext.prebid.trace = null + setAccountId(accountId) + } + + and: "Activities set with all bidders allowed" + def activities = AllowActivities.getDefaultAllowActivities(FETCH_BIDS, Activity.defaultActivity) + + and: "Existed account with allow activities setup" + def account = getAccountWithAllowActivitiesAndPrivacyModule(accountId, activities) + accountDao.save(account) + + when: "PBS processes auction requests" + def bidResponse = activityPbsService.sendAuctionRequest(bidRequest) + + then: "Bid response shouldn't contain trace" + assert !bidResponse.ext.debug.trace + } + + def "PBS auction should log info about activity in response when ext.prebid.trace=base and allow=false"() { + given: "Default basic generic BidRequest" + def accountId = PBSUtils.randomNumber as String + def bidRequest = BidRequest.defaultBidRequest.tap { + ext.prebid.trace = BASIC + device = new Device(geo: new Geo(country: USA, region: ALABAMA.abbreviation)) + setAccountId(accountId) + } + + and: "Activities set with all bidders rejected" + def allow = false + def activity = Activity.getDefaultActivity([ActivityRule.getDefaultActivityRule(Condition.baseCondition, allow)]) + def activities = AllowActivities.getDefaultAllowActivities(FETCH_BIDS, activity) + + and: "Save account with allow activities setup" + def account = getAccountWithAllowActivitiesAndPrivacyModule(accountId, activities) + accountDao.save(account) + + when: "PBS processes auction requests" + def bidResponse = activityPbsService.sendAuctionRequest(bidRequest) + + then: "Bid response should contain basic info in debug" + def infrastructure = bidResponse.ext.debug.trace.activityInfrastructure + def fetchBidsActivity = getActivityByName(infrastructure, FETCH_BIDS) + assert fetchBidsActivity.description.containsAll(TRIGGERING_ACTIVITY_TRACE) + assert fetchBidsActivity.description.containsAll(PROCESSING_ACTIVITY_TRACE) + assert fetchBidsActivity.activityInvocationPayload.every { it == null } + assert fetchBidsActivity.ruleConfiguration.every { it == null } + assert fetchBidsActivity.allowByDefault.contains(activity.defaultAction) + assert fetchBidsActivity.result.contains("DISALLOW") + assert fetchBidsActivity.country.every { it == null } + assert fetchBidsActivity.region.every { it == null } + } + + def "PBS auction should log info about activity in response when ext.prebid.trace=base and allow=true"() { + given: "Default basic generic BidRequest" + def accountId = PBSUtils.randomNumber as String + def bidRequest = BidRequest.defaultBidRequest.tap { + ext.prebid.trace = BASIC + device = new Device(geo: new Geo(country: USA, region: ALABAMA.abbreviation)) + setAccountId(accountId) + } + + and: "Set up activities" + def allow = true + def activity = Activity.getDefaultActivity([ActivityRule.getDefaultActivityRule(Condition.baseCondition, allow)]) + def activities = AllowActivities.getDefaultAllowActivities(FETCH_BIDS, activity) + + and: "Save account with allow activities setup" + def account = getAccountWithAllowActivitiesAndPrivacyModule(accountId, activities) + accountDao.save(account) + + when: "PBS processes auction requests" + def bidResponse = pbsServiceFactory.getService(PBS_CONFIG).sendAuctionRequest(bidRequest) + + then: "Bid response should contain basic info in debug" + def infrastructure = bidResponse.ext.debug.trace.activityInfrastructure + + and: "fetchBids should contain triggering and processing activity trace with allow result" + def fetchBidsActivity = getActivityByName(infrastructure, FETCH_BIDS) + assert fetchBidsActivity.description.containsAll(PROCESSING_ACTIVITY_TRACE) + assert fetchBidsActivity.description.containsAll(TRIGGERING_ACTIVITY_TRACE) + assert fetchBidsActivity.activityInvocationPayload.every { it == null } + assert fetchBidsActivity.allowByDefault.contains(activity.defaultAction) + assert fetchBidsActivity.ruleConfiguration.every { it == null } + assert fetchBidsActivity.result.contains("ALLOW") + assert fetchBidsActivity.country.every { it == null } + assert fetchBidsActivity.region.every { it == null } + + and: "transmitUfpd should contain only triggering activity trace without result status" + def transmitUfpdActivity = getActivityByName(infrastructure, TRANSMIT_UFPD) + assert !transmitUfpdActivity.description.containsAll(PROCESSING_ACTIVITY_TRACE) + assert transmitUfpdActivity.description.containsAll(TRIGGERING_ACTIVITY_TRACE) + assert transmitUfpdActivity.activityInvocationPayload.every { it == null } + assert transmitUfpdActivity.allowByDefault.contains(activity.defaultAction) + assert transmitUfpdActivity.ruleConfiguration.every { it == null } + assert transmitUfpdActivity.result.every { it == null } + assert transmitUfpdActivity.country.every { it == null } + assert transmitUfpdActivity.region.every { it == null } + + and: "transmitPreciseGeo should contain only triggering activity trace without result status" + def transmitPreciseGeoActivity = getActivityByName(infrastructure, TRANSMIT_PRECISE_GEO) + assert !transmitPreciseGeoActivity.description.containsAll(PROCESSING_ACTIVITY_TRACE) + assert transmitPreciseGeoActivity.description.containsAll(TRIGGERING_ACTIVITY_TRACE) + assert transmitPreciseGeoActivity.activityInvocationPayload.every { it == null } + assert transmitPreciseGeoActivity.allowByDefault.contains(activity.defaultAction) + assert transmitPreciseGeoActivity.ruleConfiguration.every { it == null } + assert transmitPreciseGeoActivity.result.every { it == null } + assert transmitPreciseGeoActivity.country.every { it == null } + assert transmitPreciseGeoActivity.region.every { it == null } + + and: "transmitTid should contain only triggering activity trace without result status" + def transmitTidActivity = getActivityByName(infrastructure, TRANSMIT_TID) + assert !transmitTidActivity.description.containsAll(PROCESSING_ACTIVITY_TRACE) + assert transmitTidActivity.description.containsAll(TRIGGERING_ACTIVITY_TRACE) + assert transmitTidActivity.activityInvocationPayload.every { it == null } + assert transmitTidActivity.allowByDefault.contains(activity.defaultAction) + assert transmitTidActivity.ruleConfiguration.every { it == null } + assert transmitTidActivity.result.every { it == null } + assert transmitTidActivity.country.every { it == null } + assert transmitTidActivity.region.every { it == null } + } + + def "PBS auction should log info about activity in response when ext.prebid.trace=verbose and allow=#allow"() { + given: "Default basic generic BidRequest" + def accountId = PBSUtils.randomNumber as String + def bidRequest = BidRequest.defaultBidRequest.tap { + ext.prebid.trace = VERBOSE + device = new Device(geo: new Geo(country: USA, region: ALABAMA.abbreviation)) + regs.ext.gpc = PBSUtils.randomString + regs.gppSid = [USP_CA_V1.intValue] + setAccountId(accountId) + } + + and: "Set up activities" + def gpc = PBSUtils.randomString + def condition = Condition.baseCondition.tap { + it.gppSid = [USP_CO_V1.intValue] + it.gpc = gpc + it.geo = [CAN.withState(ARIZONA)] + } + def activityRule = ActivityRule.getDefaultActivityRule(condition, allow) + def activity = Activity.getDefaultActivity([activityRule]) + def activities = AllowActivities.getDefaultAllowActivities(FETCH_BIDS, activity) + + and: "Save account with allow activities setup" + def account = getAccountWithAllowActivitiesAndPrivacyModule(accountId, activities) + accountDao.save(account) + + when: "PBS processes auction requests" + def bidResponse = activityPbsService.sendAuctionRequest(bidRequest) + + then: "Bid response should contain basic info in debug" + def infrastructure = bidResponse.ext.debug.trace.activityInfrastructure + + and: "fetchBids should contain triggering and processing activity trace with abstain result" + def fetchBidsActivity = getActivityByName(infrastructure, FETCH_BIDS) + assert fetchBidsActivity.description.containsAll(PROCESSING_ACTIVITY_TRACE) + assert fetchBidsActivity.description.containsAll(TRIGGERING_ACTIVITY_TRACE) + assert fetchBidsActivity.activityInvocationPayload.contains(new ActivityInvocationPayload( + componentName: GENERIC.value, + componentType: BIDDER, + gpc: bidRequest.regs.ext.gpc, + region: ALABAMA.abbreviation, + country: USA.value)) + assert fetchBidsActivity.ruleConfiguration.contains(new RuleConfiguration( + componentNames: condition.componentName, + componentTypes: condition.componentType, + allow: allow, + gppSidsMatched: false, + gpc: gpc, + geoCodes: [new GeoCode(country: CAN, region: ARIZONA.abbreviation)])) + assert fetchBidsActivity.allowByDefault.contains(activity.defaultAction) + assert fetchBidsActivity.result.contains("ABSTAIN") + assert fetchBidsActivity.country.every { it == null } + assert fetchBidsActivity.region.every { it == null } + + and: "transmitUfpd should contain only triggering activity trace without result status" + def transmitUfpdActivity = getActivityByName(infrastructure, TRANSMIT_UFPD) + assert !transmitUfpdActivity.description.containsAll(PROCESSING_ACTIVITY_TRACE) + assert transmitUfpdActivity.description.containsAll(TRIGGERING_ACTIVITY_TRACE) + assert transmitUfpdActivity.activityInvocationPayload.contains(new ActivityInvocationPayload( + componentName: GENERIC.value, + componentType: BIDDER, + gpc: bidRequest.regs.ext.gpc, + region: ALABAMA.abbreviation, + country: USA)) + assert transmitUfpdActivity.ruleConfiguration.every { it == null } + assert transmitUfpdActivity.allowByDefault.contains(activity.defaultAction) + assert transmitUfpdActivity.result.every { it == null } + assert transmitUfpdActivity.country.every { it == null } + assert transmitUfpdActivity.region.every { it == null } + + and: "transmitPreciseGeo should contain only triggering activity trace without result status" + def transmitPreciseGeoActivity = getActivityByName(infrastructure, TRANSMIT_PRECISE_GEO) + assert !transmitPreciseGeoActivity.description.containsAll(PROCESSING_ACTIVITY_TRACE) + assert transmitPreciseGeoActivity.description.containsAll(TRIGGERING_ACTIVITY_TRACE) + assert transmitPreciseGeoActivity.activityInvocationPayload.contains(new ActivityInvocationPayload( + componentName: GENERIC.value, + componentType: BIDDER, + gpc: bidRequest.regs.ext.gpc, + region: ALABAMA.abbreviation, + country: USA.value)) + assert transmitPreciseGeoActivity.ruleConfiguration.every { it == null } + assert transmitPreciseGeoActivity.allowByDefault.contains(activity.defaultAction) + assert transmitPreciseGeoActivity.result.every { it == null } + assert transmitPreciseGeoActivity.country.every { it == null } + assert transmitPreciseGeoActivity.region.every { it == null } + + and: "transmitTid should contain only triggering activity trace without result status" + def transmitTidActivity = getActivityByName(infrastructure, TRANSMIT_TID) + assert !transmitTidActivity.description.containsAll(PROCESSING_ACTIVITY_TRACE) + assert transmitTidActivity.description.containsAll(TRIGGERING_ACTIVITY_TRACE) + assert transmitTidActivity.activityInvocationPayload.contains(new ActivityInvocationPayload( + componentName: GENERIC.value, + componentType: BIDDER, + gpc: bidRequest.regs.ext.gpc, + region: ALABAMA.abbreviation, + country: USA)) + assert transmitTidActivity.ruleConfiguration.every { it == null } + assert transmitTidActivity.allowByDefault.contains(activity.defaultAction) + assert transmitTidActivity.result.every { it == null } + assert transmitTidActivity.country.every { it == null } + assert transmitTidActivity.region.every { it == null } + + where: + allow << [false, true] + } + + def "PBS auction should log info about activity in response when ext.prebid.trace=verbose and allow=#allow and privacy module"() { + given: "Default bid request" + def accountId = PBSUtils.randomNumber as String + def bidRequest = BidRequest.defaultBidRequest.tap { + ext.prebid.trace = VERBOSE + device = new Device(geo: new Geo(country: USA, region: ALABAMA.abbreviation)) + regs.ext.gpc = PBSUtils.randomString + regs.gppSid = [USP_CA_V1.intValue] + regs.gpp = new UspNatV1Consent.Builder().setGpc(true).build() + setAccountId(accountId) + } + + and: "Set up activities" + def gpc = PBSUtils.randomString + def condition = Condition.baseCondition.tap { + it.gpc = gpc + it.geo = [CAN.withState(ARIZONA)] + } + def activityRule = ActivityRule.getDefaultActivityRule(condition, allow).tap { + it.privacyRegulation = [IAB_US_GENERAL] + } + def activity = Activity.getDefaultActivity([activityRule]) + def activities = AllowActivities.getDefaultAllowActivities(FETCH_BIDS, activity) + + and: "Account gpp configuration" + def accountGppConfig = new AccountGppConfig(code: IAB_US_GENERAL, enabled: true) + + and: "Save account with allow activities setup" + def account = getAccountWithAllowActivitiesAndPrivacyModule(accountId, activities, [accountGppConfig]) + accountDao.save(account) + + when: "PBS processes auction requests" + def bidResponse = activityPbsService.sendAuctionRequest(bidRequest) + + then: "Bid response should contain verbose info in debug" + def infrastructure = bidResponse.ext.debug.trace.activityInfrastructure + + and: "fetchBids should contain triggering and processing activity trace with abstain result" + def fetchBidsActivity = getActivityByName(infrastructure, FETCH_BIDS) + assert fetchBidsActivity.description.containsAll(PROCESSING_ACTIVITY_TRACE) + assert fetchBidsActivity.description.containsAll(TRIGGERING_ACTIVITY_TRACE) + assert fetchBidsActivity.activityInvocationPayload.contains(new ActivityInvocationPayload( + componentName: GENERIC.value, + componentType: BIDDER, + gpc: bidRequest.regs.ext.gpc, + region: ALABAMA.abbreviation, + country: USA)) + assert fetchBidsActivity.ruleConfiguration.contains(new RuleConfiguration( + and: [new And(and: ["USNatDefault. Precomputed result: ABSTAIN."])])) + assert fetchBidsActivity.allowByDefault.contains(activity.defaultAction) + assert fetchBidsActivity.result.contains("ABSTAIN") + assert fetchBidsActivity.country.every { it == null } + assert fetchBidsActivity.region.every { it == null } + + and: "transmitUfpd should contain only triggering activity trace without result status" + def transmitUfpdActivity = getActivityByName(infrastructure, TRANSMIT_UFPD) + assert transmitUfpdActivity.description.containsAll(TRIGGERING_ACTIVITY_TRACE) + assert transmitUfpdActivity.activityInvocationPayload.contains(new ActivityInvocationPayload( + componentName: GENERIC.value, + componentType: BIDDER, + gpc: bidRequest.regs.ext.gpc, + region: ALABAMA.abbreviation, + country: USA)) + assert transmitUfpdActivity.ruleConfiguration.every { it == null } + assert transmitUfpdActivity.allowByDefault.contains(activity.defaultAction) + assert transmitUfpdActivity.result.every { it == null } + assert transmitUfpdActivity.country.every { it == null } + assert transmitUfpdActivity.region.every { it == null } + + and: "transmitPreciseGeo should contain only triggering activity trace without result status" + def transmitPreciseGeoActivity = getActivityByName(infrastructure, TRANSMIT_PRECISE_GEO) + assert !transmitPreciseGeoActivity.description.containsAll(PROCESSING_ACTIVITY_TRACE) + assert transmitPreciseGeoActivity.description.containsAll(TRIGGERING_ACTIVITY_TRACE) + assert transmitPreciseGeoActivity.activityInvocationPayload.contains(new ActivityInvocationPayload( + componentName: GENERIC.value, + componentType: BIDDER, + gpc: bidRequest.regs.ext.gpc, + region: ALABAMA.abbreviation, + country: USA)) + assert transmitPreciseGeoActivity.ruleConfiguration.every { it == null } + assert transmitPreciseGeoActivity.allowByDefault.contains(activity.defaultAction) + assert transmitPreciseGeoActivity.result.every { it == null } + assert transmitPreciseGeoActivity.country.every { it == null } + assert transmitPreciseGeoActivity.region.every { it == null } + + and: "transmitTid should contain only triggering activity trace without result status" + def transmitTidActivity = getActivityByName(infrastructure, TRANSMIT_TID) + assert !transmitTidActivity.description.containsAll(PROCESSING_ACTIVITY_TRACE) + assert transmitTidActivity.description.containsAll(TRIGGERING_ACTIVITY_TRACE) + assert transmitTidActivity.activityInvocationPayload.contains(new ActivityInvocationPayload( + componentName: GENERIC.value, + componentType: BIDDER, + gpc: bidRequest.regs.ext.gpc, + region: ALABAMA.abbreviation, + country: USA)) + assert transmitTidActivity.ruleConfiguration.every { it == null } + assert transmitTidActivity.allowByDefault.contains(activity.defaultAction) + assert transmitTidActivity.result.every { it == null } + assert transmitTidActivity.country.every { it == null } + assert transmitTidActivity.region.every { it == null } + + where: + allow << [false, true] + } + + private List getActivityByName(List activityInfrastructures, + ActivityType activity) { + def firstIndex = activityInfrastructures.findLastIndexOf { it -> it.activity == activity } + def lastIndex = activityInfrastructures.findIndexOf { it -> it.activity == activity } + activityInfrastructures[new IntRange(true, firstIndex, lastIndex)] + } +} + diff --git a/src/test/java/org/prebid/server/activity/infrastructure/ActivityControllerTest.java b/src/test/java/org/prebid/server/activity/infrastructure/ActivityControllerTest.java index c50d254330e..64cd2579cd7 100644 --- a/src/test/java/org/prebid/server/activity/infrastructure/ActivityControllerTest.java +++ b/src/test/java/org/prebid/server/activity/infrastructure/ActivityControllerTest.java @@ -1,43 +1,82 @@ package org.prebid.server.activity.infrastructure; import org.junit.Test; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.prebid.server.activity.infrastructure.debug.ActivityInfrastructureDebug; +import org.prebid.server.activity.infrastructure.rule.Rule; import org.prebid.server.activity.infrastructure.rule.TestRule; import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.same; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; public class ActivityControllerTest { + @org.junit.Rule + public final MockitoRule mockitoRule = MockitoJUnit.rule(); + + @Mock + private ActivityInfrastructureDebug debug; + @Test - public void isAllowedShouldReturnExpectedResultIfNoRulesMatched() { + public void isAllowedShouldReturnDefaultResultIfAllRulesReturnsAbstain() { + // given + final Rule rule = TestRule.disallowIfMatches(payload -> false); + final ActivityController activityController = ActivityController.of(true, singletonList(rule), debug); + + // when + final boolean result = activityController.isAllowed(null); + + // then + assertThat(result).isTrue(); + verify(debug).emitActivityInvocationDefaultResult(true); + verify(debug).emitProcessedRule(same(rule), eq(Rule.Result.ABSTAIN)); + } + + @Test + public void isAllowedShouldReturnFalse() { // given final ActivityController activityController = ActivityController.of( true, asList( TestRule.allowIfMatches(payload -> false), - TestRule.disallowIfMatches(payload -> false))); + TestRule.disallowIfMatches(payload -> true), + TestRule.disallowIfMatches(payload -> false)), + debug); // when - final ActivityCallResult result = activityController.isAllowed(null); + final boolean result = activityController.isAllowed(null); // then - assertThat(result).isEqualTo(ActivityCallResult.of(true, 2)); + assertThat(result).isFalse(); + verify(debug).emitActivityInvocationDefaultResult(true); + verify(debug, times(2)).emitProcessedRule(any(), any()); } @Test - public void isAllowedShouldReturnExpectedResultIfSomeRuleMatched() { + public void isAllowedShouldReturnTrue() { // given final ActivityController activityController = ActivityController.of( - true, + false, asList( TestRule.allowIfMatches(payload -> false), - TestRule.disallowIfMatches(payload -> true), - TestRule.disallowIfMatches(payload -> false))); + TestRule.allowIfMatches(payload -> true), + TestRule.disallowIfMatches(payload -> false)), + debug); // when - final ActivityCallResult result = activityController.isAllowed(null); + final boolean result = activityController.isAllowed(null); // then - assertThat(result).isEqualTo(ActivityCallResult.of(false, 2)); + assertThat(result).isTrue(); + verify(debug).emitActivityInvocationDefaultResult(false); + verify(debug, times(2)).emitProcessedRule(any(), any()); } } diff --git a/src/test/java/org/prebid/server/activity/infrastructure/ActivityInfrastructureTest.java b/src/test/java/org/prebid/server/activity/infrastructure/ActivityInfrastructureTest.java index fa1ad5beec4..8693239e040 100644 --- a/src/test/java/org/prebid/server/activity/infrastructure/ActivityInfrastructureTest.java +++ b/src/test/java/org/prebid/server/activity/infrastructure/ActivityInfrastructureTest.java @@ -1,5 +1,6 @@ package org.prebid.server.activity.infrastructure; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; @@ -7,12 +8,14 @@ import org.mockito.junit.MockitoRule; import org.prebid.server.activity.Activity; import org.prebid.server.activity.ComponentType; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; -import org.prebid.server.activity.infrastructure.payload.impl.ActivityCallPayloadImpl; -import org.prebid.server.metric.Metrics; -import org.prebid.server.proto.openrtb.ext.request.TraceLevel; +import org.prebid.server.activity.infrastructure.debug.ActivityInfrastructureDebug; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.payload.impl.ActivityInvocationPayloadImpl; +import org.prebid.server.proto.openrtb.ext.response.ExtTraceActivityInfrastructure; import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.function.UnaryOperator; import java.util.stream.Collectors; @@ -20,11 +23,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.same; import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; public class ActivityInfrastructureTest { @@ -36,109 +38,82 @@ public class ActivityInfrastructureTest { private ActivityController activityController; @Mock - private Metrics metrics; + private ActivityInfrastructureDebug debug; + + private ActivityInfrastructure infrastructure; + + @Before + public void setUp() { + infrastructure = new ActivityInfrastructure( + Arrays.stream(Activity.values()) + .collect(Collectors.toMap( + UnaryOperator.identity(), + key -> activityController)), + debug); + } @Test public void creationShouldFailOnInvalidConfiguration() { // when and then assertThatExceptionOfType(AssertionError.class) - .isThrownBy(() -> new ActivityInfrastructure( - "accountId", - Map.of(Activity.CALL_BIDDER, activityController), - TraceLevel.basic, - metrics)); + .isThrownBy(() -> new ActivityInfrastructure(Map.of(Activity.CALL_BIDDER, activityController), debug)); } @Test - public void isAllowedShouldReturnTrueAndUpdateMetrics() { + public void isAllowedShouldReturnFalse() { // given given(activityController.isAllowed(argThat(arg -> arg.componentType().equals(ComponentType.BIDDER)))) - .willReturn(ActivityCallResult.of(true, 3)); + .willReturn(false); - final ActivityInfrastructure infrastructure = activityInfrastructure(TraceLevel.verbose); - final ActivityCallPayload payload = ActivityCallPayloadImpl.of(ComponentType.BIDDER, "bidder"); + final ActivityInvocationPayload payload = ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, "bidder"); // when final boolean result = infrastructure.isAllowed(Activity.CALL_BIDDER, payload); // then - assertThat(result).isEqualTo(true); - - verify(metrics).updateRequestsActivityProcessedRulesCount(eq(3)); - verify(metrics).updateAccountActivityProcessedRulesCount(any(), eq(3)); - verify(metrics, never()).updateRequestsActivityDisallowedCount(any()); - verify(metrics, never()).updateAccountActivityDisallowedCount(any(), any()); - verify(metrics, never()).updateAdapterActivityDisallowedCount(any(), any()); + assertThat(result).isFalse(); } @Test - public void isAllowedShouldNotUpdateMetricsIfAllowedAndZeroProcessedRules() { + public void isAllowedShouldReturnTrue() { // given - given(activityController.isAllowed(any())) - .willReturn(ActivityCallResult.of(true, 0)); + given(activityController.isAllowed(argThat(arg -> arg.componentType().equals(ComponentType.BIDDER)))) + .willReturn(true); - final ActivityInfrastructure infrastructure = activityInfrastructure(TraceLevel.basic); - final ActivityCallPayload payload = ActivityCallPayloadImpl.of(ComponentType.BIDDER, "bidder"); + final ActivityInvocationPayload payload = ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, "bidder"); // when - infrastructure.isAllowed(Activity.CALL_BIDDER, payload); + final boolean result = infrastructure.isAllowed(Activity.CALL_BIDDER, payload); // then - verify(metrics, never()).updateRequestsActivityProcessedRulesCount(anyInt()); - verify(metrics, never()).updateAccountActivityProcessedRulesCount(any(), anyInt()); - verify(metrics, never()).updateRequestsActivityDisallowedCount(any()); - verify(metrics, never()).updateAccountActivityDisallowedCount(any(), any()); - verify(metrics, never()).updateAdapterActivityDisallowedCount(any(), any()); + assertThat(result).isTrue(); } @Test - public void isAllowedShouldUpdateExpectedMetricsIfDisallowedAndTraceLevelIsBasic() { + public void isAllowedShouldEmitDataForDebug() { // given - given(activityController.isAllowed(any())) - .willReturn(ActivityCallResult.of(false, 1)); + given(activityController.isAllowed(any())).willReturn(true); - final ActivityInfrastructure infrastructure = activityInfrastructure(TraceLevel.basic); - final ActivityCallPayload payload = ActivityCallPayloadImpl.of(ComponentType.BIDDER, "bidder"); + final ActivityInvocationPayload payload = ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, "bidder"); // when - infrastructure.isAllowed(Activity.CALL_BIDDER, payload); + final boolean result = infrastructure.isAllowed(Activity.CALL_BIDDER, payload); // then - verify(metrics).updateRequestsActivityProcessedRulesCount(eq(1)); - verify(metrics, never()).updateAccountActivityProcessedRulesCount(any(), anyInt()); - verify(metrics).updateRequestsActivityDisallowedCount(eq(Activity.CALL_BIDDER)); - verify(metrics, never()).updateAccountActivityDisallowedCount(any(), any()); - verify(metrics).updateAdapterActivityDisallowedCount(eq("bidder"), eq(Activity.CALL_BIDDER)); + verify(debug).emitActivityInvocation(eq(Activity.CALL_BIDDER), same(payload)); + verify(debug).emitActivityInvocationResult(eq(Activity.CALL_BIDDER), same(payload), same(result)); } @Test - public void isAllowedShouldUpdateExpectedMetricsIfDisallowedAndTraceLevelIsVerbose() { + public void debugTraceShouldReturnSameTraceLog() { // given - given(activityController.isAllowed(any())) - .willReturn(ActivityCallResult.of(false, 1)); - - final ActivityInfrastructure infrastructure = activityInfrastructure(TraceLevel.verbose); - final ActivityCallPayload payload = ActivityCallPayloadImpl.of(ComponentType.BIDDER, "bidder"); + final List trace = Collections.emptyList(); + given(debug.trace()).willReturn(trace); // when - infrastructure.isAllowed(Activity.CALL_BIDDER, payload); + final List debugTrace = infrastructure.debugTrace(); // then - verify(metrics).updateRequestsActivityProcessedRulesCount(eq(1)); - verify(metrics).updateAccountActivityProcessedRulesCount(eq("accountId"), eq(1)); - verify(metrics).updateRequestsActivityDisallowedCount(eq(Activity.CALL_BIDDER)); - verify(metrics).updateAccountActivityDisallowedCount(eq("accountId"), eq(Activity.CALL_BIDDER)); - verify(metrics).updateAdapterActivityDisallowedCount(eq("bidder"), eq(Activity.CALL_BIDDER)); - } - - private ActivityInfrastructure activityInfrastructure(TraceLevel traceLevel) { - return new ActivityInfrastructure( - "accountId", - Arrays.stream(Activity.values()) - .collect(Collectors.toMap( - UnaryOperator.identity(), - key -> activityController)), - traceLevel, - metrics); + assertThat(debugTrace).isSameAs(trace); } } diff --git a/src/test/java/org/prebid/server/activity/infrastructure/creator/ActivityInfrastructureCreatorTest.java b/src/test/java/org/prebid/server/activity/infrastructure/creator/ActivityInfrastructureCreatorTest.java index 0ef53a2e377..0931afe953e 100644 --- a/src/test/java/org/prebid/server/activity/infrastructure/creator/ActivityInfrastructureCreatorTest.java +++ b/src/test/java/org/prebid/server/activity/infrastructure/creator/ActivityInfrastructureCreatorTest.java @@ -7,12 +7,13 @@ import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.prebid.server.activity.Activity; -import org.prebid.server.activity.infrastructure.ActivityCallResult; import org.prebid.server.activity.infrastructure.ActivityController; import org.prebid.server.activity.infrastructure.ActivityInfrastructure; +import org.prebid.server.activity.infrastructure.debug.ActivityInfrastructureDebug; import org.prebid.server.activity.infrastructure.rule.TestRule; import org.prebid.server.auction.gpp.model.GppContext; import org.prebid.server.auction.gpp.model.GppContextCreator; +import org.prebid.server.json.JacksonMapper; import org.prebid.server.metric.MetricName; import org.prebid.server.metric.Metrics; import org.prebid.server.settings.model.Account; @@ -44,11 +45,17 @@ public class ActivityInfrastructureCreatorTest { @Mock private Metrics metrics; + @Mock + private JacksonMapper jacksonMapper; + + @Mock + private ActivityInfrastructureDebug debug; + private ActivityInfrastructureCreator creator; @Before public void setUp() { - creator = new ActivityInfrastructureCreator(activityRuleFactory, metrics); + creator = new ActivityInfrastructureCreator(activityRuleFactory, metrics, jacksonMapper); } @Test @@ -57,7 +64,7 @@ public void parseShouldReturnExpectedResultIfAccountPrivacyNull() { final Account account = Account.builder().build(); // when - final Map controllers = creator.parse(account, null); + final Map controllers = creator.parse(account, null, debug); // then assertThat(controllers.keySet()).containsExactlyInAnyOrder(Activity.values()); @@ -69,7 +76,7 @@ public void parseShouldReturnExpectedResultIfAccountPrivacyActivitiesNull() { final Account account = Account.builder().privacy(AccountPrivacyConfig.of(null, null, null, null)).build(); // when - final Map controllers = creator.parse(account, null); + final Map controllers = creator.parse(account, null, debug); // then assertThat(controllers.keySet()).containsExactlyInAnyOrder(Activity.values()); @@ -90,12 +97,10 @@ null, singletonList(AccountActivityComponentRuleConfig.of(null, null)))), .build(); // when - creator.parse(account, null); + creator.parse(account, null, debug); // then - verify(activityRuleFactory).from( - any(), - argThat(creationContext -> creationContext.getPrivacyModulesConfigs().size() == 1)); + verify(activityRuleFactory).from(any(), argThat(arg -> arg.getPrivacyModulesConfigs().size() == 1)); verify(metrics).updateAlertsMetrics(eq(MetricName.general)); } @@ -122,21 +127,15 @@ public void parseShouldReturnExpectedResult() { .willReturn(TestRule.disallowIfMatches(payload -> true)); // when - final Map controllers = creator.parse(account, gppContext); + final Map controllers = creator.parse(account, gppContext, debug); // then assertThat(controllers.keySet()).containsExactlyInAnyOrder(Activity.values()); assertThat(controllers.get(Activity.SYNC_USER).isAllowed(null)) - .isEqualTo(ActivityCallResult.of(ActivityInfrastructure.ALLOW_ACTIVITY_BY_DEFAULT, 0)); - - assertThat(controllers.get(Activity.CALL_BIDDER).isAllowed(null)) - .isEqualTo(ActivityCallResult.of(false, 0)); - - assertThat(controllers.get(Activity.MODIFY_UFDP).isAllowed(null)) - .isEqualTo(ActivityCallResult.of(true, 0)); - - assertThat(controllers.get(Activity.TRANSMIT_UFPD).isAllowed(null)) - .isEqualTo(ActivityCallResult.of(false, 1)); + .isEqualTo(ActivityInfrastructure.ALLOW_ACTIVITY_BY_DEFAULT); + assertThat(controllers.get(Activity.CALL_BIDDER).isAllowed(null)).isEqualTo(false); + assertThat(controllers.get(Activity.MODIFY_UFDP).isAllowed(null)).isEqualTo(true); + assertThat(controllers.get(Activity.TRANSMIT_UFPD).isAllowed(null)).isEqualTo(false); } } diff --git a/src/test/java/org/prebid/server/activity/infrastructure/creator/rule/ComponentRuleCreatorTest.java b/src/test/java/org/prebid/server/activity/infrastructure/creator/rule/ComponentRuleCreatorTest.java index e2252d9a305..9d6835112b7 100644 --- a/src/test/java/org/prebid/server/activity/infrastructure/creator/rule/ComponentRuleCreatorTest.java +++ b/src/test/java/org/prebid/server/activity/infrastructure/creator/rule/ComponentRuleCreatorTest.java @@ -2,7 +2,7 @@ import org.junit.Test; import org.prebid.server.activity.ComponentType; -import org.prebid.server.activity.infrastructure.payload.impl.ActivityCallPayloadImpl; +import org.prebid.server.activity.infrastructure.payload.impl.ActivityInvocationPayloadImpl; import org.prebid.server.activity.infrastructure.rule.Rule; import org.prebid.server.settings.model.activity.rule.AccountActivityComponentRuleConfig; @@ -38,7 +38,7 @@ public void fromShouldCreateExpectedRule() { final Rule rule = target.from(config, null); // then - assertThat(rule.proceed(ActivityCallPayloadImpl.of(ComponentType.BIDDER, "NaMe"))) + assertThat(rule.proceed(ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, "NaMe"))) .isEqualTo(Rule.Result.DISALLOW); } } diff --git a/src/test/java/org/prebid/server/activity/infrastructure/creator/rule/GeoRuleCreatorTest.java b/src/test/java/org/prebid/server/activity/infrastructure/creator/rule/GeoRuleCreatorTest.java index 6bcb837c00e..c7bddd6d136 100644 --- a/src/test/java/org/prebid/server/activity/infrastructure/creator/rule/GeoRuleCreatorTest.java +++ b/src/test/java/org/prebid/server/activity/infrastructure/creator/rule/GeoRuleCreatorTest.java @@ -7,9 +7,9 @@ import org.junit.Test; import org.prebid.server.activity.ComponentType; import org.prebid.server.activity.infrastructure.creator.ActivityControllerCreationContext; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; -import org.prebid.server.activity.infrastructure.payload.impl.ActivityCallPayloadImpl; -import org.prebid.server.activity.infrastructure.payload.impl.BidRequestActivityCallPayload; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.payload.impl.ActivityInvocationPayloadImpl; +import org.prebid.server.activity.infrastructure.payload.impl.BidRequestActivityInvocationPayload; import org.prebid.server.activity.infrastructure.rule.Rule; import org.prebid.server.auction.gpp.model.GppContext; import org.prebid.server.auction.gpp.model.GppContextCreator; @@ -56,23 +56,23 @@ public void fromShouldCreateExpectedRule() { final Rule rule = target.from(config, creationContext); // then - final ActivityCallPayload payload1 = BidRequestActivityCallPayload.of( - ActivityCallPayloadImpl.of(ComponentType.BIDDER, "NaMe"), + final ActivityInvocationPayload payload1 = BidRequestActivityInvocationPayload.of( + ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, "NaMe"), givenBidRequest("country1", "region", "2")); assertThat(rule.proceed(payload1)).isEqualTo(Rule.Result.DISALLOW); - final ActivityCallPayload payload2 = BidRequestActivityCallPayload.of( - ActivityCallPayloadImpl.of(ComponentType.BIDDER, "nAmE"), + final ActivityInvocationPayload payload2 = BidRequestActivityInvocationPayload.of( + ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, "nAmE"), givenBidRequest("country2", "region", "2")); assertThat(rule.proceed(payload2)).isEqualTo(Rule.Result.DISALLOW); - final ActivityCallPayload payload3 = BidRequestActivityCallPayload.of( - ActivityCallPayloadImpl.of(ComponentType.BIDDER, "name"), + final ActivityInvocationPayload payload3 = BidRequestActivityInvocationPayload.of( + ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, "name"), givenBidRequest("country3", "region", "2")); assertThat(rule.proceed(payload3)).isEqualTo(Rule.Result.DISALLOW); - final ActivityCallPayload payload4 = BidRequestActivityCallPayload.of( - ActivityCallPayloadImpl.of(ComponentType.BIDDER, "name"), + final ActivityInvocationPayload payload4 = BidRequestActivityInvocationPayload.of( + ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, "name"), givenBidRequest("country1", null, "2")); assertThat(rule.proceed(payload4)).isEqualTo(Rule.Result.DISALLOW); } diff --git a/src/test/java/org/prebid/server/activity/infrastructure/debug/ActivityDebugUtilsTest.java b/src/test/java/org/prebid/server/activity/infrastructure/debug/ActivityDebugUtilsTest.java new file mode 100644 index 00000000000..81726bd5734 --- /dev/null +++ b/src/test/java/org/prebid/server/activity/infrastructure/debug/ActivityDebugUtilsTest.java @@ -0,0 +1,73 @@ +package org.prebid.server.activity.infrastructure.debug; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fasterxml.jackson.databind.node.TextNode; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.prebid.server.VertxTest; + +import java.util.List; + +import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; + +public class ActivityDebugUtilsTest extends VertxTest { + + @Rule + public final MockitoRule mockitoRule = MockitoJUnit.rule(); + + @Mock + private Loggable loggable; + + @Mock + private Object object; + + @Test + public void asLogEntryShouldReturnExpectedResult() { + // given + final ObjectNode objectNode = mapper.createObjectNode(); + given(loggable.asLogEntry(any())).willReturn(objectNode); + + // when + final JsonNode result = ActivityDebugUtils.asLogEntry(loggable, mapper); + + // then + assertThat(result).isSameAs(objectNode); + } + + @Test + public void asLogEntryShouldReturnTextNodeIfObjectDoesNotImplementLoggable() { + // given + given(object.toString()).willReturn("object"); + + // when + final JsonNode result = ActivityDebugUtils.asLogEntry(object, mapper); + + // then + assertThat(result).isEqualTo(TextNode.valueOf("object")); + } + + @Test + public void asLogEntryShouldReturnArrayNodeOnList() { + // given + final ObjectNode objectNode = mapper.createObjectNode(); + given(loggable.asLogEntry(any())).willReturn(objectNode); + + given(object.toString()).willReturn("object"); + + final List objects = asList(loggable, object); + + // when + final ArrayNode result = ActivityDebugUtils.asLogEntry(objects, mapper); + + // then + assertThat(result).containsExactly(objectNode, TextNode.valueOf("object")); + } +} diff --git a/src/test/java/org/prebid/server/activity/infrastructure/debug/ActivityInfrastructureDebugTest.java b/src/test/java/org/prebid/server/activity/infrastructure/debug/ActivityInfrastructureDebugTest.java new file mode 100644 index 00000000000..6839267328c --- /dev/null +++ b/src/test/java/org/prebid/server/activity/infrastructure/debug/ActivityInfrastructureDebugTest.java @@ -0,0 +1,252 @@ +package org.prebid.server.activity.infrastructure.debug; + +import com.fasterxml.jackson.databind.node.TextNode; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.prebid.server.VertxTest; +import org.prebid.server.activity.Activity; +import org.prebid.server.activity.ComponentType; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.rule.Rule; +import org.prebid.server.activity.infrastructure.rule.TestRule; +import org.prebid.server.metric.Metrics; +import org.prebid.server.proto.openrtb.ext.request.TraceLevel; +import org.prebid.server.proto.openrtb.ext.response.ExtTraceActivityInvocation; +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 static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +public class ActivityInfrastructureDebugTest extends VertxTest { + + @org.junit.Rule + public final MockitoRule mockitoRule = MockitoJUnit.rule(); + + @Mock + private Metrics metrics; + + @Mock + private ActivityInvocationPayload payload; + + @Test + public void emitActivityInvocationShouldDoNothingIfTraceLevelIsNull() { + // given + final ActivityInfrastructureDebug debug = debug(null); + + // when + debug.emitActivityInvocation(Activity.CALL_BIDDER, payload); + + // then + assertThat(debug.trace()).isEmpty(); + verifyNoInteractions(metrics); + } + + @Test + public void emitActivityInvocationShouldAddEntryToTheTraceIfTraceLevelIsBasic() { + // given + final ActivityInfrastructureDebug debug = debug(TraceLevel.basic); + + // when + debug.emitActivityInvocation(Activity.CALL_BIDDER, payload); + + // then + assertThat(debug.trace()).containsExactly(ExtTraceActivityInvocation.of( + "Invocation of Activity Infrastructure.", + Activity.CALL_BIDDER, + null)); + verifyNoInteractions(metrics); + } + + @Test + public void emitActivityInvocationShouldAddEntryToTheTraceWithPayloadIfTraceLevelIsVerbose() { + // given + final ActivityInfrastructureDebug debug = debug(TraceLevel.verbose); + + // when + debug.emitActivityInvocation(Activity.CALL_BIDDER, payload); + + // then + assertThat(debug.trace()).containsExactly(ExtTraceActivityInvocation.of( + "Invocation of Activity Infrastructure.", + Activity.CALL_BIDDER, + payload)); + verifyNoInteractions(metrics); + } + + @Test + public void emitActivityInvocationDefaultResultShouldDoNothingIfTraceLevelIsNull() { + // given + final ActivityInfrastructureDebug debug = debug(null); + + // when + debug.emitActivityInvocationDefaultResult(true); + + // then + assertThat(debug.trace()).isEmpty(); + verifyNoInteractions(metrics); + } + + @Test + public void emitActivityInvocationDefaultResultShouldAddEntryToTheTraceIfTraceLevelIsBasic() { + // given + final ActivityInfrastructureDebug debug = debug(TraceLevel.basic); + + // when + debug.emitActivityInvocationDefaultResult(true); + + // then + assertThat(debug.trace()).containsExactly(ExtTraceActivityInvocationDefaultResult.of( + "Setting the default invocation result.", + true)); + verifyNoInteractions(metrics); + } + + @Test + public void emitProcessedRuleShouldReturnExpectedResultIfTraceLevelIsNull() { + // given + final ActivityInfrastructureDebug debug = debug(null); + + // when + debug.emitProcessedRule(TestRule.allowIfMatches(payload -> true), Rule.Result.ALLOW); + + // then + assertThat(debug.trace()).isEmpty(); + verify(metrics).updateRequestsActivityProcessedRulesCount(); + verifyNoMoreInteractions(metrics); + } + + @Test + public void emitProcessedRuleShouldReturnExpectedResultIfTraceLevelIsBasic() { + // given + final ActivityInfrastructureDebug debug = debug(TraceLevel.basic); + + // when + debug.emitProcessedRule(TestRule.allowIfMatches(payload -> true), Rule.Result.ALLOW); + + // then + assertThat(debug.trace()).containsExactly(ExtTraceActivityRule.of( + "Processing rule.", + null, + Rule.Result.ALLOW)); + verify(metrics).updateRequestsActivityProcessedRulesCount(); + verifyNoMoreInteractions(metrics); + } + + @Test + public void emitProcessedRuleShouldReturnExpectedResultIfTraceLevelIsVerbose() { + // given + final ActivityInfrastructureDebug debug = debug(TraceLevel.verbose); + + // when + debug.emitProcessedRule(TestRule.allowIfMatches(payload -> true), Rule.Result.ALLOW); + + // then + assertThat(debug.trace()).containsExactly(ExtTraceActivityRule.of( + "Processing rule.", + TextNode.valueOf("TestRule"), + Rule.Result.ALLOW)); + verify(metrics).updateRequestsActivityProcessedRulesCount(); + verify(metrics).updateAccountActivityProcessedRulesCount(eq("accountId")); + verifyNoMoreInteractions(metrics); + } + + @Test + public void emitActivityInvocationResultShouldDoNothingIfTraceLevelIsNullAndActivityAllowed() { + // given + final ActivityInfrastructureDebug debug = debug(null); + + // when + debug.emitActivityInvocationResult(Activity.CALL_BIDDER, payload, true); + + // then + assertThat(debug.trace()).isEmpty(); + verifyNoInteractions(metrics); + } + + @Test + public void emitActivityInvocationResultShouldReturnExpectedResultIfActivityDisallowed() { + // given + final ActivityInfrastructureDebug debug = debug(null); + + // when + debug.emitActivityInvocationResult(Activity.CALL_BIDDER, payload, false); + + // then + assertThat(debug.trace()).isEmpty(); + verify(metrics).updateRequestsActivityDisallowedCount(eq(Activity.CALL_BIDDER)); + verifyNoMoreInteractions(metrics); + } + + @Test + public void emitActivityInvocationResultShouldReturnExpectedResultIfActivityDisallowedAndComponentTypeIsBidder() { + // given + given(payload.componentType()).willReturn(ComponentType.BIDDER); + given(payload.componentName()).willReturn("bidder"); + + final ActivityInfrastructureDebug debug = debug(null); + + // when + debug.emitActivityInvocationResult(Activity.CALL_BIDDER, payload, false); + + // then + assertThat(debug.trace()).isEmpty(); + verify(metrics).updateRequestsActivityDisallowedCount(eq(Activity.CALL_BIDDER)); + verify(metrics).updateAdapterActivityDisallowedCount(eq("bidder"), eq(Activity.CALL_BIDDER)); + verifyNoMoreInteractions(metrics); + } + + @Test + public void emitActivityInvocationResultShouldReturnExpectedResultIfTraceLevelIsBasic() { + // given + given(payload.componentType()).willReturn(ComponentType.BIDDER); + given(payload.componentName()).willReturn("bidder"); + + final ActivityInfrastructureDebug debug = debug(TraceLevel.basic); + + // when + debug.emitActivityInvocationResult(Activity.CALL_BIDDER, payload, false); + + // then + assertThat(debug.trace()).containsExactly(ExtTraceActivityInvocationResult.of( + "Activity Infrastructure invocation result.", + Activity.CALL_BIDDER, + false)); + verify(metrics).updateRequestsActivityDisallowedCount(eq(Activity.CALL_BIDDER)); + verify(metrics).updateAdapterActivityDisallowedCount(eq("bidder"), eq(Activity.CALL_BIDDER)); + verifyNoMoreInteractions(metrics); + } + + @Test + public void emitActivityInvocationResultShouldReturnExpectedResultIfTraceLevelIsVerbose() { + // given + given(payload.componentType()).willReturn(ComponentType.BIDDER); + given(payload.componentName()).willReturn("bidder"); + + final ActivityInfrastructureDebug debug = debug(TraceLevel.verbose); + + // when + debug.emitActivityInvocationResult(Activity.CALL_BIDDER, payload, false); + + // then + assertThat(debug.trace()).containsExactly(ExtTraceActivityInvocationResult.of( + "Activity Infrastructure invocation result.", + Activity.CALL_BIDDER, + false)); + verify(metrics).updateRequestsActivityDisallowedCount(eq(Activity.CALL_BIDDER)); + verify(metrics).updateAccountActivityDisallowedCount(eq("accountId"), eq(Activity.CALL_BIDDER)); + verify(metrics).updateAdapterActivityDisallowedCount(eq("bidder"), eq(Activity.CALL_BIDDER)); + verifyNoMoreInteractions(metrics); + } + + private ActivityInfrastructureDebug debug(TraceLevel traceLevel) { + return new ActivityInfrastructureDebug("accountId", traceLevel, metrics, jacksonMapper); + } +} diff --git a/src/test/java/org/prebid/server/activity/infrastructure/privacy/TestPrivacyModule.java b/src/test/java/org/prebid/server/activity/infrastructure/privacy/TestPrivacyModule.java index 7e8979cbdf0..7e42b959ab1 100644 --- a/src/test/java/org/prebid/server/activity/infrastructure/privacy/TestPrivacyModule.java +++ b/src/test/java/org/prebid/server/activity/infrastructure/privacy/TestPrivacyModule.java @@ -1,7 +1,7 @@ package org.prebid.server.activity.infrastructure.privacy; import lombok.Value; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; @Value(staticConstructor = "of") public class TestPrivacyModule implements PrivacyModule { @@ -9,7 +9,7 @@ public class TestPrivacyModule implements PrivacyModule { Result result; @Override - public Result proceed(ActivityCallPayload activityCallPayload) { + public Result proceed(ActivityInvocationPayload activityInvocationPayload) { return result; } } diff --git a/src/test/java/org/prebid/server/activity/infrastructure/privacy/uscustomlogic/USCustomLogicModuleTest.java b/src/test/java/org/prebid/server/activity/infrastructure/privacy/uscustomlogic/USCustomLogicModuleTest.java index 9cf2f493a39..269ab35cd8b 100644 --- a/src/test/java/org/prebid/server/activity/infrastructure/privacy/uscustomlogic/USCustomLogicModuleTest.java +++ b/src/test/java/org/prebid/server/activity/infrastructure/privacy/uscustomlogic/USCustomLogicModuleTest.java @@ -1,5 +1,7 @@ package org.prebid.server.activity.infrastructure.privacy.uscustomlogic; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.TextNode; import io.github.jamsesso.jsonlogic.ast.JsonLogicNode; import io.github.jamsesso.jsonlogic.ast.JsonLogicString; import io.github.jamsesso.jsonlogic.evaluator.JsonLogicEvaluationException; @@ -8,6 +10,7 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; +import org.prebid.server.VertxTest; import org.prebid.server.activity.infrastructure.rule.Rule; import org.prebid.server.json.JsonLogic; @@ -18,7 +21,7 @@ import static org.mockito.ArgumentMatchers.same; import static org.mockito.BDDMockito.given; -public class USCustomLogicModuleTest { +public class USCustomLogicModuleTest extends VertxTest { @org.junit.Rule public final MockitoRule mockitoRule = MockitoJUnit.rule(); @@ -64,4 +67,22 @@ public void proceedShouldReturnAllow() throws JsonLogicEvaluationException { // then assertThat(result).isEqualTo(Rule.Result.ALLOW); } + + @Test + public void asLogEntryShouldReturnExpectedResult() throws JsonLogicEvaluationException { + // given + final JsonLogicNode jsonLogicNode = new JsonLogicString(StringUtils.EMPTY); + final Map data = new HashMap<>(); + + given(dataSupplier.get()).willReturn(data); + given(jsonLogic.evaluate(same(jsonLogicNode), same(data))).willReturn(false); + + final USCustomLogicModule target = new USCustomLogicModule(jsonLogic, jsonLogicNode, dataSupplier); + + // when + final JsonNode logEntry = target.asLogEntry(mapper); + + // then + assertThat(logEntry).isEqualTo(TextNode.valueOf("USCustomLogicModule. Precomputed result: ALLOW.")); + } } diff --git a/src/test/java/org/prebid/server/activity/infrastructure/privacy/usnat/USNatModuleTest.java b/src/test/java/org/prebid/server/activity/infrastructure/privacy/usnat/USNatModuleTest.java new file mode 100644 index 00000000000..21f5ce79349 --- /dev/null +++ b/src/test/java/org/prebid/server/activity/infrastructure/privacy/usnat/USNatModuleTest.java @@ -0,0 +1,34 @@ +package org.prebid.server.activity.infrastructure.privacy.usnat; + +import com.fasterxml.jackson.databind.JsonNode; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.prebid.server.VertxTest; +import org.prebid.server.activity.Activity; +import org.prebid.server.activity.infrastructure.privacy.usnat.inner.USNatDefault; + +import static org.assertj.core.api.Assertions.assertThat; + +public class USNatModuleTest extends VertxTest { + + @Rule + public final MockitoRule rule = MockitoJUnit.rule(); + + @Mock + private USNatGppReader usNatGppReader; + + @Test + public void asLogEntryShouldReturnExpectedResult() { + // given + final USNatModule usNatModule = new USNatModule(Activity.CALL_BIDDER, usNatGppReader); + + // when + final JsonNode logEntry = usNatModule.asLogEntry(mapper); + + // then + assertThat(logEntry).isEqualTo(USNatDefault.instance().asLogEntry(mapper)); + } +} diff --git a/src/test/java/org/prebid/server/activity/infrastructure/privacy/usnat/debug/USNatModuleLogEntryTest.java b/src/test/java/org/prebid/server/activity/infrastructure/privacy/usnat/debug/USNatModuleLogEntryTest.java new file mode 100644 index 00000000000..b9978355254 --- /dev/null +++ b/src/test/java/org/prebid/server/activity/infrastructure/privacy/usnat/debug/USNatModuleLogEntryTest.java @@ -0,0 +1,52 @@ +package org.prebid.server.activity.infrastructure.privacy.usnat.debug; + +import com.fasterxml.jackson.databind.node.TextNode; +import com.iab.gpp.encoder.GppModel; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.prebid.server.activity.infrastructure.privacy.PrivacyModule; +import org.prebid.server.activity.infrastructure.privacy.usnat.USNatGppReader; +import org.prebid.server.activity.infrastructure.privacy.usnat.inner.USNatDefault; +import org.prebid.server.activity.infrastructure.privacy.usnat.inner.USNatSyncUser; +import org.prebid.server.activity.infrastructure.privacy.usnat.reader.USNationalGppReader; +import org.prebid.server.activity.infrastructure.rule.Rule; + +import static org.assertj.core.api.Assertions.assertThat; + +public class USNatModuleLogEntryTest { + + @org.junit.Rule + public final MockitoRule mockitoRule = MockitoJUnit.rule(); + + @Mock + private GppModel gppModel; + + @Test + public void fromShouldReturnExpectedTextNode() { + // given + final USNatGppReader gppReader = new USNationalGppReader(gppModel); + final PrivacyModule privacyModule = new USNatSyncUser(gppReader); + + // when + final TextNode result = USNatModuleLogEntry.from(privacyModule, gppReader, Rule.Result.ALLOW); + + // then + assertThat(result) + .isEqualTo(TextNode.valueOf("USNatSyncUser with USNationalGppReader. Precomputed result: ALLOW.")); + } + + @Test + public void fromShouldReturnExpectedTextNodeForUSNatDefault() { + // given + final PrivacyModule privacyModule = USNatDefault.instance(); + + // when + final TextNode result = USNatModuleLogEntry.from(privacyModule, Rule.Result.ABSTAIN); + + // then + assertThat(result) + .isEqualTo(TextNode.valueOf("USNatDefault. Precomputed result: ABSTAIN.")); + } +} diff --git a/src/test/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatDefaultTest.java b/src/test/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatDefaultTest.java index 12aba32b16d..d201dfcd55a 100644 --- a/src/test/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatDefaultTest.java +++ b/src/test/java/org/prebid/server/activity/infrastructure/privacy/usnat/inner/USNatDefaultTest.java @@ -10,7 +10,7 @@ public class USNatDefaultTest { @Test public void proceedShouldAlwaysReturnAbstain() { // when - final Rule.Result result = new USNatDefault().proceed(null); + final Rule.Result result = USNatDefault.instance().proceed(null); // then assertThat(result).isEqualTo(Rule.Result.ABSTAIN); diff --git a/src/test/java/org/prebid/server/activity/infrastructure/rule/AndRuleTest.java b/src/test/java/org/prebid/server/activity/infrastructure/rule/AndRuleTest.java index 77ec804f20e..8d9094965e2 100644 --- a/src/test/java/org/prebid/server/activity/infrastructure/rule/AndRuleTest.java +++ b/src/test/java/org/prebid/server/activity/infrastructure/rule/AndRuleTest.java @@ -1,10 +1,14 @@ package org.prebid.server.activity.infrastructure.rule; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.TextNode; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; +import org.prebid.server.VertxTest; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; @@ -15,7 +19,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; -public class AndRuleTest { +public class AndRuleTest extends VertxTest { @org.junit.Rule public final MockitoRule mockitoRule = MockitoJUnit.rule(); @@ -75,4 +79,20 @@ public void proceedShouldReturnAbstain() { assertThat(result).isEqualTo(Rule.Result.ABSTAIN); verify(abstainRule).proceed(any()); } + + @Test + public void asLogEntryShouldReturnExpectedObjectNode() { + // given + final AndRule rule = new AndRule(asList( + TestRule.allowIfMatches(payload -> true), + TestRule.disallowIfMatches(payload -> false))); + + // when + final JsonNode result = rule.asLogEntry(mapper); + + // then + assertThat(result.get("and")) + .isInstanceOf(ArrayNode.class) + .containsExactly(TextNode.valueOf("TestRule"), TextNode.valueOf("TestRule")); + } } diff --git a/src/test/java/org/prebid/server/activity/infrastructure/rule/ComponentRuleTest.java b/src/test/java/org/prebid/server/activity/infrastructure/rule/ComponentRuleTest.java index 7ee19315238..2918b75c8b4 100644 --- a/src/test/java/org/prebid/server/activity/infrastructure/rule/ComponentRuleTest.java +++ b/src/test/java/org/prebid/server/activity/infrastructure/rule/ComponentRuleTest.java @@ -1,13 +1,18 @@ package org.prebid.server.activity.infrastructure.rule; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.BooleanNode; +import com.fasterxml.jackson.databind.node.TextNode; import org.junit.Test; +import org.prebid.server.VertxTest; import org.prebid.server.activity.ComponentType; -import org.prebid.server.activity.infrastructure.payload.impl.ActivityCallPayloadImpl; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.payload.impl.ActivityInvocationPayloadImpl; import static java.util.Collections.singleton; import static org.assertj.core.api.Assertions.assertThat; -public class ComponentRuleTest { +public class ComponentRuleTest extends VertxTest { @Test public void allowedShouldReturnExpectedResult() { @@ -27,7 +32,7 @@ public void matchesShouldReturnTrueIfComponentTypesIsNull() { final ComponentRule rule = new ComponentRule(null, null, true); // when - final boolean matches = rule.matches(ActivityCallPayloadImpl.of(ComponentType.BIDDER, null)); + final boolean matches = rule.matches(ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, null)); // then assertThat(matches).isEqualTo(true); @@ -39,7 +44,7 @@ public void matchesShouldReturnFalseIfComponentTypesDoesNotContainsArgument() { final ComponentRule rule = new ComponentRule(singleton(ComponentType.ANALYTICS), null, true); // when - final boolean matches = rule.matches(ActivityCallPayloadImpl.of(ComponentType.BIDDER, null)); + final boolean matches = rule.matches(ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, null)); // then assertThat(matches).isEqualTo(false); @@ -49,9 +54,11 @@ public void matchesShouldReturnFalseIfComponentTypesDoesNotContainsArgument() { public void matchesShouldReturnTrueIfComponentNamesIsNull() { // given final ComponentRule rule = new ComponentRule(null, null, true); + final ActivityInvocationPayload payload = ActivityInvocationPayloadImpl.of( + ComponentType.ANALYTICS, "componentName"); // when - final boolean matches = rule.matches(ActivityCallPayloadImpl.of(ComponentType.ANALYTICS, "componentName")); + final boolean matches = rule.matches(payload); // then assertThat(matches).isEqualTo(true); @@ -61,9 +68,11 @@ public void matchesShouldReturnTrueIfComponentNamesIsNull() { public void matchesShouldReturnFalseIfComponentNamesDoesNotContainsArgument() { // given final ComponentRule rule = new ComponentRule(null, singleton("other"), true); + final ActivityInvocationPayload payload = ActivityInvocationPayloadImpl.of( + ComponentType.ANALYTICS, "componentName"); // when - final boolean matches = rule.matches(ActivityCallPayloadImpl.of(ComponentType.ANALYTICS, "componentName")); + final boolean matches = rule.matches(payload); // then assertThat(matches).isEqualTo(false); @@ -75,9 +84,23 @@ public void matchesShouldReturnExpectedResult() { final ComponentRule rule = new ComponentRule(singleton(ComponentType.BIDDER), singleton("bidder"), true); // when - final boolean matches = rule.matches(ActivityCallPayloadImpl.of(ComponentType.BIDDER, "bidder")); + final boolean matches = rule.matches(ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, "bidder")); // then assertThat(matches).isEqualTo(true); } + + @Test + public void asLogEntryShouldReturnExpectedObjectNode() { + // given + final ComponentRule rule = new ComponentRule(singleton(ComponentType.BIDDER), singleton("bidder"), true); + + // when + final JsonNode result = rule.asLogEntry(mapper); + + // then + assertThat(result.get("component_types")).containsExactly(TextNode.valueOf("BIDDER")); + assertThat(result.get("component_names")).containsExactly(TextNode.valueOf("bidder")); + assertThat(result.get("allow")).isEqualTo(BooleanNode.getTrue()); + } } diff --git a/src/test/java/org/prebid/server/activity/infrastructure/rule/GeoRuleTest.java b/src/test/java/org/prebid/server/activity/infrastructure/rule/GeoRuleTest.java index c98f6d0b38e..25637228a5f 100644 --- a/src/test/java/org/prebid/server/activity/infrastructure/rule/GeoRuleTest.java +++ b/src/test/java/org/prebid/server/activity/infrastructure/rule/GeoRuleTest.java @@ -1,22 +1,26 @@ package org.prebid.server.activity.infrastructure.rule; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.BooleanNode; +import com.fasterxml.jackson.databind.node.TextNode; import com.iab.openrtb.request.BidRequest; import com.iab.openrtb.request.Device; import com.iab.openrtb.request.Geo; import com.iab.openrtb.request.Regs; import org.junit.Test; +import org.prebid.server.VertxTest; import org.prebid.server.activity.ComponentType; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; -import org.prebid.server.activity.infrastructure.payload.impl.ActivityCallPayloadImpl; -import org.prebid.server.activity.infrastructure.payload.impl.BidRequestActivityCallPayload; -import org.prebid.server.activity.infrastructure.payload.impl.PrivacyEnforcementServiceActivityCallPayload; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.payload.impl.ActivityInvocationPayloadImpl; +import org.prebid.server.activity.infrastructure.payload.impl.BidRequestActivityInvocationPayload; +import org.prebid.server.activity.infrastructure.payload.impl.PrivacyEnforcementServiceActivityInvocationPayload; import org.prebid.server.proto.openrtb.ext.request.ExtRegs; import static java.util.Collections.singleton; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; -public class GeoRuleTest { +public class GeoRuleTest extends VertxTest { @Test public void allowedShouldReturnExpectedResult() { @@ -36,7 +40,7 @@ public void matchesShouldReturnTrueIfComponentTypesIsNull() { final GeoRule rule = new GeoRule(null, null, true, null, null, true); // when - final boolean matches = rule.matches(ActivityCallPayloadImpl.of(ComponentType.BIDDER, null)); + final boolean matches = rule.matches(ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, null)); // then assertThat(matches).isEqualTo(true); @@ -48,7 +52,7 @@ public void matchesShouldReturnFalseIfComponentTypesDoesNotContainsArgument() { final GeoRule rule = new GeoRule(singleton(ComponentType.ANALYTICS), null, true, null, null, true); // when - final boolean matches = rule.matches(ActivityCallPayloadImpl.of(ComponentType.BIDDER, null)); + final boolean matches = rule.matches(ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, null)); // then assertThat(matches).isEqualTo(false); @@ -58,9 +62,11 @@ public void matchesShouldReturnFalseIfComponentTypesDoesNotContainsArgument() { public void matchesShouldReturnTrueIfComponentNamesIsNull() { // given final GeoRule rule = new GeoRule(null, null, true, null, null, true); + final ActivityInvocationPayload payload = ActivityInvocationPayloadImpl.of( + ComponentType.ANALYTICS, "componentName"); // when - final boolean matches = rule.matches(ActivityCallPayloadImpl.of(ComponentType.ANALYTICS, "componentName")); + final boolean matches = rule.matches(payload); // then assertThat(matches).isEqualTo(true); @@ -70,9 +76,11 @@ public void matchesShouldReturnTrueIfComponentNamesIsNull() { public void matchesShouldReturnFalseIfComponentNamesDoesNotContainsArgument() { // given final GeoRule rule = new GeoRule(null, singleton("other"), true, null, null, true); + final ActivityInvocationPayload payload = ActivityInvocationPayloadImpl.of( + ComponentType.ANALYTICS, "componentName"); // when - final boolean matches = rule.matches(ActivityCallPayloadImpl.of(ComponentType.ANALYTICS, "componentName")); + final boolean matches = rule.matches(payload); // then assertThat(matches).isEqualTo(false); @@ -82,9 +90,11 @@ public void matchesShouldReturnFalseIfComponentNamesDoesNotContainsArgument() { public void matchesShouldReturnFalseIfSidsDoesNotMatched() { // given final GeoRule rule = new GeoRule(null, null, false, null, null, true); + final ActivityInvocationPayload payload = ActivityInvocationPayloadImpl.of( + ComponentType.ANALYTICS, "componentName"); // when - final boolean matches = rule.matches(ActivityCallPayloadImpl.of(ComponentType.ANALYTICS, "componentName")); + final boolean matches = rule.matches(payload); // then assertThat(matches).isEqualTo(false); @@ -100,8 +110,8 @@ public void matchesShouldReturnTrueIfGeoCodeWithoutRegionMatched() { singletonList(GeoRule.GeoCode.of("Country", null)), null, true); - final ActivityCallPayload payload = PrivacyEnforcementServiceActivityCallPayload.of( - ActivityCallPayloadImpl.of(ComponentType.BIDDER, "bidder"), + final ActivityInvocationPayload payload = PrivacyEnforcementServiceActivityInvocationPayload.of( + ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, "bidder"), "country", "region", null); @@ -123,8 +133,8 @@ public void matchesShouldReturnFalseIfCountryDoesNotMatched() { singletonList(GeoRule.GeoCode.of("Country", null)), null, true); - final ActivityCallPayload payload = PrivacyEnforcementServiceActivityCallPayload.of( - ActivityCallPayloadImpl.of(ComponentType.BIDDER, "bidder"), + final ActivityInvocationPayload payload = PrivacyEnforcementServiceActivityInvocationPayload.of( + ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, "bidder"), "otherCountry", "region", null); @@ -146,8 +156,8 @@ public void matchesShouldReturnTrueIfGeoCodeMatched() { singletonList(GeoRule.GeoCode.of("Country", "Region")), null, true); - final ActivityCallPayload payload = PrivacyEnforcementServiceActivityCallPayload.of( - ActivityCallPayloadImpl.of(ComponentType.BIDDER, "bidder"), + final ActivityInvocationPayload payload = PrivacyEnforcementServiceActivityInvocationPayload.of( + ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, "bidder"), "country", "region", null); @@ -169,8 +179,8 @@ public void matchesShouldReturnFalseIfRegionDoesNotMatched() { singletonList(GeoRule.GeoCode.of("Country", "Region")), null, true); - final ActivityCallPayload payload = PrivacyEnforcementServiceActivityCallPayload.of( - ActivityCallPayloadImpl.of(ComponentType.BIDDER, "bidder"), + final ActivityInvocationPayload payload = PrivacyEnforcementServiceActivityInvocationPayload.of( + ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, "bidder"), "country", "otherRegion", null); @@ -186,7 +196,7 @@ public void matchesShouldReturnFalseIfRegionDoesNotMatched() { public void matchesShouldReturnTrueIfGpcMatched() { // given final GeoRule rule = new GeoRule(null, null, true, null, "2", true); - final ActivityCallPayload payload = BidRequestActivityCallPayload.of( + final ActivityInvocationPayload payload = BidRequestActivityInvocationPayload.of( null, BidRequest.builder() .regs(Regs.builder().ext(ExtRegs.of(null, null, "2")).build()) @@ -203,7 +213,7 @@ public void matchesShouldReturnTrueIfGpcMatched() { public void matchesShouldReturnFalseIfGpcNotMatched() { // given final GeoRule rule = new GeoRule(null, null, true, null, "2", true); - final ActivityCallPayload payload = BidRequestActivityCallPayload.of( + final ActivityInvocationPayload payload = BidRequestActivityInvocationPayload.of( null, BidRequest.builder() .regs(Regs.builder().ext(ExtRegs.of(null, null, "1")).build()) @@ -226,8 +236,8 @@ public void matchesShouldReturnExpectedResult() { singletonList(GeoRule.GeoCode.of("Country", "Region")), "2", true); - final ActivityCallPayload payload = BidRequestActivityCallPayload.of( - ActivityCallPayloadImpl.of(ComponentType.BIDDER, "bidder"), + final ActivityInvocationPayload payload = BidRequestActivityInvocationPayload.of( + ActivityInvocationPayloadImpl.of(ComponentType.BIDDER, "bidder"), BidRequest.builder() .device(Device.builder().geo(Geo.builder().country("country").region("region").build()).build()) .regs(Regs.builder().ext(ExtRegs.of(null, null, "2")).build()) @@ -239,4 +249,30 @@ public void matchesShouldReturnExpectedResult() { // then assertThat(matches).isEqualTo(true); } + + @Test + public void asLogEntryShouldReturnExpectedObjectNode() { + // given + final GeoRule rule = new GeoRule( + singleton(ComponentType.BIDDER), + singleton("bidder"), + false, + singletonList(GeoRule.GeoCode.of("Country", "Region")), + "2", + true); + + // when + final JsonNode result = rule.asLogEntry(mapper); + + // then + assertThat(result.get("component_types")).containsExactly(TextNode.valueOf("BIDDER")); + assertThat(result.get("component_names")).containsExactly(TextNode.valueOf("bidder")); + assertThat(result.get("gpp_sids_matched")).isEqualTo(BooleanNode.getFalse()); + assertThat(result.get("geo_codes")).hasSize(1).allSatisfy(geoCode -> { + assertThat(geoCode.get("country")).isEqualTo(TextNode.valueOf("Country")); + assertThat(geoCode.get("region")).isEqualTo(TextNode.valueOf("Region")); + }); + assertThat(result.get("gpc")).isEqualTo(TextNode.valueOf("2")); + assertThat(result.get("allow")).isEqualTo(BooleanNode.getTrue()); + } } diff --git a/src/test/java/org/prebid/server/activity/infrastructure/rule/TestRule.java b/src/test/java/org/prebid/server/activity/infrastructure/rule/TestRule.java index c63a4e87a4a..996eb645b44 100644 --- a/src/test/java/org/prebid/server/activity/infrastructure/rule/TestRule.java +++ b/src/test/java/org/prebid/server/activity/infrastructure/rule/TestRule.java @@ -1,35 +1,44 @@ package org.prebid.server.activity.infrastructure.rule; -import org.prebid.server.activity.infrastructure.payload.ActivityCallPayload; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.TextNode; +import org.prebid.server.activity.infrastructure.debug.Loggable; +import org.prebid.server.activity.infrastructure.payload.ActivityInvocationPayload; import java.util.Objects; import java.util.function.Predicate; -public class TestRule extends AbstractMatchRule { +public class TestRule extends AbstractMatchRule implements Loggable { - private final Predicate predicate; + private final Predicate predicate; private final boolean allowed; - private TestRule(Predicate predicate, boolean allowed) { + private TestRule(Predicate predicate, boolean allowed) { this.predicate = Objects.requireNonNull(predicate); this.allowed = allowed; } - public static TestRule allowIfMatches(Predicate predicate) { + public static TestRule allowIfMatches(Predicate predicate) { return new TestRule(predicate, true); } - public static TestRule disallowIfMatches(Predicate predicate) { + public static TestRule disallowIfMatches(Predicate predicate) { return new TestRule(predicate, false); } @Override - public boolean matches(ActivityCallPayload activityCallPayload) { - return predicate.test(activityCallPayload); + public boolean matches(ActivityInvocationPayload activityInvocationPayload) { + return predicate.test(activityInvocationPayload); } @Override public boolean allowed() { return allowed; } + + @Override + public JsonNode asLogEntry(ObjectMapper mapper) { + return TextNode.valueOf(TestRule.class.getSimpleName()); + } } diff --git a/src/test/java/org/prebid/server/auction/BidResponseCreatorTest.java b/src/test/java/org/prebid/server/auction/BidResponseCreatorTest.java index f8d7aa9ba19..8c789700804 100644 --- a/src/test/java/org/prebid/server/auction/BidResponseCreatorTest.java +++ b/src/test/java/org/prebid/server/auction/BidResponseCreatorTest.java @@ -23,8 +23,8 @@ import lombok.Value; import lombok.experimental.Accessors; import org.apache.commons.collections4.MapUtils; +import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; @@ -32,6 +32,9 @@ import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.prebid.server.VertxTest; +import org.prebid.server.activity.Activity; +import org.prebid.server.activity.infrastructure.ActivityInfrastructure; +import org.prebid.server.activity.infrastructure.rule.Rule; import org.prebid.server.auction.categorymapping.CategoryMappingService; import org.prebid.server.auction.model.AuctionContext; import org.prebid.server.auction.model.AuctionParticipation; @@ -82,6 +85,7 @@ import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebidChannel; import org.prebid.server.proto.openrtb.ext.request.ExtRequestTargeting; import org.prebid.server.proto.openrtb.ext.request.ExtStoredRequest; +import org.prebid.server.proto.openrtb.ext.request.TraceLevel; import org.prebid.server.proto.openrtb.ext.response.BidType; import org.prebid.server.proto.openrtb.ext.response.CacheAsset; import org.prebid.server.proto.openrtb.ext.response.Events; @@ -94,6 +98,12 @@ 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.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.ExtTraceActivityInvocation; +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.ExtTraceDeal; import org.prebid.server.proto.openrtb.ext.response.FledgeAuctionConfig; import org.prebid.server.proto.openrtb.ext.response.seatnonbid.NonBid; @@ -163,7 +173,7 @@ public class BidResponseCreatorTest extends VertxTest { private static final String BID_ADM = "adm"; private static final String BID_NURL = "nurl"; - @Rule + @org.junit.Rule public final MockitoRule mockitoRule = MockitoJUnit.rule(); @Mock @@ -182,6 +192,8 @@ public class BidResponseCreatorTest extends VertxTest { private CategoryMappingService categoryMappingService; @Mock private HookStageExecutor hookStageExecutor; + @Mock + private ActivityInfrastructure activityInfrastructure; @Spy private WinningBidComparatorFactory winningBidComparatorFactory; @@ -2918,10 +2930,9 @@ public void shouldProcessRequestAndAddErrorAboutDeprecatedBidder() { final BidRequest bidRequest = givenBidRequest(Imp.builder() .ext(mapper.valueToTree( ExtImp.of(ExtImpPrebid.builder() - .bidder(mapper.valueToTree(singletonMap(invalidBidderName, 0))) - .build(), - null) - )) + .bidder(mapper.valueToTree(singletonMap(invalidBidderName, 0))) + .build(), + null))) .build()); final List bidderResponses = singletonList(BidderResponse.of("bidder1", givenSeatBid(), 100)); @@ -3132,6 +3143,46 @@ public void shouldPopulateExtensionResponseDebugAndDeepDebugLogIfEnabled() { ZonedDateTime.now(clock), targeting, "test-2")))); } + @Test + public void shouldPopulateActivityInfrastructureTraceLogOnSpecifiedTraceLevel() { + // given + final List traceLog = asList( + ExtTraceActivityInvocation.of("1", Activity.CALL_BIDDER, null), + ExtTraceActivityInvocationDefaultResult.of("2", true), + ExtTraceActivityRule.of("3", null, Rule.Result.ABSTAIN), + ExtTraceActivityInvocationResult.of("4", Activity.CALL_BIDDER, true)); + + given(activityInfrastructure.debugTrace()).willReturn(traceLog); + + final List bidderResponses = singletonList( + BidderResponse.of( + "bidder1", + givenSeatBid(BidderBid.of( + Bid.builder().id("bidId1").price(BigDecimal.valueOf(5.67)).impid(IMP_ID).build(), + banner, + "USD")), + 100)); + + final AuctionContext auctionContext = givenAuctionContext( + givenBidRequest(givenImp()), + builder -> builder + .debugContext(DebugContext.of(false, false, TraceLevel.verbose)) + .activityInfrastructure(activityInfrastructure) + .auctionParticipations(toAuctionParticipant(bidderResponses))); + + // when + final BidResponse bidResponse = bidResponseCreator.create(auctionContext, CACHE_INFO, MULTI_BIDS).result(); + + // then + assertThat(bidResponse) + .extracting(BidResponse::getExt) + .extracting(ExtBidResponse::getDebug) + .extracting(ExtResponseDebug::getTrace) + .extracting(ExtDebugTrace::getActivityInfrastructure) + .asInstanceOf(InstanceOfAssertFactories.list(ExtTraceActivityInfrastructure.class)) + .isEqualTo(traceLog); + } + @Test public void shouldBidResponseDebugReturnNullIfDeepDebugLogIsEnabledAndNotPopulated() { // given diff --git a/src/test/java/org/prebid/server/metric/MetricsTest.java b/src/test/java/org/prebid/server/metric/MetricsTest.java index 06fa59478dd..df74259945d 100644 --- a/src/test/java/org/prebid/server/metric/MetricsTest.java +++ b/src/test/java/org/prebid/server/metric/MetricsTest.java @@ -1395,20 +1395,20 @@ public void shouldIncrementUpdateAdapterActivityDisallowedCount() { @Test public void shouldIncrementUpdateRequestsActivityProcessedRulesCount() { // when - metrics.updateRequestsActivityProcessedRulesCount(2); + metrics.updateRequestsActivityProcessedRulesCount(); // then - assertThat(metricRegistry.counter("requests.activity.processedrules.count").getCount()).isEqualTo(2); + assertThat(metricRegistry.counter("requests.activity.processedrules.count").getCount()).isEqualTo(1); } @Test public void shouldIncrementUpdateAccountActivityProcessedRulesCount() { // when - metrics.updateAccountActivityProcessedRulesCount("account_id", 2); + metrics.updateAccountActivityProcessedRulesCount("account_id"); // then assertThat(metricRegistry.counter("account.account_id.activity.processedrules.count").getCount()) - .isEqualTo(2); + .isEqualTo(1); } private void verifyCreatesConfiguredCounterType(Consumer metricsConsumer) { diff --git a/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-first-and-second-response.json b/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-first-and-second-response.json index c5cac98ba82..19264d25845 100644 --- a/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-first-and-second-response.json +++ b/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-first-and-second-response.json @@ -360,7 +360,77 @@ "message": "Matched Line Item lineItem2 for bidder rubicon ready to serve. relPriority 3" } ] - } + }, + "activity_infrastructure": [ + { + "description": "Invocation of Activity Infrastructure.", + "activity": "fetchBids", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "fetchBids", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitUfpd", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitUfpd", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitPreciseGeo", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitPreciseGeo", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitTid", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitTid", + "allowed": true + } + ] } }, "responsetimemillis": { diff --git a/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-first-bid-only-response.json b/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-first-bid-only-response.json index 40eb580994b..297f0518a8e 100644 --- a/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-first-bid-only-response.json +++ b/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-first-bid-only-response.json @@ -357,7 +357,77 @@ "message": "Matched Line Item lineItem2 for bidder rubicon ready to serve. relPriority 3" } ] - } + }, + "activity_infrastructure": [ + { + "description": "Invocation of Activity Infrastructure.", + "activity": "fetchBids", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "fetchBids", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitUfpd", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitUfpd", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitPreciseGeo", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitPreciseGeo", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitTid", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitTid", + "allowed": true + } + ] } }, "responsetimemillis": { diff --git a/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-in-order-response.json b/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-in-order-response.json index 40eb580994b..297f0518a8e 100644 --- a/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-in-order-response.json +++ b/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-in-order-response.json @@ -357,7 +357,77 @@ "message": "Matched Line Item lineItem2 for bidder rubicon ready to serve. relPriority 3" } ] - } + }, + "activity_infrastructure": [ + { + "description": "Invocation of Activity Infrastructure.", + "activity": "fetchBids", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "fetchBids", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitUfpd", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitUfpd", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitPreciseGeo", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitPreciseGeo", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitTid", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitTid", + "allowed": true + } + ] } }, "responsetimemillis": { diff --git a/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-in-reverse-order-response.json b/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-in-reverse-order-response.json index 55694465a89..6b0db95f32e 100644 --- a/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-in-reverse-order-response.json +++ b/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-in-reverse-order-response.json @@ -363,7 +363,77 @@ "message": "Matched Line Item lineItem2 for bidder rubicon ready to serve. relPriority 3" } ] - } + }, + "activity_infrastructure": [ + { + "description": "Invocation of Activity Infrastructure.", + "activity": "fetchBids", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "fetchBids", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitUfpd", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitUfpd", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitPreciseGeo", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitPreciseGeo", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitTid", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitTid", + "allowed": true + } + ] } }, "responsetimemillis": { diff --git a/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-second-bid-only-response.json b/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-second-bid-only-response.json index ba2ee7f1ed2..a0ccf324d82 100644 --- a/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-second-bid-only-response.json +++ b/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-second-bid-only-response.json @@ -361,7 +361,77 @@ "message": "Matched Line Item lineItem2 for bidder rubicon ready to serve. relPriority 3" } ] - } + }, + "activity_infrastructure": [ + { + "description": "Invocation of Activity Infrastructure.", + "activity": "fetchBids", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "fetchBids", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitUfpd", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitUfpd", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitPreciseGeo", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitPreciseGeo", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitTid", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitTid", + "allowed": true + } + ] } }, "responsetimemillis": { diff --git a/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-third-and-second-response.json b/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-third-and-second-response.json index 6e457c13072..3fbc3594c12 100644 --- a/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-third-and-second-response.json +++ b/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-third-and-second-response.json @@ -362,7 +362,77 @@ "message": "Matched Line Item lineItem2 for bidder rubicon ready to serve. relPriority 3" } ] - } + }, + "activity_infrastructure": [ + { + "description": "Invocation of Activity Infrastructure.", + "activity": "fetchBids", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "fetchBids", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitUfpd", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitUfpd", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitPreciseGeo", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitPreciseGeo", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitTid", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitTid", + "allowed": true + } + ] } }, "responsetimemillis": { diff --git a/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-third-bid-only-response.json b/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-third-bid-only-response.json index b3818238704..7bea97d3c61 100644 --- a/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-third-bid-only-response.json +++ b/src/test/resources/org/prebid/server/it/deals/premature/responses/test-auction-third-bid-only-response.json @@ -361,7 +361,77 @@ "message": "Matched Line Item lineItem2 for bidder rubicon ready to serve. relPriority 3" } ] - } + }, + "activity_infrastructure": [ + { + "description": "Invocation of Activity Infrastructure.", + "activity": "fetchBids", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "fetchBids", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitUfpd", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitUfpd", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitPreciseGeo", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitPreciseGeo", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitTid", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitTid", + "allowed": true + } + ] } }, "responsetimemillis": { diff --git a/src/test/resources/org/prebid/server/it/deals/simulation/test-auction-response-1.json b/src/test/resources/org/prebid/server/it/deals/simulation/test-auction-response-1.json index 8175a007492..6d8a30fe28b 100644 --- a/src/test/resources/org/prebid/server/it/deals/simulation/test-auction-response-1.json +++ b/src/test/resources/org/prebid/server/it/deals/simulation/test-auction-response-1.json @@ -265,7 +265,77 @@ "message": "Matched Line Item lineItem2 for bidder rubicon ready to serve. relPriority 3" } ] - } + }, + "activity_infrastructure": [ + { + "description": "Invocation of Activity Infrastructure.", + "activity": "fetchBids", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "fetchBids", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitUfpd", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitUfpd", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitPreciseGeo", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitPreciseGeo", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitTid", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitTid", + "allowed": true + } + ] } }, "responsetimemillis": { diff --git a/src/test/resources/org/prebid/server/it/deals/simulation/test-auction-response-2.json b/src/test/resources/org/prebid/server/it/deals/simulation/test-auction-response-2.json index 16b8be9b54f..cb8373269fd 100644 --- a/src/test/resources/org/prebid/server/it/deals/simulation/test-auction-response-2.json +++ b/src/test/resources/org/prebid/server/it/deals/simulation/test-auction-response-2.json @@ -249,7 +249,77 @@ "message": "Matched Line Item lineItem2 for bidder rubicon ready to serve. relPriority 3" } ] - } + }, + "activity_infrastructure": [ + { + "description": "Invocation of Activity Infrastructure.", + "activity": "fetchBids", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "fetchBids", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitUfpd", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitUfpd", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitPreciseGeo", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitPreciseGeo", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitTid", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitTid", + "allowed": true + } + ] } }, "responsetimemillis": { diff --git a/src/test/resources/org/prebid/server/it/deals/test-auction-response.json b/src/test/resources/org/prebid/server/it/deals/test-auction-response.json index 8340a7ebefe..5c7e281e286 100644 --- a/src/test/resources/org/prebid/server/it/deals/test-auction-response.json +++ b/src/test/resources/org/prebid/server/it/deals/test-auction-response.json @@ -713,7 +713,128 @@ "message": "Line Item lineItem2 targeting did not match imp with id impId4" } ] - } + }, + "activity_infrastructure": [ + { + "description": "Invocation of Activity Infrastructure.", + "activity": "fetchBids", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "fetchBids", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "fetchBids", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "fetchBids", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "fetchBids", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "fetchBids", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "fetchBids", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "fetchBids", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitUfpd", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitUfpd", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitPreciseGeo", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitPreciseGeo", + "allowed": true + }, + { + "description": "Invocation of Activity Infrastructure.", + "activity": "transmitTid", + "activity_invocation_payload": { + "component_type": "BIDDER", + "component_name": "rubicon" + } + }, + { + "description": "Setting the default invocation result.", + "allow_by_default": true + }, + { + "description": "Activity Infrastructure invocation result.", + "activity": "transmitTid", + "allowed": true + } + ] } }, "warnings": {