1 package fr.ifremer.dali.service.persistence;
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 fr.ifremer.dali.config.DaliConfiguration;
27 import fr.ifremer.dali.dao.administration.program.DaliProgramDao;
28 import fr.ifremer.dali.dao.administration.user.DaliDepartmentDao;
29 import fr.ifremer.dali.dao.administration.user.DaliQuserDao;
30 import fr.ifremer.dali.dao.data.survey.DaliCampaignDao;
31 import fr.ifremer.dali.dao.referential.DaliAnalysisInstrumentDao;
32 import fr.ifremer.dali.dao.referential.DaliReferentialDao;
33 import fr.ifremer.dali.dao.referential.DaliSamplingEquipmentDao;
34 import fr.ifremer.dali.dao.referential.DaliUnitDao;
35 import fr.ifremer.dali.dao.referential.monitoringLocation.DaliMonitoringLocationDao;
36 import fr.ifremer.dali.dao.referential.pmfm.*;
37 import fr.ifremer.dali.dao.referential.taxon.DaliTaxonGroupDao;
38 import fr.ifremer.dali.dao.referential.taxon.DaliTaxonNameDao;
39 import fr.ifremer.dali.dao.system.context.DaliContextDao;
40 import fr.ifremer.dali.dao.technical.Daos;
41 import fr.ifremer.dali.service.DaliServiceLocator;
42 import fr.ifremer.dali.service.StatusFilter;
43 import fr.ifremer.dali.service.system.SystemService;
44 import fr.ifremer.quadrige3.core.ProgressionCoreModel;
45 import fr.ifremer.quadrige3.core.dao.technical.DatabaseSchemaDao;
46 import fr.ifremer.quadrige3.core.exception.DatabaseSchemaUpdateException;
47 import fr.ifremer.quadrige3.core.exception.VersionNotFoundException;
48 import fr.ifremer.quadrige3.core.service.technical.CacheService;
49 import org.apache.commons.logging.Log;
50 import org.apache.commons.logging.LogFactory;
51 import org.nuiton.jaxx.application.ApplicationTechnicalException;
52 import org.nuiton.version.Version;
53 import org.springframework.cache.Cache;
54 import org.springframework.stereotype.Service;
55
56 import javax.annotation.Resource;
57 import javax.sql.DataSource;
58 import java.time.LocalDate;
59 import java.util.ArrayList;
60 import java.util.List;
61
62
63
64
65
66
67 @Service("daliPersistenceService")
68 public class PersistenceServiceImpl implements PersistenceService {
69
70
71
72
73 private static final Log LOG = LogFactory.getLog(PersistenceServiceImpl.class);
74
75 @Resource
76 protected CacheService cacheService;
77 @Resource(name = "daliSystemService")
78 protected SystemService systemService;
79 @Resource
80 protected DaliConfiguration config;
81 @Resource
82 protected DatabaseSchemaDao databaseSchemaDao;
83 @Resource(name = "daliContextDao")
84 protected DaliContextDao contextDao;
85 @Resource(name = "daliProgramDao")
86 protected DaliProgramDao programDao;
87 @Resource(name = "daliCampaignDao")
88 protected DaliCampaignDao campaignDao;
89 @Resource(name = "daliQuserDao")
90 protected DaliQuserDao quserDao;
91 @Resource(name = "daliDepartmentDao")
92 protected DaliDepartmentDao departmentDao;
93 @Resource(name = "daliReferentialDao")
94 protected DaliReferentialDao referentialDao;
95 @Resource(name = "daliUnitDao")
96 protected DaliUnitDao unitDao;
97 @Resource(name = "daliMonitoringLocationDao")
98 protected DaliMonitoringLocationDao monitoringLocationDao;
99 @Resource(name = "daliPmfmDao")
100 protected DaliPmfmDao pmfmDao;
101 @Resource(name = "daliParameterDao")
102 protected DaliParameterDao parameterDao;
103 @Resource(name = "daliMatrixDao")
104 protected DaliMatrixDao matrixDao;
105 @Resource(name = "daliFractionDao")
106 protected DaliFractionDao fractionDao;
107 @Resource(name = "daliMethodDao")
108 protected DaliMethodDao methodDao;
109 @Resource(name = "daliTaxonGroupDao")
110 protected DaliTaxonGroupDao taxonGroupDao;
111 @Resource(name = "daliTaxonNameDao")
112 protected DaliTaxonNameDao taxonNameDao;
113 @Resource(name = "daliAnalysisInstrumentDao")
114 private DaliAnalysisInstrumentDao analysisInstrumentDao;
115 @Resource(name = "daliSamplingEquipmentDao")
116 private DaliSamplingEquipmentDao samplingEquipmentDao;
117
118
119
120
121 @Override
122 public void afterPropertiesSet() {
123 if (config.isCleanCacheAtStartup()) {
124 clearAllCaches();
125 }
126 }
127
128
129
130
131 @Override
132 public void close() {
133 shutdownDatabase();
134 }
135
136
137
138
139 @Override
140 public Version getDbVersion() {
141 try {
142 if (!databaseSchemaDao.isDbLoaded()) {
143 throw new VersionNotFoundException("db is not open");
144 }
145 return databaseSchemaDao.getSchemaVersion();
146 } catch (VersionNotFoundException e) {
147 if (LOG.isErrorEnabled()) {
148 LOG.error("Could not find db version", e);
149 }
150 return null;
151 }
152 }
153
154
155
156
157 @Override
158 public Version getApplicationVersion() {
159 return databaseSchemaDao.getSchemaVersionIfUpdate();
160 }
161
162
163
164
165 @Override
166 public void updateSchema() {
167 try {
168 databaseSchemaDao.updateSchema();
169 } catch (DatabaseSchemaUpdateException e) {
170 throw new ApplicationTechnicalException(e);
171 }
172 }
173
174
175
176
177 @Override
178 public void compactDb() {
179
180 if (LOG.isDebugEnabled()) {
181 LOG.debug("Compacting database");
182 }
183
184 Daos.compactDatabase(getDataSource());
185 }
186
187
188
189
190 @Override
191 public void clearAllCaches() {
192 cacheService.clearAllCaches();
193
194
195 try {
196 Thread.sleep(1000);
197 } catch (InterruptedException ignored) {
198 }
199
200 System.gc();
201 }
202
203
204
205
206 @Override
207 public void loadDefaultCaches(ProgressionCoreModel progressionModel) {
208 if (config.isCacheEnabledAtStartup()) {
209
210 if (LOG.isDebugEnabled()) {
211 LOG.debug("Loading default caches...");
212 }
213
214 loadReferentialCaches(progressionModel);
215
216 if (LOG.isDebugEnabled()) {
217 LOG.debug("Loading default caches... [OK]");
218 }
219 }
220 }
221
222 @Override
223 public void enableMassiveUpdate() {
224
225 if (!Daos.isHsqlFileDatabase(config.getJdbcUrl())) return;
226
227 if (LOG.isDebugEnabled()) {
228 LOG.debug("Enable massive update behavior [CHECKPOINT first]");
229 }
230
231
232 Daos.sqlUpdate(getDataSource(), "CHECKPOINT");
233
234 if (LOG.isDebugEnabled()) {
235 LOG.debug("Enable massive update behavior");
236 }
237
238
239 Daos.sqlUpdate(getDataSource(), "SET FILES BACKUP INCREMENT FALSE");
240
241 }
242
243 @Override
244 public void disableMassiveUpdate() {
245
246 if (!Daos.isHsqlFileDatabase(config.getJdbcUrl())) return;
247
248 if (LOG.isDebugEnabled()) {
249 LOG.debug("Disable massive update behavior [CHECKPOINT first]");
250 }
251
252
253 Daos.sqlUpdate(getDataSource(), "CHECKPOINT");
254
255 if (LOG.isDebugEnabled()) {
256 LOG.debug("Disable massive update behavior");
257 }
258
259
260 Daos.sqlUpdate(getDataSource(), "SET FILES BACKUP INCREMENT TRUE");
261
262 }
263
264
265
266
267
268
269
270
271 private void loadReferentialCaches(ProgressionCoreModel progressionModel) {
272
273 List<Runnable> runnables = new ArrayList<>();
274 runnables.add(() -> referentialDao.getAllStatus());
275 runnables.add(() -> contextDao.getAllContext());
276 runnables.add(() -> departmentDao.getAllDepartments(StatusFilter.ACTIVE.toStatusCodes()));
277 runnables.add(() -> quserDao.getAllUsers(StatusFilter.ACTIVE.toStatusCodes()));
278 runnables.add(() -> programDao.getAllPrograms());
279 runnables.add(() -> campaignDao.getAllCampaigns());
280 runnables.add(() -> referentialDao.getAllDepthLevels());
281 runnables.add(() -> referentialDao.getAllGroupingTypes());
282 runnables.add(() -> referentialDao.getAllPositioningSystems());
283 runnables.add(() -> referentialDao.getAllQualityFlags(StatusFilter.ACTIVE.toStatusCodes()));
284 runnables.add(() -> analysisInstrumentDao.getAllAnalysisInstruments(StatusFilter.ACTIVE.toStatusCodes()));
285 runnables.add(() -> samplingEquipmentDao.getAllSamplingEquipments(StatusFilter.ACTIVE.toStatusCodes()));
286 runnables.add(() -> unitDao.getAllUnits(StatusFilter.ACTIVE.toStatusCodes()));
287 runnables.add(() -> monitoringLocationDao.getAllLocations(StatusFilter.ACTIVE.toStatusCodes()));
288 runnables.add(() -> monitoringLocationDao.getAllHarbours(StatusFilter.ACTIVE.toStatusCodes()));
289 runnables.add(() -> parameterDao.getAllParameterGroups(StatusFilter.ACTIVE.toStatusCodes()));
290 runnables.add(() -> parameterDao.getAllParameters(StatusFilter.ACTIVE.toStatusCodes()));
291 runnables.add(() -> matrixDao.getAllMatrices(StatusFilter.ACTIVE.toStatusCodes()));
292 runnables.add(() -> fractionDao.getAllFractions(StatusFilter.ACTIVE.toStatusCodes()));
293 runnables.add(() -> methodDao.getAllMethods(StatusFilter.ACTIVE.toStatusCodes()));
294 runnables.add(() -> pmfmDao.getAllPmfms(StatusFilter.ACTIVE.toStatusCodes()));
295 runnables.add(() -> referentialDao.getAllTaxonomicLevels());
296 runnables.add(() -> taxonNameDao.fillReferents(taxonNameDao.getAllTaxonNames()));
297 runnables.add(() -> {
298
299 Cache cache = cacheService.getCache(DaliTaxonNameDao.TAXON_NAME_BY_TAXON_GROUP_ID_CACHE);
300 if (cache != null && cache.get(LocalDate.now()) == null) {
301
302 cacheService.clearCache(DaliTaxonGroupDao.ALL_TAXON_GROUPS_CACHE);
303 }
304 taxonGroupDao.getAllTaxonGroups();
305 });
306
307
308 progressionModel.setTotal(runnables.size());
309 runnables.forEach(runnable -> {
310 runnable.run();
311 progressionModel.increments(1);
312 });
313 }
314
315
316
317
318 private void shutdownDatabase() {
319
320 if (!Daos.isHsqlFileDatabase(config.getJdbcUrl())) {
321 return;
322 }
323
324 if (LOG.isDebugEnabled()) {
325 LOG.debug("shutting down database");
326 }
327 Daos.shutdownDatabase(getDataSource());
328 if (LOG.isDebugEnabled()) {
329 LOG.debug("database down");
330 }
331 }
332
333
334
335
336
337
338 protected DataSource getDataSource() {
339 return DaliServiceLocator.instance().getService("dataSource", DataSource.class);
340 }
341
342 }