--- /dev/null
+package hu.user.mediacube.integration.safedelete;
+
+import lombok.extern.log4j.Log4j2;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+@Log4j2
+public class FileOperations {
+
+ static public void silentDelete(Path path) {
+ try {
+ Files.delete(path);
+ } catch (Exception e) {
+ log.catching(e);
+ }
+
+ }
+
+ static public void silentRename(Path source, String prefix) {
+ try {
+ String fileName = String.format("%s%s", prefix, source.getFileName().toString());
+ Path target = Paths.get(source.getParent().toAbsolutePath().toString(), fileName);
+ Files.move(source, target);
+ } catch (Exception e) {
+ log.catching(e);
+ }
+ }
+}
@Component
@Log4j2
public class SafeDeleteCommand {
+ private static final String ERROR_FILENAME_PREFIX = "ERROR-";
+
@Autowired
MediaCubeDatabaseService mediaCubeDatabaseService;
Path inputPath = Paths.get(directory);
try (DirectoryStream<Path> stream = Files.newDirectoryStream(inputPath)) {
for (Path filePath : stream) {
- if (!Files.isDirectory(filePath)) {
- processInputFile(filePath, forceDeleteArchived);
+ if (Files.isDirectory(filePath) || filePath.getFileName().toString().startsWith(ERROR_FILENAME_PREFIX)) {
+ continue;
}
+ processInputFile(filePath, forceDeleteArchived);
}
}
}
tsmService.verify(source, status);
if (forceDeleteArchived && status.isFileSizeEquals() && status.isHashEquals()) {
- try {
- Files.delete(source);
- } catch (Exception e) {
- log.catching(e);
- }
+ FileOperations.silentDelete(source);
}
} catch (Exception e) {
log.catching(e);
+ FileOperations.silentRename(source, ERROR_FILENAME_PREFIX);
}
}
}
@Log4j2
@SpringBootApplication()
-@MapperScan({"hu.user.mediacube.rdb"})
+@MapperScan({"hu.user.mediacube.rdb", "hu.user.mediacube.integration.safedelete.db"})
public class SafeDeleteMainEntry implements CommandLineRunner {
@Autowired
SafeDeleteCommand safeDeleteCommand;
package hu.user.mediacube.integration.safedelete;
import lombok.Getter;
+import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@Getter
+@Setter
@ConfigurationProperties(prefix = "tsm")
public class SafeDeleteProperties {
private String nodeName;
@Mapper()
public interface MediaCubeRecordMapper {
- @SelectProvider(type = MediaCubeRecord.class, method = "getByFileName")
+ @SelectProvider(type = MediaCubeRecordProvider.class, method = "getByFileName")
@Results({
@Result(property = "item.id", column = "itemid", jdbcType = JdbcType.BIGINT, id = true),
@Result(property = "media.id", column = "mediaid", jdbcType = JdbcType.BIGINT, id = true),
SQL sql = new SQL();
sql.SELECT("i.id item", "m.id mediaid", "m.archived", "mf.id mediafilefid", "mf.lastmodified");
sql.FROM("mediafile mf");
- sql.LEFT_OUTER_JOIN("media m ON (m.id = mf.mediaid)");
- sql.LEFT_OUTER_JOIN("item i ON (i.id = m.itemid)");
+ sql.INNER_JOIN("media m ON (m.id = mf.mediaid)");
+ sql.INNER_JOIN("item i ON (i.id = m.itemid)");
sql.WHERE("mf.relativepath = #{fileName}");
return sql.toString();
}
public void verify(String fileName, ArchiveFileStatus status) throws Exception {
List<MediaCubeRecord> dbRecords = mediaCubeRecordMapper.getByFileName(fileName);
if (dbRecords.size() != 1) {
- throw new Exception("Database records count mismatch. Expected 1 found " + dbRecords.size());
+ throw new Exception(String.format("Database record count mismatch. Expected 1 found %d", dbRecords.size()));
}
status.setMetadataExists(true);
}
package hu.user.mediacube.integration.safedelete.verifier;
import hu.user.mediacube.integration.safedelete.ArchiveFileStatus;
+import hu.user.mediacube.integration.safedelete.FileOperations;
import hu.user.mediacube.integration.safedelete.SafeDeleteProperties;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.codec.digest.DigestUtils;
}
public void verify(Path source, ArchiveFileStatus status) throws Exception {
- Path restored = restore(source.getFileName().toString());
- long restoredLength = restored.toFile().length();
- long originalLength = source.toFile().length();
- if (originalLength != restoredLength) {
- throw new Exception(String.format("File size mismatch. Expected %d, found %d", originalLength, restoredLength));
- }
- status.setFileSizeEquals(true);
+ Path restored = null;
+ try {
+ restored = restore(source.getFileName().toString());
+ long restoredLength = restored.toFile().length();
+ long originalLength = source.toFile().length();
+ if (originalLength != restoredLength) {
+ throw new Exception(String.format("File size mismatch. Expected %d, found %d", originalLength, restoredLength));
+ }
+ status.setFileSizeEquals(true);
- String originalMD5 = createMD5Hash(source);
- String restoredMD5 = createMD5Hash(restored);
- if (!StringUtils.equals(originalMD5, restoredMD5)) {
- throw new Exception(String.format("File MD5 hash mismatch. Expected %d, found %d", originalMD5, restoredMD5));
+ String originalMD5 = createMD5Hash(source);
+ String restoredMD5 = createMD5Hash(restored);
+ if (!StringUtils.equals(originalMD5, restoredMD5)) {
+ throw new Exception(String.format("File MD5 hash mismatch. Expected %d, found %d", originalMD5, restoredMD5));
+ }
+ status.setHashEquals(true);
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ if (Objects.nonNull(restored)) {
+ FileOperations.silentDelete(restored);
+ FileOperations.silentDelete(restored.getParent());
+ }
}
- status.setHashEquals(true);
}
private String createMD5Hash(Path filePath) throws IOException {