1 /* 2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"). 5 * You may not use this file except in compliance with the License. 6 * A copy of the License is located at 7 * 8 * http://aws.amazon.com/apache2.0 9 * 10 * or in the "license" file accompanying this file. This file is distributed 11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 * express or implied. See the License for the specific language governing 13 * permissions and limitations under the License. 14 */ 15 16 package software.amazon.awssdk.profiles; 17 18 import static org.assertj.core.api.Assertions.assertThat; 19 import static org.assertj.core.api.Assertions.assertThatExceptionOfType; 20 import static org.assertj.core.api.Assertions.assertThatThrownBy; 21 22 import java.util.AbstractMap; 23 import java.util.HashMap; 24 import java.util.Map; 25 import java.util.stream.Stream; 26 import org.junit.jupiter.api.Test; 27 import software.amazon.awssdk.utils.StringInputStream; 28 29 /** 30 * Validate the functionality of {@link ProfileFile}. 31 */ 32 public class ProfileFileTest { 33 @Test emptyFilesHaveNoProfiles()34 public void emptyFilesHaveNoProfiles() { 35 assertThat(configFileProfiles("")).isEmpty(); 36 } 37 38 @Test emptyProfilesHaveNoProperties()39 public void emptyProfilesHaveNoProperties() { 40 assertThat(configFileProfiles("[profile foo]")) 41 .isEqualTo(profiles(profile("foo"))); 42 } 43 44 @Test profileDefinitionsMustEndWithBrackets()45 public void profileDefinitionsMustEndWithBrackets() { 46 assertThatThrownBy(() -> configFileProfiles("[profile foo")) 47 .hasMessageContaining("Profile definition must end with ']'"); 48 } 49 50 @Test profileNamesShouldBeTrimmed()51 public void profileNamesShouldBeTrimmed() { 52 assertThat(configFileProfiles("[profile \tfoo \t]")) 53 .isEqualTo(profiles(profile("foo"))); 54 } 55 56 @Test tabsCanSeparateProfileNamesFromProfilePrefix()57 public void tabsCanSeparateProfileNamesFromProfilePrefix() { 58 assertThat(configFileProfiles("[profile\tfoo]")) 59 .isEqualTo(profiles(profile("foo"))); 60 } 61 62 @Test propertiesMustBeDefinedInAProfile()63 public void propertiesMustBeDefinedInAProfile() { 64 assertThatThrownBy(() -> configFileProfiles("name = value")) 65 .hasMessageContaining("Expected a profile definition"); 66 } 67 68 @Test profilesCanContainProperties()69 public void profilesCanContainProperties() { 70 assertThat(configFileProfiles("[profile foo]\n" + 71 "name = value")) 72 .isEqualTo(profiles(profile("foo", property("name", "value")))); 73 } 74 75 @Test windowsStyleLineEndingsAreSupported()76 public void windowsStyleLineEndingsAreSupported() { 77 assertThat(configFileProfiles("[profile foo]\r\n" + 78 "name = value")) 79 .isEqualTo(profiles(profile("foo", property("name", "value")))); 80 } 81 82 @Test equalsSignsAreSupportedInPropertyNames()83 public void equalsSignsAreSupportedInPropertyNames() { 84 assertThat(configFileProfiles("[profile foo]\r\n" + 85 "name = val=ue")) 86 .isEqualTo(profiles(profile("foo", property("name", "val=ue")))); 87 } 88 89 @Test unicodeCharactersAreSupportedInPropertyValues()90 public void unicodeCharactersAreSupportedInPropertyValues() { 91 assertThat(configFileProfiles("[profile foo]\r\n" + 92 "name = \uD83D\uDE02")) 93 .isEqualTo(profiles(profile("foo", property("name", "\uD83D\uDE02")))); 94 } 95 96 @Test profilesCanContainMultipleProperties()97 public void profilesCanContainMultipleProperties() { 98 assertThat(configFileProfiles("[profile foo]\n" + 99 "name = value\n" + 100 "name2 = value2")) 101 .isEqualTo(profiles(profile("foo", 102 property("name", "value"), 103 property("name2", "value2")))); 104 } 105 106 @Test propertyKeysAndValuesAreTrimmed()107 public void propertyKeysAndValuesAreTrimmed() { 108 assertThat(configFileProfiles("[profile foo]\n" + 109 "name \t= \tvalue \t")) 110 .isEqualTo(profiles(profile("foo", property("name", "value")))); 111 } 112 113 @Test propertyValuesCanBeEmpty()114 public void propertyValuesCanBeEmpty() { 115 assertThat(configFileProfiles("[profile foo]\n" + 116 "name =")) 117 .isEqualTo(profiles(profile("foo", property("name", "")))); 118 } 119 120 @Test propertyKeysCannotBeEmpty()121 public void propertyKeysCannotBeEmpty() { 122 assertThatThrownBy(() -> configFileProfiles("[profile foo]\n" + 123 "= value")) 124 .hasMessageContaining("Property did not have a name"); 125 } 126 127 @Test propertyDefinitionsMustContainAnEqualsSign()128 public void propertyDefinitionsMustContainAnEqualsSign() { 129 assertThatThrownBy(() -> configFileProfiles("[profile foo]\n" + 130 "key : value")) 131 .hasMessageContaining("Expected an '=' sign defining a property"); 132 } 133 134 @Test multipleProfilesCanBeEmpty()135 public void multipleProfilesCanBeEmpty() { 136 assertThat(configFileProfiles("[profile foo]\n" + 137 "[profile bar]")) 138 .isEqualTo(profiles(profile("foo"), 139 profile("bar"))); 140 } 141 142 @Test multipleProfilesCanHaveProperties()143 public void multipleProfilesCanHaveProperties() { 144 assertThat(configFileProfiles("[profile foo]\n" + 145 "name = value\n" + 146 "[profile bar]\n" + 147 "name2 = value2")) 148 .isEqualTo(profiles(profile("foo", property("name", "value")), 149 profile("bar", property("name2", "value2")))); 150 } 151 152 @Test blankLinesAreIgnored()153 public void blankLinesAreIgnored() { 154 assertThat(configFileProfiles("\t \n" + 155 "[profile foo]\n" + 156 "\t\n" + 157 " \n" + 158 "name = value\n" + 159 "\t \n" + 160 "[profile bar]\n" + 161 " \t")) 162 .isEqualTo(profiles(profile("foo", property("name", "value")), 163 profile("bar"))); 164 } 165 166 @Test poundSignCommentsAreIgnored()167 public void poundSignCommentsAreIgnored() { 168 assertThat(configFileProfiles("# Comment\n" + 169 "[profile foo] # Comment\n" + 170 "name = value # Comment with # sign")) 171 .isEqualTo(profiles(profile("foo", property("name", "value")))); 172 } 173 174 @Test semicolonCommentsAreIgnored()175 public void semicolonCommentsAreIgnored() { 176 assertThat(configFileProfiles("; Comment\n" + 177 "[profile foo] ; Comment\n" + 178 "name = value ; Comment with ; sign")) 179 .isEqualTo(profiles(profile("foo", property("name", "value")))); 180 } 181 182 @Test commentTypesCanBeUsedTogether()183 public void commentTypesCanBeUsedTogether() { 184 assertThat(configFileProfiles("# Comment\n" + 185 "[profile foo] ; Comment\n" + 186 "name = value # Comment with ; sign")) 187 .isEqualTo(profiles(profile("foo", property("name", "value")))); 188 } 189 190 @Test commentsCanBeEmpty()191 public void commentsCanBeEmpty() { 192 assertThat(configFileProfiles(";\n" + 193 "[profile foo];\n" + 194 "name = value ;\n")) 195 .isEqualTo(profiles(profile("foo", property("name", "value")))); 196 } 197 198 @Test commentsCanBeAdjacentToProfileNames()199 public void commentsCanBeAdjacentToProfileNames() { 200 assertThat(configFileProfiles("[profile foo]; Adjacent semicolons\n" + 201 "[profile bar]# Adjacent pound signs")) 202 .isEqualTo(profiles(profile("foo"), 203 profile("bar"))); 204 } 205 206 @Test commentsAdjacentToValuesAreIncludedInTheValue()207 public void commentsAdjacentToValuesAreIncludedInTheValue() { 208 assertThat(configFileProfiles("[profile foo]\n" + 209 "name = value; Adjacent semicolons\n" + 210 "name2 = value# Adjacent pound signs")) 211 .isEqualTo(profiles(profile("foo", 212 property("name", "value; Adjacent semicolons"), 213 property("name2", "value# Adjacent pound signs")))); 214 } 215 216 @Test propertyValuesCanBeContinuedOnTheNextLine()217 public void propertyValuesCanBeContinuedOnTheNextLine() { 218 assertThat(configFileProfiles("[profile foo]\n" + 219 "name = value\n" + 220 " -continued")) 221 .isEqualTo(profiles(profile("foo", 222 property("name", "value\n-continued")))); 223 } 224 225 @Test propertyValuesCanBeContinuedAcrossMultipleLines()226 public void propertyValuesCanBeContinuedAcrossMultipleLines() { 227 assertThat(configFileProfiles("[profile foo]\n" + 228 "name = value\n" + 229 " -continued\n" + 230 " -and-continued")) 231 .isEqualTo(profiles(profile("foo", 232 property("name", "value\n-continued\n-and-continued")))); 233 } 234 235 @Test continuationValuesIncludeSemicolonComments()236 public void continuationValuesIncludeSemicolonComments() { 237 assertThat(configFileProfiles("[profile foo]\n" + 238 "name = value\n" + 239 " -continued ; Comment")) 240 .isEqualTo(profiles(profile("foo", 241 property("name", "value\n-continued ; Comment")))); 242 } 243 244 @Test continuationsCannotBeUsedOutsideOfAProfile()245 public void continuationsCannotBeUsedOutsideOfAProfile() { 246 assertThatThrownBy(() -> configFileProfiles(" -continued")) 247 .hasMessageContaining("Expected a profile or property definition"); 248 } 249 250 @Test continuationsCannotBeUsedOutsideOfAProperty()251 public void continuationsCannotBeUsedOutsideOfAProperty() { 252 assertThatThrownBy(() -> configFileProfiles("[profile foo]\n" + 253 " -continued")) 254 .hasMessageContaining("Expected a profile or property definition"); 255 } 256 257 @Test continuationsResetWithProfileDefinition()258 public void continuationsResetWithProfileDefinition() { 259 assertThatThrownBy(() -> configFileProfiles("[profile foo]\n" + 260 "name = value\n" + 261 "[profile foo]\n" + 262 " -continued")) 263 .hasMessageContaining("Expected a profile or property definition"); 264 } 265 266 @Test duplicateProfilesInTheSameFileMergeProperties()267 public void duplicateProfilesInTheSameFileMergeProperties() { 268 assertThat(configFileProfiles("[profile foo]\n" + 269 "name = value\n" + 270 "[profile foo]\n" + 271 "name2 = value2")) 272 .isEqualTo(profiles(profile("foo", 273 property("name", "value"), 274 property("name2", "value2")))); 275 } 276 277 @Test duplicatePropertiesInAProfileUseTheLastOneDefined()278 public void duplicatePropertiesInAProfileUseTheLastOneDefined() { 279 assertThat(configFileProfiles("[profile foo]\n" + 280 "name = value\n" + 281 "name = value2")) 282 .isEqualTo(profiles(profile("foo", property("name", "value2")))); 283 } 284 285 @Test duplicatePropertiesInDuplicateProfilesUseTheLastOneDefined()286 public void duplicatePropertiesInDuplicateProfilesUseTheLastOneDefined() { 287 assertThat(configFileProfiles("[profile foo]\n" + 288 "name = value\n" + 289 "[profile foo]\n" + 290 "name = value2")) 291 .isEqualTo(profiles(profile("foo", property("name", "value2")))); 292 } 293 294 @Test defaultProfileWithProfilePrefixOverridesDefaultProfileWithoutPrefixWhenPrefixedIsFirst()295 public void defaultProfileWithProfilePrefixOverridesDefaultProfileWithoutPrefixWhenPrefixedIsFirst() { 296 assertThat(configFileProfiles("[profile default]\n" + 297 "name = value\n" + 298 "[default]\n" + 299 "name2 = value2")) 300 .isEqualTo(profiles(profile("default", property("name", "value")))); 301 } 302 303 @Test defaultProfileWithProfilePrefixOverridesDefaultProfileWithoutPrefixWhenPrefixedIsLast()304 public void defaultProfileWithProfilePrefixOverridesDefaultProfileWithoutPrefixWhenPrefixedIsLast() { 305 assertThat(configFileProfiles("[default]\n" + 306 "name2 = value2\n" + 307 "[profile default]\n" + 308 "name = value")) 309 .isEqualTo(profiles(profile("default", property("name", "value")))); 310 } 311 312 @Test invalidProfilesNamesAreIgnored()313 public void invalidProfilesNamesAreIgnored() { 314 assertThat(aggregateFileProfiles("[profile in valid]\n" + 315 "name = value\n", 316 "[in valid 2]\n" + 317 "name2 = value2")) 318 .isEqualTo(profiles()); 319 } 320 321 @Test invalidPropertyNamesAreIgnored()322 public void invalidPropertyNamesAreIgnored() { 323 assertThat(configFileProfiles("[profile foo]\n" + 324 "in valid = value")) 325 .isEqualTo(profiles(profile("foo"))); 326 } 327 328 @Test allValidProfileNameCharactersAreSupported()329 public void allValidProfileNameCharactersAreSupported() { 330 assertThat(configFileProfiles("[profile ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_./%@:+]")) 331 .isEqualTo(profiles(profile("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_./%@:+"))); 332 } 333 334 @Test allValidPropertyNameCharactersAreSupported()335 public void allValidPropertyNameCharactersAreSupported() { 336 assertThat(configFileProfiles("[profile foo]\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_./%@:+ = value")) 337 .isEqualTo(profiles(profile("foo", property("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_./%@:+", 338 "value")))); 339 } 340 341 @Test propertiesCanHaveSubProperties()342 public void propertiesCanHaveSubProperties() { 343 assertThat(configFileProfiles("[profile foo]\n" + 344 "s3 =\n" + 345 " name = value")) 346 .isEqualTo(profiles(profile("foo", property("s3", "\nname = value")))); 347 } 348 349 @Test invalidSubPropertiesCauseAnError()350 public void invalidSubPropertiesCauseAnError() { 351 assertThatThrownBy(() -> configFileProfiles("[profile foo]\n" + 352 "s3 =\n" + 353 " invalid")) 354 .hasMessageContaining("Expected an '=' sign defining a property"); 355 } 356 357 @Test subPropertiesCanHaveEmptyValues()358 public void subPropertiesCanHaveEmptyValues() { 359 assertThat(configFileProfiles("[profile foo]\n" + 360 "s3 =\n" + 361 " name =")) 362 .isEqualTo(profiles(profile("foo", property("s3", "\nname =")))); 363 } 364 365 @Test invalidSubPropertiesCannotHaveEmptyNames()366 public void invalidSubPropertiesCannotHaveEmptyNames() { 367 assertThatThrownBy(() -> configFileProfiles("[profile foo]\n" + 368 "s3 =\n" + 369 " = value")) 370 .hasMessageContaining("Property did not have a name"); 371 } 372 373 @Test subPropertiesCanHaveInvalidNames()374 public void subPropertiesCanHaveInvalidNames() { 375 assertThat(configFileProfiles("[profile foo]\n" + 376 "s3 =\n" + 377 " in valid = value")) 378 .isEqualTo(profiles(profile("foo", property("s3", "\nin valid = value")))); 379 } 380 381 @Test subPropertiesCanHaveBlankLines()382 public void subPropertiesCanHaveBlankLines() { 383 assertThat(configFileProfiles("[profile foo]\n" + 384 "s3 =\n" + 385 " name = value\n" + 386 "\t \n" + 387 " name2 = value2")) 388 .isEqualTo(profiles(profile("foo", property("s3", "\nname = value\nname2 = value2")))); 389 } 390 391 @Test profilesDuplicatedInMultipleFilesAreMerged()392 public void profilesDuplicatedInMultipleFilesAreMerged() { 393 assertThat(aggregateFileProfiles("[profile foo]\n" + 394 "name = value\n", 395 "[foo]\n" + 396 "name2 = value2")) 397 .isEqualTo(profiles(profile("foo", 398 property("name", "value"), 399 property("name2", "value2")))); 400 } 401 402 @Test defaultProfilesWithMixedPrefixesInConfigFileIgnoreOneWithoutPrefixWhenMerging()403 public void defaultProfilesWithMixedPrefixesInConfigFileIgnoreOneWithoutPrefixWhenMerging() { 404 assertThat(configFileProfiles("[profile default]\n" + 405 "name = value\n" + 406 "[default]\n" + 407 "name2 = value2\n" + 408 "[profile default]\n" + 409 "name3 = value3")) 410 .isEqualTo(profiles(profile("default", 411 property("name", "value"), 412 property("name3", "value3")))); 413 } 414 415 @Test duplicatePropertiesBetweenFilesUsesCredentialsProperty()416 public void duplicatePropertiesBetweenFilesUsesCredentialsProperty() { 417 assertThat(aggregateFileProfiles("[profile foo]\n" + 418 "name = value", 419 "[foo]\n" + 420 "name = value2")) 421 .isEqualTo(profiles(profile("foo", property("name", "value2")))); 422 } 423 424 @Test configProfilesWithoutPrefixAreIgnored()425 public void configProfilesWithoutPrefixAreIgnored() { 426 assertThat(configFileProfiles("[foo]\n" + 427 "name = value")) 428 .isEqualTo(profiles()); 429 } 430 431 @Test credentialsProfilesWithPrefixAreIgnored()432 public void credentialsProfilesWithPrefixAreIgnored() { 433 assertThat(credentialFileProfiles("[profile foo]\n" + 434 "name = value")) 435 .isEqualTo(profiles()); 436 } 437 438 @Test sectionsInCredentialsFilesIsIgnored()439 public void sectionsInCredentialsFilesIsIgnored() { 440 441 String ASSUME_ROLE_PROFILE = 442 "[test]\n" 443 + "region = us-west-1\n" 444 + "credential_source = Environment\n" 445 + "sso_session = session\n" 446 + "role_arn = some_Arn\n" 447 + "[sso-session session]\n" 448 + "sso_region = us-west-1\n" 449 + "start_url = someUrl\n"; 450 451 ProfileFile profileFile = credentialFile(ASSUME_ROLE_PROFILE); 452 Map<String, Profile> profileMap = profileFile.profiles(); 453 assertThat(profileMap) 454 .isEqualTo(profiles(profile("test", property("region", "us-west-1") 455 , property("credential_source", "Environment") 456 , property("sso_session", "session"), 457 property("role_arn", "some_Arn")))); 458 459 ; 460 assertThat(profileFile.getSection("sso-session", "session")).isNotPresent(); 461 } 462 463 @Test invalidSectionNamesAreNotAddedInSectionListOfProfileFiles()464 public void invalidSectionNamesAreNotAddedInSectionListOfProfileFiles() { 465 466 ProfileFile aggregatedProfileFiles = ProfileFile.aggregator() 467 .addFile(credentialFile("[in valid 2]\n" 468 + "name2 = value2")) 469 .addFile(configFile("[profile validSection]\n" 470 + "sso_session = validSso\n" 471 + "[sso-session validSso]\n" 472 + "start_url = Valid-url\n")) 473 .addFile(configFile("[profile section]\n" 474 + "sso_session = sso invalid\n" 475 + "[sso-session sso invalid]\n" 476 + "start_url = url\n")) 477 .build(); 478 479 assertThat(aggregatedProfileFiles.profiles()) 480 .isEqualTo(profiles(profile("section", property("sso_session", "sso invalid")), 481 profile("validSection", property("sso_session", "validSso")))); 482 483 assertThat(aggregatedProfileFiles.getSection("sso-session", "sso")).isNotPresent(); 484 assertThat(aggregatedProfileFiles.getSection("sso-session", "sso invalid")).isNotPresent(); 485 assertThat(aggregatedProfileFiles.getSection("sso-session", "validSso").get()) 486 .isEqualTo(profile("validSso", property("start_url", "Valid-url"))); 487 } 488 489 @Test defaultSessionNameIsNotSupported_when_session_doesNot_exist()490 public void defaultSessionNameIsNotSupported_when_session_doesNot_exist() { 491 492 String nonExistentSessionName = "nonExistentSession"; 493 ProfileFile aggregatedProfileFiles = ProfileFile.aggregator() 494 .addFile(configFile("[profile validSection]\n" 495 + "sso_session = " + nonExistentSessionName + "\n" 496 + "[profile " + nonExistentSessionName + "]\n" 497 + "start_url = Valid-url-2\n" 498 + "[sso-session default]\n" 499 + "start_url = Valid-url\n")) 500 .build(); 501 502 assertThat(aggregatedProfileFiles.profiles()) 503 .isEqualTo(profiles(profile("validSection", property("sso_session", nonExistentSessionName)), 504 profile(nonExistentSessionName, property("start_url", "Valid-url-2")))); 505 506 assertThat(aggregatedProfileFiles.getSection("sso-session", nonExistentSessionName)).isNotPresent(); 507 } 508 509 @Test sessionIsNotAdjacentToProfile()510 public void sessionIsNotAdjacentToProfile() { 511 512 ProfileFile aggregatedProfileFiles = ProfileFile.aggregator() 513 .addFile(configFile("[profile profile1]\n" 514 + "sso_session = sso-token1\n" 515 + "[profile profile2]\n" 516 + "region = us-west-2\n" 517 + "[default]\n" 518 + "default_property = property1\n")) 519 .addFile(configFile("[sso-session sso-token1]\n" 520 + "start_url = startUrl1\n" 521 + "[profile profile3]\n" 522 + "region = us-east-1\n") 523 ).build(); 524 525 assertThat(aggregatedProfileFiles.profiles()) 526 .isEqualTo(profiles(profile("profile1", property("sso_session", "sso-token1")), 527 profile("default", property("default_property", "property1")), 528 profile("profile2", property("region", "us-west-2")), 529 profile("profile3", property("region", "us-east-1")) 530 531 )); 532 533 assertThat(aggregatedProfileFiles.getSection("sso-session", "sso-token1")).isPresent(); 534 assertThat(aggregatedProfileFiles.getSection("sso-session", "sso-token1").get()).isEqualTo( 535 profile("sso-token1", property("start_url", "startUrl1")) ); 536 } 537 538 @Test exceptionIsThrown_when_sectionDoesnotHaveASquareBracket()539 public void exceptionIsThrown_when_sectionDoesnotHaveASquareBracket() { 540 541 542 assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy( 543 () -> ProfileFile.aggregator() 544 .addFile(configFile("[profile profile1]\n" 545 + "sso_session = sso-token1\n" 546 + "[sso-session sso-token1\n" 547 + "start_url = startUrl1\n") 548 ).build()).withMessageContaining("Section definition must end with ']' on line 3"); 549 550 } 551 552 @Test loadingDefaultProfileFileWorks()553 public void loadingDefaultProfileFileWorks() { 554 ProfileFile.defaultProfileFile(); 555 } 556 557 @Test returnsEmptyMap_when_AwsFilesDoNotExist()558 public void returnsEmptyMap_when_AwsFilesDoNotExist() { 559 ProfileFile missingProfile = ProfileFile.aggregator() 560 .build(); 561 562 assertThat(missingProfile.profiles()).isEmpty(); 563 assertThat(missingProfile.profiles()).isInstanceOf(Map.class); 564 } 565 configFile(String configFile)566 private ProfileFile configFile(String configFile) { 567 return ProfileFile.builder() 568 .content(new StringInputStream(configFile)) 569 .type(ProfileFile.Type.CONFIGURATION) 570 .build(); 571 } 572 configFileProfiles(String configFile)573 private Map<String, Profile> configFileProfiles(String configFile) { 574 return configFile(configFile).profiles(); 575 } 576 credentialFile(String credentialFile)577 private ProfileFile credentialFile(String credentialFile) { 578 return ProfileFile.builder() 579 .content(new StringInputStream(credentialFile)) 580 .type(ProfileFile.Type.CREDENTIALS) 581 .build(); 582 } 583 credentialFileProfiles(String credentialFile)584 private Map<String, Profile> credentialFileProfiles(String credentialFile) { 585 return credentialFile(credentialFile).profiles(); 586 } 587 aggregateFileProfiles(String configFile, String credentialFile)588 private Map<String, Profile> aggregateFileProfiles(String configFile, String credentialFile) { 589 return ProfileFile.aggregator() 590 .addFile(credentialFile(credentialFile)) 591 .addFile(configFile(configFile)) 592 .build() 593 .profiles(); 594 } 595 profiles(Profile... profiles)596 private Map<String, Profile> profiles(Profile... profiles) { 597 Map<String, Profile> result = new HashMap<>(); 598 Stream.of(profiles).forEach(p -> result.put(p.name(), p)); 599 return result; 600 } 601 602 @SafeVarargs profile(String name, Map.Entry<String, String>... properties)603 private final Profile profile(String name, Map.Entry<String, String>... properties) { 604 Map<String, String> propertiesMap = new HashMap<>(); 605 Stream.of(properties).forEach(p -> propertiesMap.put(p.getKey(), p.getValue())); 606 return Profile.builder().name(name).properties(propertiesMap).build(); 607 } 608 property(String name, String value)609 private Map.Entry<String, String> property(String name, String value) { 610 return new AbstractMap.SimpleImmutableEntry<>(name, value); 611 } 612 } 613