e46bfaa3e8fa2c5682847c0cb1dcd224da8a9040
[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 import user.jobengine.server.steps.shared.MetadataType;\r
29 import user.jobengine.server.steps.shared.MetadataTypeDetector;\r
30 \r
31 public class ProjectCleanupMountedLocationStep extends JobStep implements FileVisitor<Path> {\r
32 \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
43 \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
49                                 continue;\r
50                         if ((killDate != null && currentKillDate.after(killDate)) || killDate == null)\r
51                                 killDate = currentKillDate;\r
52                 }\r
53                 return new Date().after(killDate) ? killDate : null;\r
54         }\r
55 \r
56         @StepEntry\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
65                 }\r
66 \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
70                 }\r
71                 try {\r
72                         setProgress(1);\r
73                         dateFormat = new SimpleDateFormat(DATEFORMAT);\r
74                         Files.walkFileTree(sourcePath, new SimpleFileVisitor<Path>() {\r
75                                 @Override\r
76                                 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\r
77                                         allCount[0]++;\r
78                                         return super.visitFile(file, attrs);\r
79                                 }\r
80                         });\r
81                         Files.walkFileTree(sourcePath, this);\r
82                 } catch (Exception e) {\r
83                         logger.catching(e);\r
84                         logger.error(marker, "Az '{}' mappa elérése sikertelen. A rendszer hibaüzenete: {}", sourcePath,\r
85                                         e.getMessage());\r
86                         throw e;\r
87                 } finally {\r
88                         if (directoryStream != null) {\r
89                                 try {\r
90                                         directoryStream.close();\r
91                                 } catch (IOException e) {\r
92                                 }\r
93                         }\r
94                 }\r
95                 return null;\r
96         }\r
97 \r
98         private Date getKillDate(Path killDateFile) {\r
99                 String fileName = killDateFile.getFileName().toString();\r
100                 int end = fileName.lastIndexOf(DOT);\r
101                 if (end < 1)\r
102                         return null;\r
103                 int start = fileName.lastIndexOf(DOT, end - 1);\r
104                 if (start < 0)\r
105                         return null;\r
106                 String strKillDate = fileName.substring(start + 1, end);\r
107                 Date result = null;\r
108                 if (StringUtils.isNumeric(strKillDate)) {\r
109                         try {\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
115                                 return null;\r
116                         }\r
117                 } else\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
120                 return result;\r
121         }\r
122 \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
127                 try {\r
128                         statusPath = Paths.get(filePath.getParent().toString(), STATUSFOLDER);\r
129                 } catch (Exception e) {\r
130                         logger.catching(e);\r
131                         return null;\r
132                 }\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
139                         }\r
140                 }\r
141                 Collections.sort(result);\r
142                 return result;\r
143         }\r
144 \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
152                 }\r
153                 return result;\r
154         }\r
155 \r
156         @Override\r
157         public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {\r
158                 return FileVisitResult.CONTINUE;\r
159         }\r
160 \r
161         @Override\r
162         public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {\r
163                 if (dir.equals(sourcePath))\r
164                         return FileVisitResult.CONTINUE;\r
165 \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
170                 }\r
171 \r
172                 return FileVisitResult.CONTINUE;\r
173         }\r
174 \r
175         private boolean processPathItem(Path filePath) {\r
176                 currentCount[0]++;\r
177                 setProgress(currentCount[0] * 100 / allCount[0]);\r
178 \r
179                 if (filePath.toFile().isDirectory() || !filePath.toString().toUpperCase().endsWith(".EZP"))\r
180                         return false;\r
181 \r
182                 // level check\r
183                 if (filePath.getNameCount() != sourcePath.getNameCount() + 3) {\r
184                         // logger.warn(marker, "A {} fájl elérési útja a várttól eltérő.", filePath);\r
185                         return false;\r
186                 }\r
187 \r
188                 List<Path> killDateFiles = getKillDateFiles(filePath);\r
189                 if (killDateFiles == null || killDateFiles.size() == 0) {\r
190                         logger.warn(marker, "A {} fájlhoz nem található 'killdate' állomány.", filePath);\r
191                         return false;\r
192                 }\r
193 \r
194                 if (killDateFiles.size() != 1)\r
195                         logger.warn(marker,\r
196                                         "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
197                                         filePath);\r
198 \r
199                 Date killDate = checkExpiration(killDateFiles);\r
200                 if (killDate == null)\r
201                         return false;\r
202 \r
203                 Path parent = getProjectRootPath(filePath);\r
204                 if (parent != null) {\r
205                         Path pathToDelete = Paths.get(sourcePath.toAbsolutePath().toString(),\r
206                                         filePath.getName(sourcePath.getNameCount()).toString());\r
207                         try {\r
208                                 FileUtils.deleteDirectory(pathToDelete.toFile());\r
209                                 logger.info(marker, "A {} mappa sikeresen törlődött. Lejárat: {}", pathToDelete,\r
210                                                 dateFormat.format(killDate));\r
211                         } catch (Exception e) {\r
212                                 logger.error(marker, "A {} mappa törlése nem lehetséges, a rendszer üzenete: {}", pathToDelete,\r
213                                                 e.getMessage());\r
214                                 logger.error(e);\r
215                         }\r
216                 }\r
217                 // else\r
218                 // logger.warn(marker, "A {} fájlhoz nem határozható meg a törlendő\r
219                 // szülőkönyvtár.", filePath);\r
220                 return true;\r
221         }\r
222 \r
223         @Override\r
224         public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\r
225                 processPathItem(file);\r
226                 return FileVisitResult.CONTINUE;\r
227         }\r
228 \r
229         @Override\r
230         public FileVisitResult visitFileFailed(Path file, IOException e) throws IOException {\r
231                 logger.error(marker, "A {} fájl nem érhető el. A rendszer hibaüzenete: {}", file.toString(), e.getMessage());\r
232                 return FileVisitResult.CONTINUE;\r
233         }\r
234 }\r