3838import static java .util .Map .entry ;
3939import static org .elasticsearch .ingest .geoip .GeoIpTestUtils .copyDatabase ;
4040import static org .elasticsearch .ingest .geoip .IpinfoIpDataLookups .parseAsn ;
41+ import static org .elasticsearch .ingest .geoip .IpinfoIpDataLookups .parseLocationDouble ;
4142import static org .hamcrest .Matchers .empty ;
4243import static org .hamcrest .Matchers .equalTo ;
4344import static org .hamcrest .Matchers .is ;
@@ -72,6 +73,10 @@ public void testDatabasePropertyInvariants() {
7273 // the second ASN variant database is like a specialization of the ASN database
7374 assertThat (Sets .difference (Database .Asn .properties (), Database .AsnV2 .properties ()), is (empty ()));
7475 assertThat (Database .Asn .defaultProperties (), equalTo (Database .AsnV2 .defaultProperties ()));
76+
77+ // the second City variant database is like a version of the ordinary City database but lacking many fields
78+ assertThat (Sets .difference (Database .CityV2 .properties (), Database .City .properties ()), is (empty ()));
79+ assertThat (Sets .difference (Database .CityV2 .defaultProperties (), Database .City .defaultProperties ()), is (empty ()));
7580 }
7681
7782 public void testParseAsn () {
@@ -88,6 +93,18 @@ public void testParseAsn() {
8893 assertThat (parseAsn ("anythingelse" ), nullValue ());
8994 }
9095
96+ public void testParseLocationDouble () {
97+ // expected case: "123.45" is 123.45
98+ assertThat (parseLocationDouble ("123.45" ), equalTo (123.45 ));
99+ // defensive cases: null and empty becomes null, this is not expected fwiw
100+ assertThat (parseLocationDouble (null ), nullValue ());
101+ assertThat (parseLocationDouble ("" ), nullValue ());
102+ // defensive cases: we strip whitespace
103+ assertThat (parseLocationDouble (" -123.45 " ), equalTo (-123.45 ));
104+ // bottom case: a non-parsable string is null
105+ assertThat (parseLocationDouble ("anythingelse" ), nullValue ());
106+ }
107+
91108 public void testAsn () throws IOException {
92109 assumeFalse ("https://github.com/elastic/elasticsearch/issues/114266" , Constants .WINDOWS );
93110 Path configDir = tmpDir ;
@@ -100,7 +117,7 @@ public void testAsn() throws IOException {
100117
101118 // this is the 'free' ASN database (sample)
102119 try (DatabaseReaderLazyLoader loader = configDatabases .getDatabase ("ip_asn_sample.mmdb" )) {
103- IpDataLookup lookup = new IpinfoIpDataLookups .Asn (Set . of ( Database .Property . values () ));
120+ IpDataLookup lookup = new IpinfoIpDataLookups .Asn (Database .AsnV2 . properties ( ));
104121 Map <String , Object > data = lookup .getData (loader , "5.182.109.0" );
105122 assertThat (
106123 data ,
@@ -118,7 +135,7 @@ public void testAsn() throws IOException {
118135
119136 // this is the non-free or 'standard' ASN database (sample)
120137 try (DatabaseReaderLazyLoader loader = configDatabases .getDatabase ("asn_sample.mmdb" )) {
121- IpDataLookup lookup = new IpinfoIpDataLookups .Asn (Set . of ( Database .Property . values () ));
138+ IpDataLookup lookup = new IpinfoIpDataLookups .Asn (Database .AsnV2 . properties ( ));
122139 Map <String , Object > data = lookup .getData (loader , "23.53.116.0" );
123140 assertThat (
124141 data ,
@@ -185,7 +202,7 @@ public void testCountry() throws IOException {
185202
186203 // this is the 'free' Country database (sample)
187204 try (DatabaseReaderLazyLoader loader = configDatabases .getDatabase ("ip_country_sample.mmdb" )) {
188- IpDataLookup lookup = new IpinfoIpDataLookups .Country (Set . of ( Database .Property . values () ));
205+ IpDataLookup lookup = new IpinfoIpDataLookups .Country (Database .Country . properties ( ));
189206 Map <String , Object > data = lookup .getData (loader , "4.221.143.168" );
190207 assertThat (
191208 data ,
@@ -202,6 +219,74 @@ public void testCountry() throws IOException {
202219 }
203220 }
204221
222+ public void testGeolocation () throws IOException {
223+ assumeFalse ("https://github.com/elastic/elasticsearch/issues/114266" , Constants .WINDOWS );
224+ Path configDir = tmpDir ;
225+ copyDatabase ("ipinfo/ip_geolocation_sample.mmdb" , configDir .resolve ("ip_geolocation_sample.mmdb" ));
226+
227+ GeoIpCache cache = new GeoIpCache (1000 ); // real cache to test purging of entries upon a reload
228+ ConfigDatabases configDatabases = new ConfigDatabases (configDir , cache );
229+ configDatabases .initialize (resourceWatcherService );
230+
231+ // this is the non-free or 'standard' Geolocation database (sample)
232+ try (DatabaseReaderLazyLoader loader = configDatabases .getDatabase ("ip_geolocation_sample.mmdb" )) {
233+ IpDataLookup lookup = new IpinfoIpDataLookups .Geolocation (Database .CityV2 .properties ());
234+ Map <String , Object > data = lookup .getData (loader , "2.124.90.182" );
235+ assertThat (
236+ data ,
237+ equalTo (
238+ Map .ofEntries (
239+ entry ("ip" , "2.124.90.182" ),
240+ entry ("country_iso_code" , "GB" ),
241+ entry ("region_name" , "England" ),
242+ entry ("city_name" , "London" ),
243+ entry ("timezone" , "Europe/London" ),
244+ entry ("postal_code" , "E1W" ),
245+ entry ("location" , Map .of ("lat" , 51.50853 , "lon" , -0.12574 ))
246+ )
247+ )
248+ );
249+ }
250+ }
251+
252+ public void testGeolocationInvariants () {
253+ assumeFalse ("https://github.com/elastic/elasticsearch/issues/114266" , Constants .WINDOWS );
254+ Path configDir = tmpDir ;
255+ copyDatabase ("ipinfo/ip_geolocation_sample.mmdb" , configDir .resolve ("ip_geolocation_sample.mmdb" ));
256+
257+ {
258+ final Set <String > expectedColumns = Set .of (
259+ "network" ,
260+ "city" ,
261+ "region" ,
262+ "country" ,
263+ "postal_code" ,
264+ "timezone" ,
265+ "latitude" ,
266+ "longitude"
267+ );
268+
269+ Path databasePath = configDir .resolve ("ip_geolocation_sample.mmdb" );
270+ assertDatabaseInvariants (databasePath , (ip , row ) -> {
271+ assertThat (row .keySet (), equalTo (expectedColumns ));
272+ {
273+ String latitude = (String ) row .get ("latitude" );
274+ assertThat (latitude , equalTo (latitude .trim ()));
275+ Double parsed = parseLocationDouble (latitude );
276+ assertThat (parsed , notNullValue ());
277+ assertThat (latitude , equalTo (Double .toString (parsed ))); // reverse it
278+ }
279+ {
280+ String longitude = (String ) row .get ("longitude" );
281+ assertThat (longitude , equalTo (longitude .trim ()));
282+ Double parsed = parseLocationDouble (longitude );
283+ assertThat (parsed , notNullValue ());
284+ assertThat (longitude , equalTo (Double .toString (parsed ))); // reverse it
285+ }
286+ });
287+ }
288+ }
289+
205290 private static void assertDatabaseInvariants (final Path databasePath , final BiConsumer <InetAddress , Map <String , Object >> rowConsumer ) {
206291 try (Reader reader = new Reader (pathToFile (databasePath ))) {
207292 Networks <?> networks = reader .networks (Map .class );
0 commit comments