Spring boot Load configuration per environment using PropertySource - java

I'm trying to add authorization to several microservices. Given all the services share similar authorization process, I want to extract the logic to a shared library.
I managed to create library, but I realise all the configurations need to be set in the application.yml file in the microservice which calls the library. I don't want to expose some of the configurations at service layer though.
After some searches, I found I could set #PropertySource("library.properties") in my library's configuration class to force reading properties from the specified .properties file within the library.
The problem now is I want to set different values for different environments, e.g. authorization URL for test and production would be different. How can I configure the file so that the configuration class would read same property value based on active profile (e.g. environment = test/staging/production)?

You can have multiple property files such as "application-environment.yml” in your resource folder. Spring framework picks the right one based on the active profile.
For example, if you define a “staging” environment and have a staging profile and then your property file should be named as application-staging.yml.

Related

How to load configurations in spring application from two sources where configuration from first source is required to load second one

I have spring based java application, The application support different databases and can be deployed on various containers. We have two type of configuration sources:
- Properties file: Bare minimum configuration to start the application. i.e application datasource JNDI name and database type.
- Config stored in DB as JSON/ hocon: Other configurations used by application.
what is the best way to have it implemented in spring context file, so that these configurations can be made available to the spring beans. The key problem here is to extract configuration from DB I need values from properties file (to locate the datasource).
Is to possible to have overriding feature where properties file have some default configurations, which are overridden by configuration loaded from DB. I have tried using multiple properties file, but not sure how I can have two property sources.

Spring boot is not able to get configuration file from my file system

I am trying to build a sample app on Spring boot and spring cloud.
I have written my database and hibernate configuration in config.properties property file which is located in my desktop and I want my spring boot to make use of this configuration.
My project have 3 modules
API
DataLayer
ServiceLayer
This is the code that I have mentioned in the application.property file of API
spring.profiles.active=native
spring.cloud.config.server.native.searchLocation=C:/Users/DEV/Desktop/configuration/config.properties
and the property file of DataLayer and ServiceLayer is empty
But when I run the API I am getting the following error
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
Process finished with exit code 1
Could any one help me with this error.
Thanks in advance.
This is can not be done from your API module. You added configuration server properties to your 'client' (from configuration point of view) application.
If you want to use Spring Cloud Config to configure your project you should have separate application that will manage your configuration. Let's call it config-server. (You should properly configure maven or gradle dependencies, see documentation) To configure usage of native profile in the config-server in application.properties you have to add properties that you mentioned in the question (example for native profile).
spring.profiles.active=native
spring.cloud.config.server.native.searchLocation=file:<path-to-the-directory-with-conf-files> or classpath:/<path-to-the-directory-with-conf-files>
Note: config-server can handle configuration for lot of services.
More can be found in the documentation Spring Cloud Config Server section.
Then in your API (or any other module) which is a spring boot app you should add spring-cloud-config-client dependency and add bootstrap.properties (or .yml) configuration file. There your should add properties that will describe communication with config-server. By default config-server listens on port 8888.
spring.application.name=<your app name>
spring.cloud.config.uri=http://localhost:8888 # this is also default value for this property
At start-up it will go by http to config-server and fetch your configuration properties based on service name (spring.application.name).
More can be found in Spring Cloud Config client section
Important: make sure your properly organize files in your configuration directory (which is used by native profile by config-server), find some samples. Property files naming are important. For start you can try to use your-application-name.properties
You have to have file: prefixed to the property file location.
Documentation from https://cloud.spring.io/spring-cloud-config/multi/multi__spring_cloud_config_server.html
There is also a “native” profile in the Config Server that does not use Git but loads the config files from the local classpath or file system (any static URL you want to point to with spring.cloud.config.server.native.searchLocations). To use the native profile, launch the Config Server with spring.profiles.active=native.
[Note]
Remember to use the file: prefix for file resources (the default without a prefix is usually the classpath). As with any Spring Boot
configuration, you can embed ${}-style environment placeholders, but
remember that absolute paths in Windows require an extra / (for
example, file:///${user.home}/config-repo).
[Warning]
The default value of the searchLocations is identical to a local Spring Boot application (that is, [classpath:/, classpath:/config,
file:./, file:./config]). This does not expose the
application.properties from the server to all clients, because any
property sources present in the server are removed before being sent
to the client.
[Tip] A filesystem backend is great for getting started quickly and for testing. To use it in production, you need to be sure that the
file system is reliable and shared across all instances of the Config
Server.

Using environment based configuration properties in java library

I have one java spring boot library and it is using some configuration as below using zookeeper address for loadbalancer.
<user:registry regProtocol="zookeeper" name="testZk" address="${zookeeper.address}"/>
zookeeper.address will be different between development and production environments.
Users of this library can include zookeeper.address in their cloud config properties based on the environment but are there other ways so that library users don't need to include these in their properties and library in some way use different properties based on environment from user.
Serving Plain Text will resolve above problem.
http://cloud.spring.io/spring-cloud-static/spring-cloud-config/2.0.0.M5/single/spring-cloud-config.html#_serving_plain_text
Just define multiple environments, you wish to in application properties and on the user side activate the properties, it will work.
I'm pretty new with java but I think that they could use an application.properties file to overwrite any environmental properties.
application.properties in spring

How to secure liquibase properties (database password etc.) in springboot application?

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.

How to config routes in Spring Cloud Zuul

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.

Categories

Resources