Предоставление контекста для выполнения Spark UDF - PullRequest
0 голосов
/ 07 марта 2020

Я работаю на Scala языке программирования. Я хочу иметь sh весь столбец данных с sha2 и солью. Я реализовал следующий UDF, который должен принимать MessageDigest и входную строку, которая будет хэшироваться.

  val md = MessageDigest.getInstance("SHA-256")

  val random = new SecureRandom();
  val salt: Array[Byte] = new Array[Byte](16)
  random.nextBytes(salt)
  md.update(salt)

  dataFrame.withColumn("ColumnName", Sqlfunc(md, col("ColumnName")))

  ....some other code....

  val HashValue: ((MessageDigest, String) => String) = (md: MessageDigest, input: String) =>
  {
    val hashedPassword: Array[Byte] = md.digest(input.getBytes(StandardCharsets.UTF_8))
    val sb: StringBuilder = new StringBuilder
    for (b <- hashedPassword) {sb.append(String.format("%02x", Byte.box(b)))}
    sb.toString();
  }

  val Sqlfunc = udf(HashValue)

Однако приведенный выше код не компилируется, потому что я не знаю, как передать messageDigest этой функции, поэтому я сталкиваюсь со следующей ошибкой

 <<< ERROR!
java.lang.ClassCastException: com...................$$anonfun$9 cannot be cast to scala.Function1

Может кто-нибудь сказать мне, что я Я делаю не так? Также я новичок в криптографии, поэтому не стесняйтесь предлагать все, что вы можете. Мы должны использовать Sha2 и соль. Что вы думаете о спектакле здесь?

Спасибо

1 Ответ

1 голос
/ 07 марта 2020

MessageDigest нет в ваших данных. Это просто контекст для оценки UDF. Этот тип контекста предоставляется через замыкания .

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

object X extends Serializable {
  import org.apache.spark.sql.expressions.UserDefinedFunction
  import org.apache.spark.sql.functions.udf

  def foo(context: String)(arg1: Int, arg2: Int): String =
    context.slice(arg1, arg2)

  def udfFoo(context: String): UserDefinedFunction =
    udf(foo(context) _)
}

. Попробуйте:

spark.range(1).toDF
  .select(X.udfFoo("Hello, there!")('id, 'id + 5))
  .show(false)

генерирует

+-----------------+
|UDF(id, (id + 5))|
+-----------------+
|Hello            |
+-----------------+
...