Skip to content

Commit a110d71

Browse files
authored
ingest-geoip: establish boundaries (#109655)
1 parent 6535bda commit a110d71

File tree

15 files changed

+840
-835
lines changed

15 files changed

+840
-835
lines changed

modules/ingest-geoip/src/internalClusterTest/java/org/elasticsearch/ingest/geoip/DatabaseNodeServiceIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ private void assertValidDatabase(DatabaseNodeService databaseNodeService, String
8484
IpDatabase database = databaseNodeService.getDatabase(databaseFileName);
8585
assertNotNull(database);
8686
assertThat(database.getDatabaseType(), equalTo(databaseType));
87-
CountryResponse countryResponse = database.getCountry("89.160.20.128");
87+
CountryResponse countryResponse = database.getResponse("89.160.20.128", GeoIpTestUtils::getCountry);
8888
assertNotNull(countryResponse);
8989
Country country = countryResponse.getCountry();
9090
assertNotNull(country);

modules/ingest-geoip/src/internalClusterTest/java/org/elasticsearch/ingest/geoip/ReloadingDatabasesWhilePerformingGeoLookupsIT.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,10 @@ private static DatabaseNodeService createRegistry(Path geoIpConfigDir, Path geoI
205205
private static void lazyLoadReaders(DatabaseNodeService databaseNodeService) throws IOException {
206206
if (databaseNodeService.get("GeoLite2-City.mmdb") != null) {
207207
databaseNodeService.get("GeoLite2-City.mmdb").getDatabaseType();
208-
databaseNodeService.get("GeoLite2-City.mmdb").getCity("2.125.160.216");
208+
databaseNodeService.get("GeoLite2-City.mmdb").getResponse("2.125.160.216", GeoIpTestUtils::getCity);
209209
}
210210
databaseNodeService.get("GeoLite2-City-Test.mmdb").getDatabaseType();
211-
databaseNodeService.get("GeoLite2-City-Test.mmdb").getCity("2.125.160.216");
211+
databaseNodeService.get("GeoLite2-City-Test.mmdb").getResponse("2.125.160.216", GeoIpTestUtils::getCity);
212212
}
213213

214214
}

modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/Database.java

Lines changed: 1 addition & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
package org.elasticsearch.ingest.geoip;
1111

12-
import org.elasticsearch.common.Strings;
1312
import org.elasticsearch.core.Nullable;
1413

1514
import java.util.Arrays;
@@ -19,12 +18,10 @@
1918
import java.util.Set;
2019

2120
/**
22-
* A high-level representation of a kind of geoip database that is supported by the {@link GeoIpProcessor}.
21+
* A high-level representation of a kind of ip location database that is supported by the {@link GeoIpProcessor}.
2322
* <p>
2423
* A database has a set of properties that are valid to use with it (see {@link Database#properties()}),
2524
* as well as a list of default properties to use if no properties are specified (see {@link Database#defaultProperties()}).
26-
* <p>
27-
* See especially {@link Database#getDatabase(String, String)} which is used to obtain instances of this class.
2825
*/
2926
enum Database {
3027

@@ -142,61 +139,6 @@ enum Database {
142139
)
143140
);
144141

145-
private static final String CITY_DB_SUFFIX = "-City";
146-
private static final String COUNTRY_DB_SUFFIX = "-Country";
147-
private static final String ASN_DB_SUFFIX = "-ASN";
148-
private static final String ANONYMOUS_IP_DB_SUFFIX = "-Anonymous-IP";
149-
private static final String CONNECTION_TYPE_DB_SUFFIX = "-Connection-Type";
150-
private static final String DOMAIN_DB_SUFFIX = "-Domain";
151-
private static final String ENTERPRISE_DB_SUFFIX = "-Enterprise";
152-
private static final String ISP_DB_SUFFIX = "-ISP";
153-
154-
@Nullable
155-
private static Database getMaxmindDatabase(final String databaseType) {
156-
if (databaseType.endsWith(Database.CITY_DB_SUFFIX)) {
157-
return Database.City;
158-
} else if (databaseType.endsWith(Database.COUNTRY_DB_SUFFIX)) {
159-
return Database.Country;
160-
} else if (databaseType.endsWith(Database.ASN_DB_SUFFIX)) {
161-
return Database.Asn;
162-
} else if (databaseType.endsWith(Database.ANONYMOUS_IP_DB_SUFFIX)) {
163-
return Database.AnonymousIp;
164-
} else if (databaseType.endsWith(Database.CONNECTION_TYPE_DB_SUFFIX)) {
165-
return Database.ConnectionType;
166-
} else if (databaseType.endsWith(Database.DOMAIN_DB_SUFFIX)) {
167-
return Database.Domain;
168-
} else if (databaseType.endsWith(Database.ENTERPRISE_DB_SUFFIX)) {
169-
return Database.Enterprise;
170-
} else if (databaseType.endsWith(Database.ISP_DB_SUFFIX)) {
171-
return Database.Isp;
172-
} else {
173-
return null; // no match was found
174-
}
175-
}
176-
177-
/**
178-
* Parses the passed-in databaseType (presumably from the passed-in databaseFile) and return the Database instance that is
179-
* associated with that databaseType.
180-
*
181-
* @param databaseType the database type String from the metadata of the database file
182-
* @param databaseFile the database file from which the database type was obtained
183-
* @throws IllegalArgumentException if the databaseType is not associated with a Database instance
184-
* @return the Database instance that is associated with the databaseType
185-
*/
186-
public static Database getDatabase(final String databaseType, final String databaseFile) {
187-
Database database = null;
188-
189-
if (Strings.hasText(databaseType)) {
190-
database = getMaxmindDatabase(databaseType);
191-
}
192-
193-
if (database == null) {
194-
throw new IllegalArgumentException("Unsupported database type [" + databaseType + "] for file [" + databaseFile + "]");
195-
}
196-
197-
return database;
198-
}
199-
200142
private final Set<Property> properties;
201143
private final Set<Property> defaultProperties;
202144

modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/DatabaseReaderLazyLoader.java

Lines changed: 4 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -9,47 +9,32 @@
99

1010
package org.elasticsearch.ingest.geoip;
1111

12-
import com.maxmind.db.DatabaseRecord;
13-
import com.maxmind.db.Network;
1412
import com.maxmind.db.NoCache;
1513
import com.maxmind.db.Reader;
16-
import com.maxmind.geoip2.model.AnonymousIpResponse;
17-
import com.maxmind.geoip2.model.AsnResponse;
18-
import com.maxmind.geoip2.model.CityResponse;
19-
import com.maxmind.geoip2.model.ConnectionTypeResponse;
20-
import com.maxmind.geoip2.model.CountryResponse;
21-
import com.maxmind.geoip2.model.DomainResponse;
22-
import com.maxmind.geoip2.model.EnterpriseResponse;
23-
import com.maxmind.geoip2.model.IspResponse;
2414

2515
import org.apache.logging.log4j.LogManager;
2616
import org.apache.logging.log4j.Logger;
2717
import org.apache.lucene.util.SetOnce;
2818
import org.elasticsearch.ExceptionsHelper;
2919
import org.elasticsearch.common.CheckedBiFunction;
3020
import org.elasticsearch.common.CheckedSupplier;
31-
import org.elasticsearch.common.network.InetAddresses;
32-
import org.elasticsearch.common.network.NetworkAddress;
3321
import org.elasticsearch.core.Booleans;
3422
import org.elasticsearch.core.IOUtils;
3523
import org.elasticsearch.core.Nullable;
3624
import org.elasticsearch.core.SuppressForbidden;
3725

3826
import java.io.File;
3927
import java.io.IOException;
40-
import java.net.InetAddress;
4128
import java.nio.file.Files;
4229
import java.nio.file.Path;
43-
import java.util.List;
4430
import java.util.Objects;
45-
import java.util.Optional;
4631
import java.util.concurrent.atomic.AtomicInteger;
4732

4833
/**
4934
* Facilitates lazy loading of the database reader, so that when the geoip plugin is installed, but not used,
5035
* no memory is being wasted on the database reader.
5136
*/
52-
class DatabaseReaderLazyLoader implements IpDatabase {
37+
public class DatabaseReaderLazyLoader implements IpDatabase {
5338

5439
private static final boolean LOAD_DATABASE_ON_HEAP = Booleans.parseBoolean(System.getProperty("es.geoip.load_db_on_heap", "false"));
5540

@@ -96,94 +81,6 @@ public final String getDatabaseType() throws IOException {
9681
return databaseType.get();
9782
}
9883

99-
@Nullable
100-
@Override
101-
public CityResponse getCity(String ipAddress) {
102-
return getResponse(ipAddress, (reader, ip) -> lookup(reader, ip, CityResponse.class, CityResponse::new));
103-
}
104-
105-
@Nullable
106-
@Override
107-
public CountryResponse getCountry(String ipAddress) {
108-
return getResponse(ipAddress, (reader, ip) -> lookup(reader, ip, CountryResponse.class, CountryResponse::new));
109-
}
110-
111-
@Nullable
112-
@Override
113-
public AsnResponse getAsn(String ipAddress) {
114-
return getResponse(
115-
ipAddress,
116-
(reader, ip) -> lookup(
117-
reader,
118-
ip,
119-
AsnResponse.class,
120-
(response, responseIp, network, locales) -> new AsnResponse(response, responseIp, network)
121-
)
122-
);
123-
}
124-
125-
@Nullable
126-
@Override
127-
public AnonymousIpResponse getAnonymousIp(String ipAddress) {
128-
return getResponse(
129-
ipAddress,
130-
(reader, ip) -> lookup(
131-
reader,
132-
ip,
133-
AnonymousIpResponse.class,
134-
(response, responseIp, network, locales) -> new AnonymousIpResponse(response, responseIp, network)
135-
)
136-
);
137-
}
138-
139-
@Nullable
140-
@Override
141-
public ConnectionTypeResponse getConnectionType(String ipAddress) {
142-
return getResponse(
143-
ipAddress,
144-
(reader, ip) -> lookup(
145-
reader,
146-
ip,
147-
ConnectionTypeResponse.class,
148-
(response, responseIp, network, locales) -> new ConnectionTypeResponse(response, responseIp, network)
149-
)
150-
);
151-
}
152-
153-
@Nullable
154-
@Override
155-
public DomainResponse getDomain(String ipAddress) {
156-
return getResponse(
157-
ipAddress,
158-
(reader, ip) -> lookup(
159-
reader,
160-
ip,
161-
DomainResponse.class,
162-
(response, responseIp, network, locales) -> new DomainResponse(response, responseIp, network)
163-
)
164-
);
165-
}
166-
167-
@Nullable
168-
@Override
169-
public EnterpriseResponse getEnterprise(String ipAddress) {
170-
return getResponse(ipAddress, (reader, ip) -> lookup(reader, ip, EnterpriseResponse.class, EnterpriseResponse::new));
171-
}
172-
173-
@Nullable
174-
@Override
175-
public IspResponse getIsp(String ipAddress) {
176-
return getResponse(
177-
ipAddress,
178-
(reader, ip) -> lookup(
179-
reader,
180-
ip,
181-
IspResponse.class,
182-
(response, responseIp, network, locales) -> new IspResponse(response, responseIp, network)
183-
)
184-
);
185-
}
186-
18784
boolean preLookup() {
18885
return currentUsages.updateAndGet(current -> current < 0 ? current : current + 1) > 0;
18986
}
@@ -199,14 +96,12 @@ int current() {
19996
return currentUsages.get();
20097
}
20198

99+
@Override
202100
@Nullable
203-
private <RESPONSE> RESPONSE getResponse(
204-
String ipAddress,
205-
CheckedBiFunction<Reader, String, Optional<RESPONSE>, Exception> responseProvider
206-
) {
101+
public <RESPONSE> RESPONSE getResponse(String ipAddress, CheckedBiFunction<Reader, String, RESPONSE, Exception> responseProvider) {
207102
return cache.putIfAbsent(ipAddress, databasePath.toString(), ip -> {
208103
try {
209-
return responseProvider.apply(get(), ipAddress).orElse(null);
104+
return responseProvider.apply(get(), ipAddress);
210105
} catch (Exception e) {
211106
throw ExceptionsHelper.convertToRuntime(e);
212107
}
@@ -263,23 +158,6 @@ private static File pathToFile(Path databasePath) {
263158
return databasePath.toFile();
264159
}
265160

266-
@FunctionalInterface
267-
private interface ResponseBuilder<RESPONSE> {
268-
RESPONSE build(RESPONSE response, String responseIp, Network network, List<String> locales);
269-
}
270-
271-
private <RESPONSE> Optional<RESPONSE> lookup(Reader reader, String ip, Class<RESPONSE> clazz, ResponseBuilder<RESPONSE> builder)
272-
throws IOException {
273-
InetAddress inetAddress = InetAddresses.forString(ip);
274-
DatabaseRecord<RESPONSE> record = reader.getRecord(inetAddress, clazz);
275-
RESPONSE result = record.getData();
276-
if (result == null) {
277-
return Optional.empty();
278-
} else {
279-
return Optional.of(builder.build(result, NetworkAddress.format(inetAddress), record.getNetwork(), List.of("en")));
280-
}
281-
}
282-
283161
long getBuildDateMillis() throws IOException {
284162
if (buildDate.get() == null) {
285163
synchronized (buildDate) {

modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/GeoIpCache.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
* cost of deserialization for each lookup (cached or not). This comes at slight expense of higher memory usage, but significant
2727
* reduction of CPU usage.
2828
*/
29-
final class GeoIpCache {
29+
public final class GeoIpCache {
3030

3131
/**
3232
* Internal-only sentinel object for recording that a result from the geoip database was null (i.e. there was no result). By caching

0 commit comments

Comments
 (0)