package org.ngbw.examples; import java.io.IOException; import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.concurrent.Future; import org.ngbw.sdk.UserAuthenticationException; import org.ngbw.sdk.Workbench; import org.ngbw.sdk.WorkbenchSession; import org.ngbw.sdk.common.util.Resource; import org.ngbw.sdk.common.util.ResourceNotFoundException; import org.ngbw.sdk.core.shared.TaskRunStage; import org.ngbw.sdk.database.Folder; import org.ngbw.sdk.database.Task; import org.ngbw.sdk.database.TaskInputSourceDocument; import org.ngbw.sdk.database.TaskLogMessage; import org.ngbw.sdk.database.TaskOutputSourceDocument; import org.ngbw.sdk.database.User; import org.ngbw.sdk.tool.DisabledResourceException; import org.ngbw.sdk.TaskResult; /* Terri, Tue Jan 29 12:10:01 PST 2013: this hasn't been used since the early days of the bio workbench site. I just updated it to work with the types of process workers we have now. We can no longer wait for a task to complete by waiting for a process to exit, since process worker types that use the running task table don't spawn a separate process to manage the task. - SSHExecProcessWorker, for xsede jobs, Uses RunningTaskTable. - SSHLongProcessWorker, for triton jobs. Uses RunningTaskTable. - SSHProcessWorker, for snooker, very quick jobs. Doesn't use RunningTaskTable, spawns a process_runner. Run this with "sdkrun org.ngbw.examples.TestTools 2>/tmp/testtools.log" Or "sdkrun org.ngbw.examples.TestTools BEAST_TG 2>/tmp/testtools.log" Uses: sdk/src/main/resources/examples/tooltest files: test.properties - has a section for each tool that can be tested. Specify any non input file properties that correspond to visible controls. testInputFiles.properties = has a section for each tool. Specifies where to find input files. Each tool that can be tested has a subdir here that contains it's test input files. See documents/for_developers/Releasing_a_new_tool.doc. It has a section on how to create the resources for testing a tool. Default properties for test.properties and testInputProperties can be generated by going to /cipres-portal-src/src/main/codeGeneration and running: "ant clean generate Test". I don't know if the build runs this normally. It creates an AUTO-GENERATED subdirectory that contains, among other things, a copy of test.properties and testInputFiles.properties with parameters for every tool. You can copy those that you want from these files to sdk/src/main/resources/examples/tooltest versions of the properties files. */ public class TestTools { private static final String USERNAME = "test1"; private static final String PASSWORD = "test1"; //Workbench object instances private static Workbench workbench = Workbench.getInstance(); private static WorkbenchSession session; private static Folder folder; //global map for all parameters of all tools private static Map> toolParameterMap; //global map of all input parameters to their fileNames private static Map> inputFileNameMap; //filenames versus file data private static Map inputDataMap; private static ArrayList submittedJobs = new ArrayList(); //read parameter properties file into map static { String parameterPropertiesFile = "examples/tooltest/test.properties"; Properties parameterProperties; try { parameterProperties = Resource.getResource(parameterPropertiesFile).getProperties(); } catch (ResourceNotFoundException e) { throw new RuntimeException(e.toString(), e); } readParameterProperties(parameterProperties); String inputDataPropertiesFile = "examples/tooltest/testInputFiles.properties"; Properties inputDataProperties; try { inputDataProperties = Resource.getResource(inputDataPropertiesFile).getProperties(); } catch (ResourceNotFoundException e) { //that file cannot be found throw new RuntimeException(e.toString(), e); } readInputDataProperties(inputDataProperties); } public static void main(String[] args) { try { try { session = workbench.getSession(USERNAME, PASSWORD); } catch (UserAuthenticationException e) { System.err.println(e.toString()); System.exit(-1); } User user = session.getUser(); String folderLabel = "Test Folder"; folder = findFolderByLabel(user.findFolders(), folderLabel); if (folder == null) { folder = new Folder(user); folder.setLabel(folderLabel); folder.save(); } Collection arglist = null; if (args.length > 0) { arglist = Arrays.asList(args); } //loop over all tools. if we have command line args, skip tools not given on // command line, otherwise process all. int i=0; for (String toolId : toolParameterMap.keySet()) { if ((arglist != null) && !arglist.contains(toolId)) { continue; } System.out.println(); System.out.println("TESTING: "+toolId); //test a tool TaskResult tr = runCommand(toolId); submittedJobs.add(tr); } waitForJobs(); System.exit(0); } catch (Exception err) { err.printStackTrace(System.err); System.exit(-1); } } private static void waitForJobs() throws Exception { while (submittedJobs.size() > 0) { // use an iterator instead of for each loop so that we can remove entries as we iterate. System.out.println("Checking for completion of " + submittedJobs.size() + " jobs"); for (Iterator it = submittedJobs.iterator(); it.hasNext(); ) { TaskResult tr = it.next(); if (tr.checkIfDone()) { displayTask(tr.getTaskId(), tr.getExitCode()); Task task = new Task(tr.getTaskId()); task.delete(); it.remove(); } } // wait 30 seconds Thread.sleep(30 * 1000); } System.out.println("All test jobs have finished."); } private static void displayTask(long taskId, int exitCode) throws Exception { Task task = new Task(taskId); System.out.println("Task " + taskId + " completed with exit code" + exitCode + ". Task Output: " ); Map> output = task.output(); if (output !=null) { for (String parameter : output.keySet()) { System.out.println("Parameter: " + parameter); List outputData = output.get(parameter); for (TaskOutputSourceDocument file : outputData) { System.out.println("Filename: " + file.getName()); if (file.getName().equals("EXIT_VALUE") || file.getName().equals("COMMANDLINE")) { displayContents(file); } } } } } static void displayContents(TaskOutputSourceDocument doc) { try { byte[] b = doc.getData(); if ((b != null) && b.length > 0) { System.out.println(new String(b)); } else { System.out.println("File is empty."); } } catch (Exception e) { System.out.println("Caught exception " + e.getMessage() + " trying to display file contents."); } System.out.println(); } private static String runCommand(String toolId) throws SQLException, IOException, DisabledResourceException { Task task = new Task(folder); task.setToolId(toolId); task.setLabel(toolId + "Task-" + System.currentTimeMillis()); task.toolParameters().putAll(toolParameterMap.get(toolId)); task.input().putAll(getInputData(toolId)); task.setStage(TaskRunStage.READY); task.save(); System.out.println("Task id = " + task.getTaskId()); return workbench.saveAndSubmitTask(task, folder, null); } //return map that keys input data to input parameter private static Map> getInputData(String toolId) { if (toolId == null) { throw new NullPointerException("Tool is null!"); } if (inputFileNameMap.containsKey(toolId) == false) { throw new NullPointerException("Tool + " + toolId + " is not registered"); } Map> inputData = new HashMap>(); for (String parameter : inputFileNameMap.get(toolId).keySet()) { String fileName = inputFileNameMap.get(toolId).get(parameter); byte[] docData = inputDataMap.get(fileName); if (docData == null) { throw new NullPointerException("No data registered for " + fileName); } List paramInput = new ArrayList(); // this will be stored in task.input(), which is a map of (I think) parameter name // to list of TaskInputSourceDocuments for that parameter. Here we're creating // the TaskInputSourceDocuments with a byte array of data, but they can also be // created from an existing item in the db with a ctor that just takes the // document ID or from an IOStream to avoid reading the whole thing into // memory. // paramInput.add(new TaskInputSourceDocument(fileName, docData)); inputData.put(parameter, paramInput); } return inputData; } //resolve properties into parameter map private static void readParameterProperties(Properties properties) { toolParameterMap = new HashMap>(); Enumeration propNames = properties.propertyNames(); while (propNames.hasMoreElements()) { String propertyKey = (String) propNames.nextElement(); String value = properties.getProperty(propertyKey); String[] combo = propertyKey.split("\\."); if (combo.length != 2) { throw new RuntimeException("Invalid property key: " + propertyKey); } String toolName = combo[0]; String parameter = combo[1]; if (toolParameterMap.containsKey(toolName) == false) { toolParameterMap.put(toolName, new HashMap()); } Map parameters = toolParameterMap.get(toolName); parameters.put(parameter, value); } } //resolve input file names properties into inputData map private static void readInputDataProperties(Properties properties) { inputFileNameMap = new HashMap>(); inputDataMap = new HashMap(); Enumeration propNames = properties.propertyNames(); while (propNames.hasMoreElements()) { String propertyKey = (String) propNames.nextElement(); String inputFileName = properties.getProperty(propertyKey); String[] combo = propertyKey.split("\\."); if (combo.length != 2) { throw new RuntimeException("Invalid property key: " + propertyKey); } String toolName = combo[0]; String parameter = combo[1]; if (inputDataMap.containsKey(inputFileName) == false) { byte[] data; //get a local data file into a byte[] try { data = Resource.getResource(inputFileName).getBytes(); } catch (ResourceNotFoundException e) { //that file cannot be found throw new RuntimeException(e.toString(), e); } inputDataMap.put(inputFileName, data); } if (inputFileNameMap.containsKey(toolName) == false) { inputFileNameMap.put(toolName, new HashMap()); } Map parameters = inputFileNameMap.get(toolName); parameters.put(parameter, inputFileName); } } private static Folder findFolderByLabel(List folders, String label) { for (Iterator elements = folders.iterator() ; elements.hasNext() ; ) { Folder folder = elements.next(); if (folder.getLabel().equals(label)) return folder; } return null; } }