1 package user.jobengine.server.steps;
\r
4 import java.io.IOException;
\r
5 import java.nio.file.DirectoryStream;
\r
6 import java.nio.file.FileVisitResult;
\r
7 import java.nio.file.FileVisitor;
\r
8 import java.nio.file.Files;
\r
9 import java.nio.file.Path;
\r
10 import java.nio.file.Paths;
\r
11 import java.nio.file.SimpleFileVisitor;
\r
12 import java.nio.file.attribute.BasicFileAttributes;
\r
13 import java.text.ParseException;
\r
14 import java.text.SimpleDateFormat;
\r
15 import java.util.ArrayList;
\r
16 import java.util.Collections;
\r
17 import java.util.Date;
\r
18 import java.util.List;
\r
20 import org.apache.commons.io.FileUtils;
\r
21 import org.apache.commons.lang.StringUtils;
\r
22 import org.apache.logging.log4j.LogManager;
\r
23 import org.apache.logging.log4j.Logger;
\r
24 import org.apache.logging.log4j.Marker;
\r
26 import user.jobengine.server.IJobEngine;
\r
27 import user.jobengine.server.IJobRuntime;
\r
28 import user.jobengine.server.steps.shared.MetadataType;
\r
29 import user.jobengine.server.steps.shared.MetadataTypeDetector;
\r
31 public class ProjectCleanupMountedLocationStep extends JobStep implements FileVisitor<Path> {
\r
33 private static final Logger logger = LogManager.getLogger();
\r
34 private static final String DATEFORMAT = "yyyyMMdd";
\r
35 private static final String DOT = ".";
\r
36 private static final String STATUSFOLDER = ".STATUS";
\r
37 private static final String KILLDATEEXT = ".killdate";
\r
38 private Marker marker;
\r
39 final int[] allCount = { 0 };
\r
40 final int[] currentCount = { 0 };
\r
41 private Path sourcePath;
\r
42 private SimpleDateFormat dateFormat;
\r
44 private Date checkExpiration(List<Path> killDateFiles) {
\r
45 Date killDate = null;
\r
46 for (Path killDateFile : killDateFiles) {
\r
47 Date currentKillDate = getKillDate(killDateFile);
\r
48 if (currentKillDate == null)
\r
50 if ((killDate != null && currentKillDate.after(killDate)) || killDate == null)
\r
51 killDate = currentKillDate;
\r
53 return new Date().after(killDate) ? killDate : null;
\r
57 public Object[] execute(String sourceFolder, IJobEngine jobEngine, IJobRuntime jobRuntime) throws Exception {
\r
58 marker = jobRuntime.getSessionMarker();
\r
59 sourcePath = Paths.get(sourceFolder);
\r
60 DirectoryStream<Path> directoryStream = null;
\r
61 if (StringUtils.isBlank(sourcePath.toString())) {
\r
62 logger.error(marker, "A folyamat 'sourcePath' bemeneti paramétere üres.");
\r
63 throw new NullPointerException(
\r
64 "System is not configured properly, 'sourceFolder' input parameter missing.");
\r
67 if (!sourcePath.toFile().exists() || !sourcePath.toFile().isDirectory()) {
\r
68 logger.error(marker, "A(z) {} mappa nem létezik.", sourceFolder);
\r
69 throw new NullPointerException(String.format("Directory %s does not exist.", sourceFolder));
\r
73 dateFormat = new SimpleDateFormat(DATEFORMAT);
\r
74 Files.walkFileTree(sourcePath, new SimpleFileVisitor<Path>() {
\r
76 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
\r
78 return super.visitFile(file, attrs);
\r
81 Files.walkFileTree(sourcePath, this);
\r
82 } catch (Exception e) {
\r
84 logger.error(marker, "Az '{}' mappa elérése sikertelen. A rendszer hibaüzenete: {}", sourcePath,
\r
88 if (directoryStream != null) {
\r
90 directoryStream.close();
\r
91 } catch (IOException e) {
\r
98 private Date getKillDate(Path killDateFile) {
\r
99 String fileName = killDateFile.getFileName().toString();
\r
100 int end = fileName.lastIndexOf(DOT);
\r
103 int start = fileName.lastIndexOf(DOT, end - 1);
\r
106 String strKillDate = fileName.substring(start + 1, end);
\r
107 Date result = null;
\r
108 if (StringUtils.isNumeric(strKillDate)) {
\r
110 result = dateFormat.parse(strKillDate);
\r
111 } catch (ParseException e) {
\r
112 logger.error(marker,
\r
113 "A {} fájl 'killdate' állománya hibás formátumú, a {} karaktersorozat nem konvertálható dátummá.",
\r
114 fileName, strKillDate);
\r
118 logger.error(marker, "A {} fájl 'killdate' állománya hibás formátumú, az dátum helyett ez áll: '{}'.",
\r
119 fileName, strKillDate);
\r
123 private List<Path> getKillDateFiles(Path filePath) {
\r
124 String killDateFilePattern = String.format("%s.*%s", filePath.getFileName().toString(), KILLDATEEXT);
\r
125 List<Path> result = new ArrayList<>();
\r
126 Path statusPath = null;
\r
128 statusPath = Paths.get(filePath.getParent().toString(), STATUSFOLDER);
\r
129 } catch (Exception e) {
\r
130 logger.catching(e);
\r
133 File statusPathFile = statusPath.toFile();
\r
134 if (statusPathFile.exists() && statusPathFile.isDirectory()) {
\r
135 try (DirectoryStream<Path> stream = Files.newDirectoryStream(statusPath, killDateFilePattern)) {
\r
136 stream.forEach(p -> result.add(p));
\r
137 } catch (Exception e) {
\r
138 logger.catching(e);
\r
141 Collections.sort(result);
\r
145 private Path getProjectRootPath(Path filePath) {
\r
146 Path result = null;
\r
147 if (filePath.getNameCount() > sourcePath.getNameCount()) {
\r
148 String dir = filePath.getName(sourcePath.getNameCount()).toString();
\r
149 String[] tokens = dir.split("-");
\r
150 if (tokens.length != 0 && MetadataTypeDetector.GuessMetadataType(tokens[0]) == MetadataType.TrafficPromo)
\r
151 result = Paths.get(sourcePath.toAbsolutePath().toString(), dir);
\r
157 public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
\r
158 return FileVisitResult.CONTINUE;
\r
162 public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
\r
163 if (dir.equals(sourcePath))
\r
164 return FileVisitResult.CONTINUE;
\r
166 Path parent = getProjectRootPath(dir);
\r
167 if (parent == null) {
\r
168 System.out.println("Skipping " + dir);
\r
169 return FileVisitResult.SKIP_SUBTREE;
\r
172 return FileVisitResult.CONTINUE;
\r
175 private boolean processPathItem(Path filePath) {
\r
177 int progress = currentCount[0] * 100 / allCount[0];
\r
178 setProgress(progress);
\r
180 if (filePath.toFile().isDirectory() || !filePath.toString().toUpperCase().endsWith(".EZP"))
\r
184 if (filePath.getNameCount() != sourcePath.getNameCount() + 3) {
\r
185 // logger.warn(marker, "A {} fájl elérési útja a várttól eltérő.", filePath);
\r
189 List<Path> killDateFiles = getKillDateFiles(filePath);
\r
190 if (killDateFiles == null || killDateFiles.size() == 0) {
\r
191 logger.warn(marker, "A {} fájlhoz nem található 'killdate' állomány.", filePath);
\r
195 if (killDateFiles.size() != 1)
\r
196 logger.warn(marker,
\r
197 "A {} fájlhoz több 'killdate' állomány található, a legújabb dátum határozza meg a törlés időpontját.",
\r
200 Date killDate = checkExpiration(killDateFiles);
\r
201 if (killDate == null)
\r
204 Path parent = getProjectRootPath(filePath);
\r
205 if (parent != null) {
\r
206 Path pathToDelete = Paths.get(sourcePath.toAbsolutePath().toString(),
\r
207 filePath.getName(sourcePath.getNameCount()).toString());
\r
209 FileUtils.deleteDirectory(pathToDelete.toFile());
\r
210 logger.info(marker, "A {} mappa sikeresen törlődött. Lejárat: {}", pathToDelete,
\r
211 dateFormat.format(killDate));
\r
212 } catch (Exception e) {
\r
213 logger.error(marker, "A {} mappa törlése nem lehetséges, a rendszer üzenete: {}", pathToDelete,
\r
219 // logger.warn(marker, "A {} fájlhoz nem határozható meg a törlendő
\r
220 // szülőkönyvtár.", filePath);
\r
225 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
\r
226 processPathItem(file);
\r
227 return FileVisitResult.CONTINUE;
\r
231 public FileVisitResult visitFileFailed(Path file, IOException e) throws IOException {
\r
232 logger.error(marker, "A {} fájl nem érhető el. A rendszer hibaüzenete: {}", file.toString(), e.getMessage());
\r
233 return FileVisitResult.CONTINUE;
\r