1 package fr.ifremer.quadrige2.synchro.service.client;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import com.google.common.base.Joiner;
27 import com.google.common.base.Preconditions;
28 import com.google.common.base.Splitter;
29 import com.google.common.io.Files;
30 import fr.ifremer.common.synchro.service.SynchroResult;
31 import fr.ifremer.quadrige2.core.exception.Quadrige2TechnicalException;
32 import fr.ifremer.quadrige2.core.config.Quadrige2Configuration;
33 import fr.ifremer.quadrige2.core.dao.technical.Dates;
34 import fr.ifremer.quadrige2.synchro.service.client.vo.SynchroClientExportResult;
35 import fr.ifremer.quadrige2.synchro.service.client.vo.SynchroClientExportToFileResult;
36 import fr.ifremer.quadrige2.synchro.service.client.vo.SynchroClientImportFromFileResult;
37 import fr.ifremer.quadrige2.synchro.service.client.vo.SynchroClientImportResult;
38 import fr.ifremer.quadrige2.synchro.meta.data.DataSynchroTables;
39 import fr.ifremer.quadrige2.synchro.service.data.DataSynchroContext;
40 import fr.ifremer.quadrige2.synchro.service.referential.ReferentialSynchroContext;
41 import fr.ifremer.quadrige2.synchro.vo.SynchroDateOperatorVO;
42 import fr.ifremer.quadrige2.synchro.vo.SynchroExportContextVO;
43 import org.apache.commons.collections4.CollectionUtils;
44 import org.apache.commons.io.FileUtils;
45 import org.apache.commons.lang3.StringUtils;
46 import org.apache.commons.logging.Log;
47 import org.apache.commons.logging.LogFactory;
48 import org.nuiton.i18n.I18n;
49 import org.springframework.context.annotation.Lazy;
50 import org.springframework.stereotype.Service;
51
52 import javax.annotation.Resource;
53 import java.io.File;
54 import java.io.FileWriter;
55 import java.io.IOException;
56 import java.text.DateFormat;
57 import java.text.SimpleDateFormat;
58 import java.util.Date;
59 import java.util.Set;
60
61
62
63
64
65
66 @Service("synchroHistoryService")
67 @Lazy
68 public class SynchroHistoryServiceImpl implements SynchroHistoryService {
69 private static final Log log = LogFactory.getLog(SynchroHistoryServiceImpl.class);
70
71 private static final String HISTORY_LOG_FILE = "synchro.txt";
72
73
74 static {
75 I18n.n("quadrige2.synchro.service.history.filter.date.EQUALS");
76 I18n.n("quadrige2.synchro.service.history.filter.date.BETWEEN");
77 I18n.n("quadrige2.synchro.service.history.filter.date.BEFORE");
78 I18n.n("quadrige2.synchro.service.history.filter.date.BEFORE_OR_EQUALS");
79 I18n.n("quadrige2.synchro.service.history.filter.date.AFTER");
80 I18n.n("quadrige2.synchro.service.history.filter.date.AFTER_OR_EQUALS");
81 }
82
83 @Resource
84 private Quadrige2Configuration configuration;
85
86
87 @Override
88 public void save(int userId, SynchroClientImportResult result) {
89 Preconditions.checkNotNull(result);
90 StringBuilder messageBuilder = new StringBuilder();
91
92 boolean withReferential = result.getReferentialResult() != null && result.getReferentialResult().getTotalTreated() > 0;
93 boolean withData = result.getDataResult() != null && result.getDataResult().getTotalTreated() > 0;
94
95
96 if (!withReferential && !withData) {
97 return;
98 }
99
100 Date referentialUpdateDate = result.getReferentialSynchronizationDate();
101 Date dataUpdateDate = result.getDataSynchronizationDate();
102
103 DateFormat dateFormat = DateFormat.getDateTimeInstance(SimpleDateFormat.LONG, SimpleDateFormat.LONG);
104
105
106 if (withData) {
107 messageBuilder.append(I18n.t("quadrige2.synchro.service.history.import",
108 dateFormat.format(dataUpdateDate)));
109 }
110
111
112 else {
113 messageBuilder.append(I18n.t("quadrige2.synchro.service.history.import.referential",
114 dateFormat.format(referentialUpdateDate)));
115 }
116
117
118 if (messageBuilder.length() > 0) {
119 appendToHistoryFile(userId, messageBuilder.toString());
120 }
121 }
122
123
124 @Override
125 public void save(int userId, SynchroClientImportFromFileResult result) {
126 Preconditions.checkNotNull(result);
127 Preconditions.checkNotNull(result.getFile());
128 StringBuilder messageBuilder = new StringBuilder();
129
130 boolean withReferential = result.getReferentialResult() != null && result.getReferentialResult().getTotalTreated() > 0;
131 boolean withData = result.getDataResult() != null && result.getDataResult().getTotalTreated() > 0;
132
133 Date nowDate = new Date();
134 Date referentialUpdateDate = result.getReferentialSynchronizationDate();
135 if (referentialUpdateDate == null) {
136 referentialUpdateDate = nowDate;
137 }
138 Date dataUpdateDate = result.getDataSynchronizationDate();
139 if (dataUpdateDate == null) {
140 dataUpdateDate = nowDate;
141 }
142
143 DateFormat dateFormat = DateFormat.getDateTimeInstance(SimpleDateFormat.LONG, SimpleDateFormat.LONG);
144
145
146 if (withData && withReferential) {
147 messageBuilder.append(I18n.t("quadrige2.synchro.service.history.importFromFile",
148 dateFormat.format(dataUpdateDate),
149 result.getFile()));
150 }
151
152
153 else if (withData) {
154 messageBuilder.append(I18n.t("quadrige2.synchro.service.history.importFromFile.data",
155 dateFormat.format(dataUpdateDate),
156 result.getFile()));
157 }
158
159
160 else if (withReferential) {
161 messageBuilder.append(I18n.t("quadrige2.synchro.service.history.importFromFile.referential",
162 dateFormat.format(referentialUpdateDate),
163 result.getFile()));
164 }
165
166
167 else {
168 messageBuilder.append(I18n.t("quadrige2.synchro.service.history.importFromFile.noData",
169 dateFormat.format(new Date()),
170 result.getFile()));
171 }
172
173
174 if (messageBuilder.length() > 0) {
175 appendToHistoryFile(userId, messageBuilder.toString());
176 }
177 }
178
179
180 @Override
181 public void save(int userId, SynchroClientExportResult result) {
182 Preconditions.checkNotNull(result);
183
184 saveExportServerResult(userId, result.getServerResult(), result.getDataContext().getProgramCodes());
185 }
186
187
188 @Override
189 public void saveExportServerResult(int userId, SynchroResult serverResult, Set<String> programCodes) {
190 StringBuilder messageBuilder = new StringBuilder();
191
192 boolean hasUpdates = serverResult != null && serverResult.getTotalTreated() > 0;
193
194
195 if (!hasUpdates) {
196 return;
197 }
198
199
200 DateFormat dateFormat = DateFormat.getDateTimeInstance(SimpleDateFormat.LONG, SimpleDateFormat.LONG);
201
202
203
204 int surveyNbInserts = serverResult.getNbInserts(DataSynchroTables.SURVEY.name());
205 int surveyNbUpdates = serverResult.getNbUpdates(DataSynchroTables.SURVEY.name());
206 int surveyNbDeletes = serverResult.getNbDeletes(DataSynchroTables.SURVEY.name());
207
208 String rejectedRows = serverResult.getRejectedRows(DataSynchroTables.SURVEY.name());
209 int surveyNbRejects = countErrorItems(rejectedRows);
210
211 String programCodesStr = CollectionUtils.isEmpty(programCodes)
212 ? ""
213 : Joiner.on(", ").join(programCodes);
214
215 messageBuilder.append(I18n.t("quadrige2.synchro.service.history.export",
216 dateFormat.format(new Date()),
217 CollectionUtils.size(programCodes),
218 programCodesStr,
219 surveyNbInserts,
220 surveyNbUpdates,
221 surveyNbDeletes,
222 surveyNbRejects));
223
224
225 if (messageBuilder.length() > 0) {
226 appendToHistoryFile(userId, messageBuilder.toString());
227 }
228 }
229
230
231 @Override
232 public void save(int userId, SynchroClientExportToFileResult result) {
233 Preconditions.checkNotNull(result);
234 Preconditions.checkNotNull(result.getFile());
235 StringBuilder messageBuilder = new StringBuilder();
236
237 boolean withReferential = result.getReferentialResult() != null && result.getReferentialResult().getTotalTreated() > 0;
238 boolean withData = result.getDataResult() != null && result.getDataResult().getTotalTreated() > 0;
239
240
241 if (!withReferential && !withData) {
242 return;
243 }
244
245
246 DateFormat dateFormat = DateFormat.getDateTimeInstance(SimpleDateFormat.LONG, SimpleDateFormat.LONG);
247
248
249 if (withData) {
250
251 DataSynchroContext dataContext = result.getDataContext();
252 Set<String> programCodes = dataContext.getProgramCodes();
253 int surveyNbInserts = result.getDataResult().getNbInserts(DataSynchroTables.SURVEY.name());
254
255 StringBuilder filterMessageBuilder = new StringBuilder();
256
257
258 if (dataContext.isDirtyOnly()) {
259 filterMessageBuilder.append("\n")
260 .append(I18n.t("quadrige2.synchro.service.history.filter.withDirtyOnly"));
261 }
262
263
264 if (dataContext.getDataStartDate() != null) {
265 SynchroDateOperatorVO operator = dataContext.getDateOperator();
266 String datePattern = I18n.t("quadrige2.synchro.service.history.filter.date.pattern");
267 filterMessageBuilder.append("\n")
268 .append(I18n.t("quadrige2.synchro.service.history.filter.date." + operator.name(),
269 Dates.formatDate(dataContext.getDataStartDate(), datePattern),
270 Dates.formatDate(dataContext.getDataEndDate(), datePattern)));
271 }
272
273
274 if (CollectionUtils.isNotEmpty(programCodes)) {
275 String programCodesStr = CollectionUtils.isEmpty(programCodes)
276 ? ""
277 : Joiner.on(", ").join(programCodes);
278 filterMessageBuilder
279 .append("\n")
280 .append(I18n.t("quadrige2.synchro.service.history.filter.program",
281 CollectionUtils.size(programCodes),
282 programCodesStr));
283 }
284
285 messageBuilder.append(I18n.t("quadrige2.synchro.service.history.exportToFile",
286 dateFormat.format(new Date()),
287 result.getFile().getPath(),
288 filterMessageBuilder.toString(),
289 surveyNbInserts));
290
291 }
292
293
294 else if (withReferential) {
295 ReferentialSynchroContext referentialContext = result.getReferentialContext();
296 Set<String> programCodes = referentialContext.getProgramCodes();
297
298 StringBuilder filterMessageBuilder = new StringBuilder();
299
300
301 if (CollectionUtils.isNotEmpty(programCodes)) {
302 String programCodesStr = CollectionUtils.isEmpty(programCodes)
303 ? ""
304 : Joiner.on(", ").join(programCodes);
305 filterMessageBuilder
306 .append("\n")
307 .append(I18n.t("quadrige2.synchro.service.history.filter.program",
308 CollectionUtils.size(programCodes),
309 programCodesStr));
310 }
311
312
313 messageBuilder.append(I18n.t("quadrige2.synchro.service.history.exportToFile.referential",
314 dateFormat.format(new Date()),
315 result.getFile().getPath(),
316 filterMessageBuilder.toString()));
317 }
318
319
320 if (messageBuilder.length() > 0) {
321 appendToHistoryFile(userId, messageBuilder.toString());
322 }
323 }
324
325
326 @Override
327 public String getContent(int userId) {
328 File file = getHistoryFileByUserId(userId);
329 if (!file.exists()) {
330 return null;
331 }
332
333 try {
334 return FileUtils.readFileToString(file);
335 } catch (IOException e) {
336 throw new Quadrige2TechnicalException(I18n.t("quadrige2.service.synchroHistory.readContent.failed"), e);
337 }
338 }
339
340
341 @Override
342 public File getHistoryFileByUserId(int userId) {
343 File result = new File(
344 configuration.getSynchronizationDirectory(),
345 new StringBuilder()
346 .append(userId)
347 .append(File.separator)
348 .append(HISTORY_LOG_FILE)
349 .toString());
350 return result;
351 }
352
353 @Override
354 public void saveExportError(int userId, SynchroExportContextVO exportContext, String message) {
355
356 StringBuilder messageBuilder = new StringBuilder();
357
358
359 DateFormat dateFormat = DateFormat.getDateTimeInstance(SimpleDateFormat.LONG, SimpleDateFormat.LONG);
360
361
362 String programCodesStr = CollectionUtils.isEmpty(exportContext.getDataProgramCodes())
363 ? ""
364 : Joiner.on(", ").join(exportContext.getDataProgramCodes());
365 messageBuilder.append(I18n.t("quadrige2.synchro.service.history.export.failed",
366 dateFormat.format(new Date()),
367 CollectionUtils.size(exportContext.getDataProgramCodes()),
368 programCodesStr,
369 message));
370
371
372 appendToHistoryFile(userId, messageBuilder.toString());
373 }
374
375
376
377
378
379
380
381
382
383
384
385
386
387 protected void appendToHistoryFile(int userId, String messageToAppend) {
388 File historyFile = getHistoryFileByUserId(userId);
389
390 try {
391
392
393 Files.createParentDirs(historyFile);
394
395 try (FileWriter fw = new FileWriter(historyFile, true)) {
396 fw.write('\n');
397 fw.write(messageToAppend);
398 fw.write('\n');
399 }
400 } catch (IOException e) {
401 throw new Quadrige2TechnicalException(I18n.t("quadrige2.synchro.service.history.error", historyFile.getPath()), e);
402 }
403 }
404
405
406
407
408
409
410
411
412
413
414 protected int countErrorItems(String rejectedRows) {
415 if (StringUtils.isBlank(rejectedRows)) {
416 return 0;
417 }
418 return Splitter.on('\n').trimResults().omitEmptyStrings().splitToList(rejectedRows).size();
419 }
420
421 }