spring-boot-starter-quartz specify different db connector? - spring-boot

I have a spring boot application that is working correctly
with quartz job that is working correctly
all quartz related tables are created on FOO schema that is specified in the application.properties
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=
how do I specify a different DB schema only for the quartz objects?

To use another datasource for quartz-schedulers you have to create a bean data-source annotated with #QuartzDataSource
#Bean
#QuartzDataSource
public DataSource dataSource() {
...
}
To have Quartz use a DataSource other than the application’s main DataSource, declare a DataSource bean, annotating its #Bean method with #QuartzDataSource. Doing so ensures that the Quartz-specific DataSource is used by both the SchedulerFactoryBean and for schema initialization.
Related docs: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-quartz.html

Related

Fetch DB password from a web service in Spring boot

I have a specific requirement where in i need to fetch the database password (spring.datasource.password=) from a secure vault through a web service call.
But the problem is that when i start my spring boot application it tries to make a Hikari connection pool.
How can i acheive this ?
Option one
You can override Spring's autoconfiguration by creating DataSource bean in your configuration.
#Bean
public DataSource dataSource(HikariConfig hikariConfig) {
return new HikariDataSource(hikariConfig);
}
#Bean
#ConfigurationProperties(prefix = "prefix")
public HikariConfig hirariConfig() {
HicariConfig config = new HikariConfig();
// password retrieve logic
config.setPassword(password);
return config;
}
Option two
If you want to utilize Spring's autoconfigured DataSource, you can also use Spring Cloud Vault, which can lookup properties in Vault. Here are some tutorials which may help you to get started: https://spring.io/projects/spring-cloud-vault, https://spring.io/guides/gs/vault-config/.
Other options
You can inject your password as an environment variable. This variable should be named SPRING_DATASOURCE_PASSWORD. Or you can create your own PropertySource which will supply needed variable.
You can find more about this option in Spring blog.

Spring Boot and Spring Session: How to control the DataSource

I'm experimenting with Spring Boot and Spring session together, specifically using JDBC.
Just adding the line in application.properties:
spring.session.store-type=jdbc
made it just work, which is nice because I happen to also have some data source properties in that file, ie
myapp.datasource.url=jdbc:mysql://localhost/etc...
myapp.datasource.driver-class-name=com.mysql.jdbc.Driver
But I'm actually using those for my own data source with my own configuration, like so:
#Configuration
#PropertySource("classpath:credentials.properties")
public class DataSourceConfig {
#Primary
#Bean(name = "dataSource")
#ConfigurationProperties(prefix = "myapp.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
}
and as far as I can tell, Spring Session is creating its own data source instead of using mine. Is there a way I can get it to use mine instead?
(my real data source has some additional configs with Hikari not shown here)
Spring Session itself does not create DataSource but rather uses the one present in your application context, if it's the either:
the only DataSource bean
DataSource marked as #Primary
Also if you wish to use a specific DataSource for Spring Session (for example, if you have multiple DataSources in your application) you can do that by:
annotating DataSource marked as designated for Spring Session by #SpringSessionDataSource (Spring Session 2.0 onwards)
providing JdbcTemplate bean that uses the desired DataSource and naming it springSessionJdbcOperations (Spring Session 1.x)
The Spring Session JDBC configuration capabilities and logic should be quite easy to understand from the JdbcHttpSessionConfiguration.

Initialize standalone databases, Spring Boot and MyBatis

I'm building Spring Boot + MyBatis project using standalone postgresql database.
Well, for some reason, "convention-based" database initialization doesn't occur. I added data source manually, created sql-scripts, but when I run the project, from the log it's not even processing these scripts. I want to understand how the process works for not-embedded databases.
Can one create an instance of data source using code?
Should I link data source in property file or separate class?
What one should do to link separate data source (postgresql in this case) with Spring Boot configuration?
Yes
#Bean
public DataSource dataSource() {
DataSourceBuilder.create()
.url("jdbc:postgresql://localhost:5432/database")
.username("username")
.password("password")
...
.build();
}
2-3. You can use property file along with providing java based DataSourceConfiguration
spring.datasource.url: jdbc:postgresql://localhost:5432/database
spring.datasource.username: username
spring.datasource.password: pasword
And refers these properties in your Configuration class as follows:
#Bean
#ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
If you have only one database to connect to, the most convenient way is to add it's connection properties into property file, prefixed with spring.datasource (scroll here to check available options) and add org.postgresql dependency to pom.xml (build.grade) file and SpringBoot will do the rest.

SpringBoot Datasource AutoConfiguration Not Working

I have a simple SpringBoot application and I'd like to use AutoConfiguration to configure the Tomcat jdbc pooled data sources.
I am using these Spring dependencies:
// Spring Boot
compile 'org.springframework.boot:spring-boot-starter-web:1.3.5.RELEASE'
compile 'org.springframework.boot:spring-boot-starter-jdbc:1.3.5.RELEASE'
Here are my datasource properties in my application.yml file:
spring:
datasource:
url: jdbc:mysql://my.host/mydb
username: user
password: pwd
driver-class-name: com.mysql.jdbc.Driver
initialSize: 5
I am sure the properties are being loaded because the app is picking up other values.
I define the bean in my config file as:
#Bean(name="myDataSource")
#ConfigurationProperties(prefix="spring.datasource")
public DataSource getDataSource() {
DataSource dataSource = DataSourceBuilder.create().build()
return dataSource
}
And I inject the datasource into my DAO like this:
#Slf4j
#Repository
class MyDAO {
#Autowired
DataSource dataSource
public void getFoo() {
log.info("DB URL: ${dataSource.getUrl()}")
}
}
If I set a breakpoint in the getDataSource() method, the DataSourceBuilder will create an instance of DataSource. However, all the properties of that object like URL, user and password are all null. Also, when I call getFoo(), the dataSource variable is null. I have tried commenting out the bean definition in my AppConfig. The dataSource is still null. Any suggestions?
I looked through the Spring Boot documentation and my Spring book but I didn't see any examples like this. I see examples where I create the DataSource myself. But I was hoping Spring's auto-configuration would tie this stuff together automatically.
Thanks in advance for any help you can provide.
By creating your own bean, you're actually switching off Boot's auto-configuration of a DataSource. You can just delete your getDataSource method and let Boot auto-configure one instead.
Based on Andy's comments I found out that I had two problems. First of all, I needed to include the JPA dependency to the project. I added this line to my build.gradle file:
compile 'org.springframework.boot:spring-boot-starter-data-jpa:1.3.5.RELEASE'
Second, I was creating instances of MyDAO using new(). I fixed this by creating a service class that used #Autowired to inject an instance of MyDAO. Once the DAO became a Spring managed bean, it was able to inject the instance of DataSource from the Tomcat connection pool.

How do you use a Tomcat JNDI JDBC datasource in Spring Boot

I have a Spring boot application and want to deploy as a WAR to Tomcat 7. As part of this I need to keep configuration out of the WAR, so that I can deploy the same war to my stage and production servers and have it pickup the mysql connection via configuration.
To this end I want to configure my Spring Boot app to use a mysql connection configured as a JNDI datasource in the Tomcat instance.
Can spring boot do this and if so how?
Alternatively is this easy to do in Spring 4 without resorting to xml based configuration.
If you're using Spring Boot 1.2 or greater, this got easier. You can just add this to application.properties
spring.datasource.jndi-name=java:comp/env/jdbc/my_database
The relevant docs: http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html#boot-features-connecting-to-a-jndi-datasource
#Bean
public DataSource dataSource() {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
DataSource dataSource = dataSourceLookup.getDataSource("jdbc/apolloJNDI");
return dataSource;
}
No "java:comp/env/" its needed because JndiDataSourceLookup internaly calls convertJndiName that add this part. In other clases you should set the complete path.
Here's what I had done.
Add the following to to Application.java
#Bean
public DataSource dataSource() {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
DataSource dataSource = dataSourceLookup.getDataSource("java:comp/env/jdbc/mysqldb");
return dataSource;
}
Then follow the example in https://spring.io/guides/gs/accessing-data-jpa/ to set up the TransactionManager and Hibernate specific properties.
A hint for all of you using Spring Boot with an external Tomcat. Please ensure your war doesn't contain any tomcat jars. Multiple versions of same jar will produce hidden ClassCastException manifested by javax.naming.NamingException.

Resources