How do I store a Micronaut application properties with array of object in AWS Parameter Store since we can't have square brackets in the parameter name of AWS Parameter Store?
Here's a snippet of properties that need to be stored in AWS Parameter Store,
micronaut:
security:
intercept-url-map:
- pattern: /hello
http-method: GET
access:
- isAnonymous()
- pattern: /bye
http-method: GET
access:
- isAnonymous()
I managed to solve this issue by decorating AWSParameterStoreConfigClient
, bean that responsible to orchestrating the properties reading from AWS Parameter Store. Before implementing the solution please be aware that,
AWSParameterStoreConfigClient
bean will still be loaded and perform the properties reading, including the API call to the cloud. Make sure that your app won't be disrupted by such behavior.Here's the solution code,
import io.micronaut.context.annotation.BootstrapContextCompatible
import io.micronaut.context.annotation.Factory
import io.micronaut.context.annotation.Requirements
import io.micronaut.context.annotation.Requires
import io.micronaut.context.env.Environment
import io.micronaut.context.env.MapPropertySource
import io.micronaut.context.env.PropertySource
import io.micronaut.discovery.aws.parameterstore.AWSParameterStoreConfigClient
import io.micronaut.discovery.config.ConfigurationClient
import jakarta.inject.Singleton
import reactor.core.publisher.Flux
@Factory
@Requirements(
Requires(env = ["ec2"]),
Requires(beans = [AWSParameterStoreConfigClient::class])
)
@BootstrapContextCompatible
class ConfigurationClientConfiguration {
@Singleton
fun enhancedAWSParameterStoreConfigurationClient(
delegate: AWSParameterStoreConfigClient,
) = object : ConfigurationClient {
override fun getDescription() = "Decorated AWS Parameter Store"
override fun getPropertySources(environment: Environment) = Flux.from(delegate.getPropertySources(environment))
.map { propertySource ->
var newPropertySource = (propertySource as MapPropertySource).asMap().toMutableMap()
newPropertySource = newPropertySource.mapKeys { (key) ->
key.replace("\\.\\d+\\.".toRegex()) { matchResult ->
matchResult.value.replaceFirst(".", "[").replaceFirst(".", "].")
}
}.toMutableMap()
PropertySource.of(newPropertySource)
}
}
}