scala - 如何使用 "scopt"命令行参数解析具有字段的案例类作为另一个案例类?

标签 scala apache-spark apache-kafka command-line-arguments scopt

解析字段(例如-master:String =“”)可以工作,但是如果这是在另一个案例类中,例如下面给出的案例类Job(SparkArgs),并且我需要解析JobArgs,该怎么办


case class SparkArgs(master: String)

val parser = new scopt.OptionParser[SparkArgs]("testing") {
    head("spark-example", "2.11")

    opt[String]('c', "master").required().valueName("spark-master").
      action((x, c) => c.copy(master = x)).
      text("Setting master is required")
  }

  parser.parse(args, SparkArgs()) match {

    case Some(config) =>
    // do stuff
      println(config.master)
    case None => // failed

  }
//I am able to parse master above by >> run --master=local[2]

//Now how to parse if there are case class as parameters instead of String and Int and also those fields needs to be parsed,say scopt.OptionParser[JobArgs]
//eg -

 case class JobArgs(sparkArgs: SparkArgs, kafkaArgs: KafkaArgs)
 case class KafkaArgs(
                        kafkaPORT: String="",
                        checkpointPath: String="src/main/resources/checkpoints"
                      )
  case class SparkArgs(master: String = "")


//I tried-
val parser = new scopt.OptionParser[JobArgs]("testing") {
    head("spark-example", "2.11")

   //Now how to parse all those fields which are master and kafkaPORT here
  }

//and run similarly as>> run --master=local[2] --kafkaPORT=localhost:9092 

最佳答案

怎么样:

case class JobArgs(sparkArgs: SparkArgs = SparkArgs(), kafkaArgs: KafkaArgs = KafkaArgs())

case class KafkaArgs(
                      kafkaPORT: String = "",
                      checkpointPath: String = "src/main/resources/checkpoints"
                    )

case class SparkArgs(master: String = "")

object StackoverFlow {
  def main(args: Array[String]): Unit = {

    val parser = new scopt.OptionParser[JobArgs]("testing") {
      head("spark-example", "2.11")

      opt[String]("master")
        .required()
        .valueName("spark-master")
        .action((master, c) => c.copy(sparkArgs = SparkArgs(master)))
        .text("All necessary benchmark topics get created.")

      opt[String]("kafkaPort")
        .required()
        .valueName("kafka-port")
        .action((kafkaPort, c) => c.copy(kafkaArgs = KafkaArgs(kafkaPort)))
    }

    parser.parse(args, JobArgs()) match {
      case Some(c) => println(c)
      case _ => sys.exit(1)
    }
  }
}

使用参数 --master FCM --kafkaPort 1965 执行它会产生以下输出:

JobArgs(SparkArgs(FCM),KafkaArgs(1965,src/main/resources/checkpoints))

如果您还想通过checkpointPath,您可以通过以下方式实现:

case class JobArgs(sparkArgs: SparkArgs = SparkArgs(), kafkaArgs: KafkaArgs = KafkaArgs())

case class KafkaArgs(
                      kafkaPORT: String = "",
                      checkpointPath: String = "src/main/resources/checkpoints"
                    )

case class SparkArgs(master: String = "")

object StackoverFlow {
  def main(args: Array[String]): Unit = {

    val parser = new scopt.OptionParser[JobArgs]("testing") {
      head("spark-example", "2.11")

      opt[String]("master")
        .required()
        .valueName("spark-master")
        .action((master, c) => c.copy(sparkArgs = SparkArgs(master)))
        .text("All necessary benchmark topics get created.")

      opt[Unit]("kafka")
        .action((kafkaPort, c) => c.copy(kafkaArgs = KafkaArgs()))
        .children(
          opt[String]('p', "port")
            .required()
            .action((x, c) => c.copy(kafkaArgs = c.kafkaArgs.copy(kafkaPORT = x))),
          opt[String]('c', "checkpointPath")
            .required()
            .action((x, c) => c.copy(kafkaArgs = c.kafkaArgs.copy(checkpointPath = x)))
        )
    }

    parser.parse(args, JobArgs()) match {
      case Some(c) => println(c)
      case _ => sys.exit(1)
    }
  }
}

相应地,使用以下参数执行:

--master FC --kafka --port 1965 --checkpointPath Mag/de/burg

导致以下输出: JobArgs(SparkArgs(FC),KafkaArgs(1965,Mag/de/burg))

关于scala - 如何使用 "scopt"命令行参数解析具有字段的案例类作为另一个案例类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57568516/

相关文章:

.net - 消息代理(Kafka、RabbitMQ)VS 服务总线(nServiceBus)

具有扩展密封特征的案例类的 Scala 泛型

java - 如何分割输入数据并将其加载到RDD

scala - 如何在 spark-sql 中使用 "not rlike"?

apache-spark - 将外部属性文件添加到spark中的类路径

java - kafka-设置java启动参数的正确方法

java - Apache Kafka 使用日志压缩策略或如何清理旧的压缩日志

scala - Akka Streams 的 ActorPublisher 作为 Web 响应的源 - 背压如何工作

scala - 为什么 crossScalaVersion 不是 scalaVersion?

Scala 与关键字的使用