I'm currently developing an REST app whith Spring boot. For development, I hardcode my database configuration in application.properties. However, this app is going to be deployed on different WildFly servers, each of them defining their DB config (user credentials) in standalone.xml.
As I'm a newbe to Spring/Java, here is my question: How can I use the DB config from standalone for my spring app?
I already did some research. What I got is to define Services with an #PersistenceContext annotated entity manager. But how can I use it without defining new services, just by using plain JpaRepositories?
In Wildfly you will have a datasource configured with at JNDI name.
Instead of configuring url, username and password you have to configure this JNDI name:
spring.datasource.jndi-name=java:jboss/datasources/myGreatDS
That's all.
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 am working on spring boot application which uses REST webservices. Till now , all the database paaswords i used to store in my application.properties class and am using HICKARI CP also to manage the connection pooling.
But now , i have created the user services in Cloud foundry and have included the script of CF in my build.gradle file too.
But i do not have any idea as to how shall i access these services within my code and how can i autowire thise datasources. Please advice any solution.
Use Spring cloud service connector. This is sub project of Springs cloud.
http://cloud.spring.io/spring-cloud-connectors/spring-cloud-spring-service-connector.html#_relational_database_db2_mysql_oracle_postgresql_sql_server
you can create a mysql service inside your cloud foundry space. And the bind the same to your app. This can be done as defining services inside your manifest.yml or using bind-service command in cf cli.
You can add spring cloud service connector dependencies in your gradle build and add datasource configuration bean.
#Bean
public DataSource dataSource() {
return connectionFactory().dataSource("your-mysql-service-name");
}
This creates a datasource of the mysql service in your application, and registers as a bean in spring context. That can be autowired where ever needed.
Alternatively, cloud foundry exposes the details about every service that application is binded to, in VCAP_SERVICES env variable. Once your application is binded to service, you can find your mysql service username, password, connection url, db name etc in this variable. You can read this variable and parse the values and build a datasource of your own.
Using service connectors are preferred approach as the infrastructure code is handled by springs.
In my spring-boot application I have an existing dataSource, which I use for Hibernate and/or JdbcTemplate.
I am planning to use spring-session with spring-session-jdbc in the future.
Can the already existing and configured dataSource of the application be used?
If yes, how?
Or do I need to configure an additional dataSource for spring-session-jdbc?
The answer is:
Yes, it is possible, like the documentation of the newly released Spring Session 1.2.0 states:
http://docs.spring.io/spring-session/docs/current/reference/html5/guides/httpsession-jdbc-boot.html#httpsession-jdbc-boot-configuration
It also works without Spring Boot. In an old Spring-MVC project based on xml-config, which does not use Spring Boot, the configured dataSource is automatically used by Spring Session.
I am using LDAP with spring mvc 3. I want to configure it in a way where if my primary LDAP URL fails to connect then it connects to secondary LDAP URL. Can it be managed in spring configuration?
Set the urls property (pass it an array of ldap server urls) instead of the url property on your LDAPContextSource bean in your spring config. This will allow it to fail over if it can't talk to the first server.