Skip to content

Commit 56998b9

Browse files
committed
Add fallback when atomic move not supported
1 parent 4775f64 commit 56998b9

2 files changed

Lines changed: 28 additions & 4 deletions

File tree

services/signin/src/main/java/software/amazon/awssdk/services/signin/internal/OnDiskTokenManager.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.io.OutputStream;
2121
import java.io.UncheckedIOException;
2222
import java.nio.charset.StandardCharsets;
23+
import java.nio.file.AtomicMoveNotSupportedException;
2324
import java.nio.file.Files;
2425
import java.nio.file.Path;
2526
import java.nio.file.StandardCopyOption;
@@ -90,13 +91,13 @@ public Optional<LoginAccessToken> loadToken() {
9091

9192
@Override
9293
public void storeToken(LoginAccessToken token) {
93-
// atomic write (write to a temp file and then move/replace the destination location).
94+
// Write to a temp file first, then move to the destination to avoid partial reads.
9495
try {
9596
Path temp = createOwnerOnlyTempFile(tokenLocation.getParent(), "token-", ".tmp");
9697
try (OutputStream os = Files.newOutputStream(temp)) {
9798
os.write(marshalToken(token));
9899
}
99-
Files.move(temp, tokenLocation, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
100+
atomicOrFallbackMove(temp, tokenLocation);
100101
} catch (IOException | UncheckedIOException e) {
101102
throw SdkClientException.create("Unable to write token to location " + tokenLocation, e);
102103
}
@@ -118,6 +119,17 @@ private static Path createOwnerOnlyTempFile(Path dir, String prefix, String suff
118119
}
119120
}
120121

122+
/**
123+
* Attempts an atomic move, falling back to a non-atomic replace if the file system does not support it.
124+
*/
125+
private static void atomicOrFallbackMove(Path source, Path target) throws IOException {
126+
try {
127+
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
128+
} catch (AtomicMoveNotSupportedException e) {
129+
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
130+
}
131+
}
132+
121133
@Override
122134
public void close() {
123135

services/ssooidc/src/main/java/software/amazon/awssdk/services/ssooidc/internal/OnDiskTokenManager.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.io.InputStream;
2323
import java.io.OutputStream;
2424
import java.nio.charset.StandardCharsets;
25+
import java.nio.file.AtomicMoveNotSupportedException;
2526
import java.nio.file.Files;
2627
import java.nio.file.Path;
2728
import java.nio.file.Paths;
@@ -85,13 +86,13 @@ public Optional<SsoOidcToken> loadToken() {
8586

8687
@Override
8788
public void storeToken(SsoOidcToken token) {
88-
// Atomic write: write to a temp file with restricted permissions, then move to the destination.
89+
// Write to a temp file first, then move to the destination to avoid partial reads.
8990
try {
9091
Path temp = createOwnerOnlyTempFile(tokenLocation.getParent(), "token-", ".tmp");
9192
try (OutputStream os = Files.newOutputStream(temp)) {
9293
os.write(marshalToken(token));
9394
}
94-
Files.move(temp, tokenLocation, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
95+
atomicOrFallbackMove(temp, tokenLocation);
9596
} catch (IOException e) {
9697
throw SdkClientException.create("Unable to write token to location " + tokenLocation, e);
9798
}
@@ -113,6 +114,17 @@ private static Path createOwnerOnlyTempFile(Path dir, String prefix, String suff
113114
}
114115
}
115116

117+
/**
118+
* Attempts an atomic move, falling back to a non-atomic replace if the file system does not support it.
119+
*/
120+
private static void atomicOrFallbackMove(Path source, Path target) throws IOException {
121+
try {
122+
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
123+
} catch (AtomicMoveNotSupportedException e) {
124+
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
125+
}
126+
}
127+
116128
@Override
117129
public void close() {
118130
}

0 commit comments

Comments
 (0)