From 4486d89d5356b4279101d88d3f2141a73de45406 Mon Sep 17 00:00:00 2001 From: ilya Date: Tue, 17 Feb 2026 12:39:44 +0100 Subject: [PATCH 1/5] DATA-53829: Fixing permission logic --- .../README.md | 53 ++++++++++--------- ...elIdentityProcessedAuctionRequestHook.java | 37 ++++++++----- ...entityProcessedAuctionRequestHookTest.java | 6 ++- 3 files changed, 56 insertions(+), 40 deletions(-) diff --git a/extra/modules/live-intent-omni-channel-identity/README.md b/extra/modules/live-intent-omni-channel-identity/README.md index be5ad801ec1..a8a3ce5b113 100644 --- a/extra/modules/live-intent-omni-channel-identity/README.md +++ b/extra/modules/live-intent-omni-channel-identity/README.md @@ -2,9 +2,12 @@ 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. As part of this onboarding process, partners will also be provided with the `identity-resolution-endpoint` URL as well as with the `auth-token`. +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 +`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 @@ -12,35 +15,35 @@ To start using the LiveIntent Omni Channel Identity module you have to enable it ```yaml hooks: - liveintent-omni-channel-identity: - enabled: true - host-execution-plan: > - { - "endpoints": { - "/openrtb2/auction": { - "stages": { - "processed-auction-request": { - "groups": [ - { - "timeout": 100, - "hook-sequence": [ + liveintent-omni-channel-identity: + enabled: true + host-execution-plan: > + { + "endpoints": { + "/openrtb2/auction": { + "stages": { + "processed-auction-request": { + "groups": [ { - "module-code": "liveintent-omni-channel-identity", - "hook-impl-code": "liveintent-omni-channel-identity-enrichment-hook" + "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" - treatment-rate: 0.9 + modules: + liveintent-omni-channel-identity: + request-timeout-ms: 2000 + identity-resolution-endpoint: "https://u.liveintent.com/idx" + auth-token: "secret-token" + treatment-rate: 0.9 ``` 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 3afdb146018..ada30cc4ae3 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 @@ -44,6 +44,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.Objects; import java.util.Optional; @@ -58,6 +59,8 @@ public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHook implements private static final String CODE = "liveintent-omni-channel-identity-enrichment-hook"; + private static final String INSERTER = "s2s.liveintent.com"; + private final LiveIntentOmniChannelProperties config; private final JacksonMapper mapper; private final HttpClient httpClient; @@ -161,7 +164,11 @@ private MultiMap headers() { } private IdResResponse processResponse(HttpClientResponse response) { - return mapper.decodeValue(response.getBody(), IdResResponse.class); + final IdResResponse res = mapper.decodeValue(response.getBody(), IdResResponse.class); + final List eids = res.getEids().stream() + .map(eid -> eid.toBuilder().inserter(INSERTER).build()) + .toList(); + return IdResResponse.of(eids); } private static Future> noAction() { @@ -208,14 +215,6 @@ private BidRequest updateAllowedBidders(BidRequest bidRequest, List resolve final ExtRequestPrebid extPrebid = ext != null ? ext.getPrebid() : null; final ExtRequestPrebidData extPrebidData = extPrebid != null ? extPrebid.getData() : null; - final List existingPerms = extPrebidData != null - ? extPrebidData.getEidPermissions() - : null; - - if (CollectionUtils.isEmpty(existingPerms)) { - return bidRequest; - } - final ExtRequestPrebid updatedExtPrebid = Optional.ofNullable(extPrebid) .map(ExtRequestPrebid::toBuilder) .orElseGet(ExtRequestPrebid::builder) @@ -237,7 +236,11 @@ private ExtRequestPrebidData updatePrebidData(ExtRequestPrebidData extPrebidData .map(Eid::getSource) .collect(Collectors.toSet()); - final List updatedPermissions = extPrebidData.getEidPermissions().stream() + final List eidPermissions = extPrebidData != null + ? ListUtils.emptyIfNull(extPrebidData.getEidPermissions()) + : Collections.emptyList(); + + final List updatedPermissions = eidPermissions.stream() .map(permission -> restrictEidPermission(permission, resolvedSources)) .filter(Objects::nonNull) .toList(); @@ -252,16 +255,24 @@ private ExtRequestPrebidDataEidPermissions restrictEidPermission(ExtRequestPrebi return permission; } + final List permittedBidders = ListUtils.emptyIfNull(permission.getBidders()); + + if (CollectionUtils.isEmpty(permittedBidders) || permittedBidders.contains("*")) { + return ExtRequestPrebidDataEidPermissions.builder() + .source(permission.getSource()) + .bidders(targetBidders.stream().toList()) + .build(); + } + final List finalBidders = ListUtils.emptyIfNull(permission.getBidders()).stream() .filter(targetBidders::contains) .toList(); return CollectionUtils.isEmpty(finalBidders) ? null - : ExtRequestPrebidDataEidPermissions - .builder() - .bidders(finalBidders) + : ExtRequestPrebidDataEidPermissions.builder() .source(permission.getSource()) + .bidders(finalBidders) .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 4dfaa8c8df4..9c2f2e992fa 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 @@ -248,6 +248,7 @@ public void callShouldEnrichUserEidsWithRequestedEids() { final Eid expectedEid = Eid.builder() .source("liveintent.com") .uids(singletonList(Uid.builder().id("id2").atype(3).build())) + .matcher("liveintent.com") .build(); final String responseBody = MAPPER.encodeToString(IdResResponse.of(List.of(expectedEid))); @@ -273,7 +274,7 @@ public void callShouldEnrichUserEidsWithRequestedEids() { .extracting(AuctionRequestPayload::bidRequest) .extracting(BidRequest::getUser) .extracting(User::getEids) - .isEqualTo(List.of(givenEid, expectedEid)); + .isEqualTo(List.of(givenEid, expectedEid.toBuilder().inserter("s2s.liveintent.com").build())); verify(httpClient).post( eq("https://test.com/idres"), @@ -290,6 +291,7 @@ public void callShouldCreateUserAndUseRequestedEidsWhenUserIsAbsent() { final Eid expectedEid = Eid.builder() .source("liveintent.com") .uids(singletonList(Uid.builder().id("id2").atype(3).build())) + .matcher("liveintent.com") .build(); final String responseBody = MAPPER.encodeToString(IdResResponse.of(List.of(expectedEid))); @@ -315,7 +317,7 @@ public void callShouldCreateUserAndUseRequestedEidsWhenUserIsAbsent() { .extracting(AuctionRequestPayload::bidRequest) .extracting(BidRequest::getUser) .extracting(User::getEids) - .isEqualTo(List.of(expectedEid)); + .isEqualTo(List.of(expectedEid.toBuilder().inserter("s2s.liveintent.com").build())); verify(httpClient).post( eq("https://test.com/idres"), From 6d17fa754733c020a26394441126923da3e7657f Mon Sep 17 00:00:00 2001 From: ilya Date: Mon, 9 Mar 2026 13:23:00 +0100 Subject: [PATCH 2/5] DATA-53829: Fixing PR issues --- .../channel/identity/model/FullSource.java | 12 +++++++ ...elIdentityProcessedAuctionRequestHook.java | 35 +++++++++++++++---- ...entityProcessedAuctionRequestHookTest.java | 6 ++++ 3 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/FullSource.java diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/FullSource.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/FullSource.java new file mode 100644 index 00000000000..95a03e04cd5 --- /dev/null +++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/FullSource.java @@ -0,0 +1,12 @@ +package org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model; + +import lombok.Builder; +import lombok.Value; + +@Value +@Builder(toBuilder = true) +public class FullSource { + + String source; + String inserter; +} 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 ada30cc4ae3..26131d4c504 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.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.FullSource; 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; import org.prebid.server.hooks.modules.liveintent.omni.channel.identity.v1.LiveIntentOmniChannelIdentityModule; @@ -197,6 +198,9 @@ private InvocationResultImpl update(IdResResponse resolut private AuctionRequestPayload updatedPayload(AuctionRequestPayload requestPayload, List resolvedEids) { final List eids = ListUtils.emptyIfNull(resolvedEids); + if (CollectionUtils.isEmpty(eids)) { + return requestPayload; + } final BidRequest bidRequest = updateAllowedBidders(requestPayload.bidRequest(), resolvedEids); final User updatedUser = Optional.ofNullable(bidRequest.getUser()) .map(user -> user.toBuilder().eids(ListUtil.union(ListUtils.emptyIfNull(user.getEids()), eids))) @@ -207,7 +211,7 @@ private AuctionRequestPayload updatedPayload(AuctionRequestPayload requestPayloa } private BidRequest updateAllowedBidders(BidRequest bidRequest, List resolvedEids) { - if (CollectionUtils.isEmpty(targetBidders) || CollectionUtils.isEmpty(resolvedEids)) { + if (CollectionUtils.isEmpty(targetBidders)) { return bidRequest; } @@ -232,8 +236,8 @@ private BidRequest updateAllowedBidders(BidRequest bidRequest, List resolve private ExtRequestPrebidData updatePrebidData(ExtRequestPrebidData extPrebidData, List resolvedEids) { final List originalBidders = extPrebidData != null ? extPrebidData.getBidders() : null; - final Set resolvedSources = resolvedEids.stream() - .map(Eid::getSource) + final Set resolvedSources = resolvedEids.stream() + .map(eid -> FullSource.builder().source(eid.getSource()).inserter(eid.getInserter()).build()) .collect(Collectors.toSet()); final List eidPermissions = extPrebidData != null @@ -245,13 +249,30 @@ private ExtRequestPrebidData updatePrebidData(ExtRequestPrebidData extPrebidData .filter(Objects::nonNull) .toList(); - return ExtRequestPrebidData.of(originalBidders, updatedPermissions); + if (CollectionUtils.isEmpty(updatedPermissions)) { + return ExtRequestPrebidData.of( + originalBidders, + resolvedEids.stream() + .map(eid -> + ExtRequestPrebidDataEidPermissions.builder() + .bidders(targetBidders.stream().toList()) + .inserter(INSERTER) + .source(eid.getSource()) + .build()) + .toList()); + } else { + return ExtRequestPrebidData.of(originalBidders, updatedPermissions); + } } private ExtRequestPrebidDataEidPermissions restrictEidPermission(ExtRequestPrebidDataEidPermissions permission, - Set resolvedSources) { + Set resolvedSources) { - if (!resolvedSources.contains(permission.getSource())) { + final FullSource permFullSource = FullSource.builder() + .source(permission.getSource()) + .inserter(permission.getInserter()) + .build(); + if (!resolvedSources.contains(permFullSource)) { return permission; } @@ -260,6 +281,7 @@ private ExtRequestPrebidDataEidPermissions restrictEidPermission(ExtRequestPrebi if (CollectionUtils.isEmpty(permittedBidders) || permittedBidders.contains("*")) { return ExtRequestPrebidDataEidPermissions.builder() .source(permission.getSource()) + .inserter(permission.getInserter()) .bidders(targetBidders.stream().toList()) .build(); } @@ -272,6 +294,7 @@ private ExtRequestPrebidDataEidPermissions restrictEidPermission(ExtRequestPrebi ? null : ExtRequestPrebidDataEidPermissions.builder() .source(permission.getSource()) + .inserter(permission.getInserter()) .bidders(finalBidders) .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 9c2f2e992fa..af1f3ddb807 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 @@ -386,15 +386,18 @@ public void shouldRestrictExistingEidPermissionsByIntersectionAndKeepGlobalBidde final ExtRequestPrebidDataEidPermissions otherBidder = ExtRequestPrebidDataEidPermissions.builder() .source("some.other-source.com") + .inserter("some.other-inserter.com") .bidders(singletonList("bidderY")) .build(); final ExtRequestPrebidDataEidPermissions liBidder2 = ExtRequestPrebidDataEidPermissions.builder() .source("liveintent.com") + .inserter("s2s.liveintent.com") .bidders(singletonList("bidder2")) .build(); final ExtRequestPrebidDataEidPermissions liBidder23 = ExtRequestPrebidDataEidPermissions.builder() .source("liveintent.com") + .inserter("s2s.liveintent.com") .bidders(List.of("bidder2", "bidder3")) .build(); @@ -452,10 +455,12 @@ public void shouldNotAddNewEidPermissionsOrModifyGlobalBiddersWhenSourceNotPrese final User givenUser = User.builder().eids(singletonList(givenEid)).build(); final ExtRequestPrebidDataEidPermissions bidder1 = ExtRequestPrebidDataEidPermissions.builder() .source("some.other-source.com") + .inserter("some.other-inserter.com") .bidders(singletonList("bidder3")) .build(); final ExtRequestPrebidDataEidPermissions bidder2 = ExtRequestPrebidDataEidPermissions.builder() .source("some.source.com") + .inserter("s2s.liveintent.com") .bidders(singletonList("bidder3")) .build(); @@ -516,6 +521,7 @@ public void shouldRemovePermissionWhenIntersectionIsEmpty() { List.of( ExtRequestPrebidDataEidPermissions.builder() .source("liveintent.com") + .inserter("s2s.liveintent.com") .bidders(singletonList("not-allowed")) .build(), ExtRequestPrebidDataEidPermissions.builder() From d4eb7b2da0e0fefeac343263ee83a47019afad9a Mon Sep 17 00:00:00 2001 From: ilya Date: Tue, 10 Mar 2026 17:29:56 +0100 Subject: [PATCH 3/5] DATA-53829: Fixing PR issues --- ...OmniChannelIdentityProcessedAuctionRequestHook.java | 10 ++-------- .../request/ExtRequestPrebidDataEidPermissions.java | 2 +- 2 files changed, 3 insertions(+), 9 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 26131d4c504..73b7baba243 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 @@ -279,9 +279,7 @@ private ExtRequestPrebidDataEidPermissions restrictEidPermission(ExtRequestPrebi final List permittedBidders = ListUtils.emptyIfNull(permission.getBidders()); if (CollectionUtils.isEmpty(permittedBidders) || permittedBidders.contains("*")) { - return ExtRequestPrebidDataEidPermissions.builder() - .source(permission.getSource()) - .inserter(permission.getInserter()) + return permission.toBuilder() .bidders(targetBidders.stream().toList()) .build(); } @@ -292,11 +290,7 @@ private ExtRequestPrebidDataEidPermissions restrictEidPermission(ExtRequestPrebi return CollectionUtils.isEmpty(finalBidders) ? null - : ExtRequestPrebidDataEidPermissions.builder() - .source(permission.getSource()) - .inserter(permission.getInserter()) - .bidders(finalBidders) - .build(); + : permission.toBuilder().bidders(finalBidders).build(); } @Override diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/request/ExtRequestPrebidDataEidPermissions.java b/src/main/java/org/prebid/server/proto/openrtb/ext/request/ExtRequestPrebidDataEidPermissions.java index 2373c40e886..0e717619cdb 100644 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/request/ExtRequestPrebidDataEidPermissions.java +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/request/ExtRequestPrebidDataEidPermissions.java @@ -7,7 +7,7 @@ import java.util.List; @Value -@Builder +@Builder(toBuilder = true) public class ExtRequestPrebidDataEidPermissions { /** From d15ed9e1cfa93bf5e856e7abc7eb149b38336fb8 Mon Sep 17 00:00:00 2001 From: ilya Date: Thu, 12 Mar 2026 17:38:18 +0100 Subject: [PATCH 4/5] DATA-53829: Fixing PR issues --- .../channel/identity/model/FullSource.java | 5 ++- ...elIdentityProcessedAuctionRequestHook.java | 33 ++++++++----------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/FullSource.java b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/FullSource.java index 95a03e04cd5..ac6d393755c 100644 --- a/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/FullSource.java +++ b/extra/modules/live-intent-omni-channel-identity/src/main/java/org/prebid/server/hooks/modules/liveintent/omni/channel/identity/model/FullSource.java @@ -1,12 +1,11 @@ package org.prebid.server.hooks.modules.liveintent.omni.channel.identity.model; -import lombok.Builder; import lombok.Value; -@Value -@Builder(toBuilder = true) +@Value(staticConstructor = "of") public class FullSource { String source; + String inserter; } 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 73b7baba243..e03698f6a62 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 @@ -237,7 +237,7 @@ private ExtRequestPrebidData updatePrebidData(ExtRequestPrebidData extPrebidData final List originalBidders = extPrebidData != null ? extPrebidData.getBidders() : null; final Set resolvedSources = resolvedEids.stream() - .map(eid -> FullSource.builder().source(eid.getSource()).inserter(eid.getInserter()).build()) + .map(eid -> FullSource.of(eid.getSource(), eid.getInserter())) .collect(Collectors.toSet()); final List eidPermissions = extPrebidData != null @@ -249,29 +249,24 @@ private ExtRequestPrebidData updatePrebidData(ExtRequestPrebidData extPrebidData .filter(Objects::nonNull) .toList(); - if (CollectionUtils.isEmpty(updatedPermissions)) { - return ExtRequestPrebidData.of( - originalBidders, - resolvedEids.stream() - .map(eid -> - ExtRequestPrebidDataEidPermissions.builder() - .bidders(targetBidders.stream().toList()) - .inserter(INSERTER) - .source(eid.getSource()) - .build()) - .toList()); - } else { - return ExtRequestPrebidData.of(originalBidders, updatedPermissions); - } + return CollectionUtils.isEmpty(updatedPermissions) + ? ExtRequestPrebidData.of( + originalBidders, + resolvedEids.stream() + .map(eid -> + ExtRequestPrebidDataEidPermissions.builder() + .bidders(targetBidders.stream().toList()) + .inserter(INSERTER) + .source(eid.getSource()) + .build()) + .toList()) + : ExtRequestPrebidData.of(originalBidders, updatedPermissions); } private ExtRequestPrebidDataEidPermissions restrictEidPermission(ExtRequestPrebidDataEidPermissions permission, Set resolvedSources) { - final FullSource permFullSource = FullSource.builder() - .source(permission.getSource()) - .inserter(permission.getInserter()) - .build(); + final FullSource permFullSource = FullSource.of(permission.getSource(), permission.getInserter()); if (!resolvedSources.contains(permFullSource)) { return permission; } From dd8194ed8be7f1fbe96353a2ac3afbc17e82436c Mon Sep 17 00:00:00 2001 From: ilya Date: Wed, 25 Mar 2026 17:27:42 +0100 Subject: [PATCH 5/5] DATA-53829: Fixing PR issues --- ...elIdentityProcessedAuctionRequestHook.java | 138 ++++++++++-------- ...entityProcessedAuctionRequestHookTest.java | 21 ++- 2 files changed, 95 insertions(+), 64 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 e03698f6a62..ba5203e5e75 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 @@ -10,6 +10,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.ListUtils; import org.apache.commons.collections4.SetUtils; +import org.apache.commons.lang3.StringUtils; import org.prebid.server.activity.Activity; import org.prebid.server.activity.ComponentType; import org.prebid.server.activity.infrastructure.ActivityInfrastructure; @@ -23,7 +24,6 @@ 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.FullSource; 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; import org.prebid.server.hooks.modules.liveintent.omni.channel.identity.v1.LiveIntentOmniChannelIdentityModule; @@ -45,7 +45,6 @@ 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.Objects; import java.util.Optional; @@ -166,10 +165,17 @@ private MultiMap headers() { private IdResResponse processResponse(HttpClientResponse response) { final IdResResponse res = mapper.decodeValue(response.getBody(), IdResResponse.class); - final List eids = res.getEids().stream() + final List eids = res.getEids(); + + if (CollectionUtils.isEmpty(eids)) { + return res; + } + + final List modifiedEids = eids.stream() .map(eid -> eid.toBuilder().inserter(INSERTER).build()) .toList(); - return IdResResponse.of(eids); + + return IdResResponse.of(modifiedEids); } private static Future> noAction() { @@ -197,32 +203,37 @@ private InvocationResultImpl update(IdResResponse resolut } private AuctionRequestPayload updatedPayload(AuctionRequestPayload requestPayload, List resolvedEids) { - final List eids = ListUtils.emptyIfNull(resolvedEids); - if (CollectionUtils.isEmpty(eids)) { - return requestPayload; - } - final BidRequest bidRequest = updateAllowedBidders(requestPayload.bidRequest(), resolvedEids); - final User updatedUser = Optional.ofNullable(bidRequest.getUser()) - .map(user -> user.toBuilder().eids(ListUtil.union(ListUtils.emptyIfNull(user.getEids()), eids))) - .orElseGet(() -> User.builder().eids(eids)) - .build(); + return CollectionUtils.isNotEmpty(resolvedEids) + ? AuctionRequestPayloadImpl.of(updateBidRequest(requestPayload.bidRequest(), resolvedEids)) + : requestPayload; + } - return AuctionRequestPayloadImpl.of(bidRequest.toBuilder().user(updatedUser).build()); + private BidRequest updateBidRequest(BidRequest bidRequest, List resolvedEids) { + return bidRequest.toBuilder() + .ext(updateExtRequest(bidRequest.getExt(), resolvedEids)) + .user(updateUser(bidRequest.getUser(), resolvedEids)) + .build(); } - private BidRequest updateAllowedBidders(BidRequest bidRequest, List resolvedEids) { - if (CollectionUtils.isEmpty(targetBidders)) { - return bidRequest; - } + private ExtRequest updateExtRequest(ExtRequest ext, List resolvedEids) { + final Set uniqueSources = CollectionUtils.emptyIfNull(resolvedEids).stream() + .map(Eid::getSource) + .filter(StringUtils::isNotEmpty) + .collect(Collectors.toSet()); - final ExtRequest ext = bidRequest.getExt(); final ExtRequestPrebid extPrebid = ext != null ? ext.getPrebid() : null; final ExtRequestPrebidData extPrebidData = extPrebid != null ? extPrebid.getData() : null; + final List eidPermissions = + extPrebidData != null ? extPrebidData.getEidPermissions() : null; + + final List modifiedEidPermissions = CollectionUtils.isEmpty(eidPermissions) + ? createEidPermissions(uniqueSources) + : modifyEidPermissions(eidPermissions, uniqueSources); final ExtRequestPrebid updatedExtPrebid = Optional.ofNullable(extPrebid) .map(ExtRequestPrebid::toBuilder) .orElseGet(ExtRequestPrebid::builder) - .data(updatePrebidData(extPrebidData, resolvedEids)) + .data(updatePrebidData(extPrebidData, modifiedEidPermissions)) .build(); final ExtRequest updatedExtRequest = ExtRequest.of(updatedExtPrebid); @@ -230,62 +241,71 @@ private BidRequest updateAllowedBidders(BidRequest bidRequest, List resolve mapper.fillExtension(updatedExtRequest, ext.getProperties()); } - return bidRequest.toBuilder().ext(updatedExtRequest).build(); + return updatedExtRequest; } - private ExtRequestPrebidData updatePrebidData(ExtRequestPrebidData extPrebidData, List resolvedEids) { - final List originalBidders = extPrebidData != null ? extPrebidData.getBidders() : null; + private static User updateUser(User user, List resolvedEids) { + final List updatedEids = Optional.ofNullable(user) + .map(User::getEids) + .map(eids -> ListUtil.union(eids, resolvedEids)) + .orElse(resolvedEids); - final Set resolvedSources = resolvedEids.stream() - .map(eid -> FullSource.of(eid.getSource(), eid.getInserter())) - .collect(Collectors.toSet()); + return Optional.ofNullable(user) + .map(User::toBuilder) + .orElseGet(User::builder) + .eids(updatedEids) + .build(); + } - final List eidPermissions = extPrebidData != null - ? ListUtils.emptyIfNull(extPrebidData.getEidPermissions()) - : Collections.emptyList(); + private List createEidPermissions(Set sources) { + return sources.stream() + .map(source -> ExtRequestPrebidDataEidPermissions.builder() + .source(source) + .inserter(INSERTER) + .bidders(targetBidders.stream().toList()) + .build()) + .toList(); + } - final List updatedPermissions = eidPermissions.stream() - .map(permission -> restrictEidPermission(permission, resolvedSources)) + private List modifyEidPermissions( + List eidPermissions, + Set sources) { + final List modifiedEidPermissions = eidPermissions.stream() + .map(it -> updateEidPermission(it, sources)) .filter(Objects::nonNull) .toList(); - - return CollectionUtils.isEmpty(updatedPermissions) - ? ExtRequestPrebidData.of( - originalBidders, - resolvedEids.stream() - .map(eid -> - ExtRequestPrebidDataEidPermissions.builder() - .bidders(targetBidders.stream().toList()) - .inserter(INSERTER) - .source(eid.getSource()) - .build()) - .toList()) - : ExtRequestPrebidData.of(originalBidders, updatedPermissions); + final List defaultEidPermissions = createEidPermissions(sources); + return ListUtils.union(modifiedEidPermissions, defaultEidPermissions); } - private ExtRequestPrebidDataEidPermissions restrictEidPermission(ExtRequestPrebidDataEidPermissions permission, - Set resolvedSources) { + private ExtRequestPrebidData updatePrebidData(ExtRequestPrebidData extPrebidData, + List eidPermissions) { - final FullSource permFullSource = FullSource.of(permission.getSource(), permission.getInserter()); - if (!resolvedSources.contains(permFullSource)) { - return permission; - } + final List originalBidders = extPrebidData != null ? extPrebidData.getBidders() : null; - final List permittedBidders = ListUtils.emptyIfNull(permission.getBidders()); + return ExtRequestPrebidData.of(originalBidders, eidPermissions); + } - if (CollectionUtils.isEmpty(permittedBidders) || permittedBidders.contains("*")) { - return permission.toBuilder() - .bidders(targetBidders.stream().toList()) - .build(); + private ExtRequestPrebidDataEidPermissions updateEidPermission(ExtRequestPrebidDataEidPermissions eidPermission, + Set sources) { + if (!sources.contains(eidPermission.getSource()) || !INSERTER.equals(eidPermission.getInserter())) { + return eidPermission; } - final List finalBidders = ListUtils.emptyIfNull(permission.getBidders()).stream() + final List allowedBidders = ListUtils.emptyIfNull(eidPermission.getBidders()); + final List finalBidders = allowedBidders.stream() .filter(targetBidders::contains) .toList(); - return CollectionUtils.isEmpty(finalBidders) - ? null - : permission.toBuilder().bidders(finalBidders).build(); + if (CollectionUtils.isEmpty(allowedBidders) || allowedBidders.contains("*")) { + return eidPermission.toBuilder().bidders(targetBidders.stream().toList()).build(); + } + + if (CollectionUtils.isEmpty(finalBidders)) { + return null; + } + + return eidPermission.toBuilder().bidders(finalBidders).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 af1f3ddb807..e89910b02de 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 @@ -32,6 +32,7 @@ import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebid; import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebidData; import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebidDataEidPermissions; +import org.prebid.server.util.ListUtil; import org.prebid.server.vertx.httpclient.HttpClient; import org.prebid.server.vertx.httpclient.model.HttpClientResponse; @@ -77,6 +78,8 @@ public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHookTest { private Set configuredBidders; + private ExtRequestPrebidDataEidPermissions defaultPermissions; + @BeforeEach public void setUp() { configuredBidders = Set.of("bidder1", "bidder2"); @@ -86,6 +89,12 @@ public void setUp() { given(properties.getTreatmentRate()).willReturn(1.0f); given(properties.getTargetBidders()).willReturn(configuredBidders); + defaultPermissions = ExtRequestPrebidDataEidPermissions.builder() + .inserter("s2s.liveintent.com") + .bidders(configuredBidders.stream().toList()) + .source("liveintent.com") + .build(); + target = new LiveIntentOmniChannelIdentityProcessedAuctionRequestHook( properties, userFpdActivityMask, MAPPER, httpClient, 0.01d); } @@ -412,7 +421,7 @@ public void shouldRestrictExistingEidPermissionsByIntersectionAndKeepGlobalBidde final ExtRequestPrebidData expectedData = ExtRequestPrebidData.of( List.of("bidderX"), - List.of(otherBidder, liBidder2)); + ListUtil.union(List.of(otherBidder, liBidder2), List.of(defaultPermissions))); final Eid expectedEid = Eid.builder().source("liveintent.com").build(); @@ -474,7 +483,8 @@ public void shouldNotAddNewEidPermissionsOrModifyGlobalBiddersWhenSourceNotPrese .build())) .build(); - final ExtRequestPrebidData expectedData = ExtRequestPrebidData.of(List.of("bidder3"), bidders); + final ExtRequestPrebidData expectedData = ExtRequestPrebidData.of(List.of("bidder3"), + ListUtil.union(bidders, List.of(defaultPermissions))); final Eid expectedEid = Eid.builder().source("liveintent.com").build(); @@ -556,9 +566,10 @@ public void shouldRemovePermissionWhenIntersectionIsEmpty() { final ExtRequestPrebidData expectedData = ExtRequestPrebidData.of( List.of("bidderGlobal"), List.of(ExtRequestPrebidDataEidPermissions.builder() - .source("keep.com") - .bidders(singletonList("bidderGlobal")) - .build())); + .source("keep.com") + .bidders(singletonList("bidderGlobal")) + .build(), + defaultPermissions)); assertThat(result.status()).isEqualTo(InvocationStatus.success); assertThat(result.payloadUpdate().apply(AuctionRequestPayloadImpl.of(givenBidRequest)))