Skip to content

Commit b8f0431

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

17 files changed

Lines changed: 397 additions & 269 deletions

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

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,25 @@
99
*/
1010
package org.openmrs.module.initializer;
1111

12+
import java.io.File;
1213
import java.io.IOException;
14+
import java.nio.file.Files;
1315
import java.nio.file.Path;
1416
import java.nio.file.Paths;
1517
import java.util.List;
18+
import java.util.stream.Stream;
1619

20+
import org.apache.commons.io.FileUtils;
21+
import org.apache.commons.lang3.StringUtils;
1722
import org.apache.log4j.Level;
23+
import org.openmrs.GlobalProperty;
24+
import org.openmrs.api.AdministrationService;
1825
import org.openmrs.api.context.Context;
1926
import org.openmrs.module.BaseModuleActivator;
2027
import org.openmrs.module.ModuleException;
28+
import org.openmrs.module.initializer.api.ConfigDirUtil;
2129
import org.openmrs.module.initializer.api.InitializerService;
30+
import org.openmrs.module.initializer.api.entities.InitializerChecksum;
2231
import org.openmrs.module.initializer.api.logging.InitializerLogConfigurator;
2332
import org.openmrs.util.OpenmrsUtil;
2433
import org.slf4j.Logger;
@@ -76,8 +85,9 @@ public void started() {
7685
InitializerMessageSource messageSource = getInitializerMessageSource();
7786
Context.getMessageSourceService().setActiveMessageSource(messageSource);
7887

79-
String startupLoadingMode = getInitializerService().getInitializerConfig().getStartupLoadingMode();
88+
migrateCheksumsFromFilesToDB();
8089

90+
String startupLoadingMode = getInitializerService().getInitializerConfig().getStartupLoadingMode();
8191
if (PROPS_STARTUP_LOAD_DISABLED.equalsIgnoreCase(startupLoadingMode)) {
8292
log.info("OpenMRS config loading process disabled at initializer startup");
8393
} else {
@@ -91,7 +101,7 @@ public void started() {
91101
lockAquired = true;
92102

93103
// Check if config changed
94-
if (!getInitializerService().isConfigChanged()) {
104+
if (!getInitializerService().hasChecksumsChanged()) {
95105
log.info("No config changes... skipping initializer");
96106
return;
97107
}
@@ -100,9 +110,8 @@ public void started() {
100110
log.info("OpenMRS config loading process started...");
101111
getInitializerService().loadUnsafe(true, throwError);
102112

103-
// Save new checksums
104-
getInitializerService().updateChecksums();
105113
log.info("OpenMRS config loading process completed.");
114+
getInitializerService().clearChecksumsCache(); // Free up memory
106115
}
107116
catch (Exception e) {
108117
log.error("Initializer failed", e);
@@ -117,10 +126,48 @@ public void started() {
117126
}
118127
}
119128

129+
public void migrateCheksumsFromFilesToDB() {
130+
String globalProperty = getAdministrationService().getGlobalProperty("initializer.checksumsMigrated");
131+
if (globalProperty == null) {
132+
// Migrate file checksums, to be removed in later versions
133+
Path base = Paths.get(getInitializerService().getConfigDirPath());
134+
try (Stream<Path> stream = Files.walk(base)) {
135+
stream.filter(p -> p.toString().endsWith(ConfigDirUtil.CHECKSUM_FILE_EXT)).forEach(path -> {
136+
File checksumFile = path.toFile();
137+
if (checksumFile.exists()) {
138+
try {
139+
String checksum = FileUtils.readFileToString(checksumFile, "UTF-8");
140+
Path rel = base.relativize(path);
141+
String filePath = StringUtils.removeEnd(rel.toString().replace(File.separator, "/"),
142+
ConfigDirUtil.CHECKSUM_FILE_EXT);
143+
144+
getInitializerService().saveOrUpdateChecksum(new InitializerChecksum(filePath, checksum));
145+
if (!checksumFile.delete()) {
146+
log.warn("Checksum file {} was not deleted", checksumFile);
147+
}
148+
}
149+
catch (IOException e) {
150+
log.warn("Could not migrate checksum file {}", checksumFile, e);
151+
}
152+
}
153+
});
154+
}
155+
catch (IOException e) {
156+
throw new RuntimeException(e);
157+
}
158+
159+
getAdministrationService().saveGlobalProperty(new GlobalProperty("initializer.checksumsMigrated", "true"));
160+
}
161+
}
162+
120163
protected InitializerService getInitializerService() {
121164
return Context.getService(InitializerService.class);
122165
}
123166

167+
protected AdministrationService getAdministrationService() {
168+
return Context.getAdministrationService();
169+
}
170+
124171
protected List<InitializerLogConfigurator> getInitializerLogConfigurator() {
125172
return Context.getRegisteredComponents(InitializerLogConfigurator.class);
126173
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ 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+
2931
/*
3032
* The domain name, so the final part of configuration domain subdirectory. Eg.
3133
* "locations" in "../configuration/locations"
@@ -39,8 +41,8 @@ public class ConfigDirUtil {
3941
protected String domainDirPath = "";
4042

4143
/**
42-
* Instantiates a configuration directory utility class for the specified configuration and checksum
43-
* files directories and for the specified domain.
44+
* Instantiates a configuration directory utility class for the specified configuration directories
45+
* and for the specified domain.
4446
*
4547
* @param configDirPath The absolute path to the configuration directory.
4648
* @param domain The domain name within the configuration directory.

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,18 +113,17 @@ 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();
129128
}
130129
}

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

Lines changed: 3 additions & 5 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,9 @@ public interface InitializerDAO {
2827

2928
void deleteLock(String lockName);
3029

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

33-
void saveOrUpdate(InitializerChecksum checksum);
34-
35-
void deleteByFilePath(String filePath);
32+
void saveOrUpdateChecksum(InitializerChecksum checksum);
3633

34+
void clearChecksums();
3735
}

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

Lines changed: 42 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 {
@@ -128,18 +131,50 @@ public interface InitializerService extends OpenmrsService {
128131
List<Concept> getUnretiredConceptsByFullySpecifiedName(String name);
129132

130133
/**
131-
* Determines whether the initializer configuration has changed since the last successful execution.
134+
* Determines whether the initializer config files have changed since the last successful execution.
132135
*
133-
* @return true or false if configuration changes are detected and the initializer should run or
134-
* otherwise.
136+
* @return true or false if changes are detected and the initializer should run or otherwise.
135137
*/
136-
Boolean isConfigChanged();
138+
boolean hasChecksumsChanged();
137139

138140
/**
139-
* Updates and persists the current configuration checksums after a successful initializer
140-
* execution.
141+
* Used to free up memory after initialization is done
141142
*/
142-
void updateChecksums();
143+
void clearChecksumsCache();
144+
145+
/**
146+
* Used for testing only
147+
*/
148+
void clearChecksums();
149+
150+
/**
151+
* Gets all checksums from DB.
152+
*
153+
* @return map of file paths and checksums
154+
*/
155+
Map<String, String> getAllChecksums();
156+
157+
/**
158+
* Calculates checksum for the given file and returns it if it is different from the one in DB.
159+
*
160+
* @param file
161+
* @return checksum if changed
162+
*/
163+
InitializerChecksum getChecksumIfChanged(File file);
164+
165+
/**
166+
* Calculates checksums for all initializer files. It is cached.
167+
*
168+
* @return map of file paths and checksums
169+
*/
170+
Map<String, String> getFileChecksums();
171+
172+
/**
173+
* Saves new or updates checksum if changed
174+
*
175+
* @param checksum
176+
*/
177+
void saveOrUpdateChecksum(InitializerChecksum checksum);
143178

144179
/**
145180
* Attempts to acquire the initializer lock for the given name.

0 commit comments

Comments
 (0)