public Optional apply()

in baremaps-core/src/main/java/org/apache/baremaps/iploc/IpLocMapper.java [61:162]


  public Optional<IpLocObject> apply(NicObject nicObject) {
    try {
      if (nicObject.attributes().isEmpty()) {
        return Optional.empty();
      }

      if (!NicUtils.isInetnum(nicObject)) {
        return Optional.empty();
      }

      var inetnum = nicObject.attributes().get(0);
      var ipRange = IpResourceRange.parse(inetnum.value());
      var start = InetAddresses.forString(ipRange.getStart().toString());
      var end = InetAddresses.forString(ipRange.getEnd().toString());
      var inetRange = new InetRange(start, end);

      var attributes = nicObject.toMap();

      // Use a default name if there is no netname
      var network = attributes.getOrDefault("netname", "unknown");

      // If there is a geoloc field, we use the latitude and longitude provided
      if (attributes.containsKey("geoloc")) {
        var location = stringToCoordinate(attributes.get("geoloc"));
        if (location.isPresent()) {
          return Optional.of(new IpLocObject(
              attributes.get("geoloc"),
              inetRange,
              location.get(),
              network,
              attributes.get("country"),
              attributes.get("source"),
              IpLocPrecision.GEOLOC));
        }
      }

      // If there is a country, we use that with a cherry-picked list of fields to query the
      // geocoder with confidence to find a relevant precise location,
      // in the worst case the error is within a country
      List<String> searchedFields = List.of("descr", "netname");
      // at least one of a searchedField is present and the country is present.
      if (attributes.keySet().stream().anyMatch(searchedFields::contains)
          && attributes.containsKey("country")) {
        // build a query text string out of the cherry-picked fields
        var queryTextBuilder = new StringBuilder();
        for (String field : searchedFields) {
          if (!Strings.isNullOrEmpty(attributes.get(field))) {
            queryTextBuilder.append(attributes.get(field)).append(" ");
          }
        }

        String queryText = queryTextBuilder.toString();
        var location = findLocationInCountry(queryText, attributes.get("country"));
        if (location.isPresent()) {
          return Optional.of(new IpLocObject(
              queryText,
              inetRange,
              location.get(),
              network,
              attributes.get("country"),
              attributes.get("source"),
              IpLocPrecision.GEOCODER));
        }
      }

      // If there is a country get the location of country
      if (attributes.containsKey("country")) {
        var location = findCountryLocation(attributes.get("country"));
        if (location.isPresent()) {
          return Optional.of(new IpLocObject(
              attributes.get("country"),
              inetRange,
              location.get(),
              network,
              attributes.get("country"),
              attributes.get("source"),
              IpLocPrecision.COUNTRY));
        }
      }

      return Optional.of(new IpLocObject(
          null,
          inetRange,
          new Coordinate(),
          network,
          null,
          attributes.get("source"),
          IpLocPrecision.WORLD));
    } catch (Exception e) {
      logger.warn("Error while mapping nic object to ip loc object", e);
      logger.warn("Nic object attributes:");
      nicObject.attributes().forEach(attribute -> {
        var name = attribute.name();
        var value = attribute.value();
        if (value.length() > 100) {
          value = value.substring(0, 100).concat("...");
        }
        logger.warn("  {} = {}", name, value);
      });
      return Optional.empty();
    }
  }