From 06f9a772dc60b9f7ee8fa1a58a27c2f99af8651c Mon Sep 17 00:00:00 2001 From: judy0131 Date: Tue, 11 Sep 2018 14:51:24 +0800 Subject: [PATCH 01/14] remove core-site.xml hdfs-site.xml hive-site.xml yarn-site.xml --- conf/config.properties | 7 +- .../src/main/resources/core-site.xml | 17 ---- .../src/main/resources/hdfs-site.xml | 44 --------- .../src/main/resources/hive-site.xml | 90 ------------------- .../src/main/resources/yarn-site.xml | 52 ----------- .../src/main/scala/cn/piflow/api/API.scala | 5 ++ 6 files changed, 11 insertions(+), 204 deletions(-) delete mode 100644 piflow-bundle/src/main/resources/core-site.xml delete mode 100644 piflow-bundle/src/main/resources/hdfs-site.xml delete mode 100644 piflow-bundle/src/main/resources/hive-site.xml delete mode 100644 piflow-bundle/src/main/resources/yarn-site.xml diff --git a/conf/config.properties b/conf/config.properties index 0ffd173..593ab0d 100644 --- a/conf/config.properties +++ b/conf/config.properties @@ -4,8 +4,13 @@ server.port=8001 #spark.master=spark://10.0.86.89:7077 #spark.master=spark://10.0.86.191:7077 spark.master=yarn -spark.deploy.mode=cluster +spark.deploy.mode=client +yarn.resourcemanager.hostname=10.0.86.191 +yarn.resourcemanager.address=10.0.86.191:8032 +yarn.access.namenode=hdfs://10.0.86.191:9000 +yarn.stagingDir=hdfs://10.0.86.191:9000/tmp/ +hive.metastore.uris=thrift://10.0.86.191:9083 piflow.bundle=/opt/project/piflow/out/artifacts/piflow_bundle/piflow-bundle.jar diff --git a/piflow-bundle/src/main/resources/core-site.xml b/piflow-bundle/src/main/resources/core-site.xml deleted file mode 100644 index 5501561..0000000 --- a/piflow-bundle/src/main/resources/core-site.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - fs.defaultFS - hdfs://10.0.86.191:9000 - - - - io.file.buffer.size - 131072 - - - - hadoop.tmp.dir - /opt/hadoop-2.6.0/tmp - - diff --git a/piflow-bundle/src/main/resources/hdfs-site.xml b/piflow-bundle/src/main/resources/hdfs-site.xml deleted file mode 100644 index 3de1e21..0000000 --- a/piflow-bundle/src/main/resources/hdfs-site.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - dfs.namenode.http-address - 10.0.86.191:50070 - - - - dfs.namenode.secondary.http-address - 10.0.86.191:50090 - - - dfs.replication - 1 - - - - dfs.namenode.name.dir - file:/opt/hadoop-2.6.0/dfs/name - - - - dfs.datanode.data.dir - file:/opt/hadoop-2.6.0/dfs/data - - - dfs.client.read.shortcircuit - true - - - dfs.domain.socket.path - /var/run/hadoop-hdfs/dn._PORT - - - - dfs.client.file-block-storage-locations.timeout - 10000 - - - dfs.datanode.hdfs-blocks-metadata.enabled - true - - - diff --git a/piflow-bundle/src/main/resources/hive-site.xml b/piflow-bundle/src/main/resources/hive-site.xml deleted file mode 100644 index cbba649..0000000 --- a/piflow-bundle/src/main/resources/hive-site.xml +++ /dev/null @@ -1,90 +0,0 @@ - - - hive.metastore.warehouse.dir - - /user/hive/warehouse - location of default database for the warehouse - - - - hive.metastore.uris - thrift://10.0.86.89:9083 - Thrift URI for the remote metastore. Used by metastore client to connect to remote metastore. - - - - javax.jdo.option.ConnectionURL - jdbc:mysql://10.0.86.90:3306/hive?createDatabaseIfNotExist=true - JDBC connect string for a JDBC metastore - - - javax.jdo.option.ConnectionDriverName - com.mysql.jdbc.Driver - Driver class name for a JDBC metastore - - - - javax.jdo.option.ConnectionUserName - root - username to use against metastore database - - - javax.jdo.option.ConnectionPassword - root - password to use against metastore database - - - - - - hive.support.concurrency - true - - - - - - hive.enforce.bucketing - - true - - - - - - hive.exec.dynamic.partition.mode - - nonstrict - - - - - - hive.txn.manager - - org.apache.hadoop.hive.ql.lockmgr.DbTxnManager - - - - - - hive.compactor.initiator.on - - true - - - - - - hive.compactor.worker.threads - - 1 - - - - - - diff --git a/piflow-bundle/src/main/resources/yarn-site.xml b/piflow-bundle/src/main/resources/yarn-site.xml deleted file mode 100644 index 8a142db..0000000 --- a/piflow-bundle/src/main/resources/yarn-site.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - yarn.resourcemanager.hostname - 10.0.86.191 - - - The address of the applications manager interface in the RM. - yarn.resourcemanager.address - ${yarn.resourcemanager.hostname}:8032 - - - The address of the scheduler interface. - yarn.resourcemanager.scheduler.address - ${yarn.resourcemanager.hostname}:8030 - - - The http address of the RM web application. - yarn.resourcemanager.webapp.address - ${yarn.resourcemanager.hostname}:8088 - - - The https adddress of the RM web application. - yarn.resourcemanager.webapp.https.address - ${yarn.resourcemanager.hostname}:8090 - - - yarn.resourcemanager.resource-tracker.address - ${yarn.resourcemanager.hostname}:8031 - - - The address of the RM admin interface. - yarn.resourcemanager.admin.address - ${yarn.resourcemanager.hostname}:8033 - - - yarn.nodemanager.aux-services - mapreduce_shuffle - - - yarn.scheduler.maximum-allocation-mb - 12288 - 每个节点可用内存,单位MB,默认8182MB - - - yarn.nodemanager.pmem-check-enabled - false - - - yarn.nodemanager.vmem-check-enabled - false - - diff --git a/piflow-server/src/main/scala/cn/piflow/api/API.scala b/piflow-server/src/main/scala/cn/piflow/api/API.scala index 00e267b..36b596e 100644 --- a/piflow-server/src/main/scala/cn/piflow/api/API.scala +++ b/piflow-server/src/main/scala/cn/piflow/api/API.scala @@ -28,10 +28,15 @@ object API { .master(PropertyUtil.getPropertyValue("spark.master")) .appName(flowBean.name) .config("spark.deploy.mode",PropertyUtil.getPropertyValue("spark.deploy.mode")) + .config("spark.hadoop.yarn.resourcemanager.hostname", PropertyUtil.getPropertyValue("yarn.resourcemanager.hostname")) + .config("spark.hadoop.yarn.resourcemanager.address", PropertyUtil.getPropertyValue("yarn.resourcemanager.address")) + .config("spark.yarn.access.namenode", PropertyUtil.getPropertyValue("yarn.access.namenode")) + .config("spark.yarn.stagingDir", PropertyUtil.getPropertyValue("yarn.stagingDir")) //.config("spark.driver.memory", "1g") //.config("spark.executor.memory", "1g") //.config("spark.cores.max", "2") .config("spark.jars", PropertyUtil.getPropertyValue("piflow.bundle")) + .config("hive.metastore.uris",PropertyUtil.getPropertyValue("hive.metastore.uris")) .enableHiveSupport() .getOrCreate() From 66b3175ef729ad2834d183a85db996ad8fcc7a3d Mon Sep 17 00:00:00 2001 From: judy0131 Date: Tue, 11 Sep 2018 17:13:05 +0800 Subject: [PATCH 02/14] fix bug --- piflow-bundle/src/main/scala/cn/piflow/conf/bean/StopBean.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/piflow-bundle/src/main/scala/cn/piflow/conf/bean/StopBean.scala b/piflow-bundle/src/main/scala/cn/piflow/conf/bean/StopBean.scala index 373e09a..8c0f73f 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/conf/bean/StopBean.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/conf/bean/StopBean.scala @@ -39,7 +39,7 @@ class StopBean { case _ => throw new ClassNotFoundException(this.bundle + " is not found!!!") } } - case _ => throw new ClassNotFoundException(this.bundle + " is not found!!!") + case ex : Exception => throw ex } From 6b72da851895f113b2187fd977d5fb5177cbfd42 Mon Sep 17 00:00:00 2001 From: judy0131 Date: Wed, 12 Sep 2018 16:42:33 +0800 Subject: [PATCH 03/14] 1.return immediately when start flow, do not wait 2.fix stop flow bug --- .../src/main/scala/cn/piflow/api/API.scala | 4 ++-- ...tGet.scala => HTTPClientGetFlowInfo.scala} | 4 ++-- ...Client.scala => HTTPClientStartFlow.scala} | 4 ++-- .../cn/piflow/api/HTTPClientStopFlow.scala | 24 +++++++++++++++++++ .../scala/cn/piflow/api/HTTPService.scala | 16 +++++++++---- 5 files changed, 41 insertions(+), 11 deletions(-) rename piflow-server/src/main/scala/cn/piflow/api/{HTTPClientGet.scala => HTTPClientGetFlowInfo.scala} (85%) rename piflow-server/src/main/scala/cn/piflow/api/{HTTPClient.scala => HTTPClientStartFlow.scala} (96%) create mode 100644 piflow-server/src/main/scala/cn/piflow/api/HTTPClientStopFlow.scala diff --git a/piflow-server/src/main/scala/cn/piflow/api/API.scala b/piflow-server/src/main/scala/cn/piflow/api/API.scala index 36b596e..bc3b479 100644 --- a/piflow-server/src/main/scala/cn/piflow/api/API.scala +++ b/piflow-server/src/main/scala/cn/piflow/api/API.scala @@ -46,8 +46,8 @@ object API { .bind("checkpoint.path", PropertyUtil.getPropertyValue("checkpoint.path")) .start(flow); val applicationId = spark.sparkContext.applicationId - process.awaitTermination(); - spark.close(); + //process.awaitTermination(); + //spark.close(); (applicationId,process) } diff --git a/piflow-server/src/main/scala/cn/piflow/api/HTTPClientGet.scala b/piflow-server/src/main/scala/cn/piflow/api/HTTPClientGetFlowInfo.scala similarity index 85% rename from piflow-server/src/main/scala/cn/piflow/api/HTTPClientGet.scala rename to piflow-server/src/main/scala/cn/piflow/api/HTTPClientGetFlowInfo.scala index 0c3ea2e..9a3cf70 100644 --- a/piflow-server/src/main/scala/cn/piflow/api/HTTPClientGet.scala +++ b/piflow-server/src/main/scala/cn/piflow/api/HTTPClientGetFlowInfo.scala @@ -9,11 +9,11 @@ import org.apache.http.message.BasicNameValuePair import org.apache.http.util.EntityUtils import org.omg.CORBA.NameValuePair -object HTTPClientGet { +object HTTPClientGetFlowInfo { def main(args: Array[String]): Unit = { - val url = "http://10.0.86.98:8002/flow/info?appID=application_1536562610670_0001" + val url = "http://10.0.86.98:8001/flow/info?appID=application_1536562610670_0005" val client = HttpClients.createDefault() val getFlowInfo:HttpGet = new HttpGet(url) diff --git a/piflow-server/src/main/scala/cn/piflow/api/HTTPClient.scala b/piflow-server/src/main/scala/cn/piflow/api/HTTPClientStartFlow.scala similarity index 96% rename from piflow-server/src/main/scala/cn/piflow/api/HTTPClient.scala rename to piflow-server/src/main/scala/cn/piflow/api/HTTPClientStartFlow.scala index f16ce6c..3c37be0 100644 --- a/piflow-server/src/main/scala/cn/piflow/api/HTTPClient.scala +++ b/piflow-server/src/main/scala/cn/piflow/api/HTTPClientStartFlow.scala @@ -6,11 +6,11 @@ import org.apache.http.entity.StringEntity import org.apache.http.impl.client.HttpClients import org.apache.http.util.EntityUtils -object HTTPClient { +object HTTPClientStartFlow { def main(args: Array[String]): Unit = { val json = """{"flow":{"name":"test","uuid":"1234","stops":[{"uuid":"1111","name":"XmlParser","bundle":"cn.piflow.bundle.xml.XmlParser","properties":{"xmlpath":"hdfs://10.0.86.89:9000/xjzhu/dblp.mini.xml","rowTag":"phdthesis"}},{"uuid":"2222","name":"SelectField","bundle":"cn.piflow.bundle.common.SelectField","properties":{"schema":"title,author,pages"}},{"uuid":"3333","name":"PutHiveStreaming","bundle":"cn.piflow.bundle.hive.PutHiveStreaming","properties":{"database":"sparktest","table":"dblp_phdthesis"}},{"uuid":"4444","name":"CsvParser","bundle":"cn.piflow.bundle.csv.CsvParser","properties":{"csvPath":"hdfs://10.0.86.89:9000/xjzhu/phdthesis.csv","header":"false","delimiter":",","schema":"title,author,pages"}},{"uuid":"555","name":"Merge","bundle":"cn.piflow.bundle.common.Merge","properties":{}},{"uuid":"666","name":"Fork","bundle":"cn.piflow.bundle.common.Fork","properties":{"outports":["out1","out2","out3"]}},{"uuid":"777","name":"JsonSave","bundle":"cn.piflow.bundle.json.JsonSave","properties":{"jsonSavePath":"hdfs://10.0.86.89:9000/xjzhu/phdthesis.json"}},{"uuid":"888","name":"CsvSave","bundle":"cn.piflow.bundle.csv.CsvSave","properties":{"csvSavePath":"hdfs://10.0.86.89:9000/xjzhu/phdthesis_result.csv","header":"true","delimiter":","}}],"paths":[{"from":"XmlParser","outport":"","inport":"","to":"SelectField"},{"from":"SelectField","outport":"","inport":"data1","to":"Merge"},{"from":"CsvParser","outport":"","inport":"data2","to":"Merge"},{"from":"Merge","outport":"","inport":"","to":"Fork"},{"from":"Fork","outport":"out1","inport":"","to":"PutHiveStreaming"},{"from":"Fork","outport":"out2","inport":"","to":"JsonSave"},{"from":"Fork","outport":"out3","inport":"","to":"CsvSave"}]}}""" - val url = "http://10.0.86.98:8002/flow/start" + val url = "http://10.0.86.98:8001/flow/start" val client = HttpClients.createDefault() val post:HttpPost = new HttpPost(url) diff --git a/piflow-server/src/main/scala/cn/piflow/api/HTTPClientStopFlow.scala b/piflow-server/src/main/scala/cn/piflow/api/HTTPClientStopFlow.scala new file mode 100644 index 0000000..87f5788 --- /dev/null +++ b/piflow-server/src/main/scala/cn/piflow/api/HTTPClientStopFlow.scala @@ -0,0 +1,24 @@ +package cn.piflow.api + +import org.apache.http.client.methods.{CloseableHttpResponse, HttpPost} +import org.apache.http.entity.StringEntity +import org.apache.http.impl.client.HttpClients +import org.apache.http.util.EntityUtils + +object HTTPClientStopFlow { + def main(args: Array[String]): Unit = { + val json = """{"appID":"application_1536718350536_0023"}""" + val url = "http://10.0.86.98:8001/flow/stop" + val client = HttpClients.createDefault() + val post:HttpPost = new HttpPost(url) + + post.addHeader("Content-Type", "application/json") + post.setEntity(new StringEntity(json)) + + val response:CloseableHttpResponse = client.execute(post) + val entity = response.getEntity + val str = EntityUtils.toString(entity,"UTF-8") + println(str) + } + +} diff --git a/piflow-server/src/main/scala/cn/piflow/api/HTTPService.scala b/piflow-server/src/main/scala/cn/piflow/api/HTTPService.scala index b8b6458..79fa621 100644 --- a/piflow-server/src/main/scala/cn/piflow/api/HTTPService.scala +++ b/piflow-server/src/main/scala/cn/piflow/api/HTTPService.scala @@ -60,7 +60,7 @@ object HTTPService extends DefaultJsonProtocol with Directives with SprayJsonSup case HttpEntity.Strict(_, data) =>{ val flowJson = data.utf8String val (appId,process) = API.startFlow(flowJson) - processMap += (process.pid() -> process) + processMap += (appId -> process) Future.successful(HttpResponse(entity = appId)) } @@ -71,13 +71,19 @@ object HTTPService extends DefaultJsonProtocol with Directives with SprayJsonSup case HttpRequest(POST, Uri.Path("/flow/stop"), headers, entity, protocol) =>{ val data = toJson(entity) - val processId = data.get("processId").getOrElse("").asInstanceOf[String] - if(processId.equals("") || !processMap.contains(processId)){ + val appId = data.get("appID").getOrElse("").asInstanceOf[String] + if(appId.equals("") || !processMap.contains(appId)){ Future.failed(new Exception("Can not found process Error!")) }else{ - val result = API.stopFlow(processMap.get(processId).asInstanceOf[Process]) - Future.successful(HttpResponse(entity = result)) + processMap.get(appId) match { + case Some(process) => + val result = API.stopFlow(process.asInstanceOf[Process]) + Future.successful(HttpResponse(entity = result)) + case _ => + Future.successful(HttpResponse(entity = "Can not found process Error!")) + } + } } From 11a594d20c3f85b7ba9e30789164e55f76c96953 Mon Sep 17 00:00:00 2001 From: judy0131 Date: Thu, 13 Sep 2018 10:16:22 +0800 Subject: [PATCH 04/14] add yarn.jars config to solve the problem -->"Neither spark.yarn.jars nor spark.yarn.archive is set, falling back to uploading libraries under SPARK_HOME",which makes the spark on yarn job run very slow! --- conf/config.properties | 1 + piflow-server/src/main/scala/cn/piflow/api/API.scala | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/conf/config.properties b/conf/config.properties index 593ab0d..3becfa6 100644 --- a/conf/config.properties +++ b/conf/config.properties @@ -9,6 +9,7 @@ yarn.resourcemanager.hostname=10.0.86.191 yarn.resourcemanager.address=10.0.86.191:8032 yarn.access.namenode=hdfs://10.0.86.191:9000 yarn.stagingDir=hdfs://10.0.86.191:9000/tmp/ +yarn.jars=hdfs://10.0.86.191:9000/user/spark/share/lib/*.jar hive.metastore.uris=thrift://10.0.86.191:9083 diff --git a/piflow-server/src/main/scala/cn/piflow/api/API.scala b/piflow-server/src/main/scala/cn/piflow/api/API.scala index bc3b479..872f8d4 100644 --- a/piflow-server/src/main/scala/cn/piflow/api/API.scala +++ b/piflow-server/src/main/scala/cn/piflow/api/API.scala @@ -32,11 +32,12 @@ object API { .config("spark.hadoop.yarn.resourcemanager.address", PropertyUtil.getPropertyValue("yarn.resourcemanager.address")) .config("spark.yarn.access.namenode", PropertyUtil.getPropertyValue("yarn.access.namenode")) .config("spark.yarn.stagingDir", PropertyUtil.getPropertyValue("yarn.stagingDir")) + .config("spark.yarn.jars", PropertyUtil.getPropertyValue("yarn.jars")) //.config("spark.driver.memory", "1g") //.config("spark.executor.memory", "1g") //.config("spark.cores.max", "2") .config("spark.jars", PropertyUtil.getPropertyValue("piflow.bundle")) - .config("hive.metastore.uris",PropertyUtil.getPropertyValue("hive.metastore.uris")) + //.config("hive.metastore.uris",PropertyUtil.getPropertyValue("hive.metastore.uris")) .enableHiveSupport() .getOrCreate() From dd06ac6a43d7023585e7f73662c7a467c83f1459 Mon Sep 17 00:00:00 2001 From: judy0131 Date: Thu, 13 Sep 2018 10:35:41 +0800 Subject: [PATCH 05/14] add comment --- piflow-server/src/main/scala/cn/piflow/api/API.scala | 2 +- readMe.txt | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/piflow-server/src/main/scala/cn/piflow/api/API.scala b/piflow-server/src/main/scala/cn/piflow/api/API.scala index 872f8d4..5c196e1 100644 --- a/piflow-server/src/main/scala/cn/piflow/api/API.scala +++ b/piflow-server/src/main/scala/cn/piflow/api/API.scala @@ -37,7 +37,7 @@ object API { //.config("spark.executor.memory", "1g") //.config("spark.cores.max", "2") .config("spark.jars", PropertyUtil.getPropertyValue("piflow.bundle")) - //.config("hive.metastore.uris",PropertyUtil.getPropertyValue("hive.metastore.uris")) + .config("hive.metastore.uris",PropertyUtil.getPropertyValue("hive.metastore.uris")) .enableHiveSupport() .getOrCreate() diff --git a/readMe.txt b/readMe.txt index fa30ac1..72c4597 100644 --- a/readMe.txt +++ b/readMe.txt @@ -6,3 +6,6 @@ mvn install:install-file -Dfile=/opt/project/piflow/piflow-bundle/lib/spark-xml_ clean package -Dmaven.test.skip=true -U +3.set SPARK_HOME in Configurations + Edit Configurations --> Application(HttpService) --> Configurations --> Environment Variable + From c142c0352926b94413bf05b5d5aa38e52954a5c7 Mon Sep 17 00:00:00 2001 From: judy0131 Date: Fri, 14 Sep 2018 12:58:50 +0800 Subject: [PATCH 06/14] add get stop properties api --- .../piflow/conf/bean/PropertyDescriptor.scala | 19 ++++++++ .../scala/cn/piflow/conf/bean/StopBean.scala | 29 ++---------- .../scala/cn/piflow/conf/util/ClassUtil.scala | 46 +++++++++++++++---- .../cn/piflow/bundle/ClassFindTest.scala | 24 ++++++---- .../src/main/scala/cn/piflow/api/API.scala | 22 ++++++++- .../scala/cn/piflow/api/HTTPService.scala | 17 ++++++- .../api/HttpClientGetStopProperties.scala | 21 +++++++++ 7 files changed, 134 insertions(+), 44 deletions(-) create mode 100644 piflow-server/src/main/scala/cn/piflow/api/HttpClientGetStopProperties.scala diff --git a/piflow-bundle/src/main/scala/cn/piflow/conf/bean/PropertyDescriptor.scala b/piflow-bundle/src/main/scala/cn/piflow/conf/bean/PropertyDescriptor.scala index c4de27b..d6fc7a5 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/conf/bean/PropertyDescriptor.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/conf/bean/PropertyDescriptor.scala @@ -1,5 +1,8 @@ package cn.piflow.conf.bean +import net.liftweb.json.JsonDSL._ +import net.liftweb.json._ + class PropertyDescriptor { var name : String = _ var displayName : String = _ @@ -38,6 +41,22 @@ class PropertyDescriptor { this.sensitive = sensitive this } + def toJson():String = { + val allowableValueStr = if(this.allowableValues == null) "" else this.allowableValues.mkString(",") + val json = + ("property" -> + ("name" -> this.name) ~ + ("displayName" -> this.displayName) ~ + ("description" -> this.description) ~ + ("defaultValue" -> this.defaultValue) ~ + ("allowableValues" -> allowableValueStr) ~ + ("required" -> this.required.toString) ~ + ("sensitive" -> this.sensitive.toString)) + + + val jsonString = compactRender(json) + jsonString + } } object PropertyDescriptor{ diff --git a/piflow-bundle/src/main/scala/cn/piflow/conf/bean/StopBean.scala b/piflow-bundle/src/main/scala/cn/piflow/conf/bean/StopBean.scala index 8c0f73f..0825d04 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/conf/bean/StopBean.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/conf/bean/StopBean.scala @@ -19,33 +19,14 @@ class StopBean { } def constructStop() : ConfigurableStop = { - //val stop = Class.forName(this.bundle).getConstructor(classOf[Map[String, String]]).newInstance(this.properties) - /*val stop = Class.forName(this.bundle).newInstance() - stop.asInstanceOf[ConfigurableStop].setProperties(this.properties) - stop.asInstanceOf[ConfigurableStop]*/ + try{ - val stop = Class.forName(this.bundle).newInstance() - stop.asInstanceOf[ConfigurableStop].setProperties(this.properties) - stop.asInstanceOf[ConfigurableStop] - }catch{ - - case classNotFoundException:ClassNotFoundException =>{ - val stop : Option[ConfigurableStop] = ClassUtil.findConfigurableStop(this.bundle) - stop match { - case Some(s) => { - s.asInstanceOf[ConfigurableStop].setProperties(this.properties) - s.asInstanceOf[ConfigurableStop] - } - case _ => throw new ClassNotFoundException(this.bundle + " is not found!!!") - } - } + val stop = ClassUtil.findConfigurableStop(this.bundle) + stop.setProperties(this.properties) + stop + }catch { case ex : Exception => throw ex - - } - - - } } 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 9127af1..194cf54 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 @@ -3,6 +3,7 @@ package cn.piflow.conf.util import java.io.File import cn.piflow.conf.ConfigurableStop +import cn.piflow.conf.bean.PropertyDescriptor import org.clapper.classutil.ClassFinder @@ -11,11 +12,9 @@ object ClassUtil { val configurableStopClass:String = "cn.piflow.conf.ConfigurableStop" //val classpath:String = "/opt/project/piflow/classpath" - val classpath = System.getProperty("user.dir")+ "/classpath/" - - def findAllConfigurableStop() : List[String] = { + val classpath = System.getProperty("user.dir") var stopList : List[String] = List() val classpathFile = new File(classpath) @@ -35,8 +34,9 @@ object ClassUtil { stopList } - def findConfigurableStop(bundle : String) : Option[ConfigurableStop] = { + private def findConfigurableStopInClasspath(bundle : String) : Option[ConfigurableStop] = { + val classpath = System.getProperty("user.dir")+ "/classpath/" var stop:Option[ConfigurableStop] = None val classpathFile = new File(classpath) @@ -47,7 +47,6 @@ object ClassUtil { val plugins = ClassFinder.concreteSubclasses(configurableStopClass,classMap) plugins.foreach{ pluginClassInfo => - //println(pluginString.name) if(pluginClassInfo.name.equals(bundle)){ val plugin = Class.forName(pluginClassInfo.name).newInstance() stop = Some(plugin.asInstanceOf[ConfigurableStop]) @@ -57,15 +56,46 @@ object ClassUtil { stop } - def getJarFile(dir : File) : Seq[File] = { + private def getJarFile(dir : File) : Seq[File] = { val files = dir.listFiles.filter(! _.isDirectory).filter( _.toString.endsWith(".jar")) files ++ dir.listFiles().filter(_.isDirectory).flatMap(getJarFile) } + def findConfigurableStop(bundle : String) : ConfigurableStop = { + try{ + val stop = Class.forName(bundle).newInstance() + stop.asInstanceOf[ConfigurableStop] + }catch{ + + case classNotFoundException:ClassNotFoundException =>{ + val stop : Option[ConfigurableStop] = ClassUtil.findConfigurableStopInClasspath(bundle) + stop match { + case Some(s) => s.asInstanceOf[ConfigurableStop] + case _ => throw new ClassNotFoundException(bundle + " is not found!!!") + } + } + case ex : Exception => throw ex + } + } + + def findConfigurableStopPropertyDescriptor(bundle : String) : List[PropertyDescriptor] = { + val stopPropertyDesc = ClassUtil.findConfigurableStop(bundle) + stopPropertyDesc.getPropertyDescriptor() + } + + + /*def main(args: Array[String]): Unit = { //val stop = findConfigurableStop("cn.piflow.bundle.Class1") - val allConfigurableStopList = findAllConfigurableStop() - println("\n\n\n" + allConfigurableStopList) + //val allConfigurableStopList = findAllConfigurableStop() + val propertyDescriptorList = findConfigurableStopPropertyDescriptor("cn.piflow.bundle.ftp.LoadFromFtp") + var propertyJsonList = List[String]() + propertyDescriptorList.foreach( p => propertyJsonList = p.toJson() +: propertyJsonList ) + val start ="""{"properties":[""" + val end = """]}""" + val str = propertyJsonList.mkString(start, ",", end) + println(str) + }*/ } diff --git a/piflow-bundle/src/test/scala/cn/piflow/bundle/ClassFindTest.scala b/piflow-bundle/src/test/scala/cn/piflow/bundle/ClassFindTest.scala index 361c078..add38cf 100644 --- a/piflow-bundle/src/test/scala/cn/piflow/bundle/ClassFindTest.scala +++ b/piflow-bundle/src/test/scala/cn/piflow/bundle/ClassFindTest.scala @@ -44,14 +44,22 @@ class ClassFindTest { def testFindConfigurableStop() = { val bundle = "cn.piflow.bundle.hive.SelectHiveQL" val stop = findConfigurableStop(bundle) - stop match { - case Some(x) => { - println("Find " + x.getClass.toString + "!!!!!!!!") - //val propertiesDescList = x.getPropertyDescriptor() - //propertiesDescList.foreach(println(_)) - } - case _ => println("Can not find : " + bundle) - } + println("Find " + stop.getClass.toString + "!!!!!!!!") + + } + @Test + def testFindConfigurableStopClassPath() = { + val bundle = "cn.piflow.bundle.Class1" + val stop = findConfigurableStop(bundle) + println("Find " + stop.getClass.toString + "!!!!!!!!") + + } + @Test + def testFindConfigurableStopNotExist() = { + val bundle = "cn.piflow.bundle.Class5" + val stop = findConfigurableStop(bundle) + println("Find " + stop.getClass.toString + "!!!!!!!!") + } @Test diff --git a/piflow-server/src/main/scala/cn/piflow/api/API.scala b/piflow-server/src/main/scala/cn/piflow/api/API.scala index 5c196e1..c3e9975 100644 --- a/piflow-server/src/main/scala/cn/piflow/api/API.scala +++ b/piflow-server/src/main/scala/cn/piflow/api/API.scala @@ -1,15 +1,17 @@ package cn.piflow.api import cn.piflow.Runner -import cn.piflow.conf.bean.FlowBean +import cn.piflow.conf.bean.{FlowBean, PropertyDescriptor} import org.apache.spark.sql.SparkSession -import cn.piflow.conf.util.{FileUtil, OptionUtil} +import cn.piflow.conf.util.{ClassUtil, FileUtil, OptionUtil} import cn.piflow.Process import cn.piflow.api.util.PropertyUtil +import cn.piflow.conf.util.ClassUtil.findConfigurableStopPropertyDescriptor import org.apache.http.client.methods.{CloseableHttpResponse, HttpGet, HttpPost} import org.apache.http.impl.client.HttpClients import org.apache.http.util.EntityUtils + import scala.util.parsing.json.JSON object API { @@ -70,4 +72,20 @@ object API { str } + def getStopProperties(bundle : String) : String = { + try{ + + val propertyDescriptorList = findConfigurableStopPropertyDescriptor(bundle) + var propertyJsonList = List[String]() + propertyDescriptorList.foreach( p => propertyJsonList = p.toJson() +: propertyJsonList ) + val start ="""{"properties":[""" + val end = """]}""" + val str = propertyJsonList.mkString(start, ",", end) + str + }catch{ + case ex : Exception => println(ex);throw ex + } + + } + } diff --git a/piflow-server/src/main/scala/cn/piflow/api/HTTPService.scala b/piflow-server/src/main/scala/cn/piflow/api/HTTPService.scala index 79fa621..9287236 100644 --- a/piflow-server/src/main/scala/cn/piflow/api/HTTPService.scala +++ b/piflow-server/src/main/scala/cn/piflow/api/HTTPService.scala @@ -5,7 +5,6 @@ import java.util.concurrent.CompletionStage import akka.actor.ActorSystem import akka.http.scaladsl.Http - import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport import akka.http.scaladsl.model._ import akka.http.scaladsl.model.HttpMethods._ @@ -69,7 +68,7 @@ object HTTPService extends DefaultJsonProtocol with Directives with SprayJsonSup } - case HttpRequest(POST, Uri.Path("/flow/stop"), headers, entity, protocol) =>{ + case HttpRequest(POST, Uri.Path("/flow/stop"), headers, entity, protocol) =>{ val data = toJson(entity) val appId = data.get("appID").getOrElse("").asInstanceOf[String] if(appId.equals("") || !processMap.contains(appId)){ @@ -87,6 +86,20 @@ object HTTPService extends DefaultJsonProtocol with Directives with SprayJsonSup } } + case HttpRequest(GET, Uri.Path("/stop/properties"), headers, entity, protocol) =>{ + val bundle = req.getUri().query().getOrElse("bundle","") + if(bundle.equals("")){ + Future.failed(new Exception("Can not found bundle Error!")) + }else{ + try{ + val stopPropertyDescStr = API.getStopProperties(bundle) + Future.successful(HttpResponse(entity = stopPropertyDescStr)) + }catch { + case _ => Future.successful(HttpResponse(entity = "Can not found stop properties Error!")) + } + } + } + case _: HttpRequest => Future.successful(HttpResponse(404, entity = "Unknown resource!")) } diff --git a/piflow-server/src/main/scala/cn/piflow/api/HttpClientGetStopProperties.scala b/piflow-server/src/main/scala/cn/piflow/api/HttpClientGetStopProperties.scala new file mode 100644 index 0000000..8dece20 --- /dev/null +++ b/piflow-server/src/main/scala/cn/piflow/api/HttpClientGetStopProperties.scala @@ -0,0 +1,21 @@ +package cn.piflow.api + +import org.apache.http.client.methods.{CloseableHttpResponse, HttpGet} +import org.apache.http.impl.client.HttpClients +import org.apache.http.util.EntityUtils + +object HttpClientGetStopProperties { + + def main(args: Array[String]): Unit = { + + val url = "http://10.0.86.98:8001/stop/properties?bundle=cn.piflow.bundle.ftp.LoadFromFtp2" + val client = HttpClients.createDefault() + val getFlowInfo:HttpGet = new HttpGet(url) + + val response:CloseableHttpResponse = client.execute(getFlowInfo) + val entity = response.getEntity + val str = EntityUtils.toString(entity,"UTF-8") + println("Property Desc is " + str) + } + +} From e6c4b22e5aaad56080b38ae94fe6af3af8323290 Mon Sep 17 00:00:00 2001 From: judy0131 Date: Mon, 17 Sep 2018 14:10:51 +0800 Subject: [PATCH 07/14] add stop's author --- .../src/main/scala/cn/piflow/bundle/clean/EmailClean.scala | 1 + .../scala/cn/piflow/bundle/clean/IdentityNumberClean.scala | 1 + .../scala/cn/piflow/bundle/clean/PhoneNumberClean.scala | 1 + .../src/main/scala/cn/piflow/bundle/clean/TitleClean.scala | 1 + .../src/main/scala/cn/piflow/bundle/common/Fork.scala | 1 + .../src/main/scala/cn/piflow/bundle/common/Merge.scala | 1 + .../main/scala/cn/piflow/bundle/common/SelectField.scala | 1 + .../src/main/scala/cn/piflow/bundle/csv/CsvParser.scala | 1 + .../src/main/scala/cn/piflow/bundle/csv/CsvSave.scala | 1 + .../src/main/scala/cn/piflow/bundle/file/FetchFile.scala | 1 + .../src/main/scala/cn/piflow/bundle/file/PutFile.scala | 1 + .../scala/cn/piflow/bundle/file/RegexTextProcess.scala | 1 + .../src/main/scala/cn/piflow/bundle/ftp/LoadFromFtp.scala | 1 + .../src/main/scala/cn/piflow/bundle/ftp/UploadToFtp.scala | 1 + .../src/main/scala/cn/piflow/bundle/hive/PutHiveQL.scala | 1 + .../scala/cn/piflow/bundle/hive/PutHiveStreaming.scala | 1 + .../main/scala/cn/piflow/bundle/hive/SelectHiveQL.scala | 2 ++ .../main/scala/cn/piflow/bundle/http/LoadZipFromUrl.scala | 1 + .../src/main/scala/cn/piflow/bundle/http/UnGZip.scala | 1 + .../src/main/scala/cn/piflow/bundle/jdbc/JdbcRead.scala | 1 + .../src/main/scala/cn/piflow/bundle/jdbc/JdbcWrite.scala | 1 + .../src/main/scala/cn/piflow/bundle/json/JsonParser.scala | 7 ++++--- .../src/main/scala/cn/piflow/bundle/json/JsonSave.scala | 1 + .../scala/cn/piflow/bundle/script/DataFrameRowParser.scala | 1 + .../main/scala/cn/piflow/bundle/script/ShellExecutor.scala | 1 + .../main/scala/cn/piflow/bundle/xml/FolderXmlParser.scala | 1 + .../src/main/scala/cn/piflow/bundle/xml/XmlParser.scala | 1 + .../src/main/scala/cn/piflow/bundle/xml/XmlSave.scala | 1 + .../src/main/scala/cn/piflow/conf/ConfigurableStop.scala | 2 ++ 29 files changed, 34 insertions(+), 3 deletions(-) diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/EmailClean.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/EmailClean.scala index 25e611c..412132f 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/EmailClean.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/EmailClean.scala @@ -10,6 +10,7 @@ import cn.piflow.conf.util.MapUtil import org.apache.spark.sql.SparkSession class EmailClean extends ConfigurableStop{ + override val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 var columnName:String=_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/IdentityNumberClean.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/IdentityNumberClean.scala index 888db4e..0d8f06a 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/IdentityNumberClean.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/IdentityNumberClean.scala @@ -14,6 +14,7 @@ import org.apache.spark.sql.SparkSession import scala.reflect.macros.ParseException class IdentityNumberClean extends ConfigurableStop{ + override val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 //var regex:String =_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/PhoneNumberClean.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/PhoneNumberClean.scala index 584f958..05119eb 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/PhoneNumberClean.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/PhoneNumberClean.scala @@ -8,6 +8,7 @@ import cn.piflow.conf.util.MapUtil import org.apache.spark.sql.SparkSession class PhoneNumberClean extends ConfigurableStop{ + override val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 var columnName:String=_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/TitleClean.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/TitleClean.scala index 5a71533..7d709f6 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/TitleClean.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/TitleClean.scala @@ -8,6 +8,7 @@ import cn.piflow.conf.util.MapUtil import org.apache.spark.sql.SparkSession class TitleClean extends ConfigurableStop{ + override val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 var columnName:String=_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Fork.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Fork.scala index bf406f1..cde39f4 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Fork.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Fork.scala @@ -9,6 +9,7 @@ import scala.beans.BeanProperty class Fork extends ConfigurableStop{ + override val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 1 val outportCount: Int = -1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Merge.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Merge.scala index 95a86e1..267f328 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Merge.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Merge.scala @@ -8,6 +8,7 @@ import scala.beans.BeanProperty class Merge extends ConfigurableStop{ + override val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = -1 val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/SelectField.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/SelectField.scala index 380d7f7..1d23793 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/SelectField.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/SelectField.scala @@ -11,6 +11,7 @@ import scala.beans.BeanProperty class SelectField extends ConfigurableStop { + override val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 1 val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvParser.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvParser.scala index b84014a..59ca979 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvParser.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvParser.scala @@ -10,6 +10,7 @@ import org.apache.spark.sql.{DataFrame, SparkSession} class CsvParser extends ConfigurableStop{ + override val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvSave.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvSave.scala index 52cad43..c8041dd 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvSave.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvSave.scala @@ -7,6 +7,7 @@ import cn.piflow.conf.{ConfigurableStop, CsvGroup, StopGroup} import org.apache.spark.sql.SaveMode class CsvSave extends ConfigurableStop{ + override val authorEmail: String = "xjzhu@cnic.cn" override val inportCount: Int = 1 override val outportCount: Int = 0 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/file/FetchFile.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/file/FetchFile.scala index 5415d4d..06c475f 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/file/FetchFile.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/file/FetchFile.scala @@ -10,6 +10,7 @@ import org.apache.hadoop.conf.Configuration import org.apache.hadoop.fs.{FileSystem, Path} class FetchFile extends ConfigurableStop{ + override val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 var hdfs_path:String =_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/file/PutFile.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/file/PutFile.scala index 59f49d1..e94deea 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/file/PutFile.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/file/PutFile.scala @@ -13,6 +13,7 @@ import org.apache.hadoop.conf.Configuration import org.apache.spark.sql.SparkSession class PutFile extends ConfigurableStop{ + override val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 var hdfs_path:String =_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/file/RegexTextProcess.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/file/RegexTextProcess.scala index fef8dde..9b519bb 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/file/RegexTextProcess.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/file/RegexTextProcess.scala @@ -9,6 +9,7 @@ import org.apache.spark.sql.SparkSession class RegexTextProcess extends ConfigurableStop{ + override val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 var regex:String =_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/LoadFromFtp.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/LoadFromFtp.scala index 0ac1425..a1abb7b 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/LoadFromFtp.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/LoadFromFtp.scala @@ -13,6 +13,7 @@ import sun.net.ftp.{FtpClient, FtpDirEntry} import scala.reflect.io.Directory class LoadFromFtp extends ConfigurableStop{ + override val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 var url_str:String =_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/UploadToFtp.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/UploadToFtp.scala index e926d85..2a639ad 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/UploadToFtp.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/UploadToFtp.scala @@ -13,6 +13,7 @@ import sun.net.ftp.{FtpClient, FtpDirEntry} import scala.reflect.io.Directory class UploadToFtp extends ConfigurableStop{ + override val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 var url_str:String =_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveQL.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveQL.scala index ca82554..460891f 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveQL.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveQL.scala @@ -8,6 +8,7 @@ import org.apache.spark.sql.SparkSession class PutHiveQL extends ConfigurableStop { + override val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveStreaming.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveStreaming.scala index 3b98f85..95edd9c 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveStreaming.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveStreaming.scala @@ -10,6 +10,7 @@ import scala.beans.BeanProperty class PutHiveStreaming extends ConfigurableStop { + override val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 1 val outportCount: Int = 0 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/SelectHiveQL.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/SelectHiveQL.scala index 62f1dee..6573ff8 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/SelectHiveQL.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/SelectHiveQL.scala @@ -13,6 +13,7 @@ import scala.beans.BeanProperty class SelectHiveQL extends ConfigurableStop { + override val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 @@ -51,6 +52,7 @@ class SelectHiveQL extends ConfigurableStop { HiveGroup } + } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/http/LoadZipFromUrl.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/http/LoadZipFromUrl.scala index 038a10a..b5b5e9e 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/http/LoadZipFromUrl.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/http/LoadZipFromUrl.scala @@ -10,6 +10,7 @@ import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} import org.apache.spark.sql.SparkSession class LoadZipFromUrl extends ConfigurableStop{ + override val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 var url_str:String =_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/http/UnGZip.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/http/UnGZip.scala index b254c74..dc36621 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/http/UnGZip.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/http/UnGZip.scala @@ -11,6 +11,7 @@ import org.apache.commons.compress.archivers.tar.{TarArchiveEntry, TarArchiveInp import org.apache.spark.sql.{DataFrame, SparkSession} class UnGZip extends ConfigurableStop { + override val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 val fileTypes:List[String]=List("tar.gz","tar","gz") diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcRead.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcRead.scala index 7493e33..ed7857b 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcRead.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcRead.scala @@ -9,6 +9,7 @@ import org.apache.spark.sql.SparkSession import scala.beans.BeanProperty class JdbcRead extends ConfigurableStop { + override val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcWrite.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcWrite.scala index 3faed33..abdeda3 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcWrite.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcWrite.scala @@ -12,6 +12,7 @@ import scala.beans.BeanProperty class JdbcWrite extends ConfigurableStop{ + override val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 1 val outportCount: Int = 0 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonParser.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonParser.scala index 281d9c6..d7814b3 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonParser.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonParser.scala @@ -10,8 +10,9 @@ import scala.beans.BeanProperty class JsonPathParser extends ConfigurableStop{ - @BeanProperty val inportCount: Int = 1 - @BeanProperty val outportCount: Int = 1 + override val authorEmail: String = "xjzhu@cnic.cn" + val inportCount: Int = 1 + val outportCount: Int = 1 var jsonPath: String = _ var tag : String = _ @@ -47,7 +48,7 @@ class JsonPathParser extends ConfigurableStop{ } class JsonStringParser extends ConfigurableStop{ - + override val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 1 val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonSave.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonSave.scala index f5a63b4..f2457b3 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonSave.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonSave.scala @@ -10,6 +10,7 @@ import scala.beans.BeanProperty class JsonSave extends ConfigurableStop{ + override val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 1 val outportCount: Int = 0 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/script/DataFrameRowParser.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/script/DataFrameRowParser.scala index 48d3010..1727a64 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/script/DataFrameRowParser.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/script/DataFrameRowParser.scala @@ -11,6 +11,7 @@ import scala.beans.BeanProperty class DataFrameRowParser extends ConfigurableStop{ + override val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 1 val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/script/ShellExecutor.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/script/ShellExecutor.scala index 5131387..37c9c47 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/script/ShellExecutor.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/script/ShellExecutor.scala @@ -12,6 +12,7 @@ import sys.process._ class ShellExecutor extends ConfigurableStop{ + override val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/FolderXmlParser.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/FolderXmlParser.scala index 3257f2a..e485932 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/FolderXmlParser.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/FolderXmlParser.scala @@ -17,6 +17,7 @@ import scala.util.control.Breaks._ * Created by admin on 2018/8/27. */ class FolderXmlParser extends ConfigurableStop{ + override val authorEmail: String = "lijie" override val inportCount: Int = -1 override val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlParser.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlParser.scala index cf47385..8f92393 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlParser.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlParser.scala @@ -11,6 +11,7 @@ import scala.beans.BeanProperty class XmlParser extends ConfigurableStop { + override val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 1 val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlSave.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlSave.scala index f44c071..27c2e3a 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlSave.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlSave.scala @@ -10,6 +10,7 @@ import scala.beans.BeanProperty class XmlSave extends ConfigurableStop{ + override val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 1 val outportCount: Int = 0 diff --git a/piflow-bundle/src/main/scala/cn/piflow/conf/ConfigurableStop.scala b/piflow-bundle/src/main/scala/cn/piflow/conf/ConfigurableStop.scala index eb02d9b..95fce37 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/conf/ConfigurableStop.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/conf/ConfigurableStop.scala @@ -6,9 +6,11 @@ import cn.piflow.conf.bean.PropertyDescriptor trait ConfigurableStop extends Stop{ + val authorEmail : String val inportCount : Int val outportCount : Int + def setProperties(map: Map[String, Any]) def getPropertyDescriptor() : List[PropertyDescriptor] From 08079e198527e3b75103efaf7c29a8ca4ef226c2 Mon Sep 17 00:00:00 2001 From: judy0131 Date: Mon, 17 Sep 2018 15:13:36 +0800 Subject: [PATCH 08/14] add wait process terminate Runnable --- piflow-server/src/main/scala/cn/piflow/api/API.scala | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/piflow-server/src/main/scala/cn/piflow/api/API.scala b/piflow-server/src/main/scala/cn/piflow/api/API.scala index c3e9975..0babe70 100644 --- a/piflow-server/src/main/scala/cn/piflow/api/API.scala +++ b/piflow-server/src/main/scala/cn/piflow/api/API.scala @@ -51,6 +51,7 @@ object API { val applicationId = spark.sparkContext.applicationId //process.awaitTermination(); //spark.close(); + new Thread( new WaitProcessTerminateRunnable(spark, process)).start() (applicationId,process) } @@ -89,3 +90,10 @@ object API { } } + +class WaitProcessTerminateRunnable(spark : SparkSession, process: Process) extends Runnable { + override def run(): Unit = { + process.awaitTermination() + spark.close() + } +} From e2b2df0418eec911671d3ca351ea41289b49d98b Mon Sep 17 00:00:00 2001 From: judy0131 Date: Tue, 25 Sep 2018 16:31:55 +0800 Subject: [PATCH 09/14] 1.modify ConfigurableStop getGroup api 2.modify findAllConfigurableStop 3.add findAllGroups --- classpath/piflow-external.jar | Bin 219056 -> 7137 bytes piflow-bundle/pom.xml | 11 +++ .../cn/piflow/bundle/clean/EmailClean.scala | 6 +- .../bundle/clean/IdentityNumberClean.scala | 7 +- .../bundle/clean/PhoneNumberClean.scala | 6 +- .../cn/piflow/bundle/clean/TitleClean.scala | 6 +- .../scala/cn/piflow/bundle/common/Fork.scala | 6 +- .../scala/cn/piflow/bundle/common/Merge.scala | 6 +- .../cn/piflow/bundle/common/SelectField.scala | 6 +- .../cn/piflow/bundle/csv/CsvParser.scala | 6 +- .../scala/cn/piflow/bundle/csv/CsvSave.scala | 6 +- .../cn/piflow/bundle/file/FetchFile.scala | 6 +- .../scala/cn/piflow/bundle/file/PutFile.scala | 6 +- .../piflow/bundle/file/RegexTextProcess.scala | 6 +- .../cn/piflow/bundle/ftp/LoadFromFtp.scala | 6 +- .../cn/piflow/bundle/ftp/UploadToFtp.scala | 9 ++- .../cn/piflow/bundle/hive/PutHiveQL.scala | 6 +- .../piflow/bundle/hive/PutHiveStreaming.scala | 7 +- .../cn/piflow/bundle/hive/SelectHiveQL.scala | 6 +- .../piflow/bundle/http/LoadZipFromUrl.scala | 7 +- .../scala/cn/piflow/bundle/http/UnGZip.scala | 6 +- .../cn/piflow/bundle/jdbc/JdbcRead.scala | 6 +- .../cn/piflow/bundle/jdbc/JdbcWrite.scala | 7 +- .../cn/piflow/bundle/json/JsonParser.scala | 12 ++-- .../cn/piflow/bundle/json/JsonSave.scala | 7 +- .../bundle/script/DataFrameRowParser.scala | 7 +- .../piflow/bundle/script/ShellExecutor.scala | 6 +- .../piflow/bundle/xml/FolderXmlParser.scala | 6 +- .../cn/piflow/bundle/xml/XmlParser.scala | 6 +- .../scala/cn/piflow/bundle/xml/XmlSave.scala | 6 +- .../cn/piflow/conf/ConfigurableStop.scala | 2 +- .../scala/cn/piflow/conf/StopGroupEnum.scala | 18 +++++ .../scala/cn/piflow/conf/util/ClassUtil.scala | 64 +++++++++++++++--- pom.xml | 4 +- 34 files changed, 182 insertions(+), 100 deletions(-) create mode 100644 piflow-bundle/src/main/scala/cn/piflow/conf/StopGroupEnum.scala diff --git a/classpath/piflow-external.jar b/classpath/piflow-external.jar index 445ae833ac85213796bb6f36afd1fb9381c3e272..4425d62804df65b0e58056a5d313dc467ef892b1 100644 GIT binary patch literal 7137 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 literal 219056 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%0A{haK0)Vt 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%0DX8@w1#8D_|O_#1DiR@3K9D!e{{+`0oH; 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

365K6_QS$KS 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 X=YuwaUaSfLu#4Vzk(EIU$c6PUA+$kR diff --git a/piflow-bundle/pom.xml b/piflow-bundle/pom.xml index ff10e6c..3480ac9 100644 --- a/piflow-bundle/pom.xml +++ b/piflow-bundle/pom.xml @@ -26,6 +26,17 @@ org.clapper classutil_2.11 1.3.0 + + + + org.reflections + reflections + 0.9.11 + + + com.chuusai + shapeless_2.11 + 2.3.1 com.sksamuel.scrimage diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/EmailClean.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/EmailClean.scala index 412132f..5769950 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/EmailClean.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/EmailClean.scala @@ -4,7 +4,7 @@ import java.beans.Transient import cn.piflow.bundle.util.CleanUtil import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} -import cn.piflow.conf.{CleanGroup,ConfigurableStop, StopGroup} +import cn.piflow.conf.{CleanGroup, ConfigurableStop, StopGroup, StopGroupEnum} import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import org.apache.spark.sql.SparkSession @@ -47,8 +47,8 @@ class EmailClean extends ConfigurableStop{ override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - CleanGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.CleanGroup.toString) } } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/IdentityNumberClean.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/IdentityNumberClean.scala index 0d8f06a..ed6ba18 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/IdentityNumberClean.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/IdentityNumberClean.scala @@ -6,7 +6,7 @@ import java.util.{Calendar, Date} import cn.piflow.bundle.util.CleanUtil import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} -import cn.piflow.conf.{CleanGroup, ConfigurableStop, FileGroup, StopGroup} +import cn.piflow.conf._ import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import org.apache.spark.sql.SparkSession @@ -52,8 +52,7 @@ class IdentityNumberClean extends ConfigurableStop{ override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - CleanGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.CleanGroup.toString) } - } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/PhoneNumberClean.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/PhoneNumberClean.scala index 05119eb..84ebc42 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/PhoneNumberClean.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/PhoneNumberClean.scala @@ -2,7 +2,7 @@ package cn.piflow.bundle.clean import cn.piflow.bundle.util.CleanUtil import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} -import cn.piflow.conf.{CleanGroup, ConfigurableStop, StopGroup} +import cn.piflow.conf.{CleanGroup, ConfigurableStop, StopGroup, StopGroupEnum} import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import org.apache.spark.sql.SparkSession @@ -46,8 +46,8 @@ class PhoneNumberClean extends ConfigurableStop{ override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - CleanGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.CleanGroup.toString) } } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/TitleClean.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/TitleClean.scala index 7d709f6..cc590fe 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/TitleClean.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/TitleClean.scala @@ -2,7 +2,7 @@ package cn.piflow.bundle.clean import cn.piflow.bundle.util.CleanUtil import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} -import cn.piflow.conf.{CleanGroup, ConfigurableStop, StopGroup} +import cn.piflow.conf.{CleanGroup, ConfigurableStop, StopGroup, StopGroupEnum} import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import org.apache.spark.sql.SparkSession @@ -44,8 +44,8 @@ class TitleClean extends ConfigurableStop{ override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - CleanGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.CleanGroup.toString) } } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Fork.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Fork.scala index cde39f4..491a900 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Fork.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Fork.scala @@ -1,6 +1,6 @@ package cn.piflow.bundle.common -import cn.piflow.conf.{CommonGroup, ConfigurableStop, StopGroup} +import cn.piflow.conf.{CommonGroup, ConfigurableStop, StopGroup, StopGroupEnum} import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} @@ -31,8 +31,8 @@ class Fork extends ConfigurableStop{ override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - CommonGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.CommonGroup.toString) } } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Merge.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Merge.scala index 267f328..1a6eb9b 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Merge.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Merge.scala @@ -1,6 +1,6 @@ package cn.piflow.bundle.common -import cn.piflow.conf.{CommonGroup, ConfigurableStop, StopGroup} +import cn.piflow.conf.{CommonGroup, ConfigurableStop, StopGroup, StopGroupEnum} import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} @@ -30,8 +30,8 @@ class Merge extends ConfigurableStop{ override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - CommonGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.CommonGroup.toString) } } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/SelectField.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/SelectField.scala index 1d23793..3e60fb5 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/SelectField.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/SelectField.scala @@ -1,7 +1,7 @@ package cn.piflow.bundle.common import cn.piflow._ -import cn.piflow.conf.{CommonGroup, ConfigurableStop, StopGroup} +import cn.piflow.conf.{CommonGroup, ConfigurableStop, StopGroup, StopGroupEnum} import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import org.apache.spark.sql.{Column, DataFrame} @@ -45,8 +45,8 @@ class SelectField extends ConfigurableStop { override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - CommonGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.CommonGroup.toString) } } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvParser.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvParser.scala index 59ca979..5fb6117 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvParser.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvParser.scala @@ -1,7 +1,7 @@ package cn.piflow.bundle.csv import cn.piflow._ -import cn.piflow.conf.{ConfigurableStop, CsvGroup, HiveGroup, StopGroup} +import cn.piflow.conf._ import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import org.apache.spark.sql.types.{StringType, StructField, StructType} @@ -69,8 +69,8 @@ class CsvParser extends ConfigurableStop{ override def getIcon(): Array[Byte] = ??? - def getGroup() : StopGroup = { - CsvGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.CsvGroup.toString) } } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvSave.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvSave.scala index c8041dd..5e339de 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvSave.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvSave.scala @@ -3,7 +3,7 @@ package cn.piflow.bundle.csv import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.{ImageUtil, MapUtil} import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} -import cn.piflow.conf.{ConfigurableStop, CsvGroup, StopGroup} +import cn.piflow.conf.{ConfigurableStop, CsvGroup, StopGroup, StopGroupEnum} import org.apache.spark.sql.SaveMode class CsvSave extends ConfigurableStop{ @@ -43,8 +43,8 @@ class CsvSave extends ConfigurableStop{ ImageUtil.getImage("./src/main/resources/selectHiveQL.jpg") } - override def getGroup(): StopGroup = { - CsvGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.CsvGroup.toString) } override def initialize(ctx: ProcessContext): Unit = { diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/file/FetchFile.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/file/FetchFile.scala index 06c475f..339df31 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/file/FetchFile.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/file/FetchFile.scala @@ -3,7 +3,7 @@ package cn.piflow.bundle.file import java.net.URI import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} -import cn.piflow.conf.{ConfigurableStop, FileGroup, StopGroup} +import cn.piflow.conf.{ConfigurableStop, FileGroup, StopGroup, StopGroupEnum} import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import org.apache.hadoop.conf.Configuration @@ -54,8 +54,8 @@ class FetchFile extends ConfigurableStop{ override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - FileGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.FileGroup.toString) } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/file/PutFile.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/file/PutFile.scala index e94deea..9c9433d 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/file/PutFile.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/file/PutFile.scala @@ -6,7 +6,7 @@ import java.net.{HttpURLConnection, URI, URL} import org.apache.hadoop.fs.FileSystem import org.apache.hadoop.fs.Path import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} -import cn.piflow.conf.{ConfigurableStop, FileGroup, StopGroup} +import cn.piflow.conf.{ConfigurableStop, FileGroup, StopGroup, StopGroupEnum} import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import org.apache.hadoop.conf.Configuration @@ -57,8 +57,8 @@ class PutFile extends ConfigurableStop{ override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - FileGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.FileGroup.toString) } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/file/RegexTextProcess.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/file/RegexTextProcess.scala index 9b519bb..8c80fc1 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/file/RegexTextProcess.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/file/RegexTextProcess.scala @@ -3,7 +3,7 @@ package cn.piflow.bundle.file import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} -import cn.piflow.conf.{ConfigurableStop, FileGroup, StopGroup} +import cn.piflow.conf.{ConfigurableStop, FileGroup, StopGroup, StopGroupEnum} import org.apache.spark.sql.SparkSession @@ -56,7 +56,7 @@ class RegexTextProcess extends ConfigurableStop{ override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - FileGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.FileGroup.toString) } } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/LoadFromFtp.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/LoadFromFtp.scala index a1abb7b..f5728f5 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/LoadFromFtp.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/LoadFromFtp.scala @@ -5,7 +5,7 @@ import java.net.{HttpURLConnection, URL} import java.util import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} -import cn.piflow.conf.{ConfigurableStop, FtpGroup, HttpGroup, StopGroup} +import cn.piflow.conf.{ConfigurableStop, FtpGroup, HttpGroup, StopGroup, StopGroupEnum} import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import sun.net.ftp.{FtpClient, FtpDirEntry} @@ -156,8 +156,8 @@ class LoadFromFtp extends ConfigurableStop{ override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - FtpGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.FtpGroup.toString) } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/UploadToFtp.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/UploadToFtp.scala index 2a639ad..2db23c0 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/UploadToFtp.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/UploadToFtp.scala @@ -4,7 +4,7 @@ import java.io.{DataOutputStream, File, InputStream, OutputStream} import java.util import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} -import cn.piflow.conf.{ConfigurableStop, FtpGroup, StopGroup} +import cn.piflow.conf.{ConfigurableStop, FtpGroup, StopGroup, StopGroupEnum} import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import sun.net.TelnetOutputStream @@ -170,8 +170,7 @@ class UploadToFtp extends ConfigurableStop{ override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - FtpGroup - } - + override def getGroup(): List[String] = { + List(StopGroupEnum.FtpGroup.toString) + } } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveQL.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveQL.scala index 460891f..77dd709 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveQL.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveQL.scala @@ -2,7 +2,7 @@ package cn.piflow.bundle.hive import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil -import cn.piflow.conf.{ConfigurableStop, HiveGroup, StopGroup} +import cn.piflow.conf.{ConfigurableStop, HiveGroup, StopGroup, StopGroupEnum} import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} import org.apache.spark.sql.SparkSession @@ -57,8 +57,8 @@ class PutHiveQL extends ConfigurableStop { override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - HiveGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.HiveGroup.toString) } } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveStreaming.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveStreaming.scala index 95edd9c..8a73821 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveStreaming.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveStreaming.scala @@ -1,7 +1,7 @@ package cn.piflow.bundle.hive import cn.piflow._ -import cn.piflow.conf.{ConfigurableStop, HiveGroup, StopGroup} +import cn.piflow.conf.{ConfigurableStop, HiveGroup, StopGroup, StopGroupEnum} import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import org.apache.spark.sql.SparkSession @@ -41,8 +41,9 @@ class PutHiveStreaming extends ConfigurableStop { override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - HiveGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.HiveGroup.toString) } + } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/SelectHiveQL.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/SelectHiveQL.scala index 6573ff8..b66f8e2 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/SelectHiveQL.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/SelectHiveQL.scala @@ -2,7 +2,7 @@ package cn.piflow.bundle.hive import cn.piflow._ import cn.piflow.conf.util.ImageUtil -import cn.piflow.conf.{ConfigurableStop, HiveGroup, StopGroup} +import cn.piflow.conf.{ConfigurableStop, HiveGroup, StopGroup, StopGroupEnum} import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.{ImageUtil, MapUtil} import org.apache.spark.sql.SparkSession @@ -48,8 +48,8 @@ class SelectHiveQL extends ConfigurableStop { ImageUtil.getImage("./src/main/resources/selectHiveQL.jpg") } - override def getGroup(): StopGroup = { - HiveGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.HiveGroup.toString) } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/http/LoadZipFromUrl.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/http/LoadZipFromUrl.scala index b5b5e9e..fefd11d 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/http/LoadZipFromUrl.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/http/LoadZipFromUrl.scala @@ -3,7 +3,7 @@ package cn.piflow.bundle.http import java.io._ import java.net.{HttpURLConnection, URL} -import cn.piflow.conf.{ConfigurableStop, HttpGroup, StopGroup} +import cn.piflow.conf.{ConfigurableStop, HttpGroup, StopGroup, StopGroupEnum} import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} @@ -82,8 +82,9 @@ class LoadZipFromUrl extends ConfigurableStop{ override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - HttpGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.HttpGroup.toString) } + } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/http/UnGZip.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/http/UnGZip.scala index dc36621..c0fa8df 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/http/UnGZip.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/http/UnGZip.scala @@ -4,7 +4,7 @@ import java.io.{ByteArrayInputStream, File, FileInputStream, FileOutputStream} import java.lang.Exception import java.util.zip.GZIPInputStream -import cn.piflow.conf.{ConfigurableStop, HiveGroup, HttpGroup, StopGroup} +import cn.piflow.conf._ import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} import org.apache.commons.compress.archivers.tar.{TarArchiveEntry, TarArchiveInputStream} @@ -208,8 +208,8 @@ class UnGZip extends ConfigurableStop { override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - HttpGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.HttpGroup.toString) } } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcRead.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcRead.scala index ed7857b..2290f06 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcRead.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcRead.scala @@ -1,7 +1,7 @@ package cn.piflow.bundle.jdbc import cn.piflow._ -import cn.piflow.conf.{ConfigurableStop, JdbcGroup, StopGroup} +import cn.piflow.conf.{ConfigurableStop, JdbcGroup, StopGroup, StopGroupEnum} import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import org.apache.spark.sql.SparkSession @@ -51,8 +51,8 @@ class JdbcRead extends ConfigurableStop { override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - JdbcGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.JdbcGroup.toString) } } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcWrite.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcWrite.scala index abdeda3..2c0ef2b 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcWrite.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcWrite.scala @@ -3,7 +3,7 @@ package cn.piflow.bundle.jdbc import java.util.Properties import cn.piflow._ -import cn.piflow.conf.{ConfigurableStop, JdbcGroup, StopGroup} +import cn.piflow.conf.{ConfigurableStop, JdbcGroup, StopGroup, StopGroupEnum} import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import org.apache.spark.sql.{SaveMode, SparkSession} @@ -47,8 +47,9 @@ class JdbcWrite extends ConfigurableStop{ override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - JdbcGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.JdbcGroup.toString) } + } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonParser.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonParser.scala index d7814b3..929bc27 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonParser.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonParser.scala @@ -1,7 +1,7 @@ package cn.piflow.bundle.json import cn.piflow._ -import cn.piflow.conf.{ConfigurableStop, JsonGroup, StopGroup} +import cn.piflow.conf.{ConfigurableStop, JsonGroup, StopGroup, StopGroupEnum} import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import org.apache.spark.sql.SparkSession @@ -41,10 +41,11 @@ class JsonPathParser extends ConfigurableStop{ override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - JsonGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.JsonGroup.toString) } + } class JsonStringParser extends ConfigurableStop{ @@ -76,8 +77,9 @@ class JsonStringParser extends ConfigurableStop{ override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - JsonGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.JsonGroup.toString) } + } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonSave.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonSave.scala index f2457b3..c15a18c 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonSave.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonSave.scala @@ -1,7 +1,7 @@ package cn.piflow.bundle.json import cn.piflow._ -import cn.piflow.conf.{ConfigurableStop, JsonGroup, StopGroup} +import cn.piflow.conf.{ConfigurableStop, JsonGroup, StopGroup, StopGroupEnum} import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import org.apache.spark.sql.SaveMode @@ -36,8 +36,9 @@ class JsonSave extends ConfigurableStop{ override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - JsonGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.JsonGroup.toString) } + } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/script/DataFrameRowParser.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/script/DataFrameRowParser.scala index 1727a64..8882ed2 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/script/DataFrameRowParser.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/script/DataFrameRowParser.scala @@ -2,7 +2,7 @@ package cn.piflow.bundle.script import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.{ImageUtil, MapUtil} -import cn.piflow.conf.{CommonGroup, ConfigurableStop, ScriptGroup, StopGroup} +import cn.piflow.conf._ import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} import org.apache.spark.sql.types.{StringType, StructField, StructType} import org.apache.spark.sql.{Row, SparkSession} @@ -29,10 +29,11 @@ class DataFrameRowParser extends ConfigurableStop{ ImageUtil.getImage("./src/main/resources/DataFrameParse.jpg") } - override def getGroup(): StopGroup = { - ScriptGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.ScriptGroup.toString) } + override def initialize(ctx: ProcessContext): Unit = {} override def perform(in: JobInputStream, out: JobOutputStream, pec: JobContext): Unit = { diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/script/ShellExecutor.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/script/ShellExecutor.scala index 37c9c47..2b77657 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/script/ShellExecutor.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/script/ShellExecutor.scala @@ -3,7 +3,7 @@ package cn.piflow.bundle.script import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.{ImageUtil, MapUtil} import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} -import cn.piflow.conf.{ConfigurableStop, ScriptGroup, StopGroup} +import cn.piflow.conf.{ConfigurableStop, ScriptGroup, StopGroup, StopGroupEnum} import org.apache.spark.sql.{Row, SparkSession} import org.apache.spark.sql.types.{StringType, StructField, StructType} @@ -33,8 +33,8 @@ class ShellExecutor extends ConfigurableStop{ ImageUtil.getImage("./src/main/resources/ShellExecutor.jpg") } - override def getGroup(): StopGroup = { - ScriptGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.ScriptGroup.toString) } override def initialize(ctx: ProcessContext): Unit = { diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/FolderXmlParser.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/FolderXmlParser.scala index e485932..154196b 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/FolderXmlParser.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/FolderXmlParser.scala @@ -4,7 +4,7 @@ import java.net.URI import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil -import cn.piflow.conf.{ConfigurableStop, StopGroup, XmlGroup} +import cn.piflow.conf.{ConfigurableStop, StopGroup, StopGroupEnum, XmlGroup} import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} import org.apache.hadoop.conf.Configuration import org.apache.hadoop.fs.{FileSystem, Path} @@ -45,8 +45,8 @@ class FolderXmlParser extends ConfigurableStop{ override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - XmlGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.XmlGroup.toString) } override def initialize(ctx: ProcessContext): Unit ={} diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlParser.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlParser.scala index 8f92393..cde5e46 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlParser.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlParser.scala @@ -1,7 +1,7 @@ package cn.piflow.bundle.xml import cn.piflow._ -import cn.piflow.conf.{ConfigurableStop, StopGroup, XmlGroup} +import cn.piflow.conf.{ConfigurableStop, StopGroup, StopGroupEnum, XmlGroup} import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import org.apache.spark.sql.SparkSession @@ -50,8 +50,8 @@ class XmlParser extends ConfigurableStop { override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - XmlGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.XmlGroup.toString) } } diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlSave.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlSave.scala index 27c2e3a..522ea54 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlSave.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlSave.scala @@ -1,7 +1,7 @@ package cn.piflow.bundle.xml import cn.piflow._ -import cn.piflow.conf.{ConfigurableStop, StopGroup, XmlGroup} +import cn.piflow.conf.{ConfigurableStop, StopGroup, StopGroupEnum, XmlGroup} import cn.piflow.conf.bean.PropertyDescriptor import cn.piflow.conf.util.MapUtil import org.codehaus.jackson.map.ext.CoreXMLSerializers.XMLGregorianCalendarSerializer @@ -35,8 +35,8 @@ class XmlSave extends ConfigurableStop{ override def getIcon(): Array[Byte] = ??? - override def getGroup(): StopGroup = { - XmlGroup + override def getGroup(): List[String] = { + List(StopGroupEnum.XmlGroup.toString) } } diff --git a/piflow-bundle/src/main/scala/cn/piflow/conf/ConfigurableStop.scala b/piflow-bundle/src/main/scala/cn/piflow/conf/ConfigurableStop.scala index 95fce37..1f15704 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/conf/ConfigurableStop.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/conf/ConfigurableStop.scala @@ -17,6 +17,6 @@ trait ConfigurableStop extends Stop{ def getIcon() : Array[Byte] - def getGroup() : StopGroup + def getGroup() : List[String] } diff --git a/piflow-bundle/src/main/scala/cn/piflow/conf/StopGroupEnum.scala b/piflow-bundle/src/main/scala/cn/piflow/conf/StopGroupEnum.scala new file mode 100644 index 0000000..8761aad --- /dev/null +++ b/piflow-bundle/src/main/scala/cn/piflow/conf/StopGroupEnum.scala @@ -0,0 +1,18 @@ +package cn.piflow.conf + +object StopGroupEnum extends Enumeration { + + type StopGroup = Value + val CommonGroup = Value("CommonGroup") + val CsvGroup = Value("CsvGroup") + val HiveGroup = Value("HiveGroup") + val JdbcGroup = Value("JdbcGroup") + val JsonGroup = Value("JsonGroup") + val XmlGroup = Value("XmlGroup") + val HttpGroup = Value("HttpGroup") + val FtpGroup = Value("FtpGroup") + val ScriptGroup = Value("ScriptGroup") + val FileGroup = Value("FileGroup") + val CleanGroup = Value("CleanGroup") + +} 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 194cf54..dce45f8 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 @@ -5,6 +5,7 @@ import java.io.File import cn.piflow.conf.ConfigurableStop import cn.piflow.conf.bean.PropertyDescriptor import org.clapper.classutil.ClassFinder +import org.reflections.Reflections object ClassUtil { @@ -12,7 +13,7 @@ object ClassUtil { val configurableStopClass:String = "cn.piflow.conf.ConfigurableStop" //val classpath:String = "/opt/project/piflow/classpath" - def findAllConfigurableStop() : List[String] = { + /*def findAllConfigurableStop() : List[String] = { val classpath = System.getProperty("user.dir") var stopList : List[String] = List() @@ -32,6 +33,51 @@ object ClassUtil { } stopList + }*/ + + def findAllConfigurableStop() : List[ConfigurableStop] = { + var stopList:List[ConfigurableStop] = List() + + //find internal stop + val reflections = new Reflections("") + val allClasses = reflections.getSubTypesOf(classOf[ConfigurableStop]) + val it = allClasses.iterator(); + while(it.hasNext) { + val plugin = Class.forName(it.next().getName).newInstance() + val stop = plugin.asInstanceOf[ConfigurableStop] + stopList = stop +: stopList + } + + //find external stop + stopList = stopList ::: findAllConfigurableStopInClasspath() + stopList + } + + + private def findAllConfigurableStopInClasspath() : List[ConfigurableStop] = { + + val classpath = System.getProperty("user.dir")+ "/classpath/" + var stopList:List[ConfigurableStop] = List() + + val classpathFile = new File(classpath) + println("classpath is " + classpath) + val finder = ClassFinder(getJarFile(classpathFile)) + val classes = finder.getClasses + val classMap = ClassFinder.classInfoMap(classes) + val plugins = ClassFinder.concreteSubclasses(configurableStopClass,classMap) + plugins.foreach{ + pluginClassInfo => + val plugin = Class.forName(pluginClassInfo.name).newInstance() + stopList = plugin.asInstanceOf[ConfigurableStop] +: stopList + } + stopList + } + + def findAllGroups() : List[String] = { + + val stoplist = findAllConfigurableStop(); + val groupList = stoplist.flatMap(_.getGroup()).distinct + groupList } private def findConfigurableStopInClasspath(bundle : String) : Option[ConfigurableStop] = { @@ -57,7 +103,7 @@ object ClassUtil { } private def getJarFile(dir : File) : Seq[File] = { - val files = dir.listFiles.filter(! _.isDirectory).filter( _.toString.endsWith(".jar")) + val files = dir.listFiles.filter(! _.isDirectory).filter( _.toString.endsWith(".jar")).filter(_.toString.contains("piflow")) files ++ dir.listFiles().filter(_.isDirectory).flatMap(getJarFile) } @@ -83,19 +129,21 @@ object ClassUtil { stopPropertyDesc.getPropertyDescriptor() } - - - /*def main(args: Array[String]): Unit = { + def main(args: Array[String]): Unit = { //val stop = findConfigurableStop("cn.piflow.bundle.Class1") //val allConfigurableStopList = findAllConfigurableStop() - val propertyDescriptorList = findConfigurableStopPropertyDescriptor("cn.piflow.bundle.ftp.LoadFromFtp") + /*val propertyDescriptorList = findConfigurableStopPropertyDescriptor("cn.piflow.bundle.Xjzhu") var propertyJsonList = List[String]() propertyDescriptorList.foreach( p => propertyJsonList = p.toJson() +: propertyJsonList ) val start ="""{"properties":[""" val end = """]}""" val str = propertyJsonList.mkString(start, ",", end) - println(str) + println(str)*/ + //println(findAllGroups()); - }*/ + val stoplist = findAllGroups(); + println(stoplist) + + } } diff --git a/pom.xml b/pom.xml index 69bde91..ad7d777 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ spark-yarn_2.11 ${spark.version} - + From 4c3385ea9fcefd257873acb93247ee50e5216aa1 Mon Sep 17 00:00:00 2001 From: judy0131 Date: Tue, 25 Sep 2018 17:35:11 +0800 Subject: [PATCH 10/14] add stop groups api --- .../src/main/scala/cn/piflow/api/API.scala | 23 +++++++++++++++++-- .../cn/piflow/api/HTTPClientGetGroups.scala | 21 +++++++++++++++++ .../scala/cn/piflow/api/HTTPService.scala | 10 ++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 piflow-server/src/main/scala/cn/piflow/api/HTTPClientGetGroups.scala diff --git a/piflow-server/src/main/scala/cn/piflow/api/API.scala b/piflow-server/src/main/scala/cn/piflow/api/API.scala index 0babe70..f57a65b 100644 --- a/piflow-server/src/main/scala/cn/piflow/api/API.scala +++ b/piflow-server/src/main/scala/cn/piflow/api/API.scala @@ -10,7 +10,7 @@ import cn.piflow.conf.util.ClassUtil.findConfigurableStopPropertyDescriptor import org.apache.http.client.methods.{CloseableHttpResponse, HttpGet, HttpPost} import org.apache.http.impl.client.HttpClients import org.apache.http.util.EntityUtils - +import org.apache.spark.launcher.SparkLauncher import scala.util.parsing.json.JSON @@ -53,6 +53,20 @@ object API { //spark.close(); new Thread( new WaitProcessTerminateRunnable(spark, process)).start() (applicationId,process) + + /*val launcher = new SparkLauncher + launcher.setMaster(PropertyUtil.getPropertyValue("spark.master")) + .setAppName("test") + .setDeployMode(PropertyUtil.getPropertyValue("spark.deploy.mode")) + .setConf("spark.hadoop.yarn.resourcemanager.hostname", PropertyUtil.getPropertyValue("yarn.resourcemanager.hostname")) + .setConf("spark.hadoop.yarn.resourcemanager.address", PropertyUtil.getPropertyValue("yarn.resourcemanager.address")).setConf("spark.yarn.access.namenode", PropertyUtil.getPropertyValue("yarn.access.namenode")) + .setConf("spark.yarn.stagingDir", PropertyUtil.getPropertyValue("yarn.stagingDir")) + .setConf("spark.yarn.jars", PropertyUtil.getPropertyValue("yarn.jars")) + .setConf("spark.jars", PropertyUtil.getPropertyValue("piflow.bundle")) + .setConf("hive.metastore.uris", PropertyUtil.getPropertyValue("hive.metastore.uris")) + .setMainClass("lalla") + .addAppArgs(flowJson)*/ + } def stopFlow(process : Process): String = { @@ -89,11 +103,16 @@ object API { } + def getAllGroups() = { + val groups = ClassUtil.findAllGroups().mkString(",") + """{"groups":"""" + groups + """"}""" + } + } class WaitProcessTerminateRunnable(spark : SparkSession, process: Process) extends Runnable { override def run(): Unit = { process.awaitTermination() - spark.close() + //spark.close() } } diff --git a/piflow-server/src/main/scala/cn/piflow/api/HTTPClientGetGroups.scala b/piflow-server/src/main/scala/cn/piflow/api/HTTPClientGetGroups.scala new file mode 100644 index 0000000..c554eb1 --- /dev/null +++ b/piflow-server/src/main/scala/cn/piflow/api/HTTPClientGetGroups.scala @@ -0,0 +1,21 @@ +package cn.piflow.api + +import org.apache.http.client.methods.{CloseableHttpResponse, HttpGet} +import org.apache.http.impl.client.HttpClients +import org.apache.http.util.EntityUtils + +object HTTPClientGetGroups { + + def main(args: Array[String]): Unit = { + + val url = "http://10.0.86.98:8001/stop/groups" + val client = HttpClients.createDefault() + val getGroups:HttpGet = new HttpGet(url) + + val response:CloseableHttpResponse = client.execute(getGroups) + val entity = response.getEntity + val str = EntityUtils.toString(entity,"UTF-8") + println("Groups is: " + str) + } + +} diff --git a/piflow-server/src/main/scala/cn/piflow/api/HTTPService.scala b/piflow-server/src/main/scala/cn/piflow/api/HTTPService.scala index 9287236..8be709c 100644 --- a/piflow-server/src/main/scala/cn/piflow/api/HTTPService.scala +++ b/piflow-server/src/main/scala/cn/piflow/api/HTTPService.scala @@ -98,6 +98,16 @@ object HTTPService extends DefaultJsonProtocol with Directives with SprayJsonSup case _ => Future.successful(HttpResponse(entity = "Can not found stop properties Error!")) } } + } + case HttpRequest(GET, Uri.Path("/stop/groups"), headers, entity, protocol) =>{ + + try{ + val stopGroups = API.getAllGroups() + Future.successful(HttpResponse(entity = stopGroups)) + }catch { + case _ => Future.successful(HttpResponse(entity = "Can not found stop properties Error!")) + } + } case _: HttpRequest => From fd2ef07acd48039c2afb4cbe59fb4358214d9926 Mon Sep 17 00:00:00 2001 From: judy0131 Date: Tue, 25 Sep 2018 18:07:34 +0800 Subject: [PATCH 11/14] add stop info api --- .../cn/piflow/bundle/hive/SelectHiveQL.scala | 2 +- .../scala/cn/piflow/conf/util/ClassUtil.scala | 33 +++++++++++++++++-- .../src/main/scala/cn/piflow/api/API.scala | 9 ++--- .../scala/cn/piflow/api/HTTPService.scala | 6 ++-- ...ties.scala => HttpClientGetStopInfo.scala} | 4 +-- 5 files changed, 39 insertions(+), 15 deletions(-) rename piflow-server/src/main/scala/cn/piflow/api/{HttpClientGetStopProperties.scala => HttpClientGetStopInfo.scala} (79%) diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/SelectHiveQL.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/SelectHiveQL.scala index b66f8e2..f6accf4 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/SelectHiveQL.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/SelectHiveQL.scala @@ -39,7 +39,7 @@ class SelectHiveQL extends ConfigurableStop { override def getPropertyDescriptor(): List[PropertyDescriptor] = { var descriptor : List[PropertyDescriptor] = List() - val hiveQL = new PropertyDescriptor().name("hiveQL").displayName("HiveQL").defaultValue("").required(true) + val hiveQL = new PropertyDescriptor().name("hiveQL").displayName("HiveQL").defaultValue("").allowableValues(Set("")).required(true) descriptor = hiveQL :: descriptor descriptor } 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 dce45f8..b37ec88 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 @@ -4,8 +4,11 @@ import java.io.File import cn.piflow.conf.ConfigurableStop import cn.piflow.conf.bean.PropertyDescriptor +import net.liftweb.json.compactRender import org.clapper.classutil.ClassFinder import org.reflections.Reflections +import net.liftweb.json.JsonDSL._ +import net.liftweb.json._ object ClassUtil { @@ -129,6 +132,29 @@ object ClassUtil { stopPropertyDesc.getPropertyDescriptor() } + def findConfigurableStopInfo(bundle : String) : String = { + val stop = ClassUtil.findConfigurableStop(bundle) + val propertyDescriptorList:List[PropertyDescriptor] = stop.getPropertyDescriptor() + + val json = + ("StopInfo" -> + ("owner" -> stop.authorEmail) ~ + ("inportCount" -> stop.inportCount) ~ + ("outportCount" -> stop.outportCount) ~ + ("groups" -> stop.getGroup().mkString(",")) ~ + ("properties" -> + propertyDescriptorList.map { property =>( + ("name" -> property.name) ~ + ("displayName" -> property.displayName) ~ + ("description" -> property.description) ~ + ("defaultValue" -> property.defaultValue) ~ + ("allowableValues" -> property.allowableValues) ~ + ("required" -> property.required.toString) ~ + ("sensitive" -> property.sensitive.toString)) }) ) + val jsonString = compactRender(json) + jsonString + } + def main(args: Array[String]): Unit = { //val stop = findConfigurableStop("cn.piflow.bundle.Class1") //val allConfigurableStopList = findAllConfigurableStop() @@ -139,10 +165,13 @@ object ClassUtil { val end = """]}""" val str = propertyJsonList.mkString(start, ",", end) println(str)*/ + + val stop = findConfigurableStopInClasspath("cn.piflow.bundle.Xjzhu") + val temp = 1 //println(findAllGroups()); - val stoplist = findAllGroups(); - println(stoplist) + //val stoplist = findAllGroups(); + //println(stoplist) } diff --git a/piflow-server/src/main/scala/cn/piflow/api/API.scala b/piflow-server/src/main/scala/cn/piflow/api/API.scala index f57a65b..79272d2 100644 --- a/piflow-server/src/main/scala/cn/piflow/api/API.scala +++ b/piflow-server/src/main/scala/cn/piflow/api/API.scala @@ -87,15 +87,10 @@ object API { str } - def getStopProperties(bundle : String) : String = { + def getStopInfo(bundle : String) : String = { try{ - val propertyDescriptorList = findConfigurableStopPropertyDescriptor(bundle) - var propertyJsonList = List[String]() - propertyDescriptorList.foreach( p => propertyJsonList = p.toJson() +: propertyJsonList ) - val start ="""{"properties":[""" - val end = """]}""" - val str = propertyJsonList.mkString(start, ",", end) + val str = ClassUtil.findConfigurableStopInfo(bundle) str }catch{ case ex : Exception => println(ex);throw ex diff --git a/piflow-server/src/main/scala/cn/piflow/api/HTTPService.scala b/piflow-server/src/main/scala/cn/piflow/api/HTTPService.scala index 8be709c..408fd8e 100644 --- a/piflow-server/src/main/scala/cn/piflow/api/HTTPService.scala +++ b/piflow-server/src/main/scala/cn/piflow/api/HTTPService.scala @@ -86,14 +86,14 @@ object HTTPService extends DefaultJsonProtocol with Directives with SprayJsonSup } } - case HttpRequest(GET, Uri.Path("/stop/properties"), headers, entity, protocol) =>{ + case HttpRequest(GET, Uri.Path("/stop/info"), headers, entity, protocol) =>{ val bundle = req.getUri().query().getOrElse("bundle","") if(bundle.equals("")){ Future.failed(new Exception("Can not found bundle Error!")) }else{ try{ - val stopPropertyDescStr = API.getStopProperties(bundle) - Future.successful(HttpResponse(entity = stopPropertyDescStr)) + val stopInfo = API.getStopInfo(bundle) + Future.successful(HttpResponse(entity = stopInfo)) }catch { case _ => Future.successful(HttpResponse(entity = "Can not found stop properties Error!")) } diff --git a/piflow-server/src/main/scala/cn/piflow/api/HttpClientGetStopProperties.scala b/piflow-server/src/main/scala/cn/piflow/api/HttpClientGetStopInfo.scala similarity index 79% rename from piflow-server/src/main/scala/cn/piflow/api/HttpClientGetStopProperties.scala rename to piflow-server/src/main/scala/cn/piflow/api/HttpClientGetStopInfo.scala index 8dece20..748fb71 100644 --- a/piflow-server/src/main/scala/cn/piflow/api/HttpClientGetStopProperties.scala +++ b/piflow-server/src/main/scala/cn/piflow/api/HttpClientGetStopInfo.scala @@ -4,11 +4,11 @@ import org.apache.http.client.methods.{CloseableHttpResponse, HttpGet} import org.apache.http.impl.client.HttpClients import org.apache.http.util.EntityUtils -object HttpClientGetStopProperties { +object HttpClientGetStopInfo { def main(args: Array[String]): Unit = { - val url = "http://10.0.86.98:8001/stop/properties?bundle=cn.piflow.bundle.ftp.LoadFromFtp2" + val url = "http://10.0.86.98:8001/stop/info?bundle=cn.piflow.bundle.hive.SelectHiveQL" val client = HttpClients.createDefault() val getFlowInfo:HttpGet = new HttpGet(url) From 9102bf97bb7a2e15da2de4679c5e9a4344460a24 Mon Sep 17 00:00:00 2001 From: judy0131 Date: Wed, 26 Sep 2018 17:49:32 +0800 Subject: [PATCH 12/14] fix bug: can not find user defined Configurable Stop --- classpath/piflow-external.jar | Bin 7137 -> 7069 bytes piflow-bundle/pom.xml | 5 -- .../cn/piflow/bundle/clean/EmailClean.scala | 2 +- .../bundle/clean/IdentityNumberClean.scala | 2 +- .../bundle/clean/PhoneNumberClean.scala | 2 +- .../cn/piflow/bundle/clean/TitleClean.scala | 2 +- .../scala/cn/piflow/bundle/common/Fork.scala | 2 +- .../scala/cn/piflow/bundle/common/Merge.scala | 2 +- .../cn/piflow/bundle/common/SelectField.scala | 2 +- .../cn/piflow/bundle/csv/CsvParser.scala | 2 +- .../scala/cn/piflow/bundle/csv/CsvSave.scala | 6 +- .../cn/piflow/bundle/file/FetchFile.scala | 2 +- .../scala/cn/piflow/bundle/file/PutFile.scala | 2 +- .../piflow/bundle/file/RegexTextProcess.scala | 2 +- .../cn/piflow/bundle/ftp/LoadFromFtp.scala | 2 +- .../cn/piflow/bundle/ftp/UploadToFtp.scala | 2 +- .../cn/piflow/bundle/hive/PutHiveQL.scala | 2 +- .../piflow/bundle/hive/PutHiveStreaming.scala | 2 +- .../cn/piflow/bundle/hive/SelectHiveQL.scala | 2 +- .../piflow/bundle/http/LoadZipFromUrl.scala | 2 +- .../scala/cn/piflow/bundle/http/UnGZip.scala | 2 +- .../cn/piflow/bundle/jdbc/JdbcRead.scala | 2 +- .../cn/piflow/bundle/jdbc/JdbcWrite.scala | 2 +- .../cn/piflow/bundle/json/JsonParser.scala | 4 +- .../cn/piflow/bundle/json/JsonSave.scala | 2 +- .../bundle/script/DataFrameRowParser.scala | 2 +- .../piflow/bundle/script/ShellExecutor.scala | 2 +- .../piflow/bundle/xml/FolderXmlParser.scala | 6 +- .../cn/piflow/bundle/xml/XmlParser.scala | 2 +- .../scala/cn/piflow/bundle/xml/XmlSave.scala | 2 +- .../cn/piflow/conf/ConfigurableStop.scala | 2 +- .../scala/cn/piflow/conf/util/ClassUtil.scala | 55 +++++++++++++----- 32 files changed, 75 insertions(+), 53 deletions(-) diff --git a/classpath/piflow-external.jar b/classpath/piflow-external.jar index 4425d62804df65b0e58056a5d313dc467ef892b1..5633af9eee9f6377df3376d1ba957fc71ffbf4f5 100644 GIT binary patch delta 6613 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 delta 6700 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 R{WVi3MUdkni<14j{$G?i*yjKM diff --git a/piflow-bundle/pom.xml b/piflow-bundle/pom.xml index 3480ac9..8c6112f 100644 --- a/piflow-bundle/pom.xml +++ b/piflow-bundle/pom.xml @@ -16,11 +16,6 @@ piflow-core 0.9 - org.clapper diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/EmailClean.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/EmailClean.scala index 5769950..c2adf1e 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/EmailClean.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/EmailClean.scala @@ -10,7 +10,7 @@ import cn.piflow.conf.util.MapUtil import org.apache.spark.sql.SparkSession class EmailClean extends ConfigurableStop{ - override val authorEmail: String = "xiaoxiao@cnic.cn" + val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 var columnName:String=_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/IdentityNumberClean.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/IdentityNumberClean.scala index ed6ba18..2ae4560 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/IdentityNumberClean.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/IdentityNumberClean.scala @@ -14,7 +14,7 @@ import org.apache.spark.sql.SparkSession import scala.reflect.macros.ParseException class IdentityNumberClean extends ConfigurableStop{ - override val authorEmail: String = "xiaoxiao@cnic.cn" + val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 //var regex:String =_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/PhoneNumberClean.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/PhoneNumberClean.scala index 84ebc42..5864f01 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/PhoneNumberClean.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/PhoneNumberClean.scala @@ -8,7 +8,7 @@ import cn.piflow.conf.util.MapUtil import org.apache.spark.sql.SparkSession class PhoneNumberClean extends ConfigurableStop{ - override val authorEmail: String = "xiaoxiao@cnic.cn" + val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 var columnName:String=_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/TitleClean.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/TitleClean.scala index cc590fe..fa413b6 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/TitleClean.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/clean/TitleClean.scala @@ -8,7 +8,7 @@ import cn.piflow.conf.util.MapUtil import org.apache.spark.sql.SparkSession class TitleClean extends ConfigurableStop{ - override val authorEmail: String = "xiaoxiao@cnic.cn" + val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 var columnName:String=_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Fork.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Fork.scala index 491a900..94d5fbf 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Fork.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Fork.scala @@ -9,7 +9,7 @@ import scala.beans.BeanProperty class Fork extends ConfigurableStop{ - override val authorEmail: String = "xjzhu@cnic.cn" + val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 1 val outportCount: Int = -1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Merge.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Merge.scala index 1a6eb9b..a042581 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Merge.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/Merge.scala @@ -8,7 +8,7 @@ import scala.beans.BeanProperty class Merge extends ConfigurableStop{ - override val authorEmail: String = "xjzhu@cnic.cn" + val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = -1 val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/SelectField.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/SelectField.scala index 3e60fb5..e9deaac 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/common/SelectField.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/common/SelectField.scala @@ -11,7 +11,7 @@ import scala.beans.BeanProperty class SelectField extends ConfigurableStop { - override val authorEmail: String = "xjzhu@cnic.cn" + val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 1 val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvParser.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvParser.scala index 5fb6117..02bb4de 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvParser.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvParser.scala @@ -10,7 +10,7 @@ import org.apache.spark.sql.{DataFrame, SparkSession} class CsvParser extends ConfigurableStop{ - override val authorEmail: String = "xjzhu@cnic.cn" + val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvSave.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvSave.scala index 5e339de..4f01cb2 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvSave.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/csv/CsvSave.scala @@ -7,9 +7,9 @@ import cn.piflow.conf.{ConfigurableStop, CsvGroup, StopGroup, StopGroupEnum} import org.apache.spark.sql.SaveMode class CsvSave extends ConfigurableStop{ - override val authorEmail: String = "xjzhu@cnic.cn" - override val inportCount: Int = 1 - override val outportCount: Int = 0 + val authorEmail: String = "xjzhu@cnic.cn" + val inportCount: Int = 1 + val outportCount: Int = 0 var csvSavePath: String = _ var header: Boolean = _ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/file/FetchFile.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/file/FetchFile.scala index 339df31..95cc489 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/file/FetchFile.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/file/FetchFile.scala @@ -10,7 +10,7 @@ import org.apache.hadoop.conf.Configuration import org.apache.hadoop.fs.{FileSystem, Path} class FetchFile extends ConfigurableStop{ - override val authorEmail: String = "xiaoxiao@cnic.cn" + val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 var hdfs_path:String =_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/file/PutFile.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/file/PutFile.scala index 9c9433d..b4460a7 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/file/PutFile.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/file/PutFile.scala @@ -13,7 +13,7 @@ import org.apache.hadoop.conf.Configuration import org.apache.spark.sql.SparkSession class PutFile extends ConfigurableStop{ - override val authorEmail: String = "xiaoxiao@cnic.cn" + val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 var hdfs_path:String =_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/file/RegexTextProcess.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/file/RegexTextProcess.scala index 8c80fc1..00fb7d8 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/file/RegexTextProcess.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/file/RegexTextProcess.scala @@ -9,7 +9,7 @@ import org.apache.spark.sql.SparkSession class RegexTextProcess extends ConfigurableStop{ - override val authorEmail: String = "xiaoxiao@cnic.cn" + val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 var regex:String =_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/LoadFromFtp.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/LoadFromFtp.scala index f5728f5..8e60bb3 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/LoadFromFtp.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/LoadFromFtp.scala @@ -13,7 +13,7 @@ import sun.net.ftp.{FtpClient, FtpDirEntry} import scala.reflect.io.Directory class LoadFromFtp extends ConfigurableStop{ - override val authorEmail: String = "xiaoxiao@cnic.cn" + val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 var url_str:String =_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/UploadToFtp.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/UploadToFtp.scala index 2db23c0..ce7e89f 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/UploadToFtp.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/ftp/UploadToFtp.scala @@ -13,7 +13,7 @@ import sun.net.ftp.{FtpClient, FtpDirEntry} import scala.reflect.io.Directory class UploadToFtp extends ConfigurableStop{ - override val authorEmail: String = "xiaoxiao@cnic.cn" + val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 var url_str:String =_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveQL.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveQL.scala index 77dd709..a7d5e5a 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveQL.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveQL.scala @@ -8,7 +8,7 @@ import org.apache.spark.sql.SparkSession class PutHiveQL extends ConfigurableStop { - override val authorEmail: String = "xiaoxiao@cnic.cn" + val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveStreaming.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveStreaming.scala index 8a73821..449aec8 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveStreaming.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/PutHiveStreaming.scala @@ -10,7 +10,7 @@ import scala.beans.BeanProperty class PutHiveStreaming extends ConfigurableStop { - override val authorEmail: String = "xjzhu@cnic.cn" + val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 1 val outportCount: Int = 0 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/SelectHiveQL.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/SelectHiveQL.scala index f6accf4..4235ef6 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/SelectHiveQL.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/hive/SelectHiveQL.scala @@ -13,7 +13,7 @@ import scala.beans.BeanProperty class SelectHiveQL extends ConfigurableStop { - override val authorEmail: String = "xjzhu@cnic.cn" + val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/http/LoadZipFromUrl.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/http/LoadZipFromUrl.scala index fefd11d..25c1906 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/http/LoadZipFromUrl.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/http/LoadZipFromUrl.scala @@ -10,7 +10,7 @@ import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext} import org.apache.spark.sql.SparkSession class LoadZipFromUrl extends ConfigurableStop{ - override val authorEmail: String = "xiaoxiao@cnic.cn" + val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 var url_str:String =_ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/http/UnGZip.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/http/UnGZip.scala index c0fa8df..57864b9 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/http/UnGZip.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/http/UnGZip.scala @@ -11,7 +11,7 @@ import org.apache.commons.compress.archivers.tar.{TarArchiveEntry, TarArchiveInp import org.apache.spark.sql.{DataFrame, SparkSession} class UnGZip extends ConfigurableStop { - override val authorEmail: String = "xiaoxiao@cnic.cn" + val authorEmail: String = "xiaoxiao@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 val fileTypes:List[String]=List("tar.gz","tar","gz") diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcRead.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcRead.scala index 2290f06..7e0a52c 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcRead.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcRead.scala @@ -9,7 +9,7 @@ import org.apache.spark.sql.SparkSession import scala.beans.BeanProperty class JdbcRead extends ConfigurableStop { - override val authorEmail: String = "xjzhu@cnic.cn" + val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcWrite.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcWrite.scala index 2c0ef2b..081a936 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcWrite.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/jdbc/JdbcWrite.scala @@ -12,7 +12,7 @@ import scala.beans.BeanProperty class JdbcWrite extends ConfigurableStop{ - override val authorEmail: String = "xjzhu@cnic.cn" + val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 1 val outportCount: Int = 0 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonParser.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonParser.scala index 929bc27..cce204d 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonParser.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonParser.scala @@ -10,7 +10,7 @@ import scala.beans.BeanProperty class JsonPathParser extends ConfigurableStop{ - override val authorEmail: String = "xjzhu@cnic.cn" + val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 1 val outportCount: Int = 1 @@ -49,7 +49,7 @@ class JsonPathParser extends ConfigurableStop{ } class JsonStringParser extends ConfigurableStop{ - override val authorEmail: String = "xjzhu@cnic.cn" + val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 1 val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonSave.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonSave.scala index c15a18c..0f42dab 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonSave.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/json/JsonSave.scala @@ -10,7 +10,7 @@ import scala.beans.BeanProperty class JsonSave extends ConfigurableStop{ - override val authorEmail: String = "xjzhu@cnic.cn" + val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 1 val outportCount: Int = 0 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/script/DataFrameRowParser.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/script/DataFrameRowParser.scala index 8882ed2..c54b222 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/script/DataFrameRowParser.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/script/DataFrameRowParser.scala @@ -11,7 +11,7 @@ import scala.beans.BeanProperty class DataFrameRowParser extends ConfigurableStop{ - override val authorEmail: String = "xjzhu@cnic.cn" + val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 1 val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/script/ShellExecutor.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/script/ShellExecutor.scala index 2b77657..b3353f6 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/script/ShellExecutor.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/script/ShellExecutor.scala @@ -12,7 +12,7 @@ import sys.process._ class ShellExecutor extends ConfigurableStop{ - override val authorEmail: String = "xjzhu@cnic.cn" + val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 0 val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/FolderXmlParser.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/FolderXmlParser.scala index 154196b..53de666 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/FolderXmlParser.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/FolderXmlParser.scala @@ -17,9 +17,9 @@ import scala.util.control.Breaks._ * Created by admin on 2018/8/27. */ class FolderXmlParser extends ConfigurableStop{ - override val authorEmail: String = "lijie" - override val inportCount: Int = -1 - override val outportCount: Int = 1 + val authorEmail: String = "lijie" + val inportCount: Int = -1 + val outportCount: Int = 1 var rowTag:String = _ var xmlpath:String = _ diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlParser.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlParser.scala index cde5e46..586e84a 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlParser.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlParser.scala @@ -11,7 +11,7 @@ import scala.beans.BeanProperty class XmlParser extends ConfigurableStop { - override val authorEmail: String = "xjzhu@cnic.cn" + val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 1 val outportCount: Int = 1 diff --git a/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlSave.scala b/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlSave.scala index 522ea54..b8c64fa 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlSave.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/bundle/xml/XmlSave.scala @@ -10,7 +10,7 @@ import scala.beans.BeanProperty class XmlSave extends ConfigurableStop{ - override val authorEmail: String = "xjzhu@cnic.cn" + val authorEmail: String = "xjzhu@cnic.cn" val inportCount: Int = 1 val outportCount: Int = 0 diff --git a/piflow-bundle/src/main/scala/cn/piflow/conf/ConfigurableStop.scala b/piflow-bundle/src/main/scala/cn/piflow/conf/ConfigurableStop.scala index 1f15704..f02fa27 100644 --- a/piflow-bundle/src/main/scala/cn/piflow/conf/ConfigurableStop.scala +++ b/piflow-bundle/src/main/scala/cn/piflow/conf/ConfigurableStop.scala @@ -4,7 +4,7 @@ import cn.piflow.Stop import cn.piflow.conf.bean.PropertyDescriptor -trait ConfigurableStop extends Stop{ +abstract class ConfigurableStop extends Stop{ val authorEmail : String val inportCount : Int 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 b37ec88..7fa8a6a 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 @@ -16,7 +16,7 @@ object ClassUtil { val configurableStopClass:String = "cn.piflow.conf.ConfigurableStop" //val classpath:String = "/opt/project/piflow/classpath" - /*def findAllConfigurableStop() : List[String] = { + /*def findAllConfigurableStopByClassFinder() : List[String] = { val classpath = System.getProperty("user.dir") var stopList : List[String] = List() @@ -63,17 +63,29 @@ object ClassUtil { var stopList:List[ConfigurableStop] = List() val classpathFile = new File(classpath) - println("classpath is " + classpath) + //println("classpath is " + classpath) val finder = ClassFinder(getJarFile(classpathFile)) val classes = finder.getClasses - val classMap = ClassFinder.classInfoMap(classes) + val it = classes.iterator + + while(it.hasNext) { + val externalClass = it.next() + if(externalClass.superClassName.equals(configurableStopClass)){ + + val stopIntance = Class.forName(externalClass.name).newInstance() + stopList = stopIntance.asInstanceOf[ConfigurableStop] +: stopList + } + } + stopList + + /*val classMap = ClassFinder.classInfoMap(classes) val plugins = ClassFinder.concreteSubclasses(configurableStopClass,classMap) plugins.foreach{ pluginClassInfo => val plugin = Class.forName(pluginClassInfo.name).newInstance() stopList = plugin.asInstanceOf[ConfigurableStop] +: stopList } - stopList + stopList*/ } def findAllGroups() : List[String] = { @@ -89,10 +101,22 @@ object ClassUtil { var stop:Option[ConfigurableStop] = None val classpathFile = new File(classpath) - println("classpath is " + classpath) + //println("classpath is " + classpath) val finder = ClassFinder(getJarFile(classpathFile)) val classes = finder.getClasses - val classMap = ClassFinder.classInfoMap(classes) + val it = classes.iterator + + while(it.hasNext) { + val externalClass = it.next() + if(externalClass.superClassName.equals(configurableStopClass)){ + if (externalClass.name.equals(bundle)){ + val stopIntance = Class.forName(externalClass.name).newInstance() + stop = Some(stopIntance.asInstanceOf[ConfigurableStop]) + return stop + } + } + } + /*val classMap = ClassFinder.classInfoMap(classes) val plugins = ClassFinder.concreteSubclasses(configurableStopClass,classMap) plugins.foreach{ pluginClassInfo => @@ -101,7 +125,7 @@ object ClassUtil { stop = Some(plugin.asInstanceOf[ConfigurableStop]) return stop } - } + }*/ stop } @@ -153,9 +177,10 @@ object ClassUtil { ("sensitive" -> property.sensitive.toString)) }) ) val jsonString = compactRender(json) jsonString + } - def main(args: Array[String]): Unit = { + /*def main(args: Array[String]): Unit = { //val stop = findConfigurableStop("cn.piflow.bundle.Class1") //val allConfigurableStopList = findAllConfigurableStop() /*val propertyDescriptorList = findConfigurableStopPropertyDescriptor("cn.piflow.bundle.Xjzhu") @@ -166,13 +191,15 @@ object ClassUtil { val str = propertyJsonList.mkString(start, ",", end) println(str)*/ - val stop = findConfigurableStopInClasspath("cn.piflow.bundle.Xjzhu") - val temp = 1 - //println(findAllGroups()); + /*val stop = findAllConfigurableStop() + stop.foreach(s => println(s.getClass.getName)) + val temp = 1*/ - //val stoplist = findAllGroups(); - //println(stoplist) - } + /*val stop = findConfigurableStop("cn.piflow.bundle.Xjzhu") + println(stop.getClass.getName)*/ + + + }*/ } From 6804e91a59929ae20542b4c98aa059fddf8cbf18 Mon Sep 17 00:00:00 2001 From: judy0131 Date: Thu, 27 Sep 2018 11:23:25 +0800 Subject: [PATCH 13/14] fix bug: can not find user defined Configurable Stop --- .../scala/cn/piflow/conf/util/ClassUtil.scala | 16 +++++++++++----- .../src/main/scala/cn/piflow/api/API.scala | 5 ++--- 2 files changed, 13 insertions(+), 8 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 7fa8a6a..76657f5 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 @@ -136,18 +136,23 @@ object ClassUtil { def findConfigurableStop(bundle : String) : ConfigurableStop = { try{ + println("find ConfigurableStop by Class.forName: " + bundle) val stop = Class.forName(bundle).newInstance() stop.asInstanceOf[ConfigurableStop] }catch{ case classNotFoundException:ClassNotFoundException =>{ + println("find ConfigurableStop in Classpath: " + bundle) val stop : Option[ConfigurableStop] = ClassUtil.findConfigurableStopInClasspath(bundle) stop match { case Some(s) => s.asInstanceOf[ConfigurableStop] case _ => throw new ClassNotFoundException(bundle + " is not found!!!") } } - case ex : Exception => throw ex + case ex : Exception => { + println("Can not find Configurable: " + bundle) + throw ex + } } } @@ -159,6 +164,7 @@ object ClassUtil { def findConfigurableStopInfo(bundle : String) : String = { val stop = ClassUtil.findConfigurableStop(bundle) val propertyDescriptorList:List[PropertyDescriptor] = stop.getPropertyDescriptor() + propertyDescriptorList.foreach(p=> if (p.allowableValues == null) p.allowableValues = List("")) val json = ("StopInfo" -> @@ -180,7 +186,7 @@ object ClassUtil { } - /*def main(args: Array[String]): Unit = { + def main(args: Array[String]): Unit = { //val stop = findConfigurableStop("cn.piflow.bundle.Class1") //val allConfigurableStopList = findAllConfigurableStop() /*val propertyDescriptorList = findConfigurableStopPropertyDescriptor("cn.piflow.bundle.Xjzhu") @@ -196,10 +202,10 @@ object ClassUtil { val temp = 1*/ - /*val stop = findConfigurableStop("cn.piflow.bundle.Xjzhu") - println(stop.getClass.getName)*/ + val stop = findConfigurableStop("cn.piflow.bundle.Xjzhu") + println(stop.getClass.getName) - }*/ + } } diff --git a/piflow-server/src/main/scala/cn/piflow/api/API.scala b/piflow-server/src/main/scala/cn/piflow/api/API.scala index 79272d2..e26dbd3 100644 --- a/piflow-server/src/main/scala/cn/piflow/api/API.scala +++ b/piflow-server/src/main/scala/cn/piflow/api/API.scala @@ -3,10 +3,9 @@ package cn.piflow.api import cn.piflow.Runner import cn.piflow.conf.bean.{FlowBean, PropertyDescriptor} import org.apache.spark.sql.SparkSession -import cn.piflow.conf.util.{ClassUtil, FileUtil, OptionUtil} +import cn.piflow.conf.util.{ClassUtil, OptionUtil} import cn.piflow.Process -import cn.piflow.api.util.PropertyUtil -import cn.piflow.conf.util.ClassUtil.findConfigurableStopPropertyDescriptor +import cn.piflow.api.util.{PropertyUtil} import org.apache.http.client.methods.{CloseableHttpResponse, HttpGet, HttpPost} import org.apache.http.impl.client.HttpClients import org.apache.http.util.EntityUtils From dcd8777558ec1c72ff68122ddac2ac2fc3e42155 Mon Sep 17 00:00:00 2001 From: judy0131 Date: Thu, 27 Sep 2018 11:31:24 +0800 Subject: [PATCH 14/14] add bundle for getStopInfo --- piflow-bundle/src/main/scala/cn/piflow/conf/util/ClassUtil.scala | 1 + 1 file changed, 1 insertion(+) 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 76657f5..043e49b 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 @@ -168,6 +168,7 @@ object ClassUtil { val json = ("StopInfo" -> + ("bundle" -> bundle) ~ ("owner" -> stop.authorEmail) ~ ("inportCount" -> stop.inportCount) ~ ("outportCount" -> stop.outportCount) ~