Copy application package atomically
Fix bug where we don't do this atomically, looks like this can happend
when application package is copied at the same time as config server is shut down
@@ -41,6 +41,8 @@ import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
@@ -504,7 +506,7 @@ public class SessionRepository {
long sessionId, Optional<Long> currentlyActiveSessionId,
boolean internalRedeploy) throws IOException {
File userApplicationDir = getSessionAppDir(sessionId);
- IOUtils.copyDirectory(applicationFile, userApplicationDir);
+ copyApp(applicationFile, userApplicationDir);
ApplicationPackage applicationPackage = createApplication(applicationFile,
userApplicationDir,
applicationId,
@@ -515,6 +517,20 @@ public class SessionRepository {
return applicationPackage;
}
+ private void copyApp(File sourceDir, File destinationDir) throws IOException {
+ if (destinationDir.exists())
+ throw new RuntimeException("Destination dir " + destinationDir + " already exists");
+ if (! sourceDir.isDirectory())
+ throw new IllegalArgumentException(sourceDir.getAbsolutePath() + " is not a directory");
+
+ // Copy app it atomically: Copy to default tmp dir and move to destination
+ java.nio.file.Path tempDestinationDir = Files.createTempDirectory(destinationDir.getParentFile().toPath(), "app-package");
+ log.log(Level.FINE, "Copying dir " + sourceDir.getAbsolutePath() + " to " + tempDestinationDir.toFile().getAbsolutePath());
+ IOUtils.copyDirectory(sourceDir, tempDestinationDir.toFile());
+ log.log(Level.FINE, "Moving " + tempDestinationDir + " to " + destinationDir.getAbsolutePath());
+ Files.move(tempDestinationDir, destinationDir.toPath(), StandardCopyOption.ATOMIC_MOVE);
+ }
+
/**
* Returns a new session instance for the given session id.
*/
