From 668914b9cbd9136728d41d40ca02891e2548169f Mon Sep 17 00:00:00 2001 From: zhaowei8188127 <18810460332@163.com> Date: Fri, 6 Sep 2013 10:01:56 +0800 Subject: [PATCH] add log4j. change module upload dir from /classes to /lib. --- haflow.module.init.jar | Bin 0 -> 28008 bytes .../engine/oozie/FlowDeployService.java | 2 +- .../java/haflow/engine/oozie/OozieEngine.java | 5 +- .../haflow/module/basic/DemoJavaModule.java | 39 -------- .../module/datamining/BuildForestModule.java | 92 ----------------- .../datamining/CanopyClusterModule.java | 83 ---------------- .../module/datamining/DescribeModule.java | 93 ------------------ .../module/datamining/TestForestModule.java | 88 ----------------- .../module/dm/weka/WekaAssociationModule.java | 75 -------------- .../module/dm/weka/WekaClassifierModule.java | 75 -------------- .../module/dm/weka/WekaClusterModule.java | 75 -------------- .../module/statistics/R/RSVDModule.java | 75 -------------- .../ui/controller/ModuleController.java | 16 +-- src/main/java/haflow/util/ClassHelper.java | 2 + .../haflow/util/ModuleJarClassLoader.java | 27 +++++ src/main/resources/log4j.properties | 5 + 16 files changed, 48 insertions(+), 704 deletions(-) create mode 100644 haflow.module.init.jar delete mode 100644 src/main/java/haflow/module/basic/DemoJavaModule.java delete mode 100644 src/main/java/haflow/module/datamining/BuildForestModule.java delete mode 100644 src/main/java/haflow/module/datamining/CanopyClusterModule.java delete mode 100644 src/main/java/haflow/module/datamining/DescribeModule.java delete mode 100644 src/main/java/haflow/module/datamining/TestForestModule.java delete mode 100644 src/main/java/haflow/module/dm/weka/WekaAssociationModule.java delete mode 100644 src/main/java/haflow/module/dm/weka/WekaClassifierModule.java delete mode 100644 src/main/java/haflow/module/dm/weka/WekaClusterModule.java delete mode 100644 src/main/java/haflow/module/statistics/R/RSVDModule.java create mode 100644 src/main/java/haflow/util/ModuleJarClassLoader.java create mode 100644 src/main/resources/log4j.properties diff --git a/haflow.module.init.jar b/haflow.module.init.jar new file mode 100644 index 0000000000000000000000000000000000000000..cf42b594af48ca63aeeb7c3d2c089c20f08a5ead GIT binary patch literal 28008 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 O^iLN$_iyXNKK&0_r#dzO literal 0 HcmV?d00001 diff --git a/src/main/java/haflow/engine/oozie/FlowDeployService.java b/src/main/java/haflow/engine/oozie/FlowDeployService.java index b429aa5..a7e2228 100644 --- a/src/main/java/haflow/engine/oozie/FlowDeployService.java +++ b/src/main/java/haflow/engine/oozie/FlowDeployService.java @@ -24,7 +24,7 @@ public class FlowDeployService { if (jarPath.endsWith(".jar")) { File jarFile = new File(jarPath); File dstPath = new File(deployPath + "/lib"); - // System.out.println(jarPath); + System.out.println(jarPath); this.copyJarFile(jarFile, dstPath, jarFile.getName()); } } diff --git a/src/main/java/haflow/engine/oozie/OozieEngine.java b/src/main/java/haflow/engine/oozie/OozieEngine.java index 48ff40d..bfbf949 100644 --- a/src/main/java/haflow/engine/oozie/OozieEngine.java +++ b/src/main/java/haflow/engine/oozie/OozieEngine.java @@ -39,6 +39,7 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.w3c.dom.Document; @@ -47,6 +48,7 @@ import org.w3c.dom.Document; @Component public class OozieEngine extends AbstractEngine { + private Logger logger = Logger.getLogger(this.getClass().getName()); private ModuleUtil moduleUtil; private NodeConfigurationService nodeConfigurationService; private ClusterConfiguration clusterConfiguration; @@ -151,7 +153,7 @@ public class OozieEngine extends AbstractEngine { List sorted = new TopologicalSort(graph).getOrder(); if (sorted == null) { - messageBuilder.append("Error: Flow is has Circles!"); + messageBuilder.append("Error: Flow has Circles!"); } else { String flowName = flow.getName(); String workflowXml = genWorkflowXml(flowName, sorted, @@ -212,6 +214,7 @@ public class OozieEngine extends AbstractEngine { System.out.println(messageBuilder.toString()); model.setMessage(messageBuilder.toString()); System.out.println(messageBuilder.toString()); + logger.info(messageBuilder); return model; } catch (Exception e) { e.printStackTrace(); diff --git a/src/main/java/haflow/module/basic/DemoJavaModule.java b/src/main/java/haflow/module/basic/DemoJavaModule.java deleted file mode 100644 index e6ab6b8..0000000 --- a/src/main/java/haflow/module/basic/DemoJavaModule.java +++ /dev/null @@ -1,39 +0,0 @@ -package haflow.module.basic; - -import haflow.module.AbstractJavaModule; -import haflow.module.DataType; -import haflow.module.Module; -import haflow.module.ModuleConfiguration; -import haflow.module.ModuleConfigurationType; -import haflow.module.ModuleEndpoint; -import haflow.module.ModuleType; - -import java.util.Map; - -@Module(id = "ada600a8-aa63-968a-ca46-9085a0e0bd2f", name = "DemoJava", category = "Basic", type = ModuleType.JAVA, configurations = { @ModuleConfiguration(key = "arg_test", displayName = "Arguments Test", pattern = "^(.*)$", type = ModuleConfigurationType.PLAIN_TEXT), }, inputs = { @ModuleEndpoint(name = "from", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText) }, outputs = { - @ModuleEndpoint(name = "ok", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText), - @ModuleEndpoint(name = "error", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText) }) -public class DemoJavaModule extends AbstractJavaModule { - - @Override - public boolean validate(Map configurations, - Map inputs, Map outputs) { - // TODO Auto-generated method stub - return false; - } - - @Override - public String getMainClass() { - return DemoJavaModule.class.getName(); - } - - public static void main(String[] args) { - System.out.println("Demo Java Main"); - - System.out.println("# Arguments: " + args.length); - for (int i = 0; i < args.length; i++) { - System.out.println("Argument[" + i + "]: " + args[i]); - } - } - -} diff --git a/src/main/java/haflow/module/datamining/BuildForestModule.java b/src/main/java/haflow/module/datamining/BuildForestModule.java deleted file mode 100644 index 2b90723..0000000 --- a/src/main/java/haflow/module/datamining/BuildForestModule.java +++ /dev/null @@ -1,92 +0,0 @@ -package haflow.module.datamining; - -import haflow.module.AbstractJavaModule; -import haflow.module.DataType; -import haflow.module.Module; -import haflow.module.ModuleConfiguration; -import haflow.module.ModuleConfigurationType; -import haflow.module.ModuleEndpoint; -import haflow.module.ModuleType; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -@Module(id = "ada600a8-aa63-968a-ca46-4356a0e0bdac", name = "BuildForest", category = "DataMining-Mahout", type = ModuleType.JAVA, - configurations = { - @ModuleConfiguration(key = "data", displayName = "data: Data path", pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "dataset", displayName = "dataset: Dataset path",pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "selection", displayName = "selection: Number of variables to select randomly at each tree-node.", pattern = "^(.*)$",type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "no-complete", displayName = "no-complete: The tree is not complemented", pattern = "^(.*)$",type=ModuleConfigurationType.BOOLEAN), - @ModuleConfiguration(key = "minsplit", displayName = "minsplit: Minimum Split", pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "minprop", displayName = "minprop: Minimum Porportion", pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "seed", displayName = "seed: Seed Value", pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "partial", displayName = "partial: use the Partial Data Implementation", pattern = "^(.*)$", type=ModuleConfigurationType.BOOLEAN), - @ModuleConfiguration(key = "nbtrees", displayName = "nbtrees: Number of trees to grow.", pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "output", displayName = "output: Output path", pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT)}, - inputs = { @ModuleEndpoint(name = "from", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText) }, outputs = { - @ModuleEndpoint(name = "ok", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText), - @ModuleEndpoint(name = "error", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText) }) -public class BuildForestModule extends AbstractJavaModule { - - @Override - public boolean validate(Map configurations, - Map inputs, Map outputs) { - // TODO Auto-generated method stub - return false; - } - - @Override - public String getMainClass() { - return "org.apache.mahout.classifier.df.mapreduce.BuildForest"; - } - - @Override - public List getArguments(Map configurations) { - Module module= this.getClass().getAnnotation(Module.class); - ModuleConfiguration[] confs = module.configurations(); - - List result = new ArrayList(); - for (String key : configurations.keySet()) { - ModuleConfigurationType confType = getConfigurationType(key, confs); - switch(confType){ - case BOOLEAN: - String boolValue = configurations.get(key); - if( boolValue.equals("true")){ - result.add("--" + key ); - } - break; - case PLAIN_TEXT: - String textValue = configurations.get(key).trim(); - if( textValue.length() > 0){ - result.add("--" + key); - result.add(configurations.get(key)); - } - break; - case OTHER: - default: - System.out.println("Invalid Parameters!"); - break; - } - } - return result; - } - - private ModuleConfigurationType getConfigurationType(String key, ModuleConfiguration[] confs){ - for( ModuleConfiguration conf : confs){ - if( key.equals(conf.key())) - return conf.type(); - } - return ModuleConfigurationType.OTHER; - } - - public static void main(String[] args) { - System.out.println("Demo Java Main"); - - System.out.println("# Arguments: " + args.length); - for (int i = 0; i < args.length; i++) { - System.out.println("Argument[" + i + "]: " + args[i]); - } - } - -} diff --git a/src/main/java/haflow/module/datamining/CanopyClusterModule.java b/src/main/java/haflow/module/datamining/CanopyClusterModule.java deleted file mode 100644 index b166107..0000000 --- a/src/main/java/haflow/module/datamining/CanopyClusterModule.java +++ /dev/null @@ -1,83 +0,0 @@ -package haflow.module.datamining; - -import haflow.module.AbstractJavaModule; -import haflow.module.DataType; -import haflow.module.Module; -import haflow.module.ModuleConfiguration; -import haflow.module.ModuleConfigurationType; -import haflow.module.ModuleEndpoint; -import haflow.module.ModuleType; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -@Module(id = "ada600a8-aa63-968a-ca46-4356a0e0bd00", name = "CanopyCluster", category = "DataMining-Mahout", type = ModuleType.JAVA, - configurations = { - @ModuleConfiguration(key = "input", displayName = "input", pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "output", displayName = "output",pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "distanceMeasure", displayName = "distanceMeasure", pattern = "^(.*)$",type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "t1", displayName = "t1", pattern = "^(.*)$",type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "t2", displayName = "t2", pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "t3", displayName = "t3", pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "t4", displayName = "t4", pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "clusterFilter", displayName = "clusterFilter", pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "overwrite", displayName = "overwrite", pattern = "^(.*)$", type=ModuleConfigurationType.BOOLEAN), - @ModuleConfiguration(key = "outlierThreshold", displayName = "outlierThreshold", pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT)}, - inputs = { @ModuleEndpoint(name = "from", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText) }, outputs = { - @ModuleEndpoint(name = "ok", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText), - @ModuleEndpoint(name = "error", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText) }) -public class CanopyClusterModule extends AbstractJavaModule { - - @Override - public boolean validate(Map configurations, - Map inputs, Map outputs) { - // TODO Auto-generated method stub - return false; - } - - @Override - public String getMainClass() { - return "org.apache.mahout.clustering.canopy.CanopyDriver"; - } - - @Override - public List getArguments(Map configurations) { - Module module= this.getClass().getAnnotation(Module.class); - ModuleConfiguration[] confs = module.configurations(); - - List result = new ArrayList(); - for (String key : configurations.keySet()) { - ModuleConfigurationType confType = getConfigurationType(key, confs); - switch(confType){ - case BOOLEAN: - String boolValue = configurations.get(key); - if( boolValue.equals("true")){ - result.add("--" + key ); - } - break; - case PLAIN_TEXT: - String textValue = configurations.get(key).trim(); - if( textValue.length() > 0){ - result.add("--" + key); - result.add(configurations.get(key)); - } - break; - case OTHER: - default: - System.out.println("Invalid Parameters!"); - break; - } - } - return result; - } - - private ModuleConfigurationType getConfigurationType(String key, ModuleConfiguration[] confs){ - for( ModuleConfiguration conf : confs){ - if( key.equals(conf.key())) - return conf.type(); - } - return ModuleConfigurationType.OTHER; - } - -} diff --git a/src/main/java/haflow/module/datamining/DescribeModule.java b/src/main/java/haflow/module/datamining/DescribeModule.java deleted file mode 100644 index a594467..0000000 --- a/src/main/java/haflow/module/datamining/DescribeModule.java +++ /dev/null @@ -1,93 +0,0 @@ -package haflow.module.datamining; - -import haflow.module.AbstractJavaModule; -import haflow.module.DataType; -import haflow.module.Module; -import haflow.module.ModuleConfiguration; -import haflow.module.ModuleConfigurationType; -import haflow.module.ModuleEndpoint; -import haflow.module.ModuleType; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -@Module(id = "ada600a8-aa63-968a-ca46-4356a0e0bdab", name = "Describe", category = "DataMining-Mahout", type = ModuleType.JAVA, configurations = { - @ModuleConfiguration(key = "path", displayName = "path: Data path", pattern = "^(.*)$", type = ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "descriptor", displayName = "descriptor: Data descriptor", pattern = "^(.*)$", type = ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "file", displayName = "file: Path to generated descriptor file", pattern = "^(.*)$", type = ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "regression", displayName = "regression: Regression Problem", pattern = "^(.*)$", type = ModuleConfigurationType.BOOLEAN) }, inputs = { @ModuleEndpoint(name = "from", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText) }, outputs = { - @ModuleEndpoint(name = "ok", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText), - @ModuleEndpoint(name = "error", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText) }) -public class DescribeModule extends AbstractJavaModule { - - @Override - public boolean validate(Map configurations, - Map inputs, Map outputs) { - // TODO Auto-generated method stub - return false; - } - - @Override - public String getMainClass() { - return "org.apache.mahout.classifier.df.tools.Describe"; - } - - @Override - public List getArguments(Map configurations) { - Module module = this.getClass().getAnnotation(Module.class); - ModuleConfiguration[] confs = module.configurations(); - - List result = new ArrayList(); - for (String key : configurations.keySet()) { - ModuleConfigurationType confType = getConfigurationType(key, confs); - switch (confType) { - case BOOLEAN: - String boolValue = configurations.get(key); - if( boolValue.equals("true")){ - result.add("--" + key); - } - break; - case PLAIN_TEXT: - String textValue = configurations.get(key).trim(); - if( textValue.length() > 0){ - if(key.equals("descriptor")){ - result.add("--" + key); - String[] descriptors = textValue.split(" "); - for(String desp : descriptors){ - result.add(desp); - } - }else{ - result.add("--" + key); - result.add(configurations.get(key)); - } - } - break; - case OTHER: - default: - System.out.println("Invalid Parameters!"); - break; - } - } - return result; - } - - private ModuleConfigurationType getConfigurationType(String key, - ModuleConfiguration[] confs) { - for (ModuleConfiguration conf : confs) { - if (key.equals(conf.key())) - return conf.type(); - } - return ModuleConfigurationType.OTHER; - } - - public static void main(String[] args) { - System.out.println("Demo Java Main"); - - System.out.println("# Arguments: " + args.length); - for (int i = 0; i < args.length; i++) { - System.out.println("Argument[" + i + "]: " + args[i]); - } - } - -} diff --git a/src/main/java/haflow/module/datamining/TestForestModule.java b/src/main/java/haflow/module/datamining/TestForestModule.java deleted file mode 100644 index 00e2d1d..0000000 --- a/src/main/java/haflow/module/datamining/TestForestModule.java +++ /dev/null @@ -1,88 +0,0 @@ -package haflow.module.datamining; - -import haflow.module.AbstractJavaModule; -import haflow.module.DataType; -import haflow.module.Module; -import haflow.module.ModuleConfiguration; -import haflow.module.ModuleConfigurationType; -import haflow.module.ModuleEndpoint; -import haflow.module.ModuleType; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -@Module(id = "ada600a8-aa63-968a-ca46-4356a0e0bdad", name = "TestForest", category = "DataMining-Mahout", type = ModuleType.JAVA, - configurations = { - @ModuleConfiguration(key = "input", displayName = "input : Path to job input directory.", pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "dataset", displayName = "dataset : Dataset path",pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "model", displayName = "model: Path to the Decision Forest", pattern = "^(.*)$",type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "output", displayName = "output: The directory pathname for output.", pattern = "^(.*)$",type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "analyze", displayName = "analyze: ", pattern = "^(.*)$", type=ModuleConfigurationType.BOOLEAN), - @ModuleConfiguration(key = "mapreduce", displayName = "mapreduce: ", pattern = "^(.*)$", type=ModuleConfigurationType.BOOLEAN)}, - inputs = { @ModuleEndpoint(name = "from", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText) }, outputs = { - @ModuleEndpoint(name = "ok", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText), - @ModuleEndpoint(name = "error", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText) }) -public class TestForestModule extends AbstractJavaModule { - - @Override - public boolean validate(Map configurations, - Map inputs, Map outputs) { - // TODO Auto-generated method stub - return false; - } - - @Override - public String getMainClass() { - return "org.apache.mahout.classifier.df.mapreduce.TestForest"; - } - - @Override - public List getArguments(Map configurations) { - Module module= this.getClass().getAnnotation(Module.class); - ModuleConfiguration[] confs = module.configurations(); - - List result = new ArrayList(); - for (String key : configurations.keySet()) { - ModuleConfigurationType confType = getConfigurationType(key, confs); - switch(confType){ - case BOOLEAN: - String boolValue = configurations.get(key); - if( boolValue.equals("true")){ - result.add("--" + key ); - } - break; - case PLAIN_TEXT: - String textValue = configurations.get(key).trim(); - if( textValue.length() > 0){ - result.add("--" + key); - result.add(configurations.get(key)); - } - break; - case OTHER: - default: - System.out.println("Invalid Parameters!"); - break; - } - } - return result; - } - - private ModuleConfigurationType getConfigurationType(String key, ModuleConfiguration[] confs){ - for( ModuleConfiguration conf : confs){ - if( key.equals(conf.key())) - return conf.type(); - } - return ModuleConfigurationType.OTHER; - } - - public static void main(String[] args) { - System.out.println("Demo Java Main"); - - System.out.println("# Arguments: " + args.length); - for (int i = 0; i < args.length; i++) { - System.out.println("Argument[" + i + "]: " + args[i]); - } - } - -} diff --git a/src/main/java/haflow/module/dm/weka/WekaAssociationModule.java b/src/main/java/haflow/module/dm/weka/WekaAssociationModule.java deleted file mode 100644 index c73c481..0000000 --- a/src/main/java/haflow/module/dm/weka/WekaAssociationModule.java +++ /dev/null @@ -1,75 +0,0 @@ -package haflow.module.dm.weka; - -import haflow.module.AbstractJavaModule; -import haflow.module.DataType; -import haflow.module.Module; -import haflow.module.ModuleConfiguration; -import haflow.module.ModuleConfigurationType; -import haflow.module.ModuleEndpoint; -import haflow.module.ModuleType; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -@Module(id = "ada600a8-aa63-968a-ca46-0156a0e0bdff", name = "Apriori", category = "DataMining-Weka", type = ModuleType.JAVA, - configurations = { - @ModuleConfiguration(key = "input", displayName = "input", pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "output", displayName = "output",pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT)}, - inputs = { @ModuleEndpoint(name = "from", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText) }, outputs = { - @ModuleEndpoint(name = "ok", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText), - @ModuleEndpoint(name = "error", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText) }) -public class WekaAssociationModule extends AbstractJavaModule { - - @Override - public boolean validate(Map configurations, - Map inputs, Map outputs) { - // TODO Auto-generated method stub - return false; - } - - @Override - public String getMainClass() { - return "org.apache.mahout.clustering.canopy.CanopyDriver"; - } - - @Override - public List getArguments(Map configurations) { - Module module= this.getClass().getAnnotation(Module.class); - ModuleConfiguration[] confs = module.configurations(); - - List result = new ArrayList(); - for (String key : configurations.keySet()) { - ModuleConfigurationType confType = getConfigurationType(key, confs); - switch(confType){ - case BOOLEAN: - String boolValue = configurations.get(key); - if( boolValue.equals("true")){ - result.add("--" + key ); - } - break; - case PLAIN_TEXT: - String textValue = configurations.get(key).trim(); - if( textValue.length() > 0){ - result.add("--" + key); - result.add(configurations.get(key)); - } - break; - case OTHER: - default: - System.out.println("Invalid Parameters!"); - break; - } - } - return result; - } - - private ModuleConfigurationType getConfigurationType(String key, ModuleConfiguration[] confs){ - for( ModuleConfiguration conf : confs){ - if( key.equals(conf.key())) - return conf.type(); - } - return ModuleConfigurationType.OTHER; - } - -} diff --git a/src/main/java/haflow/module/dm/weka/WekaClassifierModule.java b/src/main/java/haflow/module/dm/weka/WekaClassifierModule.java deleted file mode 100644 index bd3d51e..0000000 --- a/src/main/java/haflow/module/dm/weka/WekaClassifierModule.java +++ /dev/null @@ -1,75 +0,0 @@ -package haflow.module.dm.weka; - -import haflow.module.AbstractJavaModule; -import haflow.module.DataType; -import haflow.module.Module; -import haflow.module.ModuleConfiguration; -import haflow.module.ModuleConfigurationType; -import haflow.module.ModuleEndpoint; -import haflow.module.ModuleType; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -@Module(id = "ada600a8-aa63-968a-ca46-0056a0e0bdff", name = "KMeans", category = "DataMining-Weka", type = ModuleType.JAVA, - configurations = { - @ModuleConfiguration(key = "input", displayName = "input", pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "output", displayName = "output",pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT)}, - inputs = { @ModuleEndpoint(name = "from", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText) }, outputs = { - @ModuleEndpoint(name = "ok", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText), - @ModuleEndpoint(name = "error", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText) }) -public class WekaClassifierModule extends AbstractJavaModule { - - @Override - public boolean validate(Map configurations, - Map inputs, Map outputs) { - // TODO Auto-generated method stub - return false; - } - - @Override - public String getMainClass() { - return "org.apache.mahout.clustering.canopy.CanopyDriver"; - } - - @Override - public List getArguments(Map configurations) { - Module module= this.getClass().getAnnotation(Module.class); - ModuleConfiguration[] confs = module.configurations(); - - List result = new ArrayList(); - for (String key : configurations.keySet()) { - ModuleConfigurationType confType = getConfigurationType(key, confs); - switch(confType){ - case BOOLEAN: - String boolValue = configurations.get(key); - if( boolValue.equals("true")){ - result.add("--" + key ); - } - break; - case PLAIN_TEXT: - String textValue = configurations.get(key).trim(); - if( textValue.length() > 0){ - result.add("--" + key); - result.add(configurations.get(key)); - } - break; - case OTHER: - default: - System.out.println("Invalid Parameters!"); - break; - } - } - return result; - } - - private ModuleConfigurationType getConfigurationType(String key, ModuleConfiguration[] confs){ - for( ModuleConfiguration conf : confs){ - if( key.equals(conf.key())) - return conf.type(); - } - return ModuleConfigurationType.OTHER; - } - -} diff --git a/src/main/java/haflow/module/dm/weka/WekaClusterModule.java b/src/main/java/haflow/module/dm/weka/WekaClusterModule.java deleted file mode 100644 index 506a049..0000000 --- a/src/main/java/haflow/module/dm/weka/WekaClusterModule.java +++ /dev/null @@ -1,75 +0,0 @@ -package haflow.module.dm.weka; - -import haflow.module.AbstractJavaModule; -import haflow.module.DataType; -import haflow.module.Module; -import haflow.module.ModuleConfiguration; -import haflow.module.ModuleConfigurationType; -import haflow.module.ModuleEndpoint; -import haflow.module.ModuleType; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -@Module(id = "ada600a8-aa63-968a-ca46-0256a0e0bdff", name = "ID3", category = "DataMining-Weka", type = ModuleType.JAVA, - configurations = { - @ModuleConfiguration(key = "input", displayName = "input", pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "output", displayName = "output",pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT)}, - inputs = { @ModuleEndpoint(name = "from", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText) }, outputs = { - @ModuleEndpoint(name = "ok", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText), - @ModuleEndpoint(name = "error", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText) }) -public class WekaClusterModule extends AbstractJavaModule { - - @Override - public boolean validate(Map configurations, - Map inputs, Map outputs) { - // TODO Auto-generated method stub - return false; - } - - @Override - public String getMainClass() { - return "org.apache.mahout.clustering.canopy.CanopyDriver"; - } - - @Override - public List getArguments(Map configurations) { - Module module= this.getClass().getAnnotation(Module.class); - ModuleConfiguration[] confs = module.configurations(); - - List result = new ArrayList(); - for (String key : configurations.keySet()) { - ModuleConfigurationType confType = getConfigurationType(key, confs); - switch(confType){ - case BOOLEAN: - String boolValue = configurations.get(key); - if( boolValue.equals("true")){ - result.add("--" + key ); - } - break; - case PLAIN_TEXT: - String textValue = configurations.get(key).trim(); - if( textValue.length() > 0){ - result.add("--" + key); - result.add(configurations.get(key)); - } - break; - case OTHER: - default: - System.out.println("Invalid Parameters!"); - break; - } - } - return result; - } - - private ModuleConfigurationType getConfigurationType(String key, ModuleConfiguration[] confs){ - for( ModuleConfiguration conf : confs){ - if( key.equals(conf.key())) - return conf.type(); - } - return ModuleConfigurationType.OTHER; - } - -} diff --git a/src/main/java/haflow/module/statistics/R/RSVDModule.java b/src/main/java/haflow/module/statistics/R/RSVDModule.java deleted file mode 100644 index 515b2fb..0000000 --- a/src/main/java/haflow/module/statistics/R/RSVDModule.java +++ /dev/null @@ -1,75 +0,0 @@ -package haflow.module.statistics.R; - -import haflow.module.AbstractJavaModule; -import haflow.module.DataType; -import haflow.module.Module; -import haflow.module.ModuleConfiguration; -import haflow.module.ModuleConfigurationType; -import haflow.module.ModuleEndpoint; -import haflow.module.ModuleType; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -@Module(id = "ada600a8-aa63-968a-ca46-ff00a0e0bdff", name = "SVD", category = "Statistics-R", type = ModuleType.JAVA, - configurations = { - @ModuleConfiguration(key = "input", displayName = "input", pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT), - @ModuleConfiguration(key = "output", displayName = "output",pattern = "^(.*)$", type=ModuleConfigurationType.PLAIN_TEXT)}, - inputs = { @ModuleEndpoint(name = "from", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText) }, outputs = { - @ModuleEndpoint(name = "ok", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText), - @ModuleEndpoint(name = "error", minNumber = 1, maxNumber = 1, dataType = DataType.PlainText) }) -public class RSVDModule extends AbstractJavaModule { - - @Override - public boolean validate(Map configurations, - Map inputs, Map outputs) { - // TODO Auto-generated method stub - return false; - } - - @Override - public String getMainClass() { - return "org.apache.mahout.clustering.canopy.CanopyDriver"; - } - - @Override - public List getArguments(Map configurations) { - Module module= this.getClass().getAnnotation(Module.class); - ModuleConfiguration[] confs = module.configurations(); - - List result = new ArrayList(); - for (String key : configurations.keySet()) { - ModuleConfigurationType confType = getConfigurationType(key, confs); - switch(confType){ - case BOOLEAN: - String boolValue = configurations.get(key); - if( boolValue.equals("true")){ - result.add("--" + key ); - } - break; - case PLAIN_TEXT: - String textValue = configurations.get(key).trim(); - if( textValue.length() > 0){ - result.add("--" + key); - result.add(configurations.get(key)); - } - break; - case OTHER: - default: - System.out.println("Invalid Parameters!"); - break; - } - } - return result; - } - - private ModuleConfigurationType getConfigurationType(String key, ModuleConfiguration[] confs){ - for( ModuleConfiguration conf : confs){ - if( key.equals(conf.key())) - return conf.type(); - } - return ModuleConfigurationType.OTHER; - } - -} diff --git a/src/main/java/haflow/ui/controller/ModuleController.java b/src/main/java/haflow/ui/controller/ModuleController.java index 6bcc74b..c7912a2 100644 --- a/src/main/java/haflow/ui/controller/ModuleController.java +++ b/src/main/java/haflow/ui/controller/ModuleController.java @@ -1,11 +1,12 @@ package haflow.ui.controller; -import java.io.File; -import java.util.UUID; - import haflow.ui.helper.ModuleHelper; import haflow.ui.model.ModuleListModel; +import java.io.File; +import java.util.UUID; + +import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.util.FileCopyUtils; @@ -20,6 +21,7 @@ import org.springframework.web.servlet.ModelAndView; @Controller @RequestMapping("/module") public class ModuleController { + private Logger logger = Logger.getLogger(ModuleController.class.getName()); private ModuleHelper moduleHelper; private ModuleHelper getModuleHelper() { @@ -42,15 +44,15 @@ public class ModuleController { if (!file.isEmpty()) { try { String fileName = file.getOriginalFilename(); - String[] suffixs = fileName.split("\\."); - String suffix = "." + suffixs[suffixs.length - 1]; - if ((".jar".indexOf(suffix.toLowerCase()) != -1)) { + if (fileName.endsWith(".jar")) { byte[] bytes = file.getBytes(); - String uploadDir = Thread.currentThread() + String clazzPath = Thread.currentThread() .getContextClassLoader().getResource("/").getFile(); + String uploadDir = clazzPath.substring(0, clazzPath.length()-8) + "lib/"; String filePath = uploadDir + fileName; File toUpload = new File(filePath); FileCopyUtils.copy(bytes, toUpload); + logger.info(fileName + " uploaded to : " + filePath); return new ModelAndView("upload-success"); } else { return new ModelAndView("upload-error"); diff --git a/src/main/java/haflow/util/ClassHelper.java b/src/main/java/haflow/util/ClassHelper.java index 69d2367..e718c04 100644 --- a/src/main/java/haflow/util/ClassHelper.java +++ b/src/main/java/haflow/util/ClassHelper.java @@ -68,6 +68,8 @@ public class ClassHelper { .replace("/", "."); classNames.add(className); } + }else if(filePath.endsWith(".jar")){ + classNames.addAll(getClassNameFromJar(packageName, true, new File(filePath))); } } } diff --git a/src/main/java/haflow/util/ModuleJarClassLoader.java b/src/main/java/haflow/util/ModuleJarClassLoader.java new file mode 100644 index 0000000..aec14c0 --- /dev/null +++ b/src/main/java/haflow/util/ModuleJarClassLoader.java @@ -0,0 +1,27 @@ +package haflow.util; + +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; + +import org.apache.log4j.Logger; + +public class ModuleJarClassLoader{ + private static Logger logger = Logger.getLogger(ModuleJarClassLoader.class.getName()); + + public static ClassLoader loadJarClasses(String jarFilePath){ + logger.info("Start loading jar " + jarFilePath); + try { + URL url = new URL("file:/" + jarFilePath); + System.out.println(url.toExternalForm()); + URL[] urls = {url}; + ClassLoader loader = URLClassLoader.newInstance(urls, ModuleJarClassLoader.class.getClassLoader()); + return loader; + } catch (MalformedURLException e) { + e.printStackTrace(); + logger.error(e.getMessage()); + } + return null; + } + +} diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties new file mode 100644 index 0000000..01de8f3 --- /dev/null +++ b/src/main/resources/log4j.properties @@ -0,0 +1,5 @@ +log4j.rootLogger=INFO, Console + +log4j.appender.Console=org.apache.log4j.ConsoleAppender +log4j.appender.Console.layout=org.apache.log4j.PatternLayout +log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n \ No newline at end of file