From 4653c4f6ed311e1ad52c11967b1dbe516d295e2a Mon Sep 17 00:00:00 2001 From: antonbabak Date: Tue, 19 Nov 2024 11:01:56 +0100 Subject: [PATCH 01/11] Module Execution Fix --- .../server/hooks/execution/GroupExecutor.java | 13 ++- .../server/hooks/execution/HookCatalog.java | 9 ++- .../server/hooks/execution/StageExecutor.java | 1 + .../spring/config/HooksConfiguration.java | 32 +++++++- .../hooks/execution/HookCatalogTest.java | 37 ++++++--- .../execution/HookStageExecutorTest.java | 80 +++++++++++++++++++ .../it/test-application-hooks.properties | 2 + 7 files changed, 158 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java b/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java index 5fac3d8376b..6bf57bec2c7 100644 --- a/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java +++ b/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java @@ -35,6 +35,7 @@ class GroupExecutor { private ExecutionGroup group; private PAYLOAD initialPayload; private Function> hookProvider; + private Function moduleConfigProvider; private InvocationContextProvider invocationContextProvider; private HookExecutionContext hookExecutionContext; private boolean rejectAllowed; @@ -68,6 +69,11 @@ public GroupExecutor withHookProvider(Function withModuleConfigProvider(Function moduleConfigProvider) { + this.moduleConfigProvider = moduleConfigProvider; + return this; + } + public GroupExecutor withInvocationContextProvider( InvocationContextProvider invocationContextProvider) { @@ -117,7 +123,12 @@ private Future> executeHook( final CONTEXT invocationContext = invocationContextProvider.apply(timeout, hookId, moduleContextFor(hookId)); - if (isConfigToInvokeRequired && invocationContext instanceof AuctionInvocationContext) { + final Boolean isHostConfigProvided = moduleConfigProvider.apply(hookId); + + if (!isHostConfigProvided + && isConfigToInvokeRequired + && invocationContext instanceof AuctionInvocationContext) { + final ObjectNode accountConfig = ((AuctionInvocationContext) invocationContext).accountConfig(); if (accountConfig == null || accountConfig.isNull()) { return Future.succeededFuture(InvocationResultImpl.builder() diff --git a/src/main/java/org/prebid/server/hooks/execution/HookCatalog.java b/src/main/java/org/prebid/server/hooks/execution/HookCatalog.java index 754e3925b11..9b9347c7ff9 100644 --- a/src/main/java/org/prebid/server/hooks/execution/HookCatalog.java +++ b/src/main/java/org/prebid/server/hooks/execution/HookCatalog.java @@ -7,6 +7,7 @@ import java.util.Collection; import java.util.Objects; +import java.util.Set; /** * Provides simple access to all {@link Hook}s registered in application. @@ -14,9 +15,11 @@ public class HookCatalog { private final Collection modules; + private final Set moduleConfigPresenceSet; - public HookCatalog(Collection modules) { + public HookCatalog(Collection modules, Set moduleConfigPresenceSet) { this.modules = Objects.requireNonNull(modules); + this.moduleConfigPresenceSet = Objects.requireNonNull(moduleConfigPresenceSet); } public > HOOK hookById( @@ -35,4 +38,8 @@ public HookCatalog(Collection modules) { .findFirst() .orElse(null); } + + public boolean hasHostConfig(String moduleCode) { + return moduleConfigPresenceSet.contains(moduleCode); + } } diff --git a/src/main/java/org/prebid/server/hooks/execution/StageExecutor.java b/src/main/java/org/prebid/server/hooks/execution/StageExecutor.java index d99cd14030f..183e84f78a5 100644 --- a/src/main/java/org/prebid/server/hooks/execution/StageExecutor.java +++ b/src/main/java/org/prebid/server/hooks/execution/StageExecutor.java @@ -102,6 +102,7 @@ private Future> executeGroup(ExecutionGroup group, PAYLOAD .withInitialPayload(initialPayload) .withHookProvider( hookId -> hookCatalog.hookById(hookId.getModuleCode(), hookId.getHookImplCode(), stage)) + .withModuleConfigProvider(hookId -> hookCatalog.hasHostConfig(hookId.getModuleCode())) .withInvocationContextProvider(invocationContextProvider) .withHookExecutionContext(hookExecutionContext) .withRejectAllowed(rejectAllowed) diff --git a/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java b/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java index 64534d119aa..cfe05e23120 100644 --- a/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java @@ -12,17 +12,24 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.EnumerablePropertySource; +import org.springframework.core.env.Environment; import org.springframework.validation.annotation.Validated; import java.time.Clock; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; +import java.util.Set; +import java.util.stream.Collectors; @Configuration public class HooksConfiguration { @Bean - HookCatalog hookCatalog(Collection modules) { - return new HookCatalog(modules); + HookCatalog hookCatalog(Collection modules, Set moduleConfigPresenceSet) { + return new HookCatalog(modules, moduleConfigPresenceSet); } @Bean @@ -46,6 +53,27 @@ HookStageExecutor hookStageExecutor(HooksConfigurationProperties hooksConfigurat isConfigToInvokeRequired); } + @Bean + Set moduleConfigPresenceSet(Collection modules, Environment environment) { + if (modules.isEmpty() || !(environment instanceof ConfigurableEnvironment)) { + return Collections.emptySet(); + } + + final Set hooksPropertiesKeys = ((ConfigurableEnvironment) environment).getPropertySources().stream() + .filter(EnumerablePropertySource.class::isInstance) + .map(EnumerablePropertySource.class::cast) + .map(EnumerablePropertySource::getPropertyNames) + .flatMap(Arrays::stream) + .filter(propertyName -> propertyName.startsWith("hooks.")) + .collect(Collectors.toSet()); + + return modules.stream() + .map(Module::code) + .filter(code -> hooksPropertiesKeys.stream() + .anyMatch(key -> key.startsWith("hooks.%s.config".formatted(code)))) + .collect(Collectors.toSet()); + } + @Bean @ConfigurationProperties("hooks") HooksConfigurationProperties hooksConfigurationProperties() { diff --git a/src/test/java/org/prebid/server/hooks/execution/HookCatalogTest.java b/src/test/java/org/prebid/server/hooks/execution/HookCatalogTest.java index 108605efe58..63ec73bbe3b 100644 --- a/src/test/java/org/prebid/server/hooks/execution/HookCatalogTest.java +++ b/src/test/java/org/prebid/server/hooks/execution/HookCatalogTest.java @@ -20,30 +20,43 @@ import static java.util.Collections.singleton; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; +import static org.mockito.Mock.Strictness; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @ExtendWith(MockitoExtension.class) public class HookCatalogTest { - @Mock + @Mock(strictness = Strictness.LENIENT) private Module sampleModule; @Mock private Hook sampleHook; - private HookCatalog hookCatalog; + private HookCatalog target; @BeforeEach public void setUp() { given(sampleModule.code()).willReturn("sample-module"); - hookCatalog = new HookCatalog(singleton(sampleModule)); + target = new HookCatalog(singleton(sampleModule), singleton("sample-module")); + } + + @Test + public void hasHostConfigShouldReturnTrueWhenModuleHasConfig() { + // when & then + assertThat(target.hasHostConfig("sample-module")).isTrue(); + } + + @Test + public void hasHostConfigShouldReturnFalseWhenModuleDoesNotHaveConfig() { + // when & then + assertThat(target.hasHostConfig("another-module")).isFalse(); } @Test public void hookByIdShouldTolerateUnknownModule() { // when - final EntrypointHook foundHook = hookCatalog.hookById( + final EntrypointHook foundHook = target.hookById( "unknown-module", null, StageWithHookType.ENTRYPOINT); // then @@ -53,7 +66,7 @@ public void hookByIdShouldTolerateUnknownModule() { @Test public void hookByIdShouldTolerateUnknownHook() { // when - final EntrypointHook foundHook = hookCatalog.hookById( + final EntrypointHook foundHook = target.hookById( "sample-module", "unknown-hook", StageWithHookType.ENTRYPOINT); // then @@ -66,7 +79,7 @@ public void hookByIdShouldReturnEntrypointHook() { givenHook(EntrypointHook.class); // when - final EntrypointHook foundHook = hookCatalog.hookById( + final EntrypointHook foundHook = target.hookById( "sample-module", "sample-hook", StageWithHookType.ENTRYPOINT); // then @@ -81,7 +94,7 @@ public void hookByIdShouldReturnRawAuctionRequestHook() { givenHook(RawAuctionRequestHook.class); // when - final RawAuctionRequestHook foundHook = hookCatalog.hookById( + final RawAuctionRequestHook foundHook = target.hookById( "sample-module", "sample-hook", StageWithHookType.RAW_AUCTION_REQUEST); // then @@ -96,7 +109,7 @@ public void hookByIdShouldReturnProcessedAuctionRequestHook() { givenHook(ProcessedAuctionRequestHook.class); // when - final ProcessedAuctionRequestHook foundHook = hookCatalog.hookById( + final ProcessedAuctionRequestHook foundHook = target.hookById( "sample-module", "sample-hook", StageWithHookType.PROCESSED_AUCTION_REQUEST); // then @@ -111,7 +124,7 @@ public void hookByIdShouldReturnBidderRequestHook() { givenHook(BidderRequestHook.class); // when - final BidderRequestHook foundHook = hookCatalog.hookById( + final BidderRequestHook foundHook = target.hookById( "sample-module", "sample-hook", StageWithHookType.BIDDER_REQUEST); // then @@ -126,7 +139,7 @@ public void hookByIdShouldReturnRawBidderResponseHook() { givenHook(RawBidderResponseHook.class); // when - final RawBidderResponseHook foundHook = hookCatalog.hookById( + final RawBidderResponseHook foundHook = target.hookById( "sample-module", "sample-hook", StageWithHookType.RAW_BIDDER_RESPONSE); // then @@ -141,7 +154,7 @@ public void hookByIdShouldReturnProcessedBidderResponseHook() { givenHook(ProcessedBidderResponseHook.class); // when - final ProcessedBidderResponseHook foundHook = hookCatalog.hookById( + final ProcessedBidderResponseHook foundHook = target.hookById( "sample-module", "sample-hook", StageWithHookType.PROCESSED_BIDDER_RESPONSE); // then @@ -156,7 +169,7 @@ public void hookByIdShouldReturnAuctionResponseHook() { givenHook(AuctionResponseHook.class); // when - final AuctionResponseHook foundHook = hookCatalog.hookById( + final AuctionResponseHook foundHook = target.hookById( "sample-module", "sample-hook", StageWithHookType.AUCTION_RESPONSE); // then diff --git a/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java b/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java index 22d8e49f6a2..c5592435ec0 100644 --- a/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java +++ b/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java @@ -1362,6 +1362,86 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsRequiredBut })); } + @Test + public void shouldExecuteRawAuctionRequestHooksWhichHasHostConfigWhenAccountConfigIsRequiredAndAbsent( + VertxTestContext context) { + + // given + givenRawAuctionRequestHook( + "module-alpha", + "hook-a", + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + payload.bidRequest().toBuilder().at(1).build())))); + + givenRawAuctionRequestHook( + "module-alpha", + "hook-b", + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + payload.bidRequest().toBuilder().id("id").build())))); + + givenRawAuctionRequestHook( + "module-beta", + "hook-a", + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + payload.bidRequest().toBuilder().test(1).build())))); + + givenRawAuctionRequestHook( + "module-beta", + "hook-b", + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + payload.bidRequest().toBuilder().tmax(1000L).build())))); + + given(hookCatalog.hasHostConfig("module-alpha")).willReturn(true); + given(hookCatalog.hasHostConfig("module-beta")).willReturn(false); + + final String hostExecutionPlan = executionPlan(singletonMap( + Endpoint.openrtb2_auction, + EndpointExecutionPlan.of(singletonMap( + Stage.raw_auction_request, + execPlanTwoGroupsTwoHooksEach())))); + + final HookStageExecutor executor = HookStageExecutor.create( + hostExecutionPlan, + null, + hookCatalog, + timeoutFactory, + vertx, + clock, + jacksonMapper, + true); + + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + + // when + final Future> future = executor.executeRawAuctionRequestStage( + AuctionContext.builder() + .bidRequest(BidRequest.builder().build()) + .account(Account.empty("accountId")) + .hookExecutionContext(hookExecutionContext) + .debugContext(DebugContext.empty()) + .build()); + + // then + future.onComplete(context.succeeding(result -> { + assertThat(result).isNotNull(); + assertThat(result.getPayload()).isNotNull().satisfies(payload -> + assertThat(payload.bidRequest()).isEqualTo(BidRequest.builder() + .at(1) + .id("id") + .build())); + + assertThat(hookExecutionContext.getStageOutcomes()) + .hasEntrySatisfying( + Stage.raw_auction_request, + stageOutcomes -> assertThat(stageOutcomes) + .hasSize(1) + .extracting(StageExecutionOutcome::getEntity) + .containsOnly("auction-request")); + + context.completeNow(); + })); + } + @Test public void shouldExecuteRawAuctionRequestHooksHappyPath(VertxTestContext context) { // given diff --git a/src/test/resources/org/prebid/server/it/test-application-hooks.properties b/src/test/resources/org/prebid/server/it/test-application-hooks.properties index 76a196872fe..bd9b5505baf 100644 --- a/src/test/resources/org/prebid/server/it/test-application-hooks.properties +++ b/src/test/resources/org/prebid/server/it/test-application-hooks.properties @@ -1,3 +1,5 @@ +settings.modules.require-config-to-invoke=true +hooks.sample-it-module.config.anything=true hooks.host-execution-plan={ \ "endpoints": { \ "/openrtb2/auction": { \ From 33b9cbbdba76f2ee9aef7d8dd4e2d2ed675e1ab8 Mon Sep 17 00:00:00 2001 From: antonbabak Date: Thu, 21 Nov 2024 14:57:06 +0100 Subject: [PATCH 02/11] Small fix --- .../org/prebid/server/spring/config/HooksConfiguration.java | 2 +- .../org/prebid/server/it/test-application-hooks.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java b/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java index cfe05e23120..8cc7e9ac00d 100644 --- a/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java @@ -70,7 +70,7 @@ Set moduleConfigPresenceSet(Collection modules, Environment envi return modules.stream() .map(Module::code) .filter(code -> hooksPropertiesKeys.stream() - .anyMatch(key -> key.startsWith("hooks.%s.config".formatted(code)))) + .anyMatch(key -> key.startsWith("hooks.%s".formatted(code)))) .collect(Collectors.toSet()); } diff --git a/src/test/resources/org/prebid/server/it/test-application-hooks.properties b/src/test/resources/org/prebid/server/it/test-application-hooks.properties index bd9b5505baf..a6f4b903eba 100644 --- a/src/test/resources/org/prebid/server/it/test-application-hooks.properties +++ b/src/test/resources/org/prebid/server/it/test-application-hooks.properties @@ -1,5 +1,5 @@ settings.modules.require-config-to-invoke=true -hooks.sample-it-module.config.anything=true +hooks.sample-it-module.anything.anything=true hooks.host-execution-plan={ \ "endpoints": { \ "/openrtb2/auction": { \ From eb1debbe1ab93668ee082a010e8c050d7e4f7fcb Mon Sep 17 00:00:00 2001 From: antonbabak Date: Wed, 27 Nov 2024 14:11:24 +0100 Subject: [PATCH 03/11] Module Execution Config --- .../server/hooks/execution/GroupExecutor.java | 68 +++++++--- .../server/hooks/execution/HookCatalog.java | 9 +- .../hooks/execution/HookStageExecutor.java | 11 +- .../server/hooks/execution/StageExecutor.java | 10 +- .../model/AccountHooksConfiguration.java | 3 + .../spring/config/HooksConfiguration.java | 32 +---- .../hooks/execution/HookCatalogTest.java | 37 ++---- .../execution/HookStageExecutorTest.java | 121 ++++++++++++------ .../it/test-application-hooks.properties | 2 - 9 files changed, 161 insertions(+), 132 deletions(-) diff --git a/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java b/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java index 6bf57bec2c7..51f6b38be3e 100644 --- a/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java +++ b/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java @@ -5,6 +5,7 @@ import io.vertx.core.Future; import io.vertx.core.Promise; import io.vertx.core.Vertx; +import org.apache.commons.lang3.BooleanUtils; import org.prebid.server.hooks.execution.model.ExecutionGroup; import org.prebid.server.hooks.execution.model.HookExecutionContext; import org.prebid.server.hooks.execution.model.HookId; @@ -19,6 +20,8 @@ import org.prebid.server.log.LoggerFactory; import java.time.Clock; +import java.util.Collections; +import java.util.Map; import java.util.concurrent.TimeoutException; import java.util.function.Function; import java.util.function.Supplier; @@ -28,30 +31,38 @@ class GroupExecutor { private static final ConditionalLogger conditionalLogger = new ConditionalLogger(LoggerFactory.getLogger(GroupExecutor.class)); + private static final String MODULE_ALWAYS_EXECUTE_MESSAGE = "Can not skip the module execution execution"; + private final Vertx vertx; private final Clock clock; private final boolean isConfigToInvokeRequired; + private final Map modulesExecution; private ExecutionGroup group; private PAYLOAD initialPayload; private Function> hookProvider; - private Function moduleConfigProvider; private InvocationContextProvider invocationContextProvider; private HookExecutionContext hookExecutionContext; private boolean rejectAllowed; - private GroupExecutor(Vertx vertx, Clock clock, boolean isConfigToInvokeRequired) { + private GroupExecutor(Vertx vertx, + Clock clock, + boolean isConfigToInvokeRequired, + Map modulesExecution) { + this.vertx = vertx; this.clock = clock; this.isConfigToInvokeRequired = isConfigToInvokeRequired; + this.modulesExecution = modulesExecution; } public static GroupExecutor create( Vertx vertx, Clock clock, - boolean isConfigToInvokeRequired) { + boolean isConfigToInvokeRequired, + Map modulesExecution) { - return new GroupExecutor<>(vertx, clock, isConfigToInvokeRequired); + return new GroupExecutor<>(vertx, clock, isConfigToInvokeRequired, modulesExecution); } public GroupExecutor withGroup(ExecutionGroup group) { @@ -69,11 +80,6 @@ public GroupExecutor withHookProvider(Function withModuleConfigProvider(Function moduleConfigProvider) { - this.moduleConfigProvider = moduleConfigProvider; - return this; - } - public GroupExecutor withInvocationContextProvider( InvocationContextProvider invocationContextProvider) { @@ -123,22 +129,42 @@ private Future> executeHook( final CONTEXT invocationContext = invocationContextProvider.apply(timeout, hookId, moduleContextFor(hookId)); - final Boolean isHostConfigProvided = moduleConfigProvider.apply(hookId); + return skipExecution(invocationContext, hookId).recover(ignored -> + executeWithTimeout(() -> hook.call(groupResult.payload(), invocationContext), timeout)); + } + + private Future> skipExecution(CONTEXT invocationContext, HookId hookId) { + if (modulesExecution == null || !(invocationContext instanceof AuctionInvocationContext)) { + return Future.failedFuture(MODULE_ALWAYS_EXECUTE_MESSAGE); + } + + final String moduleCode = hookId.getModuleCode(); + final Boolean toBeExecuted = modulesExecution.get(moduleCode); - if (!isHostConfigProvided - && isConfigToInvokeRequired - && invocationContext instanceof AuctionInvocationContext) { + if (BooleanUtils.isTrue(toBeExecuted)) { + return Future.failedFuture(MODULE_ALWAYS_EXECUTE_MESSAGE); + } + + if (BooleanUtils.isFalse(toBeExecuted)) { + return Future.succeededFuture(InvocationResultImpl.builder() + .status(InvocationStatus.success) + .action(InvocationAction.no_invocation) + .debugMessages(Collections.singletonList( + "The module %s is disabled by the account".formatted(moduleCode))) + .build()); + } - final ObjectNode accountConfig = ((AuctionInvocationContext) invocationContext).accountConfig(); - if (accountConfig == null || accountConfig.isNull()) { - return Future.succeededFuture(InvocationResultImpl.builder() - .status(InvocationStatus.success) - .action(InvocationAction.no_invocation) - .build()); - } + final ObjectNode accountConfig = ((AuctionInvocationContext) invocationContext).accountConfig(); + if (isConfigToInvokeRequired && (accountConfig == null || accountConfig.isNull())) { + return Future.succeededFuture(InvocationResultImpl.builder() + .status(InvocationStatus.success) + .action(InvocationAction.no_invocation) + .debugMessages(Collections.singletonList( + "The account config for the module %s is required but absent".formatted(moduleCode))) + .build()); } - return executeWithTimeout(() -> hook.call(groupResult.payload(), invocationContext), timeout); + return Future.failedFuture(MODULE_ALWAYS_EXECUTE_MESSAGE); } private Future executeWithTimeout(Supplier> action, Long timeout) { diff --git a/src/main/java/org/prebid/server/hooks/execution/HookCatalog.java b/src/main/java/org/prebid/server/hooks/execution/HookCatalog.java index 9b9347c7ff9..754e3925b11 100644 --- a/src/main/java/org/prebid/server/hooks/execution/HookCatalog.java +++ b/src/main/java/org/prebid/server/hooks/execution/HookCatalog.java @@ -7,7 +7,6 @@ import java.util.Collection; import java.util.Objects; -import java.util.Set; /** * Provides simple access to all {@link Hook}s registered in application. @@ -15,11 +14,9 @@ public class HookCatalog { private final Collection modules; - private final Set moduleConfigPresenceSet; - public HookCatalog(Collection modules, Set moduleConfigPresenceSet) { + public HookCatalog(Collection modules) { this.modules = Objects.requireNonNull(modules); - this.moduleConfigPresenceSet = Objects.requireNonNull(moduleConfigPresenceSet); } public > HOOK hookById( @@ -38,8 +35,4 @@ public HookCatalog(Collection modules, Set moduleConfigPresenceS .findFirst() .orElse(null); } - - public boolean hasHostConfig(String moduleCode) { - return moduleConfigPresenceSet.contains(moduleCode); - } } diff --git a/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java b/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java index 8e565d29d90..080010e3bd0 100644 --- a/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java +++ b/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java @@ -54,6 +54,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.stream.Stream; public class HookStageExecutor { @@ -273,9 +274,16 @@ private StageExecutor modulesExecutionForAccount(Account account) { + return Optional.ofNullable(account.getHooks()) + .map(AccountHooksConfiguration::getModulesExecution) + .orElseGet(Collections::emptyMap); + } + private static ExecutionPlan parseAndValidateExecutionPlan( String executionPlan, JacksonMapper mapper, @@ -402,8 +410,7 @@ private InvocationContextProvider bidderInvocationConte String bidder) { return (timeout, hookId, moduleContext) -> BidderInvocationContextImpl.of( - auctionInvocationContext(endpoint, timeout, auctionContext, hookId, moduleContext), - bidder); + auctionInvocationContext(endpoint, timeout, auctionContext, hookId, moduleContext), bidder); } private Timeout createTimeout(Long timeout) { diff --git a/src/main/java/org/prebid/server/hooks/execution/StageExecutor.java b/src/main/java/org/prebid/server/hooks/execution/StageExecutor.java index 183e84f78a5..a4cfa53ff69 100644 --- a/src/main/java/org/prebid/server/hooks/execution/StageExecutor.java +++ b/src/main/java/org/prebid/server/hooks/execution/StageExecutor.java @@ -12,6 +12,7 @@ import java.time.Clock; import java.util.ArrayList; +import java.util.Map; class StageExecutor { @@ -27,6 +28,7 @@ class StageExecutor { private InvocationContextProvider invocationContextProvider; private HookExecutionContext hookExecutionContext; private boolean rejectAllowed; + private Map modulesExecution; private StageExecutor(HookCatalog hookCatalog, Vertx vertx, Clock clock, boolean isConfigToInvokeRequired) { this.hookCatalog = hookCatalog; @@ -81,6 +83,11 @@ public StageExecutor withRejectAllowed(boolean rejectAllowed) return this; } + public StageExecutor withModulesExecution(Map modulesExecution) { + this.modulesExecution = modulesExecution; + return this; + } + public Future> execute() { Future> stageFuture = Future.succeededFuture(StageResult.of(initialPayload, entity)); @@ -97,12 +104,11 @@ public Future> execute() { } private Future> executeGroup(ExecutionGroup group, PAYLOAD initialPayload) { - return GroupExecutor.create(vertx, clock, isConfigToInvokeRequired) + return GroupExecutor.create(vertx, clock, isConfigToInvokeRequired, modulesExecution) .withGroup(group) .withInitialPayload(initialPayload) .withHookProvider( hookId -> hookCatalog.hookById(hookId.getModuleCode(), hookId.getHookImplCode(), stage)) - .withModuleConfigProvider(hookId -> hookCatalog.hasHostConfig(hookId.getModuleCode())) .withInvocationContextProvider(invocationContextProvider) .withHookExecutionContext(hookExecutionContext) .withRejectAllowed(rejectAllowed) diff --git a/src/main/java/org/prebid/server/settings/model/AccountHooksConfiguration.java b/src/main/java/org/prebid/server/settings/model/AccountHooksConfiguration.java index 75d3b03b6e5..b3949be3e9b 100644 --- a/src/main/java/org/prebid/server/settings/model/AccountHooksConfiguration.java +++ b/src/main/java/org/prebid/server/settings/model/AccountHooksConfiguration.java @@ -14,4 +14,7 @@ public class AccountHooksConfiguration { ExecutionPlan executionPlan; Map modules; + + @JsonAlias("modules-execute") + Map modulesExecution; } diff --git a/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java b/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java index 8cc7e9ac00d..64534d119aa 100644 --- a/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java @@ -12,24 +12,17 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.EnumerablePropertySource; -import org.springframework.core.env.Environment; import org.springframework.validation.annotation.Validated; import java.time.Clock; -import java.util.Arrays; import java.util.Collection; -import java.util.Collections; -import java.util.Set; -import java.util.stream.Collectors; @Configuration public class HooksConfiguration { @Bean - HookCatalog hookCatalog(Collection modules, Set moduleConfigPresenceSet) { - return new HookCatalog(modules, moduleConfigPresenceSet); + HookCatalog hookCatalog(Collection modules) { + return new HookCatalog(modules); } @Bean @@ -53,27 +46,6 @@ HookStageExecutor hookStageExecutor(HooksConfigurationProperties hooksConfigurat isConfigToInvokeRequired); } - @Bean - Set moduleConfigPresenceSet(Collection modules, Environment environment) { - if (modules.isEmpty() || !(environment instanceof ConfigurableEnvironment)) { - return Collections.emptySet(); - } - - final Set hooksPropertiesKeys = ((ConfigurableEnvironment) environment).getPropertySources().stream() - .filter(EnumerablePropertySource.class::isInstance) - .map(EnumerablePropertySource.class::cast) - .map(EnumerablePropertySource::getPropertyNames) - .flatMap(Arrays::stream) - .filter(propertyName -> propertyName.startsWith("hooks.")) - .collect(Collectors.toSet()); - - return modules.stream() - .map(Module::code) - .filter(code -> hooksPropertiesKeys.stream() - .anyMatch(key -> key.startsWith("hooks.%s".formatted(code)))) - .collect(Collectors.toSet()); - } - @Bean @ConfigurationProperties("hooks") HooksConfigurationProperties hooksConfigurationProperties() { diff --git a/src/test/java/org/prebid/server/hooks/execution/HookCatalogTest.java b/src/test/java/org/prebid/server/hooks/execution/HookCatalogTest.java index 63ec73bbe3b..108605efe58 100644 --- a/src/test/java/org/prebid/server/hooks/execution/HookCatalogTest.java +++ b/src/test/java/org/prebid/server/hooks/execution/HookCatalogTest.java @@ -20,43 +20,30 @@ import static java.util.Collections.singleton; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; -import static org.mockito.Mock.Strictness; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @ExtendWith(MockitoExtension.class) public class HookCatalogTest { - @Mock(strictness = Strictness.LENIENT) + @Mock private Module sampleModule; @Mock private Hook sampleHook; - private HookCatalog target; + private HookCatalog hookCatalog; @BeforeEach public void setUp() { given(sampleModule.code()).willReturn("sample-module"); - target = new HookCatalog(singleton(sampleModule), singleton("sample-module")); - } - - @Test - public void hasHostConfigShouldReturnTrueWhenModuleHasConfig() { - // when & then - assertThat(target.hasHostConfig("sample-module")).isTrue(); - } - - @Test - public void hasHostConfigShouldReturnFalseWhenModuleDoesNotHaveConfig() { - // when & then - assertThat(target.hasHostConfig("another-module")).isFalse(); + hookCatalog = new HookCatalog(singleton(sampleModule)); } @Test public void hookByIdShouldTolerateUnknownModule() { // when - final EntrypointHook foundHook = target.hookById( + final EntrypointHook foundHook = hookCatalog.hookById( "unknown-module", null, StageWithHookType.ENTRYPOINT); // then @@ -66,7 +53,7 @@ public void hookByIdShouldTolerateUnknownModule() { @Test public void hookByIdShouldTolerateUnknownHook() { // when - final EntrypointHook foundHook = target.hookById( + final EntrypointHook foundHook = hookCatalog.hookById( "sample-module", "unknown-hook", StageWithHookType.ENTRYPOINT); // then @@ -79,7 +66,7 @@ public void hookByIdShouldReturnEntrypointHook() { givenHook(EntrypointHook.class); // when - final EntrypointHook foundHook = target.hookById( + final EntrypointHook foundHook = hookCatalog.hookById( "sample-module", "sample-hook", StageWithHookType.ENTRYPOINT); // then @@ -94,7 +81,7 @@ public void hookByIdShouldReturnRawAuctionRequestHook() { givenHook(RawAuctionRequestHook.class); // when - final RawAuctionRequestHook foundHook = target.hookById( + final RawAuctionRequestHook foundHook = hookCatalog.hookById( "sample-module", "sample-hook", StageWithHookType.RAW_AUCTION_REQUEST); // then @@ -109,7 +96,7 @@ public void hookByIdShouldReturnProcessedAuctionRequestHook() { givenHook(ProcessedAuctionRequestHook.class); // when - final ProcessedAuctionRequestHook foundHook = target.hookById( + final ProcessedAuctionRequestHook foundHook = hookCatalog.hookById( "sample-module", "sample-hook", StageWithHookType.PROCESSED_AUCTION_REQUEST); // then @@ -124,7 +111,7 @@ public void hookByIdShouldReturnBidderRequestHook() { givenHook(BidderRequestHook.class); // when - final BidderRequestHook foundHook = target.hookById( + final BidderRequestHook foundHook = hookCatalog.hookById( "sample-module", "sample-hook", StageWithHookType.BIDDER_REQUEST); // then @@ -139,7 +126,7 @@ public void hookByIdShouldReturnRawBidderResponseHook() { givenHook(RawBidderResponseHook.class); // when - final RawBidderResponseHook foundHook = target.hookById( + final RawBidderResponseHook foundHook = hookCatalog.hookById( "sample-module", "sample-hook", StageWithHookType.RAW_BIDDER_RESPONSE); // then @@ -154,7 +141,7 @@ public void hookByIdShouldReturnProcessedBidderResponseHook() { givenHook(ProcessedBidderResponseHook.class); // when - final ProcessedBidderResponseHook foundHook = target.hookById( + final ProcessedBidderResponseHook foundHook = hookCatalog.hookById( "sample-module", "sample-hook", StageWithHookType.PROCESSED_BIDDER_RESPONSE); // then @@ -169,7 +156,7 @@ public void hookByIdShouldReturnAuctionResponseHook() { givenHook(AuctionResponseHook.class); // when - final AuctionResponseHook foundHook = target.hookById( + final AuctionResponseHook foundHook = hookCatalog.hookById( "sample-module", "sample-hook", StageWithHookType.AUCTION_RESPONSE); // then diff --git a/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java b/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java index c5592435ec0..a14b2aec27f 100644 --- a/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java +++ b/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java @@ -1177,7 +1177,7 @@ public void shouldExecuteRawAuctionRequestHooksWhenAccountOverridesExecutionPlan execPlanOneGroupOneHook("module-beta", "hook-b"))))); final Account account = Account.builder() .id("accountId") - .hooks(AccountHooksConfiguration.of(accountPlan, null)) + .hooks(AccountHooksConfiguration.of(accountPlan, null, null)) .build(); final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); @@ -1233,7 +1233,7 @@ public void shouldExecuteRawAuctionRequestHooksToleratingUnknownHookInAccountPla HookId.of("module-beta", "hook-a"))))))))); final Account account = Account.builder() .id("accountId") - .hooks(AccountHooksConfiguration.of(accountPlan, null)) + .hooks(AccountHooksConfiguration.of(accountPlan, null, null)) .build(); final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); @@ -1289,7 +1289,7 @@ public void shouldExecuteRawAuctionRequestHooksToleratingUnknownHookInAccountPla } @Test - public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsRequiredButAbsent(VertxTestContext context) { + public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsNotRequired(VertxTestContext context) { // given givenRawAuctionRequestHook( "module-alpha", @@ -1297,12 +1297,6 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsRequiredBut immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().at(1).build())))); - givenRawAuctionRequestHook( - "module-alpha", - "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( - payload.bidRequest().toBuilder().id("id").build())))); - givenRawAuctionRequestHook( "module-beta", "hook-a", @@ -1310,16 +1304,32 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsRequiredBut payload.bidRequest().toBuilder().test(1).build())))); givenRawAuctionRequestHook( - "module-beta", + "module-gamma", + "hook-b", + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + payload.bidRequest().toBuilder().id("id").build())))); + + givenRawAuctionRequestHook( + "module-delta", "hook-b", immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().tmax(1000L).build())))); + final StageExecutionPlan stageExecutionPlan = StageExecutionPlan.of(asList( + ExecutionGroup.of( + 200L, + asList( + HookId.of("module-alpha", "hook-a"), + HookId.of("module-beta", "hook-a"))), + ExecutionGroup.of( + 200L, + asList( + HookId.of("module-gamma", "hook-b"), + HookId.of("module-delta", "hook-b"))))); + final String hostExecutionPlan = executionPlan(singletonMap( Endpoint.openrtb2_auction, - EndpointExecutionPlan.of(singletonMap( - Stage.raw_auction_request, - execPlanTwoGroupsTwoHooksEach())))); + EndpointExecutionPlan.of(singletonMap(Stage.raw_auction_request, stageExecutionPlan)))); final HookStageExecutor executor = HookStageExecutor.create( hostExecutionPlan, @@ -1329,7 +1339,7 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsRequiredBut vertx, clock, jacksonMapper, - true); + false); final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); @@ -1338,7 +1348,16 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsRequiredBut final Future> future = executor.executeRawAuctionRequestStage( AuctionContext.builder() .bidRequest(givenBidRequest) - .account(Account.empty("accountId")) + .account(Account.builder() + .id("accountId") + .hooks(AccountHooksConfiguration.of( + null, + Map.of("module-alpha", mapper.createObjectNode(), + "module-beta", mapper.createObjectNode(), + "module-gamma", mapper.createObjectNode()), + Map.of("module-alpha", true, + "module-beta", false))) + .build()) .hookExecutionContext(hookExecutionContext) .debugContext(DebugContext.empty()) .build()); @@ -1346,9 +1365,12 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsRequiredBut // then future.onComplete(context.succeeding(result -> { assertThat(result).isNotNull(); - assertThat(result.getPayload()).isNotNull() - .extracting(AuctionRequestPayload::bidRequest) - .isEqualTo(givenBidRequest); + assertThat(result.getPayload()).isNotNull().satisfies(payload -> + assertThat(payload.bidRequest()).isEqualTo(BidRequest.builder() + .at(1) + .id("id") + .tmax(1000L) + .build())); assertThat(hookExecutionContext.getStageOutcomes()) .hasEntrySatisfying( @@ -1363,9 +1385,7 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsRequiredBut } @Test - public void shouldExecuteRawAuctionRequestHooksWhichHasHostConfigWhenAccountConfigIsRequiredAndAbsent( - VertxTestContext context) { - + public void shouldExecuteRawAuctionRequestHooksWhenAccountConfigIsRequired(VertxTestContext context) { // given givenRawAuctionRequestHook( "module-alpha", @@ -1373,12 +1393,6 @@ public void shouldExecuteRawAuctionRequestHooksWhichHasHostConfigWhenAccountConf immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().at(1).build())))); - givenRawAuctionRequestHook( - "module-alpha", - "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( - payload.bidRequest().toBuilder().id("id").build())))); - givenRawAuctionRequestHook( "module-beta", "hook-a", @@ -1386,19 +1400,32 @@ public void shouldExecuteRawAuctionRequestHooksWhichHasHostConfigWhenAccountConf payload.bidRequest().toBuilder().test(1).build())))); givenRawAuctionRequestHook( - "module-beta", + "module-gamma", + "hook-b", + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + payload.bidRequest().toBuilder().id("id").build())))); + + givenRawAuctionRequestHook( + "module-delta", "hook-b", immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().tmax(1000L).build())))); - given(hookCatalog.hasHostConfig("module-alpha")).willReturn(true); - given(hookCatalog.hasHostConfig("module-beta")).willReturn(false); + final StageExecutionPlan stageExecutionPlan = StageExecutionPlan.of(asList( + ExecutionGroup.of( + 200L, + asList( + HookId.of("module-alpha", "hook-a"), + HookId.of("module-beta", "hook-a"))), + ExecutionGroup.of( + 200L, + asList( + HookId.of("module-gamma", "hook-b"), + HookId.of("module-delta", "hook-b"))))); final String hostExecutionPlan = executionPlan(singletonMap( Endpoint.openrtb2_auction, - EndpointExecutionPlan.of(singletonMap( - Stage.raw_auction_request, - execPlanTwoGroupsTwoHooksEach())))); + EndpointExecutionPlan.of(singletonMap(Stage.raw_auction_request, stageExecutionPlan)))); final HookStageExecutor executor = HookStageExecutor.create( hostExecutionPlan, @@ -1413,10 +1440,20 @@ public void shouldExecuteRawAuctionRequestHooksWhichHasHostConfigWhenAccountConf final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); // when + final BidRequest givenBidRequest = BidRequest.builder().build(); final Future> future = executor.executeRawAuctionRequestStage( AuctionContext.builder() - .bidRequest(BidRequest.builder().build()) - .account(Account.empty("accountId")) + .bidRequest(givenBidRequest) + .account(Account.builder() + .id("accountId") + .hooks(AccountHooksConfiguration.of( + null, + Map.of("module-alpha", mapper.createObjectNode(), + "module-beta", mapper.createObjectNode(), + "module-gamma", mapper.createObjectNode()), + Map.of("module-alpha", true, + "module-beta", false))) + .build()) .hookExecutionContext(hookExecutionContext) .debugContext(DebugContext.empty()) .build()); @@ -1544,7 +1581,7 @@ public void shouldExecuteRawAuctionRequestHooksAndPassAuctionInvocationContext(V AuctionContext.builder() .bidRequest(BidRequest.builder().build()) .account(Account.builder() - .hooks(AccountHooksConfiguration.of(null, accountModulesConfiguration)) + .hooks(AccountHooksConfiguration.of(null, accountModulesConfiguration, null)) .build()) .hookExecutionContext(hookExecutionContext) .debugContext(DebugContext.empty()) @@ -1818,7 +1855,7 @@ public void shouldExecuteProcessedAuctionRequestHooksAndPassAuctionInvocationCon AuctionContext.builder() .bidRequest(BidRequest.builder().build()) .account(Account.builder() - .hooks(AccountHooksConfiguration.of(null, accountModulesConfiguration)) + .hooks(AccountHooksConfiguration.of(null, accountModulesConfiguration, null)) .build()) .hookExecutionContext(hookExecutionContext) .debugContext(DebugContext.empty()) @@ -2105,7 +2142,7 @@ public void shouldExecuteBidderRequestHooksAndPassBidderInvocationContext(VertxT .bidRequest(BidRequest.builder().build()) .account(Account.builder() .hooks(AccountHooksConfiguration.of( - null, singletonMap("module-alpha", mapper.createObjectNode()))) + null, singletonMap("module-alpha", mapper.createObjectNode()), null)) .build()) .hookExecutionContext(hookExecutionContext) .debugContext(DebugContext.empty()) @@ -2260,7 +2297,7 @@ public void shouldExecuteRawBidderResponseHooksAndPassBidderInvocationContext(Ve .bidRequest(BidRequest.builder().build()) .account(Account.builder() .hooks(AccountHooksConfiguration.of( - null, singletonMap("module-alpha", mapper.createObjectNode()))) + null, singletonMap("module-alpha", mapper.createObjectNode()), null)) .build()) .hookExecutionContext(hookExecutionContext) .debugContext(DebugContext.empty()) @@ -2421,7 +2458,7 @@ public void shouldExecuteProcessedBidderResponseHooksAndPassBidderInvocationCont .bidRequest(BidRequest.builder().build()) .account(Account.builder() .hooks(AccountHooksConfiguration.of( - null, singletonMap("module-alpha", mapper.createObjectNode()))) + null, singletonMap("module-alpha", mapper.createObjectNode()), null)) .build()) .hookExecutionContext(hookExecutionContext) .debugContext(DebugContext.empty()) @@ -2586,7 +2623,7 @@ public void shouldExecuteAllProcessedBidResponsesHooksAndPassAuctionInvocationCo .bidRequest(BidRequest.builder().build()) .account(Account.builder() .hooks(AccountHooksConfiguration.of( - null, singletonMap("module-alpha", mapper.createObjectNode()))) + null, singletonMap("module-alpha", mapper.createObjectNode()), null)) .build()) .hookExecutionContext(hookExecutionContext) .debugContext(DebugContext.empty()) @@ -2728,7 +2765,7 @@ public void shouldExecuteAuctionResponseHooksAndPassAuctionInvocationContext(Ver .bidRequest(BidRequest.builder().build()) .account(Account.builder() .hooks(AccountHooksConfiguration.of( - null, singletonMap("module-alpha", mapper.createObjectNode()))) + null, singletonMap("module-alpha", mapper.createObjectNode()), null)) .build()) .hookExecutionContext(hookExecutionContext) .debugContext(DebugContext.empty()) diff --git a/src/test/resources/org/prebid/server/it/test-application-hooks.properties b/src/test/resources/org/prebid/server/it/test-application-hooks.properties index a6f4b903eba..76a196872fe 100644 --- a/src/test/resources/org/prebid/server/it/test-application-hooks.properties +++ b/src/test/resources/org/prebid/server/it/test-application-hooks.properties @@ -1,5 +1,3 @@ -settings.modules.require-config-to-invoke=true -hooks.sample-it-module.anything.anything=true hooks.host-execution-plan={ \ "endpoints": { \ "/openrtb2/auction": { \ From 8683ec6d70b6b49f30c2e34c9582c650bc8ed10a Mon Sep 17 00:00:00 2001 From: antonbabak Date: Wed, 27 Nov 2024 16:05:12 +0100 Subject: [PATCH 04/11] Config Changes --- .../hooks/execution/HookStageExecutor.java | 4 +++- .../settings/model/AccountHooksAdminConfig.java | 16 ++++++++++++++++ .../model/AccountHooksConfiguration.java | 3 +-- .../hooks/execution/HookStageExecutorTest.java | 11 +++++++---- 4 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 src/main/java/org/prebid/server/settings/model/AccountHooksAdminConfig.java diff --git a/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java b/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java index 080010e3bd0..e59c1df268e 100644 --- a/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java +++ b/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java @@ -46,6 +46,7 @@ import org.prebid.server.model.CaseInsensitiveMultiMap; import org.prebid.server.model.Endpoint; import org.prebid.server.settings.model.Account; +import org.prebid.server.settings.model.AccountHooksAdminConfig; import org.prebid.server.settings.model.AccountHooksConfiguration; import java.time.Clock; @@ -280,7 +281,8 @@ private StageExecutor modulesExecutionForAccount(Account account) { return Optional.ofNullable(account.getHooks()) - .map(AccountHooksConfiguration::getModulesExecution) + .map(AccountHooksConfiguration::getAdmin) + .map(AccountHooksAdminConfig::getModuleExecution) .orElseGet(Collections::emptyMap); } diff --git a/src/main/java/org/prebid/server/settings/model/AccountHooksAdminConfig.java b/src/main/java/org/prebid/server/settings/model/AccountHooksAdminConfig.java new file mode 100644 index 00000000000..b9bd8e7eaaf --- /dev/null +++ b/src/main/java/org/prebid/server/settings/model/AccountHooksAdminConfig.java @@ -0,0 +1,16 @@ +package org.prebid.server.settings.model; + +import com.fasterxml.jackson.annotation.JsonAlias; +import lombok.Builder; +import lombok.Value; + +import java.util.Map; + +@Builder +@Value +public class AccountHooksAdminConfig { + + @JsonAlias("module-execution") + Map moduleExecution; + +} diff --git a/src/main/java/org/prebid/server/settings/model/AccountHooksConfiguration.java b/src/main/java/org/prebid/server/settings/model/AccountHooksConfiguration.java index b3949be3e9b..98edb138a52 100644 --- a/src/main/java/org/prebid/server/settings/model/AccountHooksConfiguration.java +++ b/src/main/java/org/prebid/server/settings/model/AccountHooksConfiguration.java @@ -15,6 +15,5 @@ public class AccountHooksConfiguration { Map modules; - @JsonAlias("modules-execute") - Map modulesExecution; + AccountHooksAdminConfig admin; } diff --git a/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java b/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java index a14b2aec27f..05939f7c278 100644 --- a/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java +++ b/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java @@ -79,6 +79,7 @@ import org.prebid.server.model.Endpoint; import org.prebid.server.proto.openrtb.ext.response.BidType; import org.prebid.server.settings.model.Account; +import org.prebid.server.settings.model.AccountHooksAdminConfig; import org.prebid.server.settings.model.AccountHooksConfiguration; import java.time.Clock; @@ -1355,8 +1356,9 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsNotRequired Map.of("module-alpha", mapper.createObjectNode(), "module-beta", mapper.createObjectNode(), "module-gamma", mapper.createObjectNode()), - Map.of("module-alpha", true, - "module-beta", false))) + AccountHooksAdminConfig.builder() + .moduleExecution(Map.of("module-alpha", true, "module-beta", false)) + .build())) .build()) .hookExecutionContext(hookExecutionContext) .debugContext(DebugContext.empty()) @@ -1451,8 +1453,9 @@ public void shouldExecuteRawAuctionRequestHooksWhenAccountConfigIsRequired(Vertx Map.of("module-alpha", mapper.createObjectNode(), "module-beta", mapper.createObjectNode(), "module-gamma", mapper.createObjectNode()), - Map.of("module-alpha", true, - "module-beta", false))) + AccountHooksAdminConfig.builder() + .moduleExecution(Map.of("module-alpha", true, "module-beta", false)) + .build())) .build()) .hookExecutionContext(hookExecutionContext) .debugContext(DebugContext.empty()) From de764bc48fc94106edbf458bfbed4f3f8a526059 Mon Sep 17 00:00:00 2001 From: antonbabak Date: Thu, 28 Nov 2024 10:04:15 +0100 Subject: [PATCH 05/11] Fix comments --- docs/metrics.md | 12 -- ...ConfiantAdQualityBidResponsesScanHook.java | 2 +- .../v1/model/InvocationResultImpl.java | 36 +++++ ...FiftyOneDeviceDetectionEntrypointHook.java | 2 +- ...eDeviceDetectionRawAuctionRequestHook.java | 2 +- .../v1/model/InvocationResultImpl.java | 24 +++ .../v1/Ortb2BlockingBidderRequestHook.java | 2 +- .../Ortb2BlockingRawBidderResponseHook.java | 2 +- .../v1/model/InvocationResultImpl.java | 37 +++++ .../Ortb2BlockingBidderRequestHookTest.java | 2 +- ...rtb2BlockingRawBidderResponseHookTest.java | 2 +- ...orrectionAllProcessedBidResponsesHook.java | 8 +- .../v1/model/InvocationResultImpl.java | 38 +++++ ...diaFilterAllProcessedBidResponsesHook.java | 2 +- .../v1/model}/InvocationResultImpl.java | 6 +- .../server/auction/ExchangeService.java | 1 - .../server/hooks/execution/GroupExecutor.java | 61 +------- .../server/hooks/execution/GroupResult.java | 1 - .../hooks/execution/HookStageExecutor.java | 22 ++- .../server/hooks/execution/StageExecutor.java | 11 +- .../execution/model/ExecutionAction.java | 2 +- .../server/hooks/v1/InvocationAction.java | 2 +- .../org/prebid/server/metric/MetricName.java | 1 - .../org/prebid/server/metric/Metrics.java | 17 +- .../execution/HookStageExecutorTest.java | 145 +++++++++--------- ...ltUtils.java => InvocationResultImpl.java} | 30 +++- .../it/hooks/SampleItAuctionResponseHook.java | 4 +- .../it/hooks/SampleItBidderRequestHook.java | 4 +- .../it/hooks/SampleItEntrypointHook.java | 6 +- .../SampleItProcessedAuctionRequestHook.java | 4 +- .../SampleItProcessedBidderResponseHook.java | 4 +- .../hooks/SampleItRawBidderResponseHook.java | 4 +- .../SampleItRejectingBidderRequestHook.java | 4 +- ...tRejectingProcessedAuctionRequestHook.java | 4 +- ...tRejectingProcessedBidderResponseHook.java | 4 +- ...ampleItRejectingRawAuctionRequestHook.java | 4 +- ...ampleItRejectingRawBidderResponseHook.java | 4 +- .../org/prebid/server/metric/MetricsTest.java | 27 +--- 38 files changed, 314 insertions(+), 229 deletions(-) create mode 100644 extra/modules/confiant-ad-quality/src/main/java/org/prebid/server/hooks/modules/com/confiant/adquality/v1/model/InvocationResultImpl.java create mode 100644 extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/model/InvocationResultImpl.java create mode 100644 extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/model/InvocationResultImpl.java create mode 100644 extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/model/InvocationResultImpl.java rename {src/main/java/org/prebid/server/hooks/v1 => extra/modules/pb-richmedia-filter/src/main/java/org/prebid/server/hooks/modules/pb/richmedia/filter/v1/model}/InvocationResultImpl.java (66%) rename src/test/java/org/prebid/server/hooks/v1/{InvocationResultUtils.java => InvocationResultImpl.java} (75%) diff --git a/docs/metrics.md b/docs/metrics.md index 85df92bc269..75a663407e0 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -135,15 +135,3 @@ Following metrics are collected and submitted if account is configured with `det - `analytics..(auction|amp|video|cookie_sync|event|setuid).timeout` - number of event requests, failed with timeout cause - `analytics..(auction|amp|video|cookie_sync|event|setuid).err` - number of event requests, failed with errors - `analytics..(auction|amp|video|cookie_sync|event|setuid).badinput` - number of event requests, rejected with bad input cause - -## Modules metrics -- `modules.module..stage..hook..call` - number of times the hook is called -- `modules.module..stage..hook..duration` - timer tracking the called hook execution time -- `modules.module..stage..hook..success.(noop|update|reject|no-invocation)` - number of times the hook is called successfully with the action applied -- `modules.module..stage..hook..(failure|timeout|execution-error)` - number of times the hook execution is failed - -## Modules per-account metrics -- `account..modules.module..call` - number of times the module is called -- `account..modules.module..duration` - timer tracking the called module execution time -- `account..modules.module..success.(noop|update|reject|no-invocation)` - number of times the module is called successfully with the action applied -- `account..modules.module..failure` - number of times the module execution is failed 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 2db501f1852..7db1446bcce 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 @@ -18,9 +18,9 @@ import org.prebid.server.hooks.modules.com.confiant.adquality.core.BidsScanResult; import org.prebid.server.hooks.modules.com.confiant.adquality.core.BidsScanner; import org.prebid.server.hooks.modules.com.confiant.adquality.model.GroupByIssues; +import org.prebid.server.hooks.modules.com.confiant.adquality.v1.model.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationAction; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.auction.AuctionInvocationContext; import org.prebid.server.hooks.v1.bidder.AllProcessedBidResponsesHook; diff --git a/extra/modules/confiant-ad-quality/src/main/java/org/prebid/server/hooks/modules/com/confiant/adquality/v1/model/InvocationResultImpl.java b/extra/modules/confiant-ad-quality/src/main/java/org/prebid/server/hooks/modules/com/confiant/adquality/v1/model/InvocationResultImpl.java new file mode 100644 index 00000000000..76fa5759644 --- /dev/null +++ b/extra/modules/confiant-ad-quality/src/main/java/org/prebid/server/hooks/modules/com/confiant/adquality/v1/model/InvocationResultImpl.java @@ -0,0 +1,36 @@ +package org.prebid.server.hooks.modules.com.confiant.adquality.v1.model; + +import lombok.Builder; +import lombok.Value; +import lombok.experimental.Accessors; +import org.prebid.server.hooks.v1.InvocationAction; +import org.prebid.server.hooks.v1.InvocationResult; +import org.prebid.server.hooks.v1.InvocationStatus; +import org.prebid.server.hooks.v1.PayloadUpdate; +import org.prebid.server.hooks.v1.analytics.Tags; + +import java.util.List; + +@Accessors(fluent = true) +@Builder +@Value +public class InvocationResultImpl implements InvocationResult { + + InvocationStatus status; + + String message; + + InvocationAction action; + + PayloadUpdate payloadUpdate; + + List errors; + + List warnings; + + List debugMessages; + + Object moduleContext; + + Tags analyticsTags; +} diff --git a/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/hooks/FiftyOneDeviceDetectionEntrypointHook.java b/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/hooks/FiftyOneDeviceDetectionEntrypointHook.java index 506cf66078e..9df4e2a0237 100644 --- a/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/hooks/FiftyOneDeviceDetectionEntrypointHook.java +++ b/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/hooks/FiftyOneDeviceDetectionEntrypointHook.java @@ -2,10 +2,10 @@ import org.prebid.server.hooks.modules.fiftyone.devicedetection.model.boundary.CollectedEvidence; import org.prebid.server.hooks.modules.fiftyone.devicedetection.v1.model.ModuleContext; +import org.prebid.server.hooks.modules.fiftyone.devicedetection.v1.model.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationAction; import org.prebid.server.hooks.v1.InvocationContext; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.entrypoint.EntrypointHook; import org.prebid.server.hooks.v1.entrypoint.EntrypointPayload; diff --git a/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/hooks/FiftyOneDeviceDetectionRawAuctionRequestHook.java b/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/hooks/FiftyOneDeviceDetectionRawAuctionRequestHook.java index 8b0d5cdc8d4..081177e8ca1 100644 --- a/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/hooks/FiftyOneDeviceDetectionRawAuctionRequestHook.java +++ b/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/hooks/FiftyOneDeviceDetectionRawAuctionRequestHook.java @@ -13,9 +13,9 @@ import org.prebid.server.hooks.modules.fiftyone.devicedetection.v1.core.EnrichmentResult; import org.prebid.server.hooks.modules.fiftyone.devicedetection.v1.core.SecureHeadersRetriever; import org.prebid.server.hooks.modules.fiftyone.devicedetection.v1.model.ModuleContext; +import org.prebid.server.hooks.modules.fiftyone.devicedetection.v1.model.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationAction; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.auction.AuctionInvocationContext; import org.prebid.server.hooks.v1.auction.AuctionRequestPayload; diff --git a/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/model/InvocationResultImpl.java b/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/model/InvocationResultImpl.java new file mode 100644 index 00000000000..ead75085974 --- /dev/null +++ b/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/model/InvocationResultImpl.java @@ -0,0 +1,24 @@ +package org.prebid.server.hooks.modules.fiftyone.devicedetection.v1.model; + +import lombok.Builder; +import org.prebid.server.hooks.v1.InvocationAction; +import org.prebid.server.hooks.v1.InvocationResult; +import org.prebid.server.hooks.v1.InvocationStatus; +import org.prebid.server.hooks.v1.PayloadUpdate; +import org.prebid.server.hooks.v1.analytics.Tags; + +import java.util.List; + +@Builder +public record InvocationResultImpl( + InvocationStatus status, + String message, + InvocationAction action, + PayloadUpdate payloadUpdate, + List errors, + List warnings, + List debugMessages, + Object moduleContext, + Tags analyticsTags +) implements InvocationResult { +} diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHook.java b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHook.java index bb5e05d4fb2..ff9e6ab6c3c 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHook.java +++ b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHook.java @@ -11,9 +11,9 @@ import org.prebid.server.hooks.modules.ortb2.blocking.core.model.ExecutionResult; import org.prebid.server.hooks.modules.ortb2.blocking.model.ModuleContext; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.BidderRequestPayloadImpl; +import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationAction; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.bidder.BidderInvocationContext; import org.prebid.server.hooks.v1.bidder.BidderRequestHook; diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHook.java b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHook.java index c90ac94840a..329e99d3bbc 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHook.java +++ b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHook.java @@ -13,13 +13,13 @@ import org.prebid.server.hooks.modules.ortb2.blocking.core.model.ExecutionResult; import org.prebid.server.hooks.modules.ortb2.blocking.model.ModuleContext; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.BidderResponsePayloadImpl; +import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.InvocationResultImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.analytics.ActivityImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.analytics.AppliedToImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.analytics.ResultImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.analytics.TagsImpl; import org.prebid.server.hooks.v1.InvocationAction; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.analytics.Result; import org.prebid.server.hooks.v1.analytics.Tags; diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/model/InvocationResultImpl.java b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/model/InvocationResultImpl.java new file mode 100644 index 00000000000..48be15fdf37 --- /dev/null +++ b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/model/InvocationResultImpl.java @@ -0,0 +1,37 @@ +package org.prebid.server.hooks.modules.ortb2.blocking.v1.model; + +import lombok.Builder; +import lombok.Value; +import lombok.experimental.Accessors; +import org.prebid.server.hooks.modules.ortb2.blocking.model.ModuleContext; +import org.prebid.server.hooks.v1.InvocationAction; +import org.prebid.server.hooks.v1.InvocationResult; +import org.prebid.server.hooks.v1.InvocationStatus; +import org.prebid.server.hooks.v1.PayloadUpdate; +import org.prebid.server.hooks.v1.analytics.Tags; + +import java.util.List; + +@Accessors(fluent = true) +@Builder +@Value +public class InvocationResultImpl implements InvocationResult { + + InvocationStatus status; + + String message; + + InvocationAction action; + + PayloadUpdate payloadUpdate; + + List errors; + + List warnings; + + List debugMessages; + + ModuleContext moduleContext; + + Tags analyticsTags; +} diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHookTest.java b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHookTest.java index 4c3852bc630..fe1ea6e9614 100644 --- a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHookTest.java +++ b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHookTest.java @@ -28,9 +28,9 @@ import org.prebid.server.hooks.modules.ortb2.blocking.model.ModuleContext; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.BidderInvocationContextImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.BidderRequestPayloadImpl; +import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationAction; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.PayloadUpdate; import org.prebid.server.hooks.v1.bidder.BidderRequestPayload; diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHookTest.java b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHookTest.java index 356bd7b2125..0e0a6811835 100644 --- a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHookTest.java +++ b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHookTest.java @@ -23,13 +23,13 @@ import org.prebid.server.hooks.modules.ortb2.blocking.model.ModuleContext; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.BidderInvocationContextImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.BidderResponsePayloadImpl; +import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.InvocationResultImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.analytics.ActivityImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.analytics.AppliedToImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.analytics.ResultImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.analytics.TagsImpl; import org.prebid.server.hooks.v1.InvocationAction; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.PayloadUpdate; import org.prebid.server.hooks.v1.bidder.BidderResponsePayload; diff --git a/extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/ResponseCorrectionAllProcessedBidResponsesHook.java b/extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/ResponseCorrectionAllProcessedBidResponsesHook.java index 4d7fb81c366..09e4640b064 100644 --- a/extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/ResponseCorrectionAllProcessedBidResponsesHook.java +++ b/extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/ResponseCorrectionAllProcessedBidResponsesHook.java @@ -11,9 +11,9 @@ import org.prebid.server.hooks.modules.pb.response.correction.core.ResponseCorrectionProvider; import org.prebid.server.hooks.modules.pb.response.correction.core.config.model.Config; import org.prebid.server.hooks.modules.pb.response.correction.core.correction.Correction; +import org.prebid.server.hooks.modules.pb.response.correction.v1.model.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationAction; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.auction.AuctionInvocationContext; import org.prebid.server.hooks.v1.bidder.AllProcessedBidResponsesHook; @@ -57,7 +57,7 @@ public Future> call(AllProcess return noAction(); } - final InvocationResult invocationResult = InvocationResultImpl.builder() + final InvocationResult invocationResult = InvocationResultImpl.builder() .status(InvocationStatus.success) .action(InvocationAction.update) .payloadUpdate(initialPayload -> AllProcessedBidResponsesPayloadImpl.of( @@ -84,7 +84,7 @@ private static List applyCorrections(List bidder } private Future> failure(String message) { - return Future.succeededFuture(InvocationResultImpl.builder() + return Future.succeededFuture(InvocationResultImpl.builder() .status(InvocationStatus.failure) .message(message) .action(InvocationAction.no_action) @@ -92,7 +92,7 @@ private Future> failure(String } private static Future> noAction() { - return Future.succeededFuture(InvocationResultImpl.builder() + return Future.succeededFuture(InvocationResultImpl.builder() .status(InvocationStatus.success) .action(InvocationAction.no_action) .build()); diff --git a/extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/model/InvocationResultImpl.java b/extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/model/InvocationResultImpl.java new file mode 100644 index 00000000000..1a39413583c --- /dev/null +++ b/extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/model/InvocationResultImpl.java @@ -0,0 +1,38 @@ +package org.prebid.server.hooks.modules.pb.response.correction.v1.model; + +import lombok.Builder; +import lombok.Value; +import lombok.experimental.Accessors; +import org.prebid.server.hooks.v1.InvocationAction; +import org.prebid.server.hooks.v1.InvocationResult; +import org.prebid.server.hooks.v1.InvocationStatus; +import org.prebid.server.hooks.v1.PayloadUpdate; +import org.prebid.server.hooks.v1.analytics.Tags; +import org.prebid.server.hooks.v1.auction.AuctionRequestPayload; +import org.prebid.server.hooks.v1.bidder.AllProcessedBidResponsesPayload; + +import java.util.List; + +@Accessors(fluent = true) +@Builder +@Value +public class InvocationResultImpl implements InvocationResult { + + InvocationStatus status; + + String message; + + InvocationAction action; + + PayloadUpdate payloadUpdate; + + List errors; + + List warnings; + + List debugMessages; + + Object moduleContext; + + Tags analyticsTags; +} diff --git a/extra/modules/pb-richmedia-filter/src/main/java/org/prebid/server/hooks/modules/pb/richmedia/filter/v1/PbRichmediaFilterAllProcessedBidResponsesHook.java b/extra/modules/pb-richmedia-filter/src/main/java/org/prebid/server/hooks/modules/pb/richmedia/filter/v1/PbRichmediaFilterAllProcessedBidResponsesHook.java index e0416c6d30d..ee92a5e2064 100644 --- a/extra/modules/pb-richmedia-filter/src/main/java/org/prebid/server/hooks/modules/pb/richmedia/filter/v1/PbRichmediaFilterAllProcessedBidResponsesHook.java +++ b/extra/modules/pb-richmedia-filter/src/main/java/org/prebid/server/hooks/modules/pb/richmedia/filter/v1/PbRichmediaFilterAllProcessedBidResponsesHook.java @@ -12,13 +12,13 @@ import org.prebid.server.hooks.modules.pb.richmedia.filter.model.AnalyticsResult; import org.prebid.server.hooks.modules.pb.richmedia.filter.model.MraidFilterResult; import org.prebid.server.hooks.modules.pb.richmedia.filter.model.PbRichMediaFilterProperties; +import org.prebid.server.hooks.modules.pb.richmedia.filter.v1.model.InvocationResultImpl; import org.prebid.server.hooks.modules.pb.richmedia.filter.v1.model.analytics.ActivityImpl; import org.prebid.server.hooks.modules.pb.richmedia.filter.v1.model.analytics.AppliedToImpl; import org.prebid.server.hooks.modules.pb.richmedia.filter.v1.model.analytics.ResultImpl; import org.prebid.server.hooks.modules.pb.richmedia.filter.v1.model.analytics.TagsImpl; import org.prebid.server.hooks.v1.InvocationAction; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.analytics.Result; import org.prebid.server.hooks.v1.analytics.Tags; diff --git a/src/main/java/org/prebid/server/hooks/v1/InvocationResultImpl.java b/extra/modules/pb-richmedia-filter/src/main/java/org/prebid/server/hooks/modules/pb/richmedia/filter/v1/model/InvocationResultImpl.java similarity index 66% rename from src/main/java/org/prebid/server/hooks/v1/InvocationResultImpl.java rename to extra/modules/pb-richmedia-filter/src/main/java/org/prebid/server/hooks/modules/pb/richmedia/filter/v1/model/InvocationResultImpl.java index abfe5cf8fb2..b77fc98a68b 100644 --- a/src/main/java/org/prebid/server/hooks/v1/InvocationResultImpl.java +++ b/extra/modules/pb-richmedia-filter/src/main/java/org/prebid/server/hooks/modules/pb/richmedia/filter/v1/model/InvocationResultImpl.java @@ -1,8 +1,12 @@ -package org.prebid.server.hooks.v1; +package org.prebid.server.hooks.modules.pb.richmedia.filter.v1.model; import lombok.Builder; import lombok.Value; import lombok.experimental.Accessors; +import org.prebid.server.hooks.v1.InvocationAction; +import org.prebid.server.hooks.v1.InvocationResult; +import org.prebid.server.hooks.v1.InvocationStatus; +import org.prebid.server.hooks.v1.PayloadUpdate; import org.prebid.server.hooks.v1.analytics.Tags; import java.util.List; diff --git a/src/main/java/org/prebid/server/auction/ExchangeService.java b/src/main/java/org/prebid/server/auction/ExchangeService.java index 6fff31c6459..2864ef8c937 100644 --- a/src/main/java/org/prebid/server/auction/ExchangeService.java +++ b/src/main/java/org/prebid/server/auction/ExchangeService.java @@ -1395,7 +1395,6 @@ private AuctionContext updateHooksMetrics(AuctionContext context) { .flatMap(Collection::stream) .map(GroupExecutionOutcome::getHooks) .flatMap(Collection::stream) - .filter(hookOutcome -> hookOutcome.getAction() != ExecutionAction.no_invocation) .collect(Collectors.groupingBy( outcome -> outcome.getHookId().getModuleCode(), Collectors.summingLong(HookExecutionOutcome::getExecutionTime))) diff --git a/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java b/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java index 51f6b38be3e..6ec0cc63095 100644 --- a/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java +++ b/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java @@ -1,26 +1,19 @@ package org.prebid.server.hooks.execution; -import com.fasterxml.jackson.databind.node.ObjectNode; import io.vertx.core.AsyncResult; import io.vertx.core.Future; import io.vertx.core.Promise; import io.vertx.core.Vertx; -import org.apache.commons.lang3.BooleanUtils; import org.prebid.server.hooks.execution.model.ExecutionGroup; import org.prebid.server.hooks.execution.model.HookExecutionContext; import org.prebid.server.hooks.execution.model.HookId; import org.prebid.server.hooks.v1.Hook; -import org.prebid.server.hooks.v1.InvocationAction; import org.prebid.server.hooks.v1.InvocationContext; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; -import org.prebid.server.hooks.v1.InvocationStatus; -import org.prebid.server.hooks.v1.auction.AuctionInvocationContext; import org.prebid.server.log.ConditionalLogger; import org.prebid.server.log.LoggerFactory; import java.time.Clock; -import java.util.Collections; import java.util.Map; import java.util.concurrent.TimeoutException; import java.util.function.Function; @@ -31,11 +24,8 @@ class GroupExecutor { private static final ConditionalLogger conditionalLogger = new ConditionalLogger(LoggerFactory.getLogger(GroupExecutor.class)); - private static final String MODULE_ALWAYS_EXECUTE_MESSAGE = "Can not skip the module execution execution"; - private final Vertx vertx; private final Clock clock; - private final boolean isConfigToInvokeRequired; private final Map modulesExecution; private ExecutionGroup group; @@ -45,24 +35,19 @@ class GroupExecutor { private HookExecutionContext hookExecutionContext; private boolean rejectAllowed; - private GroupExecutor(Vertx vertx, - Clock clock, - boolean isConfigToInvokeRequired, - Map modulesExecution) { + private GroupExecutor(Vertx vertx, Clock clock, Map modulesExecution) { this.vertx = vertx; this.clock = clock; - this.isConfigToInvokeRequired = isConfigToInvokeRequired; this.modulesExecution = modulesExecution; } public static GroupExecutor create( Vertx vertx, Clock clock, - boolean isConfigToInvokeRequired, Map modulesExecution) { - return new GroupExecutor<>(vertx, clock, isConfigToInvokeRequired, modulesExecution); + return new GroupExecutor<>(vertx, clock, modulesExecution); } public GroupExecutor withGroup(ExecutionGroup group) { @@ -102,6 +87,10 @@ public Future> execute() { Future> groupFuture = Future.succeededFuture(initialGroupResult); for (final HookId hookId : group.getHookSequence()) { + if (!modulesExecution.getOrDefault(hookId.getModuleCode(), true)) { + continue; + } + final Hook hook = hookProvider.apply(hookId); final long startTime = clock.millis(); @@ -128,43 +117,7 @@ private Future> executeHook( } final CONTEXT invocationContext = invocationContextProvider.apply(timeout, hookId, moduleContextFor(hookId)); - - return skipExecution(invocationContext, hookId).recover(ignored -> - executeWithTimeout(() -> hook.call(groupResult.payload(), invocationContext), timeout)); - } - - private Future> skipExecution(CONTEXT invocationContext, HookId hookId) { - if (modulesExecution == null || !(invocationContext instanceof AuctionInvocationContext)) { - return Future.failedFuture(MODULE_ALWAYS_EXECUTE_MESSAGE); - } - - final String moduleCode = hookId.getModuleCode(); - final Boolean toBeExecuted = modulesExecution.get(moduleCode); - - if (BooleanUtils.isTrue(toBeExecuted)) { - return Future.failedFuture(MODULE_ALWAYS_EXECUTE_MESSAGE); - } - - if (BooleanUtils.isFalse(toBeExecuted)) { - return Future.succeededFuture(InvocationResultImpl.builder() - .status(InvocationStatus.success) - .action(InvocationAction.no_invocation) - .debugMessages(Collections.singletonList( - "The module %s is disabled by the account".formatted(moduleCode))) - .build()); - } - - final ObjectNode accountConfig = ((AuctionInvocationContext) invocationContext).accountConfig(); - if (isConfigToInvokeRequired && (accountConfig == null || accountConfig.isNull())) { - return Future.succeededFuture(InvocationResultImpl.builder() - .status(InvocationStatus.success) - .action(InvocationAction.no_invocation) - .debugMessages(Collections.singletonList( - "The account config for the module %s is required but absent".formatted(moduleCode))) - .build()); - } - - return Future.failedFuture(MODULE_ALWAYS_EXECUTE_MESSAGE); + return executeWithTimeout(() -> hook.call(groupResult.payload(), invocationContext), timeout); } private Future executeWithTimeout(Supplier> action, Long timeout) { diff --git a/src/main/java/org/prebid/server/hooks/execution/GroupResult.java b/src/main/java/org/prebid/server/hooks/execution/GroupResult.java index 8bc7c5c0723..a4487e3a60b 100644 --- a/src/main/java/org/prebid/server/hooks/execution/GroupResult.java +++ b/src/main/java/org/prebid/server/hooks/execution/GroupResult.java @@ -173,7 +173,6 @@ private static ExecutionAction toExecutionAction(InvocationAction action) { case reject -> ExecutionAction.reject; case update -> ExecutionAction.update; case no_action -> ExecutionAction.no_action; - case no_invocation -> ExecutionAction.no_invocation; }; } diff --git a/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java b/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java index e59c1df268e..5793cf920a4 100644 --- a/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java +++ b/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java @@ -5,6 +5,7 @@ import com.iab.openrtb.response.BidResponse; import io.vertx.core.Future; import io.vertx.core.Vertx; +import org.apache.commons.collections4.map.DefaultedMap; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.prebid.server.auction.model.AuctionContext; @@ -52,6 +53,7 @@ import java.time.Clock; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -125,6 +127,7 @@ public Future> executeEntrypointStag .withExecutionPlan(planForEntrypointStage(endpoint)) .withInitialPayload(EntrypointPayloadImpl.of(queryParams, headers, body)) .withInvocationContextProvider(invocationContextProvider(endpoint)) + .withModulesExecution(Collections.emptyMap()) .withRejectAllowed(true) .execute(); } @@ -261,7 +264,7 @@ private StageExecutorcreate(hookCatalog, vertx, clock, isConfigToInvokeRequired) + return StageExecutor.create(hookCatalog, vertx, clock) .withStage(stage) .withEntity(entity) .withHookExecutionContext(context); @@ -280,10 +283,25 @@ private StageExecutor modulesExecutionForAccount(Account account) { - return Optional.ofNullable(account.getHooks()) + final Map accountModulesExecution = Optional.ofNullable(account.getHooks()) .map(AccountHooksConfiguration::getAdmin) .map(AccountHooksAdminConfig::getModuleExecution) .orElseGet(Collections::emptyMap); + + if (!isConfigToInvokeRequired) { + return DefaultedMap.defaultedMap(accountModulesExecution, true); + } + + final Map resultModulesExecution = new HashMap<>(accountModulesExecution); + + Optional.ofNullable(account.getHooks()) + .map(AccountHooksConfiguration::getModules) + .map(Map::keySet) + .stream() + .flatMap(Collection::stream) + .forEach(module -> resultModulesExecution.computeIfAbsent(module, key -> true)); + + return DefaultedMap.defaultedMap(resultModulesExecution, false); } private static ExecutionPlan parseAndValidateExecutionPlan( diff --git a/src/main/java/org/prebid/server/hooks/execution/StageExecutor.java b/src/main/java/org/prebid/server/hooks/execution/StageExecutor.java index a4cfa53ff69..caa1ffc4caa 100644 --- a/src/main/java/org/prebid/server/hooks/execution/StageExecutor.java +++ b/src/main/java/org/prebid/server/hooks/execution/StageExecutor.java @@ -19,7 +19,6 @@ class StageExecutor { private final HookCatalog hookCatalog; private final Vertx vertx; private final Clock clock; - private final boolean isConfigToInvokeRequired; private StageWithHookType> stage; private String entity; @@ -30,20 +29,18 @@ class StageExecutor { private boolean rejectAllowed; private Map modulesExecution; - private StageExecutor(HookCatalog hookCatalog, Vertx vertx, Clock clock, boolean isConfigToInvokeRequired) { + private StageExecutor(HookCatalog hookCatalog, Vertx vertx, Clock clock) { this.hookCatalog = hookCatalog; this.vertx = vertx; this.clock = clock; - this.isConfigToInvokeRequired = isConfigToInvokeRequired; } public static StageExecutor create( HookCatalog hookCatalog, Vertx vertx, - Clock clock, - boolean isConfigToInvokeRequired) { + Clock clock) { - return new StageExecutor<>(hookCatalog, vertx, clock, isConfigToInvokeRequired); + return new StageExecutor<>(hookCatalog, vertx, clock); } public StageExecutor withStage(StageWithHookType> stage) { @@ -104,7 +101,7 @@ public Future> execute() { } private Future> executeGroup(ExecutionGroup group, PAYLOAD initialPayload) { - return GroupExecutor.create(vertx, clock, isConfigToInvokeRequired, modulesExecution) + return GroupExecutor.create(vertx, clock, modulesExecution) .withGroup(group) .withInitialPayload(initialPayload) .withHookProvider( diff --git a/src/main/java/org/prebid/server/hooks/execution/model/ExecutionAction.java b/src/main/java/org/prebid/server/hooks/execution/model/ExecutionAction.java index 886cec114e8..5e13aa3f14c 100644 --- a/src/main/java/org/prebid/server/hooks/execution/model/ExecutionAction.java +++ b/src/main/java/org/prebid/server/hooks/execution/model/ExecutionAction.java @@ -2,5 +2,5 @@ public enum ExecutionAction { - no_action, update, reject, no_invocation + no_action, update, reject } diff --git a/src/main/java/org/prebid/server/hooks/v1/InvocationAction.java b/src/main/java/org/prebid/server/hooks/v1/InvocationAction.java index 821b21a730b..29b22bf1b3d 100644 --- a/src/main/java/org/prebid/server/hooks/v1/InvocationAction.java +++ b/src/main/java/org/prebid/server/hooks/v1/InvocationAction.java @@ -2,5 +2,5 @@ public enum InvocationAction { - no_action, update, reject, no_invocation + no_action, update, reject } diff --git a/src/main/java/org/prebid/server/metric/MetricName.java b/src/main/java/org/prebid/server/metric/MetricName.java index 9ea3d15f0fc..6d624fd857f 100644 --- a/src/main/java/org/prebid/server/metric/MetricName.java +++ b/src/main/java/org/prebid/server/metric/MetricName.java @@ -139,7 +139,6 @@ public enum MetricName { call, success, noop, - no_invocation("no-invocation"), reject, unknown, failure, diff --git a/src/main/java/org/prebid/server/metric/Metrics.java b/src/main/java/org/prebid/server/metric/Metrics.java index 52964a9f8b0..64edbfc85cc 100644 --- a/src/main/java/org/prebid/server/metric/Metrics.java +++ b/src/main/java/org/prebid/server/metric/Metrics.java @@ -628,20 +628,13 @@ public void updateHooksMetrics( final HookImplMetrics hookImplMetrics = hooks().module(moduleCode).stage(stage).hookImpl(hookImplCode); - if (action != ExecutionAction.no_invocation) { - hookImplMetrics.incCounter(MetricName.call); - } - + hookImplMetrics.incCounter(MetricName.call); if (status == ExecutionStatus.success) { hookImplMetrics.success().incCounter(HookMetricMapper.fromAction(action)); } else { hookImplMetrics.incCounter(HookMetricMapper.fromStatus(status)); } - - if (action != ExecutionAction.no_invocation) { - hookImplMetrics.updateTimer(MetricName.duration, executionTime); - } - + hookImplMetrics.updateTimer(MetricName.duration, executionTime); } public void updateAccountHooksMetrics( @@ -653,10 +646,7 @@ public void updateAccountHooksMetrics( if (accountMetricsVerbosityResolver.forAccount(account).isAtLeast(AccountMetricsVerbosityLevel.detailed)) { final ModuleMetrics accountModuleMetrics = forAccount(account.getId()).hooks().module(moduleCode); - if (action != ExecutionAction.no_invocation) { - accountModuleMetrics.incCounter(MetricName.call); - } - + accountModuleMetrics.incCounter(MetricName.call); if (status == ExecutionStatus.success) { accountModuleMetrics.success().incCounter(HookMetricMapper.fromAction(action)); } else { @@ -687,7 +677,6 @@ private static class HookMetricMapper { ACTION_TO_METRIC.put(ExecutionAction.no_action, MetricName.noop); ACTION_TO_METRIC.put(ExecutionAction.update, MetricName.update); ACTION_TO_METRIC.put(ExecutionAction.reject, MetricName.reject); - ACTION_TO_METRIC.put(ExecutionAction.no_invocation, MetricName.no_invocation); } static MetricName fromStatus(ExecutionStatus status) { diff --git a/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java b/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java index 05939f7c278..c0dea093017 100644 --- a/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java +++ b/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java @@ -53,7 +53,6 @@ import org.prebid.server.hooks.v1.InvocationContext; import org.prebid.server.hooks.v1.InvocationResult; import org.prebid.server.hooks.v1.InvocationResultImpl; -import org.prebid.server.hooks.v1.InvocationResultUtils; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.analytics.ActivityImpl; import org.prebid.server.hooks.v1.analytics.AppliedToImpl; @@ -154,7 +153,7 @@ public void creationShouldFailWhenHostExecutionPlanHasUnknownHook() { given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.ENTRYPOINT))) .willReturn(null); - givenEntrypointHook("module-beta", "hook-a", immediateHook(InvocationResultUtils.noAction())); + givenEntrypointHook("module-beta", "hook-a", immediateHook(InvocationResultImpl.noAction())); assertThatThrownBy(() -> createExecutor(hostPlan)) .isInstanceOf(IllegalArgumentException.class) @@ -177,7 +176,7 @@ public void creationShouldFailWhenDefaultAccountExecutionPlanHasUnknownHook() { given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.ENTRYPOINT))) .willReturn(null); - givenEntrypointHook("module-beta", "hook-a", immediateHook(InvocationResultUtils.noAction())); + givenEntrypointHook("module-beta", "hook-a", immediateHook(InvocationResultImpl.noAction())); assertThatThrownBy(() -> createExecutor(null, defaultAccountPlan)) .isInstanceOf(IllegalArgumentException.class) @@ -235,7 +234,7 @@ public void shouldExecuteEntrypointHooksHappyPath(VertxTestContext context) { givenEntrypointHook( "module-alpha", "hook-a", - immediateHook(InvocationResultUtils.succeeded( + immediateHook(InvocationResultImpl.succeeded( payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-abc"), "moduleAlphaContext"))); @@ -243,19 +242,19 @@ public void shouldExecuteEntrypointHooksHappyPath(VertxTestContext context) { givenEntrypointHook( "module-alpha", "hook-b", - delayedHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( + delayedHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-def")), 40)); givenEntrypointHook( "module-beta", "hook-a", - delayedHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( + delayedHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-ghi")), 80)); givenEntrypointHook( "module-beta", "hook-b", - immediateHook(InvocationResultUtils.succeeded( + immediateHook(InvocationResultImpl.succeeded( payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-jkl"), "moduleBetaContext"))); @@ -429,7 +428,7 @@ public void shouldExecuteEntrypointHooksToleratingMisbehavingHooks(VertxTestCont givenEntrypointHook( "module-beta", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-jkl")))); final HookStageExecutor executor = createExecutor( @@ -525,7 +524,7 @@ public void shouldExecuteEntrypointHooksToleratingTimeoutAndFailedFuture(VertxTe "module-alpha", "hook-b", delayedHook( - InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( + InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-def")), 250)); @@ -534,14 +533,14 @@ public void shouldExecuteEntrypointHooksToleratingTimeoutAndFailedFuture(VertxTe "module-beta", "hook-a", delayedHook( - InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( + InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-ghi")), 250)); givenEntrypointHook( "module-beta", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-jkl")))); final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); @@ -624,23 +623,23 @@ public void shouldExecuteEntrypointHooksHonoringStatusAndAction(VertxTestContext givenEntrypointHook( "module-alpha", "hook-a", - immediateHook(InvocationResultUtils.failed("Failed to contact service ACME"))); + immediateHook(InvocationResultImpl.failed("Failed to contact service ACME"))); givenEntrypointHook( "module-alpha", "hook-b", - immediateHook(InvocationResultUtils.noAction())); + immediateHook(InvocationResultImpl.noAction())); givenEntrypointHook( "module-beta", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-ghi")))); givenEntrypointHook( "module-beta", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-jkl")))); final HookStageExecutor executor = createExecutor( @@ -716,13 +715,13 @@ public void shouldExecuteEntrypointHooksWhenRequestIsRejectedByFirstGroup(VertxT givenEntrypointHook( "module-alpha", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-abc")))); givenEntrypointHook( "module-beta", "hook-a", - immediateHook(InvocationResultUtils.rejected("Request is of low quality"))); + immediateHook(InvocationResultImpl.rejected("Request is of low quality"))); final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( @@ -788,24 +787,24 @@ public void shouldExecuteEntrypointHooksWhenRequestIsRejectedBySecondGroup(Vertx givenEntrypointHook( "module-alpha", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-abc")))); givenEntrypointHook( "module-alpha", "hook-b", - immediateHook(InvocationResultUtils.rejected("Request is of low quality"))); + immediateHook(InvocationResultImpl.rejected("Request is of low quality"))); givenEntrypointHook( "module-beta", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-def")))); givenEntrypointHook( "module-beta", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-jkl")))); final HookStageExecutor executor = createExecutor( @@ -904,7 +903,7 @@ public void shouldExecuteEntrypointHooksToleratingMisbehavingInvocationResult(Ve givenEntrypointHook( "module-beta", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> { + immediateHook(InvocationResultImpl.succeeded(payload -> { throw new RuntimeException("Can not alter payload"); }))); @@ -1046,7 +1045,7 @@ public void shouldExecuteEntrypointHooksAndStoreResultInExecutionContext(VertxTe public void shouldExecuteEntrypointHooksAndPassInvocationContext(VertxTestContext context) { // given final EntrypointHookImpl hookImpl = spy( - EntrypointHookImpl.of(immediateHook(InvocationResultUtils.succeeded(identity())))); + EntrypointHookImpl.of(immediateHook(InvocationResultImpl.succeeded(identity())))); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.ENTRYPOINT))) .willReturn(hookImpl); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-b"), eq(StageWithHookType.ENTRYPOINT))) @@ -1109,7 +1108,7 @@ public void shouldExecuteEntrypointHooksAndPassInvocationContext(VertxTestContex public void shouldExecuteRawAuctionRequestHooksWhenNoExecutionPlanInAccount(VertxTestContext context) { // given final RawAuctionRequestHookImpl hookImpl = spy( - RawAuctionRequestHookImpl.of(immediateHook(InvocationResultUtils.noAction()))); + RawAuctionRequestHookImpl.of(immediateHook(InvocationResultImpl.noAction()))); given(hookCatalog.hookById(anyString(), anyString(), eq(StageWithHookType.RAW_AUCTION_REQUEST))) .willReturn(hookImpl); @@ -1154,7 +1153,7 @@ public void shouldExecuteRawAuctionRequestHooksWhenNoExecutionPlanInAccount(Vert public void shouldExecuteRawAuctionRequestHooksWhenAccountOverridesExecutionPlan(VertxTestContext context) { // given final RawAuctionRequestHookImpl hookImpl = spy( - RawAuctionRequestHookImpl.of(immediateHook(InvocationResultUtils.noAction()))); + RawAuctionRequestHookImpl.of(immediateHook(InvocationResultImpl.noAction()))); given(hookCatalog.hookById(anyString(), anyString(), eq(StageWithHookType.RAW_AUCTION_REQUEST))) .willReturn(hookImpl); @@ -1217,7 +1216,7 @@ public void shouldExecuteRawAuctionRequestHooksToleratingUnknownHookInAccountPla givenRawAuctionRequestHook( "module-beta", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().id("id").build())))); final HookStageExecutor executor = createExecutor(null, null); @@ -1295,25 +1294,25 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsNotRequired givenRawAuctionRequestHook( "module-alpha", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().at(1).build())))); givenRawAuctionRequestHook( "module-beta", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().test(1).build())))); givenRawAuctionRequestHook( "module-gamma", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().id("id").build())))); givenRawAuctionRequestHook( "module-delta", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().tmax(1000L).build())))); final StageExecutionPlan stageExecutionPlan = StageExecutionPlan.of(asList( @@ -1392,25 +1391,25 @@ public void shouldExecuteRawAuctionRequestHooksWhenAccountConfigIsRequired(Vertx givenRawAuctionRequestHook( "module-alpha", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().at(1).build())))); givenRawAuctionRequestHook( "module-beta", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().test(1).build())))); givenRawAuctionRequestHook( "module-gamma", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().id("id").build())))); givenRawAuctionRequestHook( "module-delta", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().tmax(1000L).build())))); final StageExecutionPlan stageExecutionPlan = StageExecutionPlan.of(asList( @@ -1488,25 +1487,25 @@ public void shouldExecuteRawAuctionRequestHooksHappyPath(VertxTestContext contex givenRawAuctionRequestHook( "module-alpha", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().at(1).build())))); givenRawAuctionRequestHook( "module-alpha", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().id("id").build())))); givenRawAuctionRequestHook( "module-beta", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().test(1).build())))); givenRawAuctionRequestHook( "module-beta", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().tmax(1000L).build())))); final HookStageExecutor executor = createExecutor( @@ -1554,7 +1553,7 @@ public void shouldExecuteRawAuctionRequestHooksHappyPath(VertxTestContext contex public void shouldExecuteRawAuctionRequestHooksAndPassAuctionInvocationContext(VertxTestContext context) { // given final RawAuctionRequestHookImpl hookImpl = spy( - RawAuctionRequestHookImpl.of(immediateHook(InvocationResultUtils.succeeded(identity())))); + RawAuctionRequestHookImpl.of(immediateHook(InvocationResultImpl.succeeded(identity())))); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.RAW_AUCTION_REQUEST))) .willReturn(hookImpl); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-b"), eq(StageWithHookType.RAW_AUCTION_REQUEST))) @@ -1727,7 +1726,7 @@ public void shouldExecuteRawAuctionRequestHooksWhenRequestIsRejected(VertxTestCo givenRawAuctionRequestHook( "module-alpha", "hook-a", - immediateHook(InvocationResultUtils.rejected("Request is no good"))); + immediateHook(InvocationResultImpl.rejected("Request is no good"))); final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( @@ -1760,25 +1759,25 @@ public void shouldExecuteProcessedAuctionRequestHooksHappyPath(VertxTestContext givenProcessedAuctionRequestHook( "module-alpha", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().at(1).build())))); givenProcessedAuctionRequestHook( "module-alpha", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().id("id").build())))); givenProcessedAuctionRequestHook( "module-beta", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().test(1).build())))); givenProcessedAuctionRequestHook( "module-beta", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().tmax(1000L).build())))); final HookStageExecutor executor = createExecutor( @@ -1827,7 +1826,7 @@ public void shouldExecuteProcessedAuctionRequestHooksHappyPath(VertxTestContext public void shouldExecuteProcessedAuctionRequestHooksAndPassAuctionInvocationContext(VertxTestContext context) { // given final ProcessedAuctionRequestHookImpl hookImpl = spy( - ProcessedAuctionRequestHookImpl.of(immediateHook(InvocationResultUtils.succeeded(identity())))); + ProcessedAuctionRequestHookImpl.of(immediateHook(InvocationResultImpl.succeeded(identity())))); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.PROCESSED_AUCTION_REQUEST))) .willReturn(hookImpl); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-b"), eq(StageWithHookType.PROCESSED_AUCTION_REQUEST))) @@ -2002,7 +2001,7 @@ public void shouldExecuteProcessedAuctionRequestHooksWhenRequestIsRejected(Vertx givenProcessedAuctionRequestHook( "module-alpha", "hook-a", - immediateHook(InvocationResultUtils.rejected("Request is no good"))); + immediateHook(InvocationResultImpl.rejected("Request is no good"))); final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( @@ -2038,25 +2037,25 @@ public void shouldExecuteBidderRequestHooksHappyPath(VertxTestContext context) { givenBidderRequestHook( "module-alpha", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> BidderRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> BidderRequestPayloadImpl.of( payload.bidRequest().toBuilder().at(1).build())))); givenBidderRequestHook( "module-alpha", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> BidderRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> BidderRequestPayloadImpl.of( payload.bidRequest().toBuilder().id("id").build())))); givenBidderRequestHook( "module-beta", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> BidderRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> BidderRequestPayloadImpl.of( payload.bidRequest().toBuilder().test(1).build())))); givenBidderRequestHook( "module-beta", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> BidderRequestPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> BidderRequestPayloadImpl.of( payload.bidRequest().toBuilder().tmax(1000L).build())))); final HookStageExecutor executor = createExecutor( @@ -2123,7 +2122,7 @@ public void shouldExecuteBidderRequestHooksHappyPath(VertxTestContext context) { public void shouldExecuteBidderRequestHooksAndPassBidderInvocationContext(VertxTestContext context) { // given final BidderRequestHookImpl hookImpl = spy( - BidderRequestHookImpl.of(immediateHook(InvocationResultUtils.succeeded(identity())))); + BidderRequestHookImpl.of(immediateHook(InvocationResultImpl.succeeded(identity())))); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.BIDDER_REQUEST))) .willReturn(hookImpl); @@ -2174,7 +2173,7 @@ public void shouldExecuteRawBidderResponseHooksHappyPath(VertxTestContext contex givenRawBidderResponseHook( "module-alpha", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> BidderResponsePayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> BidderResponsePayloadImpl.of( payload.bids().stream() .map(bid -> BidderBid.of( bid.getBid().toBuilder().id("bidId").build(), @@ -2185,7 +2184,7 @@ public void shouldExecuteRawBidderResponseHooksHappyPath(VertxTestContext contex givenRawBidderResponseHook( "module-alpha", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> BidderResponsePayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> BidderResponsePayloadImpl.of( payload.bids().stream() .map(bid -> BidderBid.of( bid.getBid().toBuilder().adid("adId").build(), @@ -2196,7 +2195,7 @@ public void shouldExecuteRawBidderResponseHooksHappyPath(VertxTestContext contex givenRawBidderResponseHook( "module-beta", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> BidderResponsePayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> BidderResponsePayloadImpl.of( payload.bids().stream() .map(bid -> BidderBid.of( bid.getBid().toBuilder().cid("cid").build(), @@ -2207,7 +2206,7 @@ public void shouldExecuteRawBidderResponseHooksHappyPath(VertxTestContext contex givenRawBidderResponseHook( "module-beta", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> BidderResponsePayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> BidderResponsePayloadImpl.of( payload.bids().stream() .map(bid -> BidderBid.of( bid.getBid().toBuilder().adm("adm").build(), @@ -2278,7 +2277,7 @@ public void shouldExecuteRawBidderResponseHooksHappyPath(VertxTestContext contex public void shouldExecuteRawBidderResponseHooksAndPassBidderInvocationContext(VertxTestContext context) { // given final RawBidderResponseHookImpl hookImpl = spy( - RawBidderResponseHookImpl.of(immediateHook(InvocationResultUtils.succeeded(identity())))); + RawBidderResponseHookImpl.of(immediateHook(InvocationResultImpl.succeeded(identity())))); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.RAW_BIDDER_RESPONSE))) .willReturn(hookImpl); @@ -2329,7 +2328,7 @@ public void shouldExecuteProcessedBidderResponseHooksHappyPath(VertxTestContext givenProcessedBidderResponseHook( "module-alpha", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> BidderResponsePayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> BidderResponsePayloadImpl.of( payload.bids().stream() .map(bid -> BidderBid.of( bid.getBid().toBuilder().id("bidId").build(), @@ -2340,7 +2339,7 @@ public void shouldExecuteProcessedBidderResponseHooksHappyPath(VertxTestContext givenProcessedBidderResponseHook( "module-alpha", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> BidderResponsePayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> BidderResponsePayloadImpl.of( payload.bids().stream() .map(bid -> BidderBid.of( bid.getBid().toBuilder().adid("adId").build(), @@ -2351,7 +2350,7 @@ public void shouldExecuteProcessedBidderResponseHooksHappyPath(VertxTestContext givenProcessedBidderResponseHook( "module-beta", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> BidderResponsePayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> BidderResponsePayloadImpl.of( payload.bids().stream() .map(bid -> BidderBid.of( bid.getBid().toBuilder().cid("cid").build(), @@ -2362,7 +2361,7 @@ public void shouldExecuteProcessedBidderResponseHooksHappyPath(VertxTestContext givenProcessedBidderResponseHook( "module-beta", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> BidderResponsePayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> BidderResponsePayloadImpl.of( payload.bids().stream() .map(bid -> BidderBid.of( bid.getBid().toBuilder().adm("adm").build(), @@ -2436,7 +2435,7 @@ public void shouldExecuteProcessedBidderResponseHooksHappyPath(VertxTestContext public void shouldExecuteProcessedBidderResponseHooksAndPassBidderInvocationContext(VertxTestContext context) { // given final ProcessedBidderResponseHookImpl hookImpl = spy( - ProcessedBidderResponseHookImpl.of(immediateHook(InvocationResultUtils.succeeded(identity())))); + ProcessedBidderResponseHookImpl.of(immediateHook(InvocationResultImpl.succeeded(identity())))); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.PROCESSED_BIDDER_RESPONSE))) .willReturn(hookImpl); @@ -2500,7 +2499,7 @@ public void shouldExecuteAllProcessedBidResponsesHooksHappyPath() { givenAllProcessedBidderResponsesHook( "module-alpha", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> AllProcessedBidResponsesPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AllProcessedBidResponsesPayloadImpl.of( payload.bidResponses().stream() .map(bidModifierForResponse.apply( (bidder, bid) -> BidderBid.of( @@ -2512,7 +2511,7 @@ public void shouldExecuteAllProcessedBidResponsesHooksHappyPath() { givenAllProcessedBidderResponsesHook( "module-alpha", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> AllProcessedBidResponsesPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AllProcessedBidResponsesPayloadImpl.of( payload.bidResponses().stream() .map(bidModifierForResponse.apply( (bidder, bid) -> BidderBid.of( @@ -2524,7 +2523,7 @@ public void shouldExecuteAllProcessedBidResponsesHooksHappyPath() { givenAllProcessedBidderResponsesHook( "module-beta", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> AllProcessedBidResponsesPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AllProcessedBidResponsesPayloadImpl.of( payload.bidResponses().stream() .map(bidModifierForResponse.apply( (bidder, bid) -> BidderBid.of( @@ -2536,7 +2535,7 @@ public void shouldExecuteAllProcessedBidResponsesHooksHappyPath() { givenAllProcessedBidderResponsesHook( "module-beta", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> AllProcessedBidResponsesPayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AllProcessedBidResponsesPayloadImpl.of( payload.bidResponses().stream() .map(bidModifierForResponse.apply( (bidder, bid) -> BidderBid.of( @@ -2601,7 +2600,7 @@ public void shouldExecuteAllProcessedBidResponsesHooksHappyPath() { public void shouldExecuteAllProcessedBidResponsesHooksAndPassAuctionInvocationContext(VertxTestContext context) { // given final AllProcessedBidResponsesHookImpl hookImpl = spy( - AllProcessedBidResponsesHookImpl.of(immediateHook(InvocationResultUtils.succeeded(identity())))); + AllProcessedBidResponsesHookImpl.of(immediateHook(InvocationResultImpl.succeeded(identity())))); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.ALL_PROCESSED_BID_RESPONSES))) .willReturn(hookImpl); @@ -2654,7 +2653,7 @@ public void shouldExecuteBidderRequestHooksWhenRequestIsRejected(VertxTestContex givenBidderRequestHook( "module-alpha", "hook-a", - immediateHook(InvocationResultUtils.rejected("Request is no good"))); + immediateHook(InvocationResultImpl.rejected("Request is no good"))); final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( @@ -2690,25 +2689,25 @@ public void shouldExecuteAuctionResponseHooksHappyPath(VertxTestContext context) givenAuctionResponseHook( "module-alpha", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionResponsePayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionResponsePayloadImpl.of( payload.bidResponse().toBuilder().id("id").build())))); givenAuctionResponseHook( "module-alpha", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionResponsePayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionResponsePayloadImpl.of( payload.bidResponse().toBuilder().bidid("bidid").build())))); givenAuctionResponseHook( "module-beta", "hook-a", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionResponsePayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionResponsePayloadImpl.of( payload.bidResponse().toBuilder().cur("cur").build())))); givenAuctionResponseHook( "module-beta", "hook-b", - immediateHook(InvocationResultUtils.succeeded(payload -> AuctionResponsePayloadImpl.of( + immediateHook(InvocationResultImpl.succeeded(payload -> AuctionResponsePayloadImpl.of( payload.bidResponse().toBuilder().nbr(1).build())))); final HookStageExecutor executor = createExecutor( @@ -2749,7 +2748,7 @@ public void shouldExecuteAuctionResponseHooksHappyPath(VertxTestContext context) public void shouldExecuteAuctionResponseHooksAndPassAuctionInvocationContext(VertxTestContext context) { // given final AuctionResponseHookImpl hookImpl = spy( - AuctionResponseHookImpl.of(immediateHook(InvocationResultUtils.succeeded(identity())))); + AuctionResponseHookImpl.of(immediateHook(InvocationResultImpl.succeeded(identity())))); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.AUCTION_RESPONSE))) .willReturn(hookImpl); @@ -2796,7 +2795,7 @@ public void shouldExecuteAuctionResponseHooksAndIgnoreRejection(VertxTestContext givenAuctionResponseHook( "module-alpha", "hook-a", - immediateHook(InvocationResultUtils.rejected("Will not apply"))); + immediateHook(InvocationResultImpl.rejected("Will not apply"))); final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( diff --git a/src/test/java/org/prebid/server/hooks/v1/InvocationResultUtils.java b/src/test/java/org/prebid/server/hooks/v1/InvocationResultImpl.java similarity index 75% rename from src/test/java/org/prebid/server/hooks/v1/InvocationResultUtils.java rename to src/test/java/org/prebid/server/hooks/v1/InvocationResultImpl.java index ce3e9ca74cb..31426173e9c 100644 --- a/src/test/java/org/prebid/server/hooks/v1/InvocationResultUtils.java +++ b/src/test/java/org/prebid/server/hooks/v1/InvocationResultImpl.java @@ -1,10 +1,34 @@ package org.prebid.server.hooks.v1; -public class InvocationResultUtils { +import lombok.Builder; +import lombok.Value; +import lombok.experimental.Accessors; +import org.prebid.server.hooks.v1.analytics.Tags; - private InvocationResultUtils() { +import java.util.List; - } +@Accessors(fluent = true) +@Builder +@Value +public class InvocationResultImpl implements InvocationResult { + + InvocationStatus status; + + String message; + + InvocationAction action; + + PayloadUpdate payloadUpdate; + + List errors; + + List warnings; + + List debugMessages; + + Object moduleContext; + + Tags analyticsTags; public static InvocationResult succeeded(PayloadUpdate payloadUpdate) { return InvocationResultImpl.builder() diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItAuctionResponseHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItAuctionResponseHook.java index 8073a5edc27..360e61fae47 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItAuctionResponseHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItAuctionResponseHook.java @@ -4,7 +4,7 @@ import io.vertx.core.Future; import org.prebid.server.hooks.execution.v1.auction.AuctionResponsePayloadImpl; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultUtils; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.auction.AuctionInvocationContext; import org.prebid.server.hooks.v1.auction.AuctionResponseHook; import org.prebid.server.hooks.v1.auction.AuctionResponsePayload; @@ -19,7 +19,7 @@ public Future> call( final BidResponse updatedBidResponse = updateBidResponse(originalBidResponse); - return Future.succeededFuture(InvocationResultUtils.succeeded(payload -> + return Future.succeededFuture(InvocationResultImpl.succeeded(payload -> AuctionResponsePayloadImpl.of(payload.bidResponse().toBuilder() .seatbid(updatedBidResponse.getSeatbid()) .build()))); diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItBidderRequestHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItBidderRequestHook.java index 4c95bcb5a7f..10af73e4d4f 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItBidderRequestHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItBidderRequestHook.java @@ -5,7 +5,7 @@ import io.vertx.core.Future; import org.prebid.server.hooks.execution.v1.bidder.BidderRequestPayloadImpl; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultUtils; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.bidder.BidderInvocationContext; import org.prebid.server.hooks.v1.bidder.BidderRequestHook; import org.prebid.server.hooks.v1.bidder.BidderRequestPayload; @@ -22,7 +22,7 @@ public Future> call( final BidRequest updatedBidRequest = updateBidRequest(originalBidRequest); - return Future.succeededFuture(InvocationResultUtils.succeeded(payload -> + return Future.succeededFuture(InvocationResultImpl.succeeded(payload -> BidderRequestPayloadImpl.of(payload.bidRequest().toBuilder() .imp(updatedBidRequest.getImp()) .build()))); diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItEntrypointHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItEntrypointHook.java index a4011db9106..36827bd39df 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItEntrypointHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItEntrypointHook.java @@ -5,7 +5,7 @@ import org.prebid.server.hooks.execution.v1.entrypoint.EntrypointPayloadImpl; import org.prebid.server.hooks.v1.InvocationContext; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultUtils; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.entrypoint.EntrypointHook; import org.prebid.server.hooks.v1.entrypoint.EntrypointPayload; import org.prebid.server.model.CaseInsensitiveMultiMap; @@ -18,7 +18,7 @@ public Future> call( final boolean rejectFlag = Boolean.parseBoolean(entrypointPayload.queryParams().get("sample-it-module-reject")); if (rejectFlag) { - return Future.succeededFuture(InvocationResultUtils.rejected("Rejected by sample entrypoint hook")); + return Future.succeededFuture(InvocationResultImpl.rejected("Rejected by sample entrypoint hook")); } return maybeUpdate(entrypointPayload); @@ -35,7 +35,7 @@ private Future> maybeUpdate(EntrypointPayloa ? updateBody(entrypointPayload.body()) : entrypointPayload.body(); - return Future.succeededFuture(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( + return Future.succeededFuture(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), updatedHeaders, updatedBody))); diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItProcessedAuctionRequestHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItProcessedAuctionRequestHook.java index dca19dd6043..a285235f420 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItProcessedAuctionRequestHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItProcessedAuctionRequestHook.java @@ -6,7 +6,7 @@ import io.vertx.core.Future; import org.prebid.server.hooks.execution.v1.auction.AuctionRequestPayloadImpl; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultUtils; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.auction.AuctionInvocationContext; import org.prebid.server.hooks.v1.auction.AuctionRequestPayload; import org.prebid.server.hooks.v1.auction.ProcessedAuctionRequestHook; @@ -29,7 +29,7 @@ public Future> call( final BidRequest updatedBidRequest = updateBidRequest(originalBidRequest); - return Future.succeededFuture(InvocationResultUtils.succeeded(payload -> + return Future.succeededFuture(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of(payload.bidRequest().toBuilder() .ext(updatedBidRequest.getExt()) .build()))); diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItProcessedBidderResponseHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItProcessedBidderResponseHook.java index b626e03d5ac..3f8e9ee7ae2 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItProcessedBidderResponseHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItProcessedBidderResponseHook.java @@ -4,7 +4,7 @@ import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.hooks.execution.v1.bidder.BidderResponsePayloadImpl; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultUtils; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.bidder.BidderInvocationContext; import org.prebid.server.hooks.v1.bidder.BidderResponsePayload; import org.prebid.server.hooks.v1.bidder.ProcessedBidderResponseHook; @@ -21,7 +21,7 @@ public Future> call( final List updatedBids = updateBids(originalBids); - return Future.succeededFuture(InvocationResultUtils.succeeded(payload -> + return Future.succeededFuture(InvocationResultImpl.succeeded(payload -> BidderResponsePayloadImpl.of(updatedBids))); } diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItRawBidderResponseHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItRawBidderResponseHook.java index 0f30527519b..fb6d915717e 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItRawBidderResponseHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItRawBidderResponseHook.java @@ -4,7 +4,7 @@ import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.hooks.execution.v1.bidder.BidderResponsePayloadImpl; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultUtils; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.bidder.BidderInvocationContext; import org.prebid.server.hooks.v1.bidder.BidderResponsePayload; import org.prebid.server.hooks.v1.bidder.RawBidderResponseHook; @@ -21,7 +21,7 @@ public Future> call( final List updatedBids = updateBids(originalBids); - return Future.succeededFuture(InvocationResultUtils.succeeded(payload -> + return Future.succeededFuture(InvocationResultImpl.succeeded(payload -> BidderResponsePayloadImpl.of(updatedBids))); } diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingBidderRequestHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingBidderRequestHook.java index d08303b93ce..bd90a974936 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingBidderRequestHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingBidderRequestHook.java @@ -2,7 +2,7 @@ import io.vertx.core.Future; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultUtils; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.bidder.BidderInvocationContext; import org.prebid.server.hooks.v1.bidder.BidderRequestHook; import org.prebid.server.hooks.v1.bidder.BidderRequestPayload; @@ -13,7 +13,7 @@ public class SampleItRejectingBidderRequestHook implements BidderRequestHook { public Future> call( BidderRequestPayload bidderRequestPayload, BidderInvocationContext invocationContext) { - return Future.succeededFuture(InvocationResultUtils.rejected("Rejected by rejecting bidder request hook")); + return Future.succeededFuture(InvocationResultImpl.rejected("Rejected by rejecting bidder request hook")); } @Override diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingProcessedAuctionRequestHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingProcessedAuctionRequestHook.java index 5dfad73d026..b5feb3aaef9 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingProcessedAuctionRequestHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingProcessedAuctionRequestHook.java @@ -2,7 +2,7 @@ import io.vertx.core.Future; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultUtils; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.auction.AuctionInvocationContext; import org.prebid.server.hooks.v1.auction.AuctionRequestPayload; import org.prebid.server.hooks.v1.auction.ProcessedAuctionRequestHook; @@ -13,7 +13,7 @@ public class SampleItRejectingProcessedAuctionRequestHook implements ProcessedAu public Future> call( AuctionRequestPayload auctionRequestPayload, AuctionInvocationContext invocationContext) { - return Future.succeededFuture(InvocationResultUtils.rejected( + return Future.succeededFuture(InvocationResultImpl.rejected( "Rejected by rejecting processed auction request hook")); } diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingProcessedBidderResponseHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingProcessedBidderResponseHook.java index d2c568837ca..a6f1438402c 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingProcessedBidderResponseHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingProcessedBidderResponseHook.java @@ -2,7 +2,7 @@ import io.vertx.core.Future; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultUtils; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.bidder.BidderInvocationContext; import org.prebid.server.hooks.v1.bidder.BidderResponsePayload; import org.prebid.server.hooks.v1.bidder.ProcessedBidderResponseHook; @@ -13,7 +13,7 @@ public class SampleItRejectingProcessedBidderResponseHook implements ProcessedBi public Future> call( BidderResponsePayload bidderResponsePayload, BidderInvocationContext invocationContext) { - return Future.succeededFuture(InvocationResultUtils.rejected( + return Future.succeededFuture(InvocationResultImpl.rejected( "Rejected by rejecting processed bidder response hook")); } diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingRawAuctionRequestHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingRawAuctionRequestHook.java index d4eda0346ca..5532962afc2 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingRawAuctionRequestHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingRawAuctionRequestHook.java @@ -2,7 +2,7 @@ import io.vertx.core.Future; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultUtils; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.auction.AuctionInvocationContext; import org.prebid.server.hooks.v1.auction.AuctionRequestPayload; import org.prebid.server.hooks.v1.auction.RawAuctionRequestHook; @@ -13,7 +13,7 @@ public class SampleItRejectingRawAuctionRequestHook implements RawAuctionRequest public Future> call( AuctionRequestPayload auctionRequestPayload, AuctionInvocationContext invocationContext) { - return Future.succeededFuture(InvocationResultUtils.rejected("Rejected by rejecting raw auction request hook")); + return Future.succeededFuture(InvocationResultImpl.rejected("Rejected by rejecting raw auction request hook")); } @Override diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingRawBidderResponseHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingRawBidderResponseHook.java index f2964a9871a..0eeeee4375c 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingRawBidderResponseHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingRawBidderResponseHook.java @@ -2,7 +2,7 @@ import io.vertx.core.Future; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultUtils; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.bidder.BidderInvocationContext; import org.prebid.server.hooks.v1.bidder.BidderResponsePayload; import org.prebid.server.hooks.v1.bidder.RawBidderResponseHook; @@ -13,7 +13,7 @@ public class SampleItRejectingRawBidderResponseHook implements RawBidderResponse public Future> call( BidderResponsePayload bidderResponsePayload, BidderInvocationContext invocationContext) { - return Future.succeededFuture(InvocationResultUtils.rejected("Rejected by rejecting raw bidder response hook")); + return Future.succeededFuture(InvocationResultImpl.rejected("Rejected by rejecting raw bidder response hook")); } @Override diff --git a/src/test/java/org/prebid/server/metric/MetricsTest.java b/src/test/java/org/prebid/server/metric/MetricsTest.java index f4943895116..bdab45b2670 100644 --- a/src/test/java/org/prebid/server/metric/MetricsTest.java +++ b/src/test/java/org/prebid/server/metric/MetricsTest.java @@ -1190,13 +1190,6 @@ public void updateHooksMetricsShouldIncrementMetrics() { "module1", Stage.entrypoint, "hook1", ExecutionStatus.success, 5L, ExecutionAction.update); metrics.updateHooksMetrics( "module1", Stage.raw_auction_request, "hook2", ExecutionStatus.success, 5L, ExecutionAction.no_action); - metrics.updateHooksMetrics( - "module1", - Stage.raw_auction_request, - "hook2", - ExecutionStatus.success, - 5L, - ExecutionAction.no_invocation); metrics.updateHooksMetrics( "module1", Stage.processed_auction_request, @@ -1209,7 +1202,7 @@ public void updateHooksMetricsShouldIncrementMetrics() { metrics.updateHooksMetrics( "module2", Stage.raw_bidder_response, "hook2", ExecutionStatus.timeout, 7L, null); metrics.updateHooksMetrics( - "module2", Stage.all_processed_bid_responses, "hook3", ExecutionStatus.execution_failure, 5L, null); + "module2", Stage.processed_bidder_response, "hook3", ExecutionStatus.execution_failure, 5L, null); metrics.updateHooksMetrics( "module2", Stage.auction_response, "hook4", ExecutionStatus.invocation_failure, 5L, null); @@ -1227,9 +1220,6 @@ public void updateHooksMetricsShouldIncrementMetrics() { .isEqualTo(1); assertThat(metricRegistry.counter("modules.module.module1.stage.rawauction.hook.hook2.success.noop").getCount()) .isEqualTo(1); - assertThat(metricRegistry.counter("modules.module.module1.stage.rawauction.hook.hook2.success.no-invocation") - .getCount()) - .isEqualTo(1); assertThat(metricRegistry.timer("modules.module.module1.stage.rawauction.hook.hook2.duration").getCount()) .isEqualTo(1); @@ -1255,14 +1245,12 @@ public void updateHooksMetricsShouldIncrementMetrics() { assertThat(metricRegistry.timer("modules.module.module2.stage.rawbidresponse.hook.hook2.duration").getCount()) .isEqualTo(1); - assertThat(metricRegistry.counter("modules.module.module2.stage.allprocbidresponses.hook.hook3.call") - .getCount()) + assertThat(metricRegistry.counter("modules.module.module2.stage.procbidresponse.hook.hook3.call").getCount()) .isEqualTo(1); - assertThat(metricRegistry.counter("modules.module.module2.stage.allprocbidresponses.hook.hook3.execution-error") + assertThat(metricRegistry.counter("modules.module.module2.stage.procbidresponse.hook.hook3.execution-error") .getCount()) .isEqualTo(1); - assertThat(metricRegistry.timer("modules.module.module2.stage.allprocbidresponses.hook.hook3.duration") - .getCount()) + assertThat(metricRegistry.timer("modules.module.module2.stage.procbidresponse.hook.hook3.duration").getCount()) .isEqualTo(1); assertThat(metricRegistry.counter("modules.module.module2.stage.auctionresponse.hook.hook4.call").getCount()) @@ -1286,8 +1274,6 @@ public void updateAccountHooksMetricsShouldIncrementMetricsIfVerbosityIsDetailed Account.empty("accountId"), "module2", ExecutionStatus.failure, null); metrics.updateAccountHooksMetrics( Account.empty("accountId"), "module3", ExecutionStatus.timeout, null); - metrics.updateAccountHooksMetrics( - Account.empty("accountId"), "module4", ExecutionStatus.success, ExecutionAction.no_invocation); // then assertThat(metricRegistry.counter("account.accountId.modules.module.module1.call").getCount()) @@ -1304,11 +1290,6 @@ public void updateAccountHooksMetricsShouldIncrementMetricsIfVerbosityIsDetailed .isEqualTo(1); assertThat(metricRegistry.counter("account.accountId.modules.module.module3.failure").getCount()) .isEqualTo(1); - - assertThat(metricRegistry.counter("account.accountId.modules.module.module4.call").getCount()) - .isEqualTo(0); - assertThat(metricRegistry.counter("account.accountId.modules.module.module4.success.no-invocation").getCount()) - .isEqualTo(1); } @Test From 4b0f59023deea588c57b00fbe11ad87c9e325aa2 Mon Sep 17 00:00:00 2001 From: antonbabak Date: Thu, 28 Nov 2024 15:08:35 +0100 Subject: [PATCH 06/11] Fix comments --- docs/metrics.md | 12 + ...ConfiantAdQualityBidResponsesScanHook.java | 2 +- .../v1/model/InvocationResultImpl.java | 36 --- ...FiftyOneDeviceDetectionEntrypointHook.java | 2 +- ...eDeviceDetectionRawAuctionRequestHook.java | 2 +- .../v1/model/InvocationResultImpl.java | 24 -- .../v1/Ortb2BlockingBidderRequestHook.java | 2 +- .../Ortb2BlockingRawBidderResponseHook.java | 2 +- .../v1/model/InvocationResultImpl.java | 37 --- .../Ortb2BlockingBidderRequestHookTest.java | 2 +- ...rtb2BlockingRawBidderResponseHookTest.java | 2 +- ...orrectionAllProcessedBidResponsesHook.java | 8 +- .../v1/model/InvocationResultImpl.java | 38 --- ...diaFilterAllProcessedBidResponsesHook.java | 2 +- .../server/auction/ExchangeService.java | 1 + .../server/hooks/execution/GroupExecutor.java | 2 +- .../server/hooks/execution/GroupResult.java | 1 + .../hooks/execution/HookStageExecutor.java | 32 +- .../execution/model/ExecutionAction.java | 2 +- .../server/hooks/v1/InvocationAction.java | 2 +- .../hooks/v1}/InvocationResultImpl.java | 6 +- .../org/prebid/server/metric/MetricName.java | 1 + .../org/prebid/server/metric/Metrics.java | 17 +- .../model/AccountHooksConfiguration.java | 2 +- ...AdminConfig.java => HooksAdminConfig.java} | 2 +- .../spring/config/HooksConfiguration.java | 8 + .../execution/HookStageExecutorTest.java | 275 ++++++++++++------ ...ltImpl.java => InvocationResultUtils.java} | 30 +- .../it/hooks/SampleItAuctionResponseHook.java | 4 +- .../it/hooks/SampleItBidderRequestHook.java | 4 +- .../it/hooks/SampleItEntrypointHook.java | 6 +- .../SampleItProcessedAuctionRequestHook.java | 4 +- .../SampleItProcessedBidderResponseHook.java | 4 +- .../hooks/SampleItRawBidderResponseHook.java | 4 +- .../SampleItRejectingBidderRequestHook.java | 4 +- ...tRejectingProcessedAuctionRequestHook.java | 4 +- ...tRejectingProcessedBidderResponseHook.java | 4 +- ...ampleItRejectingRawAuctionRequestHook.java | 4 +- ...ampleItRejectingRawBidderResponseHook.java | 4 +- .../org/prebid/server/metric/MetricsTest.java | 27 +- 40 files changed, 314 insertions(+), 311 deletions(-) delete mode 100644 extra/modules/confiant-ad-quality/src/main/java/org/prebid/server/hooks/modules/com/confiant/adquality/v1/model/InvocationResultImpl.java delete mode 100644 extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/model/InvocationResultImpl.java delete mode 100644 extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/model/InvocationResultImpl.java delete mode 100644 extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/model/InvocationResultImpl.java rename {extra/modules/pb-richmedia-filter/src/main/java/org/prebid/server/hooks/modules/pb/richmedia/filter/v1/model => src/main/java/org/prebid/server/hooks/v1}/InvocationResultImpl.java (66%) rename src/main/java/org/prebid/server/settings/model/{AccountHooksAdminConfig.java => HooksAdminConfig.java} (86%) rename src/test/java/org/prebid/server/hooks/v1/{InvocationResultImpl.java => InvocationResultUtils.java} (75%) diff --git a/docs/metrics.md b/docs/metrics.md index 75a663407e0..85df92bc269 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -135,3 +135,15 @@ Following metrics are collected and submitted if account is configured with `det - `analytics..(auction|amp|video|cookie_sync|event|setuid).timeout` - number of event requests, failed with timeout cause - `analytics..(auction|amp|video|cookie_sync|event|setuid).err` - number of event requests, failed with errors - `analytics..(auction|amp|video|cookie_sync|event|setuid).badinput` - number of event requests, rejected with bad input cause + +## Modules metrics +- `modules.module..stage..hook..call` - number of times the hook is called +- `modules.module..stage..hook..duration` - timer tracking the called hook execution time +- `modules.module..stage..hook..success.(noop|update|reject|no-invocation)` - number of times the hook is called successfully with the action applied +- `modules.module..stage..hook..(failure|timeout|execution-error)` - number of times the hook execution is failed + +## Modules per-account metrics +- `account..modules.module..call` - number of times the module is called +- `account..modules.module..duration` - timer tracking the called module execution time +- `account..modules.module..success.(noop|update|reject|no-invocation)` - number of times the module is called successfully with the action applied +- `account..modules.module..failure` - number of times the module execution is failed 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 7db1446bcce..2db501f1852 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 @@ -18,9 +18,9 @@ import org.prebid.server.hooks.modules.com.confiant.adquality.core.BidsScanResult; import org.prebid.server.hooks.modules.com.confiant.adquality.core.BidsScanner; import org.prebid.server.hooks.modules.com.confiant.adquality.model.GroupByIssues; -import org.prebid.server.hooks.modules.com.confiant.adquality.v1.model.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationAction; import org.prebid.server.hooks.v1.InvocationResult; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.auction.AuctionInvocationContext; import org.prebid.server.hooks.v1.bidder.AllProcessedBidResponsesHook; diff --git a/extra/modules/confiant-ad-quality/src/main/java/org/prebid/server/hooks/modules/com/confiant/adquality/v1/model/InvocationResultImpl.java b/extra/modules/confiant-ad-quality/src/main/java/org/prebid/server/hooks/modules/com/confiant/adquality/v1/model/InvocationResultImpl.java deleted file mode 100644 index 76fa5759644..00000000000 --- a/extra/modules/confiant-ad-quality/src/main/java/org/prebid/server/hooks/modules/com/confiant/adquality/v1/model/InvocationResultImpl.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.prebid.server.hooks.modules.com.confiant.adquality.v1.model; - -import lombok.Builder; -import lombok.Value; -import lombok.experimental.Accessors; -import org.prebid.server.hooks.v1.InvocationAction; -import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationStatus; -import org.prebid.server.hooks.v1.PayloadUpdate; -import org.prebid.server.hooks.v1.analytics.Tags; - -import java.util.List; - -@Accessors(fluent = true) -@Builder -@Value -public class InvocationResultImpl implements InvocationResult { - - InvocationStatus status; - - String message; - - InvocationAction action; - - PayloadUpdate payloadUpdate; - - List errors; - - List warnings; - - List debugMessages; - - Object moduleContext; - - Tags analyticsTags; -} diff --git a/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/hooks/FiftyOneDeviceDetectionEntrypointHook.java b/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/hooks/FiftyOneDeviceDetectionEntrypointHook.java index 9df4e2a0237..506cf66078e 100644 --- a/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/hooks/FiftyOneDeviceDetectionEntrypointHook.java +++ b/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/hooks/FiftyOneDeviceDetectionEntrypointHook.java @@ -2,10 +2,10 @@ import org.prebid.server.hooks.modules.fiftyone.devicedetection.model.boundary.CollectedEvidence; import org.prebid.server.hooks.modules.fiftyone.devicedetection.v1.model.ModuleContext; -import org.prebid.server.hooks.modules.fiftyone.devicedetection.v1.model.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationAction; import org.prebid.server.hooks.v1.InvocationContext; import org.prebid.server.hooks.v1.InvocationResult; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.entrypoint.EntrypointHook; import org.prebid.server.hooks.v1.entrypoint.EntrypointPayload; diff --git a/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/hooks/FiftyOneDeviceDetectionRawAuctionRequestHook.java b/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/hooks/FiftyOneDeviceDetectionRawAuctionRequestHook.java index 081177e8ca1..8b0d5cdc8d4 100644 --- a/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/hooks/FiftyOneDeviceDetectionRawAuctionRequestHook.java +++ b/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/hooks/FiftyOneDeviceDetectionRawAuctionRequestHook.java @@ -13,9 +13,9 @@ import org.prebid.server.hooks.modules.fiftyone.devicedetection.v1.core.EnrichmentResult; import org.prebid.server.hooks.modules.fiftyone.devicedetection.v1.core.SecureHeadersRetriever; import org.prebid.server.hooks.modules.fiftyone.devicedetection.v1.model.ModuleContext; -import org.prebid.server.hooks.modules.fiftyone.devicedetection.v1.model.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationAction; import org.prebid.server.hooks.v1.InvocationResult; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.auction.AuctionInvocationContext; import org.prebid.server.hooks.v1.auction.AuctionRequestPayload; diff --git a/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/model/InvocationResultImpl.java b/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/model/InvocationResultImpl.java deleted file mode 100644 index ead75085974..00000000000 --- a/extra/modules/fiftyone-devicedetection/src/main/java/org/prebid/server/hooks/modules/fiftyone/devicedetection/v1/model/InvocationResultImpl.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.prebid.server.hooks.modules.fiftyone.devicedetection.v1.model; - -import lombok.Builder; -import org.prebid.server.hooks.v1.InvocationAction; -import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationStatus; -import org.prebid.server.hooks.v1.PayloadUpdate; -import org.prebid.server.hooks.v1.analytics.Tags; - -import java.util.List; - -@Builder -public record InvocationResultImpl( - InvocationStatus status, - String message, - InvocationAction action, - PayloadUpdate payloadUpdate, - List errors, - List warnings, - List debugMessages, - Object moduleContext, - Tags analyticsTags -) implements InvocationResult { -} diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHook.java b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHook.java index ff9e6ab6c3c..bb5e05d4fb2 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHook.java +++ b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHook.java @@ -11,9 +11,9 @@ import org.prebid.server.hooks.modules.ortb2.blocking.core.model.ExecutionResult; import org.prebid.server.hooks.modules.ortb2.blocking.model.ModuleContext; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.BidderRequestPayloadImpl; -import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationAction; import org.prebid.server.hooks.v1.InvocationResult; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.bidder.BidderInvocationContext; import org.prebid.server.hooks.v1.bidder.BidderRequestHook; diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHook.java b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHook.java index 329e99d3bbc..c90ac94840a 100644 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHook.java +++ b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHook.java @@ -13,13 +13,13 @@ import org.prebid.server.hooks.modules.ortb2.blocking.core.model.ExecutionResult; import org.prebid.server.hooks.modules.ortb2.blocking.model.ModuleContext; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.BidderResponsePayloadImpl; -import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.InvocationResultImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.analytics.ActivityImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.analytics.AppliedToImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.analytics.ResultImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.analytics.TagsImpl; import org.prebid.server.hooks.v1.InvocationAction; import org.prebid.server.hooks.v1.InvocationResult; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.analytics.Result; import org.prebid.server.hooks.v1.analytics.Tags; diff --git a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/model/InvocationResultImpl.java b/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/model/InvocationResultImpl.java deleted file mode 100644 index 48be15fdf37..00000000000 --- a/extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/model/InvocationResultImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.prebid.server.hooks.modules.ortb2.blocking.v1.model; - -import lombok.Builder; -import lombok.Value; -import lombok.experimental.Accessors; -import org.prebid.server.hooks.modules.ortb2.blocking.model.ModuleContext; -import org.prebid.server.hooks.v1.InvocationAction; -import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationStatus; -import org.prebid.server.hooks.v1.PayloadUpdate; -import org.prebid.server.hooks.v1.analytics.Tags; - -import java.util.List; - -@Accessors(fluent = true) -@Builder -@Value -public class InvocationResultImpl implements InvocationResult { - - InvocationStatus status; - - String message; - - InvocationAction action; - - PayloadUpdate payloadUpdate; - - List errors; - - List warnings; - - List debugMessages; - - ModuleContext moduleContext; - - Tags analyticsTags; -} diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHookTest.java b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHookTest.java index fe1ea6e9614..4c3852bc630 100644 --- a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHookTest.java +++ b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingBidderRequestHookTest.java @@ -28,9 +28,9 @@ import org.prebid.server.hooks.modules.ortb2.blocking.model.ModuleContext; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.BidderInvocationContextImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.BidderRequestPayloadImpl; -import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationAction; import org.prebid.server.hooks.v1.InvocationResult; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.PayloadUpdate; import org.prebid.server.hooks.v1.bidder.BidderRequestPayload; diff --git a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHookTest.java b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHookTest.java index 0e0a6811835..356bd7b2125 100644 --- a/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHookTest.java +++ b/extra/modules/ortb2-blocking/src/test/java/org/prebid/server/hooks/modules/ortb2/blocking/v1/Ortb2BlockingRawBidderResponseHookTest.java @@ -23,13 +23,13 @@ import org.prebid.server.hooks.modules.ortb2.blocking.model.ModuleContext; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.BidderInvocationContextImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.BidderResponsePayloadImpl; -import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.InvocationResultImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.analytics.ActivityImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.analytics.AppliedToImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.analytics.ResultImpl; import org.prebid.server.hooks.modules.ortb2.blocking.v1.model.analytics.TagsImpl; import org.prebid.server.hooks.v1.InvocationAction; import org.prebid.server.hooks.v1.InvocationResult; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.PayloadUpdate; import org.prebid.server.hooks.v1.bidder.BidderResponsePayload; diff --git a/extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/ResponseCorrectionAllProcessedBidResponsesHook.java b/extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/ResponseCorrectionAllProcessedBidResponsesHook.java index 09e4640b064..4d7fb81c366 100644 --- a/extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/ResponseCorrectionAllProcessedBidResponsesHook.java +++ b/extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/ResponseCorrectionAllProcessedBidResponsesHook.java @@ -11,9 +11,9 @@ import org.prebid.server.hooks.modules.pb.response.correction.core.ResponseCorrectionProvider; import org.prebid.server.hooks.modules.pb.response.correction.core.config.model.Config; import org.prebid.server.hooks.modules.pb.response.correction.core.correction.Correction; -import org.prebid.server.hooks.modules.pb.response.correction.v1.model.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationAction; import org.prebid.server.hooks.v1.InvocationResult; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.auction.AuctionInvocationContext; import org.prebid.server.hooks.v1.bidder.AllProcessedBidResponsesHook; @@ -57,7 +57,7 @@ public Future> call(AllProcess return noAction(); } - final InvocationResult invocationResult = InvocationResultImpl.builder() + final InvocationResult invocationResult = InvocationResultImpl.builder() .status(InvocationStatus.success) .action(InvocationAction.update) .payloadUpdate(initialPayload -> AllProcessedBidResponsesPayloadImpl.of( @@ -84,7 +84,7 @@ private static List applyCorrections(List bidder } private Future> failure(String message) { - return Future.succeededFuture(InvocationResultImpl.builder() + return Future.succeededFuture(InvocationResultImpl.builder() .status(InvocationStatus.failure) .message(message) .action(InvocationAction.no_action) @@ -92,7 +92,7 @@ private Future> failure(String } private static Future> noAction() { - return Future.succeededFuture(InvocationResultImpl.builder() + return Future.succeededFuture(InvocationResultImpl.builder() .status(InvocationStatus.success) .action(InvocationAction.no_action) .build()); diff --git a/extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/model/InvocationResultImpl.java b/extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/model/InvocationResultImpl.java deleted file mode 100644 index 1a39413583c..00000000000 --- a/extra/modules/pb-response-correction/src/main/java/org/prebid/server/hooks/modules/pb/response/correction/v1/model/InvocationResultImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.prebid.server.hooks.modules.pb.response.correction.v1.model; - -import lombok.Builder; -import lombok.Value; -import lombok.experimental.Accessors; -import org.prebid.server.hooks.v1.InvocationAction; -import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationStatus; -import org.prebid.server.hooks.v1.PayloadUpdate; -import org.prebid.server.hooks.v1.analytics.Tags; -import org.prebid.server.hooks.v1.auction.AuctionRequestPayload; -import org.prebid.server.hooks.v1.bidder.AllProcessedBidResponsesPayload; - -import java.util.List; - -@Accessors(fluent = true) -@Builder -@Value -public class InvocationResultImpl implements InvocationResult { - - InvocationStatus status; - - String message; - - InvocationAction action; - - PayloadUpdate payloadUpdate; - - List errors; - - List warnings; - - List debugMessages; - - Object moduleContext; - - Tags analyticsTags; -} diff --git a/extra/modules/pb-richmedia-filter/src/main/java/org/prebid/server/hooks/modules/pb/richmedia/filter/v1/PbRichmediaFilterAllProcessedBidResponsesHook.java b/extra/modules/pb-richmedia-filter/src/main/java/org/prebid/server/hooks/modules/pb/richmedia/filter/v1/PbRichmediaFilterAllProcessedBidResponsesHook.java index ee92a5e2064..e0416c6d30d 100644 --- a/extra/modules/pb-richmedia-filter/src/main/java/org/prebid/server/hooks/modules/pb/richmedia/filter/v1/PbRichmediaFilterAllProcessedBidResponsesHook.java +++ b/extra/modules/pb-richmedia-filter/src/main/java/org/prebid/server/hooks/modules/pb/richmedia/filter/v1/PbRichmediaFilterAllProcessedBidResponsesHook.java @@ -12,13 +12,13 @@ import org.prebid.server.hooks.modules.pb.richmedia.filter.model.AnalyticsResult; import org.prebid.server.hooks.modules.pb.richmedia.filter.model.MraidFilterResult; import org.prebid.server.hooks.modules.pb.richmedia.filter.model.PbRichMediaFilterProperties; -import org.prebid.server.hooks.modules.pb.richmedia.filter.v1.model.InvocationResultImpl; import org.prebid.server.hooks.modules.pb.richmedia.filter.v1.model.analytics.ActivityImpl; import org.prebid.server.hooks.modules.pb.richmedia.filter.v1.model.analytics.AppliedToImpl; import org.prebid.server.hooks.modules.pb.richmedia.filter.v1.model.analytics.ResultImpl; import org.prebid.server.hooks.modules.pb.richmedia.filter.v1.model.analytics.TagsImpl; import org.prebid.server.hooks.v1.InvocationAction; import org.prebid.server.hooks.v1.InvocationResult; +import org.prebid.server.hooks.v1.InvocationResultImpl; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.analytics.Result; import org.prebid.server.hooks.v1.analytics.Tags; diff --git a/src/main/java/org/prebid/server/auction/ExchangeService.java b/src/main/java/org/prebid/server/auction/ExchangeService.java index 2864ef8c937..6fff31c6459 100644 --- a/src/main/java/org/prebid/server/auction/ExchangeService.java +++ b/src/main/java/org/prebid/server/auction/ExchangeService.java @@ -1395,6 +1395,7 @@ private AuctionContext updateHooksMetrics(AuctionContext context) { .flatMap(Collection::stream) .map(GroupExecutionOutcome::getHooks) .flatMap(Collection::stream) + .filter(hookOutcome -> hookOutcome.getAction() != ExecutionAction.no_invocation) .collect(Collectors.groupingBy( outcome -> outcome.getHookId().getModuleCode(), Collectors.summingLong(HookExecutionOutcome::getExecutionTime))) diff --git a/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java b/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java index 6ec0cc63095..2d8d33bef77 100644 --- a/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java +++ b/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java @@ -87,7 +87,7 @@ public Future> execute() { Future> groupFuture = Future.succeededFuture(initialGroupResult); for (final HookId hookId : group.getHookSequence()) { - if (!modulesExecution.getOrDefault(hookId.getModuleCode(), true)) { + if (!modulesExecution.get(hookId.getModuleCode())) { continue; } diff --git a/src/main/java/org/prebid/server/hooks/execution/GroupResult.java b/src/main/java/org/prebid/server/hooks/execution/GroupResult.java index a4487e3a60b..8bc7c5c0723 100644 --- a/src/main/java/org/prebid/server/hooks/execution/GroupResult.java +++ b/src/main/java/org/prebid/server/hooks/execution/GroupResult.java @@ -173,6 +173,7 @@ private static ExecutionAction toExecutionAction(InvocationAction action) { case reject -> ExecutionAction.reject; case update -> ExecutionAction.update; case no_action -> ExecutionAction.no_action; + case no_invocation -> ExecutionAction.no_invocation; }; } diff --git a/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java b/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java index 5793cf920a4..d3aaeaa28a1 100644 --- a/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java +++ b/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java @@ -47,7 +47,7 @@ import org.prebid.server.model.CaseInsensitiveMultiMap; import org.prebid.server.model.Endpoint; import org.prebid.server.settings.model.Account; -import org.prebid.server.settings.model.AccountHooksAdminConfig; +import org.prebid.server.settings.model.HooksAdminConfig; import org.prebid.server.settings.model.AccountHooksConfiguration; import java.time.Clock; @@ -70,6 +70,7 @@ public class HookStageExecutor { private final ExecutionPlan hostExecutionPlan; private final ExecutionPlan defaultAccountExecutionPlan; + private final Map hostModuleExecution; private final HookCatalog hookCatalog; private final TimeoutFactory timeoutFactory; private final Vertx vertx; @@ -78,6 +79,7 @@ public class HookStageExecutor { private HookStageExecutor(ExecutionPlan hostExecutionPlan, ExecutionPlan defaultAccountExecutionPlan, + Map hostModuleExecution, HookCatalog hookCatalog, TimeoutFactory timeoutFactory, Vertx vertx, @@ -91,10 +93,12 @@ private HookStageExecutor(ExecutionPlan hostExecutionPlan, this.vertx = vertx; this.clock = clock; this.isConfigToInvokeRequired = isConfigToInvokeRequired; + this.hostModuleExecution = hostModuleExecution; } public static HookStageExecutor create(String hostExecutionPlan, String defaultAccountExecutionPlan, + Map hostModuleExecution, HookCatalog hookCatalog, TimeoutFactory timeoutFactory, Vertx vertx, @@ -108,6 +112,7 @@ public static HookStageExecutor create(String hostExecutionPlan, Objects.requireNonNull(mapper), Objects.requireNonNull(hookCatalog)), parseAndValidateExecutionPlan(defaultAccountExecutionPlan, mapper, hookCatalog), + hostModuleExecution, hookCatalog, Objects.requireNonNull(timeoutFactory), Objects.requireNonNull(vertx), @@ -127,7 +132,7 @@ public Future> executeEntrypointStag .withExecutionPlan(planForEntrypointStage(endpoint)) .withInitialPayload(EntrypointPayloadImpl.of(queryParams, headers, body)) .withInvocationContextProvider(invocationContextProvider(endpoint)) - .withModulesExecution(Collections.emptyMap()) + .withModulesExecution(DefaultedMap.defaultedMap(hostModuleExecution, true)) .withRejectAllowed(true) .execute(); } @@ -285,23 +290,22 @@ private StageExecutor modulesExecutionForAccount(Account account) { final Map accountModulesExecution = Optional.ofNullable(account.getHooks()) .map(AccountHooksConfiguration::getAdmin) - .map(AccountHooksAdminConfig::getModuleExecution) + .map(HooksAdminConfig::getModuleExecution) .orElseGet(Collections::emptyMap); - if (!isConfigToInvokeRequired) { - return DefaultedMap.defaultedMap(accountModulesExecution, true); - } - final Map resultModulesExecution = new HashMap<>(accountModulesExecution); - Optional.ofNullable(account.getHooks()) - .map(AccountHooksConfiguration::getModules) - .map(Map::keySet) - .stream() - .flatMap(Collection::stream) - .forEach(module -> resultModulesExecution.computeIfAbsent(module, key -> true)); + if (isConfigToInvokeRequired) { + Optional.ofNullable(account.getHooks()) + .map(AccountHooksConfiguration::getModules) + .map(Map::keySet) + .stream() + .flatMap(Collection::stream) + .forEach(module -> resultModulesExecution.computeIfAbsent(module, key -> true)); + } - return DefaultedMap.defaultedMap(resultModulesExecution, false); + resultModulesExecution.putAll(hostModuleExecution); + return DefaultedMap.defaultedMap(resultModulesExecution, !isConfigToInvokeRequired); } private static ExecutionPlan parseAndValidateExecutionPlan( diff --git a/src/main/java/org/prebid/server/hooks/execution/model/ExecutionAction.java b/src/main/java/org/prebid/server/hooks/execution/model/ExecutionAction.java index 5e13aa3f14c..886cec114e8 100644 --- a/src/main/java/org/prebid/server/hooks/execution/model/ExecutionAction.java +++ b/src/main/java/org/prebid/server/hooks/execution/model/ExecutionAction.java @@ -2,5 +2,5 @@ public enum ExecutionAction { - no_action, update, reject + no_action, update, reject, no_invocation } diff --git a/src/main/java/org/prebid/server/hooks/v1/InvocationAction.java b/src/main/java/org/prebid/server/hooks/v1/InvocationAction.java index 29b22bf1b3d..821b21a730b 100644 --- a/src/main/java/org/prebid/server/hooks/v1/InvocationAction.java +++ b/src/main/java/org/prebid/server/hooks/v1/InvocationAction.java @@ -2,5 +2,5 @@ public enum InvocationAction { - no_action, update, reject + no_action, update, reject, no_invocation } diff --git a/extra/modules/pb-richmedia-filter/src/main/java/org/prebid/server/hooks/modules/pb/richmedia/filter/v1/model/InvocationResultImpl.java b/src/main/java/org/prebid/server/hooks/v1/InvocationResultImpl.java similarity index 66% rename from extra/modules/pb-richmedia-filter/src/main/java/org/prebid/server/hooks/modules/pb/richmedia/filter/v1/model/InvocationResultImpl.java rename to src/main/java/org/prebid/server/hooks/v1/InvocationResultImpl.java index b77fc98a68b..abfe5cf8fb2 100644 --- a/extra/modules/pb-richmedia-filter/src/main/java/org/prebid/server/hooks/modules/pb/richmedia/filter/v1/model/InvocationResultImpl.java +++ b/src/main/java/org/prebid/server/hooks/v1/InvocationResultImpl.java @@ -1,12 +1,8 @@ -package org.prebid.server.hooks.modules.pb.richmedia.filter.v1.model; +package org.prebid.server.hooks.v1; import lombok.Builder; import lombok.Value; import lombok.experimental.Accessors; -import org.prebid.server.hooks.v1.InvocationAction; -import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationStatus; -import org.prebid.server.hooks.v1.PayloadUpdate; import org.prebid.server.hooks.v1.analytics.Tags; import java.util.List; diff --git a/src/main/java/org/prebid/server/metric/MetricName.java b/src/main/java/org/prebid/server/metric/MetricName.java index 6d624fd857f..9ea3d15f0fc 100644 --- a/src/main/java/org/prebid/server/metric/MetricName.java +++ b/src/main/java/org/prebid/server/metric/MetricName.java @@ -139,6 +139,7 @@ public enum MetricName { call, success, noop, + no_invocation("no-invocation"), reject, unknown, failure, diff --git a/src/main/java/org/prebid/server/metric/Metrics.java b/src/main/java/org/prebid/server/metric/Metrics.java index 64edbfc85cc..52964a9f8b0 100644 --- a/src/main/java/org/prebid/server/metric/Metrics.java +++ b/src/main/java/org/prebid/server/metric/Metrics.java @@ -628,13 +628,20 @@ public void updateHooksMetrics( final HookImplMetrics hookImplMetrics = hooks().module(moduleCode).stage(stage).hookImpl(hookImplCode); - hookImplMetrics.incCounter(MetricName.call); + if (action != ExecutionAction.no_invocation) { + hookImplMetrics.incCounter(MetricName.call); + } + if (status == ExecutionStatus.success) { hookImplMetrics.success().incCounter(HookMetricMapper.fromAction(action)); } else { hookImplMetrics.incCounter(HookMetricMapper.fromStatus(status)); } - hookImplMetrics.updateTimer(MetricName.duration, executionTime); + + if (action != ExecutionAction.no_invocation) { + hookImplMetrics.updateTimer(MetricName.duration, executionTime); + } + } public void updateAccountHooksMetrics( @@ -646,7 +653,10 @@ public void updateAccountHooksMetrics( if (accountMetricsVerbosityResolver.forAccount(account).isAtLeast(AccountMetricsVerbosityLevel.detailed)) { final ModuleMetrics accountModuleMetrics = forAccount(account.getId()).hooks().module(moduleCode); - accountModuleMetrics.incCounter(MetricName.call); + if (action != ExecutionAction.no_invocation) { + accountModuleMetrics.incCounter(MetricName.call); + } + if (status == ExecutionStatus.success) { accountModuleMetrics.success().incCounter(HookMetricMapper.fromAction(action)); } else { @@ -677,6 +687,7 @@ private static class HookMetricMapper { ACTION_TO_METRIC.put(ExecutionAction.no_action, MetricName.noop); ACTION_TO_METRIC.put(ExecutionAction.update, MetricName.update); ACTION_TO_METRIC.put(ExecutionAction.reject, MetricName.reject); + ACTION_TO_METRIC.put(ExecutionAction.no_invocation, MetricName.no_invocation); } static MetricName fromStatus(ExecutionStatus status) { diff --git a/src/main/java/org/prebid/server/settings/model/AccountHooksConfiguration.java b/src/main/java/org/prebid/server/settings/model/AccountHooksConfiguration.java index 98edb138a52..f45af371385 100644 --- a/src/main/java/org/prebid/server/settings/model/AccountHooksConfiguration.java +++ b/src/main/java/org/prebid/server/settings/model/AccountHooksConfiguration.java @@ -15,5 +15,5 @@ public class AccountHooksConfiguration { Map modules; - AccountHooksAdminConfig admin; + HooksAdminConfig admin; } diff --git a/src/main/java/org/prebid/server/settings/model/AccountHooksAdminConfig.java b/src/main/java/org/prebid/server/settings/model/HooksAdminConfig.java similarity index 86% rename from src/main/java/org/prebid/server/settings/model/AccountHooksAdminConfig.java rename to src/main/java/org/prebid/server/settings/model/HooksAdminConfig.java index b9bd8e7eaaf..36b12a401f0 100644 --- a/src/main/java/org/prebid/server/settings/model/AccountHooksAdminConfig.java +++ b/src/main/java/org/prebid/server/settings/model/HooksAdminConfig.java @@ -8,7 +8,7 @@ @Builder @Value -public class AccountHooksAdminConfig { +public class HooksAdminConfig { @JsonAlias("module-execution") Map moduleExecution; diff --git a/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java b/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java index 64534d119aa..5a05ccb8c8e 100644 --- a/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java @@ -8,6 +8,7 @@ import org.prebid.server.hooks.execution.HookStageExecutor; import org.prebid.server.hooks.v1.Module; import org.prebid.server.json.JacksonMapper; +import org.prebid.server.settings.model.HooksAdminConfig; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; @@ -16,6 +17,8 @@ import java.time.Clock; import java.util.Collection; +import java.util.Collections; +import java.util.Optional; @Configuration public class HooksConfiguration { @@ -38,6 +41,9 @@ HookStageExecutor hookStageExecutor(HooksConfigurationProperties hooksConfigurat return HookStageExecutor.create( hooksConfiguration.getHostExecutionPlan(), hooksConfiguration.getDefaultAccountExecutionPlan(), + Optional.ofNullable(hooksConfiguration.getAdmin()) + .map(HooksAdminConfig::getModuleExecution) + .orElseGet(Collections::emptyMap), hookCatalog, timeoutFactory, vertx, @@ -60,5 +66,7 @@ private static class HooksConfigurationProperties { String hostExecutionPlan; String defaultAccountExecutionPlan; + + HooksAdminConfig admin; } } diff --git a/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java b/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java index c0dea093017..bfc009e760a 100644 --- a/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java +++ b/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.iab.openrtb.request.BidRequest; +import com.iab.openrtb.request.Site; +import com.iab.openrtb.request.User; import com.iab.openrtb.response.Bid; import com.iab.openrtb.response.BidResponse; import io.vertx.core.CompositeFuture; @@ -53,6 +55,7 @@ import org.prebid.server.hooks.v1.InvocationContext; import org.prebid.server.hooks.v1.InvocationResult; import org.prebid.server.hooks.v1.InvocationResultImpl; +import org.prebid.server.hooks.v1.InvocationResultUtils; import org.prebid.server.hooks.v1.InvocationStatus; import org.prebid.server.hooks.v1.analytics.ActivityImpl; import org.prebid.server.hooks.v1.analytics.AppliedToImpl; @@ -78,11 +81,12 @@ import org.prebid.server.model.Endpoint; import org.prebid.server.proto.openrtb.ext.response.BidType; import org.prebid.server.settings.model.Account; -import org.prebid.server.settings.model.AccountHooksAdminConfig; import org.prebid.server.settings.model.AccountHooksConfiguration; +import org.prebid.server.settings.model.HooksAdminConfig; import java.time.Clock; import java.time.ZoneOffset; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -153,7 +157,7 @@ public void creationShouldFailWhenHostExecutionPlanHasUnknownHook() { given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.ENTRYPOINT))) .willReturn(null); - givenEntrypointHook("module-beta", "hook-a", immediateHook(InvocationResultImpl.noAction())); + givenEntrypointHook("module-beta", "hook-a", immediateHook(InvocationResultUtils.noAction())); assertThatThrownBy(() -> createExecutor(hostPlan)) .isInstanceOf(IllegalArgumentException.class) @@ -176,7 +180,7 @@ public void creationShouldFailWhenDefaultAccountExecutionPlanHasUnknownHook() { given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.ENTRYPOINT))) .willReturn(null); - givenEntrypointHook("module-beta", "hook-a", immediateHook(InvocationResultImpl.noAction())); + givenEntrypointHook("module-beta", "hook-a", immediateHook(InvocationResultUtils.noAction())); assertThatThrownBy(() -> createExecutor(null, defaultAccountPlan)) .isInstanceOf(IllegalArgumentException.class) @@ -234,7 +238,7 @@ public void shouldExecuteEntrypointHooksHappyPath(VertxTestContext context) { givenEntrypointHook( "module-alpha", "hook-a", - immediateHook(InvocationResultImpl.succeeded( + immediateHook(InvocationResultUtils.succeeded( payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-abc"), "moduleAlphaContext"))); @@ -242,19 +246,19 @@ public void shouldExecuteEntrypointHooksHappyPath(VertxTestContext context) { givenEntrypointHook( "module-alpha", "hook-b", - delayedHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( + delayedHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-def")), 40)); givenEntrypointHook( "module-beta", "hook-a", - delayedHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( + delayedHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-ghi")), 80)); givenEntrypointHook( "module-beta", "hook-b", - immediateHook(InvocationResultImpl.succeeded( + immediateHook(InvocationResultUtils.succeeded( payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-jkl"), "moduleBetaContext"))); @@ -402,6 +406,70 @@ public void shouldBypassEntrypointHooksWhenNoPlanForStage(VertxTestContext conte })); } + @Test + public void shouldBypassEntrypointHooksThatAreDisabled(VertxTestContext context) { + // given + givenEntrypointHook( + "module-alpha", + "hook-a", + immediateHook(InvocationResultUtils.succeeded( + payload -> EntrypointPayloadImpl.of( + payload.queryParams(), payload.headers(), payload.body() + "-abc"), + "moduleAlphaContext"))); + + givenEntrypointHook( + "module-alpha", + "hook-b", + delayedHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( + payload.queryParams(), payload.headers(), payload.body() + "-def")), 40)); + + givenEntrypointHook( + "module-beta", + "hook-a", + delayedHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( + payload.queryParams(), payload.headers(), payload.body() + "-ghi")), 80)); + + givenEntrypointHook( + "module-beta", + "hook-b", + immediateHook(InvocationResultUtils.succeeded( + payload -> EntrypointPayloadImpl.of( + payload.queryParams(), payload.headers(), payload.body() + "-jkl"), + "moduleBetaContext"))); + + final HookStageExecutor executor = HookStageExecutor.create( + executionPlan(singletonMap( + Endpoint.openrtb2_auction, + EndpointExecutionPlan.of(singletonMap(Stage.entrypoint, execPlanTwoGroupsTwoHooksEach())))), + null, + Map.of("module-alpha", false), + hookCatalog, + timeoutFactory, + vertx, + clock, + jacksonMapper, + false); + + final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); + + // when + final Future> future = executor.executeEntrypointStage( + CaseInsensitiveMultiMap.empty(), + CaseInsensitiveMultiMap.empty(), + "body", + hookExecutionContext); + + // then + future.onComplete(context.succeeding(result -> { + assertThat(result).isNotNull(); + assertThat(result.isShouldReject()).isFalse(); + assertThat(result.getPayload()).isNotNull().satisfies(payload -> + assertThat(payload.body()).isEqualTo("body-ghi-jkl")); + + context.completeNow(); + })); + } + @Test public void shouldExecuteEntrypointHooksToleratingMisbehavingHooks(VertxTestContext context) { // given @@ -428,7 +496,7 @@ public void shouldExecuteEntrypointHooksToleratingMisbehavingHooks(VertxTestCont givenEntrypointHook( "module-beta", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-jkl")))); final HookStageExecutor executor = createExecutor( @@ -524,7 +592,7 @@ public void shouldExecuteEntrypointHooksToleratingTimeoutAndFailedFuture(VertxTe "module-alpha", "hook-b", delayedHook( - InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( + InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-def")), 250)); @@ -533,14 +601,14 @@ public void shouldExecuteEntrypointHooksToleratingTimeoutAndFailedFuture(VertxTe "module-beta", "hook-a", delayedHook( - InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( + InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-ghi")), 250)); givenEntrypointHook( "module-beta", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-jkl")))); final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); @@ -623,23 +691,23 @@ public void shouldExecuteEntrypointHooksHonoringStatusAndAction(VertxTestContext givenEntrypointHook( "module-alpha", "hook-a", - immediateHook(InvocationResultImpl.failed("Failed to contact service ACME"))); + immediateHook(InvocationResultUtils.failed("Failed to contact service ACME"))); givenEntrypointHook( "module-alpha", "hook-b", - immediateHook(InvocationResultImpl.noAction())); + immediateHook(InvocationResultUtils.noAction())); givenEntrypointHook( "module-beta", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-ghi")))); givenEntrypointHook( "module-beta", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-jkl")))); final HookStageExecutor executor = createExecutor( @@ -715,13 +783,13 @@ public void shouldExecuteEntrypointHooksWhenRequestIsRejectedByFirstGroup(VertxT givenEntrypointHook( "module-alpha", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-abc")))); givenEntrypointHook( "module-beta", "hook-a", - immediateHook(InvocationResultImpl.rejected("Request is of low quality"))); + immediateHook(InvocationResultUtils.rejected("Request is of low quality"))); final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( @@ -787,24 +855,24 @@ public void shouldExecuteEntrypointHooksWhenRequestIsRejectedBySecondGroup(Vertx givenEntrypointHook( "module-alpha", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-abc")))); givenEntrypointHook( "module-alpha", "hook-b", - immediateHook(InvocationResultImpl.rejected("Request is of low quality"))); + immediateHook(InvocationResultUtils.rejected("Request is of low quality"))); givenEntrypointHook( "module-beta", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-def")))); givenEntrypointHook( "module-beta", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), payload.headers(), payload.body() + "-jkl")))); final HookStageExecutor executor = createExecutor( @@ -903,7 +971,7 @@ public void shouldExecuteEntrypointHooksToleratingMisbehavingInvocationResult(Ve givenEntrypointHook( "module-beta", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> { + immediateHook(InvocationResultUtils.succeeded(payload -> { throw new RuntimeException("Can not alter payload"); }))); @@ -1045,7 +1113,7 @@ public void shouldExecuteEntrypointHooksAndStoreResultInExecutionContext(VertxTe public void shouldExecuteEntrypointHooksAndPassInvocationContext(VertxTestContext context) { // given final EntrypointHookImpl hookImpl = spy( - EntrypointHookImpl.of(immediateHook(InvocationResultImpl.succeeded(identity())))); + EntrypointHookImpl.of(immediateHook(InvocationResultUtils.succeeded(identity())))); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.ENTRYPOINT))) .willReturn(hookImpl); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-b"), eq(StageWithHookType.ENTRYPOINT))) @@ -1108,7 +1176,7 @@ public void shouldExecuteEntrypointHooksAndPassInvocationContext(VertxTestContex public void shouldExecuteRawAuctionRequestHooksWhenNoExecutionPlanInAccount(VertxTestContext context) { // given final RawAuctionRequestHookImpl hookImpl = spy( - RawAuctionRequestHookImpl.of(immediateHook(InvocationResultImpl.noAction()))); + RawAuctionRequestHookImpl.of(immediateHook(InvocationResultUtils.noAction()))); given(hookCatalog.hookById(anyString(), anyString(), eq(StageWithHookType.RAW_AUCTION_REQUEST))) .willReturn(hookImpl); @@ -1153,7 +1221,7 @@ public void shouldExecuteRawAuctionRequestHooksWhenNoExecutionPlanInAccount(Vert public void shouldExecuteRawAuctionRequestHooksWhenAccountOverridesExecutionPlan(VertxTestContext context) { // given final RawAuctionRequestHookImpl hookImpl = spy( - RawAuctionRequestHookImpl.of(immediateHook(InvocationResultImpl.noAction()))); + RawAuctionRequestHookImpl.of(immediateHook(InvocationResultUtils.noAction()))); given(hookCatalog.hookById(anyString(), anyString(), eq(StageWithHookType.RAW_AUCTION_REQUEST))) .willReturn(hookImpl); @@ -1216,7 +1284,7 @@ public void shouldExecuteRawAuctionRequestHooksToleratingUnknownHookInAccountPla givenRawAuctionRequestHook( "module-beta", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().id("id").build())))); final HookStageExecutor executor = createExecutor(null, null); @@ -1294,38 +1362,52 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsNotRequired givenRawAuctionRequestHook( "module-alpha", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().at(1).build())))); givenRawAuctionRequestHook( "module-beta", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().test(1).build())))); givenRawAuctionRequestHook( "module-gamma", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().id("id").build())))); givenRawAuctionRequestHook( "module-delta", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().tmax(1000L).build())))); + givenRawAuctionRequestHook( + "module-epsilon", + "hook-a", + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + payload.bidRequest().toBuilder().site(Site.builder().build()).build())))); + + givenRawAuctionRequestHook( + "module-zeta", + "hook-b", + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + payload.bidRequest().toBuilder().user(User.builder().build()).build())))); + final StageExecutionPlan stageExecutionPlan = StageExecutionPlan.of(asList( ExecutionGroup.of( 200L, asList( HookId.of("module-alpha", "hook-a"), - HookId.of("module-beta", "hook-a"))), + HookId.of("module-beta", "hook-a"), + HookId.of("module-epsilon", "hook-a"))), ExecutionGroup.of( 200L, asList( HookId.of("module-gamma", "hook-b"), - HookId.of("module-delta", "hook-b"))))); + HookId.of("module-delta", "hook-b"), + HookId.of("module-zeta", "hook-b"))))); final String hostExecutionPlan = executionPlan(singletonMap( Endpoint.openrtb2_auction, @@ -1334,6 +1416,7 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsNotRequired final HookStageExecutor executor = HookStageExecutor.create( hostExecutionPlan, null, + Map.of("module-epsilon", true, "module-zeta", false), hookCatalog, timeoutFactory, vertx, @@ -1354,9 +1437,13 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsNotRequired null, Map.of("module-alpha", mapper.createObjectNode(), "module-beta", mapper.createObjectNode(), - "module-gamma", mapper.createObjectNode()), - AccountHooksAdminConfig.builder() - .moduleExecution(Map.of("module-alpha", true, "module-beta", false)) + "module-gamma", mapper.createObjectNode(), + "module-zeta", mapper.createObjectNode()), + HooksAdminConfig.builder() + .moduleExecution(Map.of( + "module-alpha", true, + "module-beta", false, + "module-epsilon", false)) .build())) .build()) .hookExecutionContext(hookExecutionContext) @@ -1371,6 +1458,7 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsNotRequired .at(1) .id("id") .tmax(1000L) + .site(Site.builder().build()) .build())); assertThat(hookExecutionContext.getStageOutcomes()) @@ -1391,38 +1479,52 @@ public void shouldExecuteRawAuctionRequestHooksWhenAccountConfigIsRequired(Vertx givenRawAuctionRequestHook( "module-alpha", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().at(1).build())))); givenRawAuctionRequestHook( "module-beta", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().test(1).build())))); givenRawAuctionRequestHook( "module-gamma", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().id("id").build())))); givenRawAuctionRequestHook( "module-delta", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().tmax(1000L).build())))); + givenRawAuctionRequestHook( + "module-epsilon", + "hook-a", + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + payload.bidRequest().toBuilder().site(Site.builder().build()).build())))); + + givenRawAuctionRequestHook( + "module-zeta", + "hook-b", + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( + payload.bidRequest().toBuilder().user(User.builder().build()).build())))); + final StageExecutionPlan stageExecutionPlan = StageExecutionPlan.of(asList( ExecutionGroup.of( 200L, asList( HookId.of("module-alpha", "hook-a"), - HookId.of("module-beta", "hook-a"))), + HookId.of("module-beta", "hook-a"), + HookId.of("module-epsilon", "hook-a"))), ExecutionGroup.of( 200L, asList( HookId.of("module-gamma", "hook-b"), - HookId.of("module-delta", "hook-b"))))); + HookId.of("module-delta", "hook-b"), + HookId.of("module-zeta", "hook-b"))))); final String hostExecutionPlan = executionPlan(singletonMap( Endpoint.openrtb2_auction, @@ -1431,6 +1533,7 @@ public void shouldExecuteRawAuctionRequestHooksWhenAccountConfigIsRequired(Vertx final HookStageExecutor executor = HookStageExecutor.create( hostExecutionPlan, null, + Map.of("module-epsilon", true, "module-zeta", false), hookCatalog, timeoutFactory, vertx, @@ -1451,9 +1554,13 @@ public void shouldExecuteRawAuctionRequestHooksWhenAccountConfigIsRequired(Vertx null, Map.of("module-alpha", mapper.createObjectNode(), "module-beta", mapper.createObjectNode(), - "module-gamma", mapper.createObjectNode()), - AccountHooksAdminConfig.builder() - .moduleExecution(Map.of("module-alpha", true, "module-beta", false)) + "module-gamma", mapper.createObjectNode(), + "module-zeta", mapper.createObjectNode()), + HooksAdminConfig.builder() + .moduleExecution(Map.of( + "module-alpha", true, + "module-beta", false, + "module-epsilon", false)) .build())) .build()) .hookExecutionContext(hookExecutionContext) @@ -1467,6 +1574,7 @@ public void shouldExecuteRawAuctionRequestHooksWhenAccountConfigIsRequired(Vertx assertThat(payload.bidRequest()).isEqualTo(BidRequest.builder() .at(1) .id("id") + .site(Site.builder().build()) .build())); assertThat(hookExecutionContext.getStageOutcomes()) @@ -1487,25 +1595,25 @@ public void shouldExecuteRawAuctionRequestHooksHappyPath(VertxTestContext contex givenRawAuctionRequestHook( "module-alpha", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().at(1).build())))); givenRawAuctionRequestHook( "module-alpha", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().id("id").build())))); givenRawAuctionRequestHook( "module-beta", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().test(1).build())))); givenRawAuctionRequestHook( "module-beta", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().tmax(1000L).build())))); final HookStageExecutor executor = createExecutor( @@ -1553,7 +1661,7 @@ public void shouldExecuteRawAuctionRequestHooksHappyPath(VertxTestContext contex public void shouldExecuteRawAuctionRequestHooksAndPassAuctionInvocationContext(VertxTestContext context) { // given final RawAuctionRequestHookImpl hookImpl = spy( - RawAuctionRequestHookImpl.of(immediateHook(InvocationResultImpl.succeeded(identity())))); + RawAuctionRequestHookImpl.of(immediateHook(InvocationResultUtils.succeeded(identity())))); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.RAW_AUCTION_REQUEST))) .willReturn(hookImpl); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-b"), eq(StageWithHookType.RAW_AUCTION_REQUEST))) @@ -1726,7 +1834,7 @@ public void shouldExecuteRawAuctionRequestHooksWhenRequestIsRejected(VertxTestCo givenRawAuctionRequestHook( "module-alpha", "hook-a", - immediateHook(InvocationResultImpl.rejected("Request is no good"))); + immediateHook(InvocationResultUtils.rejected("Request is no good"))); final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( @@ -1759,25 +1867,25 @@ public void shouldExecuteProcessedAuctionRequestHooksHappyPath(VertxTestContext givenProcessedAuctionRequestHook( "module-alpha", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().at(1).build())))); givenProcessedAuctionRequestHook( "module-alpha", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().id("id").build())))); givenProcessedAuctionRequestHook( "module-beta", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().test(1).build())))); givenProcessedAuctionRequestHook( "module-beta", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of( payload.bidRequest().toBuilder().tmax(1000L).build())))); final HookStageExecutor executor = createExecutor( @@ -1826,7 +1934,7 @@ public void shouldExecuteProcessedAuctionRequestHooksHappyPath(VertxTestContext public void shouldExecuteProcessedAuctionRequestHooksAndPassAuctionInvocationContext(VertxTestContext context) { // given final ProcessedAuctionRequestHookImpl hookImpl = spy( - ProcessedAuctionRequestHookImpl.of(immediateHook(InvocationResultImpl.succeeded(identity())))); + ProcessedAuctionRequestHookImpl.of(immediateHook(InvocationResultUtils.succeeded(identity())))); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.PROCESSED_AUCTION_REQUEST))) .willReturn(hookImpl); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-b"), eq(StageWithHookType.PROCESSED_AUCTION_REQUEST))) @@ -2001,7 +2109,7 @@ public void shouldExecuteProcessedAuctionRequestHooksWhenRequestIsRejected(Vertx givenProcessedAuctionRequestHook( "module-alpha", "hook-a", - immediateHook(InvocationResultImpl.rejected("Request is no good"))); + immediateHook(InvocationResultUtils.rejected("Request is no good"))); final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( @@ -2037,25 +2145,25 @@ public void shouldExecuteBidderRequestHooksHappyPath(VertxTestContext context) { givenBidderRequestHook( "module-alpha", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> BidderRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> BidderRequestPayloadImpl.of( payload.bidRequest().toBuilder().at(1).build())))); givenBidderRequestHook( "module-alpha", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> BidderRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> BidderRequestPayloadImpl.of( payload.bidRequest().toBuilder().id("id").build())))); givenBidderRequestHook( "module-beta", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> BidderRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> BidderRequestPayloadImpl.of( payload.bidRequest().toBuilder().test(1).build())))); givenBidderRequestHook( "module-beta", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> BidderRequestPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> BidderRequestPayloadImpl.of( payload.bidRequest().toBuilder().tmax(1000L).build())))); final HookStageExecutor executor = createExecutor( @@ -2122,7 +2230,7 @@ public void shouldExecuteBidderRequestHooksHappyPath(VertxTestContext context) { public void shouldExecuteBidderRequestHooksAndPassBidderInvocationContext(VertxTestContext context) { // given final BidderRequestHookImpl hookImpl = spy( - BidderRequestHookImpl.of(immediateHook(InvocationResultImpl.succeeded(identity())))); + BidderRequestHookImpl.of(immediateHook(InvocationResultUtils.succeeded(identity())))); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.BIDDER_REQUEST))) .willReturn(hookImpl); @@ -2173,7 +2281,7 @@ public void shouldExecuteRawBidderResponseHooksHappyPath(VertxTestContext contex givenRawBidderResponseHook( "module-alpha", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> BidderResponsePayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> BidderResponsePayloadImpl.of( payload.bids().stream() .map(bid -> BidderBid.of( bid.getBid().toBuilder().id("bidId").build(), @@ -2184,7 +2292,7 @@ public void shouldExecuteRawBidderResponseHooksHappyPath(VertxTestContext contex givenRawBidderResponseHook( "module-alpha", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> BidderResponsePayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> BidderResponsePayloadImpl.of( payload.bids().stream() .map(bid -> BidderBid.of( bid.getBid().toBuilder().adid("adId").build(), @@ -2195,7 +2303,7 @@ public void shouldExecuteRawBidderResponseHooksHappyPath(VertxTestContext contex givenRawBidderResponseHook( "module-beta", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> BidderResponsePayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> BidderResponsePayloadImpl.of( payload.bids().stream() .map(bid -> BidderBid.of( bid.getBid().toBuilder().cid("cid").build(), @@ -2206,7 +2314,7 @@ public void shouldExecuteRawBidderResponseHooksHappyPath(VertxTestContext contex givenRawBidderResponseHook( "module-beta", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> BidderResponsePayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> BidderResponsePayloadImpl.of( payload.bids().stream() .map(bid -> BidderBid.of( bid.getBid().toBuilder().adm("adm").build(), @@ -2277,7 +2385,7 @@ public void shouldExecuteRawBidderResponseHooksHappyPath(VertxTestContext contex public void shouldExecuteRawBidderResponseHooksAndPassBidderInvocationContext(VertxTestContext context) { // given final RawBidderResponseHookImpl hookImpl = spy( - RawBidderResponseHookImpl.of(immediateHook(InvocationResultImpl.succeeded(identity())))); + RawBidderResponseHookImpl.of(immediateHook(InvocationResultUtils.succeeded(identity())))); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.RAW_BIDDER_RESPONSE))) .willReturn(hookImpl); @@ -2328,7 +2436,7 @@ public void shouldExecuteProcessedBidderResponseHooksHappyPath(VertxTestContext givenProcessedBidderResponseHook( "module-alpha", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> BidderResponsePayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> BidderResponsePayloadImpl.of( payload.bids().stream() .map(bid -> BidderBid.of( bid.getBid().toBuilder().id("bidId").build(), @@ -2339,7 +2447,7 @@ public void shouldExecuteProcessedBidderResponseHooksHappyPath(VertxTestContext givenProcessedBidderResponseHook( "module-alpha", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> BidderResponsePayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> BidderResponsePayloadImpl.of( payload.bids().stream() .map(bid -> BidderBid.of( bid.getBid().toBuilder().adid("adId").build(), @@ -2350,7 +2458,7 @@ public void shouldExecuteProcessedBidderResponseHooksHappyPath(VertxTestContext givenProcessedBidderResponseHook( "module-beta", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> BidderResponsePayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> BidderResponsePayloadImpl.of( payload.bids().stream() .map(bid -> BidderBid.of( bid.getBid().toBuilder().cid("cid").build(), @@ -2361,7 +2469,7 @@ public void shouldExecuteProcessedBidderResponseHooksHappyPath(VertxTestContext givenProcessedBidderResponseHook( "module-beta", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> BidderResponsePayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> BidderResponsePayloadImpl.of( payload.bids().stream() .map(bid -> BidderBid.of( bid.getBid().toBuilder().adm("adm").build(), @@ -2435,7 +2543,7 @@ public void shouldExecuteProcessedBidderResponseHooksHappyPath(VertxTestContext public void shouldExecuteProcessedBidderResponseHooksAndPassBidderInvocationContext(VertxTestContext context) { // given final ProcessedBidderResponseHookImpl hookImpl = spy( - ProcessedBidderResponseHookImpl.of(immediateHook(InvocationResultImpl.succeeded(identity())))); + ProcessedBidderResponseHookImpl.of(immediateHook(InvocationResultUtils.succeeded(identity())))); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.PROCESSED_BIDDER_RESPONSE))) .willReturn(hookImpl); @@ -2499,7 +2607,7 @@ public void shouldExecuteAllProcessedBidResponsesHooksHappyPath() { givenAllProcessedBidderResponsesHook( "module-alpha", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> AllProcessedBidResponsesPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AllProcessedBidResponsesPayloadImpl.of( payload.bidResponses().stream() .map(bidModifierForResponse.apply( (bidder, bid) -> BidderBid.of( @@ -2511,7 +2619,7 @@ public void shouldExecuteAllProcessedBidResponsesHooksHappyPath() { givenAllProcessedBidderResponsesHook( "module-alpha", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> AllProcessedBidResponsesPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AllProcessedBidResponsesPayloadImpl.of( payload.bidResponses().stream() .map(bidModifierForResponse.apply( (bidder, bid) -> BidderBid.of( @@ -2523,7 +2631,7 @@ public void shouldExecuteAllProcessedBidResponsesHooksHappyPath() { givenAllProcessedBidderResponsesHook( "module-beta", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> AllProcessedBidResponsesPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AllProcessedBidResponsesPayloadImpl.of( payload.bidResponses().stream() .map(bidModifierForResponse.apply( (bidder, bid) -> BidderBid.of( @@ -2535,7 +2643,7 @@ public void shouldExecuteAllProcessedBidResponsesHooksHappyPath() { givenAllProcessedBidderResponsesHook( "module-beta", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> AllProcessedBidResponsesPayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AllProcessedBidResponsesPayloadImpl.of( payload.bidResponses().stream() .map(bidModifierForResponse.apply( (bidder, bid) -> BidderBid.of( @@ -2600,7 +2708,7 @@ public void shouldExecuteAllProcessedBidResponsesHooksHappyPath() { public void shouldExecuteAllProcessedBidResponsesHooksAndPassAuctionInvocationContext(VertxTestContext context) { // given final AllProcessedBidResponsesHookImpl hookImpl = spy( - AllProcessedBidResponsesHookImpl.of(immediateHook(InvocationResultImpl.succeeded(identity())))); + AllProcessedBidResponsesHookImpl.of(immediateHook(InvocationResultUtils.succeeded(identity())))); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.ALL_PROCESSED_BID_RESPONSES))) .willReturn(hookImpl); @@ -2653,7 +2761,7 @@ public void shouldExecuteBidderRequestHooksWhenRequestIsRejected(VertxTestContex givenBidderRequestHook( "module-alpha", "hook-a", - immediateHook(InvocationResultImpl.rejected("Request is no good"))); + immediateHook(InvocationResultUtils.rejected("Request is no good"))); final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( @@ -2689,25 +2797,25 @@ public void shouldExecuteAuctionResponseHooksHappyPath(VertxTestContext context) givenAuctionResponseHook( "module-alpha", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionResponsePayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionResponsePayloadImpl.of( payload.bidResponse().toBuilder().id("id").build())))); givenAuctionResponseHook( "module-alpha", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionResponsePayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionResponsePayloadImpl.of( payload.bidResponse().toBuilder().bidid("bidid").build())))); givenAuctionResponseHook( "module-beta", "hook-a", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionResponsePayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionResponsePayloadImpl.of( payload.bidResponse().toBuilder().cur("cur").build())))); givenAuctionResponseHook( "module-beta", "hook-b", - immediateHook(InvocationResultImpl.succeeded(payload -> AuctionResponsePayloadImpl.of( + immediateHook(InvocationResultUtils.succeeded(payload -> AuctionResponsePayloadImpl.of( payload.bidResponse().toBuilder().nbr(1).build())))); final HookStageExecutor executor = createExecutor( @@ -2748,7 +2856,7 @@ public void shouldExecuteAuctionResponseHooksHappyPath(VertxTestContext context) public void shouldExecuteAuctionResponseHooksAndPassAuctionInvocationContext(VertxTestContext context) { // given final AuctionResponseHookImpl hookImpl = spy( - AuctionResponseHookImpl.of(immediateHook(InvocationResultImpl.succeeded(identity())))); + AuctionResponseHookImpl.of(immediateHook(InvocationResultUtils.succeeded(identity())))); given(hookCatalog.hookById(eq("module-alpha"), eq("hook-a"), eq(StageWithHookType.AUCTION_RESPONSE))) .willReturn(hookImpl); @@ -2795,7 +2903,7 @@ public void shouldExecuteAuctionResponseHooksAndIgnoreRejection(VertxTestContext givenAuctionResponseHook( "module-alpha", "hook-a", - immediateHook(InvocationResultImpl.rejected("Will not apply"))); + immediateHook(InvocationResultUtils.rejected("Will not apply"))); final HookStageExecutor executor = createExecutor( executionPlan(singletonMap( @@ -2988,6 +3096,7 @@ private HookStageExecutor createExecutor(String hostExecutionPlan, String defaul return HookStageExecutor.create( hostExecutionPlan, defaultAccountExecutionPlan, + Collections.emptyMap(), hookCatalog, timeoutFactory, vertx, diff --git a/src/test/java/org/prebid/server/hooks/v1/InvocationResultImpl.java b/src/test/java/org/prebid/server/hooks/v1/InvocationResultUtils.java similarity index 75% rename from src/test/java/org/prebid/server/hooks/v1/InvocationResultImpl.java rename to src/test/java/org/prebid/server/hooks/v1/InvocationResultUtils.java index 31426173e9c..ce3e9ca74cb 100644 --- a/src/test/java/org/prebid/server/hooks/v1/InvocationResultImpl.java +++ b/src/test/java/org/prebid/server/hooks/v1/InvocationResultUtils.java @@ -1,34 +1,10 @@ package org.prebid.server.hooks.v1; -import lombok.Builder; -import lombok.Value; -import lombok.experimental.Accessors; -import org.prebid.server.hooks.v1.analytics.Tags; +public class InvocationResultUtils { -import java.util.List; + private InvocationResultUtils() { -@Accessors(fluent = true) -@Builder -@Value -public class InvocationResultImpl implements InvocationResult { - - InvocationStatus status; - - String message; - - InvocationAction action; - - PayloadUpdate payloadUpdate; - - List errors; - - List warnings; - - List debugMessages; - - Object moduleContext; - - Tags analyticsTags; + } public static InvocationResult succeeded(PayloadUpdate payloadUpdate) { return InvocationResultImpl.builder() diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItAuctionResponseHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItAuctionResponseHook.java index 360e61fae47..8073a5edc27 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItAuctionResponseHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItAuctionResponseHook.java @@ -4,7 +4,7 @@ import io.vertx.core.Future; import org.prebid.server.hooks.execution.v1.auction.AuctionResponsePayloadImpl; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; +import org.prebid.server.hooks.v1.InvocationResultUtils; import org.prebid.server.hooks.v1.auction.AuctionInvocationContext; import org.prebid.server.hooks.v1.auction.AuctionResponseHook; import org.prebid.server.hooks.v1.auction.AuctionResponsePayload; @@ -19,7 +19,7 @@ public Future> call( final BidResponse updatedBidResponse = updateBidResponse(originalBidResponse); - return Future.succeededFuture(InvocationResultImpl.succeeded(payload -> + return Future.succeededFuture(InvocationResultUtils.succeeded(payload -> AuctionResponsePayloadImpl.of(payload.bidResponse().toBuilder() .seatbid(updatedBidResponse.getSeatbid()) .build()))); diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItBidderRequestHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItBidderRequestHook.java index 10af73e4d4f..4c95bcb5a7f 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItBidderRequestHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItBidderRequestHook.java @@ -5,7 +5,7 @@ import io.vertx.core.Future; import org.prebid.server.hooks.execution.v1.bidder.BidderRequestPayloadImpl; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; +import org.prebid.server.hooks.v1.InvocationResultUtils; import org.prebid.server.hooks.v1.bidder.BidderInvocationContext; import org.prebid.server.hooks.v1.bidder.BidderRequestHook; import org.prebid.server.hooks.v1.bidder.BidderRequestPayload; @@ -22,7 +22,7 @@ public Future> call( final BidRequest updatedBidRequest = updateBidRequest(originalBidRequest); - return Future.succeededFuture(InvocationResultImpl.succeeded(payload -> + return Future.succeededFuture(InvocationResultUtils.succeeded(payload -> BidderRequestPayloadImpl.of(payload.bidRequest().toBuilder() .imp(updatedBidRequest.getImp()) .build()))); diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItEntrypointHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItEntrypointHook.java index 36827bd39df..a4011db9106 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItEntrypointHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItEntrypointHook.java @@ -5,7 +5,7 @@ import org.prebid.server.hooks.execution.v1.entrypoint.EntrypointPayloadImpl; import org.prebid.server.hooks.v1.InvocationContext; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; +import org.prebid.server.hooks.v1.InvocationResultUtils; import org.prebid.server.hooks.v1.entrypoint.EntrypointHook; import org.prebid.server.hooks.v1.entrypoint.EntrypointPayload; import org.prebid.server.model.CaseInsensitiveMultiMap; @@ -18,7 +18,7 @@ public Future> call( final boolean rejectFlag = Boolean.parseBoolean(entrypointPayload.queryParams().get("sample-it-module-reject")); if (rejectFlag) { - return Future.succeededFuture(InvocationResultImpl.rejected("Rejected by sample entrypoint hook")); + return Future.succeededFuture(InvocationResultUtils.rejected("Rejected by sample entrypoint hook")); } return maybeUpdate(entrypointPayload); @@ -35,7 +35,7 @@ private Future> maybeUpdate(EntrypointPayloa ? updateBody(entrypointPayload.body()) : entrypointPayload.body(); - return Future.succeededFuture(InvocationResultImpl.succeeded(payload -> EntrypointPayloadImpl.of( + return Future.succeededFuture(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( payload.queryParams(), updatedHeaders, updatedBody))); diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItProcessedAuctionRequestHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItProcessedAuctionRequestHook.java index a285235f420..dca19dd6043 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItProcessedAuctionRequestHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItProcessedAuctionRequestHook.java @@ -6,7 +6,7 @@ import io.vertx.core.Future; import org.prebid.server.hooks.execution.v1.auction.AuctionRequestPayloadImpl; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; +import org.prebid.server.hooks.v1.InvocationResultUtils; import org.prebid.server.hooks.v1.auction.AuctionInvocationContext; import org.prebid.server.hooks.v1.auction.AuctionRequestPayload; import org.prebid.server.hooks.v1.auction.ProcessedAuctionRequestHook; @@ -29,7 +29,7 @@ public Future> call( final BidRequest updatedBidRequest = updateBidRequest(originalBidRequest); - return Future.succeededFuture(InvocationResultImpl.succeeded(payload -> + return Future.succeededFuture(InvocationResultUtils.succeeded(payload -> AuctionRequestPayloadImpl.of(payload.bidRequest().toBuilder() .ext(updatedBidRequest.getExt()) .build()))); diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItProcessedBidderResponseHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItProcessedBidderResponseHook.java index 3f8e9ee7ae2..b626e03d5ac 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItProcessedBidderResponseHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItProcessedBidderResponseHook.java @@ -4,7 +4,7 @@ import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.hooks.execution.v1.bidder.BidderResponsePayloadImpl; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; +import org.prebid.server.hooks.v1.InvocationResultUtils; import org.prebid.server.hooks.v1.bidder.BidderInvocationContext; import org.prebid.server.hooks.v1.bidder.BidderResponsePayload; import org.prebid.server.hooks.v1.bidder.ProcessedBidderResponseHook; @@ -21,7 +21,7 @@ public Future> call( final List updatedBids = updateBids(originalBids); - return Future.succeededFuture(InvocationResultImpl.succeeded(payload -> + return Future.succeededFuture(InvocationResultUtils.succeeded(payload -> BidderResponsePayloadImpl.of(updatedBids))); } diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItRawBidderResponseHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItRawBidderResponseHook.java index fb6d915717e..0f30527519b 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItRawBidderResponseHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItRawBidderResponseHook.java @@ -4,7 +4,7 @@ import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.hooks.execution.v1.bidder.BidderResponsePayloadImpl; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; +import org.prebid.server.hooks.v1.InvocationResultUtils; import org.prebid.server.hooks.v1.bidder.BidderInvocationContext; import org.prebid.server.hooks.v1.bidder.BidderResponsePayload; import org.prebid.server.hooks.v1.bidder.RawBidderResponseHook; @@ -21,7 +21,7 @@ public Future> call( final List updatedBids = updateBids(originalBids); - return Future.succeededFuture(InvocationResultImpl.succeeded(payload -> + return Future.succeededFuture(InvocationResultUtils.succeeded(payload -> BidderResponsePayloadImpl.of(updatedBids))); } diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingBidderRequestHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingBidderRequestHook.java index bd90a974936..d08303b93ce 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingBidderRequestHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingBidderRequestHook.java @@ -2,7 +2,7 @@ import io.vertx.core.Future; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; +import org.prebid.server.hooks.v1.InvocationResultUtils; import org.prebid.server.hooks.v1.bidder.BidderInvocationContext; import org.prebid.server.hooks.v1.bidder.BidderRequestHook; import org.prebid.server.hooks.v1.bidder.BidderRequestPayload; @@ -13,7 +13,7 @@ public class SampleItRejectingBidderRequestHook implements BidderRequestHook { public Future> call( BidderRequestPayload bidderRequestPayload, BidderInvocationContext invocationContext) { - return Future.succeededFuture(InvocationResultImpl.rejected("Rejected by rejecting bidder request hook")); + return Future.succeededFuture(InvocationResultUtils.rejected("Rejected by rejecting bidder request hook")); } @Override diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingProcessedAuctionRequestHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingProcessedAuctionRequestHook.java index b5feb3aaef9..5dfad73d026 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingProcessedAuctionRequestHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingProcessedAuctionRequestHook.java @@ -2,7 +2,7 @@ import io.vertx.core.Future; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; +import org.prebid.server.hooks.v1.InvocationResultUtils; import org.prebid.server.hooks.v1.auction.AuctionInvocationContext; import org.prebid.server.hooks.v1.auction.AuctionRequestPayload; import org.prebid.server.hooks.v1.auction.ProcessedAuctionRequestHook; @@ -13,7 +13,7 @@ public class SampleItRejectingProcessedAuctionRequestHook implements ProcessedAu public Future> call( AuctionRequestPayload auctionRequestPayload, AuctionInvocationContext invocationContext) { - return Future.succeededFuture(InvocationResultImpl.rejected( + return Future.succeededFuture(InvocationResultUtils.rejected( "Rejected by rejecting processed auction request hook")); } diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingProcessedBidderResponseHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingProcessedBidderResponseHook.java index a6f1438402c..d2c568837ca 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingProcessedBidderResponseHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingProcessedBidderResponseHook.java @@ -2,7 +2,7 @@ import io.vertx.core.Future; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; +import org.prebid.server.hooks.v1.InvocationResultUtils; import org.prebid.server.hooks.v1.bidder.BidderInvocationContext; import org.prebid.server.hooks.v1.bidder.BidderResponsePayload; import org.prebid.server.hooks.v1.bidder.ProcessedBidderResponseHook; @@ -13,7 +13,7 @@ public class SampleItRejectingProcessedBidderResponseHook implements ProcessedBi public Future> call( BidderResponsePayload bidderResponsePayload, BidderInvocationContext invocationContext) { - return Future.succeededFuture(InvocationResultImpl.rejected( + return Future.succeededFuture(InvocationResultUtils.rejected( "Rejected by rejecting processed bidder response hook")); } diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingRawAuctionRequestHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingRawAuctionRequestHook.java index 5532962afc2..d4eda0346ca 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingRawAuctionRequestHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingRawAuctionRequestHook.java @@ -2,7 +2,7 @@ import io.vertx.core.Future; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; +import org.prebid.server.hooks.v1.InvocationResultUtils; import org.prebid.server.hooks.v1.auction.AuctionInvocationContext; import org.prebid.server.hooks.v1.auction.AuctionRequestPayload; import org.prebid.server.hooks.v1.auction.RawAuctionRequestHook; @@ -13,7 +13,7 @@ public class SampleItRejectingRawAuctionRequestHook implements RawAuctionRequest public Future> call( AuctionRequestPayload auctionRequestPayload, AuctionInvocationContext invocationContext) { - return Future.succeededFuture(InvocationResultImpl.rejected("Rejected by rejecting raw auction request hook")); + return Future.succeededFuture(InvocationResultUtils.rejected("Rejected by rejecting raw auction request hook")); } @Override diff --git a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingRawBidderResponseHook.java b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingRawBidderResponseHook.java index 0eeeee4375c..f2964a9871a 100644 --- a/src/test/java/org/prebid/server/it/hooks/SampleItRejectingRawBidderResponseHook.java +++ b/src/test/java/org/prebid/server/it/hooks/SampleItRejectingRawBidderResponseHook.java @@ -2,7 +2,7 @@ import io.vertx.core.Future; import org.prebid.server.hooks.v1.InvocationResult; -import org.prebid.server.hooks.v1.InvocationResultImpl; +import org.prebid.server.hooks.v1.InvocationResultUtils; import org.prebid.server.hooks.v1.bidder.BidderInvocationContext; import org.prebid.server.hooks.v1.bidder.BidderResponsePayload; import org.prebid.server.hooks.v1.bidder.RawBidderResponseHook; @@ -13,7 +13,7 @@ public class SampleItRejectingRawBidderResponseHook implements RawBidderResponse public Future> call( BidderResponsePayload bidderResponsePayload, BidderInvocationContext invocationContext) { - return Future.succeededFuture(InvocationResultImpl.rejected("Rejected by rejecting raw bidder response hook")); + return Future.succeededFuture(InvocationResultUtils.rejected("Rejected by rejecting raw bidder response hook")); } @Override diff --git a/src/test/java/org/prebid/server/metric/MetricsTest.java b/src/test/java/org/prebid/server/metric/MetricsTest.java index bdab45b2670..f4943895116 100644 --- a/src/test/java/org/prebid/server/metric/MetricsTest.java +++ b/src/test/java/org/prebid/server/metric/MetricsTest.java @@ -1190,6 +1190,13 @@ public void updateHooksMetricsShouldIncrementMetrics() { "module1", Stage.entrypoint, "hook1", ExecutionStatus.success, 5L, ExecutionAction.update); metrics.updateHooksMetrics( "module1", Stage.raw_auction_request, "hook2", ExecutionStatus.success, 5L, ExecutionAction.no_action); + metrics.updateHooksMetrics( + "module1", + Stage.raw_auction_request, + "hook2", + ExecutionStatus.success, + 5L, + ExecutionAction.no_invocation); metrics.updateHooksMetrics( "module1", Stage.processed_auction_request, @@ -1202,7 +1209,7 @@ public void updateHooksMetricsShouldIncrementMetrics() { metrics.updateHooksMetrics( "module2", Stage.raw_bidder_response, "hook2", ExecutionStatus.timeout, 7L, null); metrics.updateHooksMetrics( - "module2", Stage.processed_bidder_response, "hook3", ExecutionStatus.execution_failure, 5L, null); + "module2", Stage.all_processed_bid_responses, "hook3", ExecutionStatus.execution_failure, 5L, null); metrics.updateHooksMetrics( "module2", Stage.auction_response, "hook4", ExecutionStatus.invocation_failure, 5L, null); @@ -1220,6 +1227,9 @@ public void updateHooksMetricsShouldIncrementMetrics() { .isEqualTo(1); assertThat(metricRegistry.counter("modules.module.module1.stage.rawauction.hook.hook2.success.noop").getCount()) .isEqualTo(1); + assertThat(metricRegistry.counter("modules.module.module1.stage.rawauction.hook.hook2.success.no-invocation") + .getCount()) + .isEqualTo(1); assertThat(metricRegistry.timer("modules.module.module1.stage.rawauction.hook.hook2.duration").getCount()) .isEqualTo(1); @@ -1245,12 +1255,14 @@ public void updateHooksMetricsShouldIncrementMetrics() { assertThat(metricRegistry.timer("modules.module.module2.stage.rawbidresponse.hook.hook2.duration").getCount()) .isEqualTo(1); - assertThat(metricRegistry.counter("modules.module.module2.stage.procbidresponse.hook.hook3.call").getCount()) + assertThat(metricRegistry.counter("modules.module.module2.stage.allprocbidresponses.hook.hook3.call") + .getCount()) .isEqualTo(1); - assertThat(metricRegistry.counter("modules.module.module2.stage.procbidresponse.hook.hook3.execution-error") + assertThat(metricRegistry.counter("modules.module.module2.stage.allprocbidresponses.hook.hook3.execution-error") .getCount()) .isEqualTo(1); - assertThat(metricRegistry.timer("modules.module.module2.stage.procbidresponse.hook.hook3.duration").getCount()) + assertThat(metricRegistry.timer("modules.module.module2.stage.allprocbidresponses.hook.hook3.duration") + .getCount()) .isEqualTo(1); assertThat(metricRegistry.counter("modules.module.module2.stage.auctionresponse.hook.hook4.call").getCount()) @@ -1274,6 +1286,8 @@ public void updateAccountHooksMetricsShouldIncrementMetricsIfVerbosityIsDetailed Account.empty("accountId"), "module2", ExecutionStatus.failure, null); metrics.updateAccountHooksMetrics( Account.empty("accountId"), "module3", ExecutionStatus.timeout, null); + metrics.updateAccountHooksMetrics( + Account.empty("accountId"), "module4", ExecutionStatus.success, ExecutionAction.no_invocation); // then assertThat(metricRegistry.counter("account.accountId.modules.module.module1.call").getCount()) @@ -1290,6 +1304,11 @@ public void updateAccountHooksMetricsShouldIncrementMetricsIfVerbosityIsDetailed .isEqualTo(1); assertThat(metricRegistry.counter("account.accountId.modules.module.module3.failure").getCount()) .isEqualTo(1); + + assertThat(metricRegistry.counter("account.accountId.modules.module.module4.call").getCount()) + .isEqualTo(0); + assertThat(metricRegistry.counter("account.accountId.modules.module.module4.success.no-invocation").getCount()) + .isEqualTo(1); } @Test From c606a74461411263eb28839aa2cbcb6381c4161c Mon Sep 17 00:00:00 2001 From: antonbabak Date: Fri, 29 Nov 2024 10:36:02 +0100 Subject: [PATCH 07/11] Add docs --- docs/application-settings.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/application-settings.md b/docs/application-settings.md index 7f164caa0dc..76215653977 100644 --- a/docs/application-settings.md +++ b/docs/application-settings.md @@ -101,6 +101,7 @@ Keep in mind following restrictions: - `cookie-sync.pri` - a list of prioritized bidder codes - `cookie-sync.coop-sync.default` - if the "coopSync" value isn't specified in the `/cookie_sync` request, use this - `hooks` - configuration for Prebid Server Modules. For further details, see: https://docs.prebid.org/prebid-server/pbs-modules/index.html#2-define-an-execution-plan +- `hooks.admin.module-execution` - a key-value map, where a key is a module name and a value is a boolean, that defines whether modules hooks should be always executed or not when they're in the execution plan; if the module is not specified it is executed by default - `settings.geo-lookup` - enables geo lookup for account if true. Defaults to false. Here are the definitions of the "purposes" that can be defined in the GDPR setting configurations: From 5c92bd40116125eea3aa8f84d36d74f404350bf7 Mon Sep 17 00:00:00 2001 From: antonbabak Date: Fri, 29 Nov 2024 13:51:35 +0100 Subject: [PATCH 08/11] Fix comments --- .../org/prebid/server/hooks/execution/HookStageExecutor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java b/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java index d3aaeaa28a1..1610fb1eb3e 100644 --- a/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java +++ b/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java @@ -291,7 +291,7 @@ private Map modulesExecutionForAccount(Account account) { final Map accountModulesExecution = Optional.ofNullable(account.getHooks()) .map(AccountHooksConfiguration::getAdmin) .map(HooksAdminConfig::getModuleExecution) - .orElseGet(Collections::emptyMap); + .orElse(Collections.emptyMap()); final Map resultModulesExecution = new HashMap<>(accountModulesExecution); From 9fd82e73b9a02adf1e1595d69783d65963c78544 Mon Sep 17 00:00:00 2001 From: antonbabak Date: Fri, 29 Nov 2024 15:08:03 +0100 Subject: [PATCH 09/11] Add docs --- docs/application-settings.md | 2 +- docs/config-app.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/application-settings.md b/docs/application-settings.md index 76215653977..2a20e0d8342 100644 --- a/docs/application-settings.md +++ b/docs/application-settings.md @@ -101,7 +101,7 @@ Keep in mind following restrictions: - `cookie-sync.pri` - a list of prioritized bidder codes - `cookie-sync.coop-sync.default` - if the "coopSync" value isn't specified in the `/cookie_sync` request, use this - `hooks` - configuration for Prebid Server Modules. For further details, see: https://docs.prebid.org/prebid-server/pbs-modules/index.html#2-define-an-execution-plan -- `hooks.admin.module-execution` - a key-value map, where a key is a module name and a value is a boolean, that defines whether modules hooks should be always executed or not when they're in the execution plan; if the module is not specified it is executed by default +- `hooks.admin.module-execution` - a key-value map, where a key is a module name and a value is a boolean, that defines whether modules hooks should/should not be always executed; if the module is not specified it is executed by default when it's present in the execution plan - `settings.geo-lookup` - enables geo lookup for account if true. Defaults to false. Here are the definitions of the "purposes" that can be defined in the GDPR setting configurations: diff --git a/docs/config-app.md b/docs/config-app.md index 40a2c42784e..4dcb5c072f7 100644 --- a/docs/config-app.md +++ b/docs/config-app.md @@ -439,6 +439,10 @@ If not defined in config all other Health Checkers would be disabled and endpoin - `analytics.pubstack.buffers.count` - threshold in events count for buffer to send events - `analytics.pubstack.buffers.report-ttl-ms` - max period between two reports. +## Modules +- `hooks.admin.module-execution` - a key-value map, where a key is a module name and a value is a boolean, that defines whether modules hooks should/should not be always executed; if the module is not specified it is executed by default when it's present in the execution plan +- `settings.modules.require-config-to-invoke` - when enabled it requires a runtime config to exist for a module. + ## Debugging - `debug.override-token` - special string token for overriding Prebid Server account and/or adapter debug information presence in the auction response. From a851984bd90db1c8ea8846c4016351993b0fce36 Mon Sep 17 00:00:00 2001 From: antonbabak Date: Tue, 3 Dec 2024 11:53:27 +0100 Subject: [PATCH 10/11] Remove host-level config --- docs/config-app.md | 7 +- .../server/hooks/execution/GroupExecutor.java | 2 +- .../hooks/execution/HookStageExecutor.java | 8 +- .../spring/config/HooksConfiguration.java | 8 -- .../execution/HookStageExecutorTest.java | 88 ++----------------- 5 files changed, 11 insertions(+), 102 deletions(-) diff --git a/docs/config-app.md b/docs/config-app.md index 4dcb5c072f7..37bb87462f6 100644 --- a/docs/config-app.md +++ b/docs/config-app.md @@ -369,6 +369,9 @@ contain 'WHERE last_updated > ?' for MySQL and 'WHERE last_updated > $1' for Pos For targeting available next options: - `settings.targeting.truncate-attr-chars` - set the max length for names of targeting keywords (0 means no truncation). +For modules: +- `settings.modules.require-config-to-invoke` - when enabled it requires a runtime config to exist for a module. + ## Host Cookie - `host-cookie.optout-cookie.name` - set the cookie name for optout checking. - `host-cookie.optout-cookie.value` - set the cookie value for optout checking. @@ -439,10 +442,6 @@ If not defined in config all other Health Checkers would be disabled and endpoin - `analytics.pubstack.buffers.count` - threshold in events count for buffer to send events - `analytics.pubstack.buffers.report-ttl-ms` - max period between two reports. -## Modules -- `hooks.admin.module-execution` - a key-value map, where a key is a module name and a value is a boolean, that defines whether modules hooks should/should not be always executed; if the module is not specified it is executed by default when it's present in the execution plan -- `settings.modules.require-config-to-invoke` - when enabled it requires a runtime config to exist for a module. - ## Debugging - `debug.override-token` - special string token for overriding Prebid Server account and/or adapter debug information presence in the auction response. diff --git a/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java b/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java index 2d8d33bef77..6ec0cc63095 100644 --- a/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java +++ b/src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java @@ -87,7 +87,7 @@ public Future> execute() { Future> groupFuture = Future.succeededFuture(initialGroupResult); for (final HookId hookId : group.getHookSequence()) { - if (!modulesExecution.get(hookId.getModuleCode())) { + if (!modulesExecution.getOrDefault(hookId.getModuleCode(), true)) { continue; } diff --git a/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java b/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java index 1610fb1eb3e..534205225b3 100644 --- a/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java +++ b/src/main/java/org/prebid/server/hooks/execution/HookStageExecutor.java @@ -70,7 +70,6 @@ public class HookStageExecutor { private final ExecutionPlan hostExecutionPlan; private final ExecutionPlan defaultAccountExecutionPlan; - private final Map hostModuleExecution; private final HookCatalog hookCatalog; private final TimeoutFactory timeoutFactory; private final Vertx vertx; @@ -79,7 +78,6 @@ public class HookStageExecutor { private HookStageExecutor(ExecutionPlan hostExecutionPlan, ExecutionPlan defaultAccountExecutionPlan, - Map hostModuleExecution, HookCatalog hookCatalog, TimeoutFactory timeoutFactory, Vertx vertx, @@ -93,12 +91,10 @@ private HookStageExecutor(ExecutionPlan hostExecutionPlan, this.vertx = vertx; this.clock = clock; this.isConfigToInvokeRequired = isConfigToInvokeRequired; - this.hostModuleExecution = hostModuleExecution; } public static HookStageExecutor create(String hostExecutionPlan, String defaultAccountExecutionPlan, - Map hostModuleExecution, HookCatalog hookCatalog, TimeoutFactory timeoutFactory, Vertx vertx, @@ -112,7 +108,6 @@ public static HookStageExecutor create(String hostExecutionPlan, Objects.requireNonNull(mapper), Objects.requireNonNull(hookCatalog)), parseAndValidateExecutionPlan(defaultAccountExecutionPlan, mapper, hookCatalog), - hostModuleExecution, hookCatalog, Objects.requireNonNull(timeoutFactory), Objects.requireNonNull(vertx), @@ -132,7 +127,7 @@ public Future> executeEntrypointStag .withExecutionPlan(planForEntrypointStage(endpoint)) .withInitialPayload(EntrypointPayloadImpl.of(queryParams, headers, body)) .withInvocationContextProvider(invocationContextProvider(endpoint)) - .withModulesExecution(DefaultedMap.defaultedMap(hostModuleExecution, true)) + .withModulesExecution(Collections.emptyMap()) .withRejectAllowed(true) .execute(); } @@ -304,7 +299,6 @@ private Map modulesExecutionForAccount(Account account) { .forEach(module -> resultModulesExecution.computeIfAbsent(module, key -> true)); } - resultModulesExecution.putAll(hostModuleExecution); return DefaultedMap.defaultedMap(resultModulesExecution, !isConfigToInvokeRequired); } diff --git a/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java b/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java index 5a05ccb8c8e..64534d119aa 100644 --- a/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/HooksConfiguration.java @@ -8,7 +8,6 @@ import org.prebid.server.hooks.execution.HookStageExecutor; import org.prebid.server.hooks.v1.Module; import org.prebid.server.json.JacksonMapper; -import org.prebid.server.settings.model.HooksAdminConfig; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; @@ -17,8 +16,6 @@ import java.time.Clock; import java.util.Collection; -import java.util.Collections; -import java.util.Optional; @Configuration public class HooksConfiguration { @@ -41,9 +38,6 @@ HookStageExecutor hookStageExecutor(HooksConfigurationProperties hooksConfigurat return HookStageExecutor.create( hooksConfiguration.getHostExecutionPlan(), hooksConfiguration.getDefaultAccountExecutionPlan(), - Optional.ofNullable(hooksConfiguration.getAdmin()) - .map(HooksAdminConfig::getModuleExecution) - .orElseGet(Collections::emptyMap), hookCatalog, timeoutFactory, vertx, @@ -66,7 +60,5 @@ private static class HooksConfigurationProperties { String hostExecutionPlan; String defaultAccountExecutionPlan; - - HooksAdminConfig admin; } } diff --git a/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java b/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java index bfc009e760a..6bcbe818fec 100644 --- a/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java +++ b/src/test/java/org/prebid/server/hooks/execution/HookStageExecutorTest.java @@ -86,7 +86,6 @@ import java.time.Clock; import java.time.ZoneOffset; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -406,70 +405,6 @@ public void shouldBypassEntrypointHooksWhenNoPlanForStage(VertxTestContext conte })); } - @Test - public void shouldBypassEntrypointHooksThatAreDisabled(VertxTestContext context) { - // given - givenEntrypointHook( - "module-alpha", - "hook-a", - immediateHook(InvocationResultUtils.succeeded( - payload -> EntrypointPayloadImpl.of( - payload.queryParams(), payload.headers(), payload.body() + "-abc"), - "moduleAlphaContext"))); - - givenEntrypointHook( - "module-alpha", - "hook-b", - delayedHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( - payload.queryParams(), payload.headers(), payload.body() + "-def")), 40)); - - givenEntrypointHook( - "module-beta", - "hook-a", - delayedHook(InvocationResultUtils.succeeded(payload -> EntrypointPayloadImpl.of( - payload.queryParams(), payload.headers(), payload.body() + "-ghi")), 80)); - - givenEntrypointHook( - "module-beta", - "hook-b", - immediateHook(InvocationResultUtils.succeeded( - payload -> EntrypointPayloadImpl.of( - payload.queryParams(), payload.headers(), payload.body() + "-jkl"), - "moduleBetaContext"))); - - final HookStageExecutor executor = HookStageExecutor.create( - executionPlan(singletonMap( - Endpoint.openrtb2_auction, - EndpointExecutionPlan.of(singletonMap(Stage.entrypoint, execPlanTwoGroupsTwoHooksEach())))), - null, - Map.of("module-alpha", false), - hookCatalog, - timeoutFactory, - vertx, - clock, - jacksonMapper, - false); - - final HookExecutionContext hookExecutionContext = HookExecutionContext.of(Endpoint.openrtb2_auction); - - // when - final Future> future = executor.executeEntrypointStage( - CaseInsensitiveMultiMap.empty(), - CaseInsensitiveMultiMap.empty(), - "body", - hookExecutionContext); - - // then - future.onComplete(context.succeeding(result -> { - assertThat(result).isNotNull(); - assertThat(result.isShouldReject()).isFalse(); - assertThat(result.getPayload()).isNotNull().satisfies(payload -> - assertThat(payload.body()).isEqualTo("body-ghi-jkl")); - - context.completeNow(); - })); - } - @Test public void shouldExecuteEntrypointHooksToleratingMisbehavingHooks(VertxTestContext context) { // given @@ -1400,14 +1335,12 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsNotRequired 200L, asList( HookId.of("module-alpha", "hook-a"), - HookId.of("module-beta", "hook-a"), - HookId.of("module-epsilon", "hook-a"))), + HookId.of("module-beta", "hook-a"))), ExecutionGroup.of( 200L, asList( HookId.of("module-gamma", "hook-b"), - HookId.of("module-delta", "hook-b"), - HookId.of("module-zeta", "hook-b"))))); + HookId.of("module-delta", "hook-b"))))); final String hostExecutionPlan = executionPlan(singletonMap( Endpoint.openrtb2_auction, @@ -1416,7 +1349,6 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsNotRequired final HookStageExecutor executor = HookStageExecutor.create( hostExecutionPlan, null, - Map.of("module-epsilon", true, "module-zeta", false), hookCatalog, timeoutFactory, vertx, @@ -1437,13 +1369,11 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsNotRequired null, Map.of("module-alpha", mapper.createObjectNode(), "module-beta", mapper.createObjectNode(), - "module-gamma", mapper.createObjectNode(), - "module-zeta", mapper.createObjectNode()), + "module-gamma", mapper.createObjectNode()), HooksAdminConfig.builder() .moduleExecution(Map.of( "module-alpha", true, - "module-beta", false, - "module-epsilon", false)) + "module-beta", false)) .build())) .build()) .hookExecutionContext(hookExecutionContext) @@ -1458,7 +1388,6 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsNotRequired .at(1) .id("id") .tmax(1000L) - .site(Site.builder().build()) .build())); assertThat(hookExecutionContext.getStageOutcomes()) @@ -1533,7 +1462,6 @@ public void shouldExecuteRawAuctionRequestHooksWhenAccountConfigIsRequired(Vertx final HookStageExecutor executor = HookStageExecutor.create( hostExecutionPlan, null, - Map.of("module-epsilon", true, "module-zeta", false), hookCatalog, timeoutFactory, vertx, @@ -1554,13 +1482,11 @@ public void shouldExecuteRawAuctionRequestHooksWhenAccountConfigIsRequired(Vertx null, Map.of("module-alpha", mapper.createObjectNode(), "module-beta", mapper.createObjectNode(), - "module-gamma", mapper.createObjectNode(), - "module-zeta", mapper.createObjectNode()), + "module-gamma", mapper.createObjectNode()), HooksAdminConfig.builder() .moduleExecution(Map.of( "module-alpha", true, - "module-beta", false, - "module-epsilon", false)) + "module-beta", false)) .build())) .build()) .hookExecutionContext(hookExecutionContext) @@ -1574,7 +1500,6 @@ public void shouldExecuteRawAuctionRequestHooksWhenAccountConfigIsRequired(Vertx assertThat(payload.bidRequest()).isEqualTo(BidRequest.builder() .at(1) .id("id") - .site(Site.builder().build()) .build())); assertThat(hookExecutionContext.getStageOutcomes()) @@ -3096,7 +3021,6 @@ private HookStageExecutor createExecutor(String hostExecutionPlan, String defaul return HookStageExecutor.create( hostExecutionPlan, defaultAccountExecutionPlan, - Collections.emptyMap(), hookCatalog, timeoutFactory, vertx, From 1b6365fccbbf51107bab2e5b4a547db1af4db6dc Mon Sep 17 00:00:00 2001 From: osulzhenko <125548596+osulzhenko@users.noreply.github.com> Date: Wed, 4 Dec 2024 12:51:29 +0200 Subject: [PATCH 11/11] Functional tests for module execution host config check (#3589) * Functional tests for module execution host config check --- .../config/AccountHooksConfiguration.groovy | 1 + .../model/config/AdminConfig.groovy | 13 + .../response/auction/TraceOutcome.groovy | 3 +- .../tests/module/GeneralModuleSpec.groovy | 381 ++++++++++++++---- 4 files changed, 322 insertions(+), 76 deletions(-) create mode 100644 src/test/groovy/org/prebid/server/functional/model/config/AdminConfig.groovy diff --git a/src/test/groovy/org/prebid/server/functional/model/config/AccountHooksConfiguration.groovy b/src/test/groovy/org/prebid/server/functional/model/config/AccountHooksConfiguration.groovy index 24f3ab97d77..bab4ec983a3 100644 --- a/src/test/groovy/org/prebid/server/functional/model/config/AccountHooksConfiguration.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/config/AccountHooksConfiguration.groovy @@ -13,4 +13,5 @@ class AccountHooksConfiguration { @JsonProperty("execution_plan") ExecutionPlan executionPlanSnakeCase PbsModulesConfig modules + AdminConfig admin } diff --git a/src/test/groovy/org/prebid/server/functional/model/config/AdminConfig.groovy b/src/test/groovy/org/prebid/server/functional/model/config/AdminConfig.groovy new file mode 100644 index 00000000000..755a47bcbaa --- /dev/null +++ b/src/test/groovy/org/prebid/server/functional/model/config/AdminConfig.groovy @@ -0,0 +1,13 @@ +package org.prebid.server.functional.model.config + +import com.fasterxml.jackson.databind.PropertyNamingStrategies +import com.fasterxml.jackson.databind.annotation.JsonNaming +import groovy.transform.ToString +import org.prebid.server.functional.model.ModuleName + +@ToString(includeNames = true, ignoreNulls = true) +@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy) +class AdminConfig { + + Map moduleExecution +} diff --git a/src/test/groovy/org/prebid/server/functional/model/response/auction/TraceOutcome.groovy b/src/test/groovy/org/prebid/server/functional/model/response/auction/TraceOutcome.groovy index f1a72a9e266..0f155bf55a1 100644 --- a/src/test/groovy/org/prebid/server/functional/model/response/auction/TraceOutcome.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/response/auction/TraceOutcome.groovy @@ -3,13 +3,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 -import org.prebid.server.functional.model.config.Stage @ToString(includeNames = true, ignoreNulls = true) @JsonNaming(PropertyNamingStrategies.LowerCaseStrategy) class TraceOutcome { - Stage entity + String entity Long executionTimeMillis List groups } diff --git a/src/test/groovy/org/prebid/server/functional/tests/module/GeneralModuleSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/module/GeneralModuleSpec.groovy index fa2929665a6..15aab0a3e2f 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/module/GeneralModuleSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/module/GeneralModuleSpec.groovy @@ -1,40 +1,53 @@ package org.prebid.server.functional.tests.module +import org.prebid.server.functional.model.ModuleName import org.prebid.server.functional.model.config.AccountConfig import org.prebid.server.functional.model.config.AccountHooksConfiguration +import org.prebid.server.functional.model.config.AdminConfig import org.prebid.server.functional.model.config.ExecutionPlan +import org.prebid.server.functional.model.config.Ortb2BlockingConfig import org.prebid.server.functional.model.config.PbResponseCorrection import org.prebid.server.functional.model.config.PbsModulesConfig +import org.prebid.server.functional.model.config.Stage import org.prebid.server.functional.model.db.Account import org.prebid.server.functional.model.request.auction.RichmediaFilter import org.prebid.server.functional.model.request.auction.TraceLevel import org.prebid.server.functional.model.response.auction.InvocationResult import org.prebid.server.functional.service.PrebidServerService import org.prebid.server.functional.util.PBSUtils +import spock.lang.PendingFeature -import static org.prebid.server.functional.model.ModuleName.PB_RESPONSE_CORRECTION +import static org.prebid.server.functional.model.ModuleName.ORTB2_BLOCKING import static org.prebid.server.functional.model.ModuleName.PB_RICHMEDIA_FILTER import static org.prebid.server.functional.model.config.Endpoint.OPENRTB2_AUCTION +import static org.prebid.server.functional.model.config.ModuleHookImplementation.ORTB2_BLOCKING_BIDDER_REQUEST +import static org.prebid.server.functional.model.config.ModuleHookImplementation.ORTB2_BLOCKING_RAW_BIDDER_RESPONSE import static org.prebid.server.functional.model.config.ModuleHookImplementation.PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES -import static org.prebid.server.functional.model.config.ModuleHookImplementation.RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES import static org.prebid.server.functional.model.config.Stage.ALL_PROCESSED_BID_RESPONSES +import static org.prebid.server.functional.model.config.Stage.BIDDER_REQUEST +import static org.prebid.server.functional.model.config.Stage.RAW_BIDDER_RESPONSE import static org.prebid.server.functional.model.request.auction.BidRequest.getDefaultBidRequest import static org.prebid.server.functional.model.response.auction.InvocationStatus.SUCCESS import static org.prebid.server.functional.model.response.auction.ResponseAction.NO_ACTION -import static org.prebid.server.functional.model.response.auction.ResponseAction.NO_INVOCATION class GeneralModuleSpec extends ModuleBaseSpec { - private final static String NO_INVOCATION_METRIC = "modules.module.%s.stage.%s.hook.%s.success.no-invocation" private final static String CALL_METRIC = "modules.module.%s.stage.%s.hook.%s.call" + private final static String NOOP_METRIC = "modules.module.%s.stage.%s.hook.%s.success.noop" private final static Map DISABLED_INVOKE_CONFIG = ['settings.modules.require-config-to-invoke': 'false'] private final static Map ENABLED_INVOKE_CONFIG = ['settings.modules.require-config-to-invoke': 'true'] - private final static Map MULTY_MODULE_CONFIG = getRichMediaFilterSettings(PBSUtils.randomString) + getResponseCorrectionConfig() + - ['hooks.host-execution-plan': encode(ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, [(ALL_PROCESSED_BID_RESPONSES): [PB_RICHMEDIA_FILTER, PB_RESPONSE_CORRECTION]]))] - private final static PrebidServerService pbsServiceWithMultipleModule = pbsServiceFactory.getService(MULTY_MODULE_CONFIG + DISABLED_INVOKE_CONFIG) - private final static PrebidServerService pbsServiceWithMultipleModuleWithRequireInvoke = pbsServiceFactory.getService(MULTY_MODULE_CONFIG + ENABLED_INVOKE_CONFIG) + private final static Map> ORTB_STAGES = [(BIDDER_REQUEST) : [ORTB2_BLOCKING], + (RAW_BIDDER_RESPONSE): [ORTB2_BLOCKING]] + private final static Map> RESPONSE_STAGES = [(ALL_PROCESSED_BID_RESPONSES): [PB_RICHMEDIA_FILTER]] + private final static Map> MODULES_STAGES = ORTB_STAGES + RESPONSE_STAGES + private final static Map MULTI_MODULE_CONFIG = getRichMediaFilterSettings(PBSUtils.randomString) + + getOrtb2BlockingSettings() + + ['hooks.host-execution-plan': encode(ExecutionPlan.getSingleEndpointExecutionPlan(OPENRTB2_AUCTION, MODULES_STAGES))] + + private final static PrebidServerService pbsServiceWithMultipleModule = pbsServiceFactory.getService(MULTI_MODULE_CONFIG + DISABLED_INVOKE_CONFIG) + private final static PrebidServerService pbsServiceWithMultipleModuleWithRequireInvoke = pbsServiceFactory.getService(MULTI_MODULE_CONFIG + ENABLED_INVOKE_CONFIG) def "PBS should call all modules and traces response when account config is empty and require-config-to-invoke is disabled"() { given: "Default bid request with verbose trace" @@ -55,19 +68,21 @@ class GeneralModuleSpec extends ModuleBaseSpec { then: "PBS response should include trace information about called modules" verifyAll(response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List) { - it.status == [SUCCESS, SUCCESS] - it.action == [NO_ACTION, NO_ACTION] - it.hookId.moduleCode.sort() == [PB_RICHMEDIA_FILTER, PB_RESPONSE_CORRECTION].code.sort() + it.status == [SUCCESS, SUCCESS, SUCCESS] + it.action == [NO_ACTION, NO_ACTION, NO_ACTION] + it.hookId.moduleCode.sort() == [ORTB2_BLOCKING, ORTB2_BLOCKING, PB_RICHMEDIA_FILTER].code.sort() } - and: "no-invocation metrics shouldn't be updated" + and: "Ortb2blocking module call metrics should be updated" def metrics = pbsServiceWithMultipleModule.sendCollectedMetricsRequest() - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] + assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 + assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 + assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - and: "hook call metrics should be updated" + and: "RB-Richmedia-Filter module call metrics should be updated" assert metrics[CALL_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 - assert metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 + assert metrics[NOOP_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 where: modulesConfig << [null, new PbsModulesConfig()] @@ -93,19 +108,21 @@ class GeneralModuleSpec extends ModuleBaseSpec { then: "PBS response should include trace information about called modules" verifyAll(response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List) { - it.status == [SUCCESS, SUCCESS] - it.action == [NO_ACTION, NO_ACTION] - it.hookId.moduleCode.sort() == [PB_RICHMEDIA_FILTER, PB_RESPONSE_CORRECTION].code.sort() + it.status == [SUCCESS, SUCCESS, SUCCESS] + it.action == [NO_ACTION, NO_ACTION, NO_ACTION] + it.hookId.moduleCode.sort() == [PB_RICHMEDIA_FILTER, ORTB2_BLOCKING, ORTB2_BLOCKING].code.sort() } - and: "no-invocation metrics shouldn't be updated" + and: "Ortb2blocking module call metrics should be updated" def metrics = pbsServiceWithMultipleModule.sendCollectedMetricsRequest() - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] + assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 + assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 + assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - and: "hook call metrics should be updated" + and: "RB-Richmedia-Filter module call metrics should be updated" assert metrics[CALL_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 - assert metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 + assert metrics[NOOP_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 where: pbRichmediaFilterConfig | pbResponseCorrectionConfig @@ -116,41 +133,47 @@ class GeneralModuleSpec extends ModuleBaseSpec { new RichmediaFilter(filterMraid: true) | new PbResponseCorrection(enabled: true) } - def "PBS shouldn't call any modules and traces that in response when account config is empty and require-config-to-invoke is enabled"() { - given: "Default bid request with verbose trace" + def "PBS should call all modules and traces response when default-account includes modules config and require-config-to-invoke is enabled"() { + given: "PBS service with module config" + def pbsModulesConfig = new PbsModulesConfig(pbRichmediaFilter: new RichmediaFilter(), ortb2Blocking: new Ortb2BlockingConfig()) + def defaultAccountConfigSettings = AccountConfig.defaultAccountConfig.tap { + hooks = new AccountHooksConfiguration(modules: pbsModulesConfig) + } + + def pbsConfig = MULTI_MODULE_CONFIG + ENABLED_INVOKE_CONFIG + ["settings.default-account-config": encode(defaultAccountConfigSettings)] + def pbsServiceWithMultipleModules = pbsServiceFactory.getService(pbsConfig) + + and: "Default bid request with verbose trace" def bidRequest = defaultBidRequest.tap { ext.prebid.trace = TraceLevel.VERBOSE } - and: "Save account without modules config" - def accountConfig = new AccountConfig(hooks: new AccountHooksConfiguration(modules: modulesConfig)) - def account = new Account(uuid: bidRequest.getAccountId(), config: accountConfig) - accountDao.save(account) - and: "Flush metrics" - flushMetrics(pbsServiceWithMultipleModuleWithRequireInvoke) + flushMetrics(pbsServiceWithMultipleModules) when: "PBS processes auction request" - def response = pbsServiceWithMultipleModuleWithRequireInvoke.sendAuctionRequest(bidRequest) + def response = pbsServiceWithMultipleModules.sendAuctionRequest(bidRequest) - then: "PBS response should include trace information about no-called modules" + then: "PBS response should include trace information about called modules" verifyAll(response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List) { - it.status == [SUCCESS, SUCCESS] - it.action == [NO_INVOCATION, NO_INVOCATION] - it.hookId.moduleCode.sort() == [PB_RICHMEDIA_FILTER, PB_RESPONSE_CORRECTION].code.sort() + it.status == [SUCCESS, SUCCESS, SUCCESS] + it.action == [NO_ACTION, NO_ACTION, NO_ACTION] + it.hookId.moduleCode.sort() == [PB_RICHMEDIA_FILTER, ORTB2_BLOCKING, ORTB2_BLOCKING].code.sort() } - and: "no-invocation metrics should be updated" - def metrics = pbsServiceWithMultipleModuleWithRequireInvoke.sendCollectedMetricsRequest() - assert metrics[NO_INVOCATION_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 - assert metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 + and: "Ortb2blocking module call metrics should be updated" + def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() + assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 + assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 + assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - and: "hook call metrics shouldn't be updated" - assert !metrics[CALL_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] - assert !metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] + and: "RB-Richmedia-Filter module call metrics should be updated" + assert metrics[CALL_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 + assert metrics[NOOP_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 - where: - modulesConfig << [null, new PbsModulesConfig()] + cleanup: "Stop and remove pbs container" + pbsServiceFactory.removeContainer(pbsConfig) } def "PBS should call all modules and traces response when account includes modules config and require-config-to-invoke is enabled"() { @@ -160,7 +183,7 @@ class GeneralModuleSpec extends ModuleBaseSpec { } and: "Save account with enabled response correction module" - def pbsModulesConfig = new PbsModulesConfig(pbRichmediaFilter: pbRichmediaFilterConfig, pbResponseCorrection: pbResponseCorrectionConfig) + def pbsModulesConfig = new PbsModulesConfig(pbRichmediaFilter: pbRichmediaFilterConfig, ortb2Blocking: ortb2BlockingConfig) def accountConfig = new AccountConfig(hooks: new AccountHooksConfiguration(modules: pbsModulesConfig)) def account = new Account(uuid: bidRequest.getAccountId(), config: accountConfig) accountDao.save(account) @@ -173,27 +196,29 @@ class GeneralModuleSpec extends ModuleBaseSpec { then: "PBS response should include trace information about called modules" verifyAll(response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List) { - it.status == [SUCCESS, SUCCESS] - it.action == [NO_ACTION, NO_ACTION] - it.hookId.moduleCode.sort() == [PB_RICHMEDIA_FILTER, PB_RESPONSE_CORRECTION].code.sort() + it.status == [SUCCESS, SUCCESS, SUCCESS] + it.action == [NO_ACTION, NO_ACTION, NO_ACTION] + it.hookId.moduleCode.sort() == [PB_RICHMEDIA_FILTER, ORTB2_BLOCKING, ORTB2_BLOCKING].code.sort() } - and: "no-invocation metrics shouldn't be updated" + and: "Ortb2blocking module call metrics should be updated" def metrics = pbsServiceWithMultipleModuleWithRequireInvoke.sendCollectedMetricsRequest() - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] + assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 + assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 + assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 - and: "hook call metrics should be updated" + and: "RB-Richmedia-Filter module call metrics should be updated" assert metrics[CALL_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 - assert metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 + assert metrics[NOOP_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 where: - pbRichmediaFilterConfig | pbResponseCorrectionConfig - new RichmediaFilter() | new PbResponseCorrection() - new RichmediaFilter() | new PbResponseCorrection(enabled: false) - new RichmediaFilter() | new PbResponseCorrection(enabled: true) - new RichmediaFilter(filterMraid: true) | new PbResponseCorrection() - new RichmediaFilter(filterMraid: true) | new PbResponseCorrection(enabled: true) + pbRichmediaFilterConfig | ortb2BlockingConfig + new RichmediaFilter() | new Ortb2BlockingConfig() + new RichmediaFilter() | new Ortb2BlockingConfig(attributes: [:] as Map) + new RichmediaFilter() | new Ortb2BlockingConfig(attributes: [:] as Map) + new RichmediaFilter(filterMraid: true) | new Ortb2BlockingConfig() + new RichmediaFilter(filterMraid: true) | new Ortb2BlockingConfig(attributes: [:] as Map) } def "PBS should call specified module and traces response when account config includes that module and require-config-to-invoke is enabled"() { @@ -203,7 +228,7 @@ class GeneralModuleSpec extends ModuleBaseSpec { } and: "Save account with enabled response correction module" - def accountConfig = new AccountConfig(hooks: new AccountHooksConfiguration(modules: new PbsModulesConfig(pbResponseCorrection: new PbResponseCorrection()))) + def accountConfig = new AccountConfig(hooks: new AccountHooksConfiguration(modules: new PbsModulesConfig(pbRichmediaFilter: new RichmediaFilter()))) def account = new Account(uuid: bidRequest.getAccountId(), config: accountConfig) accountDao.save(account) @@ -215,26 +240,234 @@ class GeneralModuleSpec extends ModuleBaseSpec { then: "PBS response should include trace information about called module" def invocationTrace = response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List - verifyAll(invocationTrace.findAll { it -> it.hookId.moduleCode == PB_RESPONSE_CORRECTION.code }) { + verifyAll(invocationTrace.findAll { it -> it.hookId.moduleCode == PB_RICHMEDIA_FILTER.code }) { it.status == [SUCCESS] it.action == [NO_ACTION] - it.hookId.moduleCode.sort() == [PB_RESPONSE_CORRECTION].code.sort() + it.hookId.moduleCode.sort() == [PB_RICHMEDIA_FILTER].code.sort() } - and: "PBS response should include trace information about no-called module" - verifyAll(invocationTrace.findAll { it -> it.hookId.moduleCode == PB_RICHMEDIA_FILTER.code }) { - it.status == [SUCCESS] - it.action == [NO_INVOCATION] - it.hookId.moduleCode.sort() == [PB_RICHMEDIA_FILTER].code.sort() + and: "Ortb2blocking module call metrics should be updated" + def metrics = pbsServiceWithMultipleModuleWithRequireInvoke.sendCollectedMetricsRequest() + assert !metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] + assert !metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] + assert !metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] + assert !metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] + + and: "RB-Richmedia-Filter module call metrics should be updated" + assert metrics[CALL_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 + assert metrics[NOOP_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 + } + + def "PBS shouldn't call any modules and traces that in response when account config is empty and require-config-to-invoke is enabled"() { + given: "Default bid request with verbose trace" + def bidRequest = defaultBidRequest.tap { + ext.prebid.trace = TraceLevel.VERBOSE } - and: "Richmedia module metrics should be updated" + and: "Save account without modules config" + def accountConfig = new AccountConfig(hooks: new AccountHooksConfiguration(modules: modulesConfig)) + def account = new Account(uuid: bidRequest.getAccountId(), config: accountConfig) + accountDao.save(account) + + and: "Flush metrics" + flushMetrics(pbsServiceWithMultipleModuleWithRequireInvoke) + + when: "PBS processes auction request" + def response = pbsServiceWithMultipleModuleWithRequireInvoke.sendAuctionRequest(bidRequest) + + then: "PBS response shouldn't include trace information about no-called modules" + assert !response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() + + and: "Ortb2blocking module call metrics shouldn't be updated" def metrics = pbsServiceWithMultipleModuleWithRequireInvoke.sendCollectedMetricsRequest() - assert metrics[NO_INVOCATION_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] == 1 + assert !metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] + assert !metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] + assert !metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] + assert !metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] + + and: "RB-Richmedia-Filter module call metrics shouldn't be updated" + assert !metrics[CALL_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] + assert !metrics[NOOP_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] + + where: + modulesConfig << [null, new PbsModulesConfig()] + } + + @PendingFeature + def "PBS should call all modules without account config when modules enabled in module-execution host config"() { + given: "PBS service with module-execution config" + def pbsConfig = MULTI_MODULE_CONFIG + ENABLED_INVOKE_CONFIG + + [("hooks.admin.module-execution.${ORTB2_BLOCKING.code}".toString()): 'true'] + def pbsServiceWithMultipleModules = pbsServiceFactory.getService(pbsConfig) + + and: "Default bid request with verbose trace" + def bidRequest = defaultBidRequest.tap { + ext.prebid.trace = TraceLevel.VERBOSE + } + + and: "Flush metrics" + flushMetrics(pbsServiceWithMultipleModules) + + when: "PBS processes auction request" + def response = pbsServiceWithMultipleModules.sendAuctionRequest(bidRequest) + + then: "PBS response should include trace information about called modules" + verifyAll(response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List) { + it.status == [SUCCESS, SUCCESS] + it.action == [NO_ACTION, NO_ACTION] + it.hookId.moduleCode.sort() == [ORTB2_BLOCKING, ORTB2_BLOCKING].code.sort() + } + + and: "Ortb2blocking module call metrics should be updated" + def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() + assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 + assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 + assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + + and: "RB-Richmedia-Filter module call metrics shouldn't be updated" + assert !metrics[CALL_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] + assert !metrics[NOOP_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] + + cleanup: "Stop and remove pbs container" + pbsServiceFactory.removeContainer(pbsConfig) + } + + def "PBS should call module without account config when default-account module-execution config enabled module"() { + given: "PBS service with module-execution and default account configs" + def defaultAccountConfigSettings = AccountConfig.defaultAccountConfig.tap { + hooks = new AccountHooksConfiguration(admin: new AdminConfig(moduleExecution: [(ORTB2_BLOCKING): true])) + } + def pbsConfig = MULTI_MODULE_CONFIG + ENABLED_INVOKE_CONFIG + ["settings.default-account-config": encode(defaultAccountConfigSettings)] + + [("hooks.admin.module-execution.${ORTB2_BLOCKING.code}".toString()): 'false'] + def pbsServiceWithMultipleModules = pbsServiceFactory.getService(pbsConfig) + + and: "Default bid request with verbose trace" + def bidRequest = defaultBidRequest.tap { + ext.prebid.trace = TraceLevel.VERBOSE + } + + and: "Save account without modules config" + def accountConfig = new AccountConfig(hooks: new AccountHooksConfiguration(modules: null)) + def account = new Account(uuid: bidRequest.getAccountId(), config: accountConfig) + accountDao.save(account) + + and: "Flush metrics" + flushMetrics(pbsServiceWithMultipleModules) + + when: "PBS processes auction request" + def response = pbsServiceWithMultipleModules.sendAuctionRequest(bidRequest) + + then: "PBS response should include trace information about called modules" + verifyAll(response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List) { + it.status == [SUCCESS, SUCCESS] + it.action == [NO_ACTION, NO_ACTION] + it.hookId.moduleCode.sort() == [ORTB2_BLOCKING, ORTB2_BLOCKING].code.sort() + } + + and: "Ortb2blocking module call metrics should be updated" + def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() + assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 + assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 + assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + + and: "RB-Richmedia-Filter module call metrics shouldn't be updated" + assert !metrics[CALL_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] + assert !metrics[NOOP_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] + + cleanup: "Stop and remove pbs container" + pbsServiceFactory.removeContainer(pbsConfig) + } + + def "PBS shouldn't call any modules without account config when default-account module-execution config not enabling module"() { + given: "PBS service with module-execution and default account configs" + def defaultAccountConfigSettings = AccountConfig.defaultAccountConfig.tap { + hooks = new AccountHooksConfiguration(admin: new AdminConfig(moduleExecution: [(ORTB2_BLOCKING): moduleExecutionStatus])) + } + def pbsConfig = MULTI_MODULE_CONFIG + ENABLED_INVOKE_CONFIG + ["settings.default-account-config": encode(defaultAccountConfigSettings)] + def pbsServiceWithMultipleModules = pbsServiceFactory.getService(pbsConfig) + + and: "Default bid request with verbose trace" + def bidRequest = defaultBidRequest.tap { + ext.prebid.trace = TraceLevel.VERBOSE + } + + and: "Save account without modules config" + def accountConfig = new AccountConfig(hooks: new AccountHooksConfiguration(modules: null)) + def account = new Account(uuid: bidRequest.getAccountId(), config: accountConfig) + accountDao.save(account) + + and: "Flush metrics" + flushMetrics(pbsServiceWithMultipleModules) + + when: "PBS processes auction request" + def response = pbsServiceWithMultipleModules.sendAuctionRequest(bidRequest) + + then: "PBS response shouldn't include trace information about no-called modules" + assert !response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() + + and: "Ortb2blocking module call metrics shouldn't be updated" + def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() + assert !metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] + assert !metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] + assert !metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] + assert !metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] + + and: "RB-Richmedia-Filter module call metrics shouldn't be updated" + assert !metrics[CALL_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] + assert !metrics[NOOP_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] + + cleanup: "Stop and remove pbs container" + pbsServiceFactory.removeContainer(pbsConfig) + + where: + moduleExecutionStatus << [false, null] + } + + def "PBS should prioritize specific account module-execution config over default-account module-execution config when both are present"() { + given: "PBS service with default account config" + def defaultAccountConfigSettings = AccountConfig.defaultAccountConfig.tap { + hooks = new AccountHooksConfiguration(admin: new AdminConfig(moduleExecution: [(ORTB2_BLOCKING): false])) + } + def pbsConfig = MULTI_MODULE_CONFIG + ENABLED_INVOKE_CONFIG + ["settings.default-account-config": encode(defaultAccountConfigSettings)] + def pbsServiceWithMultipleModules = pbsServiceFactory.getService(pbsConfig) + + and: "Default bid request with verbose trace" + def bidRequest = defaultBidRequest.tap { + ext.prebid.trace = TraceLevel.VERBOSE + } + + and: "Save account without modules config" + def accountConfig = new AccountConfig(hooks: new AccountHooksConfiguration(admin: new AdminConfig(moduleExecution: [(ORTB2_BLOCKING): true]))) + def account = new Account(uuid: bidRequest.getAccountId(), config: accountConfig) + accountDao.save(account) + + and: "Flush metrics" + flushMetrics(pbsServiceWithMultipleModules) + + when: "PBS processes auction request" + def response = pbsServiceWithMultipleModules.sendAuctionRequest(bidRequest) + + then: "PBS response should include trace information about called modules" + verifyAll(response?.ext?.prebid?.modules?.trace?.stages?.outcomes?.groups?.invocationResults?.flatten() as List) { + it.status == [SUCCESS, SUCCESS] + it.action == [NO_ACTION, NO_ACTION] + it.hookId.moduleCode.sort() == [ORTB2_BLOCKING, ORTB2_BLOCKING].code.sort() + } + + and: "Ortb2blocking module call metrics should be updated" + def metrics = pbsServiceWithMultipleModules.sendCollectedMetricsRequest() + assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 + assert metrics[CALL_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, BIDDER_REQUEST.metricValue, ORTB2_BLOCKING_BIDDER_REQUEST.code)] == 1 + assert metrics[NOOP_METRIC.formatted(ORTB2_BLOCKING.code, RAW_BIDDER_RESPONSE.metricValue, ORTB2_BLOCKING_RAW_BIDDER_RESPONSE.code)] == 1 + + and: "RB-Richmedia-Filter module call metrics shouldn't be updated" assert !metrics[CALL_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] + assert !metrics[NOOP_METRIC.formatted(PB_RICHMEDIA_FILTER.code, ALL_PROCESSED_BID_RESPONSES.metricValue, PB_RICHMEDIA_FILTER_ALL_PROCESSED_RESPONSES.code)] - and: "Response-correction module metrics should be updated" - assert !metrics[NO_INVOCATION_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] - assert metrics[CALL_METRIC.formatted(PB_RESPONSE_CORRECTION.code, ALL_PROCESSED_BID_RESPONSES.metricValue, RESPONSE_CORRECTION_ALL_PROCESSED_RESPONSES.code)] == 1 + cleanup: "Stop and remove pbs container" + pbsServiceFactory.removeContainer(pbsConfig) } }