Skip to content

Commit fef74ab

Browse files
authored
ProfileFileSupplier aggregate files in order (#3754)
* Bug fix: ProfileFileSupplier aggregate files in order * Update solution to use LinkedHashMap * Wrap LinkedHashMap into synchronized Map
1 parent 7c694a0 commit fef74ab

File tree

3 files changed

+61
-2
lines changed

3 files changed

+61
-2
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"category": "AWS SDK for Java v2",
3+
"contributor": "",
4+
"type": "bugfix",
5+
"description": "Keep precedence of options when passed to ProfileFileSupplier.aggregate"
6+
}

core/profiles/src/main/java/software/amazon/awssdk/profiles/ProfileFileSupplier.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
package software.amazon.awssdk.profiles;
1717

1818
import java.nio.file.Path;
19+
import java.util.Collections;
20+
import java.util.LinkedHashMap;
21+
import java.util.Map;
1922
import java.util.Objects;
2023
import java.util.Optional;
21-
import java.util.concurrent.ConcurrentHashMap;
2224
import java.util.concurrent.atomic.AtomicReference;
2325
import java.util.function.Supplier;
2426
import software.amazon.awssdk.annotations.SdkPublicApi;
@@ -119,7 +121,8 @@ static ProfileFileSupplier aggregate(ProfileFileSupplier... suppliers) {
119121
return new ProfileFileSupplier() {
120122

121123
final AtomicReference<ProfileFile> currentAggregateProfileFile = new AtomicReference<>();
122-
final ConcurrentHashMap<Supplier<ProfileFile>, ProfileFile> currentValuesBySupplier = new ConcurrentHashMap<>();
124+
final Map<Supplier<ProfileFile>, ProfileFile> currentValuesBySupplier
125+
= Collections.synchronizedMap(new LinkedHashMap<>());
123126

124127
@Override
125128
public ProfileFile get() {

core/profiles/src/test/java/software/amazon/awssdk/profiles/ProfileFileSupplierTest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,56 @@ void aggregate_supplierReturnsSameInstanceMultipleTimesAggregatingProfileFileSup
410410
assertThat(suppliedProfileFiles).isEqualTo(distinctAggregateProfileFiles);
411411
}
412412

413+
@Test
414+
void aggregate_duplicateOptionsGivenFixedProfileFirst_preservesPrecedence() {
415+
ProfileFile configFile1 = configFile("profile default", Pair.of("aws_access_key_id", "config-key"));
416+
Path credentialsFilePath = generateTestCredentialsFile("defaultAccessKey", "defaultSecretAccessKey");
417+
418+
ProfileFileSupplier supplier = ProfileFileSupplier.aggregate(
419+
ProfileFileSupplier.fixedProfileFile(configFile1),
420+
ProfileFileSupplier.reloadWhenModified(credentialsFilePath, ProfileFile.Type.CREDENTIALS));
421+
422+
ProfileFile profileFile = supplier.get();
423+
String accessKeyId = profileFile.profile("default").get().property("aws_access_key_id").get();
424+
425+
assertThat(accessKeyId).isEqualTo("config-key");
426+
427+
generateTestCredentialsFile("defaultAccessKey2", "defaultSecretAccessKey2");
428+
429+
profileFile = supplier.get();
430+
accessKeyId = profileFile.profile("default").get().property("aws_access_key_id").get();
431+
432+
assertThat(accessKeyId).isEqualTo("config-key");
433+
}
434+
435+
@Test
436+
void aggregate_duplicateOptionsGivenReloadingProfileFirst_preservesPrecedence() {
437+
AdjustableClock clock = new AdjustableClock();
438+
439+
ProfileFile configFile1 = configFile("profile default", Pair.of("aws_access_key_id", "config-key"));
440+
Path credentialsFilePath = generateTestCredentialsFile("defaultAccessKey", "defaultSecretAccessKey");
441+
442+
ProfileFileSupplier supplier = ProfileFileSupplier.aggregate(
443+
builderWithClock(clock)
444+
.reloadWhenModified(credentialsFilePath, ProfileFile.Type.CREDENTIALS)
445+
.build(),
446+
ProfileFileSupplier.fixedProfileFile(configFile1));
447+
448+
ProfileFile profileFile = supplier.get();
449+
String accessKeyId = profileFile.profile("default").get().property("aws_access_key_id").get();
450+
451+
assertThat(accessKeyId).isEqualTo("defaultAccessKey");
452+
453+
generateTestCredentialsFile("defaultAccessKey2", "defaultSecretAccessKey2");
454+
455+
clock.tickForward(Duration.ofMillis(1_000));
456+
457+
profileFile = supplier.get();
458+
accessKeyId = profileFile.profile("default").get().property("aws_access_key_id").get();
459+
460+
assertThat(accessKeyId).isEqualTo("defaultAccessKey2");
461+
}
462+
413463
@Test
414464
void fixedProfileFile_nullProfileFile_returnsNonNullSupplier() {
415465
ProfileFile file = null;

0 commit comments

Comments
 (0)