Further work to enable stat collection and display
authorpvtroshin <pvtroshin@e3abac25-378b-4346-85de-24260fe3988d>
Mon, 30 May 2011 17:17:34 +0000 (17:17 +0000)
committerpvtroshin <pvtroshin@e3abac25-378b-4346-85de-24260fe3988d>
Mon, 30 May 2011 17:17:34 +0000 (17:17 +0000)
git-svn-id: link to svn.lifesci.dundee.ac.uk/svn/barton/ptroshin/JABA2@4193 e3abac25-378b-4346-85de-24260fe3988d

WEB-INF/web.xml
testsrc/compbio/stat/collector/ExecutionStatCollectorTester.java
webservices/compbio/stat/collector/ExecutionStatCollector.java
webservices/compbio/stat/collector/StatDB.java
webservices/compbio/stat/servlet/Joblist.java
webservices/compbio/stat/servlet/StatisticCollector.java
webservices/compbio/ws/client/Services.java

index b03b1fe..4f75bd5 100644 (file)
                <session-timeout>20</session-timeout>\r
     </session-config>\r
  \r
+     <servlet>\r
+        <display-name>This is a standard tomcat 'default' servlet for making listings</display-name>\r
+        <servlet-name>listings</servlet-name>\r
+        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>\r
+        <init-param>\r
+            <param-name>debug</param-name>\r
+            <param-value>0</param-value>\r
+        </init-param>\r
+        <init-param>\r
+            <param-name>readonly</param-name>\r
+            <param-value>true</param-value>\r
+        </init-param>\r
+        <init-param>\r
+            <param-name>listings</param-name>\r
+            <param-value>true</param-value>\r
+        </init-param>\r
+        <load-on-startup>1</load-on-startup>\r
+    </servlet>\r
+\r
     <servlet>\r
        <description>Display pre-calculated accounting info</description>\r
        <servlet-name>DisplayStat</servlet-name>\r
         <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>\r
         <load-on-startup>1</load-on-startup>\r
     </servlet>\r
-        \r
+   \r
+    <servlet-mapping>\r
+       <servlet-name>listings</servlet-name>\r
+       <url-pattern>/</url-pattern>\r
+       </servlet-mapping>\r
+            \r
     <servlet-mapping>\r
        <servlet-name>DisplayStat</servlet-name>\r
        <url-pattern>/DisplayStat</url-pattern>\r
     <web-resource-collection>\r
        <web-resource-name>Administrator pages</web-resource-name>\r
                <!-- Prohibit access to any resources -->\r
+       <url-pattern>/</url-pattern>\r
        <url-pattern>/DisplayStat</url-pattern>\r
        <url-pattern>/Joblist</url-pattern>\r
        <url-pattern>/AnnualStat</url-pattern>\r
index d209e13..9773935 100644 (file)
@@ -1,21 +1,35 @@
 package compbio.stat.collector;\r
 \r
 import static org.testng.Assert.assertEquals;\r
+import static org.testng.Assert.assertFalse;\r
+import static org.testng.Assert.assertTrue;\r
 \r
 import java.io.File;\r
+import java.util.Date;\r
+import java.util.concurrent.Executors;\r
+import java.util.concurrent.ScheduledExecutorService;\r
+import java.util.concurrent.ScheduledFuture;\r
+import java.util.concurrent.TimeUnit;\r
 \r
+import org.testng.Assert;\r
 import org.testng.annotations.Test;\r
 \r
 import compbio.metadata.AllTestSuit;\r
+import compbio.stat.collector.ExecutionStatCollector.JobDirectory;\r
 \r
 public class ExecutionStatCollectorTester {\r
 \r
+       final static String LOCAL_JOBS = AllTestSuit.TEST_DATA_PATH_ABSOLUTE\r
+                       + File.separator + "ljobs";\r
+       final static String CLUSTER_JOBS = AllTestSuit.TEST_DATA_PATH_ABSOLUTE\r
+                       + File.separator + "jobs";\r
        @Test\r
        public void testCollectStat() {\r
                ExecutionStatCollector local_jobs = new ExecutionStatCollector(\r
-                               AllTestSuit.TEST_DATA_PATH_ABSOLUTE + File.separator + "ljobs");\r
+                               LOCAL_JOBS, 1);\r
                ExecutionStatCollector cl_jobs = new ExecutionStatCollector(\r
-                               AllTestSuit.TEST_DATA_PATH_ABSOLUTE + File.separator + "jobs");\r
+                               CLUSTER_JOBS, 24);\r
+\r
                StatProcessor local_stats = local_jobs.getStats();\r
                StatProcessor cl_stats = cl_jobs.getStats();\r
                // System.out.println("L: " + local_stats.stats);\r
@@ -29,7 +43,77 @@ public class ExecutionStatCollectorTester {
                assertEquals(2, local_stats.getAbandonedJobs().size());\r
 \r
        }\r
-       public void testUpdateStat() {\r
+\r
+       @Test\r
+       public void testUpdateStatTester() {\r
+\r
+               ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);\r
+               ScheduledFuture<?> sf = executor.scheduleAtFixedRate(\r
+                               new ExecutionStatCollector(LOCAL_JOBS, 1), 1, 10,\r
+                               TimeUnit.SECONDS);\r
+\r
+               try {\r
+                       Thread.sleep(1000 * 35);\r
+                       executor.shutdown();\r
+                       executor.awaitTermination(300, TimeUnit.SECONDS);\r
+               } catch (InterruptedException e) {\r
+                       e.printStackTrace();\r
+                       Assert.fail(e.getMessage());\r
+               }\r
+       }\r
+\r
+       /**\r
+        * This test will fail in time as it relies on last access time for file in\r
+        * the filesystem! This OK as it has been tested by then.\r
+        * \r
+        */\r
+       @Test\r
+       public void testHasTimedOut() {\r
+               ExecutionStatCollector ecol = new ExecutionStatCollector(LOCAL_JOBS, 1);\r
+               File f = new File(LOCAL_JOBS + File.separator\r
+                               + "ClustalW#1015373448154965");\r
+               File timedOut = new File(LOCAL_JOBS + File.separator\r
+                               + "Mafft#7868649707286965");\r
+\r
+               JobDirectory jd = new JobDirectory(f);\r
+               JobDirectory timedOutDir = new JobDirectory(timedOut);\r
+               System.out.println("! " + new Date(f.lastModified()));\r
+\r
+               assertTrue((System.currentTimeMillis() - f.lastModified())\r
+                               / (1000 * 60 * 60) < 1);\r
+               assertFalse((System.currentTimeMillis() - timedOut.lastModified())\r
+                               / (1000 * 60 * 60) < 1);\r
+               assertFalse(ecol.hasTimedOut(jd));\r
+               assertTrue(ecol.hasTimedOut(timedOutDir));\r
+       }\r
+\r
+       @Test\r
+       public void testHasCompleted() {\r
+               ExecutionStatCollector ecol_no_timeout = new ExecutionStatCollector(\r
+                               LOCAL_JOBS, 10000000);\r
+               ExecutionStatCollector ecol = new ExecutionStatCollector(LOCAL_JOBS, 1);\r
+\r
+               File normal = new File(LOCAL_JOBS + File.separator\r
+                               + "ClustalW#100368900075204");\r
+               File finished = new File(LOCAL_JOBS + File.separator\r
+                               + "ClustalW#1015373448154965");\r
+               File cancelled = new File(LOCAL_JOBS + File.separator\r
+                               + "Mafft#7918237850044965");\r
+               File noresult = new File(LOCAL_JOBS + File.separator\r
+                               + "ClustalW#1015343425414965");\r
+\r
+               JobDirectory dnormal = new JobDirectory(normal);\r
+               JobDirectory dfinished = new JobDirectory(finished);\r
+               JobDirectory dcancelled = new JobDirectory(cancelled);\r
+\r
+               JobDirectory dnoresult = new JobDirectory(noresult);\r
+\r
+               assertTrue(ecol.hasCompleted(dnormal));\r
+               assertTrue(ecol.hasCompleted(dfinished));\r
+               assertTrue(ecol.hasCompleted(dcancelled));\r
+\r
+               assertTrue(ecol.hasCompleted(dnoresult));\r
+               assertFalse(ecol_no_timeout.hasCompleted(dnoresult));\r
 \r
        }\r
 }\r
index 140de7c..bf3130a 100644 (file)
@@ -15,10 +15,8 @@ import java.util.Set;
 \r
 import org.apache.log4j.Logger;\r
 \r
-import compbio.engine.client.ConfExecutable;\r
 import compbio.engine.client.Executable;\r
 import compbio.metadata.JobStatus;\r
-import compbio.runner.msa.ClustalW;\r
 import compbio.util.FileUtil;\r
 import compbio.ws.client.Services;\r
 \r
@@ -239,26 +237,8 @@ public class ExecutionStatCollector implements Runnable {
                        return ftime;\r
                }\r
 \r
-               @SuppressWarnings("unchecked")\r
-               Class<Executable<?>> getWSRunnerName() {\r
-                       String name = jobdir.getName().split("#")[0];\r
-                       try {\r
-                               if (name.startsWith(ConfExecutable.CLUSTER_TASK_ID_PREFIX)) {\r
-                                       assert ConfExecutable.CLUSTER_TASK_ID_PREFIX.length() == 1;\r
-                                       name = name.substring(1);\r
-                               }\r
-                               name = ClustalW.class.getPackage().getName() + "." + name;\r
-                               return (Class<Executable<?>>) Class.forName(name);\r
-                       } catch (ClassNotFoundException e) {\r
-                               e.printStackTrace();\r
-                               throw new RuntimeException(\r
-                                               "Cannot match the directory name to the executable! Executable name is "\r
-                                                               + name);\r
-                       }\r
-               }\r
-\r
                private Services getService() {\r
-                       return Services.getService(getWSRunnerName());\r
+                       return Services.getServiceByJobDirectory(jobdir);\r
                }\r
 \r
                // Mafft, Muscle, Tcoffee, Clustal task:fasta.in result:fasta.out\r
@@ -267,7 +247,9 @@ public class ExecutionStatCollector implements Runnable {
                 * TODO replace with Universal names for WS!\r
                 */\r
                long getResultSize() {\r
-                       Class<Executable<?>> name = getWSRunnerName();\r
+                       Class<? extends Executable<?>> name = Services\r
+                                       .getRunnerByJobDirectory(jobdir);\r
+\r
                        File f = null;\r
                        if (name.getSimpleName().equalsIgnoreCase("Probcons")) {\r
                                f = files.get("alignment.out");\r
index 0f851ce..56ce9c1 100644 (file)
@@ -49,13 +49,11 @@ public class StatDB {
                                        + ";create=false");\r
 \r
                        conn.setAutoCommit(true);\r
-\r
-                       Runtime.getRuntime().addShutdownHook(new Thread() {\r
-                               @Override\r
-                               public void run() {\r
-                                       shutdownDBServer();\r
-                               }\r
-                       });\r
+                       /*\r
+                        * Runtime.getRuntime().addShutdownHook(new Thread() {\r
+                        * \r
+                        * @Override public void run() { shutdownDBServer(); } });\r
+                        */\r
                }\r
                return conn;\r
        }\r
@@ -114,7 +112,8 @@ public class StatDB {
        }\r
 \r
        void insertData(Set<JobStat> jobstatus) throws SQLException {\r
-               System.out.println("Inserting " + jobstatus.size());\r
+               log.info("Inserting " + jobstatus.size()\r
+                               + " new records into the statistics database");\r
 \r
                conn.setAutoCommit(false);\r
                String insert = "insert into exec_stat (service_name, cluster_job_id, job_id, start, finish, "\r
index 1b73018..4ceb2b8 100644 (file)
@@ -1,5 +1,6 @@
 package compbio.stat.servlet;\r
 \r
+import java.io.File;\r
 import java.io.IOException;\r
 import java.sql.SQLException;\r
 import java.sql.Timestamp;\r
@@ -95,6 +96,7 @@ public class Joblist extends HttpServlet {
                PropertyHelper helper = PropertyHelperManager.getPropertyHelper();\r
                String clusterTempDir = helper.getProperty("cluster.tmp.directory")\r
                                .trim();\r
+               clusterTempDir = new File(clusterTempDir).getName();\r
                String localTempDir = helper.getProperty("local.tmp.directory").trim();\r
                // TODO include the time slice\r
                Timestamp startDate = new Timestamp(Long.parseLong(fromDate));\r
index 0ffe77d..978d89a 100644 (file)
@@ -14,6 +14,7 @@ import compbio.engine.conf.PropertyHelperManager;
 import compbio.stat.collector.ExecutionStatCollector;\r
 import compbio.stat.collector.StatDB;\r
 import compbio.util.PropertyHelper;\r
+import compbio.util.Util;\r
 \r
 public class StatisticCollector implements ServletContextListener {\r
 \r
@@ -50,24 +51,37 @@ public class StatisticCollector implements ServletContextListener {
                int clusterMaxRuntime = getClusterJobTimeOut();\r
 \r
                int localMaxRuntime = getLocalJobTimeOut();\r
-               String localWorkDir = getLocalJobDir();\r
+               String localWorkDir = compbio.engine.client.Util\r
+                               .convertToAbsolute(getLocalJobDir());\r
 \r
                log.info("Initializing statistics collector");\r
-               executor = Executors.newScheduledThreadPool(1);\r
+               executor = Executors.newScheduledThreadPool(2);\r
 \r
                if (collectClusterStats()) {\r
+                       // TODO remove work out of the constructor Tomcat takes ages to\r
+                       // start!\r
                        ExecutionStatCollector clusterCollector = new ExecutionStatCollector(\r
                                        clusterWorkDir, clusterMaxRuntime);\r
                        clustercf = executor.scheduleAtFixedRate(clusterCollector, 60,\r
                                        24 * 60, TimeUnit.MINUTES);\r
+                       // clustercf = executor.scheduleAtFixedRate(clusterCollector, 15,\r
+                       // 30,\r
+                       // TimeUnit.SECONDS);\r
                        log.info("Collecting cluster statistics ");\r
+               } else {\r
+                       log.info("Cluster statistics collector is disabled or not configured! ");\r
                }\r
                if (collectLocalStats()) {\r
                        ExecutionStatCollector localCollector = new ExecutionStatCollector(\r
                                        localWorkDir, localMaxRuntime);\r
+                       // localcf = executor.scheduleAtFixedRate(localCollector, 100, 60,\r
+                       // TimeUnit.SECONDS);\r
+\r
                        localcf = executor.scheduleAtFixedRate(localCollector, 10, 24 * 60,\r
                                        TimeUnit.MINUTES);\r
                        log.info("Collecting local statistics ");\r
+               } else {\r
+                       log.info("Local statistics collector is disabled or not configured! ");\r
                }\r
 \r
        }\r
@@ -102,28 +116,26 @@ public class StatisticCollector implements ServletContextListener {
        }\r
 \r
        private static String getStringProperty(String propName) {\r
-               String locdir = ph.getProperty(propName);\r
-               if (locdir != null) {\r
-                       locdir = locdir.trim();\r
+               if (propName != null) {\r
+                       propName = propName.trim();\r
                }\r
-               return locdir;\r
+               return propName;\r
        }\r
 \r
        static boolean collectClusterStats() {\r
                return getBooleanProperty(ph\r
                                .getProperty("cluster.stat.collector.enable"));\r
-\r
        }\r
 \r
        static boolean collectLocalStats() {\r
                return getBooleanProperty(ph.getProperty("local.stat.collector.enable"));\r
        }\r
 \r
-       private static boolean getBooleanProperty(String propName) {\r
+       private static boolean getBooleanProperty(String propValue) {\r
                boolean enabled = false;\r
-               if (propName != null) {\r
-                       propName = propName.trim();\r
-                       enabled = Boolean.parseBoolean(propName);\r
+               if (!Util.isEmpty(propValue)) {\r
+                       propValue = propValue.trim();\r
+                       enabled = Boolean.parseBoolean(propValue);\r
                }\r
                return enabled;\r
        }\r
index 7f06da7..bff43e3 100644 (file)
@@ -18,6 +18,7 @@
 \r
 package compbio.ws.client;\r
 \r
+import java.io.File;\r
 import java.net.URL;\r
 \r
 import javax.xml.namespace.QName;\r
@@ -26,7 +27,17 @@ import javax.xml.ws.Service;
 import compbio.data.msa.JABAService;\r
 import compbio.data.msa.MsaWS;\r
 import compbio.data.msa.SequenceAnnotation;\r
+import compbio.engine.client.ConfExecutable;\r
 import compbio.engine.client.Executable;\r
+import compbio.runner.conservation.AACon;\r
+import compbio.runner.disorder.Disembl;\r
+import compbio.runner.disorder.GlobPlot;\r
+import compbio.runner.disorder.Jronn;\r
+import compbio.runner.msa.ClustalW;\r
+import compbio.runner.msa.Mafft;\r
+import compbio.runner.msa.Muscle;\r
+import compbio.runner.msa.Probcons;\r
+import compbio.runner.msa.Tcoffee;\r
 \r
 /**\r
  * List of web services currently supported by JABAWS version 2\r
@@ -45,7 +56,8 @@ public enum Services {
                return null;\r
        }\r
 \r
-       public static Services getService(Class<Executable<?>> runnerClassName) {\r
+       public static Services getServiceByRunner(\r
+                       Class<Executable<?>> runnerClassName) {\r
                assert runnerClassName != null;\r
                String sname = runnerClassName.getSimpleName().toLowerCase();\r
                for (Services service : Services.values()) {\r
@@ -56,6 +68,64 @@ public enum Services {
                return null;\r
        }\r
 \r
+       public Class<? extends Executable<?>> getServiceImpl() {\r
+               switch (this) {\r
+                       case AAConWS :\r
+                               return AACon.class;\r
+                       case ClustalWS :\r
+                               return ClustalW.class;\r
+                       case MafftWS :\r
+                               return Mafft.class;\r
+                       case MuscleWS :\r
+                               return Muscle.class;\r
+                       case TcoffeeWS :\r
+                               return Tcoffee.class;\r
+                       case ProbconsWS :\r
+                               return Probcons.class;\r
+                       case DisemblWS :\r
+                               return Disembl.class;\r
+                       case GlobPlotWS :\r
+                               return GlobPlot.class;\r
+                       case JronnWS :\r
+                               return Jronn.class;\r
+                       default :\r
+                               throw new RuntimeException(\r
+                                               "Unknown web service implementation class for service: "\r
+                                                               + this);\r
+               }\r
+       }\r
+\r
+       public static Class<? extends Executable<?>> getRunnerByJobDirectory(File jobdir) {\r
+               Services service = getServiceByRunnerName(getRunnerNameByJobDirectory(jobdir));\r
+               return service.getServiceImpl();\r
+       }\r
+\r
+       private static String getRunnerNameByJobDirectory(File jobdir) {\r
+               String name = jobdir.getName().split("#")[0];\r
+\r
+               if (name.startsWith(ConfExecutable.CLUSTER_TASK_ID_PREFIX)) {\r
+                       assert ConfExecutable.CLUSTER_TASK_ID_PREFIX.length() == 1;\r
+                       name = name.substring(1);\r
+               }\r
+               return name;\r
+       }\r
+\r
+       public static Services getServiceByJobDirectory(File jobdir) {\r
+               return getServiceByRunnerName(getRunnerNameByJobDirectory(jobdir));\r
+       }\r
+\r
+       private static Services getServiceByRunnerName(String name) {\r
+               for (Services service : Services.values()) {\r
+                       String runnerName = service.getServiceImpl().getSimpleName()\r
+                                       .toLowerCase();\r
+                       name = name.trim().toLowerCase();\r
+                       if (name.startsWith(runnerName)) {\r
+                               return service;\r
+                       }\r
+               }\r
+               return null;\r
+       }\r
+\r
        Service getService(URL url, String sqname) {\r
                QName qname = new QName(sqname, this.toString());\r
                return Service.create(url, qname);\r