Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
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;
Expand Down Expand Up @@ -50,7 +49,6 @@
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;

public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHook implements ProcessedAuctionRequestHook {

Expand All @@ -61,6 +59,9 @@ public class LiveIntentOmniChannelIdentityProcessedAuctionRequestHook implements

private static final String INSERTER = "s2s.liveintent.com";

// IdResResponse is already stamped by Ulysses, in the EID's matcher field, it has "liveintent.com"
private static final String MATCHER = "liveintent.com";

private final LiveIntentOmniChannelProperties config;
private final JacksonMapper mapper;
private final HttpClient httpClient;
Expand Down Expand Up @@ -216,19 +217,19 @@ private BidRequest updateBidRequest(BidRequest bidRequest, List<Eid> resolvedEid
}

private ExtRequest updateExtRequest(ExtRequest ext, List<Eid> resolvedEids) {
final Set<String> uniqueSources = CollectionUtils.emptyIfNull(resolvedEids).stream()
.map(Eid::getSource)
.filter(StringUtils::isNotEmpty)
.collect(Collectors.toSet());
if (CollectionUtils.isEmpty(resolvedEids)) {
return ext;
}

final ExtRequestPrebid extPrebid = ext != null ? ext.getPrebid() : null;
final ExtRequestPrebidData extPrebidData = extPrebid != null ? extPrebid.getData() : null;
final List<ExtRequestPrebidDataEidPermissions> eidPermissions =
extPrebidData != null ? extPrebidData.getEidPermissions() : null;

final List<ExtRequestPrebidDataEidPermissions> modifiedEidPermissions = CollectionUtils.isEmpty(eidPermissions)
? createEidPermissions(uniqueSources)
: modifyEidPermissions(eidPermissions, uniqueSources);
final List<ExtRequestPrebidDataEidPermissions> modifiedEidPermissions = CollectionUtils
.isEmpty(eidPermissions)
? createEidPermissions()
: modifyEidPermissions(eidPermissions);

final ExtRequestPrebid updatedExtPrebid = Optional.ofNullable(extPrebid)
.map(ExtRequestPrebid::toBuilder)
Expand Down Expand Up @@ -257,24 +258,21 @@ private static User updateUser(User user, List<Eid> resolvedEids) {
.build();
}

private List<ExtRequestPrebidDataEidPermissions> createEidPermissions(Set<String> sources) {
return sources.stream()
.map(source -> ExtRequestPrebidDataEidPermissions.builder()
.source(source)
.inserter(INSERTER)
.bidders(targetBidders.stream().toList())
.build())
.toList();
private List<ExtRequestPrebidDataEidPermissions> createEidPermissions() {
return List.of(ExtRequestPrebidDataEidPermissions.builder()
.matcher(MATCHER)
.inserter(INSERTER)
.bidders(targetBidders.stream().toList())
.build());
}

private List<ExtRequestPrebidDataEidPermissions> modifyEidPermissions(
List<ExtRequestPrebidDataEidPermissions> eidPermissions,
Set<String> sources) {
List<ExtRequestPrebidDataEidPermissions> eidPermissions) {
final List<ExtRequestPrebidDataEidPermissions> modifiedEidPermissions = eidPermissions.stream()
.map(it -> updateEidPermission(it, sources))
.filter(Objects::nonNull)
.toList();
final List<ExtRequestPrebidDataEidPermissions> defaultEidPermissions = createEidPermissions(sources);
.map(this::updateEidPermission)
.filter(Objects::nonNull)
.toList();
final List<ExtRequestPrebidDataEidPermissions> defaultEidPermissions = createEidPermissions();
return ListUtils.union(modifiedEidPermissions, defaultEidPermissions);
}

Expand All @@ -286,10 +284,9 @@ private ExtRequestPrebidData updatePrebidData(ExtRequestPrebidData extPrebidData
return ExtRequestPrebidData.of(originalBidders, eidPermissions);
}

private ExtRequestPrebidDataEidPermissions updateEidPermission(ExtRequestPrebidDataEidPermissions eidPermission,
Set<String> sources) {
if (!sources.contains(eidPermission.getSource()) || !INSERTER.equals(eidPermission.getInserter())) {
return eidPermission;
private ExtRequestPrebidDataEidPermissions updateEidPermission(ExtRequestPrebidDataEidPermissions eidPermission) {
if (!MATCHER.equals(eidPermission.getMatcher()) || !INSERTER.equals(eidPermission.getInserter())) {
return eidPermission;
}

final List<String> allowedBidders = ListUtils.emptyIfNull(eidPermission.getBidders());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ public void setUp() {

defaultPermissions = ExtRequestPrebidDataEidPermissions.builder()
.inserter("s2s.liveintent.com")
.matcher("liveintent.com")
.bidders(configuredBidders.stream().toList())
.source("liveintent.com")
.build();

target = new LiveIntentOmniChannelIdentityProcessedAuctionRequestHook(
Expand Down Expand Up @@ -254,13 +254,13 @@ public void callShouldEnrichUserEidsWithRequestedEids() {
final User givenUser = User.builder().eids(singletonList(givenEid)).build();
final BidRequest givenBidRequest = BidRequest.builder().id("request").user(givenUser).build();

final Eid expectedEid = Eid.builder()
final Eid apiResponseEid = Eid.builder()
.source("liveintent.com")
.uids(singletonList(Uid.builder().id("id2").atype(3).build()))
.matcher("liveintent.com")
.uids(singletonList(Uid.builder().id("id2").atype(3).build()))
.build();

final String responseBody = MAPPER.encodeToString(IdResResponse.of(List.of(expectedEid)));
final String responseBody = MAPPER.encodeToString(IdResResponse.of(List.of(apiResponseEid)));
given(httpClient.post(any(), any(), any(), anyLong()))
.willReturn(Future.succeededFuture(HttpClientResponse.of(200, null, responseBody)));

Expand All @@ -279,11 +279,24 @@ public void callShouldEnrichUserEidsWithRequestedEids() {
// then
assertThat(result.status()).isEqualTo(InvocationStatus.success);
assertThat(result.action()).isEqualTo(InvocationAction.update);
assertThat(result.payloadUpdate().apply(AuctionRequestPayloadImpl.of(givenBidRequest)))

final AuctionRequestPayload updatedPayload =
result.payloadUpdate().apply(AuctionRequestPayloadImpl.of(givenBidRequest));

assertThat(updatedPayload)
.extracting(AuctionRequestPayload::bidRequest)
.extracting(BidRequest::getUser)
.extracting(User::getEids)
.isEqualTo(List.of(givenEid, expectedEid.toBuilder().inserter("s2s.liveintent.com").build()));
.isEqualTo(List.of(givenEid, apiResponseEid.toBuilder()
.inserter("s2s.liveintent.com")
.build()));

assertThat(updatedPayload)
.extracting(AuctionRequestPayload::bidRequest)
.extracting(BidRequest::getExt)
.extracting(ExtRequest::getPrebid)
.extracting(ExtRequestPrebid::getData)
.isEqualTo(ExtRequestPrebidData.of(null, List.of(defaultPermissions)));

verify(httpClient).post(
eq("https://test.com/idres"),
Expand All @@ -297,13 +310,12 @@ public void callShouldCreateUserAndUseRequestedEidsWhenUserIsAbsent() {
// given
final BidRequest givenBidRequest = BidRequest.builder().id("request").user(null).build();

final Eid expectedEid = Eid.builder()
final Eid apiResponseEid = 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)));
final String responseBody = MAPPER.encodeToString(IdResResponse.of(List.of(apiResponseEid)));
given(httpClient.post(any(), any(), any(), anyLong()))
.willReturn(Future.succeededFuture(HttpClientResponse.of(200, null, responseBody)));

Expand All @@ -326,7 +338,10 @@ public void callShouldCreateUserAndUseRequestedEidsWhenUserIsAbsent() {
.extracting(AuctionRequestPayload::bidRequest)
.extracting(BidRequest::getUser)
.extracting(User::getEids)
.isEqualTo(List.of(expectedEid.toBuilder().inserter("s2s.liveintent.com").build()));
.isEqualTo(List.of(apiResponseEid.toBuilder()
.inserter("s2s.liveintent.com")
.matcher("liveintent.com")
.build()));

verify(httpClient).post(
eq("https://test.com/idres"),
Expand Down Expand Up @@ -400,12 +415,12 @@ public void shouldRestrictExistingEidPermissionsByIntersectionAndKeepGlobalBidde
.build();

final ExtRequestPrebidDataEidPermissions liBidder2 = ExtRequestPrebidDataEidPermissions.builder()
.source("liveintent.com")
.matcher("liveintent.com")
.inserter("s2s.liveintent.com")
.bidders(singletonList("bidder2"))
.build();
final ExtRequestPrebidDataEidPermissions liBidder23 = ExtRequestPrebidDataEidPermissions.builder()
.source("liveintent.com")
.matcher("liveintent.com")
.inserter("s2s.liveintent.com")
.bidders(List.of("bidder2", "bidder3"))
.build();
Expand Down Expand Up @@ -456,69 +471,6 @@ public void shouldRestrictExistingEidPermissionsByIntersectionAndKeepGlobalBidde
eq(5L));
}

@Test
public void shouldNotAddNewEidPermissionsOrModifyGlobalBiddersWhenSourceNotPresent() {
// given
final Uid givenUid = Uid.builder().id("id1").atype(2).build();
final Eid givenEid = Eid.builder().source("some.source.com").uids(singletonList(givenUid)).build();
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();

final List<ExtRequestPrebidDataEidPermissions> bidders = List.of(bidder1, bidder2);

final BidRequest givenBidRequest = BidRequest.builder()
.id("request")
.user(givenUser)
.ext(ExtRequest.of(ExtRequestPrebid.builder()
.data(ExtRequestPrebidData.of(singletonList("bidder3"), bidders))
.build()))
.build();

final ExtRequestPrebidData expectedData = ExtRequestPrebidData.of(List.of("bidder3"),
ListUtil.union(bidders, List.of(defaultPermissions)));

final Eid expectedEid = Eid.builder().source("liveintent.com").build();

final String responseBody = MAPPER.encodeToString(IdResResponse.of(List.of(expectedEid)));
given(httpClient.post(any(), any(), any(), anyLong()))
.willReturn(Future.succeededFuture(HttpClientResponse.of(200, null, responseBody)));

given(auctionInvocationContext.auctionContext()).willReturn(auctionContext);
given(auctionContext.getActivityInfrastructure()).willReturn(activityInfrastructure);
given(activityInfrastructure.isAllowed(any(), any())).willReturn(true);
given(userFpdActivityMask.maskUser(any(), eq(false), eq(false)))
.willAnswer(invocation -> invocation.getArgument(0));
given(userFpdActivityMask.maskDevice(any(), eq(false), eq(false)))
.willAnswer(invocation -> invocation.getArgument(0));

// when
final InvocationResult<AuctionRequestPayload> result =
target.call(AuctionRequestPayloadImpl.of(givenBidRequest), auctionInvocationContext).result();
// then
assertThat(result.status()).isEqualTo(InvocationStatus.success);
assertThat(result.payloadUpdate().apply(AuctionRequestPayloadImpl.of(givenBidRequest)))
.extracting(AuctionRequestPayload::bidRequest)
.extracting(BidRequest::getExt)
.extracting(ExtRequest::getPrebid)
.extracting(ExtRequestPrebid::getData)
.isEqualTo(expectedData);

verify(httpClient).post(
eq("https://test.com/idres"),
argThat(headers -> headers.contains("Authorization", "Bearer auth_token", true)),
eq(MAPPER.encodeToString(givenBidRequest)),
eq(5L));
}

@Test
public void shouldRemovePermissionWhenIntersectionIsEmpty() {
// given
Expand All @@ -530,7 +482,7 @@ public void shouldRemovePermissionWhenIntersectionIsEmpty() {
List.of("bidderGlobal"),
List.of(
ExtRequestPrebidDataEidPermissions.builder()
.source("liveintent.com")
.matcher("liveintent.com")
.inserter("s2s.liveintent.com")
.bidders(singletonList("not-allowed"))
.build(),
Expand Down