Specifying multiple Spring active profiles in k8s deployment yml - spring

I am having two active profiles in my module in Java.
I am trying to specify it in kubernetes like this:
env:
- name: spring_profiles_active
value: ["dev", "shop-module"]
Is the correct way to specify the two active configs?

Multiple active profiles can be configured in the below way:
application.properties
spring.profiles.active=dev,hsqldb
(or)
application.yml
spring:
profiles:
active: "dev,hsqldb"

how do you pass it while on command line ?? it will be supported surely if can be done via command line or you can do outside of kubernetes
try this link,
How can I specify the spring.profiles.active param with a value from an environment variable using fabric8 maven plugin?

Related

SpringBoot yml how can I run two profiles at the same time

In my application yml, I have two profiles which I need to both run
spring:
profiles:
active:
awss3, #env#
application:
name: CONFIG-SERVICE
I need awss3 to be run, in what ever the env is. Is this possible ?
In my opinion, your requirements fits Profile Groups. This approach is preferable as it allows you to visually inform the developer which profiles are required for which environments.
https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.profiles.groups
Example:
spring:
profiles:
group:
production:
- "aws3"
- "prodmq"
Then you can start the application using:
--spring.profiles.active=production
to active the production, aws3 and prodmq profiles in one hit.
To clarify: The keyword production under group: is what you will use when you run your application as spring.profiles.active=production
Alternatively like you can simply add whatever profiles you want from the command line.
java -jar -Dspring.profiles.active=awss3,prodmq demo-0.0.1-SNAPSHOT.jar
yes, using properties:
// Use your dynamic profile
spring.profiles.active=#env#
// Include your default profile
spring.profiles.include=awss3
yaml:
spring:
profiles:
include: awss3
active:
#env#

It is possibile to send variable from docker env to yml file in spring project?

I want to set variables in my spring project YML configuration from docker environment variable without using Docker Compose.
To use an environment variable in your spring project, first, you need to set in your docker container.
Set ENV in Docker Container:
Docker run -e LOGGING_LEVEL_ROOT="info" -e PROFILE="production" -it your_image
Now, You can use LOGGING_LEVEL_ROOT in your spring project YML configuration.
logging:
level:
root: ${LOGGING_LEVEL_ROOT}
Or
spring:
profiles: ${PROFILE}
Note that, since the application.properties and application.yml files
accept Spring style placeholders (${…​}), the Maven filtering is
changed to use #..# placeholders. (You can override that by setting a
Maven property called resource.delimiter.)
oot-features-external-config-placeholders-in-properties

SpringBoot project, Environment Variable in application.yml always empty

I'm trying to run a SpringBoot project that runs with docker-compose. i started its dependencies (Redis, MongoDB ,and RabbitMQ) with docker-compose up
and i'm building the project and running it with these commands
mvn clean package -DskipTests && mvn spring-boot:run
I keep having these errors :
Error processing condition on org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2RestOp erationsConfiguration$RequestScopedConfiguration
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'OAUTH_CLIENTID' in value "${OAUTH_CLIENTID}"
In the docker-compose file, the values of the environment variables are defined in the environment section.
environment:
- RABBIT_HOST=rabbitstomp
- RABBIT_USER=guest
- RABBIT_PASS=user
- MONGO_HOST=mongodb://localhost:27017
- OAUTH_CLIENTID=nz-kek
- OAUTH_CLIENT_SECRET=DzXZxeOZOJHFZIUhObSpsne
- SSO_HOST=https://webweb.com
- CORS_HOSTS=HOST1,HOST2
- SES_HOST=ses
- SES_PORT=6000
- REDIS_HOST=localhost
- REDIS_PORT=6379
This is how application.yml looks like :
spring.data.mongodb:
database: ${DB_NAME} #notificationdb
uri: ${MONGO_HOST}
security:
oauth2:
resource:
jwk:
key-set-uri: ${auth-server:${SSO_HOST}}/keys
token-info-uri: ${auth-server:${SSO_HOST}}/userinfo
client:
client-id: ${OAUTH_CLIENTID}
client-secret: ${OAUTH_CLIENT_SECRET}`
So when running the project without docker-compose, am i supposed to put the values in the application.yml ?
i also tried mvn spring-boot:run -Dspring-boot.run.arguments=--path.to.value=value1, but i'm not sure how the path should be with variables like key-set-uri: ${auth-server:${SSO_HOST}}/keys
Spring has support for providing default values in the configuration via the PlaceholderConfigurerSupport. The default value is what comes after the :. In your case, you should write:
client-id: ${OAUTH_CLIENTID:yourDevelopmentDefaultClientID}
If you use the #Value annotation to inject the values, you have support to SpEL for using expressions of the type: #{someExpression} for more complex cases.
UPDATE:
In your case, I believe you are reversing the position of the variables. The correct should be:
key-set-uri: ${SSO_HOST:auth-server}/keys
Here is what it means: first, it will try to use the SSO_HOST environment variable, which is provided to the container through docker-compose. In case this variable is not provided to the process, Spring will use auth-server as the address of the server. It seems to me that this address is visible only inside the docker-compose network, so if you are running your app outside this network, the auth-server address will not be visible. Do you know where is the auth server? Is it another docker container? Is it running on localhost?
Some interesting reference: https://www.baeldung.com/spring-value-defaults
Pass env variables in docker compose as object not a list:
environment:
RABBIT_HOST: rabbitstomp
RABBIT_USER: guest
RABBIT_PASS: user
MONGO_HOST: mongodb://localhost:27017
OAUTH_CLIENTID: nz-kek
OAUTH_CLIENT_SECRET: DzXZxeOZOJHFZIUhObSpsne
SSO_HOST: https://webweb.com
CORS_HOSTS: HOST1,HOST2
SES_HOST: ses
SES_PORT: 6000
REDIS_HOST: localhost
REDIS_PORT: 6379`

How to create Spring Cloud Config Client with env specific configuration?

I have facing an issue with Spring Cloud Config Server and Eureka Server Profiling.
Let's say I have 3 services with their name ("spring.application.name") as :
myapp-svc
myapp-spring-cloud-config-svc
myapp-spring-eureka-svc
I want to deploy each service in 2 regions ( dev and prod ). In Dev region, each service will run on localhost and in prod it will have some different url. 'myapp-spring-cloud-config-svc' in dev region will point to local git repo, while in prod region it will point to remote git repo.I can have 2 configurations:
1) When I start 'myapp-svc' service in local, it should connect to 'myapp-spring-cloud-config-svc' in dev.
I can do this by setting spring.cloud.config.uri = .
But the issue with this set up is that the property needs to be defined in bootstrap.properties.
So, If deploy 'myapp-svc' to prod, I will have to change config uri there to point it to prod config service which in turn would need another build creation.
This doesn't seem like a good solution, what if I have 50 app related services, I can't change this property in each one of them before prod deployment.
I tried setting spring.cloud.config.uri in application-dev.properties of 'myapp-svc' but it doesn't work. As per docs, it must be changed in bootstrap.
So, how do I implement this without having to create new build for prod ?
2) I can first call eureka and then using eureka I can call config service here.
The problem here is also same.
If I use eureka to look up config then "eureka.client.serviceUrl.defaultZone" must be defined in "bootstrap.yml".
See this:https://cloud.spring.io/spring-cloud-config/multi/multi__spring_cloud_config_client.html
So, in this case too, I need to change eureka url before deploying this service to prod.
Please help me on this...!!
Here is how, the properties, yml looks like for each of the above mentioned services:
1) myapp-svc:
1.1)bootstrap.yml
spring:
application:
name: myapp-svc
cloud:
config:
discovery:
enabled: true
serviceId: myapp-spring-cloud-config-svc
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8762/eureka/
server:
port: 8082
2) myapp-spring-cloud-config-svc:
2.1)application-dev.properties:
spring.cloud.config.server.git.uri=file:///C:/config-repo
eureka.client.serviceUrl.defaultZone=http://localhost:8762/eureka
2.2)application-prod.properties:
spring.cloud.config.server.git.uri=https://github.com/<mygit Repo>
2.3)bootstrap.proerties:
spring.application.name=myapp-spring-cloud-config-svc
server.port=8888
3) myapp-spring-eureka-svc
3.1)bootstrap.proerties
spring.application.name=myapp-spring-eureka-svc
server.port=8762
1) You can have profile specific bootstrap-<profile>.properties (like for application-<profile>.properties) for each supported profile to avoid rebuilding your application for each env. Then just pass application profile using to your application during start-up. Spring will load correct bootstrap-<profile>.properties and will connect to proper configuration server (or eureka, etc). Example:
java -jar your-app.jar --spring.profiles.active=dev
2) You can pass your URLs externally as custom properties (same as with profile above) and have smth like this in bootstrap.properties. Example:
spring.cloud.config.uri=${config.server.url}
then pass --config.server.url= ... during start-up.
3) You can pass Spring properties in the same way during start-up. Example:
java -jar your-app.jar --spring.cloud.config.uri= ...
4) You can use system env variables. Example:
spring.cloud.config.uri=${SYSTEM_ENV_CLOUD_CONFIG_URI}

Starting Spring Application by merging yml files

Is there a way in spring boot to merge properties from different config files and start the application?
Ex: My application-local.yml which is the one that gets used by default had following properties
server:
port: 8080
spring:
profiles: local
propertyA: xxx
propertyB: yyy
Now instead of having to copy all the properties from the local to lets say application-QA.yml like this
server:
port: 8081
spring:
profiles: local
propertyA: xxx
propertyB: zzz
where only port & propertyB has been updated, can I just have something like below?
application-QA.yml:
server:
port: 8081
propertyB: zzz
At the end I want to have the following ability to start my applicatio
with local - ./gradlew bootrun
should pick up properties from application-local.yml which is what is happening now
with QA - ./gradlew bootrun -Dsome.property=QA
should merge properties from local and QA and start the application
Right now we have to copy port & propertyB to application-local.yml and start the application in order to point to QA environment and I would like to eliminate that.
Note: ./gradlew bootrun -Dspring.profiles.active=QA doesn't seem to work for me since I will need all the properties in application-local.yml to be in application-QA.yml and not just the properties I want to override.
You can do this using spring profiles.
You can activate many profiles together and every profile will read properties from an additional application-.yml
If you activate a profile 'local', spring searches for a file
application-local.yml
If you activate a profile 'QA', spring searches for a file
application-QA.yml
So you set the common properties in application-local.yml, and only the different ones e.g. the port in application-QA.yml .
You activate both profiles together with
-Dspring.profiles.active=local,QA
See also spring howto-properties-and-configuration
You can use spring.config.additional-location to override only selected properties instead of replacing whole default properties file.
This property is taken from:
org.springframework.boot.context.config.ConfigFileApplicationListener#CONFIG_ADDITIONAL_LOCATION_PROPERTY

Resources