From 540403951ba1edea670c3b7bbe3be0925f72abc0 Mon Sep 17 00:00:00 2001 From: judy0131 Date: Fri, 27 Mar 2020 12:51:29 +0800 Subject: [PATCH 1/4] return example info for stop --- .../src/main/scala/cn/piflow/conf/util/ClassUtil.scala | 3 ++- .../src/main/scala/cn/piflow/api/HTTPClientGetStopInfo.scala | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/piflow-bundle/src/main/scala/cn/piflow/conf/util/ClassUtil.scala b/piflow-bundle/src/main/scala/cn/piflow/conf/util/ClassUtil.scala index d633a9d..ef41c7a 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/conf/util/ClassUtil.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/conf/util/ClassUtil.scala @@ -214,7 +214,8 @@ object ClassUtil { ("defaultValue" -> property.defaultValue) ~ ("allowableValues" -> property.allowableValues) ~ ("required" -> property.required.toString) ~ - ("sensitive" -> property.sensitive.toString)) }) ) + ("sensitive" -> property.sensitive.toString) ~ + ("example" -> property.example)) }) ) val jsonString = compactRender(json) jsonString diff --git a/piflow-server/src/main/scala/cn/piflow/api/HTTPClientGetStopInfo.scala b/piflow-server/src/main/scala/cn/piflow/api/HTTPClientGetStopInfo.scala index 28a23d2..12ff3fc 100644 --- a/piflow-server/src/main/scala/cn/piflow/api/HTTPClientGetStopInfo.scala +++ b/piflow-server/src/main/scala/cn/piflow/api/HTTPClientGetStopInfo.scala @@ -8,7 +8,7 @@ object HTTPClientGetStopInfo { def main(args: Array[String]): Unit = { - val url = "http://10.0.86.98:8001/stop/info?bundle=cn.piflow.bundle.jdbc.JdbcWrite" + val url = "http://10.0.85.83:8001/stop/info?bundle=cn.piflow.bundle.csv.CsvParser" val client = HttpClients.createDefault() val getFlowInfo:HttpGet = new HttpGet(url) From 58213cb4e2c66743b230eaaa1d0b9922222472bf Mon Sep 17 00:00:00 2001 From: judy0131 Date: Fri, 27 Mar 2020 20:01:52 +0800 Subject: [PATCH 2/4] Add files via upload add mock data icon --- .../src/main/resources/common/MockData.png | Bin 0 -> 31362 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 piflow-bundle/src/main/resources/common/MockData.png diff --git a/piflow-bundle/src/main/resources/common/MockData.png b/piflow-bundle/src/main/resources/common/MockData.png new file mode 100644 index 0000000000000000000000000000000000000000..902f4b0436d2ff1332ea853a4cd5cacf64988aa3 GIT binary patch literal 31362 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 V?H*SYT7>`r002ovPDHLkV1kE Date: Fri, 27 Mar 2020 20:08:51 +0800 Subject: [PATCH 3/4] add MockData Stop to support right-click --- .../main/resources/flow/common/mockData.json | 19 +++ .../resources/{ => icon}/common/MockData.png | Bin piflow-bundle/src/main/resources/scala.json | 36 +++++ .../cn/piflow/bundle/common/MockData.scala | 137 ++++++++++++++++++ .../piflow/bundle/common/MockDataTest.scala | 58 ++++++++ 5 files changed, 250 insertions(+) create mode 100644 piflow-bundle/src/main/resources/flow/common/mockData.json rename piflow-bundle/src/main/resources/{ => icon}/common/MockData.png (100%) create mode 100644 piflow-bundle/src/main/resources/scala.json create mode 100644 piflow-bundle/src/main/scala/cn/piflow/bundle/common/MockData.scala create mode 100644 piflow-bundle/src/test/scala/cn/piflow/bundle/common/MockDataTest.scala diff --git a/piflow-bundle/src/main/resources/flow/common/mockData.json b/piflow-bundle/src/main/resources/flow/common/mockData.json new file mode 100644 index 0000000..13fe4ed --- /dev/null +++ b/piflow-bundle/src/main/resources/flow/common/mockData.json @@ -0,0 +1,19 @@ +{ + "flow":{ + "name":"mockData", + "uuid":"1234", + "stops":[ + { + "uuid":"0000", + "name":"MockData", + "bundle":"cn.piflow.bundle.common.MockData", + "properties":{ + "schema": "name:String:true, age:Int, weight:Double, totalMoney:Float, isStudent:Boolean", + "count": "10" + } + } + + ], + "paths":[] + } +} \ No newline at end of file diff --git a/piflow-bundle/src/main/resources/common/MockData.png b/piflow-bundle/src/main/resources/icon/common/MockData.png similarity index 100% rename from piflow-bundle/src/main/resources/common/MockData.png rename to piflow-bundle/src/main/resources/icon/common/MockData.png diff --git a/piflow-bundle/src/main/resources/scala.json b/piflow-bundle/src/main/resources/scala.json new file mode 100644 index 0000000..38ce2c0 --- /dev/null +++ b/piflow-bundle/src/main/resources/scala.json @@ -0,0 +1,36 @@ +{ + "flow":{ + "name":"scalaTest", + "uuid":"1234567890", + "stops":[ + { + "uuid":"1111", + "name":"CsvParser", + "bundle":"cn.piflow.bundle.csv.CsvParser", + "properties":{ + "csvPath":"hdfs://10.0.88.13:9000/xjzhu/test.csv", + "header":"false", + "delimiter":",", + "schema":"title,author" + } + }, + { + "uuid":"2222", + "name":"ExecuteScala", + "bundle":"cn.piflow.bundle.script.ExecuteScala", + "properties":{ + "script":"import sys\nimport os\n\nimport numpy as np\nfrom scipy import linalg\nimport pandas as pd\n\nimport matplotlib\nmatplotlib.use('Agg')\n\n\ndef listFunction(dictInfo):\n\n return dictInfo", + "execFunction": "listFunction" + } + } + ], + "paths":[ + { + "from":"CsvParser", + "outport":"", + "inport":"", + "to":"ExecuteScala" + } + ] + } +} \ No newline at end of file diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/MockData.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/MockData.scala new file mode 100644 index 0000000..f6f873d --- /dev/null +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/MockData.scala @@ -0,0 +1,137 @@ +package cn.piflow.bundle.common + +import java.time.LocalDate + +import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} +import cn.piflow.conf.{ConfigurableStop, Port, StopGroup} +import cn.piflow.conf.bean.PropertyDescriptor +import cn.piflow.conf.util.{ImageUtil, MapUtil} +import jodd.datetime.JDateTime +import org.apache.spark.sql.{DataFrame, SparkSession} +import org.apache.spark.sql.types._ +import org.json4s +import org.json4s.JsonAST._ +import org.json4s.jackson.JsonMethods._ + +import scala.util.Random + +class MockData extends ConfigurableStop{ + override val authorEmail: String = "xjzhu@cnic.cn" + override val description: String = "Mock dataframe." + override val inportList: List[String] = List(Port.NonePort) + override val outportList: List[String] = List(Port.DefaultPort) + + var schema: String = _ + var count: Int = _ + + override def setProperties(map: Map[String, Any]): Unit = { + schema = MapUtil.get(map,"schema").asInstanceOf[String] + count = MapUtil.get(map,"count").asInstanceOf[String].toInt + } + + override def getPropertyDescriptor(): List[PropertyDescriptor] = { + var descriptor : List[PropertyDescriptor] = List() + val schema = new PropertyDescriptor() + .name("schema") + .displayName("Schema") + .description("The schema of mock data, schema's format is column:columnType:isNullable." + + "columnType can be String/Int/Long/Float/Double/Boolean. " + + "isNullable can be left blank, the default value is false") + .defaultValue("") + .required(true) + .example("id:String,name:String,age:Int") + descriptor = schema :: descriptor + + val count = new PropertyDescriptor() + .name("count") + .displayName("Count") + .description("The count of dataframe") + .defaultValue("") + .required(true) + .example("10") + descriptor = count :: descriptor + + descriptor + } + + override def getIcon(): Array[Byte] = { + ImageUtil.getImage("icon/common/MockData.png") + } + + override def getGroup(): List[String] = { + List(StopGroup.CommonGroup) + } + + override def initialize(ctx: ProcessContext): Unit = {} + + override def perform(in: JobInputStream, out: JobOutputStream, pec: JobContext): Unit = { + val field = this.schema.split(",") + + val structFieldArray : Array[StructField] = new Array[StructField](field.size) + for(i <- 0 to field.size - 1){ + val columnInfo = field(i).split(":") + val column = columnInfo(0) + val columnType = columnInfo(1) + var isNullable = false + if(columnInfo.size == 3){ + isNullable = columnInfo(2).toBoolean + } + columnType match { + case "String"=> structFieldArray(i) = new StructField(column, StringType, isNullable) + case "Int"=>structFieldArray(i) = new StructField(column, IntegerType, isNullable) + case "Double"=>structFieldArray(i) = new StructField(column, DoubleType, isNullable) + case "Float"=>structFieldArray(i) = new StructField(column, FloatType, isNullable) + case "Long"=>structFieldArray(i) = new StructField(column, LongType, isNullable) + case "Boolean"=>structFieldArray(i) = new StructField(column, BooleanType, isNullable) + //case "Date"=>structFieldArray(i) = new StructField(column, DateType, nullable = true) + //case "Timestamp"=>structFieldArray(i) = new StructField(column, TimestampType, nullable = true) + } + + } + val schemaStructType = StructType(structFieldArray) + + val spark = pec.get[SparkSession]() + import spark.implicits._ + val rnd : Random = new Random() + val i = randomJson(rnd,schemaStructType) + val df = spark.read.schema(schemaStructType).json((0 to count).map{ _ => compact(randomJson(rnd,schemaStructType))}.toDS()) + df.show() + out.write(df) + + } + + private def randomJson( rnd: Random, dataType : DataType): JValue ={ + + val alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + dataType match { + case v:DoubleType => + json4s.JDouble(rnd.nextDouble()) + case v:StringType => + JString((1 to 10).map(x => alpha(Random.nextInt.abs % alpha.size)).mkString) + case v:IntegerType => + JInt(rnd.nextInt(100)) + case v:LongType => + JInt(rnd.nextLong()) + case v:FloatType => + JDouble(rnd.nextFloat()) + case v:BooleanType => + JBool(rnd.nextBoolean()) + case v:ArrayType => + val size = rnd.nextInt(10) + JArray( + (0 to size).map(_ => randomJson(rnd, v.elementType)).toList + ) + case v:StructType => + JObject( + v.fields.flatMap{ + f => + if( f.nullable && rnd.nextBoolean()) + None + else + Some(JField(f.name, randomJson(rnd, f.dataType))) + }.toList + ) + } + + } +} diff --git a/piflow-bundle/src/test/scala/cn/piflow/bundle/common/MockDataTest.scala b/piflow-bundle/src/test/scala/cn/piflow/bundle/common/MockDataTest.scala new file mode 100644 index 0000000..2a59164 --- /dev/null +++ b/piflow-bundle/src/test/scala/cn/piflow/bundle/common/MockDataTest.scala @@ -0,0 +1,58 @@ +package cn.piflow.bundle.common + +import java.net.InetAddress + +import cn.piflow.Runner +import cn.piflow.conf.bean.FlowBean +import cn.piflow.conf.util.{FileUtil, OptionUtil} +import cn.piflow.util.{PropertyUtil, ServerIpUtil} +import org.apache.spark.sql.SparkSession +import org.h2.tools.Server +import org.junit.Test + +import scala.util.parsing.json.JSON + +class MockDataTest { + + @Test + def testFlow(): Unit ={ + + //parse flow json + val file = "src/main/resources/flow/common/mockData.json" + val flowJsonStr = FileUtil.fileReader(file) + val map = OptionUtil.getAny(JSON.parseFull(flowJsonStr)).asInstanceOf[Map[String, Any]] + println(map) + + //create flow + val flowBean = FlowBean(map) + val flow = flowBean.constructFlow() + + + val ip = InetAddress.getLocalHost.getHostAddress + cn.piflow.util.FileUtil.writeFile("server.ip=" + ip, ServerIpUtil.getServerIpFile()) + val h2Server = Server.createTcpServer("-tcp", "-tcpAllowOthers", "-tcpPort","50001").start() + //execute flow + val spark = SparkSession.builder() + .master("local[12]") + .appName("hive") + .config("spark.driver.memory", "4g") + .config("spark.executor.memory", "8g") + .config("spark.cores.max", "8") + .config("hive.metastore.uris",PropertyUtil.getPropertyValue("hive.metastore.uris")) + .enableHiveSupport() + .getOrCreate() + + val process = Runner.create() + .bind(classOf[SparkSession].getName, spark) + .bind("checkpoint.path", "") + .bind("debug.path","") + .start(flow); + + process.awaitTermination(); + val pid = process.pid(); + println(pid + "!!!!!!!!!!!!!!!!!!!!!") + spark.close(); + } + + +} From ddbe128a0dd81ae07b6b78cd7c04d9cc4f52e425 Mon Sep 17 00:00:00 2001 From: judy0131 Date: Fri, 27 Mar 2020 20:17:48 +0800 Subject: [PATCH 4/4] remove duplicate code --- .../src/main/scala/cn/piflow/bundle/common/MockData.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/MockData.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/MockData.scala index f6f873d..7dabc02 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/MockData.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/MockData.scala @@ -95,7 +95,6 @@ class MockData extends ConfigurableStop{ val rnd : Random = new Random() val i = randomJson(rnd,schemaStructType) val df = spark.read.schema(schemaStructType).json((0 to count).map{ _ => compact(randomJson(rnd,schemaStructType))}.toDS()) - df.show() out.write(df) }