How can #ColumnTransformer use the value inside application.yaml - spring

How can i put the encription_key and encription_type in the #ColumnTransformer Annotation read or write parameter from application.yaml
#ColumnTransformer(read = "convert_from(decrypt(decode(phone,'hex'), {encription key}, {encription method}),'utf8')", write = "encode(encrypt(convert_to(?,'utf8'),{encription key}, {encription method}),'hex')")
What i did is
get the value from application.yaml and put it in
#Value("${codec.iv}")
private final static String key="";
Use Database Custom function to return bytea::encription_key - it is works but not want to
HardCoding
I also see that using postgres.conf - not want.
What i want to do is
get the key and encription_method from external files(like application.yaml etc…)

Related

Use Configuration values in a File Pipe Validator with NestJS

I have a validation pipe for upload files that works.
#UseInterceptors(FileInterceptor('file'))
public async UploadTimeSheetFile(
#UploadedFile(
new ParseFilePipe({
validators: [
new MaxFileSizeValidator({ maxSize: 100000 }), // maxSize is in bytes
new EndOfWeekValidator({
EndOfWeekDayNumber: 6,
} as EndOfWeekValidatorOptions),
Without worrying about the implementation details, creating these settings with static values works. However, I want to be able to use these from my configuration service. However, if I try to use a variable (from the constructor accessing the configuration service) I get an error.
private ValidationConfig_: DateValidatorOptions;
constructor(
private readonly AppConfig_: ConfigurationService
) {
this.ValidationConfig_.EndOfWeekDayNumber = this.AppConfig_.GetEndOfWeekDay;
}
I then try to use this value:
new EndOfWeekValidator({
EndOfWeekDayNumber: this.Configuration.EndOfWeekDayNumber
} as EndOfWeekValidatorOptions),
And an error is returned Object is possibly 'undefined'.ts(2532)
Is there a way to set the values dynamically from my configuration, versus having to hard code values in the NestJS File Pipe custom validators?

For #sqslistener, value pass from environment variable other than .yaml file

I am currently using Amazon SQS to consume message in springboot.
e.g.
#sqslistener(value ="amazon.sqs.queue-name")
public void sesListener() {
// some statement
}
application.yaml
Note : amazon.sqs.queue-name is read from application.yaml which is working fine.
But Now I want to read sqs-name from environment variable, so I no need to put this queue name in application.yaml file.
Can anyone please help me out for this use-case ?
FYI : I want to use something like env.getProperty("queue-name") to read queue-name from environment variable. Currently I tried below workaround
#SqsListener(value = "#{ environment['queue-name'] }"
And also want to debug, that SqsListener is listening to the correct queue.
try this:
#sqslistener(value ="${amazon.sqs.queue-name}")
public void sesListener() {
// some statement
}

How to modify prometheus exposed metric names using Actuator in Spring-boot 2

I am using Actuator in springboot 2 to expose /actuator/prometheus endpoint from which a prometheus instance will pull metrics.
Everithing works perfect except because I am in need of tweak the metric names. I mean not the suffix (_count, _total, _bucket, ...) which are meaningful for Prometheus but something like:
http_server_requests_seconds_count -> http_server_requests_count
http_server_requests_seconds_max -> latency_seconds_max
http_server_requests_seconds_sum -> latency_seconds_sum
http_server_requests_seconds_bucket -> latency_seconds_bucket
Is there any better approach to this?
P.S.
I know i can use
management.metrics.web.server.requests-metric-name=different
to get
different_seconds_count
different_seconds_max
different_seconds_sum
different_seconds_bucket
but it would be difficult to:
1º remove the _seconds suffix
2º use a different base name for only one of them
I am guessing i could write an alternative PrometheusRenameFilter but not sure how to configure it to the default registry.
you can override this method and update the naming convention:
#Configuration
public class MetricsConfiga {
#Bean
MeterRegistryCustomizer<MeterRegistry> configurer(String applicationName) {
return (registry) -> registry.config().namingConvention(new NamingConvention() {
#Override
public String name(String name, Meter.Type type, String baseUnit) {
return "PREFIX" + Arrays.stream(name1.split("\\."))
.filter(Objects::nonNull)
.collect(Collectors.joining("_"));
}
});
}
}
Now I know how I can customize the global registry:
e.g. to set a custom meter filter:
#Configuration
public class MetricsConfig {
#Bean
MeterRegistryCustomizer<MeterRegistry> metricsConfig() {
return registry -> registry.config().meterFilter(new CustomRenameFilter());
}
}
However, setting a custom rename filter in the registry only allow to rename the base metric name.
It does not act on the suffixes nor allow to act on specific metric belonging a set e.g. generated by the summary.
with a custom NamingConvention I can add suffixes to convention base name ... I could even alter existing suffixes or replace convention base name.
Finally please note that Histogram prometheus metric type expects the creation of
<basename>_bucket
<basename>_sum
<basename>_count
with those specific names so it might be incorrect to tweak the component in the way I want because that would be a diferent component.

ConfigurationProperties loading list from YML

I'm trying to load Configuration from YML. I can load value and I can also load list if these are comma seperated values. But i can't load a typical YML List.
Configuration Class
#Component
#PropertySource("classpath:routing.yml")
#ConfigurationProperties
class RoutingProperties(){
var angular = listOf("nothing")
var value: String = ""
}
Working routing.yml
angular: /init, /home
value: Hello World
Not Working routing.yml
angular:
- init
- home
value: Hello World
Why can't i load the second version of yml / do I have a syntaxt error?
ENV: Kotlin, Spring 2.0.0.M3
As #flyx say, #PropetySource not worked with yaml files. But in spring you may override almost everything :)
PropertySource has additional parameter: factory. It's possible to create your own PropertySourceFactory base on DefaultPropertySourceFactory
open class YamlPropertyLoaderFactory : DefaultPropertySourceFactory() {
override fun createPropertySource(name: String?, resource: EncodedResource?): org.springframework.core.env.PropertySource<*> {
if (resource == null)
return super.createPropertySource(name, resource)
return YamlPropertySourceLoader().load(resource.resource.filename, resource.resource, null)
}
}
And when use this factory in propertysource annotation:
#PropertySource("classpath:/routing.yml", factory = YamlPropertyLoaderFactory::class)
Last that you need is to initialized variable angular with mutableList
Full code sample:
#Component
#PropertySource("classpath:/routing.yml", factory = YamlPropertyLoaderFactory::class)
#ConfigurationProperties
open class RoutingProperties {
var angular = mutableListOf("nothing")
var value: String = ""
override fun toString(): String {
return "RoutingProperties(angular=$angular, value='$value')"
}
}
open class YamlPropertyLoaderFactory : DefaultPropertySourceFactory() {
override fun createPropertySource(name: String?, resource: EncodedResource?): org.springframework.core.env.PropertySource<*> {
if (resource == null)
return super.createPropertySource(name, resource)
return YamlPropertySourceLoader().load(resource.resource.filename, resource.resource, null)
}
}
#SpringBootApplication
#EnableAutoConfiguration(exclude = arrayOf(DataSourceAutoConfiguration::class))
open class Application {
companion object {
#JvmStatic
fun main(args: Array<String>) {
val context = SpringApplication.run(Application::class.java, *args)
val bean = context.getBean(RoutingProperties::class.java)
println(bean)
}
}
}
Kinda old post, i know. But i am at the very same topic right now.
As of now, it seems that PropertySource does indeed work with yaml Files. Given the restriction that it only allows for primitive types (it seems) and it cant handle nested elements. I'm probably gonna dig a bit deeper and update my answer accordingly, but as of now, the accepted answer seems like a functioning workaround.
Well, according to the docs, your YAML file will be rewritten into a property file. The first YAML file becomes:
angular=/init, /home
value=Hello World
While the second one becomes:
angular[0]=init
angular[1]=home
value=Hello World
These are obviously two very different things and therefore behave differently.
Moreover, later in the docs, it is stated that YAML does not even work with #PropertySource:
24.6.4 YAML shortcomings
YAML files can’t be loaded via the #PropertySource annotation. So in the case that you need to load values that way, you need to use a properties file.
That makes me kind of wonder why the first case works for you at all.
The docs say this about the generated …[index] properties:
To bind to properties like that using the Spring DataBinder utilities (which is what #ConfigurationProperties does) you need to have a property in the target bean of type java.util.List (or Set) and you either need to provide a setter, or initialize it with a mutable value, e.g. this will bind to the properties above
So, let's have a look at Kotlin docs: listOf returns a new read-only list of given elements. So the list is not mutable as required by the docs, which I assume is why it doesn't work. Try using a mutable list (since I have never used Kotlin, I cannot give you working code). Also try to declare it as java.util.List if that's possible in Kotlin.

How configure struts2 to get validation rules from Spring via #value

We are using spring 3 and struts 2. We use spring #value annotation to get values from property files.
We want to get validation rules from property files instead of hard-coding them in action.
Here is sample property
system.properties
transfer.account.min.amount=10
Here is the action:
public class TransferToAccount implements Preparable {
#Value("${transfer.account.min.amount}") public String minAmount;
//...........execute and other methods omitted
#IntRangeFieldValidator(type = ValidatorType.FIELD, min = "${minAmount}", key = "validate.int.min")
public void setAmount(Integer amount) {
this.amount = amount;
}
The minAmount is populated correctly by value 10, but the validation is not working.
To see if parameters are passed correctly, I make a test as below.
Assume we want to get a key from spring managed property file ( This is just a test ;) )
system.properties
transfer.account.min.amount.key=validate.int.min
The resource bundle is:
validate.int.min = This field must be more than ${min}
...and we change validation as below:
#IntRangeFieldValidator(type = ValidatorType.FIELD, min = "${minAmount}", key = "${transfer.account.min.amount.key}")
Now when an error happens the validation message shows validate.int.min, instead of fetching this value from resource bundle!
Of course, when you run below code:
#IntRangeFieldValidator(type = ValidatorType.FIELD, min = "${minAmount}", key = "validate.int.min")
The error message is fetched resource bundle correctly!
If I can use annotation in this way, please let me know what is my mistake!
If I can not use annotations like this, please let me know what is the best way to avoid hard coding the validaiton rolls in actions.

Resources