Skip to content

Commit c833a7b

Browse files
committed
TRUNK-6409: Properly handle migration and partial imports
1 parent 73646cc commit c833a7b

33 files changed

Lines changed: 671 additions & 326 deletions

api-2.5/src/main/java/org/openmrs/module/initializer/api/loaders/LiquibaseLoader2_5.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,8 @@ private int sqlCount(String sql) {
8888
private void sqlUpdate(String sql) {
8989
Context.getAdministrationService().executeSQL(sql, false);
9090
}
91+
92+
public ConfigDirUtil getDirUtil() {
93+
return new ConfigDirUtil(iniz.getConfigDirPath(), getDomainName(), true);
94+
}
9195
}

api/src/main/java/org/openmrs/module/initializer/InitializerActivator.java

Lines changed: 7 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
import java.util.List;
1616

1717
import org.apache.log4j.Level;
18+
import org.openmrs.api.AdministrationService;
1819
import org.openmrs.api.context.Context;
1920
import org.openmrs.module.BaseModuleActivator;
20-
import org.openmrs.module.ModuleException;
2121
import org.openmrs.module.initializer.api.InitializerService;
2222
import org.openmrs.module.initializer.api.logging.InitializerLogConfigurator;
2323
import org.openmrs.util.OpenmrsUtil;
@@ -29,7 +29,6 @@
2929
import static org.openmrs.module.initializer.InitializerConstants.PROPS_LOGGING_LEVEL;
3030
import static org.openmrs.module.initializer.InitializerConstants.PROPS_LOGGING_LOCATION;
3131
import static org.openmrs.module.initializer.InitializerConstants.PROPS_STARTUP_LOAD_DISABLED;
32-
import static org.openmrs.module.initializer.InitializerConstants.PROPS_STARTUP_LOAD_FAIL_ON_ERROR;
3332
import static org.openmrs.module.initializer.api.utils.Utils.getPropertyValue;
3433

3534
/**
@@ -76,47 +75,18 @@ public void started() {
7675
InitializerMessageSource messageSource = getInitializerMessageSource();
7776
Context.getMessageSourceService().setActiveMessageSource(messageSource);
7877

79-
String startupLoadingMode = getInitializerService().getInitializerConfig().getStartupLoadingMode();
80-
78+
String startupLoadingMode = getInitializerConfig().getStartupLoadingMode();
8179
if (PROPS_STARTUP_LOAD_DISABLED.equalsIgnoreCase(startupLoadingMode)) {
8280
log.info("OpenMRS config loading process disabled at initializer startup");
8381
} else {
84-
boolean throwError = PROPS_STARTUP_LOAD_FAIL_ON_ERROR.equalsIgnoreCase(startupLoadingMode);
85-
boolean lockAquired = false;
86-
String lockName = "initializer";
87-
88-
try {
89-
log.info("Waiting for initializer lock...");
90-
getInitializerService().acquireLockOrWait(lockName, 15 * 60 * 1000); // 15 minutes
91-
lockAquired = true;
92-
93-
// Check if config changed
94-
if (!getInitializerService().isConfigChanged()) {
95-
log.info("No config changes... skipping initializer");
96-
return;
97-
}
98-
99-
// Run Initializer
100-
log.info("OpenMRS config loading process started...");
101-
getInitializerService().loadUnsafe(true, throwError);
102-
103-
// Save new checksums
104-
getInitializerService().updateChecksums();
105-
log.info("OpenMRS config loading process completed.");
106-
}
107-
catch (Exception e) {
108-
log.error("Initializer failed", e);
109-
throw new ModuleException("An error occurred loading initializer configuration", e);
110-
}
111-
finally {
112-
if (lockAquired) {
113-
getInitializerService().releaseLock(lockName);
114-
log.info("Initializer lock released");
115-
}
116-
}
82+
getInitializerService().runInitializer();
11783
}
11884
}
11985

86+
protected InitializerConfig getInitializerConfig() {
87+
return getInitializerService().getInitializerConfig();
88+
}
89+
12090
protected InitializerService getInitializerService() {
12191
return Context.getService(InitializerService.class);
12292
}

api/src/main/java/org/openmrs/module/initializer/InitializerConstants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ public class InitializerConstants {
5656
*/
5757
public static final String DIR_NAME_CONFIG = "configuration";
5858

59+
public static final String DIR_NAME_CHECKSUM = "configuration_checksums";
60+
5961
public static final String DIR_NAME_REJECTIONS = "configuration_rejections";
6062

6163
/*

api/src/main/java/org/openmrs/module/initializer/InitializerMessageSource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ public synchronized void refreshCache() {
202202
protected Map<String, Properties> getMessagePropertyResourcesFromFilesystem() {
203203
List<OrderedPropertiesFile> messagePropertyFiles = new ArrayList<>();
204204
for (String domain : getDomainsToScan()) {
205-
ConfigDirUtil dirUtil = new ConfigDirUtil(iniz.getConfigDirPath(), domain);
205+
ConfigDirUtil dirUtil = new ConfigDirUtil(iniz.getConfigDirPath(), domain, true);
206206
List<File> propFiles = dirUtil.getFiles(PROPERTIES_EXTENSION);
207207
for (File file : propFiles) {
208208
messagePropertyFiles.add(new OrderedPropertiesFile(file));

api/src/main/java/org/openmrs/module/initializer/api/ConfigDirUtil.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ public class ConfigDirUtil {
2626

2727
protected static final Logger log = LoggerFactory.getLogger(ConfigDirUtil.class);
2828

29+
public static final String CHECKSUM_FILE_EXT = "checksum";
30+
31+
protected boolean skipChecksums = false;
32+
2933
/*
3034
* The domain name, so the final part of configuration domain subdirectory. Eg.
3135
* "locations" in "../configuration/locations"
@@ -39,8 +43,8 @@ public class ConfigDirUtil {
3943
protected String domainDirPath = "";
4044

4145
/**
42-
* Instantiates a configuration directory utility class for the specified configuration and checksum
43-
* files directories and for the specified domain.
46+
* Instantiates a configuration directory utility class for the specified configuration directories
47+
* and for the specified domain.
4448
*
4549
* @param configDirPath The absolute path to the configuration directory.
4650
* @param domain The domain name within the configuration directory.
@@ -50,6 +54,20 @@ public ConfigDirUtil(String configDirPath, String domain) {
5054
this.domainDirPath = Paths.get(configDirPath, domain).toString();
5155
}
5256

57+
/**
58+
* Instantiates a configuration directory utility class for the specified configuration directories
59+
* and for the specified domain.
60+
*
61+
* @param configDirPath The absolute path to the configuration directory.
62+
* @param domain The domain name within the configuration directory.
63+
* @param skipChecksums Set this to true to bypass the generation of checksums.
64+
*/
65+
public ConfigDirUtil(String configDirPath, String domain, boolean skipChecksums) {
66+
this.domain = domain;
67+
this.domainDirPath = Paths.get(configDirPath, domain).toString();
68+
this.skipChecksums = skipChecksums;
69+
}
70+
5371
public String getDomain() {
5472
return domain;
5573
}
@@ -58,6 +76,10 @@ public String getDomainDirPath() {
5876
return domainDirPath;
5977
}
6078

79+
public boolean isSkipChecksums() {
80+
return skipChecksums;
81+
}
82+
6183
@Override
6284
public String toString() {
6385
return domainDirPath;

api/src/main/java/org/openmrs/module/initializer/api/HibernateInitializerDAO.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,18 +113,30 @@ public void deleteLock(String lockName) {
113113

114114
@Override
115115
@SuppressWarnings("unchecked")
116-
public List<InitializerChecksum> getAll() {
116+
public List<InitializerChecksum> getAllChecksums() {
117117
return sessionFactory.getCurrentSession().createQuery("FROM InitializerChecksum").list();
118118
}
119119

120120
@Override
121-
public void saveOrUpdate(InitializerChecksum checksum) {
121+
public void saveOrUpdateChecksum(InitializerChecksum checksum) {
122122
sessionFactory.getCurrentSession().saveOrUpdate(checksum);
123123
}
124124

125125
@Override
126-
public void deleteByFilePath(String filePath) {
127-
sessionFactory.getCurrentSession().createQuery("DELETE FROM InitializerChecksum WHERE filePath = :filePath")
128-
.setParameter("filePath", filePath).executeUpdate();
126+
public void clearChecksums() {
127+
sessionFactory.getCurrentSession().createQuery("DELETE FROM InitializerChecksum").executeUpdate();
128+
}
129+
130+
@Override
131+
public void deleteChecksum(String checksumPath) {
132+
sessionFactory.getCurrentSession().createQuery("DELETE FROM InitializerChecksum WHERE filePath = :path")
133+
.setParameter("path", checksumPath).executeUpdate();
134+
}
135+
136+
@Override
137+
public void deleteChecksumsStartingWith(String checksumPathStartingWith) {
138+
sessionFactory.getCurrentSession()
139+
.createQuery("DELETE FROM InitializerChecksum WHERE filePath LIKE :pathStartingWith")
140+
.setParameter("pathStartingWith", checksumPathStartingWith + "%").executeUpdate();
129141
}
130142
}

api/src/main/java/org/openmrs/module/initializer/api/InitializerDAO.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
import org.openmrs.Concept;
77
import org.openmrs.module.initializer.api.entities.InitializerChecksum;
8-
import org.openmrs.module.initializer.api.entities.InitializerLock;
98

109
/**
1110
* For database related functions
@@ -28,10 +27,13 @@ public interface InitializerDAO {
2827

2928
void deleteLock(String lockName);
3029

31-
List<InitializerChecksum> getAll();
30+
List<InitializerChecksum> getAllChecksums();
3231

33-
void saveOrUpdate(InitializerChecksum checksum);
32+
void saveOrUpdateChecksum(InitializerChecksum checksum);
3433

35-
void deleteByFilePath(String filePath);
34+
void clearChecksums();
3635

36+
void deleteChecksum(String checksumPath);
37+
38+
void deleteChecksumsStartingWith(String checksumPathStartingWith);
3739
}

api/src/main/java/org/openmrs/module/initializer/api/InitializerService.java

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,17 @@
99
*/
1010
package org.openmrs.module.initializer.api;
1111

12+
import java.io.File;
1213
import java.io.InputStream;
1314
import java.nio.file.Path;
1415
import java.util.List;
16+
import java.util.Map;
1517

1618
import org.openmrs.Concept;
1719
import org.openmrs.PersonAttributeType;
1820
import org.openmrs.api.OpenmrsService;
1921
import org.openmrs.module.initializer.InitializerConfig;
22+
import org.openmrs.module.initializer.api.entities.InitializerChecksum;
2023
import org.openmrs.module.initializer.api.loaders.Loader;
2124

2225
public interface InitializerService extends OpenmrsService {
@@ -32,6 +35,14 @@ public interface InitializerService extends OpenmrsService {
3235
*/
3336
String getConfigDirPath();
3437

38+
/**
39+
* @return The path to the checksum folder (with NO trailing forward slash), eg.
40+
* "/opt/openmrs/configuration_checksums"
41+
* @deprecated used only for migration
42+
*/
43+
@Deprecated
44+
String getChecksumsDirPath();
45+
3546
/**
3647
* @return The list of ordered domain loaders.
3748
*/
@@ -128,18 +139,64 @@ public interface InitializerService extends OpenmrsService {
128139
List<Concept> getUnretiredConceptsByFullySpecifiedName(String name);
129140

130141
/**
131-
* Determines whether the initializer configuration has changed since the last successful execution.
142+
* Determines whether the initializer config files have changed since the last successful execution.
132143
*
133-
* @return true or false if configuration changes are detected and the initializer should run or
134-
* otherwise.
144+
* @return true or false if changes are detected and the initializer should run or otherwise.
135145
*/
136-
Boolean isConfigChanged();
146+
boolean hasChecksumsChanged();
137147

138148
/**
139-
* Updates and persists the current configuration checksums after a successful initializer
140-
* execution.
149+
* Used to free up memory after initialization is done
141150
*/
142-
void updateChecksums();
151+
void clearChecksumsCache();
152+
153+
/**
154+
* Used for testing only
155+
*/
156+
void clearChecksums();
157+
158+
/**
159+
* Use to delete a checksum for a particular Path
160+
*
161+
* @param path
162+
*/
163+
void deleteChecksum(Path path);
164+
165+
/**
166+
* Delete all checksums for a particular domain
167+
*
168+
* @param domain
169+
*/
170+
void deleteChecksums(String domain);
171+
172+
/**
173+
* Gets all checksums from DB.
174+
*
175+
* @return map of file paths and checksums
176+
*/
177+
Map<String, String> getAllChecksums();
178+
179+
/**
180+
* Calculates checksum for the given file and returns it if it is different from the one in DB.
181+
*
182+
* @param file
183+
* @return checksum if changed
184+
*/
185+
InitializerChecksum getChecksumIfChanged(File file);
186+
187+
/**
188+
* Calculates checksums for all initializer files. It is cached.
189+
*
190+
* @return map of file paths and checksums
191+
*/
192+
Map<String, String> getFileChecksums();
193+
194+
/**
195+
* Saves new or updates checksum if changed
196+
*
197+
* @param checksum
198+
*/
199+
void saveOrUpdateChecksum(InitializerChecksum checksum);
143200

144201
/**
145202
* Attempts to acquire the initializer lock for the given name.
@@ -165,4 +222,10 @@ public interface InitializerService extends OpenmrsService {
165222
*/
166223
void acquireLockOrWait(String lockName, long timeoutMillis);
167224

225+
/**
226+
* Runs the initialization process, including migration and configuration loading.
227+
*/
228+
void runInitializer();
229+
230+
void migrateChecksumsFromFilesToDB();
168231
}

0 commit comments

Comments
 (0)