I'm building a fairly simple Spring Boot application which needs some configuration to be set (and regularly updated as part of it's use). I'd like to create a simple admin interface and first-run wizard to set/update this configuration.
I'd like a way to easily read and write these configuration values within the application and have them persist. I would like to avoid the overhead of a database for 5-10 configuration strings. There is some good documentation on externalising configuration in Spring Boot but it doesn't talk about how this config could be updated and persisted by the app.
Options I have come up with:
There is a write option with Spring configuration that I'm not aware of (this would be awesome)
Don't use the Spring Boot configuration functionality, instead use apache commons configuration (or similar??) to read and write to a file which lives in a location specified by an environment variable
as per option 2 but use HSQL, H2 or Derby as a file-based database
Thanks for any suggestions as to how best to achieve this.
Related
I have spring boot rest service which returns the currency list. Now, I have a requirement that this currency list should be configurable by prod support guys so that they can keep adding the currencies whenever they want.
I am from the asp.net background and I know in asp.net, web.config file is editable even on the prod and prod support guys can make the changes in that file and restart the IIS server to get the latest changes.
In spring boot if I add my currencies in a property file. Will that file editable on prod.
As far as I know Spring boot creates JAR or WAR file as package. Property files won't be editable on prod.
Config files are not editable at runtime. You'd need to stop the server, and modify any properties, and restart. If files aren't editable, obviously that won't work.
If you want to be able to modify runtime configs, use a database/dynamic cache lookup.
Other solutions include Spring Cloud Config, Zookeeper, or Consul.
Externalize config via Spring Cloud Config. This will let you update your config at runtime. And also allow you to keep a track of your config version.
Have a look at this for better understanding:
Spring boot-microservices config
-From java brains
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
Specification
Each tenant has their own database which handles users in greater detail, and there needs to exist a central database which handles:
Tokens (OAuth2)
Users (limited level of detail)
Mapping users to their database
Problem
I've found solutions for multi-tenancy which allows me to determine the datasource depending on the user. However, I'm not sure how I can also link certain crud repositories to this central datasource, and others to variable datasources.
Another solution involved updating the properties file, and using a configuration server (i.e. via git) to trigger #RefreshScope annotated configs. Though I'm not sure if this can work for Datasources, or if this could cause problems later on.
Extra Context
I'm using Spring Boot and Hibernate heavily in this project.
This blog gives a very good tutorial on how to do it.
After a lot of research it looks like hibernate just isn't built for doing that, but by manually writing the schema myself I can inject that into new tenant databases using native queries.
I also had a problem with MS Server DBs, as they don't allow simply appending ;createDatabaseIfNotExist to the JDBC URL, which meant even more native queries (Moving the project over to use MySQL anyway, so this is no longer a problem.)
Is it possible to share some properties for limited group of microservices? I mean I just want to declare common datasourse in one place for several microservices, which will use the same database
I try to implement it using gradle variables, which should consist all data related to db connection with profiles, but probably easier way to do it exists.
Thanks
Yes it is. You're looking for "Spring Cloud Config" server:
Spring Cloud’s config server acts as a single source of configuration
data for all other services in a microservice-based application. It is
itself a microservice whose job is to obtain configuration data from a
Git repository and serve it via RESTful endpoints. All other services
can either consume the config server’s API directly or, if they’re
Spring applications, treat the configuration server as another
property source in Spring’s Environment abstraction.
You can find a nice reading along with examples here.
While developing a springboot-liquibase application following this I need to specify the database username + password as liquibase.user and liquibase.password in the application.properties file. I am looking for a better secure way to use these parameter (dynamically fetched from some other place and use inside my java code)
Is there a way to achieve this?
There are couple of things you can do:
You can encrypt you properties file using jasypt-spring-boot. For more details have a look at demo app
If you are developing distributed system, then 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
Spring Cloud Config
This project allows you to use an external, centralized configuration repository for one or more applications. You don't need to rebuild your application if a property changes. You can simply change the property in your configuration repository and even push the changes to all of your applications.
See this Getting Started Guide.