Skip to content

Commit e45585b

Browse files
committed
Bug fix: ProfileFileSupplier aggregate files in order
1 parent 7d2edde commit e45585b

File tree

3 files changed

+65
-5
lines changed

3 files changed

+65
-5
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: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
package software.amazon.awssdk.profiles;
1717

1818
import java.nio.file.Path;
19+
import java.util.ArrayList;
20+
import java.util.List;
1921
import java.util.Objects;
2022
import java.util.Optional;
2123
import java.util.concurrent.ConcurrentHashMap;
@@ -124,29 +126,31 @@ static ProfileFileSupplier aggregate(ProfileFileSupplier... suppliers) {
124126
@Override
125127
public ProfileFile get() {
126128
boolean refreshAggregate = false;
129+
List<ProfileFile> nextValues = new ArrayList<>(suppliers.length);
127130
for (ProfileFileSupplier supplier : suppliers) {
128-
if (didSuppliedValueChange(supplier)) {
131+
if (didSuppliedValueChange(supplier, nextValues)) {
129132
refreshAggregate = true;
130133
}
131134
}
132135

133136
if (refreshAggregate) {
134-
refreshCurrentAggregate();
137+
refreshCurrentAggregate(nextValues);
135138
}
136139

137140
return currentAggregateProfileFile.get();
138141
}
139142

140-
private boolean didSuppliedValueChange(Supplier<ProfileFile> supplier) {
143+
private boolean didSuppliedValueChange(Supplier<ProfileFile> supplier, List<ProfileFile> nextValues) {
141144
ProfileFile next = supplier.get();
145+
nextValues.add(next);
142146
ProfileFile current = currentValuesBySupplier.put(supplier, next);
143147

144148
return !Objects.equals(next, current);
145149
}
146150

147-
private void refreshCurrentAggregate() {
151+
private void refreshCurrentAggregate(List<ProfileFile> nextValues) {
148152
ProfileFile.Aggregator aggregator = ProfileFile.aggregator();
149-
currentValuesBySupplier.values().forEach(aggregator::addFile);
153+
nextValues.forEach(aggregator::addFile);
150154
ProfileFile current = currentAggregateProfileFile.get();
151155
ProfileFile next = aggregator.build();
152156
if (!Objects.equals(current, next)) {

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)