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 AwsV4HttpSigner signer ;
65+
66+ @ BeforeEach
67+ public void setup () {
68+ signer = Mockito .mock (AwsV4HttpSigner .class );
69+ }
70+
4471 @ Test
45- public void profileIsHonoredForCredentialsAndRegion () {
72+ public void legacySigner_profileIsHonoredForCredentialsAndRegion () {
4673 EnvironmentVariableHelper .run (env -> {
4774 env .remove (SdkSystemSetting .AWS_REGION );
4875 env .remove (SdkSystemSetting .AWS_ACCESS_KEY_ID );
4976 env .remove (SdkSystemSetting .AWS_SECRET_ACCESS_KEY );
5077
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" ;
5678 Signer signer = mock (Signer .class );
5779
5880 ProtocolRestJsonClient client =
5981 ProtocolRestJsonClient .builder ()
60- .overrideConfiguration (overrideConfig (profileContent , profileName , signer ))
82+ .overrideConfiguration (overrideConfig (PROFILE_CONTENT , PROFILE_NAME , signer ))
6183 .build ();
6284
63- Mockito .when (signer .sign (any (), any ())).thenReturn (SdkHttpFullRequest .builder ()
64- .protocol ("https" )
65- .host ("test" )
66- .method (SdkHttpMethod .GET )
67- .build ());
85+ Mockito .when (signer .sign (any (), any ())).thenReturn (signedSdkHttpRequest ());
6886
6987 try {
7088 client .allTypes ();
@@ -87,7 +105,7 @@ public void profileIsHonoredForCredentialsAndRegion() {
87105 });
88106 }
89107
90- private ClientOverrideConfiguration overrideConfig (String profileContent , String profileName , Signer signer ) {
108+ private static ClientOverrideConfiguration overrideConfig (String profileContent , String profileName , Signer signer ) {
91109 return ClientOverrideConfiguration .builder ()
92110 .defaultProfileFile (profileFile (profileContent ))
93111 .defaultProfileName (profileName )
@@ -96,14 +114,172 @@ private ClientOverrideConfiguration overrideConfig(String profileContent, String
96114 .build ();
97115 }
98116
99- private ProfileFile profileFile (String content ) {
117+ private static ProfileFile profileFile (String content ) {
100118 return ProfileFile .builder ()
101119 .content (new StringInputStream (content ))
102120 .type (ProfileFile .Type .CONFIGURATION )
103121 .build ();
104122 }
105123
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
124+ @ Test
125+ public void nonStreaming_syncHttpSigner_profileIsHonoredForCredentialsAndRegion () {
126+ EnvironmentVariableHelper .run (env -> {
127+ env .remove (SdkSystemSetting .AWS_REGION );
128+ env .remove (SdkSystemSetting .AWS_ACCESS_KEY_ID );
129+ env .remove (SdkSystemSetting .AWS_SECRET_ACCESS_KEY );
130+
131+ ProtocolRestJsonClient client = clientWithHttpSignerOverride ();
132+
133+ SignedRequest signedRequest = SignedRequest .builder ().request (signedSdkHttpRequest ()).build ();
134+ Mockito .when (signer .sign (any (SignRequest .class ))).thenReturn (signedRequest );
135+
136+ try {
137+ client .allTypes ();
138+ } catch (Exception e ) {
139+ // expected
140+ }
141+
142+ verifySignerProperty (signer );
143+
144+ });
145+ }
146+
147+ @ Test
148+ public void streaming_syncHttpSigner_profileIsHonoredForCredentialsAndRegion () {
149+ EnvironmentVariableHelper .run (env -> {
150+ env .remove (SdkSystemSetting .AWS_REGION );
151+ env .remove (SdkSystemSetting .AWS_ACCESS_KEY_ID );
152+ env .remove (SdkSystemSetting .AWS_SECRET_ACCESS_KEY );
153+
154+ ProtocolRestJsonClient client = clientWithHttpSignerOverride ();
155+
156+ SignedRequest signedRequest = SignedRequest .builder ().request (signedSdkHttpRequest ()).build ();
157+ Mockito .when (signer .sign (any (SignRequest .class ))).thenReturn (signedRequest );
158+
159+ try {
160+ client .streamingInputOperation (StreamingInputOperationRequest .builder ().build (), RequestBody .fromString (
161+ "helloworld" ));
162+ } catch (SdkClientException e ) {
163+ // expected
164+ }
165+
166+ verifySignerProperty (signer );
167+ });
168+ }
169+
170+ @ Test
171+ public void nonStreaming_asyncHttpSigner_profileIsHonoredForCredentialsAndRegion () {
172+ EnvironmentVariableHelper .run (env -> {
173+ env .remove (SdkSystemSetting .AWS_REGION );
174+ env .remove (SdkSystemSetting .AWS_ACCESS_KEY_ID );
175+ env .remove (SdkSystemSetting .AWS_SECRET_ACCESS_KEY );
176+
177+ ProtocolRestJsonAsyncClient asyncClient = asyncClientWithHttpSignerOverride ();
178+
179+ SignedRequest signedRequest = SignedRequest .builder ().request (signedSdkHttpRequest ()).build ();
180+ Mockito .when (signer .sign (any (SignRequest .class ))).thenReturn (signedRequest );
181+
182+ try {
183+ asyncClient .allTypes ().join ();
184+ } catch (Exception e ) {
185+ // expected
186+ }
187+
188+ verifySignerProperty (signer );
189+
190+ });
191+ }
192+
193+ @ Test
194+ public void streamingOperation_asyncHttpSigner_profileIsHonoredForCredentialsAndRegion () {
195+ EnvironmentVariableHelper .run (env -> {
196+ env .remove (SdkSystemSetting .AWS_REGION );
197+ env .remove (SdkSystemSetting .AWS_ACCESS_KEY_ID );
198+ env .remove (SdkSystemSetting .AWS_SECRET_ACCESS_KEY );
199+
200+ Mockito .when (signer .signAsync (any (AsyncSignRequest .class ))).thenReturn (CompletableFuture .completedFuture (any (AsyncSignRequest .class )));
201+
202+ ProtocolRestJsonAsyncClient asyncClient = asyncClientWithHttpSignerOverride ();
203+
204+ try {
205+ asyncClient .streamingInputOperation (StreamingInputOperationRequest .builder ().build (), AsyncRequestBody .fromString (
206+ "helloworld" )).join ();
207+ } catch (Exception e ) {
208+ // expected
209+ }
210+
211+ ArgumentCaptor <AsyncSignRequest > signRequest = ArgumentCaptor .forClass (AsyncSignRequest .class );
212+ Mockito .verify (signer ).signAsync (signRequest .capture ());
213+
214+ AsyncSignRequest actualSignRequest = signRequest .getValue ();
215+
216+ String regionName = (String ) actualSignRequest .property (REGION_NAME );
217+ assertThat (regionName ).isEqualTo ("us-banana-46" );
218+
219+ assertThat (actualSignRequest .identity ()).isInstanceOf (AwsCredentials .class );
220+ AwsCredentials credentials = (AwsCredentials ) actualSignRequest .identity ();
221+ assertThat (credentials .accessKeyId ()).isEqualTo ("profileIsHonoredForCredentials_akid" );
222+ assertThat (credentials .secretAccessKey ()).isEqualTo ("profileIsHonoredForCredentials_skid" );
223+
224+ });
225+ }
226+
227+ private ProtocolRestJsonAsyncClient asyncClientWithHttpSignerOverride () {
228+ return ProtocolRestJsonAsyncClient .builder ()
229+ .overrideConfiguration (overrideConfig (PROFILE_CONTENT , PROFILE_NAME , null ))
230+ .putAuthScheme (new MockAuthScheme (signer )).build ();
231+ }
232+
233+ private ProtocolRestJsonClient clientWithHttpSignerOverride () {
234+ return ProtocolRestJsonClient .builder ()
235+ .overrideConfiguration (overrideConfig (PROFILE_CONTENT , PROFILE_NAME , null ))
236+ .putAuthScheme (new MockAuthScheme (signer )).build ();
237+ }
238+
239+ private static void verifySignerProperty (AwsV4HttpSigner signer ) {
240+ ArgumentCaptor <SignRequest > signRequest = ArgumentCaptor .forClass (SignRequest .class );
241+ Mockito .verify (signer ).sign (signRequest .capture ());
242+
243+ SignRequest actualSignRequest = signRequest .getValue ();
244+
245+ String regionName = (String ) actualSignRequest .property (REGION_NAME );
246+ assertThat (regionName ).isEqualTo ("us-banana-46" );
247+
248+ assertThat (actualSignRequest .identity ()).isInstanceOf (AwsCredentials .class );
249+ AwsCredentials credentials = (AwsCredentials ) actualSignRequest .identity ();
250+ assertThat (credentials .accessKeyId ()).isEqualTo ("profileIsHonoredForCredentials_akid" );
251+ assertThat (credentials .secretAccessKey ()).isEqualTo ("profileIsHonoredForCredentials_skid" );
252+ }
253+
254+ private static SdkHttpFullRequest signedSdkHttpRequest () {
255+ return SdkHttpFullRequest .builder ()
256+ .protocol ("https" )
257+ .host ("test" )
258+ .method (SdkHttpMethod .GET )
259+ .build ();
260+ }
261+
262+ private static class MockAuthScheme implements AwsV4AuthScheme {
263+ private final AwsV4HttpSigner signer ;
264+
265+ public MockAuthScheme (AwsV4HttpSigner signer ) {
266+ this .signer = signer ;
267+ }
268+
269+ @ Override
270+ public IdentityProvider <AwsCredentialsIdentity > identityProvider (IdentityProviders providers ) {
271+ return providers .identityProvider (AwsCredentialsIdentity .class );
272+ }
273+
274+ @ Override
275+ public AwsV4HttpSigner signer () {
276+ return signer ;
277+ }
278+
279+ @ Override
280+ public String schemeId () {
281+ return SCHEME_ID ;
282+ }
283+ }
284+
109285}
0 commit comments