@Override
    public GeoLocationResponse locate(final InetAddress address) {
        try {
            val location = new GeoLocationResponse();
            FunctionUtils.doIfNotNull(cityDatabaseReader, __ -> {
                val response = cityDatabaseReader.city(address);
                location.addAddress(response.getCity().getName());
                collectGeographicalPosition(location, response);
            });

            FunctionUtils.doIfNotNull(countryDatabaseReader, __ -> {
                val response = countryDatabaseReader.country(address);
                location.addAddress(response.getCountry().getName());
            });

            if (location.getAddresses().isEmpty() && properties.getAccountId() > 0 && StringUtils.isNotBlank(properties.getLicenseKey())) {
                try (val client = buildWebServiceClient()) {
                    val cityResponse = client.city(address);
                    location.addAddress(cityResponse.getCity().getName());
                    collectGeographicalPosition(location, cityResponse);

                    val countryResponse = client.country(address);
                    location.addAddress(countryResponse.getCountry().getName());
                }
            }

            LOGGER.debug("Geo location for [{}] is calculated as [{}]", address, location);
            return location;
        } catch (final AddressNotFoundException e) {
            LOGGER.info(e.getMessage(), e);
        } catch (final Exception e) {
            LoggingUtils.error(LOGGER, e);
        }
        return null;
    }
This is {@link MaxmindDatabaseGeoLocationService} that reads geo data
from a maxmind database and constructs a geo location based on the ip address.
Default caching of the databases is enabled by default.

@author Misagh Moayyed
@since 5.0.0
support/cas-server-support-geolocation-maxmind/src/main/java/org/apereo/cas/support/geo/maxmind/MaxmindDatabaseGeoLocationService.java