Skip to content

Commit 1091e59

Browse files
committed
Use compare and set to make thread safe
1 parent 82f045e commit 1091e59

File tree

2 files changed

+26
-29
lines changed

2 files changed

+26
-29
lines changed

core/auth/src/main/java/software/amazon/awssdk/auth/credentials/ProfileCredentialsProvider.java

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.util.Objects;
1919
import java.util.Optional;
20+
import java.util.concurrent.atomic.AtomicReference;
2021
import java.util.function.Consumer;
2122
import java.util.function.Supplier;
2223
import software.amazon.awssdk.annotations.SdkPublicApi;
@@ -49,10 +50,10 @@ public final class ProfileCredentialsProvider
4950
SdkAutoCloseable,
5051
ToCopyableBuilder<ProfileCredentialsProvider.Builder, ProfileCredentialsProvider> {
5152

52-
private AwsCredentialsProvider credentialsProvider;
53+
private final AtomicReference<AwsCredentialsProvider> credentialsProvider = new AtomicReference<>();
5354
private final RuntimeException loadException;
5455
private final Supplier<ProfileFile> profileFile;
55-
private volatile ProfileFile currentProfileFile;
56+
private final AtomicReference<ProfileFile> currentProfileFile = new AtomicReference<>();
5657
private final String profileName;
5758
private final Supplier<ProfileFile> defaultProfileFileLoader;
5859

@@ -116,32 +117,21 @@ public AwsCredentials resolveCredentials() {
116117
throw loadException;
117118
}
118119

120+
ProfileFile current = currentProfileFile.get();
119121
ProfileFile cachedOrRefreshedProfileFile = refreshProfileFile();
120-
if (isNewProfileFile(cachedOrRefreshedProfileFile)) {
121-
currentProfileFile = cachedOrRefreshedProfileFile;
122+
if (!Objects.equals(current, cachedOrRefreshedProfileFile)
123+
&& currentProfileFile.compareAndSet(current, cachedOrRefreshedProfileFile)) {
122124
handleProfileFileReload(cachedOrRefreshedProfileFile);
123125
}
124126

125-
return credentialsProvider.resolveCredentials();
126-
}
127-
128-
private void handleProfileFileReload(ProfileFile profileFile) {
129-
credentialsProvider = createCredentialsProvider(profileFile, profileName);
130-
}
131-
132-
private ProfileFile refreshProfileFile() {
133-
return profileFile.get();
134-
}
135-
136-
private boolean isNewProfileFile(ProfileFile profileFile) {
137-
return !Objects.equals(currentProfileFile, profileFile);
127+
return credentialsProvider.get().resolveCredentials();
138128
}
139129

140130
@Override
141131
public String toString() {
142132
return ToString.builder("ProfileCredentialsProvider")
143133
.add("profileName", profileName)
144-
.add("profileFile", currentProfileFile)
134+
.add("profileFile", currentProfileFile.get())
145135
.build();
146136
}
147137

@@ -155,6 +145,14 @@ public void close() {
155145
IoUtils.closeIfCloseable(credentialsProvider, null);
156146
}
157147

148+
private void handleProfileFileReload(ProfileFile profileFile) {
149+
credentialsProvider.set(createCredentialsProvider(profileFile, profileName));
150+
}
151+
152+
private ProfileFile refreshProfileFile() {
153+
return profileFile.get();
154+
}
155+
158156
@Override
159157
public Builder toBuilder() {
160158
return new BuilderImpl(this);

core/auth/src/main/java/software/amazon/awssdk/auth/token/credentials/ProfileTokenProvider.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.util.Objects;
1919
import java.util.Optional;
20+
import java.util.concurrent.atomic.AtomicReference;
2021
import java.util.function.Supplier;
2122
import software.amazon.awssdk.annotations.SdkPublicApi;
2223
import software.amazon.awssdk.annotations.SdkTestInternalApi;
@@ -38,10 +39,11 @@
3839
*/
3940
@SdkPublicApi
4041
public final class ProfileTokenProvider implements SdkTokenProvider, SdkAutoCloseable {
41-
private SdkTokenProvider tokenProvider;
42+
43+
private final AtomicReference<SdkTokenProvider> tokenProvider = new AtomicReference<>();
4244
private final RuntimeException loadException;
4345
private final Supplier<ProfileFile> profileFile;
44-
private volatile ProfileFile currentProfileFile;
46+
private final AtomicReference<ProfileFile> currentProfileFile = new AtomicReference<>();
4547
private final String profileName;
4648

4749
/**
@@ -100,20 +102,21 @@ public SdkToken resolveToken() {
100102
throw loadException;
101103
}
102104

105+
ProfileFile current = currentProfileFile.get();
103106
ProfileFile cachedOrRefreshedProfileFile = refreshProfileFile();
104-
if (isNewProfileFile(cachedOrRefreshedProfileFile)) {
105-
currentProfileFile = cachedOrRefreshedProfileFile;
107+
if (!Objects.equals(current, cachedOrRefreshedProfileFile)
108+
&& currentProfileFile.compareAndSet(current, cachedOrRefreshedProfileFile)) {
106109
handleProfileFileReload(cachedOrRefreshedProfileFile);
107110
}
108111

109-
return tokenProvider.resolveToken();
112+
return tokenProvider.get().resolveToken();
110113
}
111114

112115
@Override
113116
public String toString() {
114117
return ToString.builder("ProfileTokenProvider")
115118
.add("profileName", profileName)
116-
.add("profileFile", currentProfileFile)
119+
.add("profileFile", currentProfileFile.get())
117120
.build();
118121
}
119122

@@ -135,17 +138,13 @@ private SdkTokenProvider createTokenProvider(ProfileFile profileFile, String pro
135138
}
136139

137140
private void handleProfileFileReload(ProfileFile profileFile) {
138-
tokenProvider = createTokenProvider(profileFile, profileName);
141+
tokenProvider.set(createTokenProvider(profileFile, profileName));
139142
}
140143

141144
private ProfileFile refreshProfileFile() {
142145
return profileFile.get();
143146
}
144147

145-
private boolean isNewProfileFile(ProfileFile profileFile) {
146-
return !Objects.equals(currentProfileFile, profileFile);
147-
}
148-
149148
/**
150149
* A builder for creating a custom {@link ProfileTokenProvider}.
151150
*/

0 commit comments

Comments
 (0)