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}