Skip to content

Commit

Permalink
Module Execution Host Config Check (#3566)
Browse files Browse the repository at this point in the history
  • Loading branch information
AntoxaAntoxic authored Dec 4, 2024
1 parent 7b3fd70 commit 90faf43
Show file tree
Hide file tree
Showing 12 changed files with 565 additions and 126 deletions.
1 change: 1 addition & 0 deletions docs/application-settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/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:
Expand Down
3 changes: 3 additions & 0 deletions docs/config-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,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.
Expand Down
32 changes: 11 additions & 21 deletions src/main/java/org/prebid/server/hooks/execution/GroupExecutor.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
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;
Expand All @@ -9,16 +8,13 @@
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.Map;
import java.util.concurrent.TimeoutException;
import java.util.function.Function;
import java.util.function.Supplier;
Expand All @@ -30,7 +26,7 @@ class GroupExecutor<PAYLOAD, CONTEXT extends InvocationContext> {

private final Vertx vertx;
private final Clock clock;
private final boolean isConfigToInvokeRequired;
private final Map<String, Boolean> modulesExecution;

private ExecutionGroup group;
private PAYLOAD initialPayload;
Expand All @@ -39,18 +35,19 @@ class GroupExecutor<PAYLOAD, CONTEXT extends InvocationContext> {
private HookExecutionContext hookExecutionContext;
private boolean rejectAllowed;

private GroupExecutor(Vertx vertx, Clock clock, boolean isConfigToInvokeRequired) {
private GroupExecutor(Vertx vertx, Clock clock, Map<String, Boolean> modulesExecution) {

this.vertx = vertx;
this.clock = clock;
this.isConfigToInvokeRequired = isConfigToInvokeRequired;
this.modulesExecution = modulesExecution;
}

public static <PAYLOAD, CONTEXT extends InvocationContext> GroupExecutor<PAYLOAD, CONTEXT> create(
Vertx vertx,
Clock clock,
boolean isConfigToInvokeRequired) {
Map<String, Boolean> modulesExecution) {

return new GroupExecutor<>(vertx, clock, isConfigToInvokeRequired);
return new GroupExecutor<>(vertx, clock, modulesExecution);
}

public GroupExecutor<PAYLOAD, CONTEXT> withGroup(ExecutionGroup group) {
Expand Down Expand Up @@ -90,6 +87,10 @@ public Future<GroupResult<PAYLOAD>> execute() {
Future<GroupResult<PAYLOAD>> groupFuture = Future.succeededFuture(initialGroupResult);

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

final Hook<PAYLOAD, CONTEXT> hook = hookProvider.apply(hookId);

final long startTime = clock.millis();
Expand All @@ -116,17 +117,6 @@ private Future<InvocationResult<PAYLOAD>> executeHook(
}

final CONTEXT invocationContext = invocationContextProvider.apply(timeout, hookId, moduleContextFor(hookId));

if (isConfigToInvokeRequired && invocationContext instanceof AuctionInvocationContext) {
final ObjectNode accountConfig = ((AuctionInvocationContext) invocationContext).accountConfig();
if (accountConfig == null || accountConfig.isNull()) {
return Future.succeededFuture(InvocationResultImpl.<PAYLOAD>builder()
.status(InvocationStatus.success)
.action(InvocationAction.no_invocation)
.build());
}
}

return executeWithTimeout(() -> hook.call(groupResult.payload(), invocationContext), timeout);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -46,14 +47,17 @@
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.HooksAdminConfig;
import org.prebid.server.settings.model.AccountHooksConfiguration;

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;
import java.util.Optional;
import java.util.stream.Stream;

public class HookStageExecutor {
Expand Down Expand Up @@ -123,6 +127,7 @@ public Future<HookStageExecutionResult<EntrypointPayload>> executeEntrypointStag
.withExecutionPlan(planForEntrypointStage(endpoint))
.withInitialPayload(EntrypointPayloadImpl.of(queryParams, headers, body))
.withInvocationContextProvider(invocationContextProvider(endpoint))
.withModulesExecution(Collections.emptyMap())
.withRejectAllowed(true)
.execute();
}
Expand Down Expand Up @@ -259,7 +264,7 @@ private <PAYLOAD, CONTEXT extends InvocationContext> StageExecutor<PAYLOAD, CONT
String entity,
HookExecutionContext context) {

return StageExecutor.<PAYLOAD, CONTEXT>create(hookCatalog, vertx, clock, isConfigToInvokeRequired)
return StageExecutor.<PAYLOAD, CONTEXT>create(hookCatalog, vertx, clock)
.withStage(stage)
.withEntity(entity)
.withHookExecutionContext(context);
Expand All @@ -273,9 +278,30 @@ private <PAYLOAD, CONTEXT extends InvocationContext> StageExecutor<PAYLOAD, CONT
Endpoint endpoint) {

return stageExecutor(stage, entity, context)
.withModulesExecution(modulesExecutionForAccount(account))
.withExecutionPlan(planForStage(account, endpoint, stage.stage()));
}

private Map<String, Boolean> modulesExecutionForAccount(Account account) {
final Map<String, Boolean> accountModulesExecution = Optional.ofNullable(account.getHooks())
.map(AccountHooksConfiguration::getAdmin)
.map(HooksAdminConfig::getModuleExecution)
.orElse(Collections.emptyMap());

final Map<String, Boolean> resultModulesExecution = new HashMap<>(accountModulesExecution);

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, !isConfigToInvokeRequired);
}

private static ExecutionPlan parseAndValidateExecutionPlan(
String executionPlan,
JacksonMapper mapper,
Expand Down Expand Up @@ -402,8 +428,7 @@ private InvocationContextProvider<BidderInvocationContext> 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) {
Expand Down
18 changes: 11 additions & 7 deletions src/main/java/org/prebid/server/hooks/execution/StageExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@

import java.time.Clock;
import java.util.ArrayList;
import java.util.Map;

class StageExecutor<PAYLOAD, CONTEXT extends InvocationContext> {

private final HookCatalog hookCatalog;
private final Vertx vertx;
private final Clock clock;
private final boolean isConfigToInvokeRequired;

private StageWithHookType<? extends Hook<PAYLOAD, CONTEXT>> stage;
private String entity;
Expand All @@ -27,21 +27,20 @@ class StageExecutor<PAYLOAD, CONTEXT extends InvocationContext> {
private InvocationContextProvider<CONTEXT> invocationContextProvider;
private HookExecutionContext hookExecutionContext;
private boolean rejectAllowed;
private Map<String, Boolean> 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 <PAYLOAD, CONTEXT extends InvocationContext> StageExecutor<PAYLOAD, CONTEXT> 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<PAYLOAD, CONTEXT> withStage(StageWithHookType<? extends Hook<PAYLOAD, CONTEXT>> stage) {
Expand Down Expand Up @@ -81,6 +80,11 @@ public StageExecutor<PAYLOAD, CONTEXT> withRejectAllowed(boolean rejectAllowed)
return this;
}

public StageExecutor<PAYLOAD, CONTEXT> withModulesExecution(Map<String, Boolean> modulesExecution) {
this.modulesExecution = modulesExecution;
return this;
}

public Future<HookStageExecutionResult<PAYLOAD>> execute() {
Future<StageResult<PAYLOAD>> stageFuture = Future.succeededFuture(StageResult.of(initialPayload, entity));

Expand All @@ -97,7 +101,7 @@ public Future<HookStageExecutionResult<PAYLOAD>> execute() {
}

private Future<GroupResult<PAYLOAD>> executeGroup(ExecutionGroup group, PAYLOAD initialPayload) {
return GroupExecutor.<PAYLOAD, CONTEXT>create(vertx, clock, isConfigToInvokeRequired)
return GroupExecutor.<PAYLOAD, CONTEXT>create(vertx, clock, modulesExecution)
.withGroup(group)
.withInitialPayload(initialPayload)
.withHookProvider(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ public class AccountHooksConfiguration {
ExecutionPlan executionPlan;

Map<String, ObjectNode> modules;

HooksAdminConfig admin;
}
Original file line number Diff line number Diff line change
@@ -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 HooksAdminConfig {

@JsonAlias("module-execution")
Map<String, Boolean> moduleExecution;

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ class AccountHooksConfiguration {
@JsonProperty("execution_plan")
ExecutionPlan executionPlanSnakeCase
PbsModulesConfig modules
AdminConfig admin
}
Original file line number Diff line number Diff line change
@@ -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<ModuleName, Boolean> moduleExecution
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<TraceGroup> groups
}
Loading

0 comments on commit 90faf43

Please sign in to comment.