1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.exoplatform.commons.file.services.checker;
20
21 import org.exoplatform.commons.file.model.FileInfo;
22 import org.exoplatform.commons.file.resource.BinaryProvider;
23 import org.exoplatform.commons.file.services.job.FileStorageCleanJob;
24 import org.exoplatform.commons.file.storage.DataStorage;
25 import org.exoplatform.commons.utils.PropertyManager;
26 import org.exoplatform.commons.utils.SecurityHelper;
27 import org.exoplatform.services.log.ExoLogger;
28 import org.exoplatform.services.log.Log;
29 import org.picocontainer.Startable;
30 import org.exoplatform.management.annotations.Managed;
31 import org.exoplatform.management.annotations.ManagedDescription;
32 import org.exoplatform.management.jmx.annotations.NameTemplate;
33 import org.exoplatform.management.jmx.annotations.Property;
34
35 import java.io.*;
36 import java.security.PrivilegedAction;
37 import java.security.PrivilegedExceptionAction;
38 import java.text.SimpleDateFormat;
39 import java.util.Date;
40 import java.util.List;
41
42
43
44
45
46 @Managed
47 @NameTemplate(@Property(key = "service", value = "FileStorageCheckController"))
48 @ManagedDescription("File Storage Check consistency")
49 public class FileStorageCheckController implements Startable {
50 protected static Log LOG = ExoLogger.getLogger(FileStorageCheckController.class);
51
52 public static final String REPORT_CONSISTENT_MESSAGE = "File Storage data is consistent";
53
54 public static final String REPORT_NOT_CONSISTENT_MESSAGE = "File Storage data is NOT consistent";
55
56 private static final int pageSize = 20;
57
58 private BinaryProvider binaryProvider;
59
60 private DataStorage dataStorage;
61
62 public FileStorageCheckController(DataStorage dataStorage, BinaryProvider resourceProvider) {
63 this.dataStorage = dataStorage;
64 this.binaryProvider = resourceProvider;
65 }
66
67 @Managed
68 @ManagedDescription("Check File Storage consistency. ")
69 public String checkFileStorage() {
70 boolean defaultState = FileStorageCleanJob.isEnabled().get();
71 ;
72 try {
73 Report report = new Report();
74 if (FileStorageCleanJob.isEnabled().get()) {
75 FileStorageCleanJob.setEnabled(false);
76 }
77 SecurityHelper.doPrivilegedAction(new PrivilegedAction<Boolean>() {
78 public Boolean run() {
79 try {
80 LOG.info("Start File Storage Check Consistency");
81 boolean isConsistent = true;
82 int offset = 0;
83 boolean hasNext = true;
84 while (hasNext) {
85 List<FileInfo> list = dataStorage.getAllFilesInfo(offset, pageSize);
86
87 if (list == null || list.isEmpty()) {
88 break;
89 }
90 if (list.size() < pageSize) {
91 hasNext = false;
92 }
93 for (FileInfo fileInfo : list) {
94 String checksum = fileInfo.getChecksum();
95 if (checksum != null && !checksum.isEmpty()) {
96 if (!binaryProvider.exists(checksum)) {
97 isConsistent = false;
98 report.writeLine("File not exist in file storage File ID : " + fileInfo.getId() + " File name : "
99 + fileInfo.getName() + " , Path : " + binaryProvider.getFilePath(fileInfo.getChecksum()));
100 }
101 } else {
102 isConsistent = false;
103 report.writeLine("File metaData with empty checksum File ID : " + fileInfo.getId() + " File name : "
104 + fileInfo.getName() + " , Path : ");
105 }
106 }
107 offset += pageSize;
108 }
109 if (isConsistent) {
110 report.writeLine(REPORT_CONSISTENT_MESSAGE);
111 LOG.info("Finish File Storage Check Consistency : " + REPORT_CONSISTENT_MESSAGE);
112 } else {
113 report.writeLine(REPORT_NOT_CONSISTENT_MESSAGE);
114 LOG.info("Finish File Storage Check Consistency : " + REPORT_NOT_CONSISTENT_MESSAGE);
115 }
116 } catch (Exception e) {
117 try {
118 report.writeLine("Processing File Storage Check Consistency Error ");
119 report.writeStackTrace(e);
120 } catch (IOException e1) {
121 LOG.error(e1.getMessage());
122 }
123 LOG.error(e.getMessage());
124 }
125 return true;
126 }
127 });
128 } catch (Exception ex) {
129 LOG.error(ex.getMessage());
130 return "Failed Operation";
131 } finally {
132 FileStorageCleanJob.setEnabled(defaultState);
133 }
134 return "Success Operation";
135 }
136
137 @Managed
138 @ManagedDescription("Check File Storage consistency. ")
139 public String RepairFileStorage() {
140 try {
141
142 } catch (Exception ex) {
143 LOG.error(ex.getMessage());
144 return "Failed";
145 }
146 return "Unsupported Operation";
147 }
148
149 @Override
150 public void start() {
151
152 }
153
154 @Override
155 public void stop() {
156
157 }
158
159 private class Report {
160 private static final String DELIMITER = "\n";
161
162 private Writer writer;
163
164 private String reportPath;
165
166 public Report() throws IOException {
167 String reportPathRoot = PropertyManager.getProperty("java.io.tmpdir");
168 final File reportFile = new File(reportPathRoot,
169 "report-filesStorage-" + new SimpleDateFormat("dd-MMM-yy-HH-mm").format(new Date())
170 + ".txt");
171
172 SecurityHelper.doPrivilegedIOExceptionAction(new PrivilegedExceptionAction<Void>() {
173 public Void run() throws IOException {
174 reportPath = reportFile.getAbsolutePath();
175 writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(reportPath)));
176
177 return null;
178 }
179 });
180
181 }
182
183 private void writeLine(String message) throws IOException {
184 writer.write(message);
185 writer.write(DELIMITER);
186 writer.flush();
187 }
188
189 private void writeStackTrace(Throwable e) throws IOException {
190 writeLine(e.getMessage());
191 writeLine(e.toString());
192 StackTraceElement[] trace = e.getStackTrace();
193 for (int i = 0; i < trace.length; i++) {
194 writeLine("\tat " + trace[i]);
195 }
196
197 Throwable ourCause = e.getCause();
198 if (ourCause != null) {
199 writeLine("Cause:");
200 writeStackTrace(ourCause);
201 }
202 }
203
204 }
205 }