1313import org .elasticsearch .common .logging .DeprecationCategory ;
1414import org .elasticsearch .common .logging .DeprecationLogger ;
1515import org .elasticsearch .core .Assertions ;
16+ import org .elasticsearch .core .Strings ;
1617import org .elasticsearch .ingest .AbstractProcessor ;
1718import org .elasticsearch .ingest .IngestDocument ;
1819import org .elasticsearch .ingest .Processor ;
2223import java .io .IOException ;
2324import java .util .ArrayList ;
2425import java .util .List ;
26+ import java .util .Locale ;
2527import java .util .Map ;
2628import java .util .Set ;
2729import java .util .function .Supplier ;
@@ -36,9 +38,12 @@ public final class GeoIpProcessor extends AbstractProcessor {
3638 private static final DeprecationLogger deprecationLogger = DeprecationLogger .getLogger (GeoIpProcessor .class );
3739 static final String DEFAULT_DATABASES_DEPRECATION_MESSAGE = "the [fallback_to_default_databases] has been deprecated, because "
3840 + "Elasticsearch no longer includes the default Maxmind geoip databases. This setting will be removed in Elasticsearch 9.0" ;
41+ static final String UNSUPPORTED_DATABASE_DEPRECATION_MESSAGE = "the geoip processor will no longer support database type [{}] "
42+ + "in a future version of Elasticsearch" ; // TODO add a message about migration?
3943
40- public static final String TYPE = "geoip" ;
44+ public static final String GEOIP_TYPE = "geoip" ;
4145
46+ private final String type ;
4247 private final String field ;
4348 private final Supplier <Boolean > isValid ;
4449 private final String targetField ;
@@ -62,6 +67,7 @@ public final class GeoIpProcessor extends AbstractProcessor {
6267 * @param databaseFile the name of the database file being queried; used only for tagging documents if the database is unavailable
6368 */
6469 GeoIpProcessor (
70+ final String type ,
6571 final String tag ,
6672 final String description ,
6773 final String field ,
@@ -74,6 +80,7 @@ public final class GeoIpProcessor extends AbstractProcessor {
7480 final String databaseFile
7581 ) {
7682 super (tag , description );
83+ this .type = type ;
7784 this .field = field ;
7885 this .isValid = isValid ;
7986 this .targetField = targetField ;
@@ -93,7 +100,7 @@ public IngestDocument execute(IngestDocument document) throws IOException {
93100 Object ip = document .getFieldValue (field , Object .class , ignoreMissing );
94101
95102 if (isValid .get () == false ) {
96- document .appendFieldValue ("tags" , "_geoip_expired_database " , false );
103+ document .appendFieldValue ("tags" , "_" + type + "_expired_database " , false );
97104 return document ;
98105 } else if (ip == null && ignoreMissing ) {
99106 return document ;
@@ -104,7 +111,7 @@ public IngestDocument execute(IngestDocument document) throws IOException {
104111 try (IpDatabase ipDatabase = this .supplier .get ()) {
105112 if (ipDatabase == null ) {
106113 if (ignoreMissing == false ) {
107- tag (document , databaseFile );
114+ tag (document , type , databaseFile );
108115 }
109116 return document ;
110117 }
@@ -146,7 +153,7 @@ public IngestDocument execute(IngestDocument document) throws IOException {
146153
147154 @ Override
148155 public String getType () {
149- return TYPE ;
156+ return type ;
150157 }
151158
152159 String getField () {
@@ -202,9 +209,11 @@ public IpDatabase get() throws IOException {
202209
203210 public static final class Factory implements Processor .Factory {
204211
212+ private final String type ; // currently always just "geoip"
205213 private final IpDatabaseProvider ipDatabaseProvider ;
206214
207- public Factory (IpDatabaseProvider ipDatabaseProvider ) {
215+ public Factory (String type , IpDatabaseProvider ipDatabaseProvider ) {
216+ this .type = type ;
208217 this .ipDatabaseProvider = ipDatabaseProvider ;
209218 }
210219
@@ -215,16 +224,16 @@ public Processor create(
215224 final String description ,
216225 final Map <String , Object > config
217226 ) throws IOException {
218- String ipField = readStringProperty (TYPE , processorTag , config , "field" );
219- String targetField = readStringProperty (TYPE , processorTag , config , "target_field" , "geoip" );
220- String databaseFile = readStringProperty (TYPE , processorTag , config , "database_file" , "GeoLite2-City.mmdb" );
221- List <String > propertyNames = readOptionalList (TYPE , processorTag , config , "properties" );
222- boolean ignoreMissing = readBooleanProperty (TYPE , processorTag , config , "ignore_missing" , false );
223- boolean firstOnly = readBooleanProperty (TYPE , processorTag , config , "first_only" , true );
227+ String ipField = readStringProperty (type , processorTag , config , "field" );
228+ String targetField = readStringProperty (type , processorTag , config , "target_field" , "geoip" );
229+ String databaseFile = readStringProperty (type , processorTag , config , "database_file" , "GeoLite2-City.mmdb" );
230+ List <String > propertyNames = readOptionalList (type , processorTag , config , "properties" );
231+ boolean ignoreMissing = readBooleanProperty (type , processorTag , config , "ignore_missing" , false );
232+ boolean firstOnly = readBooleanProperty (type , processorTag , config , "first_only" , true );
224233
225234 // Validating the download_database_on_pipeline_creation even if the result
226235 // is not used directly by the factory.
227- downloadDatabaseOnPipelineCreation (config , processorTag );
236+ downloadDatabaseOnPipelineCreation (type , config , processorTag );
228237
229238 // noop, should be removed in 9.0
230239 Object value = config .remove ("fallback_to_default_databases" );
@@ -239,7 +248,7 @@ public Processor create(
239248 // at a later moment, so a processor impl is returned that tags documents instead. If a database cannot be sourced
240249 // then the processor will continue to tag documents with a warning until it is remediated by providing a database
241250 // or changing the pipeline.
242- return new DatabaseUnavailableProcessor (processorTag , description , databaseFile );
251+ return new DatabaseUnavailableProcessor (type , processorTag , description , databaseFile );
243252 }
244253 databaseType = ipDatabase .getDatabaseType ();
245254 }
@@ -248,17 +257,48 @@ public Processor create(
248257 try {
249258 factory = IpDataLookupFactories .get (databaseType , databaseFile );
250259 } catch (IllegalArgumentException e ) {
251- throw newConfigurationException (TYPE , processorTag , "database_file" , e .getMessage ());
260+ throw newConfigurationException (type , processorTag , "database_file" , e .getMessage ());
261+ }
262+
263+ // the "geoip" processor type does additional validation of the database_type
264+ if (GEOIP_TYPE .equals (type )) {
265+ // type sniffing is done with the lowercased type
266+ final String lowerCaseDatabaseType = databaseType .toLowerCase (Locale .ROOT );
267+
268+ // start with a strict positive rejection check -- as we support addition database providers,
269+ // we should expand these checks when possible
270+ if (lowerCaseDatabaseType .startsWith (IpinfoIpDataLookups .IPINFO_PREFIX )) {
271+ throw newConfigurationException (
272+ type ,
273+ processorTag ,
274+ "database_file" ,
275+ Strings .format ("Unsupported database type [%s] for file [%s]" , databaseType , databaseFile )
276+ );
277+ }
278+
279+ // end with a lax negative rejection check -- if we aren't *certain* it's a maxmind database, then we'll warn --
280+ // it's possible for example that somebody cooked up a custom database of their own that happened to work with
281+ // our preexisting code, they should migrate to the new processor, but we're not going to break them right now
282+ if (lowerCaseDatabaseType .startsWith (MaxmindIpDataLookups .GEOIP2_PREFIX ) == false
283+ && lowerCaseDatabaseType .startsWith (MaxmindIpDataLookups .GEOLITE2_PREFIX ) == false ) {
284+ deprecationLogger .warn (
285+ DeprecationCategory .OTHER ,
286+ "unsupported_database_type" ,
287+ UNSUPPORTED_DATABASE_DEPRECATION_MESSAGE ,
288+ databaseType
289+ );
290+ }
252291 }
253292
254293 final IpDataLookup ipDataLookup ;
255294 try {
256295 ipDataLookup = factory .create (propertyNames );
257296 } catch (IllegalArgumentException e ) {
258- throw newConfigurationException (TYPE , processorTag , "properties" , e .getMessage ());
297+ throw newConfigurationException (type , processorTag , "properties" , e .getMessage ());
259298 }
260299
261300 return new GeoIpProcessor (
301+ type ,
262302 processorTag ,
263303 description ,
264304 ipField ,
@@ -272,42 +312,39 @@ public Processor create(
272312 );
273313 }
274314
275- public static boolean downloadDatabaseOnPipelineCreation (Map <String , Object > config ) {
276- return downloadDatabaseOnPipelineCreation (config , null );
277- }
278-
279- public static boolean downloadDatabaseOnPipelineCreation (Map <String , Object > config , String processorTag ) {
280- return readBooleanProperty (GeoIpProcessor .TYPE , processorTag , config , "download_database_on_pipeline_creation" , true );
315+ public static boolean downloadDatabaseOnPipelineCreation (String type , Map <String , Object > config , String processorTag ) {
316+ return readBooleanProperty (type , processorTag , config , "download_database_on_pipeline_creation" , true );
281317 }
282-
283318 }
284319
285320 static class DatabaseUnavailableProcessor extends AbstractProcessor {
286321
322+ private final String type ;
287323 private final String databaseName ;
288324
289- DatabaseUnavailableProcessor (String tag , String description , String databaseName ) {
325+ DatabaseUnavailableProcessor (String type , String tag , String description , String databaseName ) {
290326 super (tag , description );
327+ this .type = type ;
291328 this .databaseName = databaseName ;
292329 }
293330
294331 @ Override
295332 public IngestDocument execute (IngestDocument ingestDocument ) throws Exception {
296- tag (ingestDocument , databaseName );
333+ tag (ingestDocument , this . type , databaseName );
297334 return ingestDocument ;
298335 }
299336
300337 @ Override
301338 public String getType () {
302- return TYPE ;
339+ return type ;
303340 }
304341
305342 public String getDatabaseName () {
306343 return databaseName ;
307344 }
308345 }
309346
310- private static void tag (IngestDocument ingestDocument , String databaseName ) {
311- ingestDocument .appendFieldValue ("tags" , "_geoip_database_unavailable_ " + databaseName , true );
347+ private static void tag (IngestDocument ingestDocument , String type , String databaseName ) {
348+ ingestDocument .appendFieldValue ("tags" , "_" + type + "_database_unavailable_ " + databaseName , true );
312349 }
313350}
0 commit comments