Skip to content

Commit

Permalink
Add module-execution config on the host level
Browse files Browse the repository at this point in the history
  • Loading branch information
AntoxaAntoxic committed Dec 5, 2024
1 parent ae475a5 commit 817122f
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 11 deletions.
7 changes: 4 additions & 3 deletions docs/config-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -370,9 +370,6 @@ 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.
Expand Down Expand Up @@ -443,6 +440,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.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public Future<GroupResult<PAYLOAD>> execute() {
Future<GroupResult<PAYLOAD>> groupFuture = Future.succeededFuture(initialGroupResult);

for (final HookId hookId : group.getHookSequence()) {
if (!modulesExecution.getOrDefault(hookId.getModuleCode(), true)) {
if (!modulesExecution.get(hookId.getModuleCode())) {
continue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ public class HookStageExecutor {

private final ExecutionPlan hostExecutionPlan;
private final ExecutionPlan defaultAccountExecutionPlan;
private final Map<String, Boolean> hostModuleExecution;
private final HookCatalog hookCatalog;
private final TimeoutFactory timeoutFactory;
private final Vertx vertx;
Expand All @@ -90,6 +91,7 @@ public class HookStageExecutor {

private HookStageExecutor(ExecutionPlan hostExecutionPlan,
ExecutionPlan defaultAccountExecutionPlan,
Map<String, Boolean> hostModuleExecution,
HookCatalog hookCatalog,
TimeoutFactory timeoutFactory,
Vertx vertx,
Expand All @@ -105,10 +107,12 @@ private HookStageExecutor(ExecutionPlan hostExecutionPlan,
this.clock = clock;
this.mapper = mapper;
this.isConfigToInvokeRequired = isConfigToInvokeRequired;
this.hostModuleExecution = hostModuleExecution;
}

public static HookStageExecutor create(String hostExecutionPlan,
String defaultAccountExecutionPlan,
Map<String, Boolean> hostModuleExecution,
HookCatalog hookCatalog,
TimeoutFactory timeoutFactory,
Vertx vertx,
Expand All @@ -122,6 +126,7 @@ public static HookStageExecutor create(String hostExecutionPlan,
return new HookStageExecutor(
parseAndValidateExecutionPlan(hostExecutionPlan, mapper, hookCatalog),
parseAndValidateExecutionPlan(defaultAccountExecutionPlan, mapper, hookCatalog),
hostModuleExecution,
hookCatalog,
Objects.requireNonNull(timeoutFactory),
Objects.requireNonNull(vertx),
Expand Down Expand Up @@ -185,7 +190,7 @@ public Future<HookStageExecutionResult<EntrypointPayload>> executeEntrypointStag
.withHookProvider(hookProviderForEntrypointStage(context))
.withInitialPayload(EntrypointPayloadImpl.of(queryParams, headers, body))
.withInvocationContextProvider(invocationContextProvider(endpoint))
.withModulesExecution(Collections.emptyMap())
.withModulesExecution(DefaultedMap.defaultedMap(hostModuleExecution, true))
.withRejectAllowed(true)
.execute();
}
Expand Down Expand Up @@ -374,6 +379,7 @@ private Map<String, Boolean> modulesExecutionForAccount(Account account) {
.forEach(module -> resultModulesExecution.computeIfAbsent(module, key -> true));
}

resultModulesExecution.putAll(hostModuleExecution);
return DefaultedMap.defaultedMap(resultModulesExecution, !isConfigToInvokeRequired);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -16,6 +17,8 @@

import java.time.Clock;
import java.util.Collection;
import java.util.Collections;
import java.util.Optional;

@Configuration
public class HooksConfiguration {
Expand All @@ -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,
Expand All @@ -60,5 +66,7 @@ private static class HooksConfigurationProperties {
String hostExecutionPlan;

String defaultAccountExecutionPlan;

HooksAdminConfig admin;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@

import java.time.Clock;
import java.time.ZoneOffset;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -411,6 +412,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<HookStageExecutionResult<EntrypointPayload>> 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
Expand Down Expand Up @@ -1341,12 +1406,14 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsNotRequired
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,
Expand All @@ -1355,6 +1422,7 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsNotRequired
final HookStageExecutor executor = HookStageExecutor.create(
hostExecutionPlan,
null,
Map.of("module-epsilon", true, "module-zeta", false),
hookCatalog,
timeoutFactory,
vertx,
Expand All @@ -1375,11 +1443,13 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsNotRequired
null,
Map.of("module-alpha", mapper.createObjectNode(),
"module-beta", mapper.createObjectNode(),
"module-gamma", mapper.createObjectNode()),
"module-gamma", mapper.createObjectNode(),
"module-zeta", mapper.createObjectNode()),
HooksAdminConfig.builder()
.moduleExecution(Map.of(
"module-alpha", true,
"module-beta", false))
"module-beta", false,
"module-epsilon", false))
.build()))
.build())
.hookExecutionContext(hookExecutionContext)
Expand All @@ -1394,6 +1464,7 @@ public void shouldNotExecuteRawAuctionRequestHooksWhenAccountConfigIsNotRequired
.at(1)
.id("id")
.tmax(1000L)
.site(Site.builder().build())
.build()));

assertThat(hookExecutionContext.getStageOutcomes())
Expand Down Expand Up @@ -1468,6 +1539,7 @@ public void shouldExecuteRawAuctionRequestHooksWhenAccountConfigIsRequired(Vertx
final HookStageExecutor executor = HookStageExecutor.create(
hostExecutionPlan,
null,
Map.of("module-epsilon", true, "module-zeta", false),
hookCatalog,
timeoutFactory,
vertx,
Expand All @@ -1488,11 +1560,13 @@ public void shouldExecuteRawAuctionRequestHooksWhenAccountConfigIsRequired(Vertx
null,
Map.of("module-alpha", mapper.createObjectNode(),
"module-beta", mapper.createObjectNode(),
"module-gamma", mapper.createObjectNode()),
"module-gamma", mapper.createObjectNode(),
"module-zeta", mapper.createObjectNode()),
HooksAdminConfig.builder()
.moduleExecution(Map.of(
"module-alpha", true,
"module-beta", false))
"module-beta", false,
"module-epsilon", false))
.build()))
.build())
.hookExecutionContext(hookExecutionContext)
Expand All @@ -1506,6 +1580,7 @@ public void shouldExecuteRawAuctionRequestHooksWhenAccountConfigIsRequired(Vertx
assertThat(payload.bidRequest()).isEqualTo(BidRequest.builder()
.at(1)
.id("id")
.site(Site.builder().build())
.build()));

assertThat(hookExecutionContext.getStageOutcomes())
Expand Down Expand Up @@ -3298,6 +3373,7 @@ private HookStageExecutor createExecutor(String hostExecutionPlan, String defaul
return HookStageExecutor.create(
hostExecutionPlan,
defaultAccountExecutionPlan,
Collections.emptyMap(),
hookCatalog,
timeoutFactory,
vertx,
Expand Down

0 comments on commit 817122f

Please sign in to comment.