001package com.thed.util; 002 003import com.thed.zblast.util.RestUtil; 004import org.apache.commons.io.monitor.FileAlterationListener; 005import org.apache.commons.io.monitor.FileAlterationListenerAdaptor; 006import org.apache.commons.io.monitor.FileAlterationMonitor; 007import org.apache.commons.io.monitor.FileAlterationObserver; 008 009import java.io.File; 010import java.io.FileNotFoundException; 011import java.io.IOException; 012import java.util.LinkedList; 013import java.util.Map; 014import java.util.Queue; 015import java.util.Scanner; 016import java.util.logging.Logger; 017import com.thed.model.AutomationJobDetail; 018 019public class AutomationFileWatcher { 020 private static Logger logger = Logger.getLogger(ZephyrSoapClient.class.getName()); 021 private Queue<AutomationJobDetail> jobs=null; 022 private static Map<AutomationJobDetail, FileAlterationMonitor> monitor; 023 024 public String startWatching(AutomationJobDetail job, Queue<Queue<AutomationJobDetail>> queue, 025 Map<AutomationJobDetail, FileAlterationMonitor> monitorToStop, Map<Long, AutomationJobDetail> reusedFolderWatchJobDetails) throws Exception { 026 // The monitor will perform polling on the folder for minutes mentioned. 027 monitor=monitorToStop; 028 final long pollingInterval = job.getDelay() * 1000 * 60; 029 File folder = new File(job.getFolderPath()); 030 FileAlterationObserver observer = new FileAlterationObserver(folder); 031 FileAlterationMonitor monitor = new FileAlterationMonitor(pollingInterval, observer); 032 FileAlterationListener listener = new FileAlterationListenerAdaptor() { 033 // Is triggered when a file is created in the monitored folder 034 @Override 035 public void onFileCreate(File file) { 036 if(jobs==null) { 037 jobs=new LinkedList<>(); 038 } 039 createAutomationJob(file); 040 } 041 042 @Override 043 public void onFileChange(File file) { 044 if(jobs==null) { 045 jobs=new LinkedList<>(); 046 } 047 createAutomationJob(file); 048 } 049 050 @Override 051 public void onStop(FileAlterationObserver observer) { 052 File directory = observer.getDirectory(); 053 if (!directory.exists()) { 054 try { 055 stopJobForDeletedFolder(directory, monitorToStop); 056 } catch (Exception e) { 057 logger.severe("Exception while stopping folderwatch. " + e); 058 } 059 }else { 060 if(jobs!=null && !jobs.isEmpty()) { 061 addJobsoQueue(); 062 } 063 } 064 } 065 066 private void createAutomationJob(File file) { 067 try { 068 if (job.getAutomationFramework().equalsIgnoreCase(ZeeConstants.TEST_NG)) { 069 if (file.getName().endsWith(".xml") && !isTestNgFile(file)) { 070 return; 071 } 072 } 073 if (job.getAutomationFramework().equalsIgnoreCase(ZeeConstants.EGG_PLANT)) { 074 if (!file.getName().equalsIgnoreCase("SuiteStatistics.csv")) { 075 return; 076 } 077 } else { 078 if (!file.getName().endsWith(".xml")) { 079 return; 080 } 081 } 082 AutomationJobDetail detail = new AutomationJobDetail(); 083 AutomationJobDetail reUseJob=null; 084 if(job.getIsReuse()){ 085 reUseJob=getCorrespondingReusableJob(job.getId(),job); 086 }else{ 087 reUseJob=job; 088 } 089 detail.setAutomationFramework(reUseJob.getAutomationFramework()); 090 detail.setCycleDuration(reUseJob.getCycleDuration()); 091 detail.setCreatePackage(reUseJob.getCreatePackage()); 092 detail.setResultPath(file.getAbsolutePath()); 093 detail.setZbotAgentMachine(reUseJob.getZbotAgentMachine()); 094 detail.setPhaseName(reUseJob.getPhaseName()); 095 detail.setReleaseId(reUseJob.getReleaseId()); 096 detail.setProjectId(reUseJob.getProjectId()); 097 detail.setCreatePhase(reUseJob.getCreatePhase()); 098 detail.setCycleName(reUseJob.getCycleName()); 099 detail.setFromFileWatcher(true); 100 detail.setId(reUseJob.getId()); 101 detail.setCycleStartDate(reUseJob.getCycleStartDate()); 102 detail.setCycleEndDate(reUseJob.getCycleEndDate()); 103 detail.setIsTimeStamp(reUseJob.getIsTimeStamp()); 104 detail.setAssignResultsTo(reUseJob.getAssignResultsTo()); 105 detail.setCyclePhaseId(reUseJob.getCyclePhaseId()); 106 detail.setCycleId(reUseJob.getCycleId()); 107 detail.setTcrCatalogTreeId(reUseJob.getTcrCatalogTreeId()); 108 detail.setIsReuse(reUseJob.getIsReuse()); 109 detail.setParserTemplate(reUseJob.getParserTemplate()); 110 jobs.offer(detail); 111 RestUtil.updateFileWatcher(job, ZeeConstants.ZBLAST_FILE_JOB_STATUS_RUNNING, 112 ZeeConstants.JOB_INFO_MESSAGE.replace("{fileName}", file.getName())); 113 } catch (IOException e) { 114 logger.severe("Exception while processing folder watch object ." + e); 115 } 116 } 117 118 private AutomationJobDetail getCorrespondingReusableJob(Long jobId,AutomationJobDetail automationJob) { 119 AutomationJobDetail automationJobDetail = reusedFolderWatchJobDetails.get(jobId); 120 if(automationJobDetail==null){ 121 automationJobDetail=job; 122 } 123 return automationJobDetail; 124 } 125 126 private void addJobsoQueue() { 127 queue.offer(jobs); 128 jobs=null; 129 } 130 }; 131 observer.checkAndNotify(); 132 observer.addListener(listener); 133 monitor.addObserver(observer); 134 monitor.start(); 135 updateStatus(job, ZeeConstants.ZBLAST_FILE_JOB_STATUS_RUNNING,ZeeConstants.ZBLAST_FILE_JOB_STATUS_RUNNING); 136 monitorToStop.put(job, monitor); 137 return null; 138 } 139 140 private void stopJobForDeletedFolder(File directory, Map<AutomationJobDetail, FileAlterationMonitor> monitorToStop) throws Exception { 141 for (Map.Entry<AutomationJobDetail, FileAlterationMonitor> monitors : monitorToStop.entrySet()) { 142 if (monitors.getKey().getFolderPath().equals(directory.getAbsolutePath())) { 143 FileAlterationMonitor jobToStop = monitors.getValue(); 144 AutomationJobDetail job = monitors.getKey(); 145 try { 146 monitorToStop.remove(job); 147 stopFolderWatch(job, jobToStop, ZeeConstants.ZBLAST_FOLDER_NOT_AVAILABLE,true); 148 } catch (IOException e) { 149 logger.severe("Exception while stopping folder watch. " + e); 150 throw new Exception(e); 151 } 152 } 153 } 154 } 155 156 public static void stopFolderWatch(AutomationJobDetail job, FileAlterationMonitor monitor, String description, boolean isUpdateRequired) throws Exception { 157 try { 158 monitor.stop(1l); 159 String status = ""; 160 String desc = ""; 161 if (job.getStatus().equalsIgnoreCase(ZeeConstants.STATUS_TO_BE_DELETED)) 162 status = ZeeConstants.ZBLAST_FILE_JOB_STATUS_DELETED; 163 else 164 status = ZeeConstants.ZBLAST_FILE_JOB_STATUS_STOPPED; 165 166 if (description != null) 167 desc = description; 168 else 169 desc = ZeeConstants.ZBLAST_FILE_JOB_STATUS_STOPPED_DESC; 170 if(isUpdateRequired) { 171 updateStatus(job, status, desc); 172 } 173 } catch (Exception e) { 174 updateStatus(job, ZeeConstants.ZBLAST_JOB_STATUS_ERROR, "Error while stopping file watcher"); 175 logger.severe("Exception while stopping folderwatch. " + e); 176 throw new Exception(e); 177 } 178 } 179 180 public static void updateStatus(AutomationJobDetail automationJobDetail, String status, String description) throws IOException { 181 RestUtil.updateFileWatcher(automationJobDetail, status, description); 182 } 183 184 public boolean isTestNgFile(File testNgFile) { 185 boolean isTestNg = false; 186 int i = 1; 187 try { 188 Scanner scanner = new Scanner(testNgFile); 189 while (scanner.hasNextLine()) { 190 String line = scanner.nextLine(); 191 if (i > 5) { 192 break; 193 } 194 if (line.contains("<testng-results ")) { 195 isTestNg = true; 196 break; 197 } 198 i++; 199 } 200 scanner.close(); 201 } catch (FileNotFoundException e) { 202 //handle this 203 } 204 return isTestNg; 205 } 206}