Skip to content

Commit 77df115

Browse files
committed
Merge branch 'refs/heads/master' into feature/paa
# Conflicts: # src/test/groovy/org/prebid/server/functional/tests/BidderParamsSpec.groovy
2 parents 7ea648e + 7861a1e commit 77df115

File tree

62 files changed

+985
-680
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+985
-680
lines changed

extra/bundle/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>org.prebid</groupId>
77
<artifactId>prebid-server-aggregator</artifactId>
8-
<version>3.18.0-SNAPSHOT</version>
8+
<version>3.19.0-SNAPSHOT</version>
99
<relativePath>../../extra/pom.xml</relativePath>
1010
</parent>
1111

extra/modules/confiant-ad-quality/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>org.prebid.server.hooks.modules</groupId>
77
<artifactId>all-modules</artifactId>
8-
<version>3.18.0-SNAPSHOT</version>
8+
<version>3.19.0-SNAPSHOT</version>
99
</parent>
1010

1111
<artifactId>confiant-ad-quality</artifactId>

extra/modules/fiftyone-devicedetection/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>org.prebid.server.hooks.modules</groupId>
77
<artifactId>all-modules</artifactId>
8-
<version>3.18.0-SNAPSHOT</version>
8+
<version>3.19.0-SNAPSHOT</version>
99
</parent>
1010

1111
<artifactId>fiftyone-devicedetection</artifactId>

extra/modules/greenbids-real-time-data/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<parent>
55
<groupId>org.prebid.server.hooks.modules</groupId>
66
<artifactId>all-modules</artifactId>
7-
<version>3.18.0-SNAPSHOT</version>
7+
<version>3.19.0-SNAPSHOT</version>
88
</parent>
99

1010
<artifactId>greenbids-real-time-data</artifactId>

extra/modules/greenbids-real-time-data/src/main/java/org/prebid/server/hooks/modules/greenbids/real/time/data/config/DatabaseReaderFactory.java

Lines changed: 95 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,128 @@
11
package org.prebid.server.hooks.modules.greenbids.real.time.data.config;
22

3+
import io.netty.handler.codec.http.HttpResponseStatus;
4+
import io.vertx.core.file.FileSystem;
5+
import io.vertx.core.http.HttpClientOptions;
6+
import io.vertx.core.http.HttpClientRequest;
7+
import io.vertx.core.http.HttpClientResponse;
8+
import com.maxmind.db.Reader;
9+
import io.vertx.core.Future;
310
import io.vertx.core.Promise;
411
import io.vertx.core.Vertx;
512
import com.maxmind.geoip2.DatabaseReader;
13+
import io.vertx.core.file.OpenOptions;
14+
import io.vertx.core.http.HttpMethod;
15+
import io.vertx.core.http.RequestOptions;
16+
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
17+
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
618
import org.prebid.server.exception.PreBidException;
19+
import org.prebid.server.log.Logger;
20+
import org.prebid.server.log.LoggerFactory;
721
import org.prebid.server.vertx.Initializable;
822

9-
import java.io.FileOutputStream;
1023
import java.io.IOException;
11-
import java.io.InputStream;
12-
import java.net.URL;
1324
import java.nio.file.Files;
1425
import java.nio.file.Path;
1526
import java.util.concurrent.atomic.AtomicReference;
27+
import java.util.zip.GZIPInputStream;
1628

1729
public class DatabaseReaderFactory implements Initializable {
1830

19-
private final String geoLiteCountryUrl;
31+
private static final Logger logger = LoggerFactory.getLogger(DatabaseReaderFactory.class);
32+
33+
private final GreenbidsRealTimeDataProperties properties;
2034

2135
private final Vertx vertx;
2236

2337
private final AtomicReference<DatabaseReader> databaseReaderRef = new AtomicReference<>();
2438

25-
public DatabaseReaderFactory(String geoLitCountryUrl, Vertx vertx) {
26-
this.geoLiteCountryUrl = geoLitCountryUrl;
39+
private final FileSystem fileSystem;
40+
41+
public DatabaseReaderFactory(GreenbidsRealTimeDataProperties properties, Vertx vertx) {
42+
this.properties = properties;
2743
this.vertx = vertx;
44+
this.fileSystem = vertx.fileSystem();
2845
}
2946

3047
@Override
3148
public void initialize(Promise<Void> initializePromise) {
49+
downloadAndExtract()
50+
.onSuccess(databaseReaderRef::set)
51+
.<Void>mapEmpty()
52+
.onComplete(initializePromise);
53+
}
54+
55+
private Future<DatabaseReader> downloadAndExtract() {
56+
final String downloadUrl = properties.getGeoLiteCountryPath();
57+
final String tmpPath = properties.getTmpPath();
58+
return downloadFile(downloadUrl, tmpPath)
59+
.compose(ignored -> vertx.executeBlocking(() -> extractMMDB(tmpPath)))
60+
.onComplete(ar -> removeFile(tmpPath));
61+
}
62+
63+
private Future<Void> downloadFile(String downloadUrl, String tmpPath) {
64+
return fileSystem.open(tmpPath, new OpenOptions())
65+
.compose(tmpFile -> sendHttpRequest(downloadUrl)
66+
.onFailure(ignore -> tmpFile.close())
67+
.compose(response -> response.pipeTo(tmpFile)));
68+
}
69+
70+
private Future<HttpClientResponse> sendHttpRequest(String url) {
71+
final RequestOptions options = new RequestOptions()
72+
.setFollowRedirects(true)
73+
.setMethod(HttpMethod.GET)
74+
.setTimeout(properties.getTimeoutMs())
75+
.setAbsoluteURI(url);
76+
77+
final HttpClientOptions httpClientOptions = new HttpClientOptions()
78+
.setConnectTimeout(properties.getTimeoutMs().intValue())
79+
.setMaxRedirects(properties.getMaxRedirects());
3280

33-
vertx.executeBlocking(() -> {
34-
try {
35-
final URL url = new URL(geoLiteCountryUrl);
36-
final Path databasePath = Files.createTempFile("GeoLite2-Country", ".mmdb");
81+
return vertx.createHttpClient(httpClientOptions).request(options)
82+
.compose(HttpClientRequest::send)
83+
.map(this::validateResponse);
84+
}
85+
86+
private HttpClientResponse validateResponse(HttpClientResponse response) {
87+
final int statusCode = response.statusCode();
88+
if (statusCode != HttpResponseStatus.OK.code()) {
89+
throw new PreBidException("Got unexpected response from server with status code %s and message %s"
90+
.formatted(statusCode, response.statusMessage()));
91+
}
92+
return response;
93+
}
3794

38-
try (InputStream inputStream = url.openStream();
39-
FileOutputStream outputStream = new FileOutputStream(databasePath.toFile())) {
40-
inputStream.transferTo(outputStream);
95+
private DatabaseReader extractMMDB(String tarGzPath) {
96+
try (GZIPInputStream gis = new GZIPInputStream(Files.newInputStream(Path.of(tarGzPath)));
97+
TarArchiveInputStream tarInput = new TarArchiveInputStream(gis)) {
98+
99+
TarArchiveEntry currentEntry;
100+
boolean hasDatabaseFile = false;
101+
while ((currentEntry = tarInput.getNextTarEntry()) != null) {
102+
if (currentEntry.getName().contains("GeoLite2-Country.mmdb")) {
103+
hasDatabaseFile = true;
104+
break;
41105
}
106+
}
107+
108+
if (!hasDatabaseFile) {
109+
throw new PreBidException("GeoLite2-Country.mmdb not found in the archive");
110+
}
111+
112+
return new DatabaseReader.Builder(tarInput)
113+
.fileMode(Reader.FileMode.MEMORY).build();
114+
} catch (IOException e) {
115+
throw new PreBidException("Failed to extract MMDB file", e);
116+
}
117+
}
42118

43-
databaseReaderRef.set(new DatabaseReader.Builder(databasePath.toFile()).build());
44-
} catch (IOException e) {
45-
throw new PreBidException("Failed to initialize DatabaseReader from URL", e);
119+
private void removeFile(String filePath) {
120+
fileSystem.exists(filePath).onSuccess(exists -> {
121+
if (exists) {
122+
fileSystem.delete(filePath)
123+
.onFailure(err -> logger.error("Failed to remove file {}", filePath, err));
46124
}
47-
return null;
48-
}).<Void>mapEmpty()
49-
.onComplete(initializePromise);
125+
});
50126
}
51127

52128
public DatabaseReader getDatabaseReader() {

extra/modules/greenbids-real-time-data/src/main/java/org/prebid/server/hooks/modules/greenbids/real/time/data/config/GreenbidsRealTimeDataConfiguration.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.google.cloud.storage.Storage;
66
import com.google.cloud.storage.StorageOptions;
77
import io.vertx.core.Vertx;
8+
import org.prebid.server.geolocation.CountryCodeMapper;
89
import org.prebid.server.hooks.modules.greenbids.real.time.data.model.filter.ThrottlingThresholds;
910
import org.prebid.server.hooks.modules.greenbids.real.time.data.core.ThrottlingThresholdsFactory;
1011
import org.prebid.server.hooks.modules.greenbids.real.time.data.core.GreenbidsInferenceDataService;
@@ -32,13 +33,15 @@ public class GreenbidsRealTimeDataConfiguration {
3233

3334
@Bean
3435
DatabaseReaderFactory databaseReaderFactory(GreenbidsRealTimeDataProperties properties, Vertx vertx) {
35-
return new DatabaseReaderFactory(properties.getGeoLiteCountryPath(), vertx);
36+
return new DatabaseReaderFactory(properties, vertx);
3637
}
3738

3839
@Bean
39-
GreenbidsInferenceDataService greenbidsInferenceDataService(DatabaseReaderFactory databaseReaderFactory) {
40+
GreenbidsInferenceDataService greenbidsInferenceDataService(DatabaseReaderFactory databaseReaderFactory,
41+
CountryCodeMapper countryCodeMapper) {
42+
4043
return new GreenbidsInferenceDataService(
41-
databaseReaderFactory, ObjectMapperProvider.mapper());
44+
databaseReaderFactory, ObjectMapperProvider.mapper(), countryCodeMapper);
4245
}
4346

4447
@Bean

extra/modules/greenbids-real-time-data/src/main/java/org/prebid/server/hooks/modules/greenbids/real/time/data/config/GreenbidsRealTimeDataProperties.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,17 @@ public class GreenbidsRealTimeDataProperties {
1111

1212
String geoLiteCountryPath;
1313

14+
String tmpPath;
15+
1416
String gcsBucketName;
1517

1618
Integer cacheExpirationMinutes;
1719

1820
String onnxModelCacheKeyPrefix;
1921

2022
String thresholdsCacheKeyPrefix;
23+
24+
Long timeoutMs;
25+
26+
Integer maxRedirects;
2127
}

extra/modules/greenbids-real-time-data/src/main/java/org/prebid/server/hooks/modules/greenbids/real/time/data/core/GreenbidsInferenceDataService.java

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
import com.fasterxml.jackson.databind.node.ObjectNode;
77
import com.iab.openrtb.request.BidRequest;
88
import com.iab.openrtb.request.Device;
9+
import com.iab.openrtb.request.Geo;
910
import com.iab.openrtb.request.Imp;
1011
import com.maxmind.geoip2.DatabaseReader;
1112
import com.maxmind.geoip2.exception.GeoIp2Exception;
1213
import com.maxmind.geoip2.model.CountryResponse;
1314
import com.maxmind.geoip2.record.Country;
1415
import org.apache.commons.lang3.StringUtils;
1516
import org.prebid.server.exception.PreBidException;
17+
import org.prebid.server.geolocation.CountryCodeMapper;
1618
import org.prebid.server.hooks.modules.greenbids.real.time.data.config.DatabaseReaderFactory;
1719
import org.prebid.server.hooks.modules.greenbids.real.time.data.model.data.ThrottlingMessage;
1820
import org.prebid.server.proto.openrtb.ext.request.ExtImpPrebid;
@@ -25,6 +27,7 @@
2527
import java.util.Collection;
2628
import java.util.Iterator;
2729
import java.util.List;
30+
import java.util.Locale;
2831
import java.util.Objects;
2932
import java.util.Optional;
3033
import java.util.stream.Collectors;
@@ -35,9 +38,14 @@ public class GreenbidsInferenceDataService {
3538

3639
private final ObjectMapper mapper;
3740

38-
public GreenbidsInferenceDataService(DatabaseReaderFactory dbReaderFactory, ObjectMapper mapper) {
41+
private final CountryCodeMapper countryCodeMapper;
42+
43+
public GreenbidsInferenceDataService(DatabaseReaderFactory dbReaderFactory,
44+
ObjectMapper mapper,
45+
CountryCodeMapper countryCodeMapper) {
3946
this.databaseReaderFactory = Objects.requireNonNull(dbReaderFactory);
4047
this.mapper = Objects.requireNonNull(mapper);
48+
this.countryCodeMapper = Objects.requireNonNull(countryCodeMapper);
4149
}
4250

4351
public List<ThrottlingMessage> extractThrottlingMessagesFromBidRequest(BidRequest bidRequest) {
@@ -86,23 +94,38 @@ private List<ThrottlingMessage> extractMessagesForImp(
8694
final String ip = Optional.ofNullable(bidRequest.getDevice())
8795
.map(Device::getIp)
8896
.orElse(null);
89-
final String countryFromIp = getCountry(ip);
97+
final String country = Optional.ofNullable(bidRequest.getDevice())
98+
.map(Device::getGeo)
99+
.map(Geo::getCountry)
100+
.map(countryCodeMapper::mapToAlpha2)
101+
.map(GreenbidsInferenceDataService::getCountryNameFromAlpha2)
102+
.filter(c -> !c.isEmpty())
103+
.orElseGet(() -> getCountry(ip));
104+
90105
return createThrottlingMessages(
91106
bidderNode,
92107
impId,
93108
greenbidsUserAgent,
94-
countryFromIp,
109+
country,
95110
hostname,
96111
hourBucket,
97112
minuteQuadrant);
98113
}
99114

100-
private String getCountry(String ip) {
101-
if (ip == null) {
102-
return null;
103-
}
115+
private static String getCountryNameFromAlpha2(String isoCode) {
116+
return StringUtils.isBlank(isoCode)
117+
? StringUtils.EMPTY
118+
: Locale.forLanguageTag("und-" + isoCode).getDisplayCountry(Locale.ENGLISH);
119+
}
104120

121+
private String getCountry(String ip) {
105122
final DatabaseReader databaseReader = databaseReaderFactory.getDatabaseReader();
123+
return ip != null && databaseReader != null
124+
? getCountryFromIpUsingDatabase(databaseReader, ip)
125+
: null;
126+
}
127+
128+
private String getCountryFromIpUsingDatabase(DatabaseReader databaseReader, String ip) {
106129
try {
107130
final InetAddress inetAddress = InetAddress.getByName(ip);
108131
final CountryResponse response = databaseReader.country(inetAddress);

0 commit comments

Comments
 (0)