diff --git a/libs/schema-validation/src/main/kotlin/gov/cdc/ocio/reportschemavalidator/health/schemaLoadersystem/HealthCheckS3Bucket.kt b/libs/schema-validation/src/main/kotlin/gov/cdc/ocio/reportschemavalidator/health/schemaLoadersystem/HealthCheckS3Bucket.kt index 61644568..eb734b72 100644 --- a/libs/schema-validation/src/main/kotlin/gov/cdc/ocio/reportschemavalidator/health/schemaLoadersystem/HealthCheckS3Bucket.kt +++ b/libs/schema-validation/src/main/kotlin/gov/cdc/ocio/reportschemavalidator/health/schemaLoadersystem/HealthCheckS3Bucket.kt @@ -1,33 +1,29 @@ package gov.cdc.ocio.reportschemavalidator.health.schemaLoadersystem -import com.fasterxml.jackson.annotation.JsonIgnoreProperties -import gov.cdc.ocio.reportschemavalidator.utils.AWSS3Configuration import gov.cdc.ocio.types.health.HealthCheckResult import gov.cdc.ocio.types.health.HealthCheckSystem import gov.cdc.ocio.types.health.HealthStatusType -import org.koin.core.component.KoinComponent -import org.koin.core.component.inject import software.amazon.awssdk.services.s3.S3Client -import software.amazon.awssdk.services.s3.model.ListObjectsV2Request +import software.amazon.awssdk.services.s3.model.ListBucketsRequest /** * Concrete implementation of the S3 Bucket health checks. */ -@JsonIgnoreProperties("koin") -class HealthCheckS3Bucket(private val s3Client: S3Client) : HealthCheckSystem("s3"), KoinComponent { - - private val awsServiceConfiguration by inject() +class HealthCheckS3Bucket( + private val getS3ClientFunc: () -> S3Client, + private val s3Bucket: String, +) : HealthCheckSystem("s3") { /** * Checks and sets S3 Bucket accessible status * @return HealthCheckResult */ override fun doHealthCheck(): HealthCheckResult { - val result = isS3FolderHealthy(awsServiceConfiguration) + val result = isS3FolderHealthy() result.onFailure { error -> - val reason = "S3 bucket is not accessible and hence not healthy ${error.localizedMessage}" + val reason = "S3 bucket is not accessible and hence not healthy: ${error.localizedMessage}" logger.error(reason) return HealthCheckResult(service, HealthStatusType.STATUS_DOWN, reason) } @@ -37,22 +33,21 @@ class HealthCheckS3Bucket(private val s3Client: S3Client) : HealthCheckSystem("s /** * Check whether S3 Buket is accessible * - * @param config AWSS3Configuration * @return Result */ - private fun isS3FolderHealthy(config: AWSS3Configuration): Result { + private fun isS3FolderHealthy(): Result { return try { - val request = ListObjectsV2Request.builder() - .bucket(config.s3Bucket) - .maxKeys(1) // one file - lightweight check + val s3Client = getS3ClientFunc() + val request = ListBucketsRequest.builder() .build() - val response = s3Client.listObjectsV2(request) - if (response.contents().isNotEmpty()) + val response = s3Client.listBuckets(request) + s3Client.close() + if (response.buckets().any { it.name() == s3Bucket }) Result.success(true) else - Result.failure(Exception("Established connection to S3 bucket, but failed list objects check.")) + Result.failure(Exception("Established connection to S3, but failed to verify the expected bucket exists.")) } catch (e: Exception) { - throw Exception("Failed to establish connection to S3 bucket.") + Result.failure(Exception("Failed to establish connection to S3 bucket: ${e.localizedMessage}")) } } } diff --git a/libs/schema-validation/src/main/kotlin/gov/cdc/ocio/reportschemavalidator/schema/S3SchemaStorageClient.kt b/libs/schema-validation/src/main/kotlin/gov/cdc/ocio/reportschemavalidator/schema/S3SchemaStorageClient.kt index 3cf35c62..5215bbc1 100644 --- a/libs/schema-validation/src/main/kotlin/gov/cdc/ocio/reportschemavalidator/schema/S3SchemaStorageClient.kt +++ b/libs/schema-validation/src/main/kotlin/gov/cdc/ocio/reportschemavalidator/schema/S3SchemaStorageClient.kt @@ -30,8 +30,9 @@ class S3SchemaStorageClient( */ private fun getS3Client(): S3Client { - val credentialsProvider = if (roleArn.isNullOrEmpty() || - webIdentityTokenFile.isNullOrEmpty()) { + val credentialsProvider = if (roleArn.isNullOrEmpty() || + webIdentityTokenFile.isNullOrEmpty() + ) { // Fallback to default credentials provider (access key and secret) DefaultCredentialsProvider.create() } else { @@ -41,6 +42,7 @@ class S3SchemaStorageClient( .webIdentityTokenFile(webIdentityTokenFile.let { Path.of(it) }) .build() } + // Load credentials from the AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN environment variables. return S3Client.builder() .region(Region.of(region)) @@ -67,6 +69,8 @@ class S3SchemaStorageClient( .readAllBytes() .decodeToString() + s3Client.close() + return result } @@ -150,5 +154,5 @@ class S3SchemaStorageClient( return getSchemaContent("$schemaName.$schemaVersion.schema.json") } - override var healthCheckSystem = HealthCheckS3Bucket(getS3Client()) as HealthCheckSystem + override var healthCheckSystem = HealthCheckS3Bucket(::getS3Client, bucketName) as HealthCheckSystem } diff --git a/libs/schema-validation/src/main/kotlin/gov/cdc/ocio/reportschemavalidator/utils/AWSS3Configuration.kt b/libs/schema-validation/src/main/kotlin/gov/cdc/ocio/reportschemavalidator/utils/AWSS3Configuration.kt deleted file mode 100644 index 2a17488c..00000000 --- a/libs/schema-validation/src/main/kotlin/gov/cdc/ocio/reportschemavalidator/utils/AWSS3Configuration.kt +++ /dev/null @@ -1,15 +0,0 @@ -package gov.cdc.ocio.reportschemavalidator.utils - -import io.ktor.server.config.* - -/** - * AWS S3 configuration class - * @param config ApplicationConfig - * @param configurationPath String? - */ -class AWSS3Configuration(config: ApplicationConfig, configurationPath: String? = null) { - private val configPath = if (configurationPath != null) "$configurationPath." else "" - val s3Bucket = config.tryGetString("${configPath}s3.report_schema_bucket") ?: "" - val s3Region = config.tryGetString("${configPath}s3.report_schema_region") ?: "" - -} \ No newline at end of file