1 package fr.ifremer.quadrige3.synchro.server.service.technical;
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
27 import fr.ifremer.quadrige3.core.exception.QuadrigeTechnicalException;
28 import fr.ifremer.quadrige3.core.config.QuadrigeConfiguration;
29 import fr.ifremer.quadrige3.core.dao.technical.Daos;
30 import fr.ifremer.quadrige3.core.dao.technical.ZipUtils;
31 import fr.ifremer.quadrige3.synchro.server.config.SynchroServerConfiguration;
32 import fr.ifremer.quadrige3.synchro.service.doc.DocSynchroService;
33 import org.apache.commons.io.FileUtils;
34 import org.apache.commons.io.FilenameUtils;
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37 import org.hibernate.cfg.Environment;
38 import org.nuiton.i18n.I18n;
39 import org.nuiton.version.Version;
40 import org.springframework.beans.factory.InitializingBean;
41 import org.springframework.beans.factory.annotation.Autowired;
42 import org.springframework.stereotype.Service;
43
44 import java.io.File;
45 import java.io.IOException;
46 import java.sql.SQLException;
47 import java.util.Properties;
48
49 import static org.nuiton.i18n.I18n.t;
50
51 @Service("databaseSchemaService")
52 public class DatabaseSchemaServiceImpl extends fr.ifremer.quadrige3.core.service.DatabaseSchemaServiceImpl implements DatabaseSchemaService, InitializingBean {
53
54 private static final Log log = LogFactory.getLog(DatabaseSchemaServiceImpl.class);
55
56 private File emptyDbFileCache;
57
58 private File tableRelationFileCache;
59
60 @Autowired
61 protected SynchroServerConfiguration synchroServerConfig;
62
63 @Autowired
64 protected DocSynchroService docSynchroService;
65
66 @Autowired
67 public DatabaseSchemaServiceImpl(QuadrigeConfiguration config) {
68 this.config = config;
69 this.emptyDbFileCache = null;
70 }
71
72 @Override
73 public void afterPropertiesSet() {
74
75 initDbFileCache();
76 }
77
78 @Override
79 public void createEmptyDb(File dbDirectory) {
80
81 if (emptyDbFileCache == null || !emptyDbFileCache.exists()) {
82
83 emptyDbFileCache = null;
84 initDbFileCache();
85
86
87 if (emptyDbFileCache == null || !emptyDbFileCache.exists()) {
88 throw new QuadrigeTechnicalException(t("quadrige3.synchro.server.import.newDatabase.noEmptyZipFile.error", emptyDbFileCache.getPath()));
89 }
90 }
91
92 try {
93 ZipUtils.uncompressFileToPath(emptyDbFileCache.toPath(), dbDirectory.toPath(), false);
94 } catch (IOException e) {
95
96 log.error(t("quadrige3.synchro.server.import.newDatabase.unzipDirectory.error", config.getVersion().toString()), e);
97 }
98 }
99
100 @Override
101 public File getEmptyDbFile() {
102 return emptyDbFileCache;
103 }
104
105 @Override
106 public File getTableRelationFileCache() {
107 return tableRelationFileCache;
108 }
109
110
111
112
113
114 private void initDbFileCache() {
115
116 if (emptyDbFileCache == null) {
117 emptyDbFileCache = createEmptyDbZipFile();
118 tableRelationFileCache = new File(emptyDbFileCache.getParentFile(), FilenameUtils.removeExtension(emptyDbFileCache.getName()) + ".json");
119 }
120 if (emptyDbFileCache.exists()) {
121 if (log.isInfoEnabled()) {
122 log.info(I18n.t("quadrige3.synchro.server.init.emptyDb.skip", emptyDbFileCache.getPath()));
123 }
124 return;
125 }
126
127 log.info(I18n.t("quadrige3.synchro.server.init.emptyDb.task", emptyDbFileCache.getPath()));
128
129
130 File emptyDbDirectory = new File(config.getTempDirectory(), String.valueOf(System.currentTimeMillis()));
131 generateAndUpdateNewTemporaryDb(emptyDbDirectory);
132
133
134 try {
135 if (emptyDbFileCache.exists()) {
136 FileUtils.forceDelete(emptyDbFileCache);
137 }
138
139 ZipUtils.compressFilesInPath(
140 emptyDbDirectory.toPath(),
141 emptyDbFileCache.toPath(),
142 true
143 );
144 } catch (IOException e) {
145
146 log.error(t("quadrige3.synchro.server.init.emptyDb.zipDirectory.error", config.getVersion().toString()), e);
147 throw new QuadrigeTechnicalException(t("quadrige3.synchro.server.init.emptyDb.zipDirectory.error", config.getVersion().toString()), e);
148 }
149 }
150
151 private File createEmptyDbZipFile() {
152
153
154 Version quadrigeVersion = databaseSchemaDao.getSchemaVersionIfUpdate();
155 File synchroDirectory = config.getSynchronizationDirectory();
156
157 return new File(synchroDirectory, "db-" + quadrigeVersion.toString() + ".zip");
158 }
159
160 private void generateAndUpdateNewTemporaryDb(File emptyDbDirectory) {
161
162 Properties connectionProperties = synchroServerConfig.getClientConnectionProperties();
163 connectionProperties.setProperty(Environment.URL, Daos.getJdbcUrl(emptyDbDirectory, config.getDbName()));
164
165
166 try {
167 try {
168
169 databaseSchemaDao.generateNewDb(emptyDbDirectory, false, null, connectionProperties, true);
170
171
172 databaseSchemaDao.updateSchema(connectionProperties);
173
174
175 docSynchroService.createTableRelationsFile(connectionProperties, tableRelationFileCache);
176
177 } catch (Throwable e) {
178 throw new QuadrigeTechnicalException(t("quadrige3.synchro.server.init.emptyDb.updateSchema.error"), e);
179 }
180 } finally {
181 closeSilently(connectionProperties);
182 }
183 }
184
185 private void closeSilently(Properties connectionProperties) {
186 try {
187 Daos.shutdownDatabase(connectionProperties);
188 } catch (SQLException e) {
189
190 }
191 }
192 }