How to have a datasource configuration as external Jar in spring boot - java

I want to create a spring boot JAR(standalone) which contains Java data source configuration and I want to utilize that JAR in other micro services for connecting to DB (instead of giving credentials in each application.properties file). I have succeeded in creating the JAR with java data source configuration. But when I add that jar to any service, the service is still expecting me to provide credentials in application.properties.
Could anyone help on how to have data source configuration in an external JAR and use that jar in service for db connection

You could implement a single properties file to take the data source credentials from there (you don't necessarily have to use Spring Boot's default application.properties) and then the easiest way to get the connection is by defining a DataSource factory method and placing it inside a class annotated with the #Configuration annotation:
#Configuration
public class DataSourceConfig {
#Bean
public DataSource getDataSource() {
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.driverClassName("org.h2.Driver");
dataSourceBuilder.url("jdbc:h2:mem:test");
dataSourceBuilder.username("SA");
dataSourceBuilder.password("");
return dataSourceBuilder.build();
}
}
This manually generates the connection to the data source that you are indicating, just make sure that all the necessary libraries for the connection are being imported correctly in your pom.xml file if you are using Maven.

Related

Binding application.properties to a class from external library in Spring

Let's say I have an external jar (that supposed to work in spring boot env) that has this simple class:
#Component
#ConfigurationProperties("test")
public class NetworkConfig {
//getters/setters
...
}
Now I use this jar as dep in a Spring project (NOT Spring Boot!!).
I have an application.properties file in that project and want to load properties from it to this class and it should be available in a context. How would I do it?
I also need to mention that external jar is my lib and I can modify it if needed.
#ConfigurationPropertiesScan ("path_to_property")

loading datasource config from AWS S3 thru archaius in SpringBoot 2.1.1.RELEASE

My springBoot app loads datasource correctly from application.properties/yml in classpath but I want to externalize datasource config so I have been trying to use archaius to load PolledConfigurationSource from S3 with following code
I have multiple datasources to connect.
PolledConfigurationSource source = new S3ConfigurationSource(s3Client , bucketName, PROPERTYFILE);
DynamicConfiguration configuration = new DynamicConfiguration(source,
new FixedDelayPollingScheduler(100, 60000 ,true));
ConfigurationManager.install(configuration);
I do have config class annotated with #Configuration as well as below class.
Here is how I m creating Datasource / JDBCTemplate
#Bean(name="datasource-1")
#ConfigurationProperties(prefix="spring.datasource.datasource-1")
public Datasource initializeDatasource1(){return DatasourceBuilder.create().build(); }
#Bean(name="datasource-2")
#ConfigurationProperties(prefix="spring.datasource.datasource-2")
public Datasource initializeDatasource2(){return DatasourceBuilder.create().build(); }
Loading archaius with SpringBoot 1.x.x was not a problem before but with SpringBoot 2.x.x plus a few dependencies from spring cloud , it doesn't work and I get exception for "jdbcUrl / url" not defined if I move config from application.properties.

Where to place a configuration file outside application war

I have a Spring application that at startup needs to read some basic properties from a file but nothing sensitive (timeout values, directory locations, etc.). It needs to be edited before starting the application depending on the desired target server.
My first easy idea was to place the file under home target server, then load it into Spring
<context:property-placeholder location="file:${JBOSS_HOME}/standalone/config/application.properties" />.
I found other sources mentioning the usage of System properties or JBoss modules.
Are there any advantages/disadvantages for using one on another? What else should I consider when choosing the appropriate one in my case?
In my understanding Spring looks by default properties file in your app directory, or you can register a properties file with XML config or Java config (Annotations):
<context:property-placeholder location="classpath*:my.properties"/>
Then you refer to the properties in your beans:
#Component
class MyClass {
#Value("${my.property.name}")
private String[] myValues;
}
or
#Configuration
#PropertySource("classpath:/com/myco/app.properties")
public class AppConfig {
#Autowired
Environment env;
#Bean
public TestBean testBean() {
TestBean testBean = new TestBean();
testBean.setName(env.getProperty("testbean.name"));
return testBean;
}
}
the properties file can be updated at any time (just stoping serv) in the apps server, tomcat, jboss, etc.
note sure if that's what you want,

Moving hibernate properties configuration file outside of project?

Is it possible to move a hibernate configuration file containing the db connection details outside of the hibernate project and connect to it?
My current configuration is as follows, but I would like to move my file from outside the project and still connect to my data sources. How can I do so?
#Configuration
#EnableTransactionManagement
#PropertySource({"classpath:hibernate.properties"})
#EnableJpaRepositories(basePackages = "com.my.packages", entityManagerFactoryRef = "schemaOneManagerFactory", transactionManagerRef = "schemaOneTransactionManager")
public class SchemaOneDataSourceConfig
{
//configuration methods
}
Do I need to make a change to line: #PropertySource({"classpath:hibernate.properties"}) ?
From the JavaDocs of PropertySource
Indicate the resource location(s) of the properties file to be loaded. For example, "classpath:/com/myco/app.properties" or "file:/path/to/file".
You just need to change a prefix to file:
#PropertySource({"file:/path/to/hibernate.properties"})
If you are using Spring Boot, you can put the properties in application.properties and you can have that file in your JAR, but also override it by putting it in a config sub-folder (relative to your running directory).
See http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-application-property-files for more info.

Changing Spring configuration file?

I have a class that reads some properties from this application.properties and add them as configuration properties to the java/spring application. What I am trying to achieve now is this: I do deliver the package to the client, and inside this application.properties there are database connection details, so the client can change them. The question is, can this be done in the stage after we create the .war file. So basically the client goes and changes the configuration file, and on deploy these configs will be used, or that must be done prior building the .war file. Attached you will see my solution:
//application.properties
#DB properties:
db.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
db.url=jdbc:sqlserver://ip\\instance:port;databaseName=db_name
db.username=db_username
db.password=db_pass
//WebConfig.java
#Configuration
#PropertySource("classpath:application.properties")
public class WebAppConfig {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
#Resource
private Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return dataSource;
}
The usual way to do this is with JNDI. It's a directory (lookup) service specifically designed for providing database connections, properties, and other runtime configuration data to packaged Java EE applications.
You can put your connection information in your server (tomcat, jboss or other). There are specific files to do that (in tomcat it is the context.xml file for example).
After, you can use this information in your application using datasource. So, when the war file is deployed on the server, the connection information are known.
Instead of packaging up application.properties, why not have it as an externally referenced file, e.g.:
#PropertySource("file:/external/path/to/application.properties")
This would allow clients to change the file without modifying your packaged distribution.
Common classpath way
In a most servlet containers there is common folder where you can store classpath resources available for all web applications. You can use this folder for configuration purposes. Change your build process to do not include application.properties into the final war file. You can prepare for example another maven project for such config files aside. Provide a copy of application.properties in your deployment documentation. During deployment you need to adjust properties in provided application.properties file according to your environment and then place it in a folder that is common for all webapplications. For Tomcat it is $CATALINA_HOME/lib folder. During development you can add a folder with this property file to server classpath via launch configuration. As a downside you can have naming conflicts between two webapps that use the same approach (two application.properties files).

Categories