Is there possibility or workaround to tell Spring Config Server to get config from itself? I have some common configs for all Spring Boot apps depending on profile and I want config server has possibility to access them without copy-paste.
From the docs:
An optional property that can be useful in this case is spring.cloud.config.server.bootstrap which is a flag to indicate that the server should configure itself from its own remote repository.
So setting spring.cloud.config.server.bootstrap=true.
Related
I'm new to the spring cloud config server. Consider a scenario where we have 10 spring boot microservice fetching configurations from the Spring Boot Cloud Config. I was wondering How the 10 spring boot microservices will work when the Spring Boot Cloud Config itself is down?
Can someone answer to below queries:
If the config server is down, Will there be downtime for all the microservice connected to it?
Let's say we have a config file application.properties in GitHub and Spring boot config refers to the application.properties file in GitHub What if the username and password to access the application.properties file itself will change?
In terms of Disaster recovery, Do we need any backup of the config server? If yes, How can we achieve the same?
If the config server is down, Will there be downtime for all the microservice connected to it?
In real world application, there will be multiple instances of your config server deployed across multiple availability zones, fronted by load balancer or API gateway, or even you can register your multiple instance with eureka server so that there is No single point of failure.
So how the configuration will look like is instance 1 is in us-east-1
instance 2 in us-west-2, so even if one AZ is down it will not impact your services.
As far as GitHub or external repo is concerned, you can configure config server to read properties natively but that not something I will suggest !!
Let's say we have a config file application.properties in GitHub and Spring boot config refers to the application.properties file in GitHub What if the username and password to access the application.properties file itself will change?
First of all you should not commit password in Github for public repo, secondly password should be dynamically fetched from Idvault, or AWS secret Manager or other services whichever you prefer. So that even if you change password it will not affect any services.
In terms of Disaster recovery, Do we need any backup of the config server? If yes, How can we achieve the same?
Config server is just reading properties/config from repo that you provide,so repository where your code is hosted is of importance to you. Github can take care of that for you !!
I have to change my custom defined spring properties (defined via #ConfigurationProperties beans) during runtime of my Spring Boot application.
Is there any elegant way of doing this using Spring Cloud Config?
I don't want to use an external application.properties in a git repository (as the spring boot application gets shipped to customers and I dont' want to create a git repository for everyone of them).
I just want to access and change the local application.properties (the one in the classpath, located in src/main/resources) file in my Spring container or (if thats not possible) in the Spring Cloud Config Server, which I could embed into my Spring Boot app. Is that possible somehow?
BTW: The goal is to create a visual editor for the customers, so that they can change the application.properties during runtime in their spring boot app.
Spring Boot supports profile based application configuration. Just add application-<profile>.properties file. Then just when running the application select a profile depending on the environment making use of spring.profiles.active.
-Dspring.profiles.active=dev
This will run the application with application-dev.properties file (overriding the default application.properties, i.e you can just leave the common stuff in the default file and change the rest depending on the env)
On a side note, having a repo for configuration is not a must. You could just place them in the class path and give a search-location.
spring:
application:
name: config-server
profiles:
active: native
cloud:
config:
server:
native:
search-locations: classpath:configs/
It actually is possible and in the end quite easy to achieve. It just took me a whole day to get all the information together. Maybe this helps someone:
You basically just need Spring Actuator, but for a certain endpoint, you also need the spring cloud dependency. (to make Post requests to the /env endpoint of Spring Actuator)
To alter your config at runtime, just add the following to your application.properties:
management.endpoints.web.exposure.include: env,refresh
management.endpoint.env.post.enabled: true //this property is only available when spring cloud is added as dependency to your project
If you (like me) don't need the feature of an externalized config, then you also have to add the following (otherwise, your Spring app will not start and throw an error that some config is missing)
spring.cloud.config.enabled: false
Now, if you send a POST request to /actuator/env endpoint with an object in the HTTP body in the form of {"name":"...", "value":"..."} (name is the name of a config property), then your config gets changed. To check that, you can do a GET request to /actuator/env/[name_of_config_property] and see that your config property has changed. No need to restart your app.
Don't forget to secure the /actuator endpoint in your SecurityConfig if you use a custom one.
It seems to me that you neither need the #RefreshScope annotation at your config classes nor the /actuator/refresh endpoint to "apply" the config changes.
Maybe what your looking for could be achieved with Spring cloud config and spring cloud bus. It's explained here: https://cloud.spring.io/spring-cloud-config/reference/html/#_push_notifications_and_spring_cloud_bus
In summary, any change on configuration sent an event to the spring cloud bus and you can then reload app context or configuration with new properties.
I have a spring boot application that is connecting to an IBM MessageQueue service using the IBM Spring Boot starter:
com.ibm.mq:mq-jms-spring-boot-starter:2.1.2
I have a component class listening to the queues and it has the following annotation to enable/disable connecting to the queue:
#ConditionalOnProperty(name = "queue.enabled", havingValue = "true")
I also have the following property in my application.properties:
queue.enabled=false
This annotation worked for disabling the queue connections when I was connecting to ActiveMQ, but upon changing the codebase to connect to IBM MQ it seems that the connection is unaffected by the ConditionalOnProperty and always tries to connect.
Is there a way to enable/disable connecting to the IBM MQ service upon server startup?
The MQAutoConfiguration class that exists in the mq-jms-spring-boot-starter dependency is what is causing the attempted queue connection.
You have two options to fix this issue, one requires you to set a specific property, and the other allows you to define the property you want used to enable or disable the queue connection.
Option 1
Set the value spring.jta.enabled = false in your application.properties file.
(This may not be a preferred option if you're using transactions in your application.)
Looking at the MQAutoConfiguration class, you can see it is conditional on the property spring.jta.enabled. Setting that property to false in your application.properties file will prevent the MQAutoConfiguration class from being registered, which means no MQ beans get registered, and therefore no attempts will be made to connect to a queue.
Option 2 (if you don't want to disable JTA)
Create the package com.ibm.mq.spring.boot and create a copy of the MQAutoConfiguration class there. Modify the #ConditionalOnProperty annotation to the property of your choosing.
Just exclude configuration in your application.properties.
spring.autoconfigure.exclude=com.ibm.mq.spring.boot.MQAutoConfiguration
Currently i am working on a REST based project in Spring Boot.
I have added the api url in 'application.properties' file.
i.e.
application.properties
api-base-url=http://localhost:8080/RestServices/v1
And also this 'api-base-url' value access from java.
In some situations i need to change the 'api-base-url' dynamically.
I have change 'api-base-url' value dynamically & working fine.
But my problem is that
when wildfly restart then the configuration will be reset to default.
i.e
This is my default value
api-base-url=http://localhost:8080/RestServices/v1
dynamically change to
api-base-url=http://10.34.2.3:8080/RestServices/v1
when wildfly restart then the configuration will be reset to default.
i.e.
api-base-url=http://localhost:8080/RestServices/v1
Have any solution for this?
You might want to consider using a cloud config server to host your config. Two examples are Spring Cloud Config and Consul.
These servers will host your application's configuration and your spring boot application will make a call out to the config server on start up to get it's config.
spring-boot-actuator exposes the endpoint /refresh which forces the application to refresh it's configuration. In this case, it will call out to the config server to get the latest version.
This way you can change the config hosted in the config server then hit the /refresh endpoint and the changes will be picked up by your application.
As #moilejter suggests, one possible way is to persist in database table and at start time you simply read from that table instead of application.properties file. Your application.properties files can hold information necessary for database connection.
You would also need a JMX method or a REST API to trigger in your application that the url has changed and which inturn, would simply read from same table. This way you would be safe even if app restarts and you won't lose the override.
You can use BeanFactoryPostProcessor coupled with Environment bean to leverage spring placeholder concept.
#user2214646
Use spring expression language
In Spring Cloud Zuul server we can define all routes which need be redirected via "application.properties".
For example:
zuul.routes.resource.path=/api/**
zuul.routes.resource.url=http://api.com:9025
Once the fat jar is created the "application.properties" is encapsulated into jar, and it's not possible to edit and reload the rules inside the file.
Is there any to inform Zuul about the routes in an external file, and at the same time reload them without stopping the server?
You can use spring cloud config for that.
Spring Cloud Config provides server and client-side support for externalized configuration in a distributed system. With the Config Server you have a central place to manage external properties for applications across all environments
http://cloud.spring.io/spring-cloud-config/spring-cloud-config.html#_spring_cloud_config_client
...a bit late to the party, but...
You can do all that you want with the ConfigServer!
Create an application.yml for config that is common across ALL applications
Create profile specific application-mycommonprofile.yml. As 1. but for the 'mycommonprofile' profile.
Create an appX.yml for each application that is specific to that application.
Create profile specific appX-myprofile.yml. As 3. but for the 'myprofile' profile.
All of these files are optional and are not dependent on any others. You can have an application-mycommonprofile.yml without an application.yml for example.
Hope that helps!
Another late-to-the-party answer, but another way is to use a profile config file, which lives in the filesystem, outside the fatjar.
If the configuration name of your Zuul proxy is 'zuul' and your normal config file is 'zuul.properties' or 'zuul.yaml', then it looks for a profile-specific config file in 'zuul-.properties' or 'zuul-.yaml'.
If you do not specify a profile, then the profile named 'default' is active.
So you can load properties from an external file name 'zuul-default.properties' or 'zuul-default.yaml' (or 'zuul-default.yml', if you use a 3-letter filename extension).
This will then be loaded when no other profile is specified.