Вызов API геокодирования местоположения возвращает пустое значение в Spark - PullRequest
2 голосов
/ 14 июля 2020

У меня возникает эта странная проблема при вызове API геокодирования eLocations через Spark, где я всегда получаю пустое тело, даже если я знаю, что адреса вернут координаты. Я разрабатываю приложение для геокодирования с использованием Spark (2.3.3) и scala. Я также использую scalaj для вызова REST API. Таким образом, строка кода, которая вызывает API, выглядит так:

def getGeoCoderLocation(sc: SparkSession, req: String, url: String, proxy_host: String, proxy_port: String, response_format: String): scala.collection.Map[String, (String, String)] = {
    import sc.implicits._

    val httpresponse = Http(url).proxy(proxy_host, proxy_port.toInt).postForm.params(("xml_request", req), ("format", response_format)).asString

    println(httpresponse.body)
    println(httpresponse.contentType.getOrElse(""))
    println(httpresponse.headers)
    println(httpresponse)
    if(!httpresponse.contentType.getOrElse("").contains("text/html")) {
      val body = httpresponse.body
      val httpresponse_body = parseJSON(Option(body).getOrElse("[{\"x\":, \"y\":}]"))

      val location = for (it <- 0 until httpresponse_body.length) yield {
        (Option(httpresponse_body(it)(0).x).getOrElse("").toString, Option(httpresponse_body(it)(0).y).getOrElse("").toString, it)
      }

      val locDF = location.toDF(Seq("LONGITUDE", "LATITUDE", "row"): _*)//.withColumn("row", monotonically_increasing_id())
      locDF.show(20, false)
      locDF.rdd.map { r => (Option(r.get(2)).getOrElse("").toString, (Option(r.get(0)).getOrElse("").toString, Option(r.getString(1)).getOrElse("").toString)) }.collectAsMap()
    }
    else {
      val locDF = Seq(("","","-")).toDF(Seq("LONGITUDE", "LATITUDE", "row"): _*)//.withColumn("row", monotonically_increasing_id())
      locDF.show(20, false)
      locDF.rdd.map { r => (Option(r.get(2)).getOrElse("").toString, (Option(r.get(0)).getOrElse("").toString, Option(r.getString(1)).getOrElse("").toString)) }.collectAsMap()
    }
  }

Где

  • url = http://elocation.oracle.com/elocation/lbs
  • proxy_host = (ip прокси)
  • proxy_port = (номер порта)
  • req = "<?xml version=\"1.0\" standalone=\"yes\"?>\n<geocode_request vendor=\"elocation\">\n\t(address_list)\n\t\t|<list of requests>|\n\t</address_list>\n</geocode_request>"
  • response_format = JSON

Итак когда я печатаю тело, оно всегда будет [{}] (т.е. пустым JSON массивом), когда я запускаю свое приложение в Spark. Когда я запускаю тот же запрос без искровой отправки, я получаю правильный массив из JSON объектов (например, java -jar test.jar).

Есть ли в Spark параметр, который блокирует приложение от получения ответов REST? Мы используем Cloudera 5.16.x

Я также пробовал установить информацию прокси, используя --conf "spark.executor.extraJavaOptions=-Dhttp.proxyHost=(ip) -Dhttp.proxyPort=(port) -Dhttps.proxyHost=(ip) -Dhttps.proxyPort=(port)", но получаю:

Exception in thread "main" org.apache.hadoop.security.KerberosAuthException: Login failure for user: (principal) from keytab (keytab) javax.security.auth.login.LoginException: Cannot locate KDC

Пожалуйста, помогите, так как я не знаю, где искать чтобы решить эту проблему, поскольку я никогда не сталкивался с этим раньше.

1 Ответ

0 голосов
/ 16 июля 2020

ок, нашел причину. полезная нагрузка была фактически пустой, поэтому elocation продолжает возвращаться пустым.

Урок дня, проверьте свою полезную нагрузку.

...