Skip to content

Commit

Permalink
Core: Geo Lookup update for IP in header (prebid#3081)
Browse files Browse the repository at this point in the history
  • Loading branch information
osulzhenko authored Mar 27, 2024
1 parent 1928473 commit 2949607
Show file tree
Hide file tree
Showing 5 changed files with 372 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.prebid.server.auction;

import com.iab.openrtb.request.BidRequest;
import com.iab.openrtb.request.Device;
import com.iab.openrtb.request.Geo;
import io.vertx.core.Future;
Expand All @@ -9,10 +8,13 @@
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.prebid.server.auction.model.AuctionContext;
import org.prebid.server.auction.model.IpAddress;
import org.prebid.server.auction.requestfactory.Ortb2ImplicitParametersResolver;
import org.prebid.server.execution.Timeout;
import org.prebid.server.geolocation.GeoLocationService;
import org.prebid.server.geolocation.model.GeoInfo;
import org.prebid.server.metric.Metrics;
import org.prebid.server.model.HttpRequestContext;
import org.prebid.server.settings.model.Account;
import org.prebid.server.settings.model.AccountSettings;

Expand All @@ -24,33 +26,37 @@ public class GeoLocationServiceWrapper {
private static final Logger logger = LoggerFactory.getLogger(GeoLocationServiceWrapper.class);

private final GeoLocationService geoLocationService;
private final Ortb2ImplicitParametersResolver implicitParametersResolver;
private final Metrics metrics;

public GeoLocationServiceWrapper(GeoLocationService geoLocationService, Metrics metrics) {
public GeoLocationServiceWrapper(GeoLocationService geoLocationService,
Ortb2ImplicitParametersResolver implicitParametersResolver,
Metrics metrics) {

this.geoLocationService = geoLocationService;
this.implicitParametersResolver = Objects.requireNonNull(implicitParametersResolver);
this.metrics = Objects.requireNonNull(metrics);
}

//todo: account settings will work as expected if the default account resolving refactoring is done
public Future<GeoInfo> lookup(AuctionContext auctionContext) {
final Account account = auctionContext.getAccount();
final BidRequest bidRequest = auctionContext.getBidRequest();
final Device device = auctionContext.getBidRequest().getDevice();
final HttpRequestContext requestContext = auctionContext.getHttpRequest();
final Timeout timeout = auctionContext.getTimeoutContext().getTimeout();

final boolean isGeoLookupEnabled = Optional.ofNullable(account.getSettings())
.map(AccountSettings::getGeoLookup)
.map(BooleanUtils::isTrue)
.orElse(false);

final Device device = bidRequest.getDevice();

return isGeoLookupEnabled
? doLookup(getIpAddress(device), getCountry(device), timeout).otherwiseEmpty()
? doLookup(getIpAddress(device, requestContext), getCountry(device), timeout).otherwiseEmpty()
: Future.succeededFuture();
}

public Future<GeoInfo> doLookup(String ipAddress, String requestCountry, Timeout timeout) {
if (geoLocationService == null || StringUtils.isNotBlank(requestCountry) || ipAddress == null) {
if (geoLocationService == null || ipAddress == null || StringUtils.isNotBlank(requestCountry)) {
return Future.failedFuture("Geolocation lookup is skipped");
}
return geoLocationService.lookup(ipAddress, timeout)
Expand All @@ -66,16 +72,23 @@ private String getCountry(Device device) {
.orElse(null);
}

private String getIpAddress(Device device) {
private String getIpAddress(Device device, HttpRequestContext request) {
final Optional<Device> optionalDevice = Optional.ofNullable(device);
return optionalDevice.map(Device::getIp)
.filter(StringUtils::isNotBlank)
.or(() -> optionalDevice
.map(Device::getIpv6)
.filter(StringUtils::isNotBlank))
.or(() -> ipFromHeader(request))
.orElse(null);
}

private Optional<String> ipFromHeader(HttpRequestContext request) {
final IpAddress headerIp = implicitParametersResolver.findIpFromRequest(request);
return Optional.ofNullable(headerIp)
.map(IpAddress::getIp);
}

private void logError(Throwable error) {
final String message = "Geolocation lookup failed: " + error.getMessage();
logger.warn(message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ private String sanitizeIp(String ip, IpAddress.IP version) {
return ipAddress != null && ipAddress.getVersion() == version ? ipAddress.getIp() : null;
}

private IpAddress findIpFromRequest(HttpRequestContext request) {
public IpAddress findIpFromRequest(HttpRequestContext request) {
final CaseInsensitiveMultiMap headers = request.getHeaders();
final String remoteHost = request.getRemoteHost();
final List<String> requestIps = paramsExtractor.ipFrom(headers, remoteHost);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.prebid.server.auction.GeoLocationServiceWrapper;
import org.prebid.server.auction.requestfactory.Ortb2ImplicitParametersResolver;
import org.prebid.server.execution.RemoteFileSyncer;
import org.prebid.server.execution.retry.FixedIntervalRetryPolicy;
import org.prebid.server.geolocation.CircuitBreakerSecuredGeoLocationService;
Expand Down Expand Up @@ -201,9 +202,13 @@ private String readCsv(Resource resource) throws IOException {
@Bean
GeoLocationServiceWrapper geoLocationServiceWrapper(
@Autowired(required = false) GeoLocationService geoLocationService,
Ortb2ImplicitParametersResolver implicitParametersResolver,
Metrics metrics) {

return new GeoLocationServiceWrapper(geoLocationService, metrics);
return new GeoLocationServiceWrapper(
geoLocationService,
implicitParametersResolver,
metrics);
}

}
Loading

0 comments on commit 2949607

Please sign in to comment.