package com.cipres.mrBayesPlugin.utilities; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.net.NoRouteToHostException; import java.net.UnknownHostException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.zip.GZIPInputStream; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import org.ngbw.directclient.CiCipresException; import org.ngbw.directclient.CiClient; import org.ngbw.directclient.CiJob; import org.ngbw.directclient.CiResultFile; import org.ngbw.restdatatypes.ErrorData; import org.ngbw.restdatatypes.LimitStatus; import org.ngbw.restdatatypes.ParamError; import com.biomatters.geneious.publicapi.components.Dialogs; import com.biomatters.geneious.publicapi.databaseservice.DatabaseServiceException; import com.biomatters.geneious.publicapi.databaseservice.WritableDatabaseService; import com.biomatters.geneious.publicapi.plugin.DocumentImportException; import com.biomatters.geneious.publicapi.plugin.PluginUtilities; import com.cipres.mrBayesPlugin.models.UserModel; import com.cipres.mrBayesPlugin.models.UserModel.Job; import jebl.util.ProgressListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Utility class that handles any CIPRES actions such as submit, and list jobs * @author rjzheng * */ public class CipresUtilities { private static final Logger slf4jLogger = LoggerFactory.getLogger(CipresUtilities.class); private static final String HOMEDIR = System.getProperty("user.home"); private static final String FILESEP = File.separator; private static final String NEWLINE = System.getProperty("line.separator"); //private static final String CONFIGFILE = "pycipres.conf"; public static final String CONFIGFILE = "geneious_cipres.conf"; public static final String SERVICEURL = "https://cipresrest.sdsc.edu/cipresrest/v1"; //public static final String APPNAME = "MRBAYES_XSEDE"; public static final String APPNAME = "Geneious_Cipres"; //public static final String APPID = "MRBAYES_XSEDE-1CA75045991B494BB3ED2D1F597AB503"; public static final String APPID = "Geneious_Cipres-24704BCC103749D8BD17369694AB1F72"; public static final String DASH = "-"; public static final String COLON = ":"; public static final String UNDERSCORE = "_"; public static final String REPORTEMAIL = "mmiller@sdsc.edu"; public static ClientCheckResult clientCheck(CiClient myClient){ try { myClient.listJobs(); return ClientCheckResult.TRUE; } catch (CiCipresException e) { if (e.getHttpStatus() == 401) return ClientCheckResult.UNAUTHORIZED; else return ClientCheckResult.FALSE; } catch (Exception ne) { if ((ne instanceof UnknownHostException) || (ne instanceof NoRouteToHostException) || (ne.toString().contains("UnknownHostException")) || (ne.toString().contains("NoRouteToHostException"))) Dialogs.showMessageDialog("The CIPRES server cannot be reached.\nPlease check your internet connetion."); else throw ne; } return ClientCheckResult.FALSE; } /** * * @return config file path */ public static String getConfigFilePath(){ return HOMEDIR + FILESEP + CONFIGFILE; } public static boolean checkEmptyString(String testStr){ boolean check = false; if(testStr == null || testStr.trim().equals("")){ check = true; } return check; } public static boolean isNewUser() { File configFile = new File(CipresUtilities.getConfigFilePath()); return !configFile.exists(); } /** * Fetch and save user's jobs * @param myClient * @param user * @throws CiCipresException */ public static void listJobs(CiClient myClient, UserModel user) throws CiCipresException { //Create a handler instance DataHandlingUtilities handler = DataHandlingUtilities.getInstance(); handler.clearJobs(); //Fetch jobs from CIPRES Collection jobs = myClient.listJobs(); //Save jobs for (CiJob job : jobs) { Job newJob = user.new Job(); newJob.setJobName(job.getClientJobName()); newJob.setJobStage(job.getJobStage()); newJob.setDate(job.getDateSubmitted()); handler.addJob(newJob); } //Set user's jobs user.setJobs(handler.getJobs()); } public static Collection getJobs(CiClient myClient) throws CiCipresException{ //Create a handler instance DataHandlingUtilities handler = DataHandlingUtilities.getInstance(); handler.clearJobs(); //Fetch jobs from CIPRES Collection jobs = myClient.listJobs(); return jobs; } public static JSONArray updateList(CiClient myClient, UserModel user) throws ParseException{ //Create a handler instance DataHandlingUtilities handler = DataHandlingUtilities.getInstance(); try { CipresUtilities.listJobs(myClient, user); } catch (CiCipresException e) { // TODO Auto-generated catch block e.printStackTrace(); } // handler.saveData("jobs.json", handler.getUserJSON()); // JSONObject retObj = handler.loadData("jobs.json"); JSONParser parser = new JSONParser(); Object obj = parser.parse(handler.getUserJSON()); JSONArray retJSONArray = handler.getJobs((JSONObject)obj); return retJSONArray; } /*** public static void deleteJobs(List selected_jobs, Collection allJobs) throws CiCipresException { for(int i = 0; i < selected_jobs.size(); i++){ for(int x = 0; x < allJobs.size(); x++){ CiJob job = (CiJob) allJobs.toArray()[x]; System.out.println("local: " + selected_jobs.get(i)); System.out.println("cloud" + job.getClientJobName()); if(selected_jobs.get(i).equals(job.getClientJobName())){ job.delete(); selected_jobs.remove(i); System.out.println(job.getClientJobName() + " deleted"); //Dialogs.showContinueCancelDialog("Incorrect user information", "Error!", null, Dialogs.DialogIcon.ERROR); } } } } ***/ /** * @author Madhusudan Gujral (rewritten) * @param selectedJobs * @param allJobs * @throws CiCipresException */ public static void deleteJobs(List selectedJobs, Collection allJobs) throws CiCipresException { for(String selectedJob: selectedJobs){ for(CiJob job: allJobs){ String jobNameWithDateAndTime = job.getClientJobName() + DASH + job.getDateSubmitted().toString(); if(selectedJob.equals(jobNameWithDateAndTime)){ job.delete(); System.out.println(jobNameWithDateAndTime + " deleted"); } } } } /** * @author Madhusudan Gujral */ public static void downloadJobs(List selectedJobs, Collection allJobs, String dwnldFldr) throws CiCipresException{ //slf4jLogger.info("Welcome to the CipresUtilities"); System.out.println("Welcome to the CipresUtilities"); StringBuilder folderPresentMessage = new StringBuilder(); StringBuilder importErrorMessage = new StringBuilder(); StringBuilder exceptionMessage = new StringBuilder(); boolean check = false; boolean imported = false; for(SelectedJobInfo selectedJobInfo: selectedJobs){ String selectedJob = selectedJobInfo.getSelectedJobNameWithDate(); System.out.println("Selected Job: " + selectedJob); String folderForFiles = dwnldFldr + FILESEP + selectedJob.replaceAll(" ", "-" ).replaceAll(COLON, UNDERSCORE); for(CiJob job: allJobs){ String jobNameWithDateAndTime = job.getClientJobName() + DASH + job.getDateSubmitted().toString(); if(selectedJob.equals(jobNameWithDateAndTime)){ Collection resultsFileCollection = job.listResults(true); for(CiResultFile resultFile: resultsFileCollection){ String fName = resultFile.getName(); System.out.println("File name: " + fName); //Dialogs.showMessageDialog(fName); } try{ System.out.println("New folder path: " + folderForFiles); File fileFldr = new File(folderForFiles); // Added time stamp to download folder int count = 1; String baseFolderForFiles = folderForFiles; while (fileFldr.exists()) { folderForFiles = baseFolderForFiles + "(" + count + ")"; fileFldr = new File(folderForFiles); ++count; } if (!fileFldr.exists()) { if (fileFldr.mkdir()){ System.out.println("Download folder: " + folderForFiles); } job.downloadResults(new File(folderForFiles), true); if (selectedJobInfo.getImported()) { String error = addToYourLocalDatabase(resultsFileCollection, folderForFiles, selectedJobInfo.getLocalFolder()); if (!error.isEmpty()) { importErrorMessage.append(addToYourLocalDatabase(resultsFileCollection, folderForFiles, selectedJobInfo.getLocalFolder())); importErrorMessage.append("\n"); } else imported = true; } }else{ if(!check){ folderPresentMessage.append("Following jobs could not be downloaded because their folder " + "names are already present in the selected folder." + NEWLINE); folderPresentMessage.append(jobNameWithDateAndTime.replaceAll(" ", "-" ) + NEWLINE); check = true; }else{ folderPresentMessage.append(jobNameWithDateAndTime.replaceAll(" ", "-" ) + NEWLINE); } } //job.downloadResults(new File(folderForFiles), true); }catch(Exception e){ System.out.println("Problem in downloading file: "); e.printStackTrace(); if (exceptionMessage.length() == 0 ) exceptionMessage.append("Below exception(s) occurred while downloading data. Please try your download again in a few minutes. Thank you!\n"); exceptionMessage.append(e.toString()); exceptionMessage.append("\n"); } } } } if(!checkEmptyString(folderPresentMessage.toString())){ Dialogs.showMessageDialog(folderPresentMessage.toString().trim()); } else if (!importErrorMessage.toString().isEmpty()) Dialogs.showMessageDialog(importErrorMessage.toString()); else if (!exceptionMessage.toString().isEmpty()) Dialogs.showMessageDialog(exceptionMessage.toString()); else Dialogs.showMessageDialog("The results of selected job(s) have been downloaded" + (imported? " and imported to Sources Panel." : ".")); } public static void submitJob(String tool, Map> vParams, Map inputParams, Map metadata) throws CiCipresException{ CiJob jobStatus = null; try { System.err.println("SubmitJob enter"); DataHandlingUtilities handler = DataHandlingUtilities.getInstance(); CiClient myClient = handler.getClient(); if(CipresUtilities.clientCheck(myClient) == ClientCheckResult.TRUE){ try { jobStatus = myClient.submitJob(tool, vParams, inputParams, metadata); } catch (CiCipresException ce) { StringBuffer sb = new StringBuffer(); ErrorData ed = ce.getErrorData(); sb.append("Cipres error code="); sb.append(ed.code); sb.append(", message="); sb.append(ed.displayMessage); sb.append("\n\n"); if (ed.code == ErrorData.FORM_VALIDATION) { for (ParamError pe : ed.paramError) { sb.append(pe.param); sb.append(": "); sb.append(pe.error); sb.append("\n"); } } else if (ed.code == ErrorData.USAGE_LIMIT) { LimitStatus ls = ed.limitStatus; sb.append("Usage Limit Error, type="); sb.append(ls.type); sb.append(", ceiling="); sb.append(ls.ceiling); sb.append("\n"); } Dialogs.showMessageDialog(sb.toString(), "Error Message(s) from REST Server"); throw ce; } }else{ System.err.println("No Client Found"); } } catch (Exception ne) { if ((ne instanceof UnknownHostException) || (ne instanceof NoRouteToHostException) || (ne.toString().contains("UnknownHostException")) || (ne.toString().contains("NoRouteToHostException"))) Dialogs.showMessageDialog("The CIPRES server cannot be reached.\nPlease check your internet connetion."); else throw ne; } if (jobStatus != null) jobStatus.show(true); } public static String addToYourLocalDatabase(Collection resultsFileCollection, String sourceFolder, String targetFolder) { WritableDatabaseService database= (WritableDatabaseService) PluginUtilities.getGeneiousService("LocalDocuments"); try { if (targetFolder != null && !targetFolder.isEmpty()) { String[] subfolders = targetFolder.split("/"); for (String subfolder : subfolders) { if (!subfolder.trim().isEmpty()) database = database.createChildFolder(subfolder); } } //boolean allowStdErrOut = false; List unzipFiles = new ArrayList(); for (CiResultFile file : resultsFileCollection) { //if (file.getName().equals("stderr.txt") && file.getLength() > 0) // allowStdErrOut = true; //if (file.getName().endsWith(".ckp.gz")) // continue; if (file.getName().endsWith(".gz")) { String sourceFile = sourceFolder + File.separator + file.getName(); String targetFile = sourceFolder + File.separator + file.getName().substring(0, file.getName().length()-3); unzipGZFile(sourceFile, targetFile); unzipFiles.add(targetFile); } } for (CiResultFile file : resultsFileCollection) { if (file.getName().endsWith("TXT") || file.getName().endsWith("conf") || file.getName().endsWith("STDERR") || file.getName().endsWith("STDOUT") || file.getName().contains((CharSequence)".ckp.") || file.getName().endsWith(".gz")) { //if (file.getName().endsWith("JOBINFO.TXT") || file.getName().endsWith("conf") || file.getName().endsWith("STDERR") || file.getName().endsWith("STDOUT")) continue; } if (file.getName().endsWith("txt")) { //if (!allowStdErrOut || (!file.getName().equals("stderr.txt") && !file.getName().equals("stdout.txt"))) //if (!file.getName().equals("stderr.txt") && !file.getName().equals("stdout.txt")) // continue; if (file.getName().startsWith("_scheduler") || file.getName().equals("done.txt") || file.getName().equals("start.txt") || file.getName().equals("term.txt")) continue; if (file.getLength() == 0) continue; } String fileName = file.getName(); if (file.getName().endsWith(".p") || file.getName().endsWith(".tstat") || file.getName().endsWith(".vstat")) { Path source = Paths.get(sourceFolder + File.separator + file.getName()); if (fileName.contains(".txt")) { CharSequence cs1 = new StringBuffer(".txt"); CharSequence cs2 = new StringBuffer(""); fileName = fileName.replace(cs1, cs2); } fileName = fileName + ".txt"; try { Files.move(source, source.resolveSibling(fileName)); } catch (Exception e) { fileName = file.getName(); } } File importfile = new File(sourceFolder + File.separator + fileName); //File importfile = new File(sourceFolder + File.separator + file.getName()); //new File("C:\\Users\\mzhuang\\MyGeneious_job_download\\Three-Kingdoms-Thu-Apr-25-12_19_16-PDT-2019\\infile.nex.run1.p"); try { System.out.println("Importing " + importfile.getAbsolutePath()); PluginUtilities.importDocumentsToDatabase(importfile, database, ProgressListener.EMPTY); } catch (DocumentImportException | IOException e) { e.printStackTrace(); } } for (String file : unzipFiles) { if (file.endsWith("TXT") || file.endsWith("conf") || file.endsWith("STDERR") || file.endsWith("STDOUT") || file.contains((CharSequence)".ckp.") || file.endsWith(".gz")) { //if (file.getName().endsWith("JOBINFO.TXT") || file.getName().endsWith("conf") || file.getName().endsWith("STDERR") || file.getName().endsWith("STDOUT")) continue; } if (file.endsWith("txt")) { if (!file.equals("stderr.txt") && !file.equals("stdout.txt")) continue; //if (file.getLength() == 0) // continue; } File importfile = new File(file); try { PluginUtilities.importDocumentsToDatabase(importfile, database, ProgressListener.EMPTY); } catch (DocumentImportException | IOException e) { e.printStackTrace(); } } } catch (DatabaseServiceException e) { return e.getMessage(); } return ""; } private static void unzipGZFile(String sourceFile, String targetFile) { FileInputStream fis = null; GZIPInputStream gzis = null; FileOutputStream fos = null; try { // Create a file input stream to read the source file. fis = new FileInputStream(sourceFile); // Create a gzip input stream to decompress the source // file defined by the file input stream. gzis = new GZIPInputStream(fis); // Create file output stream where the decompress result // will be stored. fos = new FileOutputStream(targetFile); // Create a buffer and temporary variable used during the // file decompress process. byte[] buffer = new byte[1024]; int length; // Read from the compressed source file and write the // decompress file. while ((length = gzis.read(buffer)) > 0) { fos.write(buffer, 0, length); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (gzis != null) gzis.close(); if (fis != null) fis.close(); if (fos != null) fos.close(); } catch (IOException e) {} } } }