1818import java .io .File ;
1919import java .io .IOException ;
2020import java .util .ArrayList ;
21- import java .util .HashSet ;
21+ import java .util .Date ;
22+ import java .util .HashMap ;
2223import java .util .List ;
24+ import java .util .Map ;
2325import java .util .Set ;
2426
27+ import org .apache .commons .io .FileUtils ;
2528import org .slf4j .Logger ;
2629import org .slf4j .LoggerFactory ;
2730import org .springframework .core .io .ClassPathResource ;
2831import org .springframework .core .io .Resource ;
2932import org .springframework .web .client .ResourceAccessException ;
3033
34+ import com .google .gson .Gson ;
3135import com .marklogic .appdeployer .AppConfig ;
3236import com .marklogic .appdeployer .ConfigDir ;
3337import com .marklogic .appdeployer .command .Command ;
4246import com .marklogic .appdeployer .impl .SimpleAppDeployer ;
4347import com .marklogic .client .modulesloader .Modules ;
4448import com .marklogic .client .modulesloader .ModulesFinder ;
49+ import com .marklogic .client .modulesloader .ModulesManager ;
50+ import com .marklogic .client .modulesloader .impl .DefaultModulesLoader ;
4551import com .marklogic .hub .commands .LoadModulesCommand ;
52+ import com .marklogic .hub .util .GsonUtil ;
4653import com .marklogic .mgmt .ManageClient ;
4754import com .marklogic .mgmt .ManageConfig ;
4855import com .marklogic .mgmt .admin .AdminConfig ;
5158
5259public class DataHub {
5360
54- static final private Logger logger = LoggerFactory .getLogger (DataHub .class );
61+ static final private Logger LOGGER = LoggerFactory .getLogger (DataHub .class );
5562
5663 private ManageConfig config ;
5764 private ManageClient client ;
@@ -62,6 +69,8 @@ public class DataHub {
6269 private String username ;
6370 private String password ;
6471
72+ private File assetInstallTimeFile ;
73+
6574 private final static int DEFAULT_REST_PORT = 8010 ;
6675
6776 public DataHub (HubConfig config ) {
@@ -80,7 +89,11 @@ public DataHub(String host, int restPort, String username, String password) {
8089 this .username = username ;
8190 this .password = password ;
8291 }
83-
92+
93+ public void setAssetInstallTimeFile (File assetInstallTimeFile ) {
94+ this .assetInstallTimeFile = assetInstallTimeFile ;
95+ }
96+
8497 /**
8598 * Determines if the data hub is installed in MarkLogic
8699 * @return true if installed, false otherwise
@@ -142,11 +155,13 @@ public void install() throws IOException {
142155 /**
143156 * Installs User Provided modules into the Data Hub
144157 *
145- * @param pathToUserModules - the absolute path to the user's modules folder
146- * @return the set of files that was loaded into MarkLogic
158+ * @param pathToUserModules
159+ * - the absolute path to the user's modules folder
160+ * @return the canonical/absolute path of files that was loaded, together
161+ * with its install time
147162 * @throws IOException
148163 */
149- public Set <File > installUserModules (String pathToUserModules ) throws IOException {
164+ public Map <File , Date > installUserModules (String pathToUserModules ) throws IOException {
150165 AppConfig config = new AppConfig ();
151166 config .setHost (host );
152167 config .setRestPort (restPort );
@@ -155,20 +170,44 @@ public Set<File> installUserModules(String pathToUserModules) throws IOException
155170 config .setRestAdminPassword (password );
156171
157172 RestAssetLoader loader = new RestAssetLoader (config .newDatabaseClient ());
173+ DataHubModuleManager modulesManager = new DataHubModuleManager ();
174+ if (assetInstallTimeFile != null ) {
175+ loader .setModulesManager (modulesManager );
176+ }
158177
159178 ModulesFinder finder = new AssetModulesFinder ();
160179 Modules modules = finder .findModules (new File (pathToUserModules ));
161180
162181 List <Resource > dirs = modules .getAssetDirectories ();
163182 if (dirs == null || dirs .isEmpty ()) {
164- return new HashSet < File >();
183+ return new HashMap < >();
165184 }
166185
167186 String [] paths = new String [dirs .size ()];
168187 for (int i = 0 ; i < dirs .size (); i ++) {
169188 paths [i ] = dirs .get (i ).getFile ().getAbsolutePath ();
170189 }
171- return loader .loadAssetsViaREST (paths );
190+ Set <File > loadedFiles = loader .loadAssetsViaREST (paths );
191+
192+ if (assetInstallTimeFile != null ) {
193+ Gson gson = GsonUtil .createGson ();
194+
195+ String json = gson .toJson (modulesManager .getLastInstallInfo ());
196+ try {
197+ FileUtils .write (assetInstallTimeFile , json );
198+ } catch (IOException e ) {
199+ LOGGER .error ("Cannot write asset install info." , e );
200+ }
201+
202+ return modulesManager .getLastInstallInfo ();
203+ }
204+ else {
205+ Map <File , Date > fileMap = new HashMap <>();
206+ for (File file : loadedFiles ) {
207+ fileMap .put (file , file .exists () ? new Date (file .lastModified ()) : null );
208+ }
209+ return fileMap ;
210+ }
172211 }
173212
174213 private List <Command > getCommands (AppConfig config ) {
@@ -214,5 +253,44 @@ public void uninstall() throws IOException {
214253 deployer .setCommands (getCommands (config ));
215254 deployer .undeploy (config );
216255 }
256+
257+ private class DataHubModuleManager implements ModulesManager {
258+ private Map <File , Date > lastInstallInfo = new HashMap <>();
259+
260+ public Map <File , Date > getLastInstallInfo () {
261+ return lastInstallInfo ;
262+ }
263+
264+ @ Override
265+ public void initialize () {
266+ LOGGER .debug ("initializing DataHubModuleManager" );
267+ }
268+
269+ @ Override
270+ public boolean hasFileBeenModifiedSinceLastInstalled (File file ) {
271+ Date lastInstallDate = null ;
272+ try {
273+ lastInstallDate = lastInstallInfo .get (new File (file .getCanonicalPath ()));
274+ } catch (IOException e ) {
275+ LOGGER .warn ("Cannot get canonical path of {}. Using absolute path instead." , file );
276+ lastInstallDate = lastInstallInfo .get (new File (file .getAbsolutePath ()));
277+ }
278+
279+ // a file has been modified if it has not been previously installed (new file)
280+ // or when its modified time is after the last install time
281+ return lastInstallDate == null || file .lastModified () > lastInstallDate .getTime ();
282+ }
217283
284+ @ Override
285+ public void saveLastInstalledTimestamp (File file , Date date ) {
286+ try {
287+ LOGGER .trace ("saving last timestamp of " + file .getCanonicalPath () + ": " + date );
288+ lastInstallInfo .put (new File (file .getCanonicalPath ()), date );
289+ } catch (IOException e ) {
290+ LOGGER .warn ("Cannot store canonical path of {}. Storing absolute path instead." , file );
291+ lastInstallInfo .put (new File (file .getAbsolutePath ()), date );
292+ }
293+ }
294+
295+ }
218296}
0 commit comments