-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ALS-6074] Fix uploader auth timeouts for instance profile
- Refresh auth when rebuilding client
- Loading branch information
1 parent
0c0653f
commit 8718216
Showing
5 changed files
with
150 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
uploader/src/main/java/edu/harvard/dbmi/avillach/dataupload/aws/AWSCredentialsService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package edu.harvard.dbmi.avillach.dataupload.aws; | ||
|
||
import org.apache.logging.log4j.util.Strings; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.context.ConfigurableApplicationContext; | ||
import org.springframework.stereotype.Service; | ||
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; | ||
import software.amazon.awssdk.auth.credentials.AwsCredentials; | ||
import software.amazon.awssdk.auth.credentials.AwsSessionCredentials; | ||
import software.amazon.awssdk.auth.credentials.InstanceProfileCredentialsProvider; | ||
|
||
@Service | ||
public class AWSCredentialsService { | ||
|
||
private static final Logger LOG = LoggerFactory.getLogger(AWSCredentialsService.class); | ||
|
||
private final String authMethod; | ||
private final String secret; | ||
private final String key; | ||
private final String token; | ||
private final ConfigurableApplicationContext context; | ||
|
||
|
||
private AwsCredentials credentials; | ||
|
||
@Autowired | ||
public AWSCredentialsService( | ||
@Value("${aws.authentication.method:}") String authMethod, | ||
@Value("${aws.s3.access_key_secret:}") String secret, | ||
@Value("${aws.s3.access_key_id:}") String key, | ||
@Value("${aws.s3.session_token:}") String token, | ||
ConfigurableApplicationContext context | ||
) { | ||
this.authMethod = authMethod; | ||
this.secret = secret; | ||
this.key = key; | ||
this.token = token; | ||
this.context = context; | ||
} | ||
|
||
public AwsCredentials constructCredentials() { | ||
//noinspection SwitchStatementWithTooFewBranches | ||
return switch (authMethod) { | ||
case "instance-profile" -> createInstanceProfileBasedCredentials(); | ||
default -> createUserBasedCredentials(); | ||
}; | ||
} | ||
|
||
private AwsCredentials createUserBasedCredentials() { | ||
LOG.info("Authentication method is user. Attempting to resolve user credentials."); | ||
if (Strings.isBlank(key)) { | ||
LOG.error("No AWS key. Can't create client. Exiting"); | ||
context.close(); | ||
} | ||
if (Strings.isBlank(secret)) { | ||
LOG.error("No AWS secret. Can't create client. Exiting"); | ||
context.close(); | ||
} | ||
if (Strings.isBlank(token)) { | ||
return AwsBasicCredentials.create(key, secret); | ||
} else { | ||
return AwsSessionCredentials.create(key, secret, token); | ||
} | ||
} | ||
|
||
private AwsCredentials createInstanceProfileBasedCredentials() { | ||
LOG.info("Authentication method is instance-profile. Attempting to resolve instance profile credentials."); | ||
return InstanceProfileCredentialsProvider.create().resolveCredentials(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
...der/src/test/java/edu/harvard/dbmi/avillach/dataupload/aws/AWSCredentialsServiceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package edu.harvard.dbmi.avillach.dataupload.aws; | ||
|
||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.Test; | ||
import org.mockito.InjectMocks; | ||
import org.mockito.Mock; | ||
import org.mockito.Mockito; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import org.springframework.boot.test.mock.mockito.MockBean; | ||
import org.springframework.context.ConfigurableApplicationContext; | ||
import org.springframework.test.util.ReflectionTestUtils; | ||
import software.amazon.awssdk.auth.credentials.AwsCredentials; | ||
import software.amazon.awssdk.auth.credentials.AwsSessionCredentials; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
|
||
@SpringBootTest | ||
class AWSCredentialsServiceTest { | ||
|
||
@Mock | ||
ConfigurableApplicationContext context; | ||
|
||
@InjectMocks | ||
AWSCredentialsService subject; | ||
|
||
@Test | ||
void shouldCreateCredentials() { | ||
ReflectionTestUtils.setField(subject, "authMethod", "user"); | ||
ReflectionTestUtils.setField(subject, "secret", "s1"); | ||
ReflectionTestUtils.setField(subject, "key", "k1"); | ||
ReflectionTestUtils.setField(subject, "token", "t1"); | ||
|
||
AwsCredentials actual = subject.constructCredentials(); | ||
AwsSessionCredentials expected = AwsSessionCredentials.create("k1", "s1", "t1"); | ||
|
||
Assertions.assertEquals(expected, actual); | ||
} | ||
|
||
@Test | ||
void shouldNotCreateCredentials() { | ||
ReflectionTestUtils.setField(subject, "authMethod", "user"); | ||
ReflectionTestUtils.setField(subject, "secret", ""); | ||
ReflectionTestUtils.setField(subject, "key", "k1"); | ||
ReflectionTestUtils.setField(subject, "token", "t1"); | ||
|
||
subject.constructCredentials(); | ||
|
||
Mockito.verify(context, Mockito.times(1)).close(); | ||
} | ||
} |