Skip to content

Commit

Permalink
Merge branch 'refs/heads/master' into cache-update
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/main/java/org/prebid/server/settings/CachingApplicationSettings.java
  • Loading branch information
osulzhenko committed Jun 3, 2024
2 parents 74320c1 + 6160015 commit 3fada4f
Show file tree
Hide file tree
Showing 255 changed files with 2,435 additions and 952 deletions.
1 change: 1 addition & 0 deletions docs/config-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ Removes and downloads file again if depending service cant process probably corr
- `auction.validations.secure-markup` - enables secure markup validation. Possible values: `skip`, `enforce`, `warn`. Default is `skip`.
- `auction.host-schain-node` - defines global schain node that will be appended to `request.source.ext.schain.nodes` passed to bidders
- `auction.category-mapping-enabled` - if equals to `true` the category mapping feature will be active while auction.
- `auction.strict-app-site-dooh` - if set to `true`, it will reject requests that contain more than one of app/site/dooh. Defaults to `false`.

## Event
- `event.default-timeout-ms` - timeout for event notifications
Expand Down
2 changes: 1 addition & 1 deletion extra/bundle/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.prebid</groupId>
<artifactId>prebid-server-aggregator</artifactId>
<version>3.1.0-SNAPSHOT</version>
<version>3.2.0-SNAPSHOT</version>
<relativePath>../../extra/pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion extra/modules/confiant-ad-quality/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.prebid.server.hooks.modules</groupId>
<artifactId>all-modules</artifactId>
<version>3.1.0-SNAPSHOT</version>
<version>3.2.0-SNAPSHOT</version>
</parent>

<artifactId>confiant-ad-quality</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion extra/modules/ortb2-blocking/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.prebid.server.hooks.modules</groupId>
<artifactId>all-modules</artifactId>
<version>3.1.0-SNAPSHOT</version>
<version>3.2.0-SNAPSHOT</version>
</parent>

<artifactId>ortb2-blocking</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion extra/modules/pb-richmedia-filter/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.prebid.server.hooks.modules</groupId>
<artifactId>all-modules</artifactId>
<version>3.1.0-SNAPSHOT</version>
<version>3.2.0-SNAPSHOT</version>
</parent>

<artifactId>pb-richmedia-filter</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion extra/modules/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.prebid</groupId>
<artifactId>prebid-server-aggregator</artifactId>
<version>3.1.0-SNAPSHOT</version>
<version>3.2.0-SNAPSHOT</version>
<relativePath>../../extra/pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion extra/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>org.prebid</groupId>
<artifactId>prebid-server-aggregator</artifactId>
<version>3.1.0-SNAPSHOT</version>
<version>3.2.0-SNAPSHOT</version>
<packaging>pom</packaging>

<scm>
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.prebid</groupId>
<artifactId>prebid-server-aggregator</artifactId>
<version>3.1.0-SNAPSHOT</version>
<version>3.2.0-SNAPSHOT</version>
<relativePath>extra/pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,28 +166,33 @@ private static boolean isNotEmptyObjectNode(JsonNode analytics) {
private static <T> boolean isAllowedAdapter(T event, String adapter) {
final ActivityInfrastructure activityInfrastructure;
final ActivityInvocationPayload activityInvocationPayload;
if (event instanceof AuctionEvent auctionEvent) {
final AuctionContext auctionContext = auctionEvent.getAuctionContext();
activityInfrastructure = auctionContext != null ? auctionContext.getActivityInfrastructure() : null;
activityInvocationPayload = auctionContext != null
? BidRequestActivityInvocationPayload.of(
activityInvocationPayload(adapter),
auctionContext.getBidRequest())
: null;
} else if (event instanceof AmpEvent ampEvent) {
final AuctionContext auctionContext = ampEvent.getAuctionContext();
activityInfrastructure = auctionContext != null ? auctionContext.getActivityInfrastructure() : null;
activityInvocationPayload = auctionContext != null
? BidRequestActivityInvocationPayload.of(
activityInvocationPayload(adapter),
auctionContext.getBidRequest())
: null;
} else if (event instanceof NotificationEvent notificationEvent) {
activityInfrastructure = notificationEvent.getActivityInfrastructure();
activityInvocationPayload = activityInvocationPayload(adapter);
} else {
activityInfrastructure = null;
activityInvocationPayload = null;
switch (event) {
case AuctionEvent auctionEvent -> {
final AuctionContext auctionContext = auctionEvent.getAuctionContext();
activityInfrastructure = auctionContext != null ? auctionContext.getActivityInfrastructure() : null;
activityInvocationPayload = auctionContext != null
? BidRequestActivityInvocationPayload.of(
activityInvocationPayload(adapter),
auctionContext.getBidRequest())
: null;
}
case AmpEvent ampEvent -> {
final AuctionContext auctionContext = ampEvent.getAuctionContext();
activityInfrastructure = auctionContext != null ? auctionContext.getActivityInfrastructure() : null;
activityInvocationPayload = auctionContext != null
? BidRequestActivityInvocationPayload.of(
activityInvocationPayload(adapter),
auctionContext.getBidRequest())
: null;
}
case NotificationEvent notificationEvent -> {
activityInfrastructure = notificationEvent.getActivityInfrastructure();
activityInvocationPayload = activityInvocationPayload(adapter);
}
case null, default -> {
activityInfrastructure = null;
activityInvocationPayload = null;
}
}

return isAllowedActivity(activityInfrastructure, Activity.REPORT_ANALYTICS, activityInvocationPayload);
Expand Down Expand Up @@ -318,23 +323,15 @@ private <T> Future<Void> processFail(Throwable exception, T event, String report
}

private <T> void updateMetricsByEventType(T event, String analyticsCode, MetricName result) {
final MetricName eventType;

if (event instanceof AmpEvent) {
eventType = MetricName.event_amp;
} else if (event instanceof AuctionEvent) {
eventType = MetricName.event_auction;
} else if (event instanceof CookieSyncEvent) {
eventType = MetricName.event_cookie_sync;
} else if (event instanceof NotificationEvent) {
eventType = MetricName.event_notification;
} else if (event instanceof SetuidEvent) {
eventType = MetricName.event_setuid;
} else if (event instanceof VideoEvent) {
eventType = MetricName.event_video;
} else {
eventType = MetricName.event_unknown;
}
final MetricName eventType = switch (event) {
case AmpEvent ampEvent -> MetricName.event_amp;
case AuctionEvent auctionEvent -> MetricName.event_auction;
case CookieSyncEvent cookieSyncEvent -> MetricName.event_cookie_sync;
case NotificationEvent notificationEvent -> MetricName.event_notification;
case SetuidEvent setuidEvent -> MetricName.event_setuid;
case VideoEvent videoEvent -> MetricName.event_video;
case null, default -> MetricName.event_unknown;
};

metrics.updateAnalyticEventMetric(analyticsCode, eventType, result);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,18 @@ public LogAnalyticsReporter(JacksonMapper mapper) {

@Override
public <T> Future<Void> processEvent(T event) {
final LogEvent<?> logEvent;

if (event instanceof AmpEvent ampEvent) {
logEvent = LogEvent.of("/openrtb2/amp", ampEvent.getBidResponse());
} else if (event instanceof AuctionEvent auctionEvent) {
logEvent = LogEvent.of("/openrtb2/auction", auctionEvent.getBidResponse());
} else if (event instanceof CookieSyncEvent cookieSyncEvent) {
logEvent = LogEvent.of("/cookie_sync", cookieSyncEvent.getBidderStatus());
} else if (event instanceof NotificationEvent notificationEvent) {
logEvent = LogEvent.of("/event", notificationEvent.getType() + notificationEvent.getBidId());
} else if (event instanceof SetuidEvent setuidEvent) {
logEvent = LogEvent.of(
final LogEvent<?> logEvent = switch (event) {
case AmpEvent ampEvent -> LogEvent.of("/openrtb2/amp", ampEvent.getBidResponse());
case AuctionEvent auctionEvent -> LogEvent.of("/openrtb2/auction", auctionEvent.getBidResponse());
case CookieSyncEvent cookieSyncEvent -> LogEvent.of("/cookie_sync", cookieSyncEvent.getBidderStatus());
case NotificationEvent notificationEvent ->
LogEvent.of("/event", notificationEvent.getType() + notificationEvent.getBidId());
case SetuidEvent setuidEvent -> LogEvent.of(
"/setuid",
setuidEvent.getBidder() + ":" + setuidEvent.getUid() + ":" + setuidEvent.getSuccess());
} else if (event instanceof VideoEvent videoEvent) {
logEvent = LogEvent.of("/openrtb2/video", videoEvent.getBidResponse());
} else {
logEvent = LogEvent.of("unknown", null);
}
case VideoEvent videoEvent -> LogEvent.of("/openrtb2/video", videoEvent.getBidResponse());
case null, default -> LogEvent.of("unknown", null);
};

logger.debug(mapper.encodeToString(logEvent));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,15 @@ private static String buildEventEndpointUrl(String endpoint, EventType eventType

@Override
public <T> Future<Void> processEvent(T event) {
final EventType eventType;

if (event instanceof AmpEvent) {
eventType = EventType.amp;
} else if (event instanceof AuctionEvent) {
eventType = EventType.auction;
} else if (event instanceof CookieSyncEvent) {
eventType = EventType.cookiesync;
} else if (event instanceof NotificationEvent) {
eventType = EventType.notification;
} else if (event instanceof SetuidEvent) {
eventType = EventType.setuid;
} else if (event instanceof VideoEvent) {
eventType = EventType.video;
} else {
eventType = null;
}
final EventType eventType = switch (event) {
case AmpEvent ampEvent -> EventType.amp;
case AuctionEvent auctionEvent -> EventType.auction;
case CookieSyncEvent cookieSyncEvent -> EventType.cookiesync;
case NotificationEvent notificationEvent -> EventType.notification;
case SetuidEvent setuidEvent -> EventType.setuid;
case VideoEvent videoEvent -> EventType.video;
case null, default -> null;
};

if (eventType != null) {
eventHandlers.get(eventType).handle(event);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public <T> void handle(T event) {

public void reportEvents() {
if (enabled) {
reportEventsOnCondition(events -> events.get().size() > 0, events);
reportEventsOnCondition(events -> !events.get().isEmpty(), events);
}
}

Expand Down Expand Up @@ -179,7 +179,7 @@ private long setReportTtlTimer() {
}

private void sendOnTimer() {
final boolean requestWasSent = reportEventsOnCondition(events -> events.get().size() > 0, events);
final boolean requestWasSent = reportEventsOnCondition(events -> !events.get().isEmpty(), events);
if (!requestWasSent) {
setReportTtlTimer();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ private Future<BidResponse> cacheBidsAndCreateResponse(List<BidderResponseInfo>

return Future.succeededFuture(BidResponse.builder()
.id(bidRequest.getId())
.cur(bidRequest.getCur().get(0))
.cur(bidRequest.getCur().getFirst())
.nbr(0) // signal "Unknown Error"
.seatbid(Collections.emptyList())
.ext(extBidResponse)
Expand Down Expand Up @@ -1130,7 +1130,7 @@ private BidResponse toBidResponse(List<BidderResponseInfo> bidderResponseInfos,

return BidResponse.builder()
.id(bidRequest.getId())
.cur(bidRequest.getCur().get(0))
.cur(bidRequest.getCur().getFirst())
.seatbid(seatBids)
.ext(extBidResponse)
.build();
Expand Down
87 changes: 78 additions & 9 deletions src/main/java/org/prebid/server/auction/DsaEnforcer.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.prebid.server.auction;

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.JsonNode;
import com.iab.openrtb.request.BidRequest;
import com.iab.openrtb.request.Regs;
import com.iab.openrtb.response.Bid;
Expand All @@ -12,19 +12,35 @@
import org.prebid.server.bidder.model.BidderBid;
import org.prebid.server.bidder.model.BidderError;
import org.prebid.server.bidder.model.BidderSeatBid;
import org.prebid.server.exception.PreBidException;
import org.prebid.server.json.JacksonMapper;
import org.prebid.server.proto.openrtb.ext.request.DsaPublisherRender;
import org.prebid.server.proto.openrtb.ext.request.DsaRequired;
import org.prebid.server.proto.openrtb.ext.request.ExtRegs;
import org.prebid.server.proto.openrtb.ext.request.ExtRegsDsa;
import org.prebid.server.proto.openrtb.ext.response.DsaAdvertiserRender;
import org.prebid.server.proto.openrtb.ext.response.ExtBidDsa;
import org.prebid.server.util.ObjectUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;

public class DsaEnforcer {

private static final String DSA_EXT = "dsa";
private static final Set<Integer> DSA_REQUIRED = Set.of(2, 3);
private static final Set<Integer> DSA_REQUIRED = Set.of(
DsaRequired.REQUIRED.getValue(),
DsaRequired.REQUIRED_ONLINE_PLATFORM.getValue());
private static final int MAX_DSA_FIELD_LENGTH = 100;

private final JacksonMapper mapper;

public DsaEnforcer(JacksonMapper mapper) {
this.mapper = Objects.requireNonNull(mapper);
}

public AuctionParticipation enforce(BidRequest bidRequest,
AuctionParticipation auctionParticipation,
Expand All @@ -34,7 +50,7 @@ public AuctionParticipation enforce(BidRequest bidRequest,
final BidderSeatBid seatBid = ObjectUtil.getIfNotNull(bidderResponse, BidderResponse::getSeatBid);
final List<BidderBid> bidderBids = ObjectUtil.getIfNotNull(seatBid, BidderSeatBid::getBids);

if (CollectionUtils.isEmpty(bidderBids) || !isDsaValidationRequired(bidRequest)) {
if (CollectionUtils.isEmpty(bidderBids)) {
return auctionParticipation;
}

Expand All @@ -44,9 +60,19 @@ public AuctionParticipation enforce(BidRequest bidRequest,
for (BidderBid bidderBid : bidderBids) {
final Bid bid = bidderBid.getBid();

if (!isValid(bid)) {
warnings.add(BidderError.invalidBid("Bid \"%s\" missing DSA".formatted(bid.getId())));
rejectionTracker.reject(bid.getImpid(), BidRejectionReason.GENERAL);
final ExtBidDsa dsaResponse = Optional.ofNullable(bid.getExt())
.map(ext -> ext.get(DSA_EXT))
.map(this::getDsaResponse)
.orElse(null);

try {
validateFieldLength(dsaResponse);
if (isDsaValidationRequired(bidRequest)) {
validateDsa(bidRequest, dsaResponse);
}
} catch (PreBidException e) {
warnings.add(BidderError.invalidBid("Bid \"%s\": %s".formatted(bid.getId(), e.getMessage())));
rejectionTracker.reject(bid.getImpid(), BidRejectionReason.REJECTED_BY_DSA_PRIVACY);
updatedBidderBids.remove(bidderBid);
}
}
Expand All @@ -71,9 +97,52 @@ private static boolean isDsaValidationRequired(BidRequest bidRequest) {
.orElse(false);
}

private boolean isValid(Bid bid) {
final ObjectNode bidExt = bid.getExt();
return bidExt != null && bidExt.hasNonNull(DSA_EXT) && !bidExt.get(DSA_EXT).isEmpty();
private static void validateDsa(BidRequest bidRequest, ExtBidDsa dsaResponse) {
if (dsaResponse == null) {
throw new PreBidException("DSA object missing when required");
}

final Integer adRender = dsaResponse.getAdRender();
final Integer pubRender = bidRequest.getRegs().getExt().getDsa().getPubRender();

if (pubRender == null) {
return;
}

if (pubRender == DsaPublisherRender.WILL_RENDER.getValue()
&& adRender != null && adRender == DsaAdvertiserRender.WILL_RENDER.getValue()) {
throw new PreBidException("DSA publisher and buyer both signal will render");
}

if (pubRender == DsaPublisherRender.NOT_RENDER.getValue()
&& (adRender == null || adRender == DsaAdvertiserRender.NOT_RENDER.getValue())) {
throw new PreBidException("DSA publisher and buyer both signal will not render");
}
}

private static void validateFieldLength(ExtBidDsa dsaResponse) {
if (dsaResponse == null) {
return;
}

if (!hasValidLength(dsaResponse.getBehalf())) {
throw new PreBidException("DSA behalf exceeds limit of 100 chars");
}
if (!hasValidLength(dsaResponse.getPaid())) {
throw new PreBidException("DSA paid exceeds limit of 100 chars");
}
}

private static boolean hasValidLength(String value) {
return value == null || value.length() <= MAX_DSA_FIELD_LENGTH;
}

private ExtBidDsa getDsaResponse(JsonNode dsaExt) {
try {
return mapper.mapper().convertValue(dsaExt, ExtBidDsa.class);
} catch (IllegalArgumentException e) {
return null;
}
}

}
Loading

0 comments on commit 3fada4f

Please sign in to comment.