I created a Java UDF in a snowflake in order to query GeoIp2 library and get the ISO code of a column list of IP. I have '@AWS_CSV_STAGE/lib/geoip2-2.8.0.jar','@AWS_CSV_STAGE/geodata/GeoLite2-City.mmdb' and 'maxmind-db-1.2.1.jar' already staged so i included their location with full URL from the AWS_CSV_STAGE in the import option, so i can use the GeoLite2 library and querying the database and get the ISO code (US, NL) for each IP provided. When i save the function it's correctly saved, but when i launch the SELECT on my table i get the error:
User Error Report: Java Stack Trace: java.lang.NullPointerException at function_handler_0//MyUDFHandler.isoCode(InlineCode.java:18) in function GEOLOCATOR with handler MyUDFHandler.isoCode
i have a doubt about the following lines of code if they are really using the database:
URL resource = MyUDFHandler.class.getClassLoader().getResource("GeoLite2-City.mmdb");
File file = new File(resource.toURI());
DatabaseReader reader = new DatabaseReader.Builder(file).build();
code:
create or replace function DB_TEST.MAIN_SCHEMA.GEOLOCATOR(IP VARCHAR)
returns string not null
language java
imports=('@DB_TEST.MAIN_SCHEMA.AWS_CSV_STAGE/geodata/GeoLite2-City.mmdb', '@DB_TEST.MAIN_SCHEMA.AWS_CSV_STAGE/lib/maxmind-db-1.2.1.jar', '@DB_TEST.MAIN_SCHEMA.AWS_CSV_STAGE/lib/geoip2-2.8.0.jar')
handler='MyUDFHandler.isoCode'
as
$$
import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.exception.GeoIp2Exception;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.record.Country;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.net.InetAddress;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
class MyUDFHandler {
public static String isoCode (String ip_address) throws Exception {
URL resource = MyUDFHandler.class.getClassLoader().getResource("GeoLite2-City.mmdb");
File file = new File(resource.toURI());
DatabaseReader reader = new DatabaseReader.Builder(file).build();
CityResponse response = reader.city(InetAddress.getByName(ip_address));
return response.getCountry().getIsoCode();
}
}
$$;
SELECT IP, GEOLOCATOR(IP) as GEO_IP FROM DANGEROUS_IPS LIMIT 1;