config property not getting picked in micronaut - java

I have tried to create the environment specific configuration in micronaut
with main application.yml as
micronaut:
application:
name: xyz
server:
port: 9090
environments: local
and local configuration file as
with name as application-local.yml
xyz:
aws:
accessKey: <access_key>
secretKey: <secret_key>
In code I am trying to access as
#Value("${xyz.aws.accessKey}")
I while trying to access them in code getting following error
Message: Error resolving field value [${xyz.aws.accessKey}]. Property doesn't exist or cannot be converted

I found out that there is no such properties in micronaut similar to spring's
spring.profiles.active
here instead we have to pass the external file as VM options instead
-Dmicronaut.environments=local
then it started to work

Related

Java SDK SdkClientException: Unable to load AWS credentials from any provider in the chain

I want to fetch configuration properties from Parameter Store on boostrap application, for that I am using io.awspring.cloud:spring-cloud-starter-aws-parameter-store-config:2.3.3 and I run the same configuration on Windows where it works but on linux ec2 instance or WSL2 I am receiving below error message:
AwsParameterPropertySourceNotFoundException: com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain: [EnvironmentVariableCredentialsProvider: Unable to load AWS credentials from environment variables (AWS_ACCESS_KEY_ID (or AWS_ACCESS_KEY) and AWS_SECRET_KEY (or AWS_SECRET_ACCESS_KEY))
but before run it I am doing
export AWS_ACCESS_KEY_ID="xxxx"
export AWS_SECRET_ACCESS_KEY="xxxxx"
I also verify it using printenv and yes they are there. So the question is why I am receiving ...Unable to load AWS credentials from environment variables AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY...does anyone know?
EDIT:
Forgot to mention but I use
io.awspring.cloud:spring-cloud-starter-aws-parameter-store-config
with configuration:
cloud:
aws:
credentials:
access-key: ${AWS_ACCESS_KEY_ID}
secret-key: ${AWS_SECRET_ACCESS_KEY}
region:
static: eu-west-1
auto: false
use-default-aws-region-chain: true
stack:
auto: false
But underhood it use DefaultAWSCredentialsProviderChain so it should works like AWS SDK for Java

Spring boot Could not locate PropertySource: label not found

I am trying set Spring Cloud Config Server, but the service config server, it the running on port 8888 which is correct, and another service should run on port 18060, but for reason when I startup, it allocate port 8080 for me and the return a warning "Could not locate PropertySource: label not found", what should I do? Thank you !!!
Add #EnableConfigServer at configuration class level or main class of spring boot application and restart the service .it will work .
In my case it was because I had to set the default branch of my github URI (the branch of the repository set for spring.cloud.config.server.git.uri) in the config server by setting the following to the application.properties
spring.cloud.config.server.git.default-label=main
I ran into similar issue, when I run my server locally I see in the logs only on the stratup
o.s.c.c.c.ConfigServicePropertySourceLocator - Could not locate PropertySource: label not found
It turned out this is a problem with the health check for the config server, when health check is triggered to config server an empty environment is used so the application name is empty hence the spring cloud client will try to access {config-server}/application since application is the default application name, see issue for more info on this.
To solve the issue I just disabled the health check for config server
health.config.enabled=false
Try this one. I had the same issue and solved.
First enable debug mode in your app.(In your property file: logging.level.=DEBUG . This is only to make sure the issue is same as mine Or you may have any clue of where it can go wrong.)
Then start the application and see the logs. The log shows the configured server URI and what the URL to get all property resources.
Compare both URL s - the one in the log and your Configuration server URI.
Issue is that mistakenly the URL defined the property file can have empty space at the end. (This can happen when you copy past from somewhere ) Example:
the value for spring.cloud.config.uri=http:localhost:< port >< additional empty space >
If this is the case, the client's log shows localhost:/20%20%/ < app name > / < profile >
Simply remove the post empty space. Then it should work !
In your bootstrap.yml file
Add these lines
spring:
cloud:
config:
enabled: true
uri: http://localhost:8888 ##this is the link to the server config
label: main ##this is what you are missing (name of the git repo branch)
application:
name: currency-spring-cloud-config-client
profiles:
active: testing
server:
port: 8600
spring:
cloud:
config:
enabled: true
uri:
- http://localhost:9196 ### your port for cloud config server
label: main ### your git repo branch name
In my case my server was fetching cofnigs from github repository, and I forgot that I made it private :)

Spring Boot Registration Server(Eureka Server)

I am working on a Spring Boot Registration Server(Eureka Server).
Currently it is working with below configuration.
Project Name: registration-service
Inside main method: System.setProperty("spring.config.name", "registration-service");
"yml file":
file name: registration-service
content:
eureka:
instance:
hostname: eureka-server
server:
enableSelfPreservation: false
client:
register-with-eureka: false
fetch-registry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
server:
port: 2323 # HTTP (Tomcat) port
spring:
application:
name: eureka-server
With above configuration,application start running on 2323.
But if i change spring.config.name,it does not work,start giving connection refused exception.
why it is happening? even though this spring.config.name is no where used in yml file. Should it be necessarily same as project name? or it is specific to #EnableEurekaServer enabled spring boot application.
And in yml we have to write
spring:
application:
name: eureka-server
though in other spring boot application we give name of current project(here it should be registration-service).why we have to write here eureka-server? I know,I am missing something(or a lot of things).please help me in understanding the missing part.
Spring boot by default looks for file application.yml. If u have different profiles in your application it can also look for application-{profilename}.yml. This is the default convention followed.
spring.config.name property is used to override this default behaviour. When u override this property with register-service then spring boot looks for a file register-service.yml and loads config from that.
So your eureka server url which is given in the register-service.yml file may not be available in the default application.yml file. Hence when u change the value Spring boot may not be avle to find the Eureka server url.
Keep the names unchanged, as much as possible. If u have config file as register-service.yml then keep the spring.config.name=register-service. If you change this value then u need to create the new file with config.name value and then add eureka configuration to that again.

How to one-off run #DataJpaTest against real database instead of in-memory with Spring Boot

I am using Spring Boot 1.4.3 and have a whole bunch of tests that are annotated with #DataJpaTest. By default, they run against an in-memory database. I would like to be able to run all of them against a local MySQL temporarily. How can I do this in an easy way?
I have found that I can make it work for one by adding #ActiveProfiles("local") where I have an application-local.properties that points to my local MySQL, but it is just too much work to add that everywhere, run the tests and then remove it again (since I only want to run this manually against MySQL, the CI environment will run against the in memory db).
I am using Maven if that would matter.
UPDATE:
So I have an application-local.properties which contains the db properties to connect to my local MySQL database (Which I use already to run my application against the local MySQL)
Then I right-click in IntelliJ on a package and select "Run all tests in package". In the settings of that run configuration, I add -Dspring.profiles.active=local to the "VM options" field.
I would have thought that this would activate the local profile during the tests, but it does not. If I stop the local MySQL, the tests still run fine.
In the docs it states that you are able to remove the autoconfigured h2 datasource with #AutoConfigureTestDatabase(replace= Replace.NONE) on the test class https://docs.spring.io/spring-boot/docs/1.4.2.RELEASE/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications-testing-autoconfigured-jpa-test.
Also you then need to provide your db setup in properties, so that it does not use your app properties e.g.:
# Database
spring.datasource.url=jdbc:mariadb://localhost:3303/test
spring.datasource.username=test
spring.datasource.password=test
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=true
i put this in application.properties in the test package
You can add the profile with the MySQL datasource properties in the same application.properties (or .yml) as:
application.yml
# Existing properties
---
spring:
profiles: h2
# More h2-related properties
---
spring:
profiles: postgres
database:
driverClassName: org.postgresql.Driver
datasource:
url: jdbc:postgresql://localhost:5432/db_dvdrental
username: user_dvdrental
password: changeit
jpa:
database: POSTGRESQL
generate-ddl: false
# More postgres-related properties
and either use #ActiveProfiles("postgres") in an integration test class or start teh container using VM argument as:
java -Dspring.profiles.active=h2 ...
Add application.yml(properties) with jdbc connection into src/test/resources
Run your JPA test with #AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE) - it disables using embedded database (h2), otherwise :
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'dataSource': Invocation of init method
failed; nested exception is java.lang.IllegalStateException: Failed to
replace DataSource with an embedded database for tests. If you want an
embedded database please put a supported one on the classpath or tune
the replace attribute of #AutoConfigureTestDatabase.

How do you properly set different Spring profiles in bootstrap file (for Spring Boot to target different Cloud Config Servers)?

We have different config servers per environment. Each spring boot application should target its corresponding config server. I have tried to achieve this by setting profiles in the bootstrap.properties file, e.g.:
spring.application.name=app-name
spring.cloud.config.uri=http://default-config-server.com
---
spring.profiles=dev
spring.cloud.config.uri=http://dev-config-server.com
---
spring.profiles=stage
spring.cloud.config.uri=http://stage-config-server.com
---
spring.profiles=prod
spring.cloud.config.uri=http://prod-config-server.com
And then I set the cla -Dspring.profiles.active=dev but the loaded config server is always the last one set in the file (i.e. prod config server would be loaded in the above settings, and then if prod is removed, stage would be loaded).
Is it possible to set bootstrap profiles for the cloud config server? I followed this example but can't seem to get it working. For what it's worth, these profiles work great to load the correct config (i.e. app-name-dev.properties will load if the dev profile is active), but aren't being pulled from the proper config server.
Specifying different profiles in a single file is only support for YAML files and doesn't apply to property files. For property files specify an environment specific bootstrap-[profile].properties to override properties from the default bootstrap.properties.
So in your case you would get 4 files bootstrap.properties, bootstrap-prod.properties, bootstrap-stage.properties and bootstrap-dev.properties.
However instead of that you could also only provide the default bootstrap.properties and when starting the application override the property by passing a -Dspring.cloud.config.uri=<desired-uri> to your application.
java -jar <your-app>.jar -Dspring.cloud.config.uri=<desired-url>
This will take precedence over the default configured values.
I solved a similar problem with an environment variable in Docker.
bootstrap.yml
spring:
application:
name: dummy_service
cloud:
config:
uri: ${CONFIG_SERVER_URL:http://localhost:8888/}
enabled: true
profiles:
active: ${SPR_PROFILE:dev}
Dockerfile
ENV CONFIG_SERVER_URL=""
ENV SPR_PROFILE=""
Docker-compose.yml
version: '3'
services:
dummy:
image: xxx/xxx:latest
restart: always
environment:
- SPR_PROFILE=docker
- CONFIG_SERVER_URL=http://configserver:8888/
ports:
- 8080:8080
depends_on:
- postgres
- configserver
- discovery
#LarryW (I cannot answer on the same comment):
I guess the advantage of explicitly adding the property is that it allows you to add a default value (in this case "dev") in case of not setting up the environment variable.

Categories