3fdc396a8fb66102deb8e7952cb04c28ac5a3f6a
[mediacube.git] /
1 package user.jobengine.server.steps;\r
2 \r
3 import java.io.File;\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
19 \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
25 \r
26 import user.jobengine.server.IJobEngine;\r
27 import user.jobengine.server.IJobRuntime;\r
28 \r
29 public class ProjectCleanupMountedLocationStep extends JobStep implements FileVisitor<Path> {\r
30 \r
31         private static final Logger logger = LogManager.getLogger();\r
32         private static final String DATEFORMAT = "yyyyMMdd";\r
33         private static final String DOT = ".";\r
34         private static final String STATUSFOLDER = ".STATUS";\r
35         private static final String KILLDATEEXT = ".killdate";\r
36         private Marker marker;\r
37         final int[] allCount = { 0 };\r
38         final int[] currentCount = { 0 };\r
39         private Path sourcePath;\r
40         private SimpleDateFormat dateFormat;\r
41 \r
42         private Date checkExpiration(List<Path> killDateFiles) {\r
43                 Date killDate = null;\r
44                 for (Path killDateFile : killDateFiles) {\r
45                         Date currentKillDate = getKillDate(killDateFile);\r
46                         if (currentKillDate == null)\r
47                                 continue;\r
48                         if ((killDate != null && currentKillDate.after(killDate)) || killDate == null)\r
49                                 killDate = currentKillDate;\r
50                 }\r
51                 return new Date().after(killDate) ? killDate : null;\r
52         }\r
53 \r
54         @StepEntry\r
55         public Object[] execute(String sourceFolder, IJobEngine jobEngine, IJobRuntime jobRuntime) throws Exception {\r
56                 marker = jobRuntime.getSessionMarker();\r
57                 sourcePath = Paths.get(sourceFolder);\r
58                 DirectoryStream<Path> directoryStream = null;\r
59                 if (StringUtils.isBlank(sourcePath.toString())) {\r
60                         logger.error(marker, "A folyamat 'sourcePath' bemeneti paramétere üres.");\r
61                         throw new NullPointerException("System is not configured properly, 'sourceFolder' input parameter missing.");\r
62                 }\r
63 \r
64                 if (!sourcePath.toFile().exists() || !sourcePath.toFile().isDirectory()) {\r
65                         logger.error(marker, "A {} mappa nem létezik.", sourceFolder);\r
66                         throw new NullPointerException(String.format("Directory %s not exists.", sourceFolder));\r
67                 }\r
68                 try {\r
69                         setProgress(1);\r
70                         dateFormat = new SimpleDateFormat(DATEFORMAT);\r
71                         Files.walkFileTree(sourcePath, new SimpleFileVisitor<Path>() {\r
72                                 @Override\r
73                                 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\r
74                                         allCount[0]++;\r
75                                         return super.visitFile(file, attrs);\r
76                                 }\r
77                         });\r
78                         Files.walkFileTree(sourcePath, this);\r
79                 } catch (Exception e) {\r
80                         logger.catching(e);\r
81                         logger.error(marker, "Az '{}' mappa elérése sikertelen. A rendszer hibaüzenete: {}", sourcePath, e.getMessage());\r
82                         throw e;\r
83                 } finally {\r
84                         if (directoryStream != null) {\r
85                                 try {\r
86                                         directoryStream.close();\r
87                                 } catch (IOException e) {\r
88                                 }\r
89                         }\r
90                 }\r
91                 return null;\r
92         }\r
93 \r
94         private Date getKillDate(Path killDateFile) {\r
95                 String fileName = killDateFile.getFileName().toString();\r
96                 int end = fileName.lastIndexOf(DOT);\r
97                 if (end < 1)\r
98                         return null;\r
99                 int start = fileName.lastIndexOf(DOT, end - 1);\r
100                 if (start < 0)\r
101                         return null;\r
102                 String strKillDate = fileName.substring(start + 1, end);\r
103                 Date result = null;\r
104                 if (StringUtils.isNumeric(strKillDate)) {\r
105                         try {\r
106                                 result = dateFormat.parse(strKillDate);\r
107                         } catch (ParseException e) {\r
108                                 logger.error(marker, "A {} fájl 'killdate' állománya hibás formátumú, a {} karaktersorozat nem konvertálható dátummá.", fileName, strKillDate);\r
109                                 return null;\r
110                         }\r
111                 } else\r
112                         logger.error(marker, "A {} fájl 'killdate' állománya hibás formátumú, az dátum helyett ez áll: '{}'.", fileName, strKillDate);\r
113                 return result;\r
114         }\r
115 \r
116         private List<Path> getKillDateFiles(Path filePath) {\r
117                 String killDateFilePattern = String.format("%s.*%s", filePath.getFileName().toString(), KILLDATEEXT);\r
118                 List<Path> result = new ArrayList<>();\r
119                 Path statusPath = null;\r
120                 try {\r
121                         statusPath = Paths.get(filePath.getParent().toString(), STATUSFOLDER);\r
122                 } catch (Exception e) {\r
123                         logger.catching(e);\r
124                         return null;\r
125                 }\r
126                 File statusPathFile = statusPath.toFile();\r
127                 if (statusPathFile.exists() && statusPathFile.isDirectory()) {\r
128                         try (DirectoryStream<Path> stream = Files.newDirectoryStream(statusPath, killDateFilePattern)) {\r
129                                 stream.forEach(p -> result.add(p));\r
130                         } catch (Exception e) {\r
131                                 logger.catching(e);\r
132                         }\r
133                 }\r
134                 Collections.sort(result);\r
135                 return result;\r
136         }\r
137 \r
138         private Path getProjectRootPath(Path filePath) {\r
139                 Path result = null;\r
140                 if (filePath.getNameCount() > sourcePath.getNameCount()) {\r
141                         String dir = filePath.getName(sourcePath.getNameCount()).toString();\r
142                         String[] tokens = dir.split("-");\r
143                         if (tokens.length != 0 && MetadataTypeDetector.GuessMetadataType(tokens[0]) == MetadataType.TrafficPromo)\r
144                                 result = Paths.get(sourcePath.toAbsolutePath().toString(), dir);\r
145                 }\r
146                 return result;\r
147         }\r
148 \r
149         @Override\r
150         public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {\r
151                 return FileVisitResult.CONTINUE;\r
152         }\r
153 \r
154         @Override\r
155         public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {\r
156                 if (dir.equals(sourcePath))\r
157                         return FileVisitResult.CONTINUE;\r
158 \r
159                 Path parent = getProjectRootPath(dir);\r
160                 if (parent == null) {\r
161                         System.out.println("Skipping " + dir);\r
162                         return FileVisitResult.SKIP_SUBTREE;\r
163                 }\r
164 \r
165                 return FileVisitResult.CONTINUE;\r
166         }\r
167 \r
168         private boolean processPathItem(Path filePath) {\r
169                 currentCount[0]++;\r
170                 setProgress(currentCount[0] * 100 / allCount[0]);\r
171 \r
172                 if (filePath.toFile().isDirectory() || !filePath.toString().toUpperCase().endsWith(".EZP"))\r
173                         return false;\r
174 \r
175                 //level check\r
176                 if (filePath.getNameCount() != sourcePath.getNameCount() + 3) {\r
177                         //logger.warn(marker, "A {} fájl elérési útja a várttól eltérő.", filePath);\r
178                         return false;\r
179                 }\r
180 \r
181                 List<Path> killDateFiles = getKillDateFiles(filePath);\r
182                 if (killDateFiles == null || killDateFiles.size() == 0) {\r
183                         logger.warn(marker, "A {} fájlhoz nem található 'killdate' állomány.", filePath);\r
184                         return false;\r
185                 }\r
186 \r
187                 if (killDateFiles.size() != 1)\r
188                         logger.warn(marker, "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.", filePath);\r
189 \r
190                 Date killDate = checkExpiration(killDateFiles);\r
191                 if (killDate == null)\r
192                         return false;\r
193 \r
194                 Path parent = getProjectRootPath(filePath);\r
195                 if (parent != null) {\r
196                         Path pathToDelete = Paths.get(sourcePath.toAbsolutePath().toString(), filePath.getName(sourcePath.getNameCount()).toString());\r
197                         try {\r
198                                 FileUtils.deleteDirectory(pathToDelete.toFile());\r
199                                 logger.info(marker, "A {} mappa sikeresen törlődött. Lejárat: {}", pathToDelete, dateFormat.format(killDate));\r
200                         } catch (Exception e) {\r
201                                 logger.error(marker, "A {} mappa törlése nem lehetséges, a rendszer üzenete: {}", pathToDelete, e.getMessage());\r
202                                 logger.error(e);\r
203                         }\r
204                 }\r
205                 //              else\r
206                 //                      logger.warn(marker, "A {} fájlhoz nem határozható meg a törlendő szülőkönyvtár.", filePath);\r
207                 return true;\r
208         }\r
209 \r
210         @Override\r
211         public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\r
212                 processPathItem(file);\r
213                 return FileVisitResult.CONTINUE;\r
214         }\r
215 \r
216         @Override\r
217         public FileVisitResult visitFileFailed(Path file, IOException e) throws IOException {\r
218                 logger.error(marker, "A {} fájl nem érhető el. A rendszer hibaüzenete: {}", file.toString(), e.getMessage());\r
219                 return FileVisitResult.CONTINUE;\r
220         }\r
221 }\r