I'm using the Quartz component from Apache Camel to run some scheduled routes. I would like to configure the JDBC JobStore for the scheduler, and was able to set the necessary properties in a quartz.properties
file, as shown below.
org.quartz.jobStore.useProperties = true
org.quartz.jobStore.dataSource=myDataSource
org.quartz.jobStore.tablePrefix = II_QRTZ_
org.quartz.dataSource.myDataSource.driver = com.ibm.db2.jcc.DB2Driver
org.quartz.dataSource.myDataSource.URL = url
org.quartz.dataSource.myDataSource.user = example-user
org.quartz.dataSource.myDataSource.password = example-pwd
However, we need to set different data sources/credentials based on different server environments (dev vs test vs prod). I can't seem to find a way to dynamically set the data source from the properties file.
We already had a datasource bean that would connect to the correct database based on the environment, and so I tried referencing to that after annotating it with the @QuartzDataSource
annotation. Ideally this would have been the cleanest solution. For example,
DataSourceConfig.java
@Bean(name="myDataSource")
@QuartzDataSource
@ConfigurationProperties(prefix="org.quartz.mydatasource")
@Autowired
public DataSource myDataSource(@Qualifier("applicationProps") BasePropReader applicationProperties) {
String connectionString = (String) applicationProperties.get("spring.datasource.connection.url");
return buildDataSource(applicationProperties, "example-user", "example-pwd", "com.ibm.db2.jcc.DB2Driver", connectionString);
}
/////////////////////////
quartz.properties
org.quartz.jobStore.useProperties = true
org.quartz.jobStore.dataSource=myDataSource
org.quartz.jobStore.tablePrefix = II_QRTZ_
In our web applications we did something similar as the above, where in the quartz properties file we could refer to data sources that were already configured by environment by a JNDI url. For example:
org.quartz.jobStore.useProperties = true
org.quartz.jobStore.dataSource=myDataSource
org.quartz.jobStore.tablePrefix = II_QRTZ_
org.quartz.dataSource.myDataSource.jndiURL=java:/MYDATASOURCE
We also tried setting the properties from application.properties
but that didn't work - I suspect because we're using the Quartz component from Camel.
I've tried reading up on reading environment variables from the properties file itself (via this thread), but all the variables I read end up as empty strings.
Is this even possible via Apache Camel's Quartz? Ideally we would like to continue using Camel as it saves us a lot of refactoring.
EDIT: I'm also trying to configure the quartz component by defining it as a bean in the context xml file and then passing a quartz property file based on the environment/spring active profile, but the quartz component doesn't seem to be picking up on that either. for example:
<bean id="quartz" class="org.apache.camel.component.quartz.QuartzComponent">
<property name="propertiesFile" value="org/quartz/quartz-dev.properties"/>
</bean>
I ended up creating a QuartzConfig.java
file. From there I created the quartz
bean I loaded the easily configurable properties with my existing properties file, and then sourced the environment/secret properties from code. It went something like this
@Bean("quartz")
public QuartzComponent quartzComponent() {
QuartzComponent quartzComponent = new QuartzComponent();
Properties quartzPropertiesObj = quartzProperties.getProperties();
String env = "dev"; // however you get your environment
// applicationProperties was an instance of our class that allowed us to get our secrets by environment
quartzPropertiesObj.setProperty("org.quartz.dataSource.dataSourceDB2.URL", applicationProperties.get("spring.datasource.connection.url").toString());
quartzPropertiesObj.setProperty("org.quartz.dataSource.dataSourceDB2.user", applicationProperties.get("user" + env).toString());
quartzPropertiesObj.setProperty("org.quartz.dataSource.dataSourceDB2.password", applicationProperties.get("pwd" + env).toString());
quartzComponent.setProperties(quartzPropertiesObj);
LOG.info("Quartz Config: Quartz properties file loaded into quartz component.");
return quartzComponent;
}