From bf8c1fa7d65b0cfef4721c3f4c592471acfce06a Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Fri, 25 Apr 2025 15:18:37 +0200
Subject: [PATCH 01/43] WIP - LiveIntent Module
---
extra/bundle/pom.xml | 5 ++
.../live-intent-omni-channel-identity/pom.xml | 17 ++++
...ntentOmniChannelIdentityConfiguration.java | 34 ++++++++
.../channel/identity/model/IdResResponse.java | 13 +++
.../identity/model/config/ModuleConfig.java | 9 ++
.../LiveIntentOmniChannelIdentityModule.java | 23 +++++
...elIdentityProcessedAuctionRequestHook.java | 86 +++++++++++++++++++
extra/modules/pom.xml | 1 +
8 files changed, 188 insertions(+)
create mode 100644 extra/modules/live-intent-omni-channel-identity/pom.xml
create mode 100644 extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
create mode 100644 extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java
create mode 100644 extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
create mode 100644 extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityModule.java
create mode 100644 extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
diff --git a/extra/bundle/pom.xml b/extra/bundle/pom.xml
index ce5b002df4b..d589f218121 100644
--- a/extra/bundle/pom.xml
+++ b/extra/bundle/pom.xml
@@ -55,6 +55,11 @@
pb-request-correction
${project.version}
+
+ org.prebid.server.hooks.modules
+ live-intent-omni-channel-identity
+ ${project.version}
+
diff --git a/extra/modules/live-intent-omni-channel-identity/pom.xml b/extra/modules/live-intent-omni-channel-identity/pom.xml
new file mode 100644
index 00000000000..5263d29fd21
--- /dev/null
+++ b/extra/modules/live-intent-omni-channel-identity/pom.xml
@@ -0,0 +1,17 @@
+
+
+ 4.0.0
+
+ org.prebid.server.hooks.modules
+ all-modules
+ 3.24.0-SNAPSHOT
+
+
+ live-intent-omni-channel-identity
+
+ live-intent-omni-channel-identity
+ LiveIntent Omni-Channel Identity
+
+
+
+
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
new file mode 100644
index 00000000000..183b037fd27
--- /dev/null
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
@@ -0,0 +1,34 @@
+package org.prebid.server.hooks.modules.liveintent.omni.channel.identity.config;
+
+import org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.config.ModuleConfig;
+import org.prebid.server.hooks.modules.liveintent.omni.channel.identity.v1.LiveIntentOmniChannelIdentityModule;
+import org.prebid.server.hooks.modules.liveintent.omni.channel.identity.v1.hooks.LiveIntentOmniChannelIdentityProcessedAuctionRequestHook;
+import org.prebid.server.hooks.v1.Hook;
+import org.prebid.server.hooks.v1.InvocationContext;
+import org.prebid.server.hooks.v1.Module;
+import org.prebid.server.json.JacksonMapper;
+import org.prebid.server.vertx.httpclient.HttpClient;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Set;
+
+@Configuration
+@ConditionalOnProperty(prefix = "hooks." + LiveIntentOmniChannelIdentityModule.CODE, name = "enabled", havingValue = "true")
+public class LiveIntentOmniChannelIdentityConfiguration {
+ @Bean
+ @ConfigurationProperties(prefix = "hooks.modules." + LiveIntentOmniChannelIdentityModule.CODE)
+ ModuleConfig moduleConfig() {
+ return new ModuleConfig();
+ }
+
+ @Bean
+ Module liveIntentOmniChannelIdentityModule(ModuleConfig config, JacksonMapper mapper, HttpClient httpClient) {
+ final Set extends Hook, ? extends InvocationContext>> hooks = Set.of(
+ new LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(config, mapper, httpClient)
+ );
+ return new LiveIntentOmniChannelIdentityModule(hooks);
+ }
+}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java
new file mode 100644
index 00000000000..9be5994dc52
--- /dev/null
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java
@@ -0,0 +1,13 @@
+package org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model;
+
+import com.iab.openrtb.request.Eid;
+import lombok.Builder;
+import lombok.Value;
+
+import java.util.List;
+
+@Value
+@Builder(toBuilder = true)
+public class IdResResponse {
+ List eids;
+}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
new file mode 100644
index 00000000000..6e55fc55fb2
--- /dev/null
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
@@ -0,0 +1,9 @@
+package org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.config;
+
+import lombok.Data;
+
+@Data
+public final class ModuleConfig {
+ Long requestTimeout;
+ String idResUrl;
+}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityModule.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityModule.java
new file mode 100644
index 00000000000..b0c90dbb9f1
--- /dev/null
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityModule.java
@@ -0,0 +1,23 @@
+package org.prebid.server.hooks.modules.liveintent.omni.channel.identity.v1;
+
+import org.prebid.server.hooks.v1.Hook;
+import org.prebid.server.hooks.v1.InvocationContext;
+import org.prebid.server.hooks.v1.Module;
+
+import java.util.Collection;
+
+public record LiveIntentOmniChannelIdentityModule (
+ Collection extends Hook, ? extends InvocationContext>> hooks
+) implements Module {
+ public static final String CODE = "liveintent-omni-channel-identity";
+
+ @Override
+ public String code() {
+ return CODE;
+ }
+
+ @Override
+ public Collection extends Hook, ? extends InvocationContext>> hooks() {
+ return hooks;
+ }
+}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
new file mode 100644
index 00000000000..7d8a9b4c970
--- /dev/null
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
@@ -0,0 +1,86 @@
+package org.prebid.server.hooks.modules.liveintent.omni.channel.identity.v1.hooks;
+
+import com.iab.openrtb.request.BidRequest;
+import com.iab.openrtb.request.Eid;
+import com.iab.openrtb.request.User;
+import io.vertx.core.Future;
+import org.prebid.server.hooks.execution.v1.InvocationResultImpl;
+import org.prebid.server.hooks.execution.v1.auction.AuctionRequestPayloadImpl;
+import org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.IdResResponse;
+import org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.config.ModuleConfig;
+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.auction.AuctionInvocationContext;
+import org.prebid.server.hooks.v1.auction.AuctionRequestPayload;
+import org.prebid.server.hooks.v1.auction.ProcessedAuctionRequestHook;
+import org.prebid.server.json.JacksonMapper;
+import org.prebid.server.vertx.httpclient.HttpClient;
+import org.prebid.server.vertx.httpclient.model.HttpClientResponse;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHook implements ProcessedAuctionRequestHook {
+
+ private static final String CODE = "liveintent-enrichment-hook";
+
+ private final ModuleConfig config;
+ private final JacksonMapper mapper;
+ private final HttpClient httpClient;
+
+ public LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(
+ ModuleConfig config,
+ JacksonMapper mapper,
+ HttpClient httpClient) {
+ this.config = Objects.requireNonNull(config);
+ this.mapper = Objects.requireNonNull(mapper);
+ this.httpClient = Objects.requireNonNull(httpClient);
+ }
+
+ // TODO: Error handling
+ @Override
+ public Future> call(AuctionRequestPayload auctionRequestPayload, AuctionInvocationContext invocationContext) {
+ return requestEnrichment(auctionRequestPayload)
+ .map(resolutionResult ->
+ InvocationResultImpl.builder()
+ .status(InvocationStatus.success)
+ .action(InvocationAction.update)
+ .payloadUpdate(requestPayload -> updatedPayload(requestPayload, resolutionResult))
+ .build()
+ );
+ }
+
+ @Override
+ public String code() {
+ return CODE;
+ }
+
+ private AuctionRequestPayload updatedPayload(AuctionRequestPayload requestPayload, IdResResponse idResResponse) {
+ BidRequest bidRequest = requestPayload.bidRequest();
+ User user = bidRequest.getUser();
+
+ List allEids = new ArrayList<>();
+ allEids.addAll(user.getEids());
+ allEids.addAll(idResResponse.getEids());
+
+ User updatedUser = user.toBuilder().eids(allEids).build();
+ BidRequest updatedBidRequest = requestPayload.bidRequest().toBuilder().user(updatedUser).build();
+
+ return AuctionRequestPayloadImpl.of(updatedBidRequest);
+ }
+
+ private Future requestEnrichment(AuctionRequestPayload auctionRequestPayload) {
+ String bidRequestJson = mapper.encodeToString(auctionRequestPayload.bidRequest());
+ return httpClient.post(
+ config.getIdResUrl(),
+ bidRequestJson,
+ config.getRequestTimeout())
+ .map(this::processResponse);
+ }
+
+ private IdResResponse processResponse(HttpClientResponse response) {
+ return mapper.decodeValue(response.getBody(), IdResResponse.class);
+ }
+}
diff --git a/extra/modules/pom.xml b/extra/modules/pom.xml
index 0d5de3c0a5e..332b10c9c25 100644
--- a/extra/modules/pom.xml
+++ b/extra/modules/pom.xml
@@ -24,6 +24,7 @@
pb-response-correction
greenbids-real-time-data
pb-request-correction
+ live-intent-omni-channel-identity
From 8429f34781b088123ebeef43db87213919656810 Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Fri, 25 Apr 2025 15:29:13 +0200
Subject: [PATCH 02/43] Adjust the hook code
---
...iveIntentOmniChannelIdentityProcessedAuctionRequestHook.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
index 7d8a9b4c970..425798673ed 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
@@ -24,7 +24,7 @@
public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHook implements ProcessedAuctionRequestHook {
- private static final String CODE = "liveintent-enrichment-hook";
+ private static final String CODE = "liveintent-omni-channel-identity-enrichment-hook";
private final ModuleConfig config;
private final JacksonMapper mapper;
From 459028de8da346fef2b0bc6cb1ab99e30be35d72 Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Fri, 25 Apr 2025 15:46:06 +0200
Subject: [PATCH 03/43] WIP - polish, add config tests
---
.../identity/model/config/ModuleConfig.java | 4 ++--
...elIdentityProcessedAuctionRequestHook.java | 6 +++---
.../model/config/ModuleConfigTest.java | 21 +++++++++++++++++++
3 files changed, 26 insertions(+), 5 deletions(-)
create mode 100644 extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
index 6e55fc55fb2..f106ac56111 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
@@ -4,6 +4,6 @@
@Data
public final class ModuleConfig {
- Long requestTimeout;
- String idResUrl;
+ long requestTimeoutMs;
+ String identityResolutionEndpoint;
}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
index 425798673ed..23f4b78c7a3 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
@@ -39,7 +39,7 @@ public LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(
this.httpClient = Objects.requireNonNull(httpClient);
}
- // TODO: Error handling
+ // TODO: Caching
@Override
public Future> call(AuctionRequestPayload auctionRequestPayload, AuctionInvocationContext invocationContext) {
return requestEnrichment(auctionRequestPayload)
@@ -74,9 +74,9 @@ private AuctionRequestPayload updatedPayload(AuctionRequestPayload requestPayloa
private Future requestEnrichment(AuctionRequestPayload auctionRequestPayload) {
String bidRequestJson = mapper.encodeToString(auctionRequestPayload.bidRequest());
return httpClient.post(
- config.getIdResUrl(),
+ config.getIdentityResolutionEndpoint(),
bidRequestJson,
- config.getRequestTimeout())
+ config.getRequestTimeoutMs())
.map(this::processResponse);
}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java
new file mode 100644
index 00000000000..b71c66be20b
--- /dev/null
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java
@@ -0,0 +1,21 @@
+package org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.config;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ModuleConfigTest {
+ @Test
+ public void shouldReturnRequestTimeoutMs() {
+ ModuleConfig moduleConfig = new ModuleConfig();
+ moduleConfig.setRequestTimeoutMs(5);
+ assertThat(moduleConfig.getRequestTimeoutMs()).isEqualTo(5);
+ }
+
+ @Test
+ public void shouldReturnIdentityResolutionEndpoint() {
+ ModuleConfig moduleConfig = new ModuleConfig();
+ moduleConfig.setIdentityResolutionEndpoint("https://test.com/idres");
+ assertThat(moduleConfig.getIdentityResolutionEndpoint()).isEqualTo("https://test.com/idres");
+ }
+}
From c846d1c9721f8f598e11f963a351ef7e56c1ccfe Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Mon, 28 Apr 2025 13:38:04 +0200
Subject: [PATCH 04/43] Add unit tests
---
.../live-intent-omni-channel-identity/pom.xml | 2 +-
.../channel/identity/model/IdResResponse.java | 10 +-
.../LiveIntentOmniChannelIdentityModule.java | 5 +-
...elIdentityProcessedAuctionRequestHook.java | 7 +-
...entityProcessedAuctionRequestHookTest.java | 113 ++++++++++++++++++
5 files changed, 127 insertions(+), 10 deletions(-)
create mode 100644 extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
diff --git a/extra/modules/live-intent-omni-channel-identity/pom.xml b/extra/modules/live-intent-omni-channel-identity/pom.xml
index 5263d29fd21..d1bf2a08aff 100644
--- a/extra/modules/live-intent-omni-channel-identity/pom.xml
+++ b/extra/modules/live-intent-omni-channel-identity/pom.xml
@@ -4,7 +4,7 @@
org.prebid.server.hooks.modules
all-modules
- 3.24.0-SNAPSHOT
+ 3.25.0-SNAPSHOT
live-intent-omni-channel-identity
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java
index 9be5994dc52..0e72f5763ce 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java
@@ -1,13 +1,17 @@
package org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model;
+import com.fasterxml.jackson.annotation.JsonProperty;
import com.iab.openrtb.request.Eid;
import lombok.Builder;
-import lombok.Value;
+import lombok.Data;
+import lombok.extern.jackson.Jacksonized;
import java.util.List;
-@Value
-@Builder(toBuilder = true)
+@Builder
+@Data
+@Jacksonized
public class IdResResponse {
+ @JsonProperty("eids")
List eids;
}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityModule.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityModule.java
index b0c90dbb9f1..9890c85e695 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityModule.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityModule.java
@@ -6,9 +6,8 @@
import java.util.Collection;
-public record LiveIntentOmniChannelIdentityModule (
- Collection extends Hook, ? extends InvocationContext>> hooks
-) implements Module {
+public record LiveIntentOmniChannelIdentityModule(Collection extends Hook, ? extends InvocationContext>> hooks) implements Module {
+
public static final String CODE = "liveintent-omni-channel-identity";
@Override
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
index 23f4b78c7a3..129689c32b9 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
@@ -21,6 +21,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHook implements ProcessedAuctionRequestHook {
@@ -58,11 +59,11 @@ public String code() {
}
private AuctionRequestPayload updatedPayload(AuctionRequestPayload requestPayload, IdResResponse idResResponse) {
- BidRequest bidRequest = requestPayload.bidRequest();
- User user = bidRequest.getUser();
+ BidRequest bidRequest = Optional.ofNullable(requestPayload.bidRequest()).orElse(BidRequest.builder().build());
+ User user = Optional.ofNullable(bidRequest.getUser()).orElse(User.builder().build());
List allEids = new ArrayList<>();
- allEids.addAll(user.getEids());
+ allEids.addAll(Optional.ofNullable(user.getEids()).orElse(List.of()));
allEids.addAll(idResResponse.getEids());
User updatedUser = user.toBuilder().eids(allEids).build();
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
new file mode 100644
index 00000000000..1fccc6d79eb
--- /dev/null
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
@@ -0,0 +1,113 @@
+package org.prebid.server.hooks.modules.liveintent.omni.channel.identity.v1;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.iab.openrtb.request.BidRequest;
+import com.iab.openrtb.request.Eid;
+import com.iab.openrtb.request.Uid;
+import com.iab.openrtb.request.User;
+import io.vertx.core.Future;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.prebid.server.hooks.execution.v1.auction.AuctionInvocationContextImpl;
+import org.prebid.server.hooks.execution.v1.auction.AuctionRequestPayloadImpl;
+import org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.config.ModuleConfig;
+import org.prebid.server.hooks.modules.liveintent.omni.channel.identity.v1.hooks.LiveIntentOmniChannelIdentityProcessedAuctionRequestHook;
+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.auction.AuctionInvocationContext;
+import org.prebid.server.hooks.v1.auction.AuctionRequestPayload;
+import org.prebid.server.json.JacksonMapper;
+import org.prebid.server.vertx.httpclient.HttpClient;
+import org.prebid.server.vertx.httpclient.model.HttpClientResponse;
+
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest {
+
+ private ModuleConfig moduleConfig;
+ private LiveIntentOmniChannelIdentityProcessedAuctionRequestHook target;
+ private JacksonMapper jacksonMapper;
+
+
+ @BeforeEach
+ public void setUp() {
+ ObjectMapper mapper = new ObjectMapper();
+ jacksonMapper = new JacksonMapper(mapper);
+
+ moduleConfig = new ModuleConfig();
+ moduleConfig.setRequestTimeoutMs(5);
+ moduleConfig.setIdentityResolutionEndpoint("https://test.com/idres");
+
+ target = new LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(moduleConfig, jacksonMapper, httpClient);
+ }
+
+ @Mock
+ private HttpClient httpClient;
+
+ @Test
+ public void shouldAddResolvedEids() {
+ Uid providedUid = Uid.builder().id("id1").atype(2).build();
+ Eid providedEid = Eid.builder().source("some.source.com").uids(List.of(providedUid)).build();
+
+ Uid enrichedUid = Uid.builder().id("id2").atype(3).build();
+ Eid enrichedEid = Eid.builder().source("liveintent.com").uids(List.of(enrichedUid)).build();
+
+ User user = User.builder().eids(List.of(providedEid)).build();
+ BidRequest bidRequest = BidRequest.builder().id("request").user(user).build();
+
+ AuctionInvocationContext auctionInvocationContext = AuctionInvocationContextImpl.of(null, null, false, null, null);
+
+ HttpClientResponse mockResponse = mock(HttpClientResponse.class);
+ when(mockResponse.getBody()).thenReturn("{\"eids\": [ { \"source\": \""+ enrichedEid.getSource() + "\", \"uids\": [ { \"atype\": " + enrichedUid.getAtype() + ", \"id\" : \"" + enrichedUid.getId() + "\" } ] } ] }");
+
+ when(httpClient.post(moduleConfig.getIdentityResolutionEndpoint(), jacksonMapper.encodeToString(bidRequest), moduleConfig.getRequestTimeoutMs()))
+ .thenReturn(Future.succeededFuture(mockResponse));
+
+ Future> future = target.call(AuctionRequestPayloadImpl.of(bidRequest), auctionInvocationContext);
+ InvocationResult result = future.result();
+
+ assertThat(future).isNotNull();
+ assertThat(future.succeeded()).isTrue();
+ assertThat(result).isNotNull();
+ assertThat(result.status()).isEqualTo(InvocationStatus.success);
+ assertThat(result.action()).isEqualTo(InvocationAction.update);
+ assertThat(result.payloadUpdate().apply(AuctionRequestPayloadImpl.of(bidRequest)).bidRequest().getUser().getEids()).isEqualTo(List.of(providedEid, enrichedEid));
+ }
+
+ @Test
+ public void shouldCreateUserWhenNotPresent() {
+ Uid enrichedUid = Uid.builder().id("id2").atype(3).build();
+ Eid enrichedEid = Eid.builder().source("liveintent.com").uids(List.of(enrichedUid)).build();
+
+ BidRequest bidRequest = BidRequest.builder().id("request").build();
+
+ AuctionInvocationContext auctionInvocationContext = AuctionInvocationContextImpl.of(null, null, false, null, null);
+
+ HttpClientResponse mockResponse = mock(HttpClientResponse.class);
+ when(mockResponse.getBody()).thenReturn("{\"eids\": [{ \"source\": \""+ enrichedEid.getSource() + "\", \"uids\": [{ \"atype\": " + enrichedUid.getAtype() + ", \"id\" : \"" + enrichedUid.getId() + "\" }]}]}");
+
+ when(httpClient.post(moduleConfig.getIdentityResolutionEndpoint(), jacksonMapper.encodeToString(bidRequest), moduleConfig.getRequestTimeoutMs()))
+ .thenReturn(Future.succeededFuture(mockResponse));
+
+ Future> future = target.call(AuctionRequestPayloadImpl.of(bidRequest), auctionInvocationContext);
+ InvocationResult result = future.result();
+
+ assertThat(future).isNotNull();
+ assertThat(future.succeeded()).isTrue();
+ assertThat(result).isNotNull();
+ assertThat(result.status()).isEqualTo(InvocationStatus.success);
+ assertThat(result.action()).isEqualTo(InvocationAction.update);
+ assertThat(result.payloadUpdate().apply(AuctionRequestPayloadImpl.of(bidRequest)).bidRequest().getUser().getEids()).isEqualTo(List.of(enrichedEid));
+ }
+}
From 8348d4655da3523f0ffe6070aa5743318974fb97 Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Tue, 29 Apr 2025 15:51:31 +0200
Subject: [PATCH 05/43] Add auth token
---
...ntentOmniChannelIdentityConfiguration.java | 4 +-
.../identity/model/config/ModuleConfig.java | 1 +
...elIdentityProcessedAuctionRequestHook.java | 9 ++++
.../model/config/ModuleConfigTest.java | 7 +++
...entityProcessedAuctionRequestHookTest.java | 51 +++++++++++++++----
5 files changed, 58 insertions(+), 14 deletions(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
index 183b037fd27..aabc80d852f 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
@@ -20,9 +20,7 @@
public class LiveIntentOmniChannelIdentityConfiguration {
@Bean
@ConfigurationProperties(prefix = "hooks.modules." + LiveIntentOmniChannelIdentityModule.CODE)
- ModuleConfig moduleConfig() {
- return new ModuleConfig();
- }
+ ModuleConfig moduleConfig() {return new ModuleConfig();}
@Bean
Module liveIntentOmniChannelIdentityModule(ModuleConfig config, JacksonMapper mapper, HttpClient httpClient) {
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
index f106ac56111..cf35c8e9211 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
@@ -6,4 +6,5 @@
public final class ModuleConfig {
long requestTimeoutMs;
String identityResolutionEndpoint;
+ String authToken;
}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
index 129689c32b9..1bed1267e22 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
@@ -3,7 +3,9 @@
import com.iab.openrtb.request.BidRequest;
import com.iab.openrtb.request.Eid;
import com.iab.openrtb.request.User;
+import io.netty.handler.codec.http.HttpHeaderValues;
import io.vertx.core.Future;
+import io.vertx.core.MultiMap;
import org.prebid.server.hooks.execution.v1.InvocationResultImpl;
import org.prebid.server.hooks.execution.v1.auction.AuctionRequestPayloadImpl;
import org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.IdResResponse;
@@ -15,6 +17,7 @@
import org.prebid.server.hooks.v1.auction.AuctionRequestPayload;
import org.prebid.server.hooks.v1.auction.ProcessedAuctionRequestHook;
import org.prebid.server.json.JacksonMapper;
+import org.prebid.server.util.HttpUtil;
import org.prebid.server.vertx.httpclient.HttpClient;
import org.prebid.server.vertx.httpclient.model.HttpClientResponse;
@@ -76,6 +79,7 @@ private Future requestEnrichment(AuctionRequestPayload auctionReq
String bidRequestJson = mapper.encodeToString(auctionRequestPayload.bidRequest());
return httpClient.post(
config.getIdentityResolutionEndpoint(),
+ headers(),
bidRequestJson,
config.getRequestTimeoutMs())
.map(this::processResponse);
@@ -84,4 +88,9 @@ private Future requestEnrichment(AuctionRequestPayload auctionReq
private IdResResponse processResponse(HttpClientResponse response) {
return mapper.decodeValue(response.getBody(), IdResResponse.class);
}
+
+ private MultiMap headers() {
+ return MultiMap.caseInsensitiveMultiMap()
+ .add(HttpUtil.AUTHORIZATION_HEADER, "Bearer " + config.getAuthToken());
+ }
}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java
index b71c66be20b..1fa4860b023 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java
@@ -18,4 +18,11 @@ public void shouldReturnIdentityResolutionEndpoint() {
moduleConfig.setIdentityResolutionEndpoint("https://test.com/idres");
assertThat(moduleConfig.getIdentityResolutionEndpoint()).isEqualTo("https://test.com/idres");
}
+
+ @Test
+ public void shouldReturnAuthToken() {
+ ModuleConfig moduleConfig = new ModuleConfig();
+ moduleConfig.setAuthToken("secret_token");
+ assertThat(moduleConfig.getAuthToken()).isEqualTo("secret_token");
+ }
}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
index 1fccc6d79eb..155746a1e54 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
@@ -6,9 +6,11 @@
import com.iab.openrtb.request.Uid;
import com.iab.openrtb.request.User;
import io.vertx.core.Future;
+import io.vertx.core.MultiMap;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.prebid.server.hooks.execution.v1.auction.AuctionInvocationContextImpl;
@@ -21,14 +23,19 @@
import org.prebid.server.hooks.v1.auction.AuctionInvocationContext;
import org.prebid.server.hooks.v1.auction.AuctionRequestPayload;
import org.prebid.server.json.JacksonMapper;
+import org.prebid.server.util.HttpUtil;
import org.prebid.server.vertx.httpclient.HttpClient;
import org.prebid.server.vertx.httpclient.model.HttpClientResponse;
import java.util.List;
+import java.util.function.Consumer;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.assertArg;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -39,7 +46,6 @@ public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest {
private LiveIntentOmniChannelIdentityProcessedAuctionRequestHook target;
private JacksonMapper jacksonMapper;
-
@BeforeEach
public void setUp() {
ObjectMapper mapper = new ObjectMapper();
@@ -48,6 +54,7 @@ public void setUp() {
moduleConfig = new ModuleConfig();
moduleConfig.setRequestTimeoutMs(5);
moduleConfig.setIdentityResolutionEndpoint("https://test.com/idres");
+ moduleConfig.setAuthToken("secret_auth_token");
target = new LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(moduleConfig, jacksonMapper, httpClient);
}
@@ -69,10 +76,21 @@ public void shouldAddResolvedEids() {
AuctionInvocationContext auctionInvocationContext = AuctionInvocationContextImpl.of(null, null, false, null, null);
HttpClientResponse mockResponse = mock(HttpClientResponse.class);
- when(mockResponse.getBody()).thenReturn("{\"eids\": [ { \"source\": \""+ enrichedEid.getSource() + "\", \"uids\": [ { \"atype\": " + enrichedUid.getAtype() + ", \"id\" : \"" + enrichedUid.getId() + "\" } ] } ] }");
-
- when(httpClient.post(moduleConfig.getIdentityResolutionEndpoint(), jacksonMapper.encodeToString(bidRequest), moduleConfig.getRequestTimeoutMs()))
- .thenReturn(Future.succeededFuture(mockResponse));
+ when(mockResponse.getBody()).thenReturn("{\"eids\": [ { \"source\": \"" + enrichedEid.getSource() + "\", \"uids\": [ { \"atype\": " + enrichedUid.getAtype() + ", \"id\" : \"" + enrichedUid.getId() + "\" } ] } ] }");
+
+ when(
+ httpClient.post(
+ eq(moduleConfig.getIdentityResolutionEndpoint()),
+ argThat(new ArgumentMatcher() {
+ @Override
+ public boolean matches(MultiMap entries) {
+ return entries.contains("Authorization", "Bearer " + moduleConfig.getAuthToken(), true);
+ }
+ }),
+ eq(jacksonMapper.encodeToString(bidRequest)),
+ eq(moduleConfig.getRequestTimeoutMs())
+ )
+ ).thenReturn(Future.succeededFuture(mockResponse));
Future> future = target.call(AuctionRequestPayloadImpl.of(bidRequest), auctionInvocationContext);
InvocationResult result = future.result();
@@ -95,10 +113,21 @@ public void shouldCreateUserWhenNotPresent() {
AuctionInvocationContext auctionInvocationContext = AuctionInvocationContextImpl.of(null, null, false, null, null);
HttpClientResponse mockResponse = mock(HttpClientResponse.class);
- when(mockResponse.getBody()).thenReturn("{\"eids\": [{ \"source\": \""+ enrichedEid.getSource() + "\", \"uids\": [{ \"atype\": " + enrichedUid.getAtype() + ", \"id\" : \"" + enrichedUid.getId() + "\" }]}]}");
-
- when(httpClient.post(moduleConfig.getIdentityResolutionEndpoint(), jacksonMapper.encodeToString(bidRequest), moduleConfig.getRequestTimeoutMs()))
- .thenReturn(Future.succeededFuture(mockResponse));
+ when(mockResponse.getBody()).thenReturn("{\"eids\": [{ \"source\": \"" + enrichedEid.getSource() + "\", \"uids\": [{ \"atype\": " + enrichedUid.getAtype() + ", \"id\" : \"" + enrichedUid.getId() + "\" }]}]}");
+
+ when(
+ httpClient.post(
+ eq(moduleConfig.getIdentityResolutionEndpoint()),
+ argThat(new ArgumentMatcher() {
+ @Override
+ public boolean matches(MultiMap entries) {
+ return entries.contains("Authorization", "Bearer " + moduleConfig.getAuthToken(), true);
+ }
+ }),
+ eq(jacksonMapper.encodeToString(bidRequest)),
+ eq(moduleConfig.getRequestTimeoutMs())
+ )
+ ).thenReturn(Future.succeededFuture(mockResponse));
Future> future = target.call(AuctionRequestPayloadImpl.of(bidRequest), auctionInvocationContext);
InvocationResult result = future.result();
From c0f656671640acccc15dc51cb62c76bb5459d1ad Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Tue, 6 May 2025 13:47:47 +0200
Subject: [PATCH 06/43] Add README.md
---
.../README.md | 43 +++++++++++++++++++
...elIdentityProcessedAuctionRequestHook.java | 2 -
2 files changed, 43 insertions(+), 2 deletions(-)
create mode 100644 extra/modules/live-intent-omni-channel-identity/README.md
diff --git a/extra/modules/live-intent-omni-channel-identity/README.md b/extra/modules/live-intent-omni-channel-identity/README.md
new file mode 100644
index 00000000000..3fbdba78b71
--- /dev/null
+++ b/extra/modules/live-intent-omni-channel-identity/README.md
@@ -0,0 +1,43 @@
+# Overview
+
+This module enriches bid requests with user IDs that it adds to the user EIDs.
+
+The user IDs to be enriched are configured on LiveIntent's side. The set of user IDs accessible by a partner are determined by the auth token provided in the settings.
+
+## Configuration
+To start using the LiveIntent Omni Channel Identity module you have to enable it and add configuration:
+
+```yaml
+hooks:
+ liveintent-omni-channel-identity:
+ enabled: true
+ host-execution-plan: >
+ {
+ "endpoints": {
+ "/openrtb2/auction": {
+ "stages": {
+ "all-processed-bid-responses": {
+ "groups": [
+ {
+ "timeout": 100,
+ "hook-sequence": [
+ {
+ "module-code": "liveintent-omni-channel-identity",
+ "hook-impl-code": "liveintent-omni-channel-identity-enrichment-hook"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ modules:
+ liveintent-omni-channel-identity:
+ request-timeout-ms: 2000
+ identity-resolution-endpoint: "https://liveintent.com/idx"
+ auth-token: "secret-token"
+```
+
+
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
index 1bed1267e22..44da5735acd 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
@@ -3,7 +3,6 @@
import com.iab.openrtb.request.BidRequest;
import com.iab.openrtb.request.Eid;
import com.iab.openrtb.request.User;
-import io.netty.handler.codec.http.HttpHeaderValues;
import io.vertx.core.Future;
import io.vertx.core.MultiMap;
import org.prebid.server.hooks.execution.v1.InvocationResultImpl;
@@ -43,7 +42,6 @@ public LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(
this.httpClient = Objects.requireNonNull(httpClient);
}
- // TODO: Caching
@Override
public Future> call(AuctionRequestPayload auctionRequestPayload, AuctionInvocationContext invocationContext) {
return requestEnrichment(auctionRequestPayload)
From 4f90c177df1dac03368dbda391300601f28daedc Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Tue, 6 May 2025 15:33:37 +0200
Subject: [PATCH 07/43] Fix stage
---
extra/modules/live-intent-omni-channel-identity/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/README.md b/extra/modules/live-intent-omni-channel-identity/README.md
index 3fbdba78b71..526da24fe9a 100644
--- a/extra/modules/live-intent-omni-channel-identity/README.md
+++ b/extra/modules/live-intent-omni-channel-identity/README.md
@@ -16,7 +16,7 @@ hooks:
"endpoints": {
"/openrtb2/auction": {
"stages": {
- "all-processed-bid-responses": {
+ "processed-auction-request": {
"groups": [
{
"timeout": 100,
From c6dc20e644ee907d5dbd1286b78d452d79679fd8 Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Wed, 7 May 2025 10:06:11 +0200
Subject: [PATCH 08/43] Add logging
---
...iveIntentOmniChannelIdentityConfiguration.java | 6 ++++--
.../v1/LiveIntentOmniChannelIdentityModule.java | 3 ++-
...hannelIdentityProcessedAuctionRequestHook.java | 15 ++++++++++-----
3 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
index aabc80d852f..0bc46332f3c 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
@@ -20,12 +20,14 @@
public class LiveIntentOmniChannelIdentityConfiguration {
@Bean
@ConfigurationProperties(prefix = "hooks.modules." + LiveIntentOmniChannelIdentityModule.CODE)
- ModuleConfig moduleConfig() {return new ModuleConfig();}
+ ModuleConfig moduleConfig() {
+ return new ModuleConfig();
+ }
@Bean
Module liveIntentOmniChannelIdentityModule(ModuleConfig config, JacksonMapper mapper, HttpClient httpClient) {
final Set extends Hook, ? extends InvocationContext>> hooks = Set.of(
- new LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(config, mapper, httpClient)
+ new LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(config, mapper, httpClient)
);
return new LiveIntentOmniChannelIdentityModule(hooks);
}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityModule.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityModule.java
index 9890c85e695..0ffdce8b436 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityModule.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityModule.java
@@ -6,7 +6,8 @@
import java.util.Collection;
-public record LiveIntentOmniChannelIdentityModule(Collection extends Hook, ? extends InvocationContext>> hooks) implements Module {
+public record LiveIntentOmniChannelIdentityModule(
+ Collection extends Hook, ? extends InvocationContext>> hooks) implements Module {
public static final String CODE = "liveintent-omni-channel-identity";
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
index 44da5735acd..de0720c59c8 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
@@ -16,6 +16,8 @@
import org.prebid.server.hooks.v1.auction.AuctionRequestPayload;
import org.prebid.server.hooks.v1.auction.ProcessedAuctionRequestHook;
import org.prebid.server.json.JacksonMapper;
+import org.prebid.server.log.Logger;
+import org.prebid.server.log.LoggerFactory;
import org.prebid.server.util.HttpUtil;
import org.prebid.server.vertx.httpclient.HttpClient;
import org.prebid.server.vertx.httpclient.model.HttpClientResponse;
@@ -27,6 +29,7 @@
public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHook implements ProcessedAuctionRequestHook {
+ private static final Logger logger = LoggerFactory.getLogger(LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.class);
private static final String CODE = "liveintent-omni-channel-identity-enrichment-hook";
private final ModuleConfig config;
@@ -44,14 +47,16 @@ public LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(
@Override
public Future> call(AuctionRequestPayload auctionRequestPayload, AuctionInvocationContext invocationContext) {
- return requestEnrichment(auctionRequestPayload)
+ Future> update = requestEnrichment(auctionRequestPayload)
.map(resolutionResult ->
InvocationResultImpl.builder()
- .status(InvocationStatus.success)
- .action(InvocationAction.update)
- .payloadUpdate(requestPayload -> updatedPayload(requestPayload, resolutionResult))
- .build()
+ .status(InvocationStatus.success)
+ .action(InvocationAction.update)
+ .payloadUpdate(requestPayload -> updatedPayload(requestPayload, resolutionResult))
+ .build()
);
+
+ return update.onFailure(throwable -> logger.error("Failed enrichment:", throwable));
}
@Override
From a863d0a198131b6fb900cdfedc428d9632899789 Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Wed, 7 May 2025 10:06:23 +0200
Subject: [PATCH 09/43] Add docs
---
extra/modules/live-intent-omni-channel-identity/README.md | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/README.md b/extra/modules/live-intent-omni-channel-identity/README.md
index 526da24fe9a..29ff4e55c78 100644
--- a/extra/modules/live-intent-omni-channel-identity/README.md
+++ b/extra/modules/live-intent-omni-channel-identity/README.md
@@ -1,10 +1,12 @@
# Overview
-This module enriches bid requests with user IDs that it adds to the user EIDs.
+This module enriches bid requests with user IDs that it adds to the user EIDs.
-The user IDs to be enriched are configured on LiveIntent's side. The set of user IDs accessible by a partner are determined by the auth token provided in the settings.
+The user IDs to be enriched are configured on LiveIntent's side. The set of user IDs accessible by a partner are
+determined by the auth token provided in the settings.
## Configuration
+
To start using the LiveIntent Omni Channel Identity module you have to enable it and add configuration:
```yaml
From 62a4508811b3fb6937446672bb8090946baf8153 Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Wed, 7 May 2025 10:06:43 +0200
Subject: [PATCH 10/43] Format
---
extra/modules/live-intent-omni-channel-identity/pom.xml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/pom.xml b/extra/modules/live-intent-omni-channel-identity/pom.xml
index d1bf2a08aff..03cf291d0da 100644
--- a/extra/modules/live-intent-omni-channel-identity/pom.xml
+++ b/extra/modules/live-intent-omni-channel-identity/pom.xml
@@ -1,5 +1,6 @@
-
+
4.0.0
org.prebid.server.hooks.modules
From e45ccbc1009dda931d0ad06c82bd5d89c9cac8ac Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Wed, 7 May 2025 10:13:52 +0200
Subject: [PATCH 11/43] Impro docs
---
extra/modules/live-intent-omni-channel-identity/README.md | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/README.md b/extra/modules/live-intent-omni-channel-identity/README.md
index 29ff4e55c78..3e375864088 100644
--- a/extra/modules/live-intent-omni-channel-identity/README.md
+++ b/extra/modules/live-intent-omni-channel-identity/README.md
@@ -1,9 +1,8 @@
# Overview
-This module enriches bid requests with user IDs that it adds to the user EIDs.
+This module enriches bid requests with user EIDs.
-The user IDs to be enriched are configured on LiveIntent's side. The set of user IDs accessible by a partner are
-determined by the auth token provided in the settings.
+The user EIDs to be enriched are configured per partner as part of the LiveIntent HIRO onboarding process.
## Configuration
@@ -41,5 +40,5 @@ hooks:
identity-resolution-endpoint: "https://liveintent.com/idx"
auth-token: "secret-token"
```
-
+The partner-specific `auth-token` is provided by LiveIntent as part of the onboarding.
From 3dbb46ae7ce97864a55086c190cf38f3b3613287 Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Wed, 7 May 2025 12:39:28 +0200
Subject: [PATCH 12/43] Add IdResResponse decode test
---
.../model/config/IdResResponseTest.java | 29 +++++++++++++++++++
1 file changed, 29 insertions(+)
create mode 100644 extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java
new file mode 100644
index 00000000000..d4e434f2942
--- /dev/null
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java
@@ -0,0 +1,29 @@
+package org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.config;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.IdResResponse;
+import org.prebid.server.json.JacksonMapper;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class IdResResponseTest {
+ private JacksonMapper jacksonMapper;
+
+ @BeforeEach
+ public void setUp() {
+ ObjectMapper mapper = new ObjectMapper();
+ jacksonMapper = new JacksonMapper(mapper);
+ }
+
+ @Test
+ public void shouldDecodeFromString() {
+ IdResResponse result = jacksonMapper.decodeValue("{\"eids\": [ { \"source\": \"liveintent.com\", \"uids\": [ { \"atype\": 3, \"id\" : \"some_id\" } ] } ] }", IdResResponse.class);
+ assertThat(result.getEids()).hasSize(1);
+ assertThat(result.getEids().getFirst().getSource()).isEqualTo("liveintent.com");
+ assertThat(result.getEids().getFirst().getUids()).hasSize(1);
+ assertThat(result.getEids().getFirst().getUids().getFirst().getAtype()).isEqualTo(3);
+ assertThat(result.getEids().getFirst().getUids().getFirst().getId()).isEqualTo("some_id");
+ }
+}
From 69fc41353876955d800bbc1827e501a099e9d028 Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Wed, 7 May 2025 13:00:42 +0200
Subject: [PATCH 13/43] Improve code style
---
...ntentOmniChannelIdentityConfiguration.java | 3 +-
...elIdentityProcessedAuctionRequestHook.java | 18 ++++----
.../model/config/IdResResponseTest.java | 2 +
.../model/config/ModuleConfigTest.java | 4 ++
...entityProcessedAuctionRequestHookTest.java | 46 +++++++++++--------
5 files changed, 44 insertions(+), 29 deletions(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
index 0bc46332f3c..ecceb0a4176 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
@@ -27,8 +27,7 @@ ModuleConfig moduleConfig() {
@Bean
Module liveIntentOmniChannelIdentityModule(ModuleConfig config, JacksonMapper mapper, HttpClient httpClient) {
final Set extends Hook, ? extends InvocationContext>> hooks = Set.of(
- new LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(config, mapper, httpClient)
- );
+ new LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(config, mapper, httpClient));
return new LiveIntentOmniChannelIdentityModule(hooks);
}
}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
index de0720c59c8..3b93f788bef 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
@@ -23,6 +23,7 @@
import org.prebid.server.vertx.httpclient.model.HttpClientResponse;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -40,6 +41,7 @@ public LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(
ModuleConfig config,
JacksonMapper mapper,
HttpClient httpClient) {
+
this.config = Objects.requireNonNull(config);
this.mapper = Objects.requireNonNull(mapper);
this.httpClient = Objects.requireNonNull(httpClient);
@@ -47,7 +49,7 @@ public LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(
@Override
public Future> call(AuctionRequestPayload auctionRequestPayload, AuctionInvocationContext invocationContext) {
- Future> update = requestEnrichment(auctionRequestPayload)
+ final Future> update = requestEnrichment(auctionRequestPayload)
.map(resolutionResult ->
InvocationResultImpl.builder()
.status(InvocationStatus.success)
@@ -65,21 +67,21 @@ public String code() {
}
private AuctionRequestPayload updatedPayload(AuctionRequestPayload requestPayload, IdResResponse idResResponse) {
- BidRequest bidRequest = Optional.ofNullable(requestPayload.bidRequest()).orElse(BidRequest.builder().build());
- User user = Optional.ofNullable(bidRequest.getUser()).orElse(User.builder().build());
+ final BidRequest bidRequest = Optional.ofNullable(requestPayload.bidRequest()).orElse(BidRequest.builder().build());
+ final User user = Optional.ofNullable(bidRequest.getUser()).orElse(User.builder().build());
- List allEids = new ArrayList<>();
- allEids.addAll(Optional.ofNullable(user.getEids()).orElse(List.of()));
+ final List allEids = new ArrayList<>();
+ allEids.addAll(Optional.ofNullable(user.getEids()).orElse(Collections.emptyList()));
allEids.addAll(idResResponse.getEids());
- User updatedUser = user.toBuilder().eids(allEids).build();
- BidRequest updatedBidRequest = requestPayload.bidRequest().toBuilder().user(updatedUser).build();
+ final User updatedUser = user.toBuilder().eids(allEids).build();
+ final BidRequest updatedBidRequest = requestPayload.bidRequest().toBuilder().user(updatedUser).build();
return AuctionRequestPayloadImpl.of(updatedBidRequest);
}
private Future requestEnrichment(AuctionRequestPayload auctionRequestPayload) {
- String bidRequestJson = mapper.encodeToString(auctionRequestPayload.bidRequest());
+ final String bidRequestJson = mapper.encodeToString(auctionRequestPayload.bidRequest());
return httpClient.post(
config.getIdentityResolutionEndpoint(),
headers(),
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java
index d4e434f2942..97fbb40e8d8 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java
@@ -19,7 +19,9 @@ public void setUp() {
@Test
public void shouldDecodeFromString() {
+ // given
IdResResponse result = jacksonMapper.decodeValue("{\"eids\": [ { \"source\": \"liveintent.com\", \"uids\": [ { \"atype\": 3, \"id\" : \"some_id\" } ] } ] }", IdResResponse.class);
+ // when and then
assertThat(result.getEids()).hasSize(1);
assertThat(result.getEids().getFirst().getSource()).isEqualTo("liveintent.com");
assertThat(result.getEids().getFirst().getUids()).hasSize(1);
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java
index 1fa4860b023..0ca4f894689 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java
@@ -14,15 +14,19 @@ public void shouldReturnRequestTimeoutMs() {
@Test
public void shouldReturnIdentityResolutionEndpoint() {
+ // given
ModuleConfig moduleConfig = new ModuleConfig();
moduleConfig.setIdentityResolutionEndpoint("https://test.com/idres");
+ // when and then
assertThat(moduleConfig.getIdentityResolutionEndpoint()).isEqualTo("https://test.com/idres");
}
@Test
public void shouldReturnAuthToken() {
+ // given
ModuleConfig moduleConfig = new ModuleConfig();
moduleConfig.setAuthToken("secret_token");
+ // when and then
assertThat(moduleConfig.getAuthToken()).isEqualTo("secret_token");
}
}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
index 155746a1e54..bef35918db7 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
@@ -7,6 +7,7 @@
import com.iab.openrtb.request.User;
import io.vertx.core.Future;
import io.vertx.core.MultiMap;
+import org.assertj.core.api.ListAssert;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -27,6 +28,7 @@
import org.prebid.server.vertx.httpclient.HttpClient;
import org.prebid.server.vertx.httpclient.model.HttpClientResponse;
+import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
@@ -64,20 +66,22 @@ public void setUp() {
@Test
public void shouldAddResolvedEids() {
- Uid providedUid = Uid.builder().id("id1").atype(2).build();
- Eid providedEid = Eid.builder().source("some.source.com").uids(List.of(providedUid)).build();
+ // given
+ final Uid providedUid = Uid.builder().id("id1").atype(2).build();
+ final Eid providedEid = Eid.builder().source("some.source.com").uids(Collections.singletonList(providedUid)).build();
- Uid enrichedUid = Uid.builder().id("id2").atype(3).build();
- Eid enrichedEid = Eid.builder().source("liveintent.com").uids(List.of(enrichedUid)).build();
+ final Uid enrichedUid = Uid.builder().id("id2").atype(3).build();
+ final Eid enrichedEid = Eid.builder().source("liveintent.com").uids(Collections.singletonList(enrichedUid)).build();
- User user = User.builder().eids(List.of(providedEid)).build();
- BidRequest bidRequest = BidRequest.builder().id("request").user(user).build();
+ final User user = User.builder().eids(Collections.singletonList(providedEid)).build();
+ final BidRequest bidRequest = BidRequest.builder().id("request").user(user).build();
- AuctionInvocationContext auctionInvocationContext = AuctionInvocationContextImpl.of(null, null, false, null, null);
+ final AuctionInvocationContext auctionInvocationContext = AuctionInvocationContextImpl.of(null, null, false, null, null);
- HttpClientResponse mockResponse = mock(HttpClientResponse.class);
+ final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
when(mockResponse.getBody()).thenReturn("{\"eids\": [ { \"source\": \"" + enrichedEid.getSource() + "\", \"uids\": [ { \"atype\": " + enrichedUid.getAtype() + ", \"id\" : \"" + enrichedUid.getId() + "\" } ] } ] }");
+ // when
when(
httpClient.post(
eq(moduleConfig.getIdentityResolutionEndpoint()),
@@ -92,27 +96,30 @@ public boolean matches(MultiMap entries) {
)
).thenReturn(Future.succeededFuture(mockResponse));
- Future> future = target.call(AuctionRequestPayloadImpl.of(bidRequest), auctionInvocationContext);
- InvocationResult result = future.result();
+ final Future> future = target.call(AuctionRequestPayloadImpl.of(bidRequest), auctionInvocationContext);
+ final InvocationResult result = future.result();
+ // then
assertThat(future).isNotNull();
assertThat(future.succeeded()).isTrue();
assertThat(result).isNotNull();
assertThat(result.status()).isEqualTo(InvocationStatus.success);
assertThat(result.action()).isEqualTo(InvocationAction.update);
- assertThat(result.payloadUpdate().apply(AuctionRequestPayloadImpl.of(bidRequest)).bidRequest().getUser().getEids()).isEqualTo(List.of(providedEid, enrichedEid));
+ assertThat(result.payloadUpdate().apply(AuctionRequestPayloadImpl.of(bidRequest)).bidRequest().getUser().getEids()).isEqualTo(Collections.singletonList(providedEid).add(enrichedEid));
}
@Test
public void shouldCreateUserWhenNotPresent() {
- Uid enrichedUid = Uid.builder().id("id2").atype(3).build();
- Eid enrichedEid = Eid.builder().source("liveintent.com").uids(List.of(enrichedUid)).build();
+ // given
+ final Uid enrichedUid = Uid.builder().id("id2").atype(3).build();
+ final Eid enrichedEid = Eid.builder().source("liveintent.com").uids(Collections.singletonList(enrichedUid)).build();
- BidRequest bidRequest = BidRequest.builder().id("request").build();
+ final BidRequest bidRequest = BidRequest.builder().id("request").build();
- AuctionInvocationContext auctionInvocationContext = AuctionInvocationContextImpl.of(null, null, false, null, null);
+ final AuctionInvocationContext auctionInvocationContext = AuctionInvocationContextImpl.of(null, null, false, null, null);
- HttpClientResponse mockResponse = mock(HttpClientResponse.class);
+ // when
+ final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
when(mockResponse.getBody()).thenReturn("{\"eids\": [{ \"source\": \"" + enrichedEid.getSource() + "\", \"uids\": [{ \"atype\": " + enrichedUid.getAtype() + ", \"id\" : \"" + enrichedUid.getId() + "\" }]}]}");
when(
@@ -129,14 +136,15 @@ public boolean matches(MultiMap entries) {
)
).thenReturn(Future.succeededFuture(mockResponse));
- Future> future = target.call(AuctionRequestPayloadImpl.of(bidRequest), auctionInvocationContext);
- InvocationResult result = future.result();
+ final Future> future = target.call(AuctionRequestPayloadImpl.of(bidRequest), auctionInvocationContext);
+ final InvocationResult result = future.result();
+ // then
assertThat(future).isNotNull();
assertThat(future.succeeded()).isTrue();
assertThat(result).isNotNull();
assertThat(result.status()).isEqualTo(InvocationStatus.success);
assertThat(result.action()).isEqualTo(InvocationAction.update);
- assertThat(result.payloadUpdate().apply(AuctionRequestPayloadImpl.of(bidRequest)).bidRequest().getUser().getEids()).isEqualTo(List.of(enrichedEid));
+ assertThat(result.payloadUpdate().apply(AuctionRequestPayloadImpl.of(bidRequest)).bidRequest().getUser().getEids()).isEqualTo(Collections.singletonList(enrichedEid));
}
}
From c1ad22fc2ef901a5897ceef50fec44fcd1d3173e Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Wed, 7 May 2025 13:05:08 +0200
Subject: [PATCH 14/43] Fix Collections API usage
---
...ntentOmniChannelIdentityProcessedAuctionRequestHookTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
index bef35918db7..bdf0f513cf1 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
@@ -105,7 +105,7 @@ public boolean matches(MultiMap entries) {
assertThat(result).isNotNull();
assertThat(result.status()).isEqualTo(InvocationStatus.success);
assertThat(result.action()).isEqualTo(InvocationAction.update);
- assertThat(result.payloadUpdate().apply(AuctionRequestPayloadImpl.of(bidRequest)).bidRequest().getUser().getEids()).isEqualTo(Collections.singletonList(providedEid).add(enrichedEid));
+ assertThat(result.payloadUpdate().apply(AuctionRequestPayloadImpl.of(bidRequest)).bidRequest().getUser().getEids()).isEqualTo(List.of(providedEid, enrichedEid));
}
@Test
From 26288b7d43300bb96d2bc814b9c86505ea0addb4 Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Wed, 14 May 2025 16:05:27 +0200
Subject: [PATCH 15/43] Clean up/format
---
.../README.md | 3 +-
...ntentOmniChannelIdentityConfiguration.java | 5 ++-
.../channel/identity/model/IdResResponse.java | 1 +
.../identity/model/config/ModuleConfig.java | 1 +
...elIdentityProcessedAuctionRequestHook.java | 11 +++--
.../model/config/IdResResponseTest.java | 8 +++-
.../model/config/ModuleConfigTest.java | 7 +--
...entityProcessedAuctionRequestHookTest.java | 43 ++++++++++++-------
8 files changed, 53 insertions(+), 26 deletions(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/README.md b/extra/modules/live-intent-omni-channel-identity/README.md
index 3e375864088..1165bdcb850 100644
--- a/extra/modules/live-intent-omni-channel-identity/README.md
+++ b/extra/modules/live-intent-omni-channel-identity/README.md
@@ -2,7 +2,7 @@
This module enriches bid requests with user EIDs.
-The user EIDs to be enriched are configured per partner as part of the LiveIntent HIRO onboarding process.
+The user EIDs to be enriched are configured per partner as part of the LiveIntent HIRO onboarding process.
## Configuration
@@ -40,5 +40,6 @@ hooks:
identity-resolution-endpoint: "https://liveintent.com/idx"
auth-token: "secret-token"
```
+
The partner-specific `auth-token` is provided by LiveIntent as part of the onboarding.
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
index ecceb0a4176..c140eac0cb3 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
@@ -16,8 +16,11 @@
import java.util.Set;
@Configuration
-@ConditionalOnProperty(prefix = "hooks." + LiveIntentOmniChannelIdentityModule.CODE, name = "enabled", havingValue = "true")
+@ConditionalOnProperty(
+ prefix = "hooks." + LiveIntentOmniChannelIdentityModule.CODE, name = "enabled", havingValue = "true"
+)
public class LiveIntentOmniChannelIdentityConfiguration {
+
@Bean
@ConfigurationProperties(prefix = "hooks.modules." + LiveIntentOmniChannelIdentityModule.CODE)
ModuleConfig moduleConfig() {
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java
index 0e72f5763ce..aba48041b37 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java
@@ -12,6 +12,7 @@
@Data
@Jacksonized
public class IdResResponse {
+
@JsonProperty("eids")
List eids;
}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
index cf35c8e9211..e7ed2893856 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
@@ -4,6 +4,7 @@
@Data
public final class ModuleConfig {
+
long requestTimeoutMs;
String identityResolutionEndpoint;
String authToken;
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
index 3b93f788bef..95db7b2bd55 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
@@ -30,7 +30,8 @@
public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHook implements ProcessedAuctionRequestHook {
- private static final Logger logger = LoggerFactory.getLogger(LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.class);
+ private static final Logger logger =
+ LoggerFactory.getLogger(LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.class);
private static final String CODE = "liveintent-omni-channel-identity-enrichment-hook";
private final ModuleConfig config;
@@ -48,7 +49,10 @@ public LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(
}
@Override
- public Future> call(AuctionRequestPayload auctionRequestPayload, AuctionInvocationContext invocationContext) {
+ public Future> call(
+ AuctionRequestPayload auctionRequestPayload,
+ AuctionInvocationContext invocationContext
+ ) {
final Future> update = requestEnrichment(auctionRequestPayload)
.map(resolutionResult ->
InvocationResultImpl.builder()
@@ -67,7 +71,8 @@ public String code() {
}
private AuctionRequestPayload updatedPayload(AuctionRequestPayload requestPayload, IdResResponse idResResponse) {
- final BidRequest bidRequest = Optional.ofNullable(requestPayload.bidRequest()).orElse(BidRequest.builder().build());
+ final BidRequest bidRequest = Optional.ofNullable(
+ requestPayload.bidRequest()).orElse(BidRequest.builder().build());
final User user = Optional.ofNullable(bidRequest.getUser()).orElse(User.builder().build());
final List allEids = new ArrayList<>();
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java
index 97fbb40e8d8..d6fb7da9b01 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java
@@ -9,18 +9,22 @@
import static org.assertj.core.api.Assertions.assertThat;
public class IdResResponseTest {
+
private JacksonMapper jacksonMapper;
@BeforeEach
public void setUp() {
- ObjectMapper mapper = new ObjectMapper();
+ final ObjectMapper mapper = new ObjectMapper();
jacksonMapper = new JacksonMapper(mapper);
}
@Test
public void shouldDecodeFromString() {
// given
- IdResResponse result = jacksonMapper.decodeValue("{\"eids\": [ { \"source\": \"liveintent.com\", \"uids\": [ { \"atype\": 3, \"id\" : \"some_id\" } ] } ] }", IdResResponse.class);
+ final IdResResponse result = jacksonMapper.decodeValue(
+ "{\"eids\": [ { \"source\": \"liveintent.com\", "
+ + "\"uids\": [ { \"atype\": 3, \"id\" : \"some_id\" } ] } ] }",
+ IdResResponse.class);
// when and then
assertThat(result.getEids()).hasSize(1);
assertThat(result.getEids().getFirst().getSource()).isEqualTo("liveintent.com");
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java
index 0ca4f894689..e1a90c411bd 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java
@@ -5,9 +5,10 @@
import static org.assertj.core.api.Assertions.assertThat;
public class ModuleConfigTest {
+
@Test
public void shouldReturnRequestTimeoutMs() {
- ModuleConfig moduleConfig = new ModuleConfig();
+ final ModuleConfig moduleConfig = new ModuleConfig();
moduleConfig.setRequestTimeoutMs(5);
assertThat(moduleConfig.getRequestTimeoutMs()).isEqualTo(5);
}
@@ -15,7 +16,7 @@ public void shouldReturnRequestTimeoutMs() {
@Test
public void shouldReturnIdentityResolutionEndpoint() {
// given
- ModuleConfig moduleConfig = new ModuleConfig();
+ final ModuleConfig moduleConfig = new ModuleConfig();
moduleConfig.setIdentityResolutionEndpoint("https://test.com/idres");
// when and then
assertThat(moduleConfig.getIdentityResolutionEndpoint()).isEqualTo("https://test.com/idres");
@@ -24,7 +25,7 @@ public void shouldReturnIdentityResolutionEndpoint() {
@Test
public void shouldReturnAuthToken() {
// given
- ModuleConfig moduleConfig = new ModuleConfig();
+ final ModuleConfig moduleConfig = new ModuleConfig();
moduleConfig.setAuthToken("secret_token");
// when and then
assertThat(moduleConfig.getAuthToken()).isEqualTo("secret_token");
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
index bdf0f513cf1..3c6c2c79b82 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
@@ -7,7 +7,6 @@
import com.iab.openrtb.request.User;
import io.vertx.core.Future;
import io.vertx.core.MultiMap;
-import org.assertj.core.api.ListAssert;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -24,20 +23,15 @@
import org.prebid.server.hooks.v1.auction.AuctionInvocationContext;
import org.prebid.server.hooks.v1.auction.AuctionRequestPayload;
import org.prebid.server.json.JacksonMapper;
-import org.prebid.server.util.HttpUtil;
import org.prebid.server.vertx.httpclient.HttpClient;
import org.prebid.server.vertx.httpclient.model.HttpClientResponse;
import java.util.Collections;
import java.util.List;
-import java.util.function.Consumer;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.ArgumentMatchers.assertArg;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -50,7 +44,7 @@ public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest {
@BeforeEach
public void setUp() {
- ObjectMapper mapper = new ObjectMapper();
+ final ObjectMapper mapper = new ObjectMapper();
jacksonMapper = new JacksonMapper(mapper);
moduleConfig = new ModuleConfig();
@@ -68,18 +62,26 @@ public void setUp() {
public void shouldAddResolvedEids() {
// given
final Uid providedUid = Uid.builder().id("id1").atype(2).build();
- final Eid providedEid = Eid.builder().source("some.source.com").uids(Collections.singletonList(providedUid)).build();
+ final Eid providedEid = Eid.builder().source("some.source.com")
+ .uids(Collections.singletonList(providedUid)).build();
final Uid enrichedUid = Uid.builder().id("id2").atype(3).build();
- final Eid enrichedEid = Eid.builder().source("liveintent.com").uids(Collections.singletonList(enrichedUid)).build();
+ final Eid enrichedEid = Eid.builder().source("liveintent.com")
+ .uids(Collections.singletonList(enrichedUid)).build();
final User user = User.builder().eids(Collections.singletonList(providedEid)).build();
final BidRequest bidRequest = BidRequest.builder().id("request").user(user).build();
- final AuctionInvocationContext auctionInvocationContext = AuctionInvocationContextImpl.of(null, null, false, null, null);
+ final AuctionInvocationContext auctionInvocationContext = AuctionInvocationContextImpl.of(
+ null, null, false, null, null);
final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
- when(mockResponse.getBody()).thenReturn("{\"eids\": [ { \"source\": \"" + enrichedEid.getSource() + "\", \"uids\": [ { \"atype\": " + enrichedUid.getAtype() + ", \"id\" : \"" + enrichedUid.getId() + "\" } ] } ] }");
+ when(mockResponse.getBody())
+ .thenReturn("{\"eids\": [ { \"source\": \"" + enrichedEid.getSource()
+ + "\", \"uids\": [ { \"atype\": "
+ + enrichedUid.getAtype()
+ + ", \"id\" : \""
+ + enrichedUid.getId() + "\" } ] } ] }");
// when
when(
@@ -96,7 +98,8 @@ public boolean matches(MultiMap entries) {
)
).thenReturn(Future.succeededFuture(mockResponse));
- final Future> future = target.call(AuctionRequestPayloadImpl.of(bidRequest), auctionInvocationContext);
+ final Future> future =
+ target.call(AuctionRequestPayloadImpl.of(bidRequest), auctionInvocationContext);
final InvocationResult result = future.result();
// then
@@ -105,22 +108,30 @@ public boolean matches(MultiMap entries) {
assertThat(result).isNotNull();
assertThat(result.status()).isEqualTo(InvocationStatus.success);
assertThat(result.action()).isEqualTo(InvocationAction.update);
- assertThat(result.payloadUpdate().apply(AuctionRequestPayloadImpl.of(bidRequest)).bidRequest().getUser().getEids()).isEqualTo(List.of(providedEid, enrichedEid));
+ assertThat(result.payloadUpdate().apply(AuctionRequestPayloadImpl.of(bidRequest))
+ .bidRequest().getUser().getEids()).isEqualTo(List.of(providedEid, enrichedEid));
}
@Test
public void shouldCreateUserWhenNotPresent() {
// given
final Uid enrichedUid = Uid.builder().id("id2").atype(3).build();
- final Eid enrichedEid = Eid.builder().source("liveintent.com").uids(Collections.singletonList(enrichedUid)).build();
+ final Eid enrichedEid = Eid.builder().source("liveintent.com")
+ .uids(Collections.singletonList(enrichedUid)).build();
final BidRequest bidRequest = BidRequest.builder().id("request").build();
- final AuctionInvocationContext auctionInvocationContext = AuctionInvocationContextImpl.of(null, null, false, null, null);
+ final AuctionInvocationContext auctionInvocationContext = AuctionInvocationContextImpl.of(
+ null, null, false, null, null);
// when
final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
- when(mockResponse.getBody()).thenReturn("{\"eids\": [{ \"source\": \"" + enrichedEid.getSource() + "\", \"uids\": [{ \"atype\": " + enrichedUid.getAtype() + ", \"id\" : \"" + enrichedUid.getId() + "\" }]}]}");
+ when(mockResponse.getBody())
+ .thenReturn("{\"eids\": [{ \"source\": \""
+ + enrichedEid.getSource()
+ + "\", \"uids\": [{ \"atype\": "
+ + enrichedUid.getAtype() + ", \"id\" : \""
+ + enrichedUid.getId() + "\" }]}]}");
when(
httpClient.post(
From 1f1a7cfc1aae98ad2422cb73b95552005f037194 Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Mon, 19 May 2025 11:39:40 +0200
Subject: [PATCH 16/43] Format
---
extra/modules/live-intent-omni-channel-identity/pom.xml | 2 +-
.../LiveIntentOmniChannelIdentityConfiguration.java | 2 +-
...niChannelIdentityProcessedAuctionRequestHookTest.java | 9 +++++++--
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/pom.xml b/extra/modules/live-intent-omni-channel-identity/pom.xml
index 03cf291d0da..e38a2199e23 100644
--- a/extra/modules/live-intent-omni-channel-identity/pom.xml
+++ b/extra/modules/live-intent-omni-channel-identity/pom.xml
@@ -5,7 +5,7 @@
org.prebid.server.hooks.modules
all-modules
- 3.25.0-SNAPSHOT
+ 3.26.0-SNAPSHOT
live-intent-omni-channel-identity
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
index c140eac0cb3..88ba0f7292e 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
@@ -17,7 +17,7 @@
@Configuration
@ConditionalOnProperty(
- prefix = "hooks." + LiveIntentOmniChannelIdentityModule.CODE, name = "enabled", havingValue = "true"
+ prefix = "hooks." + LiveIntentOmniChannelIdentityModule.CODE, name = "enabled", havingValue = "true"
)
public class LiveIntentOmniChannelIdentityConfiguration {
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
index 3c6c2c79b82..f213fd13ea3 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
@@ -147,7 +147,8 @@ public boolean matches(MultiMap entries) {
)
).thenReturn(Future.succeededFuture(mockResponse));
- final Future> future = target.call(AuctionRequestPayloadImpl.of(bidRequest), auctionInvocationContext);
+ final Future> future
+ = target.call(AuctionRequestPayloadImpl.of(bidRequest), auctionInvocationContext);
final InvocationResult result = future.result();
// then
@@ -156,6 +157,10 @@ public boolean matches(MultiMap entries) {
assertThat(result).isNotNull();
assertThat(result.status()).isEqualTo(InvocationStatus.success);
assertThat(result.action()).isEqualTo(InvocationAction.update);
- assertThat(result.payloadUpdate().apply(AuctionRequestPayloadImpl.of(bidRequest)).bidRequest().getUser().getEids()).isEqualTo(Collections.singletonList(enrichedEid));
+ assertThat(result.payloadUpdate()
+ .apply(AuctionRequestPayloadImpl.of(bidRequest))
+ .bidRequest()
+ .getUser()
+ .getEids()).isEqualTo(Collections.singletonList(enrichedEid));
}
}
From c9659addd035a8686d4ed85fbd12643fcd27c23d Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Mon, 19 May 2025 13:02:22 +0200
Subject: [PATCH 17/43] Add treatment rate
---
.../README.md | 7 +--
.../identity/model/config/ModuleConfig.java | 1 +
...elIdentityProcessedAuctionRequestHook.java | 40 +++++++++++----
...entityProcessedAuctionRequestHookTest.java | 51 ++++++++++++++++---
4 files changed, 80 insertions(+), 19 deletions(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/README.md b/extra/modules/live-intent-omni-channel-identity/README.md
index 1165bdcb850..be5ad801ec1 100644
--- a/extra/modules/live-intent-omni-channel-identity/README.md
+++ b/extra/modules/live-intent-omni-channel-identity/README.md
@@ -2,7 +2,9 @@
This module enriches bid requests with user EIDs.
-The user EIDs to be enriched are configured per partner as part of the LiveIntent HIRO onboarding process.
+The user EIDs to be enriched are configured per partner as part of the LiveIntent HIRO onboarding process. As part of this onboarding process, partners will also be provided with the `identity-resolution-endpoint` URL as well as with the `auth-token`.
+
+`treatment-rate` is a value between 0.0 and 1.0 (including 0.0 and 1.0) and defines the percentage of requests for which identity enrichment should be performed. This value can be freely picked. We recommend a value between 0.9 and 0.95
## Configuration
@@ -39,7 +41,6 @@ hooks:
request-timeout-ms: 2000
identity-resolution-endpoint: "https://liveintent.com/idx"
auth-token: "secret-token"
+ treatment-rate: 0.9
```
-The partner-specific `auth-token` is provided by LiveIntent as part of the onboarding.
-
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
index e7ed2893856..f17bc3c549d 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
@@ -8,4 +8,5 @@ public final class ModuleConfig {
long requestTimeoutMs;
String identityResolutionEndpoint;
String authToken;
+ float treatmentRate;
}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
index 95db7b2bd55..ac5024a3b9b 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
@@ -27,6 +27,7 @@
import java.util.List;
import java.util.Objects;
import java.util.Optional;
+import java.util.Random;
public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHook implements ProcessedAuctionRequestHook {
@@ -37,15 +38,26 @@ public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHook implements
private final ModuleConfig config;
private final JacksonMapper mapper;
private final HttpClient httpClient;
+ private final Random random;
public LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(
ModuleConfig config,
JacksonMapper mapper,
HttpClient httpClient) {
+ this(config, mapper, httpClient, new Random());
+ }
+
+ public LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(
+ ModuleConfig config,
+ JacksonMapper mapper,
+ HttpClient httpClient,
+ Random random) {
+
this.config = Objects.requireNonNull(config);
this.mapper = Objects.requireNonNull(mapper);
this.httpClient = Objects.requireNonNull(httpClient);
+ this.random = random;
}
@Override
@@ -53,16 +65,24 @@ public Future> call(
AuctionRequestPayload auctionRequestPayload,
AuctionInvocationContext invocationContext
) {
- final Future> update = requestEnrichment(auctionRequestPayload)
- .map(resolutionResult ->
- InvocationResultImpl.builder()
- .status(InvocationStatus.success)
- .action(InvocationAction.update)
- .payloadUpdate(requestPayload -> updatedPayload(requestPayload, resolutionResult))
- .build()
- );
-
- return update.onFailure(throwable -> logger.error("Failed enrichment:", throwable));
+ if (random.nextFloat() < config.getTreatmentRate()) {
+ final Future> update = requestEnrichment(auctionRequestPayload)
+ .map(resolutionResult ->
+ InvocationResultImpl.builder()
+ .status(InvocationStatus.success)
+ .action(InvocationAction.update)
+ .payloadUpdate(requestPayload -> updatedPayload(requestPayload, resolutionResult))
+ .build()
+ );
+
+ return update.onFailure(throwable -> logger.error("Failed enrichment:", throwable));
+ } else {
+ return Future.succeededFuture(
+ InvocationResultImpl.builder()
+ .status(InvocationStatus.success)
+ .action(InvocationAction.no_action)
+ .build());
+ }
}
@Override
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
index f213fd13ea3..488df3ec770 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
@@ -28,6 +28,7 @@
import java.util.Collections;
import java.util.List;
+import java.util.Random;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.argThat;
@@ -42,6 +43,11 @@ public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest {
private LiveIntentOmniChannelIdentityProcessedAuctionRequestHook target;
private JacksonMapper jacksonMapper;
+ @Mock
+ private HttpClient httpClient;
+ @Mock
+ private Random random;
+
@BeforeEach
public void setUp() {
final ObjectMapper mapper = new ObjectMapper();
@@ -51,13 +57,12 @@ public void setUp() {
moduleConfig.setRequestTimeoutMs(5);
moduleConfig.setIdentityResolutionEndpoint("https://test.com/idres");
moduleConfig.setAuthToken("secret_auth_token");
+ moduleConfig.setTreatmentRate(0.9f);
- target = new LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(moduleConfig, jacksonMapper, httpClient);
+ target = new LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(
+ moduleConfig, jacksonMapper, httpClient, random);
}
- @Mock
- private HttpClient httpClient;
-
@Test
public void shouldAddResolvedEids() {
// given
@@ -76,6 +81,9 @@ public void shouldAddResolvedEids() {
null, null, false, null, null);
final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
+ // when
+ when(random.nextFloat()).thenReturn(0.89f);
+
when(mockResponse.getBody())
.thenReturn("{\"eids\": [ { \"source\": \"" + enrichedEid.getSource()
+ "\", \"uids\": [ { \"atype\": "
@@ -83,7 +91,6 @@ public void shouldAddResolvedEids() {
+ ", \"id\" : \""
+ enrichedUid.getId() + "\" } ] } ] }");
- // when
when(
httpClient.post(
eq(moduleConfig.getIdentityResolutionEndpoint()),
@@ -112,6 +119,35 @@ public boolean matches(MultiMap entries) {
.bidRequest().getUser().getEids()).isEqualTo(List.of(providedEid, enrichedEid));
}
+ @Test
+ public void shouldNotAttemptToResolveEids() {
+ // given
+ final Uid providedUid = Uid.builder().id("id1").atype(2).build();
+ final Eid providedEid = Eid.builder().source("some.source.com")
+ .uids(Collections.singletonList(providedUid)).build();
+
+ final User user = User.builder().eids(Collections.singletonList(providedEid)).build();
+ final BidRequest bidRequest = BidRequest.builder().id("request").user(user).build();
+
+ final AuctionInvocationContext auctionInvocationContext = AuctionInvocationContextImpl.of(
+ null, null, false, null, null);
+
+ // when
+ when(random.nextFloat()).thenReturn(0.91f);
+
+ final Future> future =
+ target.call(AuctionRequestPayloadImpl.of(bidRequest), auctionInvocationContext);
+ final InvocationResult result = future.result();
+
+ // then
+ assertThat(future).isNotNull();
+ assertThat(future.succeeded()).isTrue();
+ assertThat(result).isNotNull();
+ assertThat(result.status()).isEqualTo(InvocationStatus.success);
+ assertThat(result.action()).isEqualTo(InvocationAction.no_action);
+ assertThat(result.payloadUpdate()).isNull();
+ }
+
@Test
public void shouldCreateUserWhenNotPresent() {
// given
@@ -124,8 +160,11 @@ public void shouldCreateUserWhenNotPresent() {
final AuctionInvocationContext auctionInvocationContext = AuctionInvocationContextImpl.of(
null, null, false, null, null);
- // when
final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
+
+ // when
+ when(random.nextFloat()).thenReturn(0.89f);
+
when(mockResponse.getBody())
.thenReturn("{\"eids\": [{ \"source\": \""
+ enrichedEid.getSource()
From 3ed7ee8d98514b029711e342629f7c247a7cf8c1 Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Wed, 11 Jun 2025 13:18:41 +0200
Subject: [PATCH 18/43] Remove superflous JsonProperty annotation
---
.../liveintent/omni/channel/identity/model/IdResResponse.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java
index aba48041b37..3f8432e36c5 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java
@@ -1,6 +1,5 @@
package org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model;
-import com.fasterxml.jackson.annotation.JsonProperty;
import com.iab.openrtb.request.Eid;
import lombok.Builder;
import lombok.Data;
@@ -13,6 +12,5 @@
@Jacksonized
public class IdResResponse {
- @JsonProperty("eids")
List eids;
}
From bedb9690e7153306f5e781573b3d2848852dc38e Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Wed, 11 Jun 2025 13:19:45 +0200
Subject: [PATCH 19/43] Separate field by line
---
.../omni/channel/identity/model/config/ModuleConfig.java | 3 +++
1 file changed, 3 insertions(+)
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
index f17bc3c549d..a7fc92b1feb 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
@@ -6,7 +6,10 @@
public final class ModuleConfig {
long requestTimeoutMs;
+
String identityResolutionEndpoint;
+
String authToken;
+
float treatmentRate;
}
From d94e06f044228661bfa161078bbc4d6e434eccd1 Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Wed, 11 Jun 2025 13:36:29 +0200
Subject: [PATCH 20/43] Use RandomGenerator + ThreadLocalRandom instead of
Random
---
...LiveIntentOmniChannelIdentityConfiguration.java | 4 +++-
...ChannelIdentityProcessedAuctionRequestHook.java | 14 +++-----------
2 files changed, 6 insertions(+), 12 deletions(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
index 88ba0f7292e..efc98d4d105 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
@@ -14,6 +14,7 @@
import org.springframework.context.annotation.Configuration;
import java.util.Set;
+import java.util.concurrent.ThreadLocalRandom;
@Configuration
@ConditionalOnProperty(
@@ -30,7 +31,8 @@ ModuleConfig moduleConfig() {
@Bean
Module liveIntentOmniChannelIdentityModule(ModuleConfig config, JacksonMapper mapper, HttpClient httpClient) {
final Set extends Hook, ? extends InvocationContext>> hooks = Set.of(
- new LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(config, mapper, httpClient));
+ new LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(
+ config, mapper, httpClient, () -> ThreadLocalRandom.current().nextLong()));
return new LiveIntentOmniChannelIdentityModule(hooks);
}
}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
index ac5024a3b9b..6ab5db8a13f 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
@@ -27,7 +27,7 @@
import java.util.List;
import java.util.Objects;
import java.util.Optional;
-import java.util.Random;
+import java.util.random.RandomGenerator;
public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHook implements ProcessedAuctionRequestHook {
@@ -38,21 +38,13 @@ public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHook implements
private final ModuleConfig config;
private final JacksonMapper mapper;
private final HttpClient httpClient;
- private final Random random;
-
- public LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(
- ModuleConfig config,
- JacksonMapper mapper,
- HttpClient httpClient) {
-
- this(config, mapper, httpClient, new Random());
- }
+ private final RandomGenerator random;
public LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(
ModuleConfig config,
JacksonMapper mapper,
HttpClient httpClient,
- Random random) {
+ RandomGenerator random) {
this.config = Objects.requireNonNull(config);
this.mapper = Objects.requireNonNull(mapper);
From 61ceeed89ff2ce30d1103428185a0d4461b825ce Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Wed, 11 Jun 2025 13:47:31 +0200
Subject: [PATCH 21/43] Apply code style
---
...veIntentOmniChannelIdentityProcessedAuctionRequestHook.java | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
index 6ab5db8a13f..9494ee19f3f 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
@@ -64,8 +64,7 @@ public Future> call(
.status(InvocationStatus.success)
.action(InvocationAction.update)
.payloadUpdate(requestPayload -> updatedPayload(requestPayload, resolutionResult))
- .build()
- );
+ .build());
return update.onFailure(throwable -> logger.error("Failed enrichment:", throwable));
} else {
From fa66d1846282ae717d4dd0c840b238c8ca35b63d Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Wed, 11 Jun 2025 13:49:40 +0200
Subject: [PATCH 22/43] Apply style guide: method order
---
...elIdentityProcessedAuctionRequestHook.java | 40 +++++++++----------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
index 9494ee19f3f..d1c6cba6d2f 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
@@ -76,9 +76,23 @@ public Future> call(
}
}
- @Override
- public String code() {
- return CODE;
+ private Future requestEnrichment(AuctionRequestPayload auctionRequestPayload) {
+ final String bidRequestJson = mapper.encodeToString(auctionRequestPayload.bidRequest());
+ return httpClient.post(
+ config.getIdentityResolutionEndpoint(),
+ headers(),
+ bidRequestJson,
+ config.getRequestTimeoutMs())
+ .map(this::processResponse);
+ }
+
+ private MultiMap headers() {
+ return MultiMap.caseInsensitiveMultiMap()
+ .add(HttpUtil.AUTHORIZATION_HEADER, "Bearer " + config.getAuthToken());
+ }
+
+ private IdResResponse processResponse(HttpClientResponse response) {
+ return mapper.decodeValue(response.getBody(), IdResResponse.class);
}
private AuctionRequestPayload updatedPayload(AuctionRequestPayload requestPayload, IdResResponse idResResponse) {
@@ -96,22 +110,8 @@ private AuctionRequestPayload updatedPayload(AuctionRequestPayload requestPayloa
return AuctionRequestPayloadImpl.of(updatedBidRequest);
}
- private Future requestEnrichment(AuctionRequestPayload auctionRequestPayload) {
- final String bidRequestJson = mapper.encodeToString(auctionRequestPayload.bidRequest());
- return httpClient.post(
- config.getIdentityResolutionEndpoint(),
- headers(),
- bidRequestJson,
- config.getRequestTimeoutMs())
- .map(this::processResponse);
- }
-
- private IdResResponse processResponse(HttpClientResponse response) {
- return mapper.decodeValue(response.getBody(), IdResResponse.class);
- }
-
- private MultiMap headers() {
- return MultiMap.caseInsensitiveMultiMap()
- .add(HttpUtil.AUTHORIZATION_HEADER, "Bearer " + config.getAuthToken());
+ @Override
+ public String code() {
+ return CODE;
}
}
From 09450d257e08f242000080a105442f9e288b6bad Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Wed, 11 Jun 2025 13:53:13 +0200
Subject: [PATCH 23/43] Add empty lines to separate test stages
---
.../omni/channel/identity/model/config/IdResResponseTest.java | 1 +
.../omni/channel/identity/model/config/ModuleConfigTest.java | 2 ++
...ntentOmniChannelIdentityProcessedAuctionRequestHookTest.java | 1 +
3 files changed, 4 insertions(+)
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java
index d6fb7da9b01..d53854e7eea 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java
@@ -25,6 +25,7 @@ public void shouldDecodeFromString() {
"{\"eids\": [ { \"source\": \"liveintent.com\", "
+ "\"uids\": [ { \"atype\": 3, \"id\" : \"some_id\" } ] } ] }",
IdResResponse.class);
+
// when and then
assertThat(result.getEids()).hasSize(1);
assertThat(result.getEids().getFirst().getSource()).isEqualTo("liveintent.com");
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java
index e1a90c411bd..39cfd34298e 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java
@@ -18,6 +18,7 @@ public void shouldReturnIdentityResolutionEndpoint() {
// given
final ModuleConfig moduleConfig = new ModuleConfig();
moduleConfig.setIdentityResolutionEndpoint("https://test.com/idres");
+
// when and then
assertThat(moduleConfig.getIdentityResolutionEndpoint()).isEqualTo("https://test.com/idres");
}
@@ -27,6 +28,7 @@ public void shouldReturnAuthToken() {
// given
final ModuleConfig moduleConfig = new ModuleConfig();
moduleConfig.setAuthToken("secret_token");
+
// when and then
assertThat(moduleConfig.getAuthToken()).isEqualTo("secret_token");
}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
index 488df3ec770..f454fd2ce99 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
@@ -81,6 +81,7 @@ public void shouldAddResolvedEids() {
null, null, false, null, null);
final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
+
// when
when(random.nextFloat()).thenReturn(0.89f);
From b588f6a641da1d9fb8b7907ed5846ad5e2592e6e Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Wed, 11 Jun 2025 14:17:09 +0200
Subject: [PATCH 24/43] Use NoArgsConstructor instead of Jacksonized
---
.../omni/channel/identity/model/IdResResponse.java | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java
index 3f8432e36c5..c94df691c2f 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/IdResResponse.java
@@ -1,15 +1,13 @@
package org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model;
import com.iab.openrtb.request.Eid;
-import lombok.Builder;
import lombok.Data;
-import lombok.extern.jackson.Jacksonized;
+import lombok.NoArgsConstructor;
import java.util.List;
-@Builder
@Data
-@Jacksonized
+@NoArgsConstructor
public class IdResResponse {
List eids;
From f597339101608ddd0effaa719e0cac6d50e5565e Mon Sep 17 00:00:00 2001
From: Viktor Dreiling <34981284+3link@users.noreply.github.com>
Date: Wed, 11 Jun 2025 18:14:55 +0200
Subject: [PATCH 25/43] Bump dependency version
---
extra/modules/live-intent-omni-channel-identity/pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/pom.xml b/extra/modules/live-intent-omni-channel-identity/pom.xml
index e38a2199e23..95863109ecd 100644
--- a/extra/modules/live-intent-omni-channel-identity/pom.xml
+++ b/extra/modules/live-intent-omni-channel-identity/pom.xml
@@ -5,7 +5,7 @@
org.prebid.server.hooks.modules
all-modules
- 3.26.0-SNAPSHOT
+ 3.27.0-SNAPSHOT
live-intent-omni-channel-identity
From 5f15bf19db3ce39959423f9c45b3d473d5cda670 Mon Sep 17 00:00:00 2001
From: ilya
Date: Tue, 29 Jul 2025 17:33:52 +0200
Subject: [PATCH 26/43] cm-1776: PR issues fixed
---
...ntentOmniChannelIdentityConfiguration.java | 5 ++-
...elIdentityProcessedAuctionRequestHook.java | 40 +++++++++----------
.../model/config/IdResResponseTest.java | 14 ++++---
...entityProcessedAuctionRequestHookTest.java | 28 +++++--------
4 files changed, 41 insertions(+), 46 deletions(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
index efc98d4d105..7eab97804cc 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/config/LiveIntentOmniChannelIdentityConfiguration.java
@@ -18,8 +18,9 @@
@Configuration
@ConditionalOnProperty(
- prefix = "hooks." + LiveIntentOmniChannelIdentityModule.CODE, name = "enabled", havingValue = "true"
-)
+ prefix = "hooks." + LiveIntentOmniChannelIdentityModule.CODE,
+ name = "enabled",
+ havingValue = "true")
public class LiveIntentOmniChannelIdentityConfiguration {
@Bean
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
index d1c6cba6d2f..421bdb4caee 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
@@ -19,10 +19,10 @@
import org.prebid.server.log.Logger;
import org.prebid.server.log.LoggerFactory;
import org.prebid.server.util.HttpUtil;
+import org.prebid.server.util.ListUtil;
import org.prebid.server.vertx.httpclient.HttpClient;
import org.prebid.server.vertx.httpclient.model.HttpClientResponse;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -49,31 +49,29 @@ public LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(
this.config = Objects.requireNonNull(config);
this.mapper = Objects.requireNonNull(mapper);
this.httpClient = Objects.requireNonNull(httpClient);
- this.random = random;
+ this.random = Objects.requireNonNull(random);
}
@Override
public Future> call(
AuctionRequestPayload auctionRequestPayload,
- AuctionInvocationContext invocationContext
- ) {
+ AuctionInvocationContext invocationContext) {
if (random.nextFloat() < config.getTreatmentRate()) {
- final Future> update = requestEnrichment(auctionRequestPayload)
- .map(resolutionResult ->
+ return requestEnrichment(auctionRequestPayload)
+ .>map(resolutionResult ->
InvocationResultImpl.builder()
.status(InvocationStatus.success)
.action(InvocationAction.update)
.payloadUpdate(requestPayload -> updatedPayload(requestPayload, resolutionResult))
- .build());
-
- return update.onFailure(throwable -> logger.error("Failed enrichment:", throwable));
- } else {
- return Future.succeededFuture(
- InvocationResultImpl.builder()
- .status(InvocationStatus.success)
- .action(InvocationAction.no_action)
- .build());
+ .build())
+ .onFailure(throwable -> logger.error("Failed enrichment:", throwable));
}
+ return Future.succeededFuture(
+ InvocationResultImpl.builder()
+ .status(InvocationStatus.success)
+ .action(InvocationAction.no_action)
+ .build());
+
}
private Future requestEnrichment(AuctionRequestPayload auctionRequestPayload) {
@@ -96,13 +94,13 @@ private IdResResponse processResponse(HttpClientResponse response) {
}
private AuctionRequestPayload updatedPayload(AuctionRequestPayload requestPayload, IdResResponse idResResponse) {
- final BidRequest bidRequest = Optional.ofNullable(
- requestPayload.bidRequest()).orElse(BidRequest.builder().build());
- final User user = Optional.ofNullable(bidRequest.getUser()).orElse(User.builder().build());
+ final User user = Optional.ofNullable(
+ requestPayload.bidRequest())
+ .map(BidRequest::getUser)
+ .orElse(User.builder().build());
- final List allEids = new ArrayList<>();
- allEids.addAll(Optional.ofNullable(user.getEids()).orElse(Collections.emptyList()));
- allEids.addAll(idResResponse.getEids());
+ final List allEids = ListUtil.union(
+ Optional.ofNullable(user.getEids()).orElse(Collections.emptyList()), idResResponse.getEids());
final User updatedUser = user.toBuilder().eids(allEids).build();
final BidRequest updatedBidRequest = requestPayload.bidRequest().toBuilder().user(updatedUser).build();
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java
index d53854e7eea..aa073979b34 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java
@@ -1,11 +1,15 @@
package org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.config;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.iab.openrtb.request.Eid;
+import com.iab.openrtb.request.Uid;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.IdResResponse;
import org.prebid.server.json.JacksonMapper;
+import java.util.List;
+
import static org.assertj.core.api.Assertions.assertThat;
public class IdResResponseTest {
@@ -27,10 +31,10 @@ public void shouldDecodeFromString() {
IdResResponse.class);
// when and then
- assertThat(result.getEids()).hasSize(1);
- assertThat(result.getEids().getFirst().getSource()).isEqualTo("liveintent.com");
- assertThat(result.getEids().getFirst().getUids()).hasSize(1);
- assertThat(result.getEids().getFirst().getUids().getFirst().getAtype()).isEqualTo(3);
- assertThat(result.getEids().getFirst().getUids().getFirst().getId()).isEqualTo("some_id");
+ assertThat(result.getEids()).isEqualTo(List.of(
+ Eid.builder()
+ .source("liveintent.com")
+ .uids(List.of(Uid.builder().atype(3).id("some_id").build()))
+ .build()));
}
}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
index f454fd2ce99..57f0d926bb1 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
@@ -48,6 +48,13 @@ public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest {
@Mock
private Random random;
+ private final ArgumentMatcher bearerAuthHeaderMatcher = new ArgumentMatcher<>() {
+ @Override
+ public boolean matches(MultiMap entries) {
+ return entries.contains("Authorization", "Bearer " + moduleConfig.getAuthToken(), true);
+ }
+ };
+
@BeforeEach
public void setUp() {
final ObjectMapper mapper = new ObjectMapper();
@@ -61,6 +68,7 @@ public void setUp() {
target = new LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(
moduleConfig, jacksonMapper, httpClient, random);
+
}
@Test
@@ -95,12 +103,7 @@ public void shouldAddResolvedEids() {
when(
httpClient.post(
eq(moduleConfig.getIdentityResolutionEndpoint()),
- argThat(new ArgumentMatcher() {
- @Override
- public boolean matches(MultiMap entries) {
- return entries.contains("Authorization", "Bearer " + moduleConfig.getAuthToken(), true);
- }
- }),
+ argThat(bearerAuthHeaderMatcher),
eq(jacksonMapper.encodeToString(bidRequest)),
eq(moduleConfig.getRequestTimeoutMs())
)
@@ -111,9 +114,7 @@ public boolean matches(MultiMap entries) {
final InvocationResult result = future.result();
// then
- assertThat(future).isNotNull();
assertThat(future.succeeded()).isTrue();
- assertThat(result).isNotNull();
assertThat(result.status()).isEqualTo(InvocationStatus.success);
assertThat(result.action()).isEqualTo(InvocationAction.update);
assertThat(result.payloadUpdate().apply(AuctionRequestPayloadImpl.of(bidRequest))
@@ -141,9 +142,7 @@ public void shouldNotAttemptToResolveEids() {
final InvocationResult result = future.result();
// then
- assertThat(future).isNotNull();
assertThat(future.succeeded()).isTrue();
- assertThat(result).isNotNull();
assertThat(result.status()).isEqualTo(InvocationStatus.success);
assertThat(result.action()).isEqualTo(InvocationAction.no_action);
assertThat(result.payloadUpdate()).isNull();
@@ -176,12 +175,7 @@ public void shouldCreateUserWhenNotPresent() {
when(
httpClient.post(
eq(moduleConfig.getIdentityResolutionEndpoint()),
- argThat(new ArgumentMatcher() {
- @Override
- public boolean matches(MultiMap entries) {
- return entries.contains("Authorization", "Bearer " + moduleConfig.getAuthToken(), true);
- }
- }),
+ argThat(bearerAuthHeaderMatcher),
eq(jacksonMapper.encodeToString(bidRequest)),
eq(moduleConfig.getRequestTimeoutMs())
)
@@ -192,9 +186,7 @@ public boolean matches(MultiMap entries) {
final InvocationResult result = future.result();
// then
- assertThat(future).isNotNull();
assertThat(future.succeeded()).isTrue();
- assertThat(result).isNotNull();
assertThat(result.status()).isEqualTo(InvocationStatus.success);
assertThat(result.action()).isEqualTo(InvocationAction.update);
assertThat(result.payloadUpdate()
From 587d6fb6d0277e26ab9b7758890f5c646b1089de Mon Sep 17 00:00:00 2001
From: ilya
Date: Tue, 29 Jul 2025 10:59:28 +0200
Subject: [PATCH 27/43] DATA-22937: WIP
---
...elIdentityProcessedAuctionRequestHook.java | 13 ++
...entityProcessedAuctionRequestHookTest.java | 4 +-
.../LiveIntentAnalyticsReporter.java | 160 ++++++++++++++++++
.../model/LiveIntentAnalyticsProperties.java | 15 ++
.../reporter/liveintent/model/PbsjBid.java | 22 +++
.../spring/config/AnalyticsConfiguration.java | 44 +++++
.../LiveintentAnalyticsReporterTest.java | 72 ++++++++
7 files changed, 327 insertions(+), 3 deletions(-)
create mode 100644 src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
create mode 100644 src/main/java/org/prebid/server/analytics/reporter/liveintent/model/LiveIntentAnalyticsProperties.java
create mode 100644 src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java
create mode 100644 src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
index 421bdb4caee..7f0f1a4b231 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
@@ -5,7 +5,11 @@
import com.iab.openrtb.request.User;
import io.vertx.core.Future;
import io.vertx.core.MultiMap;
+import org.prebid.server.activity.Activity;
import org.prebid.server.hooks.execution.v1.InvocationResultImpl;
+import org.prebid.server.hooks.execution.v1.analytics.ActivityImpl;
+import org.prebid.server.hooks.execution.v1.analytics.ResultImpl;
+import org.prebid.server.hooks.execution.v1.analytics.TagsImpl;
import org.prebid.server.hooks.execution.v1.auction.AuctionRequestPayloadImpl;
import org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.IdResResponse;
import org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.config.ModuleConfig;
@@ -39,6 +43,8 @@ public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHook implements
private final JacksonMapper mapper;
private final HttpClient httpClient;
private final RandomGenerator random;
+ private final ActivityImpl enriched = ActivityImpl.of("liveintent-enriched", "success", List.of());
+ private final ActivityImpl treatmentRate;
public LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(
ModuleConfig config,
@@ -50,6 +56,11 @@ public LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(
this.mapper = Objects.requireNonNull(mapper);
this.httpClient = Objects.requireNonNull(httpClient);
this.random = Objects.requireNonNull(random);
+ this.treatmentRate = ActivityImpl.of(
+ "liveintent-treatment-rate",
+ String.valueOf(config.getTreatmentRate()),
+ List.of()
+ );
}
@Override
@@ -63,6 +74,7 @@ public Future> call(
.status(InvocationStatus.success)
.action(InvocationAction.update)
.payloadUpdate(requestPayload -> updatedPayload(requestPayload, resolutionResult))
+ .analyticsTags(TagsImpl.of(List.of(enriched, treatmentRate)))
.build())
.onFailure(throwable -> logger.error("Failed enrichment:", throwable));
}
@@ -70,6 +82,7 @@ public Future> call(
InvocationResultImpl.builder()
.status(InvocationStatus.success)
.action(InvocationAction.no_action)
+ .analyticsTags(TagsImpl.of(List.of(treatmentRate)))
.build());
}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
index 57f0d926bb1..24ae8acc371 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest.java
@@ -64,11 +64,9 @@ public void setUp() {
moduleConfig.setRequestTimeoutMs(5);
moduleConfig.setIdentityResolutionEndpoint("https://test.com/idres");
moduleConfig.setAuthToken("secret_auth_token");
- moduleConfig.setTreatmentRate(0.9f);
target = new LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(
- moduleConfig, jacksonMapper, httpClient, random);
-
+ moduleConfig, 0.9f, jacksonMapper, httpClient, random);
}
@Test
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
new file mode 100644
index 00000000000..9db6b11adda
--- /dev/null
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
@@ -0,0 +1,160 @@
+package org.prebid.server.analytics.reporter.liveintent;
+
+import com.iab.openrtb.request.BidRequest;
+import com.iab.openrtb.response.BidResponse;
+import io.vertx.core.Future;
+import org.prebid.server.analytics.AnalyticsReporter;
+import org.prebid.server.analytics.model.AuctionEvent;
+import org.prebid.server.analytics.model.NotificationEvent;
+import org.prebid.server.analytics.reporter.liveintent.model.LiveIntentAnalyticsProperties;
+import org.prebid.server.analytics.reporter.liveintent.model.PbsjBid;
+import org.prebid.server.auction.model.AuctionContext;
+import org.prebid.server.exception.PreBidException;
+import org.prebid.server.hooks.execution.model.ExecutionStatus;
+import org.prebid.server.hooks.execution.model.GroupExecutionOutcome;
+import org.prebid.server.hooks.execution.model.HookExecutionContext;
+import org.prebid.server.hooks.execution.model.HookExecutionOutcome;
+import org.prebid.server.hooks.execution.model.Stage;
+import org.prebid.server.hooks.execution.model.StageExecutionOutcome;
+import org.prebid.server.hooks.v1.analytics.Activity;
+import org.prebid.server.hooks.v1.analytics.Tags;
+import org.prebid.server.json.JacksonMapper;
+import org.prebid.server.log.Logger;
+import org.prebid.server.log.LoggerFactory;
+import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebid;
+import org.prebid.server.vertx.httpclient.HttpClient;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+public class LiveIntentAnalyticsReporter implements AnalyticsReporter {
+
+ private final HttpClient httpClient;
+ private final LiveIntentAnalyticsProperties properties;
+ private final JacksonMapper jacksonMapper;
+
+ private static final Logger logger = LoggerFactory.getLogger(LiveIntentAnalyticsReporter.class);
+
+ public LiveIntentAnalyticsReporter(
+ LiveIntentAnalyticsProperties properties,
+ HttpClient httpClient,
+ JacksonMapper jacksonMapper
+ ) {
+ this.httpClient = Objects.requireNonNull(httpClient);
+ this.properties = Objects.requireNonNull(properties);
+ this.jacksonMapper = Objects.requireNonNull(jacksonMapper);
+ }
+
+ @Override
+ public Future processEvent(T event) {
+ if (event instanceof AuctionEvent auctionEvent) {
+ return processAuctionEvent(auctionEvent.getAuctionContext());
+ } else if (event instanceof NotificationEvent notificationEvent) {
+ return processNotificationEvent(notificationEvent);
+ }
+
+ return Future.succeededFuture();
+ }
+
+ private Future processNotificationEvent(NotificationEvent notificationEvent) {
+ final String url = properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-winning-bid?"
+ + "b=" + notificationEvent.getBidder()
+ + "&bidId=" + notificationEvent.getBidId();
+ return httpClient.get(url, properties.getTimeoutMs()).mapEmpty();
+ }
+
+ private Future processAuctionEvent(AuctionContext auctionContext) {
+ try {
+ final BidRequest bidRequest = Optional.ofNullable(auctionContext.getBidRequest())
+ .orElseThrow(() -> new PreBidException("Bid response should not be empty"));
+ final BidResponse bidResponse = Optional.ofNullable(auctionContext.getBidResponse())
+ .orElseThrow(() -> new PreBidException("Bid response should not be empty"));
+ final Optional requestPrebid = Optional.ofNullable(bidRequest.getExt())
+ .flatMap(ext -> Optional.of(ext.getPrebid()));
+
+ final Stream activities = getActivities(auctionContext);
+
+ final List pbsjBids = bidResponse.getSeatbid().stream()
+ .flatMap(seatBid -> seatBid.getBid().stream())
+ .flatMap(bid ->
+ bidRequest.getImp().stream()
+ .filter(impItem -> impItem.getId().equals(bid.getImpid()))
+ .findFirst()
+ .stream()
+ .map(imp ->
+ PbsjBid.builder()
+ .bidId(bid.getId())
+ .price(bid.getPrice())
+ .adUnitId(imp.getTagid())
+ .enriched(isEnriched(activities))
+ .currency(bidResponse.getCur())
+ .treatmentRate(getTreatmentRate(activities))
+ .timestamp(requestPrebid.map(ExtRequestPrebid::getAuctiontimestamp).orElse(0L))
+ .partnerId(properties.getPartnerId())
+ .build()
+ )
+ ).toList();
+
+ return httpClient.post(
+ properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-bids",
+ jacksonMapper.encodeToString(pbsjBids),
+ properties.getTimeoutMs()
+ ).mapEmpty();
+ } catch (Exception e) {
+ logger.error("Error processing event: {}", e.getMessage());
+ return Future.failedFuture(e);
+ }
+ }
+
+ private Stream getActivities(AuctionContext auctionContext) {
+ return Optional.ofNullable(auctionContext)
+ .map(AuctionContext::getHookExecutionContext)
+ .map(HookExecutionContext::getStageOutcomes)
+ .map(stages -> stages.get(Stage.processed_auction_request)).stream()
+ .flatMap(Collection::stream)
+ .filter(stageExecutionOutcome -> "auction-request".equals(stageExecutionOutcome.getEntity()))
+ .map(StageExecutionOutcome::getGroups)
+ .flatMap(Collection::stream)
+ .map(GroupExecutionOutcome::getHooks)
+ .flatMap(Collection::stream)
+ .filter(hook ->
+ "liveintent-omni-channel-identity-enrichment-hook".equals(hook.getHookId().getModuleCode())
+ && hook.getStatus() == ExecutionStatus.success
+ )
+ .map(HookExecutionOutcome::getAnalyticsTags)
+ .map(Tags::activities)
+ .flatMap(Collection::stream);
+ }
+
+ private Float getTreatmentRate(Stream activities) {
+ return activities
+ .filter(activity -> "liveintent-treatment-rate".equals(activity.name()))
+ .findFirst()
+ .map(activity -> {
+ try {
+ return Float.parseFloat(activity.status());
+ } catch (NumberFormatException e) {
+ logger.warn("Invalid treatment rate value: {}", activity.status());
+ throw e;
+ }
+ })
+ .get();
+ }
+
+ private boolean isEnriched(Stream activities) {
+ return activities.anyMatch(activity -> "liveintent-enriched".equals(activity.name()));
+ }
+
+ @Override
+ public int vendorId() {
+ return 0;
+ }
+
+ @Override
+ public String name() {
+ return "liveintentAnalytics";
+ }
+}
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/LiveIntentAnalyticsProperties.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/LiveIntentAnalyticsProperties.java
new file mode 100644
index 00000000000..054408e5401
--- /dev/null
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/LiveIntentAnalyticsProperties.java
@@ -0,0 +1,15 @@
+package org.prebid.server.analytics.reporter.liveintent.model;
+
+import lombok.Builder;
+import lombok.Data;
+import lombok.Value;
+
+@Data
+@Builder(toBuilder = true)
+@Value
+public class LiveIntentAnalyticsProperties {
+
+ String partnerId;
+ String analyticsEndpoint;
+ long timeoutMs;
+}
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java
new file mode 100644
index 00000000000..6a21385b3b9
--- /dev/null
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java
@@ -0,0 +1,22 @@
+package org.prebid.server.analytics.reporter.liveintent.model;
+
+import lombok.Builder;
+import lombok.Data;
+import lombok.Value;
+
+import java.math.BigDecimal;
+
+@Data
+@Builder(toBuilder = true)
+@Value
+public class PbsjBid {
+
+ String bidId;
+ boolean enriched;
+ BigDecimal price;
+ String adUnitId;
+ String currency;
+ Float treatmentRate;
+ Long timestamp;
+ String partnerId;
+}
diff --git a/src/main/java/org/prebid/server/spring/config/AnalyticsConfiguration.java b/src/main/java/org/prebid/server/spring/config/AnalyticsConfiguration.java
index 2e0b2d1a296..6d8f633aec6 100644
--- a/src/main/java/org/prebid/server/spring/config/AnalyticsConfiguration.java
+++ b/src/main/java/org/prebid/server/spring/config/AnalyticsConfiguration.java
@@ -12,6 +12,8 @@
import org.prebid.server.analytics.reporter.agma.model.AgmaAnalyticsProperties;
import org.prebid.server.analytics.reporter.greenbids.GreenbidsAnalyticsReporter;
import org.prebid.server.analytics.reporter.greenbids.model.GreenbidsAnalyticsProperties;
+import org.prebid.server.analytics.reporter.liveintent.LiveIntentAnalyticsReporter;
+import org.prebid.server.analytics.reporter.liveintent.model.LiveIntentAnalyticsProperties;
import org.prebid.server.analytics.reporter.log.LogAnalyticsReporter;
import org.prebid.server.analytics.reporter.pubstack.PubstackAnalyticsReporter;
import org.prebid.server.analytics.reporter.pubstack.model.PubstackAnalyticsProperties;
@@ -302,4 +304,46 @@ private static class PubstackBufferProperties {
Long reportTtlMs;
}
}
+
+ @Configuration
+ @ConditionalOnProperty(prefix = "analytics.liveintent", name = "enabled", havingValue = "true")
+ public static class LiveIntentAnalyticsConfiguration {
+
+ @Bean
+ LiveIntentAnalyticsReporter liveIntentAnalyticsReporter(
+ LiveIntentAnalyticsConfigurationProperties properties,
+ HttpClient httpClient,
+ JacksonMapper jacksonMapper
+ ) {
+ return new LiveIntentAnalyticsReporter(
+ properties.toComponentProperties(),
+ httpClient,
+ jacksonMapper
+ );
+ }
+
+ @Bean
+ @ConfigurationProperties(prefix = "analytics.liveintent")
+ LiveIntentAnalyticsConfigurationProperties liveIntentAnalyticsConfigurationProperties() {
+ return new LiveIntentAnalyticsConfigurationProperties();
+ }
+
+ @Validated
+ @NoArgsConstructor
+ @Data
+ private static class LiveIntentAnalyticsConfigurationProperties {
+
+ String partnerId;
+ String analyticsEndpoint;
+ long timeoutMs;
+
+ public LiveIntentAnalyticsProperties toComponentProperties() {
+ return LiveIntentAnalyticsProperties.builder()
+ .partnerId(this.partnerId)
+ .analyticsEndpoint(this.analyticsEndpoint)
+ .timeoutMs(this.timeoutMs)
+ .build();
+ }
+ }
+ }
}
diff --git a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
new file mode 100644
index 00000000000..50fb8d76b3e
--- /dev/null
+++ b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
@@ -0,0 +1,72 @@
+package org.prebid.server.analytics.reporter.liveintent;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.vertx.core.Future;
+import io.vertx.core.MultiMap;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.junit.jupiter.api.Test;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.prebid.server.VertxTest;
+import org.prebid.server.analytics.model.NotificationEvent;
+import org.prebid.server.analytics.reporter.liveintent.model.LiveIntentAnalyticsProperties;
+import org.prebid.server.json.JacksonMapper;
+import org.prebid.server.vertx.httpclient.HttpClient;
+import org.prebid.server.vertx.httpclient.model.HttpClientResponse;
+
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+public class LiveintentAnalyticsReporterTest extends VertxTest {
+
+ private static final HttpClientResponse SUCCESS_RESPONSE = HttpClientResponse.of(
+ 200, MultiMap.caseInsensitiveMultiMap(), "OK");
+
+ @Mock
+ private HttpClient httpClient;
+
+ private LiveIntentAnalyticsReporter target;
+
+ private LiveIntentAnalyticsProperties properties;
+
+ private JacksonMapper jacksonMapper;
+
+ @BeforeEach
+ public void setUp() {
+ final ObjectMapper mapper = new ObjectMapper();
+ jacksonMapper = new JacksonMapper(mapper);
+
+ properties = LiveIntentAnalyticsProperties.builder()
+ .analyticsEndpoint("https://localhost:8080")
+ .partnerId("pbsj")
+ .timeoutMs(1000L)
+ .build();
+
+ target = new LiveIntentAnalyticsReporter(
+ properties,
+ httpClient,
+ jacksonMapper);
+ }
+
+ @Test
+ public void shouldProcessNotificationEvent() {
+
+ // when
+ target.processEvent(NotificationEvent.builder().bidId("123").bidder("foo").build());
+ final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
+
+ when(httpClient.get(anyString(), anyLong())).thenReturn(Future.succeededFuture(mockResponse));
+ // then
+ // Verify that the HTTP client was called with the expected parameters
+ verify(httpClient).get(eq(properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-winning-bid")
+ + "?b=foo&bidId=123", eq(properties.getTimeoutMs()));
+ }
+}
From 5bbb15539d47e3c308c0d312232aea3c3bcf5524 Mon Sep 17 00:00:00 2001
From: ilya
Date: Wed, 30 Jul 2025 17:29:18 +0200
Subject: [PATCH 28/43] DATA-22937: LI Analytic module.
---
.../LiveIntentAnalyticsReporter.java | 21 +-
.../LiveintentAnalyticsReporterTest.java | 205 +++++++++++++++++-
2 files changed, 207 insertions(+), 19 deletions(-)
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
index 9db6b11adda..71b431699a9 100644
--- a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
@@ -28,7 +28,6 @@
import java.util.List;
import java.util.Objects;
import java.util.Optional;
-import java.util.stream.Stream;
public class LiveIntentAnalyticsReporter implements AnalyticsReporter {
@@ -69,21 +68,19 @@ private Future processNotificationEvent(NotificationEvent notificationEven
private Future processAuctionEvent(AuctionContext auctionContext) {
try {
final BidRequest bidRequest = Optional.ofNullable(auctionContext.getBidRequest())
- .orElseThrow(() -> new PreBidException("Bid response should not be empty"));
+ .orElseThrow(() -> new PreBidException("Bid request should not be empty"));
final BidResponse bidResponse = Optional.ofNullable(auctionContext.getBidResponse())
.orElseThrow(() -> new PreBidException("Bid response should not be empty"));
final Optional requestPrebid = Optional.ofNullable(bidRequest.getExt())
.flatMap(ext -> Optional.of(ext.getPrebid()));
- final Stream activities = getActivities(auctionContext);
+ final List activities = getActivities(auctionContext);
final List pbsjBids = bidResponse.getSeatbid().stream()
.flatMap(seatBid -> seatBid.getBid().stream())
.flatMap(bid ->
bidRequest.getImp().stream()
.filter(impItem -> impItem.getId().equals(bid.getImpid()))
- .findFirst()
- .stream()
.map(imp ->
PbsjBid.builder()
.bidId(bid.getId())
@@ -109,7 +106,7 @@ private Future processAuctionEvent(AuctionContext auctionContext) {
}
}
- private Stream getActivities(AuctionContext auctionContext) {
+ private List getActivities(AuctionContext auctionContext) {
return Optional.ofNullable(auctionContext)
.map(AuctionContext::getHookExecutionContext)
.map(HookExecutionContext::getStageOutcomes)
@@ -126,11 +123,13 @@ private Stream getActivities(AuctionContext auctionContext) {
)
.map(HookExecutionOutcome::getAnalyticsTags)
.map(Tags::activities)
- .flatMap(Collection::stream);
+ .flatMap(Collection::stream)
+ .toList();
}
- private Float getTreatmentRate(Stream activities) {
+ private Float getTreatmentRate(List activities) {
return activities
+ .stream()
.filter(activity -> "liveintent-treatment-rate".equals(activity.name()))
.findFirst()
.map(activity -> {
@@ -141,11 +140,11 @@ private Float getTreatmentRate(Stream activities) {
throw e;
}
})
- .get();
+ .orElse(-1.0f);
}
- private boolean isEnriched(Stream activities) {
- return activities.anyMatch(activity -> "liveintent-enriched".equals(activity.name()));
+ private boolean isEnriched(List activities) {
+ return activities.stream().anyMatch(activity -> "liveintent-enriched".equals(activity.name()));
}
@Override
diff --git a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
index 50fb8d76b3e..946c1a09776 100644
--- a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
+++ b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
@@ -1,8 +1,12 @@
package org.prebid.server.analytics.reporter.liveintent;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.iab.openrtb.request.BidRequest;
+import com.iab.openrtb.request.Imp;
+import com.iab.openrtb.response.Bid;
+import com.iab.openrtb.response.BidResponse;
+import com.iab.openrtb.response.SeatBid;
import io.vertx.core.Future;
-import io.vertx.core.MultiMap;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
@@ -11,12 +15,32 @@
import org.junit.jupiter.api.Test;
import org.mockito.junit.jupiter.MockitoExtension;
import org.prebid.server.VertxTest;
+import org.prebid.server.analytics.model.AuctionEvent;
import org.prebid.server.analytics.model.NotificationEvent;
import org.prebid.server.analytics.reporter.liveintent.model.LiveIntentAnalyticsProperties;
+import org.prebid.server.analytics.reporter.liveintent.model.PbsjBid;
+import org.prebid.server.auction.model.AuctionContext;
+import org.prebid.server.hooks.execution.model.ExecutionStatus;
+import org.prebid.server.hooks.execution.model.GroupExecutionOutcome;
+import org.prebid.server.hooks.execution.model.HookExecutionContext;
+import org.prebid.server.hooks.execution.model.HookExecutionOutcome;
+import org.prebid.server.hooks.execution.model.HookId;
+import org.prebid.server.hooks.execution.model.Stage;
+import org.prebid.server.hooks.execution.model.StageExecutionOutcome;
+import org.prebid.server.hooks.execution.v1.analytics.ActivityImpl;
+import org.prebid.server.hooks.execution.v1.analytics.TagsImpl;
import org.prebid.server.json.JacksonMapper;
+import org.prebid.server.model.Endpoint;
+import org.prebid.server.util.ListUtil;
import org.prebid.server.vertx.httpclient.HttpClient;
import org.prebid.server.vertx.httpclient.model.HttpClientResponse;
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.EnumMap;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -27,12 +51,12 @@
@ExtendWith(MockitoExtension.class)
public class LiveintentAnalyticsReporterTest extends VertxTest {
- private static final HttpClientResponse SUCCESS_RESPONSE = HttpClientResponse.of(
- 200, MultiMap.caseInsensitiveMultiMap(), "OK");
-
@Mock
private HttpClient httpClient;
+ @Captor
+ private ArgumentCaptor jsonCaptor;
+
private LiveIntentAnalyticsReporter target;
private LiveIntentAnalyticsProperties properties;
@@ -58,15 +82,180 @@ public void setUp() {
@Test
public void shouldProcessNotificationEvent() {
+ // given
+ final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
+ when(httpClient.get(anyString(), anyLong())).thenReturn(Future.succeededFuture(mockResponse));
// when
target.processEvent(NotificationEvent.builder().bidId("123").bidder("foo").build());
- final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
- when(httpClient.get(anyString(), anyLong())).thenReturn(Future.succeededFuture(mockResponse));
// then
// Verify that the HTTP client was called with the expected parameters
- verify(httpClient).get(eq(properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-winning-bid")
- + "?b=foo&bidId=123", eq(properties.getTimeoutMs()));
+ verify(httpClient).get(eq(properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-winning-bid"
+ + "?b=foo&bidId=123"), eq(properties.getTimeoutMs()));
+ }
+
+ @Test
+ public void shouldSendAllBidsToLiveIntent() {
+ // given
+ final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
+ when(httpClient.post(anyString(), anyString(), anyLong()))
+ .thenReturn(Future.succeededFuture(mockResponse));
+
+ // when
+ target.processEvent(buildEvent(true));
+
+ // then
+ verify(httpClient).post(
+ eq(properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-bids"),
+ jsonCaptor.capture(),
+ eq(properties.getTimeoutMs()));
+
+ final String capturedJson = jsonCaptor.getValue();
+ final List pbsjBids = Arrays.stream(jacksonMapper.decodeValue(capturedJson, PbsjBid[].class)).toList();
+ assertThat(pbsjBids).isEqualTo(List.of(
+ PbsjBid.builder()
+ .bidId("bid-id")
+ .price(BigDecimal.ONE)
+ .adUnitId("ad-unit-id")
+ .enriched(true)
+ .currency("USD")
+ .treatmentRate(0.5f)
+ .timestamp(0L)
+ .partnerId("pbsj")
+ .build()
+ ));
+ }
+
+ @Test
+ public void shouldSendAllBidsToLiveIntentNotEnriched() {
+ // given
+ final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
+ when(httpClient.post(anyString(), anyString(), anyLong()))
+ .thenReturn(Future.succeededFuture(mockResponse));
+
+ // when
+ target.processEvent(buildEvent(false));
+
+ // then
+ verify(httpClient).post(
+ eq(properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-bids"),
+ jsonCaptor.capture(),
+ eq(properties.getTimeoutMs()));
+
+ final String capturedJson = jsonCaptor.getValue();
+ final List pbsjBids = Arrays.stream(jacksonMapper.decodeValue(capturedJson, PbsjBid[].class)).toList();
+ assertThat(pbsjBids).isEqualTo(List.of(
+ PbsjBid.builder()
+ .bidId("bid-id")
+ .price(BigDecimal.ONE)
+ .adUnitId("ad-unit-id")
+ .enriched(false)
+ .currency("USD")
+ .treatmentRate(0.5f)
+ .timestamp(0L)
+ .partnerId("pbsj")
+ .build()
+ ));
+ }
+
+ @Test
+ public void shouldSendAllBidsToLiveIntentNoTreatmentRate() {
+ // given
+ final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
+ when(httpClient.post(anyString(), anyString(), anyLong()))
+ .thenReturn(Future.succeededFuture(mockResponse));
+
+ // when
+ target.processEvent(buildEvent(false, false));
+
+ // then
+ verify(httpClient).post(
+ eq(properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-bids"),
+ jsonCaptor.capture(),
+ eq(properties.getTimeoutMs()));
+
+ final String capturedJson = jsonCaptor.getValue();
+ final List pbsjBids = Arrays.stream(jacksonMapper.decodeValue(capturedJson, PbsjBid[].class)).toList();
+ assertThat(pbsjBids).isEqualTo(List.of(
+ PbsjBid.builder()
+ .bidId("bid-id")
+ .price(BigDecimal.ONE)
+ .adUnitId("ad-unit-id")
+ .enriched(false)
+ .currency("USD")
+ .treatmentRate(-1.0f)
+ .timestamp(0L)
+ .partnerId("pbsj")
+ .build()
+ ));
+ }
+
+ private AuctionEvent buildEvent(Boolean isEnriched) {
+ return buildEvent(isEnriched, true);
+ }
+
+ private AuctionEvent buildEvent(Boolean isEnriched, Boolean withTags) {
+ final HookId hookId = HookId.of(
+ "liveintent-omni-channel-identity-enrichment-hook",
+ "liveintent-omni-channel-identity-enrichment-hook");
+
+ final ActivityImpl enrichmentRate = ActivityImpl.of("liveintent-treatment-rate", "0.5", List.of());
+
+ final List enriched = isEnriched
+ ? List.of(ActivityImpl.of("liveintent-enriched", "success", List.of()))
+ : List.of();
+
+ final HookExecutionOutcome hookExecutionOutcome = HookExecutionOutcome.builder()
+ .hookId(hookId)
+ .executionTime(100L)
+ .status(ExecutionStatus.success)
+ .analyticsTags(TagsImpl.of(
+ withTags
+ ? ListUtil.union(
+ List.of(enrichmentRate),
+ enriched
+ )
+ : List.of()
+ ))
+ .action(null)
+ .build();
+
+ final StageExecutionOutcome stageExecutionOutcome = StageExecutionOutcome.of(
+ "auction-request",
+ List.of(GroupExecutionOutcome.of(List.of(hookExecutionOutcome)))
+ );
+
+ final EnumMap> stageOutcomes = new EnumMap<>(Stage.class);
+ stageOutcomes.put(Stage.processed_auction_request, List.of(stageExecutionOutcome));
+ return AuctionEvent.builder()
+ .auctionContext(
+ AuctionContext.builder()
+ .bidRequest(BidRequest.builder()
+ .id("request-id")
+ .imp(List.of(
+ Imp.builder()
+ .id("imp-id")
+ .tagid("ad-unit-id")
+ .build()))
+ .build())
+ .bidResponse(BidResponse.builder()
+ .bidid("bid-id")
+ .cur("USD")
+ .seatbid(List.of(
+ SeatBid.builder()
+ .bid(List.of(
+ Bid.builder()
+ .id("bid-id")
+ .impid("imp-id")
+ .price(BigDecimal.ONE)
+ .build()))
+ .build()))
+ .build())
+ .hookExecutionContext(HookExecutionContext.of(
+ Endpoint.openrtb2_auction,
+ stageOutcomes))
+ .build())
+ .build();
}
}
From 432625a7ee0b56e610fbcdefc2f29e7116f5f547 Mon Sep 17 00:00:00 2001
From: ilya
Date: Wed, 30 Jul 2025 17:39:25 +0200
Subject: [PATCH 29/43] DATA-22937: LI Analytic module.
---
.../reporter/liveintent/LiveIntentAnalyticsReporter.java | 5 ++---
.../analytics/reporter/liveintent/model/PbsjBid.java | 3 ++-
.../liveintent/LiveintentAnalyticsReporterTest.java | 7 ++++---
3 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
index 71b431699a9..534bd702be4 100644
--- a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
@@ -127,7 +127,7 @@ private List getActivities(AuctionContext auctionContext) {
.toList();
}
- private Float getTreatmentRate(List activities) {
+ private Optional getTreatmentRate(List activities) {
return activities
.stream()
.filter(activity -> "liveintent-treatment-rate".equals(activity.name()))
@@ -139,8 +139,7 @@ private Float getTreatmentRate(List activities) {
logger.warn("Invalid treatment rate value: {}", activity.status());
throw e;
}
- })
- .orElse(-1.0f);
+ });
}
private boolean isEnriched(List activities) {
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java
index 6a21385b3b9..d641b4e9ef0 100644
--- a/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java
@@ -5,6 +5,7 @@
import lombok.Value;
import java.math.BigDecimal;
+import java.util.Optional;
@Data
@Builder(toBuilder = true)
@@ -16,7 +17,7 @@ public class PbsjBid {
BigDecimal price;
String adUnitId;
String currency;
- Float treatmentRate;
+ Optional treatmentRate;
Long timestamp;
String partnerId;
}
diff --git a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
index 946c1a09776..f2a8f5a38fc 100644
--- a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
+++ b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
@@ -39,6 +39,7 @@
import java.util.Arrays;
import java.util.EnumMap;
import java.util.List;
+import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyLong;
@@ -120,7 +121,7 @@ public void shouldSendAllBidsToLiveIntent() {
.adUnitId("ad-unit-id")
.enriched(true)
.currency("USD")
- .treatmentRate(0.5f)
+ .treatmentRate(Optional.of(0.5f))
.timestamp(0L)
.partnerId("pbsj")
.build()
@@ -152,7 +153,7 @@ public void shouldSendAllBidsToLiveIntentNotEnriched() {
.adUnitId("ad-unit-id")
.enriched(false)
.currency("USD")
- .treatmentRate(0.5f)
+ .treatmentRate(Optional.of(0.5f))
.timestamp(0L)
.partnerId("pbsj")
.build()
@@ -184,7 +185,7 @@ public void shouldSendAllBidsToLiveIntentNoTreatmentRate() {
.adUnitId("ad-unit-id")
.enriched(false)
.currency("USD")
- .treatmentRate(-1.0f)
+ .treatmentRate(Optional.empty())
.timestamp(0L)
.partnerId("pbsj")
.build()
From bc299e905ad199b46ea1d88855e9f7e0f576d633 Mon Sep 17 00:00:00 2001
From: ilya
Date: Wed, 30 Jul 2025 18:08:00 +0200
Subject: [PATCH 30/43] DATA-22937: LI Analytic module.
---
.../reporter/liveintent/LiveIntentAnalyticsReporter.java | 5 +++--
.../analytics/reporter/liveintent/model/PbsjBid.java | 3 +--
.../liveintent/LiveintentAnalyticsReporterTest.java | 7 +++----
3 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
index 534bd702be4..da736b193d6 100644
--- a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
@@ -127,7 +127,7 @@ private List getActivities(AuctionContext auctionContext) {
.toList();
}
- private Optional getTreatmentRate(List activities) {
+ private Float getTreatmentRate(List activities) {
return activities
.stream()
.filter(activity -> "liveintent-treatment-rate".equals(activity.name()))
@@ -139,7 +139,8 @@ private Optional getTreatmentRate(List activities) {
logger.warn("Invalid treatment rate value: {}", activity.status());
throw e;
}
- });
+ })
+ .orElse(null);
}
private boolean isEnriched(List activities) {
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java
index d641b4e9ef0..6a21385b3b9 100644
--- a/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java
@@ -5,7 +5,6 @@
import lombok.Value;
import java.math.BigDecimal;
-import java.util.Optional;
@Data
@Builder(toBuilder = true)
@@ -17,7 +16,7 @@ public class PbsjBid {
BigDecimal price;
String adUnitId;
String currency;
- Optional treatmentRate;
+ Float treatmentRate;
Long timestamp;
String partnerId;
}
diff --git a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
index f2a8f5a38fc..644e30bd030 100644
--- a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
+++ b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
@@ -39,7 +39,6 @@
import java.util.Arrays;
import java.util.EnumMap;
import java.util.List;
-import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyLong;
@@ -121,7 +120,7 @@ public void shouldSendAllBidsToLiveIntent() {
.adUnitId("ad-unit-id")
.enriched(true)
.currency("USD")
- .treatmentRate(Optional.of(0.5f))
+ .treatmentRate(0.5f)
.timestamp(0L)
.partnerId("pbsj")
.build()
@@ -153,7 +152,7 @@ public void shouldSendAllBidsToLiveIntentNotEnriched() {
.adUnitId("ad-unit-id")
.enriched(false)
.currency("USD")
- .treatmentRate(Optional.of(0.5f))
+ .treatmentRate(0.5f)
.timestamp(0L)
.partnerId("pbsj")
.build()
@@ -185,8 +184,8 @@ public void shouldSendAllBidsToLiveIntentNoTreatmentRate() {
.adUnitId("ad-unit-id")
.enriched(false)
.currency("USD")
- .treatmentRate(Optional.empty())
.timestamp(0L)
+ .treatmentRate(null)
.partnerId("pbsj")
.build()
));
From 61cdcaf10cbe34ff123d125109d41d7fcf843ec8 Mon Sep 17 00:00:00 2001
From: ilya
Date: Mon, 25 Aug 2025 13:04:43 +0200
Subject: [PATCH 31/43] DATA-22937: Minor fixes after merge with master
---
...iveIntentOmniChannelIdentityProcessedAuctionRequestHook.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
index 385c01e4cb7..cedf87a33a5 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
@@ -7,6 +7,8 @@
import io.vertx.core.MultiMap;
import org.apache.commons.collections4.ListUtils;
import org.prebid.server.hooks.execution.v1.InvocationResultImpl;
+import org.prebid.server.hooks.execution.v1.analytics.ActivityImpl;
+import org.prebid.server.hooks.execution.v1.analytics.TagsImpl;
import org.prebid.server.hooks.execution.v1.auction.AuctionRequestPayloadImpl;
import org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.IdResResponse;
import org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.config.LiveIntentOmniChannelProperties;
From 9c39379ce8d9cebdb646af628068cd1108ecdaa6 Mon Sep 17 00:00:00 2001
From: ilya
Date: Tue, 2 Sep 2025 15:31:03 +0200
Subject: [PATCH 32/43] DATA-22937: PR issues fixed
---
.../identity/model/config/ModuleConfig.java | 15 --------
...elIdentityProcessedAuctionRequestHook.java | 11 ++----
.../model/config/ModuleConfigTest.java | 35 -------------------
3 files changed, 3 insertions(+), 58 deletions(-)
delete mode 100644 extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
delete mode 100644 extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
deleted file mode 100644
index a7fc92b1feb..00000000000
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfig.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.config;
-
-import lombok.Data;
-
-@Data
-public final class ModuleConfig {
-
- long requestTimeoutMs;
-
- String identityResolutionEndpoint;
-
- String authToken;
-
- float treatmentRate;
-}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
index cedf87a33a5..351833b6e86 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
@@ -42,8 +42,6 @@ public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHook implements
private final JacksonMapper mapper;
private final HttpClient httpClient;
private final double logSamplingRate;
- private final ActivityImpl enriched = ActivityImpl.of("liveintent-enriched", "success", List.of());
- private final ActivityImpl treatmentRate;
public LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(LiveIntentOmniChannelProperties config,
JacksonMapper mapper,
@@ -55,11 +53,6 @@ public LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(LiveIntentOmniCh
this.mapper = Objects.requireNonNull(mapper);
this.httpClient = Objects.requireNonNull(httpClient);
this.logSamplingRate = logSamplingRate;
- this.treatmentRate = ActivityImpl.of(
- "liveintent-treatment-rate",
- String.valueOf(config.getTreatmentRate()),
- List.of()
- );
}
@Override
@@ -104,7 +97,9 @@ private InvocationResultImpl update(IdResResponse resolut
.status(InvocationStatus.success)
.action(InvocationAction.update)
.payloadUpdate(payload -> updatedPayload(payload, resolutionResult.getEids()))
- .analyticsTags(TagsImpl.of(List.of(enriched, treatmentRate)))
+ .analyticsTags(TagsImpl.of(List.of(
+ ActivityImpl.of("liveintent-enriched", "success", List.of()),
+ ActivityImpl.of("liveintent-treatment-rate", String.valueOf(config.getTreatmentRate()), List.of()))))
.build();
}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java
deleted file mode 100644
index 39cfd34298e..00000000000
--- a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/ModuleConfigTest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.config;
-
-import org.junit.jupiter.api.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class ModuleConfigTest {
-
- @Test
- public void shouldReturnRequestTimeoutMs() {
- final ModuleConfig moduleConfig = new ModuleConfig();
- moduleConfig.setRequestTimeoutMs(5);
- assertThat(moduleConfig.getRequestTimeoutMs()).isEqualTo(5);
- }
-
- @Test
- public void shouldReturnIdentityResolutionEndpoint() {
- // given
- final ModuleConfig moduleConfig = new ModuleConfig();
- moduleConfig.setIdentityResolutionEndpoint("https://test.com/idres");
-
- // when and then
- assertThat(moduleConfig.getIdentityResolutionEndpoint()).isEqualTo("https://test.com/idres");
- }
-
- @Test
- public void shouldReturnAuthToken() {
- // given
- final ModuleConfig moduleConfig = new ModuleConfig();
- moduleConfig.setAuthToken("secret_token");
-
- // when and then
- assertThat(moduleConfig.getAuthToken()).isEqualTo("secret_token");
- }
-}
From 704b89a96b2bbae9a168d7d112e39b4423c2680c Mon Sep 17 00:00:00 2001
From: ilya
Date: Fri, 5 Sep 2025 16:03:58 +0200
Subject: [PATCH 33/43] DATA-22937: PR issues fixed
---
...elIdentityProcessedAuctionRequestHook.java | 13 +-
.../model/config/IdResResponseTest.java | 40 ------
.../LiveIntentAnalyticsReporter.java | 134 +++++++++++-------
.../model/LiveIntentAnalyticsProperties.java | 4 +-
.../reporter/liveintent/model/PbsjBid.java | 9 +-
5 files changed, 106 insertions(+), 94 deletions(-)
delete mode 100644 extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
index 351833b6e86..8121550d784 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
@@ -1,13 +1,16 @@
package org.prebid.server.hooks.modules.liveintent.omni.channel.identity.v1.hooks;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.iab.openrtb.request.BidRequest;
import com.iab.openrtb.request.Eid;
import com.iab.openrtb.request.User;
import io.vertx.core.Future;
import io.vertx.core.MultiMap;
+import lombok.Value;
import org.apache.commons.collections4.ListUtils;
import org.prebid.server.hooks.execution.v1.InvocationResultImpl;
import org.prebid.server.hooks.execution.v1.analytics.ActivityImpl;
+import org.prebid.server.hooks.execution.v1.analytics.ResultImpl;
import org.prebid.server.hooks.execution.v1.analytics.TagsImpl;
import org.prebid.server.hooks.execution.v1.auction.AuctionRequestPayloadImpl;
import org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.IdResResponse;
@@ -98,8 +101,14 @@ private InvocationResultImpl update(IdResResponse resolut
.action(InvocationAction.update)
.payloadUpdate(payload -> updatedPayload(payload, resolutionResult.getEids()))
.analyticsTags(TagsImpl.of(List.of(
- ActivityImpl.of("liveintent-enriched", "success", List.of()),
- ActivityImpl.of("liveintent-treatment-rate", String.valueOf(config.getTreatmentRate()), List.of()))))
+ ActivityImpl.of(
+ "liveintent-enriched", "success",
+ List.of(
+ ResultImpl.of(
+ "",
+ JsonNodeFactory.instance.objectNode()
+ .put("treatmentRate", config.getTreatmentRate()),
+ null))))))
.build();
}
diff --git a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java b/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java
deleted file mode 100644
index aa073979b34..00000000000
--- a/extra/modules/live-intent-omni-channel-identity/src/test/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/config/IdResResponseTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.config;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.iab.openrtb.request.Eid;
-import com.iab.openrtb.request.Uid;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model.IdResResponse;
-import org.prebid.server.json.JacksonMapper;
-
-import java.util.List;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class IdResResponseTest {
-
- private JacksonMapper jacksonMapper;
-
- @BeforeEach
- public void setUp() {
- final ObjectMapper mapper = new ObjectMapper();
- jacksonMapper = new JacksonMapper(mapper);
- }
-
- @Test
- public void shouldDecodeFromString() {
- // given
- final IdResResponse result = jacksonMapper.decodeValue(
- "{\"eids\": [ { \"source\": \"liveintent.com\", "
- + "\"uids\": [ { \"atype\": 3, \"id\" : \"some_id\" } ] } ] }",
- IdResResponse.class);
-
- // when and then
- assertThat(result.getEids()).isEqualTo(List.of(
- Eid.builder()
- .source("liveintent.com")
- .uids(List.of(Uid.builder().atype(3).id("some_id").build()))
- .build()));
- }
-}
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
index da736b193d6..14bb6ec1042 100644
--- a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
@@ -1,8 +1,12 @@
package org.prebid.server.analytics.reporter.liveintent;
import com.iab.openrtb.request.BidRequest;
+import com.iab.openrtb.response.Bid;
import com.iab.openrtb.response.BidResponse;
+import com.iab.openrtb.response.SeatBid;
import io.vertx.core.Future;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.http.client.utils.URIBuilder;
import org.prebid.server.analytics.AnalyticsReporter;
import org.prebid.server.analytics.model.AuctionEvent;
import org.prebid.server.analytics.model.NotificationEvent;
@@ -24,6 +28,8 @@
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebid;
import org.prebid.server.vertx.httpclient.HttpClient;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
@@ -31,17 +37,19 @@
public class LiveIntentAnalyticsReporter implements AnalyticsReporter {
+ private static final Logger logger = LoggerFactory.getLogger(LiveIntentAnalyticsReporter.class);
+
+ private static final String LIVEINTENT_HOOK_ID = "liveintent-omni-channel-identity-enrichment-hook";
+
private final HttpClient httpClient;
private final LiveIntentAnalyticsProperties properties;
private final JacksonMapper jacksonMapper;
- private static final Logger logger = LoggerFactory.getLogger(LiveIntentAnalyticsReporter.class);
public LiveIntentAnalyticsReporter(
LiveIntentAnalyticsProperties properties,
HttpClient httpClient,
- JacksonMapper jacksonMapper
- ) {
+ JacksonMapper jacksonMapper) {
this.httpClient = Objects.requireNonNull(httpClient);
this.properties = Objects.requireNonNull(properties);
this.jacksonMapper = Objects.requireNonNull(jacksonMapper);
@@ -59,44 +67,78 @@ public Future processEvent(T event) {
}
private Future processNotificationEvent(NotificationEvent notificationEvent) {
- final String url = properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-winning-bid?"
- + "b=" + notificationEvent.getBidder()
- + "&bidId=" + notificationEvent.getBidId();
- return httpClient.get(url, properties.getTimeoutMs()).mapEmpty();
+ try {
+ final String url = new URIBuilder(URI.create(properties.getAnalyticsEndpoint()))
+ .setPath("/analytic-events/pbsj-winning-bid")
+ .setParameter("b=", notificationEvent.getBidder())
+ .setParameter("bidId=", notificationEvent.getBidId())
+ .build()
+ .toString();
+ return httpClient.get(url, properties.getTimeoutMs()).mapEmpty();
+ }
+ catch (URISyntaxException e) {
+ logger.error("Error composing url for notification event: {}", e.getMessage());
+ return Future.failedFuture(e);
+ }
+ }
+
+ private Optional buildPbsjBid(
+ BidRequest bidRequest,
+ BidResponse bidResponse,
+ Bid bid,
+ boolean isEnriched,
+ Float treatmentRate,
+ Long timestamp) {
+ return bidRequest.getImp().stream()
+ .filter(impItem -> impItem.getId().equals(bid.getImpid()))
+ .map(imp ->
+ PbsjBid.builder()
+ .bidId(bid.getId())
+ .price(bid.getPrice())
+ .adUnitId(imp.getTagid())
+ .enriched(isEnriched)
+ .currency(bidResponse.getCur())
+ .treatmentRate(treatmentRate)
+ .timestamp(timestamp)
+ .partnerId(properties.getPartnerId())
+ .build()
+ )
+ .findFirst();
}
private Future processAuctionEvent(AuctionContext auctionContext) {
- try {
- final BidRequest bidRequest = Optional.ofNullable(auctionContext.getBidRequest())
- .orElseThrow(() -> new PreBidException("Bid request should not be empty"));
- final BidResponse bidResponse = Optional.ofNullable(auctionContext.getBidResponse())
- .orElseThrow(() -> new PreBidException("Bid response should not be empty"));
+ if(auctionContext.getBidRequest() == null) {
+ return Future.failedFuture(new PreBidException("Bid request should not be empty"));
+ }
+
+ if(auctionContext.getBidResponse() == null) {
+ return Future.failedFuture(new PreBidException("Bid response should not be empty"));
+ }
+
+ final BidRequest bidRequest = auctionContext.getBidRequest();
+ final BidResponse bidResponse = auctionContext.getBidResponse();
final Optional requestPrebid = Optional.ofNullable(bidRequest.getExt())
.flatMap(ext -> Optional.of(ext.getPrebid()));
- final List activities = getActivities(auctionContext);
-
- final List pbsjBids = bidResponse.getSeatbid().stream()
- .flatMap(seatBid -> seatBid.getBid().stream())
- .flatMap(bid ->
- bidRequest.getImp().stream()
- .filter(impItem -> impItem.getId().equals(bid.getImpid()))
- .map(imp ->
- PbsjBid.builder()
- .bidId(bid.getId())
- .price(bid.getPrice())
- .adUnitId(imp.getTagid())
- .enriched(isEnriched(activities))
- .currency(bidResponse.getCur())
- .treatmentRate(getTreatmentRate(activities))
- .timestamp(requestPrebid.map(ExtRequestPrebid::getAuctiontimestamp).orElse(0L))
- .partnerId(properties.getPartnerId())
- .build()
- )
- ).toList();
+ final Optional activity = getActivities(auctionContext);
+ final boolean isEnriched = isEnriched(activity);
+ final Float treatmentRate = getTreatmentRate(activity);
+ final Long timestamp = requestPrebid.map(ExtRequestPrebid::getAuctiontimestamp).orElse(0L);
+ final List pbsjBids = CollectionUtils.emptyIfNull(bidResponse.getSeatbid()).stream()
+ .map(SeatBid::getBid)
+ .flatMap(Collection::stream)
+ .map(bid -> buildPbsjBid(bidRequest, bidResponse, bid, isEnriched, treatmentRate, timestamp))
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .toList();
+
+ try {
return httpClient.post(
- properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-bids",
+ new URIBuilder(URI.create(properties.getAnalyticsEndpoint()))
+ .setPath("/analytic-events/pbsj-bids")
+ .build()
+ .toString(),
jacksonMapper.encodeToString(pbsjBids),
properties.getTimeoutMs()
).mapEmpty();
@@ -106,7 +148,7 @@ private Future processAuctionEvent(AuctionContext auctionContext) {
}
}
- private List getActivities(AuctionContext auctionContext) {
+ private Optional getActivities(AuctionContext auctionContext) {
return Optional.ofNullable(auctionContext)
.map(AuctionContext::getHookExecutionContext)
.map(HookExecutionContext::getStageOutcomes)
@@ -118,33 +160,25 @@ private List getActivities(AuctionContext auctionContext) {
.map(GroupExecutionOutcome::getHooks)
.flatMap(Collection::stream)
.filter(hook ->
- "liveintent-omni-channel-identity-enrichment-hook".equals(hook.getHookId().getModuleCode())
+ LIVEINTENT_HOOK_ID.equals(hook.getHookId().getModuleCode())
&& hook.getStatus() == ExecutionStatus.success
)
.map(HookExecutionOutcome::getAnalyticsTags)
.map(Tags::activities)
.flatMap(Collection::stream)
- .toList();
+ .findFirst();
}
- private Float getTreatmentRate(List activities) {
- return activities
- .stream()
- .filter(activity -> "liveintent-treatment-rate".equals(activity.name()))
+ private Float getTreatmentRate(Optional activity) {
+ return activity.stream()
+ .flatMap(a -> a.results().stream())
.findFirst()
- .map(activity -> {
- try {
- return Float.parseFloat(activity.status());
- } catch (NumberFormatException e) {
- logger.warn("Invalid treatment rate value: {}", activity.status());
- throw e;
- }
- })
+ .map(a -> a.values().at("treatmentRate").floatValue())
.orElse(null);
}
- private boolean isEnriched(List activities) {
- return activities.stream().anyMatch(activity -> "liveintent-enriched".equals(activity.name()));
+ private boolean isEnriched(Optional activity) {
+ return activity.stream().anyMatch(a -> "liveintent-enriched".equals(a.name()));
}
@Override
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/LiveIntentAnalyticsProperties.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/LiveIntentAnalyticsProperties.java
index 054408e5401..0fbe4f65032 100644
--- a/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/LiveIntentAnalyticsProperties.java
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/LiveIntentAnalyticsProperties.java
@@ -4,12 +4,14 @@
import lombok.Data;
import lombok.Value;
-@Data
@Builder(toBuilder = true)
@Value
public class LiveIntentAnalyticsProperties {
String partnerId;
+
String analyticsEndpoint;
+
long timeoutMs;
+
}
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java
index 6a21385b3b9..8a724335c34 100644
--- a/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java
@@ -6,17 +6,24 @@
import java.math.BigDecimal;
-@Data
@Builder(toBuilder = true)
@Value
public class PbsjBid {
String bidId;
+
boolean enriched;
+
BigDecimal price;
+
String adUnitId;
+
String currency;
+
Float treatmentRate;
+
Long timestamp;
+
String partnerId;
+
}
From a7b75b7555243a9c46adbf3242620797ebb1187f Mon Sep 17 00:00:00 2001
From: ilya
Date: Fri, 5 Sep 2025 16:07:57 +0200
Subject: [PATCH 34/43] DATA-22937: PR issues fixed
---
.../reporter/liveintent/LiveIntentAnalyticsReporter.java | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
index 14bb6ec1042..93066e3eb36 100644
--- a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
@@ -152,7 +152,8 @@ private Optional getActivities(AuctionContext auctionContext) {
return Optional.ofNullable(auctionContext)
.map(AuctionContext::getHookExecutionContext)
.map(HookExecutionContext::getStageOutcomes)
- .map(stages -> stages.get(Stage.processed_auction_request)).stream()
+ .map(stages -> stages.get(Stage.processed_auction_request))
+ .stream()
.flatMap(Collection::stream)
.filter(stageExecutionOutcome -> "auction-request".equals(stageExecutionOutcome.getEntity()))
.map(StageExecutionOutcome::getGroups)
@@ -164,8 +165,11 @@ private Optional getActivities(AuctionContext auctionContext) {
&& hook.getStatus() == ExecutionStatus.success
)
.map(HookExecutionOutcome::getAnalyticsTags)
+ .filter(Objects::nonNull)
.map(Tags::activities)
+ .filter(Objects::nonNull)
.flatMap(Collection::stream)
+ .filter(Objects::nonNull)
.findFirst();
}
From 2d9cc59f42d893d77d01da744afc14194444f0ac Mon Sep 17 00:00:00 2001
From: ilya
Date: Mon, 15 Sep 2025 16:34:49 +0200
Subject: [PATCH 35/43] DATA-36551: PR compilation issues fixed
---
.../LiveIntentAnalyticsReporter.java | 54 +++++++++----------
.../model/LiveIntentAnalyticsProperties.java | 1 -
.../reporter/liveintent/model/PbsjBid.java | 1 -
3 files changed, 26 insertions(+), 30 deletions(-)
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
index 93066e3eb36..db2fcb57d3a 100644
--- a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
@@ -45,7 +45,6 @@ public class LiveIntentAnalyticsReporter implements AnalyticsReporter {
private final LiveIntentAnalyticsProperties properties;
private final JacksonMapper jacksonMapper;
-
public LiveIntentAnalyticsReporter(
LiveIntentAnalyticsProperties properties,
HttpClient httpClient,
@@ -75,8 +74,7 @@ private Future processNotificationEvent(NotificationEvent notificationEven
.build()
.toString();
return httpClient.get(url, properties.getTimeoutMs()).mapEmpty();
- }
- catch (URISyntaxException e) {
+ } catch (URISyntaxException e) {
logger.error("Error composing url for notification event: {}", e.getMessage());
return Future.failedFuture(e);
}
@@ -107,31 +105,31 @@ private Optional buildPbsjBid(
}
private Future processAuctionEvent(AuctionContext auctionContext) {
- if(auctionContext.getBidRequest() == null) {
- return Future.failedFuture(new PreBidException("Bid request should not be empty"));
- }
-
- if(auctionContext.getBidResponse() == null) {
- return Future.failedFuture(new PreBidException("Bid response should not be empty"));
- }
-
- final BidRequest bidRequest = auctionContext.getBidRequest();
- final BidResponse bidResponse = auctionContext.getBidResponse();
- final Optional requestPrebid = Optional.ofNullable(bidRequest.getExt())
- .flatMap(ext -> Optional.of(ext.getPrebid()));
-
- final Optional activity = getActivities(auctionContext);
- final boolean isEnriched = isEnriched(activity);
- final Float treatmentRate = getTreatmentRate(activity);
- final Long timestamp = requestPrebid.map(ExtRequestPrebid::getAuctiontimestamp).orElse(0L);
-
- final List pbsjBids = CollectionUtils.emptyIfNull(bidResponse.getSeatbid()).stream()
- .map(SeatBid::getBid)
- .flatMap(Collection::stream)
- .map(bid -> buildPbsjBid(bidRequest, bidResponse, bid, isEnriched, treatmentRate, timestamp))
- .filter(Optional::isPresent)
- .map(Optional::get)
- .toList();
+ if(auctionContext.getBidRequest() == null) {
+ return Future.failedFuture(new PreBidException("Bid request should not be empty"));
+ }
+
+ if(auctionContext.getBidResponse() == null) {
+ return Future.failedFuture(new PreBidException("Bid response should not be empty"));
+ }
+
+ final BidRequest bidRequest = auctionContext.getBidRequest();
+ final BidResponse bidResponse = auctionContext.getBidResponse();
+ final Optional requestPrebid = Optional.ofNullable(bidRequest.getExt())
+ .flatMap(ext -> Optional.of(ext.getPrebid()));
+
+ final Optional activity = getActivities(auctionContext);
+ final boolean isEnriched = isEnriched(activity);
+ final Float treatmentRate = getTreatmentRate(activity);
+ final Long timestamp = requestPrebid.map(ExtRequestPrebid::getAuctiontimestamp).orElse(0L);
+
+ final List pbsjBids = CollectionUtils.emptyIfNull(bidResponse.getSeatbid()).stream()
+ .map(SeatBid::getBid)
+ .flatMap(Collection::stream)
+ .map(bid -> buildPbsjBid(bidRequest, bidResponse, bid, isEnriched, treatmentRate, timestamp))
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .toList();
try {
return httpClient.post(
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/LiveIntentAnalyticsProperties.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/LiveIntentAnalyticsProperties.java
index 0fbe4f65032..d4ed08dbc3f 100644
--- a/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/LiveIntentAnalyticsProperties.java
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/LiveIntentAnalyticsProperties.java
@@ -1,7 +1,6 @@
package org.prebid.server.analytics.reporter.liveintent.model;
import lombok.Builder;
-import lombok.Data;
import lombok.Value;
@Builder(toBuilder = true)
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java
index 8a724335c34..7758ffa8581 100644
--- a/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java
@@ -1,7 +1,6 @@
package org.prebid.server.analytics.reporter.liveintent.model;
import lombok.Builder;
-import lombok.Data;
import lombok.Value;
import java.math.BigDecimal;
From 58fc8c0e317de0aa062fddda86b40ee1758acca6 Mon Sep 17 00:00:00 2001
From: ilya
Date: Thu, 18 Sep 2025 17:27:45 +0200
Subject: [PATCH 36/43] DATA-22937: PR issues fixed
---
...elIdentityProcessedAuctionRequestHook.java | 4 +-
.../LiveIntentAnalyticsReporter.java | 102 +++++++++---------
.../model/LiveIntentAnalyticsProperties.java | 1 -
.../reporter/liveintent/model/PbsjBid.java | 1 -
.../spring/config/AnalyticsConfiguration.java | 6 +-
5 files changed, 56 insertions(+), 58 deletions(-)
diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
index 8121550d784..7b10860222e 100644
--- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
+++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/v1/hooks/LiveIntentOmniChannelIdentityProcessedAuctionRequestHook.java
@@ -1,12 +1,10 @@
package org.prebid.server.hooks.modules.liveintent.omni.channel.identity.v1.hooks;
-import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.iab.openrtb.request.BidRequest;
import com.iab.openrtb.request.Eid;
import com.iab.openrtb.request.User;
import io.vertx.core.Future;
import io.vertx.core.MultiMap;
-import lombok.Value;
import org.apache.commons.collections4.ListUtils;
import org.prebid.server.hooks.execution.v1.InvocationResultImpl;
import org.prebid.server.hooks.execution.v1.analytics.ActivityImpl;
@@ -106,7 +104,7 @@ private InvocationResultImpl update(IdResResponse resolut
List.of(
ResultImpl.of(
"",
- JsonNodeFactory.instance.objectNode()
+ mapper.mapper().createObjectNode()
.put("treatmentRate", config.getTreatmentRate()),
null))))))
.build();
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
index db2fcb57d3a..975c7b5b2b1 100644
--- a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
@@ -28,7 +28,6 @@
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebid;
import org.prebid.server.vertx.httpclient.HttpClient;
-import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collection;
import java.util.List;
@@ -49,6 +48,7 @@ public LiveIntentAnalyticsReporter(
LiveIntentAnalyticsProperties properties,
HttpClient httpClient,
JacksonMapper jacksonMapper) {
+
this.httpClient = Objects.requireNonNull(httpClient);
this.properties = Objects.requireNonNull(properties);
this.jacksonMapper = Objects.requireNonNull(jacksonMapper);
@@ -65,63 +65,25 @@ public Future processEvent(T event) {
return Future.succeededFuture();
}
- private Future processNotificationEvent(NotificationEvent notificationEvent) {
- try {
- final String url = new URIBuilder(URI.create(properties.getAnalyticsEndpoint()))
- .setPath("/analytic-events/pbsj-winning-bid")
- .setParameter("b=", notificationEvent.getBidder())
- .setParameter("bidId=", notificationEvent.getBidId())
- .build()
- .toString();
- return httpClient.get(url, properties.getTimeoutMs()).mapEmpty();
- } catch (URISyntaxException e) {
- logger.error("Error composing url for notification event: {}", e.getMessage());
- return Future.failedFuture(e);
- }
- }
-
- private Optional buildPbsjBid(
- BidRequest bidRequest,
- BidResponse bidResponse,
- Bid bid,
- boolean isEnriched,
- Float treatmentRate,
- Long timestamp) {
- return bidRequest.getImp().stream()
- .filter(impItem -> impItem.getId().equals(bid.getImpid()))
- .map(imp ->
- PbsjBid.builder()
- .bidId(bid.getId())
- .price(bid.getPrice())
- .adUnitId(imp.getTagid())
- .enriched(isEnriched)
- .currency(bidResponse.getCur())
- .treatmentRate(treatmentRate)
- .timestamp(timestamp)
- .partnerId(properties.getPartnerId())
- .build()
- )
- .findFirst();
- }
-
private Future processAuctionEvent(AuctionContext auctionContext) {
if(auctionContext.getBidRequest() == null) {
return Future.failedFuture(new PreBidException("Bid request should not be empty"));
}
if(auctionContext.getBidResponse() == null) {
- return Future.failedFuture(new PreBidException("Bid response should not be empty"));
+ return Future.succeededFuture();
}
final BidRequest bidRequest = auctionContext.getBidRequest();
final BidResponse bidResponse = auctionContext.getBidResponse();
- final Optional requestPrebid = Optional.ofNullable(bidRequest.getExt())
- .flatMap(ext -> Optional.of(ext.getPrebid()));
final Optional activity = getActivities(auctionContext);
final boolean isEnriched = isEnriched(activity);
final Float treatmentRate = getTreatmentRate(activity);
- final Long timestamp = requestPrebid.map(ExtRequestPrebid::getAuctiontimestamp).orElse(0L);
+ final Long timestamp = Optional.ofNullable(bidRequest.getExt())
+ .flatMap(ext -> Optional.of(ext.getPrebid()))
+ .map(ExtRequestPrebid::getAuctiontimestamp)
+ .orElse(0L);
final List pbsjBids = CollectionUtils.emptyIfNull(bidResponse.getSeatbid()).stream()
.map(SeatBid::getBid)
@@ -133,13 +95,13 @@ private Future processAuctionEvent(AuctionContext auctionContext) {
try {
return httpClient.post(
- new URIBuilder(URI.create(properties.getAnalyticsEndpoint()))
+ new URIBuilder(properties.getAnalyticsEndpoint())
.setPath("/analytic-events/pbsj-bids")
.build()
.toString(),
jacksonMapper.encodeToString(pbsjBids),
- properties.getTimeoutMs()
- ).mapEmpty();
+ properties.getTimeoutMs())
+ .mapEmpty();
} catch (Exception e) {
logger.error("Error processing event: {}", e.getMessage());
return Future.failedFuture(e);
@@ -160,8 +122,7 @@ private Optional getActivities(AuctionContext auctionContext) {
.flatMap(Collection::stream)
.filter(hook ->
LIVEINTENT_HOOK_ID.equals(hook.getHookId().getModuleCode())
- && hook.getStatus() == ExecutionStatus.success
- )
+ && hook.getStatus() == ExecutionStatus.success)
.map(HookExecutionOutcome::getAnalyticsTags)
.filter(Objects::nonNull)
.map(Tags::activities)
@@ -171,16 +132,55 @@ private Optional getActivities(AuctionContext auctionContext) {
.findFirst();
}
+ private boolean isEnriched(Optional activity) {
+ return activity.stream().anyMatch(a -> "liveintent-enriched".equals(a.name()));
+ }
+
private Float getTreatmentRate(Optional activity) {
return activity.stream()
.flatMap(a -> a.results().stream())
+ .filter(a -> a.values().has("treatmentRate"))
.findFirst()
.map(a -> a.values().at("treatmentRate").floatValue())
.orElse(null);
}
- private boolean isEnriched(Optional activity) {
- return activity.stream().anyMatch(a -> "liveintent-enriched".equals(a.name()));
+ private Optional buildPbsjBid(
+ BidRequest bidRequest,
+ BidResponse bidResponse,
+ Bid bid,
+ boolean isEnriched,
+ Float treatmentRate,
+ Long timestamp) {
+
+ return bidRequest.getImp().stream()
+ .filter(impItem -> impItem.getId().equals(bid.getImpid()))
+ .map(imp -> PbsjBid.builder()
+ .bidId(bid.getId())
+ .price(bid.getPrice())
+ .adUnitId(imp.getTagid())
+ .enriched(isEnriched)
+ .currency(bidResponse.getCur())
+ .treatmentRate(treatmentRate)
+ .timestamp(timestamp)
+ .partnerId(properties.getPartnerId())
+ .build())
+ .findFirst();
+ }
+
+ private Future processNotificationEvent(NotificationEvent notificationEvent) {
+ try {
+ final String url = new URIBuilder(properties.getAnalyticsEndpoint())
+ .setPath("/analytic-events/pbsj-winning-bid")
+ .setParameter("b", notificationEvent.getBidder())
+ .setParameter("bidId", notificationEvent.getBidId())
+ .build()
+ .toString();
+ return httpClient.get(url, properties.getTimeoutMs()).mapEmpty();
+ } catch (URISyntaxException e) {
+ logger.error("Error composing url for notification event: {}", e.getMessage());
+ return Future.failedFuture(e);
+ }
}
@Override
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/LiveIntentAnalyticsProperties.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/LiveIntentAnalyticsProperties.java
index d4ed08dbc3f..fea06b81047 100644
--- a/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/LiveIntentAnalyticsProperties.java
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/LiveIntentAnalyticsProperties.java
@@ -12,5 +12,4 @@ public class LiveIntentAnalyticsProperties {
String analyticsEndpoint;
long timeoutMs;
-
}
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java
index 7758ffa8581..00de59f9e3b 100644
--- a/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/model/PbsjBid.java
@@ -24,5 +24,4 @@ public class PbsjBid {
Long timestamp;
String partnerId;
-
}
diff --git a/src/main/java/org/prebid/server/spring/config/AnalyticsConfiguration.java b/src/main/java/org/prebid/server/spring/config/AnalyticsConfiguration.java
index 6d8f633aec6..c3c332d464a 100644
--- a/src/main/java/org/prebid/server/spring/config/AnalyticsConfiguration.java
+++ b/src/main/java/org/prebid/server/spring/config/AnalyticsConfiguration.java
@@ -313,8 +313,8 @@ public static class LiveIntentAnalyticsConfiguration {
LiveIntentAnalyticsReporter liveIntentAnalyticsReporter(
LiveIntentAnalyticsConfigurationProperties properties,
HttpClient httpClient,
- JacksonMapper jacksonMapper
- ) {
+ JacksonMapper jacksonMapper) {
+
return new LiveIntentAnalyticsReporter(
properties.toComponentProperties(),
httpClient,
@@ -334,7 +334,9 @@ LiveIntentAnalyticsConfigurationProperties liveIntentAnalyticsConfigurationPrope
private static class LiveIntentAnalyticsConfigurationProperties {
String partnerId;
+
String analyticsEndpoint;
+
long timeoutMs;
public LiveIntentAnalyticsProperties toComponentProperties() {
From d946509db70cf7515d661fe00a503257f6260dfe Mon Sep 17 00:00:00 2001
From: ilya
Date: Thu, 18 Sep 2025 17:52:45 +0200
Subject: [PATCH 37/43] DATA-22937: PR issues fixed
---
.../reporter/liveintent/LiveIntentAnalyticsReporter.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
index 975c7b5b2b1..bbf6d3637ee 100644
--- a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
@@ -25,6 +25,7 @@
import org.prebid.server.json.JacksonMapper;
import org.prebid.server.log.Logger;
import org.prebid.server.log.LoggerFactory;
+import org.prebid.server.proto.openrtb.ext.request.ExtRequest;
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebid;
import org.prebid.server.vertx.httpclient.HttpClient;
@@ -81,7 +82,7 @@ private Future processAuctionEvent(AuctionContext auctionContext) {
final boolean isEnriched = isEnriched(activity);
final Float treatmentRate = getTreatmentRate(activity);
final Long timestamp = Optional.ofNullable(bidRequest.getExt())
- .flatMap(ext -> Optional.of(ext.getPrebid()))
+ .map(ExtRequest::getPrebid)
.map(ExtRequestPrebid::getAuctiontimestamp)
.orElse(0L);
From d2eefef5ce2937a4704c3ba6bd4df03403ee168c Mon Sep 17 00:00:00 2001
From: ilya
Date: Fri, 19 Sep 2025 12:23:53 +0200
Subject: [PATCH 38/43] DATA-22937: PR issues fixed
---
.../LiveintentAnalyticsReporterTest.java | 36 +++++++------------
1 file changed, 13 insertions(+), 23 deletions(-)
diff --git a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
index 644e30bd030..849c0819127 100644
--- a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
+++ b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
@@ -1,6 +1,5 @@
package org.prebid.server.analytics.reporter.liveintent;
-import com.fasterxml.jackson.databind.ObjectMapper;
import com.iab.openrtb.request.BidRequest;
import com.iab.openrtb.request.Imp;
import com.iab.openrtb.response.Bid;
@@ -29,14 +28,13 @@
import org.prebid.server.hooks.execution.model.StageExecutionOutcome;
import org.prebid.server.hooks.execution.v1.analytics.ActivityImpl;
import org.prebid.server.hooks.execution.v1.analytics.TagsImpl;
-import org.prebid.server.json.JacksonMapper;
import org.prebid.server.model.Endpoint;
import org.prebid.server.util.ListUtil;
import org.prebid.server.vertx.httpclient.HttpClient;
import org.prebid.server.vertx.httpclient.model.HttpClientResponse;
+import com.fasterxml.jackson.core.type.TypeReference;
import java.math.BigDecimal;
-import java.util.Arrays;
import java.util.EnumMap;
import java.util.List;
@@ -61,12 +59,12 @@ public class LiveintentAnalyticsReporterTest extends VertxTest {
private LiveIntentAnalyticsProperties properties;
- private JacksonMapper jacksonMapper;
+ private TypeReference> pbjsCollectionType;
+
@BeforeEach
public void setUp() {
- final ObjectMapper mapper = new ObjectMapper();
- jacksonMapper = new JacksonMapper(mapper);
+ pbjsCollectionType = new TypeReference<>() {};
properties = LiveIntentAnalyticsProperties.builder()
.analyticsEndpoint("https://localhost:8080")
@@ -112,7 +110,7 @@ public void shouldSendAllBidsToLiveIntent() {
eq(properties.getTimeoutMs()));
final String capturedJson = jsonCaptor.getValue();
- final List pbsjBids = Arrays.stream(jacksonMapper.decodeValue(capturedJson, PbsjBid[].class)).toList();
+ final List pbsjBids = jacksonMapper.decodeValue(capturedJson, pbjsCollectionType);
assertThat(pbsjBids).isEqualTo(List.of(
PbsjBid.builder()
.bidId("bid-id")
@@ -123,8 +121,7 @@ public void shouldSendAllBidsToLiveIntent() {
.treatmentRate(0.5f)
.timestamp(0L)
.partnerId("pbsj")
- .build()
- ));
+ .build()));
}
@Test
@@ -144,7 +141,7 @@ public void shouldSendAllBidsToLiveIntentNotEnriched() {
eq(properties.getTimeoutMs()));
final String capturedJson = jsonCaptor.getValue();
- final List pbsjBids = Arrays.stream(jacksonMapper.decodeValue(capturedJson, PbsjBid[].class)).toList();
+ final List pbsjBids = jacksonMapper.decodeValue(capturedJson, pbjsCollectionType);
assertThat(pbsjBids).isEqualTo(List.of(
PbsjBid.builder()
.bidId("bid-id")
@@ -155,8 +152,7 @@ public void shouldSendAllBidsToLiveIntentNotEnriched() {
.treatmentRate(0.5f)
.timestamp(0L)
.partnerId("pbsj")
- .build()
- ));
+ .build()));
}
@Test
@@ -176,7 +172,7 @@ public void shouldSendAllBidsToLiveIntentNoTreatmentRate() {
eq(properties.getTimeoutMs()));
final String capturedJson = jsonCaptor.getValue();
- final List pbsjBids = Arrays.stream(jacksonMapper.decodeValue(capturedJson, PbsjBid[].class)).toList();
+ final List pbsjBids = jacksonMapper.decodeValue(capturedJson, pbjsCollectionType);
assertThat(pbsjBids).isEqualTo(List.of(
PbsjBid.builder()
.bidId("bid-id")
@@ -187,8 +183,7 @@ public void shouldSendAllBidsToLiveIntentNoTreatmentRate() {
.timestamp(0L)
.treatmentRate(null)
.partnerId("pbsj")
- .build()
- ));
+ .build()));
}
private AuctionEvent buildEvent(Boolean isEnriched) {
@@ -212,19 +207,14 @@ private AuctionEvent buildEvent(Boolean isEnriched, Boolean withTags) {
.status(ExecutionStatus.success)
.analyticsTags(TagsImpl.of(
withTags
- ? ListUtil.union(
- List.of(enrichmentRate),
- enriched
- )
- : List.of()
- ))
+ ? ListUtil.union(List.of(enrichmentRate), enriched)
+ : List.of()))
.action(null)
.build();
final StageExecutionOutcome stageExecutionOutcome = StageExecutionOutcome.of(
"auction-request",
- List.of(GroupExecutionOutcome.of(List.of(hookExecutionOutcome)))
- );
+ List.of(GroupExecutionOutcome.of(List.of(hookExecutionOutcome))));
final EnumMap> stageOutcomes = new EnumMap<>(Stage.class);
stageOutcomes.put(Stage.processed_auction_request, List.of(stageExecutionOutcome));
From 359ed363d41faf0f4c53d201beda5afdab7ca04b Mon Sep 17 00:00:00 2001
From: ilya
Date: Tue, 23 Sep 2025 11:47:05 +0200
Subject: [PATCH 39/43] DATA-22937: Fixing linting
---
.../reporter/liveintent/LiveIntentAnalyticsReporter.java | 4 ++--
.../reporter/liveintent/LiveintentAnalyticsReporterTest.java | 3 +--
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
index bbf6d3637ee..03a47c00ae9 100644
--- a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
@@ -67,11 +67,11 @@ public Future processEvent(T event) {
}
private Future processAuctionEvent(AuctionContext auctionContext) {
- if(auctionContext.getBidRequest() == null) {
+ if (auctionContext.getBidRequest() == null) {
return Future.failedFuture(new PreBidException("Bid request should not be empty"));
}
- if(auctionContext.getBidResponse() == null) {
+ if (auctionContext.getBidResponse() == null) {
return Future.succeededFuture();
}
diff --git a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
index 849c0819127..6625e555e6e 100644
--- a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
+++ b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
@@ -61,10 +61,9 @@ public class LiveintentAnalyticsReporterTest extends VertxTest {
private TypeReference> pbjsCollectionType;
-
@BeforeEach
public void setUp() {
- pbjsCollectionType = new TypeReference<>() {};
+ pbjsCollectionType = new TypeReference<>() { };
properties = LiveIntentAnalyticsProperties.builder()
.analyticsEndpoint("https://localhost:8080")
From be5bf0ba4514bcc8f8bd9bd7a3fd06dcd1fa46c9 Mon Sep 17 00:00:00 2001
From: ilya
Date: Wed, 24 Sep 2025 15:52:08 +0200
Subject: [PATCH 40/43] DATA-22937: PR issues fixed
---
.../prebid/server/spring/config/AnalyticsConfiguration.java | 3 +--
.../reporter/liveintent/LiveintentAnalyticsReporterTest.java | 3 +--
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/main/java/org/prebid/server/spring/config/AnalyticsConfiguration.java b/src/main/java/org/prebid/server/spring/config/AnalyticsConfiguration.java
index c3c332d464a..c27cbd41078 100644
--- a/src/main/java/org/prebid/server/spring/config/AnalyticsConfiguration.java
+++ b/src/main/java/org/prebid/server/spring/config/AnalyticsConfiguration.java
@@ -318,8 +318,7 @@ LiveIntentAnalyticsReporter liveIntentAnalyticsReporter(
return new LiveIntentAnalyticsReporter(
properties.toComponentProperties(),
httpClient,
- jacksonMapper
- );
+ jacksonMapper);
}
@Bean
diff --git a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
index 6625e555e6e..292194d285e 100644
--- a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
+++ b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
@@ -59,11 +59,10 @@ public class LiveintentAnalyticsReporterTest extends VertxTest {
private LiveIntentAnalyticsProperties properties;
- private TypeReference> pbjsCollectionType;
+ private final static TypeReference> pbjsCollectionType = new TypeReference<>() { };
@BeforeEach
public void setUp() {
- pbjsCollectionType = new TypeReference<>() { };
properties = LiveIntentAnalyticsProperties.builder()
.analyticsEndpoint("https://localhost:8080")
From 3f65d4775a116e3c08264c602be9d0c4cfe10de0 Mon Sep 17 00:00:00 2001
From: ilya
Date: Fri, 26 Sep 2025 09:37:45 +0200
Subject: [PATCH 41/43] DATA-22937: Build fixed
---
.../liveintent/LiveintentAnalyticsReporterTest.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
index 292194d285e..753daa2ad36 100644
--- a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
+++ b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
@@ -59,7 +59,7 @@ public class LiveintentAnalyticsReporterTest extends VertxTest {
private LiveIntentAnalyticsProperties properties;
- private final static TypeReference> pbjsCollectionType = new TypeReference<>() { };
+ private static final TypeReference> PBJS_COLLECTION_TYPE = new TypeReference<>() { };
@BeforeEach
public void setUp() {
@@ -108,7 +108,7 @@ public void shouldSendAllBidsToLiveIntent() {
eq(properties.getTimeoutMs()));
final String capturedJson = jsonCaptor.getValue();
- final List pbsjBids = jacksonMapper.decodeValue(capturedJson, pbjsCollectionType);
+ final List pbsjBids = jacksonMapper.decodeValue(capturedJson, PBJS_COLLECTION_TYPE);
assertThat(pbsjBids).isEqualTo(List.of(
PbsjBid.builder()
.bidId("bid-id")
@@ -139,7 +139,7 @@ public void shouldSendAllBidsToLiveIntentNotEnriched() {
eq(properties.getTimeoutMs()));
final String capturedJson = jsonCaptor.getValue();
- final List pbsjBids = jacksonMapper.decodeValue(capturedJson, pbjsCollectionType);
+ final List pbsjBids = jacksonMapper.decodeValue(capturedJson, PBJS_COLLECTION_TYPE);
assertThat(pbsjBids).isEqualTo(List.of(
PbsjBid.builder()
.bidId("bid-id")
@@ -170,7 +170,7 @@ public void shouldSendAllBidsToLiveIntentNoTreatmentRate() {
eq(properties.getTimeoutMs()));
final String capturedJson = jsonCaptor.getValue();
- final List pbsjBids = jacksonMapper.decodeValue(capturedJson, pbjsCollectionType);
+ final List pbsjBids = jacksonMapper.decodeValue(capturedJson, PBJS_COLLECTION_TYPE);
assertThat(pbsjBids).isEqualTo(List.of(
PbsjBid.builder()
.bidId("bid-id")
From 7d11882052c5457d349289b5745f9fbff794f0e7 Mon Sep 17 00:00:00 2001
From: Peixun Zhang
Date: Thu, 23 Oct 2025 15:46:02 +0200
Subject: [PATCH 42/43] update test
---
.../LiveIntentAnalyticsReporter.java | 39 +-
.../LiveintentAnalyticsReporterTest.java | 412 +++++++++---------
2 files changed, 234 insertions(+), 217 deletions(-)
diff --git a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
index 03a47c00ae9..d404a12397e 100644
--- a/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
+++ b/src/main/java/org/prebid/server/analytics/reporter/liveintent/LiveIntentAnalyticsReporter.java
@@ -78,9 +78,9 @@ private Future processAuctionEvent(AuctionContext auctionContext) {
final BidRequest bidRequest = auctionContext.getBidRequest();
final BidResponse bidResponse = auctionContext.getBidResponse();
- final Optional activity = getActivities(auctionContext);
- final boolean isEnriched = isEnriched(activity);
- final Float treatmentRate = getTreatmentRate(activity);
+ final List activities = getActivities(auctionContext);
+ final boolean isEnriched = isEnriched(activities);
+ final Float treatmentRate = getTreatmentRate(activities);
final Long timestamp = Optional.ofNullable(bidRequest.getExt())
.map(ExtRequest::getPrebid)
.map(ExtRequestPrebid::getAuctiontimestamp)
@@ -109,7 +109,7 @@ private Future processAuctionEvent(AuctionContext auctionContext) {
}
}
- private Optional getActivities(AuctionContext auctionContext) {
+ private List getActivities(AuctionContext auctionContext) {
return Optional.ofNullable(auctionContext)
.map(AuctionContext::getHookExecutionContext)
.map(HookExecutionContext::getStageOutcomes)
@@ -121,28 +121,27 @@ private Optional getActivities(AuctionContext auctionContext) {
.flatMap(Collection::stream)
.map(GroupExecutionOutcome::getHooks)
.flatMap(Collection::stream)
- .filter(hook ->
- LIVEINTENT_HOOK_ID.equals(hook.getHookId().getModuleCode())
- && hook.getStatus() == ExecutionStatus.success)
+ .filter(hook -> LIVEINTENT_HOOK_ID.equals(hook.getHookId().getModuleCode())
+ && hook.getStatus() == ExecutionStatus.success)
.map(HookExecutionOutcome::getAnalyticsTags)
.filter(Objects::nonNull)
.map(Tags::activities)
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.filter(Objects::nonNull)
- .findFirst();
+ .toList();
}
- private boolean isEnriched(Optional activity) {
+ private boolean isEnriched(List activity) {
return activity.stream().anyMatch(a -> "liveintent-enriched".equals(a.name()));
}
- private Float getTreatmentRate(Optional activity) {
+ private Float getTreatmentRate(List activity) {
return activity.stream()
.flatMap(a -> a.results().stream())
.filter(a -> a.values().has("treatmentRate"))
.findFirst()
- .map(a -> a.values().at("treatmentRate").floatValue())
+ .map(a -> a.values().get("treatmentRate").floatValue())
.orElse(null);
}
@@ -157,15 +156,15 @@ private Optional buildPbsjBid(
return bidRequest.getImp().stream()
.filter(impItem -> impItem.getId().equals(bid.getImpid()))
.map(imp -> PbsjBid.builder()
- .bidId(bid.getId())
- .price(bid.getPrice())
- .adUnitId(imp.getTagid())
- .enriched(isEnriched)
- .currency(bidResponse.getCur())
- .treatmentRate(treatmentRate)
- .timestamp(timestamp)
- .partnerId(properties.getPartnerId())
- .build())
+ .bidId(bid.getId())
+ .price(bid.getPrice())
+ .adUnitId(imp.getTagid())
+ .enriched(isEnriched)
+ .currency(bidResponse.getCur())
+ .treatmentRate(treatmentRate)
+ .timestamp(timestamp)
+ .partnerId(properties.getPartnerId())
+ .build())
.findFirst();
}
diff --git a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
index 753daa2ad36..f0d05191aa5 100644
--- a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
+++ b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
@@ -28,11 +28,15 @@
import org.prebid.server.hooks.execution.model.StageExecutionOutcome;
import org.prebid.server.hooks.execution.v1.analytics.ActivityImpl;
import org.prebid.server.hooks.execution.v1.analytics.TagsImpl;
+import org.prebid.server.hooks.execution.v1.analytics.AppliedToImpl;
+import org.prebid.server.hooks.execution.v1.analytics.ResultImpl;
+import org.prebid.server.json.ObjectMapperProvider;
import org.prebid.server.model.Endpoint;
import org.prebid.server.util.ListUtil;
import org.prebid.server.vertx.httpclient.HttpClient;
import org.prebid.server.vertx.httpclient.model.HttpClientResponse;
import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import java.math.BigDecimal;
import java.util.EnumMap;
@@ -49,201 +53,215 @@
@ExtendWith(MockitoExtension.class)
public class LiveintentAnalyticsReporterTest extends VertxTest {
- @Mock
- private HttpClient httpClient;
-
- @Captor
- private ArgumentCaptor jsonCaptor;
-
- private LiveIntentAnalyticsReporter target;
-
- private LiveIntentAnalyticsProperties properties;
-
- private static final TypeReference> PBJS_COLLECTION_TYPE = new TypeReference<>() { };
-
- @BeforeEach
- public void setUp() {
-
- properties = LiveIntentAnalyticsProperties.builder()
- .analyticsEndpoint("https://localhost:8080")
- .partnerId("pbsj")
- .timeoutMs(1000L)
- .build();
-
- target = new LiveIntentAnalyticsReporter(
- properties,
- httpClient,
- jacksonMapper);
- }
-
- @Test
- public void shouldProcessNotificationEvent() {
- // given
- final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
- when(httpClient.get(anyString(), anyLong())).thenReturn(Future.succeededFuture(mockResponse));
-
- // when
- target.processEvent(NotificationEvent.builder().bidId("123").bidder("foo").build());
-
- // then
- // Verify that the HTTP client was called with the expected parameters
- verify(httpClient).get(eq(properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-winning-bid"
- + "?b=foo&bidId=123"), eq(properties.getTimeoutMs()));
- }
-
- @Test
- public void shouldSendAllBidsToLiveIntent() {
- // given
- final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
- when(httpClient.post(anyString(), anyString(), anyLong()))
- .thenReturn(Future.succeededFuture(mockResponse));
-
- // when
- target.processEvent(buildEvent(true));
-
- // then
- verify(httpClient).post(
- eq(properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-bids"),
- jsonCaptor.capture(),
- eq(properties.getTimeoutMs()));
-
- final String capturedJson = jsonCaptor.getValue();
- final List pbsjBids = jacksonMapper.decodeValue(capturedJson, PBJS_COLLECTION_TYPE);
- assertThat(pbsjBids).isEqualTo(List.of(
- PbsjBid.builder()
- .bidId("bid-id")
- .price(BigDecimal.ONE)
- .adUnitId("ad-unit-id")
- .enriched(true)
- .currency("USD")
- .treatmentRate(0.5f)
- .timestamp(0L)
- .partnerId("pbsj")
- .build()));
- }
-
- @Test
- public void shouldSendAllBidsToLiveIntentNotEnriched() {
- // given
- final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
- when(httpClient.post(anyString(), anyString(), anyLong()))
- .thenReturn(Future.succeededFuture(mockResponse));
-
- // when
- target.processEvent(buildEvent(false));
-
- // then
- verify(httpClient).post(
- eq(properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-bids"),
- jsonCaptor.capture(),
- eq(properties.getTimeoutMs()));
-
- final String capturedJson = jsonCaptor.getValue();
- final List pbsjBids = jacksonMapper.decodeValue(capturedJson, PBJS_COLLECTION_TYPE);
- assertThat(pbsjBids).isEqualTo(List.of(
- PbsjBid.builder()
- .bidId("bid-id")
- .price(BigDecimal.ONE)
- .adUnitId("ad-unit-id")
- .enriched(false)
- .currency("USD")
- .treatmentRate(0.5f)
- .timestamp(0L)
- .partnerId("pbsj")
- .build()));
- }
-
- @Test
- public void shouldSendAllBidsToLiveIntentNoTreatmentRate() {
- // given
- final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
- when(httpClient.post(anyString(), anyString(), anyLong()))
- .thenReturn(Future.succeededFuture(mockResponse));
-
- // when
- target.processEvent(buildEvent(false, false));
-
- // then
- verify(httpClient).post(
- eq(properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-bids"),
- jsonCaptor.capture(),
- eq(properties.getTimeoutMs()));
-
- final String capturedJson = jsonCaptor.getValue();
- final List pbsjBids = jacksonMapper.decodeValue(capturedJson, PBJS_COLLECTION_TYPE);
- assertThat(pbsjBids).isEqualTo(List.of(
- PbsjBid.builder()
- .bidId("bid-id")
- .price(BigDecimal.ONE)
- .adUnitId("ad-unit-id")
- .enriched(false)
- .currency("USD")
- .timestamp(0L)
- .treatmentRate(null)
- .partnerId("pbsj")
- .build()));
- }
-
- private AuctionEvent buildEvent(Boolean isEnriched) {
- return buildEvent(isEnriched, true);
- }
-
- private AuctionEvent buildEvent(Boolean isEnriched, Boolean withTags) {
- final HookId hookId = HookId.of(
- "liveintent-omni-channel-identity-enrichment-hook",
- "liveintent-omni-channel-identity-enrichment-hook");
-
- final ActivityImpl enrichmentRate = ActivityImpl.of("liveintent-treatment-rate", "0.5", List.of());
-
- final List enriched = isEnriched
- ? List.of(ActivityImpl.of("liveintent-enriched", "success", List.of()))
- : List.of();
-
- final HookExecutionOutcome hookExecutionOutcome = HookExecutionOutcome.builder()
- .hookId(hookId)
- .executionTime(100L)
- .status(ExecutionStatus.success)
- .analyticsTags(TagsImpl.of(
- withTags
- ? ListUtil.union(List.of(enrichmentRate), enriched)
- : List.of()))
- .action(null)
- .build();
-
- final StageExecutionOutcome stageExecutionOutcome = StageExecutionOutcome.of(
- "auction-request",
- List.of(GroupExecutionOutcome.of(List.of(hookExecutionOutcome))));
-
- final EnumMap> stageOutcomes = new EnumMap<>(Stage.class);
- stageOutcomes.put(Stage.processed_auction_request, List.of(stageExecutionOutcome));
- return AuctionEvent.builder()
- .auctionContext(
- AuctionContext.builder()
- .bidRequest(BidRequest.builder()
- .id("request-id")
- .imp(List.of(
- Imp.builder()
- .id("imp-id")
- .tagid("ad-unit-id")
- .build()))
- .build())
- .bidResponse(BidResponse.builder()
- .bidid("bid-id")
- .cur("USD")
- .seatbid(List.of(
- SeatBid.builder()
- .bid(List.of(
- Bid.builder()
- .id("bid-id")
- .impid("imp-id")
- .price(BigDecimal.ONE)
- .build()))
- .build()))
- .build())
- .hookExecutionContext(HookExecutionContext.of(
- Endpoint.openrtb2_auction,
- stageOutcomes))
- .build())
- .build();
- }
+ @Mock
+ private HttpClient httpClient;
+
+ @Captor
+ private ArgumentCaptor jsonCaptor;
+
+ private LiveIntentAnalyticsReporter target;
+
+ private LiveIntentAnalyticsProperties properties;
+
+ private static final TypeReference> PBJS_COLLECTION_TYPE = new TypeReference<>() {
+ };
+
+ @BeforeEach
+ public void setUp() {
+
+ properties = LiveIntentAnalyticsProperties.builder()
+ .analyticsEndpoint("https://localhost:8080")
+ .partnerId("pbsj")
+ .timeoutMs(1000L)
+ .build();
+
+ target = new LiveIntentAnalyticsReporter(
+ properties,
+ httpClient,
+ jacksonMapper);
+ }
+
+ @Test
+ public void shouldProcessNotificationEvent() {
+ // given
+ final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
+ when(httpClient.get(anyString(), anyLong())).thenReturn(Future.succeededFuture(mockResponse));
+
+ // when
+ target.processEvent(NotificationEvent.builder().bidId("123").bidder("foo").build());
+
+ // then
+ // Verify that the HTTP client was called with the expected parameters
+ verify(httpClient).get(eq(properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-winning-bid"
+ + "?b=foo&bidId=123"), eq(properties.getTimeoutMs()));
+ }
+
+ @Test
+ public void shouldSendAllBidsToLiveIntent() {
+ // given
+ final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
+ when(httpClient.post(anyString(), anyString(), anyLong()))
+ .thenReturn(Future.succeededFuture(mockResponse));
+
+ // when
+ target.processEvent(buildEvent(true));
+
+ // then
+ verify(httpClient).post(
+ eq(properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-bids"),
+ jsonCaptor.capture(),
+ eq(properties.getTimeoutMs()));
+
+ final String capturedJson = jsonCaptor.getValue();
+ final List pbsjBids = jacksonMapper.decodeValue(capturedJson, PBJS_COLLECTION_TYPE);
+ assertThat(pbsjBids).isEqualTo(List.of(
+ PbsjBid.builder()
+ .bidId("bid-id")
+ .price(BigDecimal.ONE)
+ .adUnitId("ad-unit-id")
+ .enriched(true)
+ .currency("USD")
+ .treatmentRate(0.5f)
+ .timestamp(0L)
+ .partnerId("pbsj")
+ .build()));
+ }
+
+ @Test
+ public void shouldSendAllBidsToLiveIntentNotEnriched() {
+ // given
+ final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
+ when(httpClient.post(anyString(), anyString(), anyLong()))
+ .thenReturn(Future.succeededFuture(mockResponse));
+
+ // when
+ target.processEvent(buildEvent(false));
+
+ // then
+ verify(httpClient).post(
+ eq(properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-bids"),
+ jsonCaptor.capture(),
+ eq(properties.getTimeoutMs()));
+
+ final String capturedJson = jsonCaptor.getValue();
+ final List pbsjBids = jacksonMapper.decodeValue(capturedJson, PBJS_COLLECTION_TYPE);
+ assertThat(pbsjBids).isEqualTo(List.of(
+ PbsjBid.builder()
+ .bidId("bid-id")
+ .price(BigDecimal.ONE)
+ .adUnitId("ad-unit-id")
+ .enriched(false)
+ .currency("USD")
+ .treatmentRate(0.5f)
+ .timestamp(0L)
+ .partnerId("pbsj")
+ .build()));
+ }
+
+ @Test
+ public void shouldSendAllBidsToLiveIntentNoTreatmentRate() {
+ // given
+ final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
+ when(httpClient.post(anyString(), anyString(), anyLong()))
+ .thenReturn(Future.succeededFuture(mockResponse));
+
+ // when
+ target.processEvent(buildEvent(false, false));
+
+ // then
+ verify(httpClient).post(
+ eq(properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-bids"),
+ jsonCaptor.capture(),
+ eq(properties.getTimeoutMs()));
+
+ final String capturedJson = jsonCaptor.getValue();
+ final List pbsjBids = jacksonMapper.decodeValue(capturedJson, PBJS_COLLECTION_TYPE);
+ assertThat(pbsjBids).isEqualTo(List.of(
+ PbsjBid.builder()
+ .bidId("bid-id")
+ .price(BigDecimal.ONE)
+ .adUnitId("ad-unit-id")
+ .enriched(false)
+ .currency("USD")
+ .timestamp(0L)
+ .treatmentRate(null)
+ .partnerId("pbsj")
+ .build()));
+ }
+
+ private AuctionEvent buildEvent(Boolean isEnriched) {
+ return buildEvent(isEnriched, true);
+ }
+
+ private AuctionEvent buildEvent(Boolean isEnriched, Boolean withTags) {
+ final HookId hookId = HookId.of(
+ "liveintent-omni-channel-identity-enrichment-hook",
+ "liveintent-omni-channel-identity-enrichment-hook");
+
+ final ObjectNode treatmentRateNode = ObjectMapperProvider.mapper().createObjectNode()
+ .put("treatmentRate", 0.5f);
+
+ final AppliedToImpl appliedTo = AppliedToImpl.builder().bidIds(List.of("bid-id"))
+ .impIds(List.of("imp-id"))
+ .bidders(List.of("pbsj"))
+ .request(true)
+ .response(true)
+ .build();
+
+ final ResultImpl result = ResultImpl.of("treatmentRate", treatmentRateNode, appliedTo);
+
+ final ActivityImpl enrichmentRate = ActivityImpl.of("liveintent-treatment-rate", "0.5",
+ List.of(result));
+
+ final List enriched = isEnriched
+ ? List.of(ActivityImpl.of("liveintent-enriched", "success", List.of()))
+ : List.of();
+
+ final HookExecutionOutcome hookExecutionOutcome = HookExecutionOutcome.builder()
+ .hookId(hookId)
+ .executionTime(100L)
+ .status(ExecutionStatus.success)
+ .analyticsTags(TagsImpl.of(
+ withTags
+ ? ListUtil.union(List.of(enrichmentRate), enriched)
+ : List.of()))
+ .action(null)
+ .build();
+
+ final StageExecutionOutcome stageExecutionOutcome = StageExecutionOutcome.of(
+ "auction-request",
+ List.of(GroupExecutionOutcome.of(List.of(hookExecutionOutcome))));
+
+ final EnumMap> stageOutcomes = new EnumMap<>(Stage.class);
+ stageOutcomes.put(Stage.processed_auction_request, List.of(stageExecutionOutcome));
+ return AuctionEvent.builder()
+ .auctionContext(
+ AuctionContext.builder()
+ .bidRequest(BidRequest.builder()
+ .id("request-id")
+ .imp(List.of(
+ Imp.builder()
+ .id("imp-id")
+ .tagid("ad-unit-id")
+ .build()))
+ .build())
+ .bidResponse(BidResponse.builder()
+ .bidid("bid-id")
+ .cur("USD")
+ .seatbid(List.of(
+ SeatBid.builder()
+ .bid(List.of(
+ Bid.builder()
+ .id("bid-id")
+ .impid("imp-id")
+ .price(BigDecimal.ONE)
+ .build()))
+ .build()))
+ .build())
+ .hookExecutionContext(HookExecutionContext.of(
+ Endpoint.openrtb2_auction,
+ stageOutcomes))
+ .build())
+ .build();
+ }
}
From 3e02eff709f4caa1f4510a5eab9291b2698ba368 Mon Sep 17 00:00:00 2001
From: Peixun Zhang
Date: Mon, 27 Oct 2025 14:31:07 +0100
Subject: [PATCH 43/43] formatting
---
.../LiveintentAnalyticsReporterTest.java | 352 +++++++-----------
1 file changed, 141 insertions(+), 211 deletions(-)
diff --git a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
index f0d05191aa5..1d044a60821 100644
--- a/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
+++ b/src/test/java/org/prebid/server/analytics/reporter/liveintent/LiveintentAnalyticsReporterTest.java
@@ -53,215 +53,145 @@
@ExtendWith(MockitoExtension.class)
public class LiveintentAnalyticsReporterTest extends VertxTest {
- @Mock
- private HttpClient httpClient;
-
- @Captor
- private ArgumentCaptor jsonCaptor;
-
- private LiveIntentAnalyticsReporter target;
-
- private LiveIntentAnalyticsProperties properties;
-
- private static final TypeReference> PBJS_COLLECTION_TYPE = new TypeReference<>() {
- };
-
- @BeforeEach
- public void setUp() {
-
- properties = LiveIntentAnalyticsProperties.builder()
- .analyticsEndpoint("https://localhost:8080")
- .partnerId("pbsj")
- .timeoutMs(1000L)
- .build();
-
- target = new LiveIntentAnalyticsReporter(
- properties,
- httpClient,
- jacksonMapper);
- }
-
- @Test
- public void shouldProcessNotificationEvent() {
- // given
- final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
- when(httpClient.get(anyString(), anyLong())).thenReturn(Future.succeededFuture(mockResponse));
-
- // when
- target.processEvent(NotificationEvent.builder().bidId("123").bidder("foo").build());
-
- // then
- // Verify that the HTTP client was called with the expected parameters
- verify(httpClient).get(eq(properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-winning-bid"
- + "?b=foo&bidId=123"), eq(properties.getTimeoutMs()));
- }
-
- @Test
- public void shouldSendAllBidsToLiveIntent() {
- // given
- final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
- when(httpClient.post(anyString(), anyString(), anyLong()))
- .thenReturn(Future.succeededFuture(mockResponse));
-
- // when
- target.processEvent(buildEvent(true));
-
- // then
- verify(httpClient).post(
- eq(properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-bids"),
- jsonCaptor.capture(),
- eq(properties.getTimeoutMs()));
-
- final String capturedJson = jsonCaptor.getValue();
- final List pbsjBids = jacksonMapper.decodeValue(capturedJson, PBJS_COLLECTION_TYPE);
- assertThat(pbsjBids).isEqualTo(List.of(
- PbsjBid.builder()
- .bidId("bid-id")
- .price(BigDecimal.ONE)
- .adUnitId("ad-unit-id")
- .enriched(true)
- .currency("USD")
- .treatmentRate(0.5f)
- .timestamp(0L)
- .partnerId("pbsj")
- .build()));
- }
-
- @Test
- public void shouldSendAllBidsToLiveIntentNotEnriched() {
- // given
- final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
- when(httpClient.post(anyString(), anyString(), anyLong()))
- .thenReturn(Future.succeededFuture(mockResponse));
-
- // when
- target.processEvent(buildEvent(false));
-
- // then
- verify(httpClient).post(
- eq(properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-bids"),
- jsonCaptor.capture(),
- eq(properties.getTimeoutMs()));
-
- final String capturedJson = jsonCaptor.getValue();
- final List pbsjBids = jacksonMapper.decodeValue(capturedJson, PBJS_COLLECTION_TYPE);
- assertThat(pbsjBids).isEqualTo(List.of(
- PbsjBid.builder()
- .bidId("bid-id")
- .price(BigDecimal.ONE)
- .adUnitId("ad-unit-id")
- .enriched(false)
- .currency("USD")
- .treatmentRate(0.5f)
- .timestamp(0L)
- .partnerId("pbsj")
- .build()));
- }
-
- @Test
- public void shouldSendAllBidsToLiveIntentNoTreatmentRate() {
- // given
- final HttpClientResponse mockResponse = mock(HttpClientResponse.class);
- when(httpClient.post(anyString(), anyString(), anyLong()))
- .thenReturn(Future.succeededFuture(mockResponse));
-
- // when
- target.processEvent(buildEvent(false, false));
-
- // then
- verify(httpClient).post(
- eq(properties.getAnalyticsEndpoint() + "/analytic-events/pbsj-bids"),
- jsonCaptor.capture(),
- eq(properties.getTimeoutMs()));
-
- final String capturedJson = jsonCaptor.getValue();
- final List