Skip to content

Commit 410a0ef

Browse files
MMaieroCopilot
andauthored
fix(core.configuration): make snapshot storage more resilient [backport 5.6.0] (#5991)
* fix(core.configuration): make snapshot storage more resilient This is a partial backport of the streaming optimization changes introduced in #5734. The changes improve memory efficiency during snapshot operations by utilizing streaming APIs instead of storing multiple copies of large snapshots in memory, making the snapshot storage process more resilient to memory constraints. Signed-off-by: MMaiero <[email protected]> * Update kura/org.eclipse.kura.core.configuration/src/main/java/org/eclipse/kura/core/configuration/ConfigurationServiceImpl.java Co-authored-by: Copilot <[email protected]> * Partial implemented the changes suggested by copilot Signed-off-by: MMaiero <[email protected]> * Updated versions and cleanup Signed-off-by: MMaiero <[email protected]> * Aligned to develop on the file move Signed-off-by: MMaiero <[email protected]> --------- Signed-off-by: MMaiero <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent 2916d45 commit 410a0ef

File tree

3 files changed

+554
-27
lines changed

3 files changed

+554
-27
lines changed

kura/distrib/config/kura.build.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ org.eclipse.kura.core.keystore.version=1.6.0
1313
org.eclipse.kura.core.cloud.version=1.7.0
1414
org.eclipse.kura.core.cloud.factory.version=1.6.0
1515
org.eclipse.kura.core.comm.version=1.6.0
16-
org.eclipse.kura.core.configuration.version=2.6.0
16+
org.eclipse.kura.core.configuration.version=2.6.1-SNAPSHOT
1717
org.eclipse.kura.core.crypto.version=1.6.0
1818
org.eclipse.kura.deployment.agent.version=1.6.0
1919
org.eclipse.kura.core.deployment.version=1.7.0

kura/org.eclipse.kura.core.configuration/src/main/java/org/eclipse/kura/core/configuration/ConfigurationServiceImpl.java

Lines changed: 55 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2011, 2022 Eurotech and/or its affiliates and others
2+
* Copyright (c) 2011, 2025 Eurotech and/or its affiliates and others
33
*
44
* This program and the accompanying materials are made
55
* available under the terms of the Eclipse Public License 2.0
@@ -21,9 +21,12 @@
2121
import java.io.FileReader;
2222
import java.io.IOException;
2323
import java.io.OutputStreamWriter;
24-
import java.io.UnsupportedEncodingException;
24+
import java.nio.charset.StandardCharsets;
2525
import java.nio.file.Files;
2626
import java.nio.file.Path;
27+
import java.nio.file.StandardCopyOption;
28+
import java.nio.file.attribute.PosixFilePermission;
29+
import java.nio.file.attribute.PosixFilePermissions;
2730
import java.util.ArrayList;
2831
import java.util.Arrays;
2932
import java.util.Collections;
@@ -45,6 +48,7 @@
4548

4649
import org.eclipse.kura.KuraErrorCode;
4750
import org.eclipse.kura.KuraException;
51+
import org.eclipse.kura.KuraIOException;
4852
import org.eclipse.kura.KuraPartialSuccessException;
4953
import org.eclipse.kura.configuration.ComponentConfiguration;
5054
import org.eclipse.kura.configuration.ConfigurableComponent;
@@ -1174,40 +1178,69 @@ private void writeSnapshot(long sid, XmlComponentConfigurations conf) throws Kur
11741178
// Encrypt the XML
11751179
char[] encryptedXML = this.cryptoService.encryptAes(xmlResult.toCharArray());
11761180

1181+
File tempSnapshotFile = getTempSnapshotFile(fSnapshot);
1182+
11771183
// Write the snapshot
1178-
FileOutputStream fos = null;
1179-
OutputStreamWriter osw = null;
11801184
try {
1185+
try (FileOutputStream fos = new FileOutputStream(tempSnapshotFile);
1186+
OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8)) {
1187+
logger.debug("Writing temp snapshot - Saving {}...", tempSnapshotFile.getAbsolutePath());
1188+
osw.append(new String(encryptedXML));
1189+
osw.flush();
1190+
fos.flush();
1191+
fos.getFD().sync();
1192+
logger.debug("Writing temp snapshot - Saving {}... Done.", tempSnapshotFile.getAbsolutePath());
1193+
}
11811194
logger.info("Writing snapshot - Saving {}...", fSnapshot.getAbsolutePath());
1182-
fos = new FileOutputStream(fSnapshot);
1183-
osw = new OutputStreamWriter(fos, "UTF-8");
1184-
osw.append(new String(encryptedXML));
1185-
osw.flush();
1186-
fos.flush();
1187-
fos.getFD().sync();
1195+
moveTempFile(fSnapshot, tempSnapshotFile);
11881196
logger.info("Writing snapshot - Saving {}... Done.", fSnapshot.getAbsolutePath());
11891197
} catch (FileNotFoundException e) {
11901198
throw new KuraException(KuraErrorCode.INTERNAL_ERROR, e);
1191-
} catch (UnsupportedEncodingException e) {
1192-
throw new KuraException(KuraErrorCode.INTERNAL_ERROR, e);
11931199
} catch (IOException e) {
1194-
throw new KuraException(KuraErrorCode.INTERNAL_ERROR, e);
1200+
throw new KuraIOException(e);
11951201
} finally {
1196-
if (osw != null) {
1202+
if (tempSnapshotFile.exists()) {
11971203
try {
1198-
osw.close();
1204+
Files.delete(tempSnapshotFile.toPath());
11991205
} catch (IOException e) {
1200-
1206+
// Ignore cleanup errors
12011207
}
12021208
}
1203-
if (fos != null) {
1204-
try {
1205-
fos.close();
1206-
} catch (IOException e) {
1209+
}
1210+
}
12071211

1208-
}
1209-
}
1212+
private void moveTempFile(File fSnapshot, File tempSnapshotFile) throws KuraIOException {
1213+
try {
1214+
setSnapshotFilePermissions(fSnapshot, tempSnapshotFile);
1215+
1216+
// Consolidate snapshot writing
1217+
Files.move(tempSnapshotFile.toPath(), fSnapshot.toPath(), StandardCopyOption.REPLACE_EXISTING,
1218+
StandardCopyOption.ATOMIC_MOVE);
1219+
} catch (IOException e) {
1220+
throw new KuraIOException(e);
1221+
}
1222+
}
1223+
1224+
private void setSnapshotFilePermissions(File fSnapshot, File tempSnapshotFile) throws IOException {
1225+
try {
1226+
Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rw-------");
1227+
Files.setPosixFilePermissions(tempSnapshotFile.toPath(), perms);
1228+
1229+
} catch (UnsupportedOperationException e1) {
1230+
// POSIX permissions not supported on this file system, log and continue
1231+
logger.warn("Unable to set POSIX file permissions for snapshot file: {}", fSnapshot.getAbsolutePath(),
1232+
e1);
1233+
}
1234+
}
1235+
1236+
private File getTempSnapshotFile(File fSnapshot) throws KuraIOException {
1237+
File tempSnapshotFile;
1238+
try {
1239+
tempSnapshotFile = File.createTempFile(fSnapshot.getName(), null, new File(fSnapshot.getParent()));
1240+
} catch (IOException ex) {
1241+
throw new KuraIOException(ex);
12101242
}
1243+
return tempSnapshotFile;
12111244
}
12121245

12131246
private ComponentConfiguration getConfigurableComponentConfiguration(String pid) {

0 commit comments

Comments
 (0)