Configure spring Cassandra with multiple keyspace - spring

I am trying to create multiple spring Cassandra sessions in my spring boot application
One session connecting to primary Keysapce as configured in spring.data.cassandra.keyspace-name
One session connecting to keyspaceB
Configuration
#Configuration
// all the sessions have spring Cassandra configuration except keyspace
public class CassandraConfig extends AbstractCassandraConfiguration {
#Value("${spring.data.cassandra.keyspace-name}")
private String primaryKeysapce;
#Value("${item.keysapce.b:keyspaceB}")
private String keyspaceB;
#Override
#Primary
#Bean
public CassandraSessionFactoryBean session() throws ClassNotFoundException {
return super.session();
}
#Bean("cassandraOperations")
#Primary
public CassandraOperations cassandraOperations() throws ClassNotFoundException {
return new CassandraTemplate(session().getObject(), cassandraConverter());
}
#Bean("sessionB")
public CassandraSessionFactoryBean sessionB() throws ClassNotFoundException {
CassandraSessionFactoryBean session = super.session();
session.setKeyspaceName(keyspaceB);
return session;
}
#Bean("cassandraOperationsB")
public CassandraOperations cassandraOperationsB() throws ClassNotFoundException {
return new CassandraTemplate(sessionB().getObject(), cassandraConverter());
}
#Override
protected String getKeyspaceName() {
return primaryKeysapce;
}
}
application.properties
spring.data.cassandra.keyspace-name = primary_keysapce
spring.data.cassandra.username = xyz
spring.data.cassandra.password = abcd
spring.data.cassandra.contact-points=myhost.company.com
In My code,
#SpringBootApplication
#EnableAutoConfiguration
public class DemoApplication implements CommandLineRunner {
#Resource(name = "cassandraOperationsB")
CassandraOperations cassandraOperationsB;
// hall point to primary one as per spring properties
#Autowired
CassandraOperations cassandraOperations;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Though it works as expected with keyspaces in localhost.
But this is not working as expected. It is not taking spring cassandra properties in application.properties. It is always pointing to default properties.
I am tring to connect to cassandra on myhost.company.com, but my application is connecting to localhost all the time.
Can some one help me whats wrong here?

Related

Using multiple keyspaces working with Spring Boot 2.4.0/Spring Data Cassandra 3.1.1

I am working on a spring boot application that uses two different keyspaces in a cassandra database. In the process of trying to upgrade from spring boot 2.1.7-RELEASE to version 2.4.0, I have found that my java-based configuration no longer works. It seems to be much more difficult than before to extend AbstractCassandraConfiguration due to creation of multiple beans of the same type and ambiguity caused by having multiple cassandra/cql session factories.
All of the examples of a multi-keyspace configuration I have found online are for older versions of Spring Boot, so I am wondering if anyone has figured out a clean way to get this working in the more recent versions?
I migrated my project to using spring-data-cassandra 3.x. I resolved issues with conflicting beans by overriding CqlSessionFactoryBean bean in configurations and adding #Primary annotation for primary keyspace cassandra session bean. My project is using following gradle dependencies:
compile group: 'org.springframework.data', name: 'spring-data-cassandra', version: '3.0.5.RELEASE'
compile group: 'com.datastax.oss', name: 'java-driver-core', version: '4.6.1'
Cassandra configurations classes:
public abstract class AbstractCassandraSourceConfiguration extends AbstractCassandraConfiguration {
#Autowired
protected Environment environment;
#Override
protected int getPort() {
return Integer.parseInt(environment.getProperty("cassandra.port"));
}
#Override
protected String getContactPoints() {
return environment.getProperty("cassandra.contactpoints");
}
#Override
protected String getLocalDataCenter() {
return environment.getProperty("cassandra.data.center",
"datacenter1");
}
#Override
protected abstract String getKeyspaceName();
}
#Configuration
#EnableCassandraRepositories(basePackages = "com.data.cassandra.primary.repository",
repositoryBaseClass = CassandraRepositoryWithTtlWithTimestampImpl.class)
public class PrimaryCassandraSourceConfiguration extends AbstractCassandraSourceConfiguration {
#Override
protected String getKeyspaceName() {
return "primary_keyspace";
}
#Override
#Bean(name = "cassandraSession")
#Primary
public CqlSessionFactoryBean cassandraSession() {
final CqlSessionFactoryBean session = super.cassandraSession();
session.setKeyspaceName(getKeyspaceName());
return session;
}
#Bean(name = "cassandraTemplate")
public CassandraAdminOperations cassandraTemplate(
#Qualifier("cassandraSession") final CqlSessionFactoryBean session) {
return new CassandraAdminTemplate(session.getObject(),
cassandraConverter());
}
}
#Configuration
#EnableCassandraRepositories(cassandraTemplateRef = "secondaryCassandraTemplate",
basePackages = "com.data.cassandra.secondary.repository",
repositoryBaseClass = CassandraRepositoryWithTtlWithTimestampImpl.class)
public class SecondaryCassandraSourceConfiguration extends AbstractCassandraSourceConfiguration {
#Override
protected String getKeyspaceName() {
return "secondary_keyspace";
}
#Override
#Bean(name = "secondaryCassandraSession")
public CqlSessionFactoryBean cassandraSession() {
final CqlSessionFactoryBean session = super.cassandraSession();
session.setKeyspaceName(getKeyspaceName());
return session;
}
#Bean(name = "secondaryCassandraTemplate")
public CassandraAdminOperations cassandraTemplate(
#Qualifier("secondaryCassandraSession") final CqlSessionFactoryBean session) {
return new CassandraAdminTemplate(session.getObject(),
cassandraConverter());
}
}
I'm using spring-data-cassandra=3.0.4.RELEASE.
In my project I needed to connect to 2 keyspaces from 1 DC each. What I've configured in Cassandra #Configuration Bean is 1 Bean of Session, SessionFactoryFactoryBean and CassandraOperations per keyspace.

Not monitor a specific Datasource for Health Check

I would like to know if exist some way to disable the monitoring of a Specific DataSource by SpringBoot Actuator.
Scenario:
One Microservice uses 3 Datasources but for some Business Reason, one Datasource of them, it is not necessary to be monitored by Spring Boot Health Indicator.
How to disable the monitoring of one specific DataSource?
Many thanks in advance
Juan Antonio
I think you'd have to disable the default datasources health indicator, which you can do with this property:
management.health.db.enabled=false
And then configure your own health indicators which only address the datasources you are interested in, something like this perhaps:
#Autowired
private DataSource dataSourceA;
#Autowired
private DataSource dataSourceB;
#Bean
public DataSourceHealthIndicator dataSourceHealthIndicatorA() {
return new DataSourceHealthIndicator(dataSourceA);
}
#Bean
public DataSourceHealthIndicator dataSourceHealthIndicatorB() {
return new DataSourceHealthIndicator(dataSourceB);
}
Or, alternatively write your own 'multiple datasources health indicator' by extending AbstractHealthIndicator and injecting into it only the Datasources you are interested in monitoring. Any Spring bean of type HealthIndicator will be automatically registered with the health actuator so you only have to let Spring create your custom HealthIndicator and it will be exposed by the actuator.
For background, you can see how Spring configures the default datasource health check in: org.springframework.boot.actuate.autoconfigure.DataSourcesHealthIndicatorConfiguration.
Since Spring Boot 2, you can filter datasources from the health check by overriding org.springframework.boot.actuate.autoconfigure.jdbcDataSourceHealthIndicatorAutoConfiguration. In the example below datasources without a pool name is filtered.
#Configuration
public class YourDataSourceHealthIndicatorAutoConfiguration extends DataSourceHealthIndicatorAutoConfiguration {
public NonMigrationDataSourceHealthIndicatorAutoConfiguration(Map<String, DataSource> dataSources, ObjectProvider<DataSourcePoolMetadataProvider> metadataProviders) {
// Filter out datasources without a pool name
super(filterDataSources(dataSources), metadataProviders);
}
private static Map<String, DataSource> filterDataSources(Map<String, DataSource> dataSources) {
return dataSources.entrySet().stream()
.filter(dataSourceEntry -> {
if (dataSourceEntry.getValue() instanceof HikariDataSource) {
HikariDataSource hikariDataSource = (HikariDataSource) dataSourceEntry.getValue();
return hikariDataSource.getPoolName() != null;
} else {
return true;
}
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
}
I think the easiest way will be the following
#Configuration
public class DatasourceHealthCheckConfig extends DataSourceHealthContributorAutoConfiguration {
public DatasourceHealthCheckConfig(Map<String, DataSource> dataSources, ObjectProvider<DataSourcePoolMetadataProvider> metadataProviders) {
super(dataSources, metadataProviders);
}
#Override
public HealthContributor dbHealthContributor(Map<String, DataSource> dataSources) {
// remove the required datasource from the dataSources map by its name
return super.dbHealthContributor(dataSources);
}
}
Solution for Spring Boot 2.1.2. If you wish to disable healthcheck only for specific datasource. Bit hecky, but worked for me.
#Configuration
public class DatasourceHealthCheckConfig extends DataSourceHealthIndicatorAutoConfiguration {
public DatasourceHealthCheckConfig(ObjectProvider<Map<String, DataSource>> dataSources,
ObjectProvider<DataSourcePoolMetadataProvider> metadataProviders) {
super(filterDataSources(dataSources), metadataProviders);
}
private static ObjectProvider<Map<String, DataSource>> filterDataSources(ObjectProvider<Map<String, DataSource>> dataSources) {
final Map<String, DataSource> map = dataSources.getObject();
map.remove("specificDataSource"); // name of datasource for removal
return new ObjectProvider<>() {
#Override
public Map<String, DataSource> getObject(Object... args) throws BeansException {
return map;
}
#Override
public Map<String, DataSource> getIfAvailable() throws BeansException {
return map;
}
#Override
public Map<String, DataSource> getIfUnique() throws BeansException {
return map;
}
#Override
public Map<String, DataSource> getObject() throws BeansException {
return map;
}
};
}
}

Spring boot mongoDB autowired null repository

I am experimenting with spring and MongoDB.
In my project I have a repository and a service which has a scheduled method.
The problem is, that the repository doesn't get autowired, it is always null.
Autowire works correctly in the main application class (tested it by implementing CommandLineRunner )
The service is found by componentScan (the constructor is called)
Am I missing somethig?
directory
MachineApplication.java
#SpringBootApplication
#EnableScheduling
public class MachineApplication {
public static void main(String[] args) {
SpringApplication.run(MachineApplication.class, args);
}
}
Worker.java
#Service
public class Worker {
#Autowired
private LineDataRepository lineDataRepository;
#Autowired
private LineRepository lineRepository;
...
public Worker() {
System.out.println("--------------------------------");
System.out.println(lineDataRepository);//null
System.out.println(lineRepository);//null
}
}
LineDataRepository
#Repository
public interface LineDataRepository extends MongoRepository<LineData, String> {
}
Add #EnableMongoRepositories to the MachineApplication to let it detect Mongo repositories.
See here
I think you haven't create mongoDbFactory and mongoTemplate bean, without this bean no connection will be made to your mongoDB. Below is the configuration:
#Configuration
public class MongoConfiguration {
#SuppressWarnings("deprecation")
#Bean
public MongoDbFactory mongoDbFactory() throws Exception {
UserCredentials userCredentials = new UserCredentials("admin", "password");
return new SimpleMongoDbFactory(new Mongo(), "myspring", userCredentials);
}
#Bean
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongoDbFactory());
}
}

Spring Boot Apache Camel Routes testing

I have a Springboot application, where I have some Camel routes configured.
public class CamelConfig {
private static final Logger LOG = LoggerFactory.getLogger(CamelConfig.class);
#Value("${activemq.broker.url:tcp://localhost:61616}")
String brokerUrl;
#Value("${activemq.broker.maxconnections:1}")
int maxConnections;
#Bean
ConnectionFactory jmsConnectionFactory() {
PooledConnectionFactory pooledConnectionFactory = new PooledConnectionFactory(new ActiveMQConnectionFactory(brokerUrl));
pooledConnectionFactory.setMaxConnections(maxConnections);
return pooledConnectionFactory;
}
#Bean
public RoutesBuilder route() {
LOG.info("Initializing camel routes......................");
return new SpringRouteBuilder() {
#Override
public void configure() throws Exception {
from("activemq:testQueue")
.to("bean:queueEventHandler?method=handleQueueEvent");
}
};
}
}
I want to test this route from activemq:testQueue to queueEventHandler::handleQueueEvent.
I tried different things mentioned here http://camel.apache.org/camel-test.html, but doesn't seem to get it working.
I am trying to do something like this:
#RunWith(SpringRunner.class)
#SpringBootTest(classes = {CamelConfig.class, CamelTestContextBootstrapper.class})
public class CamelRouteConfigTest {
#Produce(uri = "activemq:testQueue")
protected ProducerTemplate template;
#Test
public void testSendMatchingMessage() throws Exception {
template.sendBodyAndHeader("testJson", "foo", "bar");
// Verify handleQueueEvent(...) method is called on bean queueEventHandler by mocking
}
But my ProducerTemplate is always null. I tried auto-wiring CamelContext, for which I get an exception saying it cannot resolve camelContext. But that can be resolved by adding SpringCamelContext.class to #SpringBootTest classes. But my ProducerTemplate is still null.
Please suggest. I am using Camel 2.18 and Spring Boot 1.4.
In Camel 2.22.0 and ongoing, which supports Spring Boot 2 you can use the following template to test your routes with Spring Boot 2 support:
#RunWith(CamelSpringRunner.class)
#SpringBootTest(webEnvironment = WebEnvironment.NONE, classes = {
Route1.class,
Route2.class,
...
})
#EnableAutoConfiguration
#DisableJmx
#DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class RouteTest {
#TestConfiguration
static class Config {
#Bean
CamelContextConfiguration contextConfiguration() {
return new CamelContextConfiguration() {
#Override
public void beforeApplicationStart(CamelContext camelContext) {
// configure Camel here
}
#Override
public void afterApplicationStart(CamelContext camelContext) {
// Start your manual routes here
}
};
}
#Bean
RouteBuilder routeBuilder() {
return new RouteBuilder() {
#Override
public void configure() {
from("direct:someEndpoint").to("mock:done");
}
};
}
// further beans ...
}
#Produce(uri = "direct:start")
private ProducerTemplate template;
#EndpointInject(uri = "mock:done")
private MockEndpoint mockDone;
#Test
public void testCamelRoute() throws Exception {
mockDone.expectedMessageCount(1);
Map<String, Object> headers = new HashMap<>();
...
template.sendBodyAndHeaders("test", headers);
mockDone.assertIsSatisfied();
}
}
Spring Boot distinguishes between #Configuration and #TestConfiguration. The primer one will replace any existing configuration, if annotated on a top-level class, while #TestConfiguration will be run in addition to the other configurations.
Further, in larger projects you might run into auto-configuration issues as you can't rely on Spring Boot 2 to configure your custom database pooling or what not correctly or in cases where you have a specific directory structure and the configurations are not located within a direct ancestor directory. In that case it is proabably preferable to omit the #EnableAutoConfiguration annotation. In order to tell Spring to still auto-configure Camel you can simply pass CamelAutoConfiguration.class to the classes mentioned in #SpringBootTest
#SpringBootTest(webEnvironment = WebEnvironment.NONE, classes = {
Route1.class,
Route2.class,
RouteTest.Config.class,
CamelAutoConfiguration.class
}
As no automatic configuration is performed, Spring won't load the test configuration inside your test class nor initialize Camel as well. By adding those configs to the boot classes manually Spring will do it for you.
For one route with MQ and Spring Boot like this:
#Component
public class InboundRoute extends RouteBuilder {
#Override
public void configure() {
JaxbDataFormat personDataFormat = new JaxbDataFormat();
personDataFormat.setContextPath(Person.class.getPackage().getName());
personDataFormat.setPrettyPrint(true);
from("direct:start").id("InboundRoute")
.log("inbound route")
.marshal(personDataFormat)
.to("log:com.company.app?showAll=true&multiline=true")
.convertBodyTo(String.class)
.inOnly("mq:q.empi.deim.in")
.transform(constant("DONE"));
}
}
I use adviceWith in order to replace the endpoint and use only mocks:
#RunWith(CamelSpringBootRunner.class)
#UseAdviceWith
#SpringBootTest(classes = InboundApp.class)
#MockEndpoints("mock:a")
public class InboundRouteCamelTest {
#EndpointInject(uri = "mock:a")
private MockEndpoint mock;
#Produce(uri = "direct:start")
private ProducerTemplate template;
#Autowired
private CamelContext context;
#Test
public void whenInboundRouteIsCalled_thenSuccess() throws Exception {
mock.expectedMinimumMessageCount(1);
RouteDefinition route = context.getRouteDefinition("InboundRoute");
route.adviceWith(context, new AdviceWithRouteBuilder() {
#Override
public void configure() {
weaveByToUri("mq:q.empi.deim.in").replace().to("mock:a");
}
});
context.start();
String response = (String) template.requestBodyAndHeader("direct:start",
getSampleMessage("/SimplePatient.xml"), Exchange.CONTENT_TYPE, MediaType.APPLICATION_XML);
assertThat(response).isEqualTo("DONE");
mock.assertIsSatisfied();
}
private String getSampleMessage(String filename) throws Exception {
return IOUtils
.toString(this.getClass().getResourceAsStream(filename), StandardCharsets.UTF_8.name());
}
}
I use the following dependencies: Spring Boot 2.1.4-RELEASE and Camel 2.23.2. The complete source code is available on Github.
This is how I did this finally:
#RunWith(SpringRunner.class)
public class CamelRouteConfigTest extends CamelTestSupport {
private static final Logger LOG = LoggerFactory.getLogger(CamelRouteConfigTest.class);
private static BrokerService brokerSvc = new BrokerService();
#Mock
private QueueEventHandler queueEventHandler;
#BeforeClass
// Sets up an embedded broker
public static void setUpBroker() throws Exception {
brokerSvc.setBrokerName("TestBroker");
brokerSvc.addConnector("tcp://localhost:61616");
brokerSvc.setPersistent(false);
brokerSvc.setUseJmx(false);
brokerSvc.start();
}
#Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new CamelConfig().route();
}
// properties in .yml has to be loaded manually. Not sure of .properties file
#Override
protected Properties useOverridePropertiesWithPropertiesComponent() {
YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
try {
PropertySource<?> applicationYamlPropertySource = loader.load(
"properties", new ClassPathResource("application.yml"),null);// null indicated common properties for all profiles.
Map source = ((MapPropertySource) applicationYamlPropertySource).getSource();
Properties properties = new Properties();
properties.putAll(source);
return properties;
} catch (IOException e) {
LOG.error("application.yml file cannot be found.");
}
return null;
}
#Override
protected JndiRegistry createRegistry() throws Exception {
JndiRegistry jndi = super.createRegistry();
MockitoAnnotations.initMocks(this);
jndi.bind("queueEventHandler", queueEventHandler);
return jndi;
}
#Test
// Sleeping for a few seconds is necessary, because this line template.sendBody runs in a different thread and
// CamelTest takes a few seconds to do the routing.
public void testRoute() throws InterruptedException {
template.sendBody("activemq:productpushevent", "HelloWorld!");
Thread.sleep(2000);
verify(queueEventHandler, times(1)).handleQueueEvent(any());
}
#AfterClass
public static void shutDownBroker() throws Exception {
brokerSvc.stop();
}
}
Did you try using Camel test runner?
#RunWith(CamelSpringJUnit4ClassRunner.class)
If you are using camel-spring-boot dependency, you may know that it uses auto configuration to setup Camel:
CamelAutoConfiguration.java
It means that you may also need to add #EnableAutoConfiguration to your test.

Spring jdbc configuration

I have been trying to implement a web service using spring. This webservice will provide data access to a mySQL database using JDBC. I am trying to not use any xml configuration files, so I have come across a problem trying to connect to the database.
I am following the tutorial: http://spring.io/guides/tutorials/rest/ but I changed a few things along the way.
Now that I am trying to implement the connection with the database I get an error when trying to execute the tomcat instance, and I guess the problem is within the configurations.
Here follows some of my code:
Datasource configuration:
#Configuration
#Profile("mySQL")
#PropertySource("classpath:/services.properties")
public class MySQLDataSourceConfiguration implements DataSourceConfiguration{
#Inject
private Environment environment;
#Bean
public DataSource dataSource() throws Exception {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setPassword(environment.getProperty("dataSource.password"));
dataSource.setUrl(environment.getProperty("dataSource.url"));
dataSource.setUsername(environment.getProperty("dataSource.user"));
dataSource.setDriverClassName(environment.getPropertyAsClass("dataSource.driverClass", Driver.class).getName());
return dataSource;
}
}
the file service.properties is where I keep my configurations for the database, so when I desire to change the database I will just have to change 4 fields.
The JDBCConfiguration class for the setup of the JDBCtemplate
#Configuration
#EnableTransactionManagement
#PropertySource("classpath:/services.properties")
#Import( { MySQLDataSourceConfiguration.class })
public class JdbcConfiguration {
#Autowired
private DataSourceConfiguration dataSourceConfiguration;
#Inject
private Environment environment;
#Bean
public JdbcTemplate setupJdbcTemplate() throws Exception {
return new JdbcTemplate(dataSourceConfiguration.dataSource());
}
#Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) throws Exception {
return new DataSourceTransactionManager(dataSource);
}
}
Then there is the Repository, that recieves the template.
#Transactional
#Repository
#Qualifier("jdbcRepository")
public class JdbcIndividualRepository implements IndividualsRepository{
private static final Logger LOG = LoggerFactory.getLogger(JdbcIndividualRepository.class);
#Autowired
private JdbcTemplate jdbcTemplate;
#Autowired
public JdbcIndividualRepository(DataSource jdbcDataSource) {
LOG.info("JDBCRepo arg constructor");
this.jdbcTemplate = new JdbcTemplate(jdbcDataSource);
}
#Override
public Individual save(Individual save) {
String sql = "INSERT INTO Individual(idIndividual, Name) VALUES(?,?)";
this.jdbcTemplate.update(sql, save.getId(), save.getName());
return save;
}
#Override
public void delete(String key) {
String sql = "DELETE FROM Individual WHERE idIndividual=?";
jdbcTemplate.update(sql, key);
}
#Override
public Individual findById(String key) {
String sql = "SELECT i.* FROM Individual i WHERE i.idIndividual=?";
return this.jdbcTemplate.queryForObject(sql, new IndividualRowMapper(), key);
}
#Override
public List<Individual> findAll() {
String sql = "SELECT * FROM Individual";
return new LinkedList<Individual>(this.jdbcTemplate.query(sql, new IndividualRowMapper()));
}
}
Then I register the jdbc configuration in the initializer class when creating the root context of the application as follows:
private WebApplicationContext createRootContext(ServletContext servletContext) {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(CoreConfig.class, SecurityConfig.class, JdbcConfiguration.class);
rootContext.refresh();
servletContext.addListener(new ContextLoaderListener(rootContext));
servletContext.setInitParameter("defaultHtmlEscape", "true");
return rootContext;
}
However, the Tomcat server wont run because it can't autowire the class MySQLDataSourceConfiguration.
Anyone knows what the problem might be? I can give more details on the code, but the question is already really large.
Appreciate any kind of help!
Cheers
EDIT
Solved changing the JdbcConfiguration class to:
#Configuration
#EnableTransactionManagement
#PropertySource("classpath:/services.properties")
#Import( { MySQLDataSourceConfiguration.class })
public class JdbcConfiguration {
#Autowired
private DataSource dataSource;
#Inject
private Environment environment;
#Bean
public JdbcTemplate setupJdbcTemplate() throws Exception {
return new JdbcTemplate(dataSource);
}
#Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) throws Exception {
return new DataSourceTransactionManager(dataSource);
}
#Bean
public IndividualsRepository createRepo(){
return new JdbcIndividualRepository(dataSource);
}
}
Remove
#Autowired
private DataSourceConfiguration dataSourceConfiguration;
Because that's not how it's supposed to be used. Instead add to the same class the following:
#Autowired DataSource dataSource;
and use it like this: new JdbcTemplate(dataSource);
Also, try adding #ComponentScan to JdbcConfiguration class. From what I see in your code the class JdbcIndividualRepository is not picked up by anything.
In your class JdbcConfiguration, you are trying to autowire DataSourceConfiguration. I'm not really sure if that's possible - typically you should try to autwire the DataSource, not the DataSourceConfiguration.
#Import( { MySQLDataSourceConfiguration.class })
public class JdbcConfiguration {
#Autowired
private DataSource dataSource;
#Bean
public JdbcTemplate setupJdbcTemplate() throws Exception {
return new JdbcTemplate(dataSource);
}
Also if you have several DataSources and you're using Spring profiles to separate them, it's easier to provide all the DataSource beans in one file and annotate each bean with a different profile:
#Configuration
public class DataSourceConfig {
#Bean
#Profile("Test")
public DataSource devDataSource() {
.... configure data source
}
#Bean
#Profile("Prod")
public DataSource prodDataSource() {
... configure data source
}

Resources