I am using Spring Activiti workflow in my project and the engine is generating their own tables to my datasource. How can I configure it to generate these tables to a different schema instead of my default?
You need to over-ride default data-source for activiti.
You will need to add spring-boot-configuration-processor as maven dependency
and you need to define data-source for activiti like :
#Autowired
private DataSourceProperties properties;
#Bean(name = "datasource.activiti")
public DataSource activitiDataSource() {
return DataSourceBuilder.create(this.properties.getClassLoader())
.url(this.properties.getUrl())
.username(this.properties.getUsername())
.password(this.properties.getPassword())
.driverClassName(this.properties.getDriverClassName())
.build();
}
For detailed steps for changing data-source, follow this blog.
Related
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.
I've got a spring-boot web application that's mostly working; my DataSource is properly configured by an external application.properties file.
Now I want to add properties to that file to help me instantiate and configure two instances of a class in my app. I have a APNsFactory that I currently instantiate manually and configure using JNDI, but I want to get away from JNDI calls:
#Bean
public
APNsFactory
apnsFactory()
throws
javax.naming.NamingException
{
sLogger.info("Configuring APNsFactory");
InitialContext ctx = new InitialContext();
APNsFactory f = new APNsFactory();
f.setProductionKeystorePath((String) ctx.lookup("java:comp/env/apns/prod/keystorePath"));
f.setProductionKeystorePassword((String) ctx.lookup("java:comp/env/apns/prod/keystorePassword"));
f.setDevelopmentKeystorePath((String) ctx.lookup("java:comp/env/apns/dev/keystorePath"));
f.setDevelopmentKeystorePassword((String) ctx.lookup("java:comp/env/apns/dev/keystorePassword"));
return f;
}
When running before in a standalone webapp container, Spring properly called that method and the JNDI context from the container’s <env-entry> tags was available.
I'm trying to update my APNsFactory to be a proper Spring FactoryBean<>, and I’ve given it a couple of #Autowire String variables that I want to be set by Spring Boot from the application.properties file.
For bonus points, I want this to be usable both in Spring Boot and in a standalone container like Tomcat or Resin.
For the life of me, I can't figure out how to get Spring to do this. There are dozens of examples for DataSources and other Beans already implemented by Spring, but none for a completely custom one, using application.properties, in a Spring Boot web environment.
I've seen some examples that use an XML config file, but I'm not sure how to do that with Spring Boot.
I don't think you need a factory bean here.
You already have spring boot that can read application.properties out-of-the-box:
So try the following:
Create key/values in the application.properties file:
myapp.keystore.path=...
myapp.keystore.passwd=...
// the same for other properties
Create ConfigurationProperties class
#ConfigurationProperties(prefix="myapp.keystore")
public class MyAppKeyStoreConfigProperties {
private String path; // the names must match to those defined in the properties file
private String passwd;
... getters, setters
}
In the class marked with #Configuration (the one where you create #Bean public APNsFactory apnsFactory()) do the following:
#Configuration
// Note the following annotation:
#EnableConfigurationProperties(MyAppKeyStoreConfigProperties.class)
public class MyConfiguration {
// Note the injected configuration parameter
#Bean public APNsFactory apnsFactory(MyAppKeyStoreConfigProperties config) {
APNsFactory f = new APNsFactory();
f.setProductionKeystorePath(config.getKeyPath());
and so on
}
}
I've intentionally didn't show the separation between production/dev stuff.
In spring boot you have profiles so that the same artifact (WAR, JAR whatever) can be configured to run with different profile and depending on that the corresponding properties will be read.
Example:
If you're running with prod profile, then in addition to application.properties that will be loaded anyway, you can put these keystore related definitions to application-prod.properties (the suffix matches the profile name) - spring boot will load those automatically. The same goes for dev profile of course.
Now I haven't totally understand the "bonus points" task :) This mechanism is spring boot proprietary way of dealing with configuration. In "standalone" server it should still have a WAR with spring boot inside so it will use this mechanism anyway. Maybe you can clarify more, so that I / our colleagues could provide a better answer
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.
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.
I want to use Spring Boot with Legacy database and use hibernate for the same. I have to access both DB2 and Teradata as data sources.I would like to know if this is possible ? I'm a newbie to Spring , SpringBoot and have no idea how to configure data sources , should i still need multiple xml configs etc. The demos in spring io sites are good but they dont deal with any of my requirement. Kindly point me in the right direction.
In Spring Boot it is very easy to configure multiple datasources. This part of the documentation describes the procedure in detail.
In essence, all you need to do is have the connection properties in a place where Spring boot can locate them (the easiest place is application.properties) and then configure the beans. The code would look like:
application.properties
datasource.primary.url=jdbc:mysql://localhost/test
datasource.primary.username=dbuser
datasource.primary.password=dbpass
datasource.secondary.url=jdbc:mysql://localhost/test2
datasource.secondary.username=dbuser2
datasource.secondary.password=dbpass2
Spring configuration file
#Bean
#Primary
#ConfigurationProperties(prefix="datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
#Bean
#ConfigurationProperties(prefix="datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
You will notice that no XML configuration is used which the preferred style these days. Actually using Spring Boot means that you don't have to write almost any configuration :)