Configuring the database properties from outside of intellij - java

I want to ask as currently I have my database properties like username and password inside the persistence layer in the intellij. But I want to place it somewhere outside so if someone wants to change the password or any configuration inside database he should not have to dig inside my current structure. Now my structure is persistence then main then resources and then dbconfig properties so is there any way I can do it.

You can create a file app.properties in your resources folder with all database information you need:
# Datasource details
testapp.db.driver = org.h2.Driver
testapp.db.url = jdbc:h2:mem:test
testapp.db.username = username
testapp.db.password = password
Then you can refer to it in your Java code as:
#Configuration
#PropertySource("app.properties")
public class DataConfig {
#Autowired
private Environment env;
#Bean
public DataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName(env.getProperty("testapp.db.driver"));
ds.setUrl(env.getProperty("testapp.db.url"));
ds.setUsername(env.getProperty("testapp.db.username"));
ds.setPassword(env.getProperty("testapp.db.password"));
return ds;
}
}

Related

Java Enviroment class problem with getting properties

I created new Enviroment in SpringConfig file:
private final Environment environment;
#Autowired
public SpringConfig(ApplicationContext applicationContext, Environment environment) {
this.applicationContext = applicationContext;
this.environment = environment;
}
And file database.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/first_db
username=root
password=1234
Created dataSource bean
#Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(Objects.requireNonNull(environment.getProperty("driver")));
dataSource.setUrl(environment.getProperty("url"));
dataSource.setUsername(environment.getProperty("username"));
dataSource.setPassword(environment.getProperty("password"));
return dataSource;
}
It gave me error and I checked what enviroment.getProperty returns me. It showed me:
com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/first_db
PC // my PC name
1234
So why does enviroment returns me my Pc's name? How do I know what properties are already assigned?
Agree with the comment from Alex R about the %USERNAME% variable having a higher priority. Using a prefix for values in your .properties files is a good practice and will help you avoid a lot of conflicts like this.
Alternatively, you can use the ResourceBundle class.
With database.properties at the top level of your Java resources (if not at the top level, just provide the path to the database.properties file), the snippet below will give you what you need:
final ResourceBundle bundle = ResourceBundle.getBundle("database");
final String username = bundle.getString("username");
final String password = bundle.getString("password");

Spring - Change schema connection for persistent_logins

I am working on a Spring Boot web application and I am implementing the "Remember me" function.
I defined in my Web Security Configuration this:
http.authorizeRequests().and()
.rememberMe().tokenRepository(this.persistentTokenRepository())
.tokenValiditySeconds(1 * 24 * 60 * 60); // 24h
and
#Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl db = new JdbcTokenRepositoryImpl();
db.setDataSource(dataSource);
return db;
}
The problem is that when I flag the option on the html page, Spring try to add a token in the default schema of my database -> "public".
Is there any way to change the default schema for that option? Everything else is linked correctly on the right schema through this property:
spring.jpa.properties.hibernate.default_schema=another_schema_name
I tried to make a personal implement of the class JdbcTokenRepositoryImpl but I can't find a way to change the schema. I looked it up online but I didn't find nothing..
Thank you
Regards,
Mohamad
You may initialize differently your dataSource variable what you use in your PersistentTokenRepository bean. Most data sources support schema setting. For instance Spring's org.springframework.jdbc.datasource.DriverManagerDataSource :
#Bean(name = "dataSource")
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
// ... tipicly set username, password, driver class name, jdbc Url
dataSource.setSchema(schema);
return dataSource;
}
You could control the schema through the mentioned property: (spring.jpa.properties.hibernate.default_schema)
#Value("${spring.jpa.properties.hibernate.default_schema}")
private String schema;

how to extenalize db connection stuff

I am new in Java Spring framework and related technologies. I want to externalize the database stuff like connection string, username and password in a different file so that incase there is change in the database username and or password, I can go an change without touching the war file and recompiling the application. Right now all the application I am supporting was hardcoded
Any help will be appreciated. NB we are oracle shop
Use properties files.
This is an example of configuring Oracle database:
spring.datasource.url=jdbc:oracle:thin:#localhost:1522:orcl
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver.class=oracle.jdbc.driver.OracleDriver
and in your config class file use something like:
#Primary
public DataSource userDataSource() {
DriverManagerDataSource dataSource
= new DriverManagerDataSource();
dataSource.setDriverClassName(
env.getProperty("spring.datasource.driver.class"));
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));
dataSource.setPassword(env.getProperty("spring.datasource.password"));
return dataSource;
}
Depending on your needs, there are a lot of tutorials on the web. Check for example:
https://www.programmergate.com/spring-boot-jpa-hibernate-oracle/

Obtaining datasource in both JNDI and non-JNDI environment

I have a modular application with one DAO implementation module that allows interacting with a database through JDBC. When I wrote the DAO module, I expected to get my DataSource via JNDI since the module was used until now as part of a web application. However, I need to use this same DAO module in a standalone application and therefore the datasource can't be obtained via JNDI.
Here is how I obtain my datasource:
#Bean(destroyMethod = "close")
public DataSource dataSource() throws Exception {
return new JndiDataSourceLookup().getDataSource("java:comp/env/jdbc/mydatasource");
}
I thought about the possibility to define the data source in the upper modules as follows:
For the web app module, same as previous code snippet.
For the standalong module, as follows:
#Bean(destroyMethod = "close")
public DataSource dataSource() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driverClassName);
dataSource.setJdbcUrl(jdbcUrl);
dataSource.setUser(username);
dataSource.setPassword(password);
return dataSource;
}
I'm looking for a better approach if there is one...

Mock the Spring Environment Object In Junit with #ContextConfiguration

I have got a test like this
RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = { AppConfig.class, TestConfig.class})
public class MyTest {
........
}
The AppConfig is the main config for my app, the TestConfig is the test config
which loads the test properties
#Configuration
#PropertySource("classpath:test_dev.properties")
public class DevConfig {
#Bean
public DataSource getDataDataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(env.getProperty("driverclass"));
dataSource.setUrl(env.getProperty("url"));
dataSource.setUsername(env.getProperty("username"));
dataSource.setPassword(env.getProperty("password"));
return dataSource;
}
}
problem is The test_dev.properties file has a encrypted password field
driverclass = ojdbc:xxx
url = xxxxxx
username = abc
password = #'"#~£$%
I need to use decryptor to decrypt it, then the decrypted password on the env object. thus env.get("password"), the real password will return
so my question is how can I mock the Environment object before the DataSource object gets crated.
in my case, I wanted to mock the password filed on the datasource object
I first let the datasource bean initialize, then in my integration test autowired the mybatis Environment (don't be confused with springs environment).
from the env you can get the datasource.
from the #beforetest section, the trick is to use Reflectiontestutils.setfield to set the password field on the datasource
alternatively you could inject the entire datasource on the target environment
but I didn't try
the key motivation for using Spring is to easily inject mock objects.

Categories

Resources