geoip: don't store geoinfo if nothing can be resolved

This commit is contained in:
Martijn van Groningen 2015-11-06 18:09:55 +07:00
parent 1dfe6f6dcf
commit 302621f16b
3 changed files with 52 additions and 20 deletions

View File

@ -48,7 +48,7 @@ task copyDefaultGeoIp2DatabaseFiles(type: Copy) {
project.bundlePlugin.dependsOn(copyDefaultGeoIp2DatabaseFiles)
compileJava.options.compilerArgs << "-Xlint:-rawtypes,-unchecked"
compileJava.options.compilerArgs << "-Xlint:-rawtypes,-unchecked,-serial"
compileTestJava.options.compilerArgs << "-Xlint:-rawtypes,-unchecked"
bundlePlugin {

View File

@ -20,10 +20,12 @@
package org.elasticsearch.ingest.processor.geoip;
import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.exception.AddressNotFoundException;
import com.maxmind.geoip2.exception.GeoIp2Exception;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.model.CountryResponse;
import com.maxmind.geoip2.record.*;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.SpecialPermission;
import org.elasticsearch.common.network.NetworkAddress;
import org.elasticsearch.ingest.Data;
@ -38,6 +40,7 @@ import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@ -67,13 +70,21 @@ public final class GeoIpProcessor implements Processor {
throw new RuntimeException(e);
}
final Map<String, Object> geoData;
Map<String, Object> geoData;
switch (dbReader.getMetadata().getDatabaseType()) {
case "GeoLite2-City":
geoData = retrieveCityGeoData(ipAddress);
try {
geoData = retrieveCityGeoData(ipAddress);
} catch (AddressNotFoundRuntimeException e) {
geoData = Collections.emptyMap();
}
break;
case "GeoLite2-Country":
geoData = retrieveCountryGeoData(ipAddress);
try {
geoData = retrieveCountryGeoData(ipAddress);
} catch (AddressNotFoundRuntimeException e) {
geoData = Collections.emptyMap();
}
break;
default:
throw new IllegalStateException("Unsupported database type [" + dbReader.getMetadata().getDatabaseType() + "]");
@ -98,14 +109,13 @@ public final class GeoIpProcessor implements Processor {
if (sm != null) {
sm.checkPermission(new SpecialPermission());
}
CityResponse response = AccessController.doPrivileged(new PrivilegedAction<CityResponse>() {
@Override
public CityResponse run() {
try {
return dbReader.city(ipAddress);
} catch (IOException | GeoIp2Exception e) {
throw new RuntimeException(e);
}
CityResponse response = AccessController.doPrivileged((PrivilegedAction<CityResponse>) () -> {
try {
return dbReader.city(ipAddress);
} catch (AddressNotFoundException e) {
throw new AddressNotFoundRuntimeException(e);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
@ -136,14 +146,13 @@ public final class GeoIpProcessor implements Processor {
if (sm != null) {
sm.checkPermission(new SpecialPermission());
}
CountryResponse response = AccessController.doPrivileged(new PrivilegedAction<CountryResponse>() {
@Override
public CountryResponse run() {
try {
return dbReader.country(ipAddress);
} catch (IOException | GeoIp2Exception e) {
throw new RuntimeException(e);
}
CountryResponse response = AccessController.doPrivileged((PrivilegedAction<CountryResponse>) () -> {
try {
return dbReader.country(ipAddress);
} catch (AddressNotFoundException e) {
throw new AddressNotFoundRuntimeException(e);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
@ -190,4 +199,14 @@ public final class GeoIpProcessor implements Processor {
}
}
// Geoip2's AddressNotFoundException is checked and due to the fact that we need run their code
// inside a PrivilegedAction code block, we are forced to catch any checked exception and rethrow
// it with an unchecked exception.
private final static class AddressNotFoundRuntimeException extends RuntimeException {
public AddressNotFoundRuntimeException(Throwable cause) {
super(cause);
}
}
}

View File

@ -77,4 +77,17 @@ public class GeoIpProcessorTests extends ESTestCase {
assertThat(geoData.get("continent_name"), equalTo("Europe"));
}
public void testAddressIsNotInTheDatabase() throws Exception {
InputStream database = GeoIpProcessor.class.getResourceAsStream("/GeoLite2-City.mmdb");
GeoIpProcessor processor = new GeoIpProcessor("source_field", new DatabaseReader.Builder(database).build(), "target_field");
Map<String, Object> document = new HashMap<>();
document.put("source_field", "202.45.11.11");
Data data = new Data("_index", "_type", "_id", document);
processor.execute(data);
@SuppressWarnings("unchecked")
Map<String, Object> geoData = (Map<String, Object>) data.getDocument().get("target_field");
assertThat(geoData.size(), equalTo(0));
}
}