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
449 changes: 310 additions & 139 deletions docs/config-app.md

Large diffs are not rendered by default.

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

<!-- Project production dependency versions -->
<spring.boot.version>3.5.10</spring.boot.version>
<vertx.version>4.5.20</vertx.version>
<vertx.version>5.0.10</vertx.version>
<validation-api.version>2.0.1.Final</validation-api.version>
<commons.collections.version>4.4</commons.collections.version>
<commons.compress.version>1.27.1</commons.compress.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
*/
public class AuctionRequestFactory {

private final long maxRequestSize;
private final Ortb2RequestFactory ortb2RequestFactory;
private final StoredRequestProcessor storedRequestProcessor;
private final ProfilesProcessor profilesProcessor;
Expand All @@ -57,8 +56,7 @@ public class AuctionRequestFactory {

private static final String ENDPOINT = Endpoint.openrtb2_auction.value();

public AuctionRequestFactory(long maxRequestSize,
Ortb2RequestFactory ortb2RequestFactory,
public AuctionRequestFactory(Ortb2RequestFactory ortb2RequestFactory,
StoredRequestProcessor storedRequestProcessor,
ProfilesProcessor profilesProcessor,
BidRequestOrtbVersionConversionManager ortbVersionConversionManager,
Expand All @@ -74,7 +72,6 @@ public AuctionRequestFactory(long maxRequestSize,
GeoLocationServiceWrapper geoLocationServiceWrapper,
BidAdjustmentsEnricher bidAdjustmentsEnricher) {

this.maxRequestSize = maxRequestSize;
this.ortb2RequestFactory = Objects.requireNonNull(ortb2RequestFactory);
this.storedRequestProcessor = Objects.requireNonNull(storedRequestProcessor);
this.profilesProcessor = Objects.requireNonNull(profilesProcessor);
Expand Down Expand Up @@ -166,10 +163,6 @@ private String extractAndValidateBody(RoutingContext routingContext) {
throw new InvalidRequestException("Incoming request has no body");
}

if (body.length() > maxRequestSize) {
throw new InvalidRequestException("Request size exceeded max size of %d bytes.".formatted(maxRequestSize));
}

return body;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ public class VideoRequestFactory {
private static final int DEFAULT_CACHE_LOG_TTL = 3600;
private static final String ENDPOINT = Endpoint.openrtb2_video.value();

private final int maxRequestSize;
private final boolean enforceStoredRequest;
private final Pattern escapeLogCacheRegexPattern;

Expand All @@ -63,8 +62,7 @@ public class VideoRequestFactory {
private final JacksonMapper mapper;
private final GeoLocationServiceWrapper geoLocationServiceWrapper;

public VideoRequestFactory(int maxRequestSize,
boolean enforceStoredRequest,
public VideoRequestFactory(boolean enforceStoredRequest,
String escapeLogCacheRegex,
Ortb2RequestFactory ortb2RequestFactory,
VideoStoredRequestProcessor storedRequestProcessor,
Expand All @@ -76,7 +74,6 @@ public VideoRequestFactory(int maxRequestSize,
GeoLocationServiceWrapper geoLocationServiceWrapper) {

this.enforceStoredRequest = enforceStoredRequest;
this.maxRequestSize = maxRequestSize;
this.ortb2RequestFactory = Objects.requireNonNull(ortb2RequestFactory);
this.storedRequestProcessor = Objects.requireNonNull(storedRequestProcessor);
this.ortbVersionConversionManager = Objects.requireNonNull(ortbVersionConversionManager);
Expand Down Expand Up @@ -120,9 +117,9 @@ public Future<WithPodErrors<AuctionContext>> fromRequest(RoutingContext routingC
.map(auctionContext -> auctionContext.with(debugResolver.debugContextFrom(auctionContext)))

.compose(auctionContext -> ortb2RequestFactory.limitImpressions(
auctionContext.getAccount(),
auctionContext.getBidRequest(),
auctionContext.getDebugWarnings())
auctionContext.getAccount(),
auctionContext.getBidRequest(),
auctionContext.getDebugWarnings())
.map(auctionContext::with))

.compose(auctionContext -> ortb2RequestFactory.validateRequest(
Expand Down Expand Up @@ -177,10 +174,6 @@ private String extractAndValidateBody(RoutingContext routingContext) {
throw new InvalidRequestException("Incoming request has no body");
}

if (body.length() > maxRequestSize) {
throw new InvalidRequestException("Request size exceeded max size of %d bytes.".formatted(maxRequestSize));
}

return body;
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/prebid/server/floors/PriceFloorFetcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import io.vertx.core.Future;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpHeaders;
import io.vertx.core.impl.ConcurrentHashSet;
import lombok.Value;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.ObjectUtils;
Expand Down Expand Up @@ -37,6 +36,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.regex.Matcher;
Expand Down Expand Up @@ -79,7 +79,7 @@ public PriceFloorFetcher(ApplicationSettings applicationSettings,
this.debugProperties = debugProperties;
this.mapper = Objects.requireNonNull(mapper);

fetchInProgress = new ConcurrentHashSet<>();
fetchInProgress = ConcurrentHashMap.newKeySet();
fetchedData = Caffeine.newBuilder()
.maximumSize(MAXIMUM_CACHE_SIZE)
.<String, AccountFetchContext>build()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
package org.prebid.server.geolocation;

import io.vertx.circuitbreaker.CircuitBreaker;
import io.vertx.circuitbreaker.CircuitBreakerOptions;
import io.vertx.circuitbreaker.CircuitBreakerState;
import io.vertx.core.Future;
import io.vertx.core.Vertx;
import org.prebid.server.execution.timeout.Timeout;
import org.prebid.server.geolocation.model.GeoInfo;
import org.prebid.server.log.ConditionalLogger;
import org.prebid.server.log.Logger;
import org.prebid.server.log.LoggerFactory;
import org.prebid.server.metric.Metrics;
import org.prebid.server.vertx.CircuitBreaker;

import java.time.Clock;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
* Wrapper for geolocation service with circuit breaker.
*/
public class CircuitBreakerSecuredGeoLocationService implements GeoLocationService {

private static final Logger logger = LoggerFactory.getLogger(CircuitBreakerSecuredGeoLocationService.class);
private static final ConditionalLogger conditionalLogger = new ConditionalLogger(logger);
private static final int LOG_PERIOD_SECONDS = 5;

private final GeoLocationService geoLocationService;
private final CircuitBreaker breaker;
Expand All @@ -31,39 +28,26 @@ public CircuitBreakerSecuredGeoLocationService(Vertx vertx,
Metrics metrics,
int openingThreshold,
long openingIntervalMs,
long closingIntervalMs,
Clock clock) {
long closingIntervalMs) {

this.geoLocationService = Objects.requireNonNull(geoLocationService);

breaker = new CircuitBreaker("geo_cb", Objects.requireNonNull(vertx),
openingThreshold, openingIntervalMs, closingIntervalMs, Objects.requireNonNull(clock))
.openHandler(ignored -> circuitOpened())
.halfOpenHandler(ignored -> circuitHalfOpened())
.closeHandler(ignored -> circuitClosed());
breaker = CircuitBreaker.create(
"geo_cb",
Objects.requireNonNull(vertx),
new CircuitBreakerOptions()
.setNotificationPeriod(0)
.setMaxFailures(openingThreshold)
.setFailuresRollingWindow(openingIntervalMs)
.setResetTimeout(closingIntervalMs));

metrics.createGeoLocationCircuitBreakerGauge(breaker::isOpen);
metrics.createGeoLocationCircuitBreakerGauge(() -> breaker.state() != CircuitBreakerState.CLOSED);

logger.info("Initialized GeoLocation service with Circuit Breaker");
}

@Override
public Future<GeoInfo> lookup(String ip, Timeout timeout) {
return breaker.execute(promise -> geoLocationService.lookup(ip, timeout).onComplete(promise));
}

private void circuitOpened() {
conditionalLogger.warn(
"GeoLocation service is unavailable, circuit opened.",
LOG_PERIOD_SECONDS,
TimeUnit.SECONDS);
}

private void circuitHalfOpened() {
logger.warn("GeoLocation service is ready to try again, circuit half-opened.");
}

private void circuitClosed() {
logger.warn("GeoLocation service becomes working, circuit closed.");
return breaker.execute(() -> geoLocationService.lookup(ip, timeout));
}
}
7 changes: 1 addition & 6 deletions src/main/java/org/prebid/server/handler/SetuidHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import io.vertx.core.AsyncResult;
import io.vertx.core.CompositeFuture;
import io.vertx.core.Future;
import io.vertx.core.http.Cookie;
import io.vertx.core.http.HttpHeaders;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.http.HttpServerRequest;
Expand Down Expand Up @@ -333,7 +332,7 @@ private void respondWithCookie(SetuidContext setuidContext) {
setuidContext.getUidsCookie(), bidder, uid);

uidsCookieService.splitUidsIntoCookies(uidsCookieUpdateResult.getValue())
.forEach(cookie -> addCookie(routingContext, cookie));
.forEach(routingContext.response()::addCookie);

if (uidsCookieUpdateResult.isUpdated()) {
metrics.updateUserSyncSetsMetric(bidder);
Expand Down Expand Up @@ -412,8 +411,4 @@ private void handleErrors(Throwable error, RoutingContext routingContext, TcfCon
analyticsDelegator.processEvent(setuidEvent, tcfContext);
}
}

private void addCookie(RoutingContext routingContext, Cookie cookie) {
routingContext.response().headers().add(HttpUtil.SET_COOKIE_HEADER, cookie.encode());
}
}
5 changes: 3 additions & 2 deletions src/main/java/org/prebid/server/json/JacksonMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.buffer.ByteBufInputStream;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.internal.buffer.BufferInternal;
import org.prebid.server.proto.openrtb.ext.FlexibleExtension;

import java.io.IOException;
Expand Down Expand Up @@ -66,15 +67,15 @@ public <T> T decodeValue(String str, TypeReference<T> type) throws DecodeExcepti

public <T> T decodeValue(Buffer buf, Class<T> clazz) throws DecodeException {
try {
return mapper.readValue((InputStream) new ByteBufInputStream(buf.getByteBuf()), clazz);
return mapper.readValue((InputStream) new ByteBufInputStream(((BufferInternal) buf).getByteBuf()), clazz);
} catch (IOException e) {
throw new DecodeException(FAILED_TO_DECODE.formatted(e.getMessage()), e);
}
}

public <T> T decodeValue(Buffer buf, TypeReference<T> type) throws DecodeException {
try {
return mapper.readValue(new ByteBufInputStream(buf.getByteBuf()), type);
return mapper.readValue(new ByteBufInputStream(((BufferInternal) buf).getByteBuf()), type);
} catch (IOException e) {
throw new DecodeException(FAILED_TO_DECODE.formatted(e.getMessage()), e);
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/prebid/server/log/CriteriaLogManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@

import com.iab.openrtb.request.BidRequest;
import com.iab.openrtb.response.BidResponse;
import io.vertx.core.impl.ConcurrentHashSet;
import org.prebid.server.json.EncodeException;
import org.prebid.server.json.JacksonMapper;

import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class CriteriaLogManager {

private static final Logger logger = LoggerFactory.getLogger(CriteriaLogManager.class);

private final Set<Criteria> criterias = new ConcurrentHashSet<>();
private final Set<Criteria> criterias = ConcurrentHashMap.newKeySet();

private final JacksonMapper mapper;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.github.benmanes.caffeine.cache.Caffeine;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.file.FileProps;
Expand Down Expand Up @@ -317,23 +316,15 @@ private VendorListResult<VendorList> processResponse(HttpClientResponse response
* Saves given vendor list on file system.
*/
private Future<VendorListResult<VendorList>> saveToFile(VendorListResult<VendorList> vendorListResult) {
final Promise<VendorListResult<VendorList>> promise = Promise.promise();
final int version = vendorListResult.getVersion();
final String filepath = new File(cacheDir, version + JSON_SUFFIX).getPath();

fileSystem.writeFile(filepath, Buffer.buffer(vendorListResult.getVendorListAsString()), result -> {
if (result.succeeded()) {
promise.complete(vendorListResult);
} else {
conditionalLogger.error(
return fileSystem.writeFile(filepath, Buffer.buffer(vendorListResult.getVendorListAsString()))
.map(vendorListResult)
.onFailure(error -> conditionalLogger.error(
"Could not create new vendor list for version %s.%s, file: %s, trace: %s".formatted(
generationVersion, version, filepath, ExceptionUtils.getStackTrace(result.cause())),
logSamplingRate);
promise.fail(result.cause());
}
});

return promise.future();
generationVersion, version, filepath, ExceptionUtils.getStackTrace(error.getCause())),
logSamplingRate));
}

private Void updateCache(VendorListResult<VendorList> vendorListResult) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.time.Clock;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -70,13 +69,15 @@ CircuitBreakerSecuredGeoLocationService circuitBreakerSecuredGeoLocationService(
Vertx vertx,
Metrics metrics,
FileSyncerProperties fileSyncerProperties,
@Qualifier("maxMindCircuitBreakerProperties") CircuitBreakerProperties circuitBreakerProperties,
Clock clock) {

return new CircuitBreakerSecuredGeoLocationService(vertx,
createGeoLocationService(fileSyncerProperties, vertx), metrics,
circuitBreakerProperties.getOpeningThreshold(), circuitBreakerProperties.getOpeningIntervalMs(),
circuitBreakerProperties.getClosingIntervalMs(), clock);
@Qualifier("maxMindCircuitBreakerProperties") CircuitBreakerProperties circuitBreakerProperties) {

return new CircuitBreakerSecuredGeoLocationService(
vertx,
createGeoLocationService(fileSyncerProperties, vertx),
metrics,
circuitBreakerProperties.getOpeningThreshold(),
circuitBreakerProperties.getOpeningIntervalMs(),
circuitBreakerProperties.getClosingIntervalMs());
}

private GeoLocationService createGeoLocationService(FileSyncerProperties properties, Vertx vertx) {
Expand Down
Loading