1818import static org .assertj .core .api .Assertions .assertThat ;
1919import static org .mockito .ArgumentMatchers .any ;
2020import static org .mockito .Mockito .mock ;
21+ import static software .amazon .awssdk .http .auth .aws .signer .AwsV4HttpSigner .REGION_NAME ;
2122
23+ import java .util .concurrent .CompletableFuture ;
24+ import org .junit .jupiter .api .BeforeEach ;
2225import org .junit .jupiter .api .Test ;
2326import org .mockito .ArgumentCaptor ;
2427import org .mockito .Mockito ;
2528import software .amazon .awssdk .auth .credentials .AwsCredentials ;
2629import software .amazon .awssdk .auth .signer .AwsSignerExecutionAttribute ;
2730import software .amazon .awssdk .awscore .AwsExecutionAttribute ;
2831import software .amazon .awssdk .core .SdkSystemSetting ;
32+ import software .amazon .awssdk .core .async .AsyncRequestBody ;
2933import software .amazon .awssdk .core .client .config .ClientOverrideConfiguration ;
3034import software .amazon .awssdk .core .client .config .SdkAdvancedClientOption ;
3135import software .amazon .awssdk .core .exception .SdkClientException ;
3236import software .amazon .awssdk .core .interceptor .ExecutionAttributes ;
3337import software .amazon .awssdk .core .signer .Signer ;
38+ import software .amazon .awssdk .core .sync .RequestBody ;
3439import software .amazon .awssdk .http .SdkHttpFullRequest ;
3540import software .amazon .awssdk .http .SdkHttpMethod ;
41+ import software .amazon .awssdk .http .auth .aws .scheme .AwsV4AuthScheme ;
42+ import software .amazon .awssdk .http .auth .aws .signer .AwsV4HttpSigner ;
43+ import software .amazon .awssdk .http .auth .spi .signer .AsyncSignRequest ;
44+ import software .amazon .awssdk .http .auth .spi .signer .SignRequest ;
45+ import software .amazon .awssdk .http .auth .spi .signer .SignedRequest ;
46+ import software .amazon .awssdk .identity .spi .AwsCredentialsIdentity ;
47+ import software .amazon .awssdk .identity .spi .IdentityProvider ;
48+ import software .amazon .awssdk .identity .spi .IdentityProviders ;
3649import software .amazon .awssdk .profiles .ProfileFile ;
3750import software .amazon .awssdk .regions .Region ;
51+ import software .amazon .awssdk .services .protocolrestjson .ProtocolRestJsonAsyncClient ;
3852import software .amazon .awssdk .services .protocolrestjson .ProtocolRestJsonClient ;
53+ import software .amazon .awssdk .services .protocolrestjson .model .StreamingInputOperationRequest ;
3954import software .amazon .awssdk .testutils .EnvironmentVariableHelper ;
4055import software .amazon .awssdk .utils .StringInputStream ;
4156
4257public class ProfileFileConfigurationTest {
4358
59+ private static final String PROFILE_CONTENT = "[profile foo]\n " +
60+ "region = us-banana-46\n " +
61+ "aws_access_key_id = profileIsHonoredForCredentials_akid\n " +
62+ "aws_secret_access_key = profileIsHonoredForCredentials_skid" ;
63+ private static final String PROFILE_NAME = "foo" ;
64+ private static ProtocolRestJsonClient client ;
65+ private ProtocolRestJsonAsyncClient asyncClient ;
66+ private AwsV4HttpSigner signer ;
67+
68+
69+ @ BeforeEach
70+ public void setup () {
71+ signer = Mockito .mock (AwsV4HttpSigner .class );
72+ client = ProtocolRestJsonClient .builder ()
73+ .overrideConfiguration (overrideConfig (PROFILE_CONTENT , PROFILE_NAME , null ))
74+ .putAuthScheme (new MockAuthScheme (signer )).build ();
75+
76+ asyncClient = ProtocolRestJsonAsyncClient .builder ()
77+ .overrideConfiguration (overrideConfig (PROFILE_CONTENT , PROFILE_NAME , null ))
78+ .putAuthScheme (new MockAuthScheme (signer )).build ();
79+ }
80+
4481 @ Test
45- public void profileIsHonoredForCredentialsAndRegion () {
82+ public void legacySigner_profileIsHonoredForCredentialsAndRegion () {
4683 EnvironmentVariableHelper .run (env -> {
4784 env .remove (SdkSystemSetting .AWS_REGION );
4885 env .remove (SdkSystemSetting .AWS_ACCESS_KEY_ID );
4986 env .remove (SdkSystemSetting .AWS_SECRET_ACCESS_KEY );
5087
51- String profileContent = "[profile foo]\n " +
52- "region = us-banana-46\n " +
53- "aws_access_key_id = profileIsHonoredForCredentials_akid\n " +
54- "aws_secret_access_key = profileIsHonoredForCredentials_skid" ;
55- String profileName = "foo" ;
5688 Signer signer = mock (Signer .class );
5789
5890 ProtocolRestJsonClient client =
5991 ProtocolRestJsonClient .builder ()
60- .overrideConfiguration (overrideConfig (profileContent , profileName , signer ))
92+ .overrideConfiguration (overrideConfig (PROFILE_CONTENT , PROFILE_NAME , signer ))
6193 .build ();
6294
63- Mockito .when (signer .sign (any (), any ())).thenReturn (SdkHttpFullRequest .builder ()
64- .protocol ("https" )
65- .host ("test" )
66- .method (SdkHttpMethod .GET )
67- .build ());
95+ Mockito .when (signer .sign (any (), any ())).thenReturn (signedSdkHttpRequest ());
6896
6997 try {
7098 client .allTypes ();
@@ -87,7 +115,7 @@ public void profileIsHonoredForCredentialsAndRegion() {
87115 });
88116 }
89117
90- private ClientOverrideConfiguration overrideConfig (String profileContent , String profileName , Signer signer ) {
118+ private static ClientOverrideConfiguration overrideConfig (String profileContent , String profileName , Signer signer ) {
91119 return ClientOverrideConfiguration .builder ()
92120 .defaultProfileFile (profileFile (profileContent ))
93121 .defaultProfileName (profileName )
@@ -96,14 +124,152 @@ private ClientOverrideConfiguration overrideConfig(String profileContent, String
96124 .build ();
97125 }
98126
99- private ProfileFile profileFile (String content ) {
127+ private static ProfileFile profileFile (String content ) {
100128 return ProfileFile .builder ()
101129 .content (new StringInputStream (content ))
102130 .type (ProfileFile .Type .CONFIGURATION )
103131 .build ();
104132 }
105133
106- // TODO(sra-identity-and-auth): Should add test for the same using SRA way, to assert the identity in SignRequest and
107- // region SignerProperty are per profile.
108- // To do this, need ability to inject AuthScheme which uses mock HttpSigner. This is pending https://i.amazon.com/SMITHY-1450
134+ @ Test
135+ public void nonStreaming_syncHttpSigner_profileIsHonoredForCredentialsAndRegion () {
136+ EnvironmentVariableHelper .run (env -> {
137+ env .remove (SdkSystemSetting .AWS_REGION );
138+ env .remove (SdkSystemSetting .AWS_ACCESS_KEY_ID );
139+ env .remove (SdkSystemSetting .AWS_SECRET_ACCESS_KEY );
140+
141+ SignedRequest signedRequest = SignedRequest .builder ().request (signedSdkHttpRequest ()).build ();
142+ Mockito .when (signer .sign (any (SignRequest .class ))).thenReturn (signedRequest );
143+
144+ try {
145+ client .allTypes ();
146+ } catch (Exception e ) {
147+ // expected
148+ }
149+
150+ verifySignerProperty (signer );
151+
152+ });
153+ }
154+
155+ @ Test
156+ public void streaming_syncHttpSigner_profileIsHonoredForCredentialsAndRegion () {
157+ EnvironmentVariableHelper .run (env -> {
158+ env .remove (SdkSystemSetting .AWS_REGION );
159+ env .remove (SdkSystemSetting .AWS_ACCESS_KEY_ID );
160+ env .remove (SdkSystemSetting .AWS_SECRET_ACCESS_KEY );
161+
162+ SignedRequest signedRequest = SignedRequest .builder ().request (signedSdkHttpRequest ()).build ();
163+ Mockito .when (signer .sign (any (SignRequest .class ))).thenReturn (signedRequest );
164+
165+ try {
166+ client .streamingInputOperation (StreamingInputOperationRequest .builder ().build (), RequestBody .fromString (
167+ "helloworld" ));
168+ } catch (SdkClientException e ) {
169+ // expected
170+ }
171+
172+ verifySignerProperty (signer );
173+ });
174+ }
175+
176+ @ Test
177+ public void nonStreaming_asyncHttpSigner_profileIsHonoredForCredentialsAndRegion () {
178+ EnvironmentVariableHelper .run (env -> {
179+ env .remove (SdkSystemSetting .AWS_REGION );
180+ env .remove (SdkSystemSetting .AWS_ACCESS_KEY_ID );
181+ env .remove (SdkSystemSetting .AWS_SECRET_ACCESS_KEY );
182+
183+ SignedRequest signedRequest = SignedRequest .builder ().request (signedSdkHttpRequest ()).build ();
184+ Mockito .when (signer .sign (any (SignRequest .class ))).thenReturn (signedRequest );
185+
186+ try {
187+ asyncClient .allTypes ().join ();
188+ } catch (Exception e ) {
189+ // expected
190+ }
191+
192+ verifySignerProperty (signer );
193+
194+ });
195+ }
196+
197+ @ Test
198+ public void streamingOperation_asyncHttpSigner_profileIsHonoredForCredentialsAndRegion () {
199+ EnvironmentVariableHelper .run (env -> {
200+ env .remove (SdkSystemSetting .AWS_REGION );
201+ env .remove (SdkSystemSetting .AWS_ACCESS_KEY_ID );
202+ env .remove (SdkSystemSetting .AWS_SECRET_ACCESS_KEY );
203+
204+ Mockito .when (signer .signAsync (any (AsyncSignRequest .class ))).thenReturn (CompletableFuture .completedFuture (any (AsyncSignRequest .class )));
205+
206+ try {
207+ asyncClient .streamingInputOperation (StreamingInputOperationRequest .builder ().build (), AsyncRequestBody .fromString (
208+ "helloworld" )).join ();
209+ } catch (Exception e ) {
210+ // expected
211+ }
212+
213+ ArgumentCaptor <AsyncSignRequest > signRequest = ArgumentCaptor .forClass (AsyncSignRequest .class );
214+ Mockito .verify (signer ).signAsync (signRequest .capture ());
215+
216+ AsyncSignRequest actualSignRequest = signRequest .getValue ();
217+
218+ String regionName = (String ) actualSignRequest .property (REGION_NAME );
219+ assertThat (regionName ).isEqualTo ("us-banana-46" );
220+
221+ assertThat (actualSignRequest .identity ()).isInstanceOf (AwsCredentials .class );
222+ AwsCredentials credentials = (AwsCredentials ) actualSignRequest .identity ();
223+ assertThat (credentials .accessKeyId ()).isEqualTo ("profileIsHonoredForCredentials_akid" );
224+ assertThat (credentials .secretAccessKey ()).isEqualTo ("profileIsHonoredForCredentials_skid" );
225+
226+ });
227+ }
228+
229+ private static void verifySignerProperty (AwsV4HttpSigner signer ) {
230+ ArgumentCaptor <SignRequest > signRequest = ArgumentCaptor .forClass (SignRequest .class );
231+ Mockito .verify (signer ).sign (signRequest .capture ());
232+
233+ SignRequest actualSignRequest = signRequest .getValue ();
234+
235+ String regionName = (String ) actualSignRequest .property (REGION_NAME );
236+ assertThat (regionName ).isEqualTo ("us-banana-46" );
237+
238+ assertThat (actualSignRequest .identity ()).isInstanceOf (AwsCredentials .class );
239+ AwsCredentials credentials = (AwsCredentials ) actualSignRequest .identity ();
240+ assertThat (credentials .accessKeyId ()).isEqualTo ("profileIsHonoredForCredentials_akid" );
241+ assertThat (credentials .secretAccessKey ()).isEqualTo ("profileIsHonoredForCredentials_skid" );
242+ }
243+
244+ private static SdkHttpFullRequest signedSdkHttpRequest () {
245+ return SdkHttpFullRequest .builder ()
246+ .protocol ("https" )
247+ .host ("test" )
248+ .method (SdkHttpMethod .GET )
249+ .build ();
250+ }
251+
252+ private static class MockAuthScheme implements AwsV4AuthScheme {
253+ private final AwsV4HttpSigner signer ;
254+
255+ public MockAuthScheme (AwsV4HttpSigner signer ) {
256+ this .signer = signer ;
257+ }
258+
259+ @ Override
260+ public IdentityProvider <AwsCredentialsIdentity > identityProvider (IdentityProviders providers ) {
261+ return providers .identityProvider (AwsCredentialsIdentity .class );
262+ }
263+
264+ @ Override
265+ public AwsV4HttpSigner signer () {
266+ return signer ;
267+ }
268+
269+ @ Override
270+ public String schemeId () {
271+ return SCHEME_ID ;
272+ }
273+ }
274+
109275}
0 commit comments