spring-projects / spring-data-cassandra

Provides support to increase developer productivity in Java when using Apache Cassandra. Uses familiar Spring concepts such as a template classes for core API usage and lightweight repository style data access.
https://spring.io/projects/spring-data-cassandra/
Apache License 2.0
374 stars 307 forks source link

Can't create multiple CassandraOperations without configuring keyspace? #1417

Closed yzy-1995 closed 11 months ago

yzy-1995 commented 11 months ago

this is my yaml

spring:
  data:
    cassandra:
      contact-points: 192.168.2.52
      port: 9042
      local-datacenter: datacenter1
      username: cassandra
      password: cassandra
dd:
  monitor:
    config:
      cassandra-double-write:
        contact-points: XXX.com
        port: 9042
        local-datacenter: datacenter1
        username: cassandra
        password: cassandra

this is my cassandraConfig

@Data
@Slf4j
@Configuration
@AutoConfigureAfter(CassandraAutoConfiguration.class)
@ConfigurationProperties(prefix = "dd.monitor.config.cassandra-double-write")
public class CassandraConfig {

    private String contactPoints;
    private int port;
    private String localDatacenter;
    private String username;
    private String password;

    public CassandraConfig() {
        log.info("CassandraConfig config.....");
    }

    @Bean
    @Qualifier("DwCqlSessionFactoryBean")
    public CqlSessionFactoryBean session() {

        CqlSessionFactoryBean session = new CqlSessionFactoryBean();
        session.setContactPoints(contactPoints);
        session.setPort(port);
        session.setUsername(username);
        session.setPassword(password);
        session.setLocalDatacenter(localDatacenter);

        return session;
    }

    @Bean
    @Qualifier("DwSessionFactoryFactoryBean")
    public SessionFactoryFactoryBean sessionFactory(
            @Qualifier("DwCqlSessionFactoryBean")CqlSession session, CassandraConverter converter) {

        SessionFactoryFactoryBean sessionFactory = new SessionFactoryFactoryBean();
        sessionFactory.setSession(session);
        sessionFactory.setConverter(converter);
        sessionFactory.setSchemaAction(SchemaAction.NONE);

        return sessionFactory;
    }

    @Bean
    @Qualifier("DwCassandraMappingContext")
    public CassandraMappingContext mappingContext(CassandraCustomConversions conversions) {
        CassandraMappingContext mappingContext = new CassandraMappingContext();
        mappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
        return mappingContext;
    }

    @Bean
    @Qualifier("DwCassandraConverter")
    public CassandraConverter converter(
            @Qualifier("DwCassandraMappingContext")CassandraMappingContext mappingContext) {
        return new MappingCassandraConverter(mappingContext);
    }

    @Bean
    @Qualifier("DwCassandraTemplate")
    public CassandraOperations cassandraTemplate(
            @Qualifier("DwSessionFactoryFactoryBean")SessionFactory sessionFactory,
            @Qualifier("DwCassandraConverter")CassandraConverter converter) {
        return new CassandraTemplate(sessionFactory, converter);
    }

}

this is my other cassandraConfig

@Data
@Slf4j
@Configuration
@AutoConfigureAfter(CassandraAutoConfiguration.class)
@ConfigurationProperties(prefix = "spring.data.cassandra")
public class CassandraDefaultConfig {

    private String contactPoints;
    private int port;
    private String localDatacenter;
    private String username;
    private String password;

    public CassandraDefaultConfig() {
        log.info("CassandraDefaultConfig config.....");
    }

    @Bean(name = "CdcSession")
    @Qualifier("CdcCqlSessionFactoryBean")
    public CqlSessionFactoryBean CdcSession() {

        CqlSessionFactoryBean CdcSession = new CqlSessionFactoryBean();
        CdcSession.setContactPoints(contactPoints);
        CdcSession.setPort(port);
        CdcSession.setUsername(username);
        CdcSession.setPassword(password);
        CdcSession.setLocalDatacenter(localDatacenter);
        CdcSession.setKeyspaceName("system1");

        return CdcSession;
    }

    @Bean(name = "CdcSessionFactory")
    @Qualifier("CdcSessionFactoryFactoryBean")
    public SessionFactoryFactoryBean CdcSessionFactory(
            @Qualifier("CdcCqlSessionFactoryBean")CqlSession CdcSession, CassandraConverter CdcConverter) {

        SessionFactoryFactoryBean CdcSessionFactory = new SessionFactoryFactoryBean();
        CdcSessionFactory.setSession(CdcSession);
        CdcSessionFactory.setConverter(CdcConverter);
        CdcSessionFactory.setSchemaAction(SchemaAction.NONE);

        return CdcSessionFactory;
    }

    @Bean(name = "CdcMappingContext")
    @Qualifier("CdcCassandraMappingContext")
    public CassandraMappingContext CdcMappingContext(CassandraCustomConversions conversions) {
        CassandraMappingContext CdcMappingContext = new CassandraMappingContext();
        CdcMappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
        return CdcMappingContext;
    }

    @Bean(name = "CdcConverter")
    @Qualifier("CdcCassandraConverter")
    public CassandraConverter CdcConverter(
            @Qualifier("CdcCassandraMappingContext")CassandraMappingContext mappingContext) {
        return new MappingCassandraConverter(mappingContext);
    }

    @Bean(name = "CdcCassandraTemplate")
    @Qualifier("CdcCassandraTemplate")
    public CassandraOperations CdcCassandraTemplate(
            @Qualifier("CdcSessionFactoryFactoryBean")SessionFactory CdcSessionFactory,
            @Qualifier("CdcCassandraConverter")CassandraConverter CdcConverter) {
        return new CassandraTemplate(CdcSessionFactory, CdcConverter);
    }
}

this is my serviceimpl

@Service
@Slf4j
public class MyServiceImpl implements MyService {

    @Autowired
    @Qualifier("CdcCassandraTemplate")
    private CassandraOperations template;

    @Autowired
    @Qualifier("DwCassandraTemplate")
    private CassandraOperations dwTemplate;

    @Override
    public MetricsBusiness insert(MetricsBusiness metricsBusiness) {
        dwTemplate.insert(metricsBusiness);
        return template.insert(metricsBusiness);
    }

    @Override
    public void batchInsert(List<MetricsBusiness> metricsBusinessList) {
        template.batchOps().insert(metricsBusinessList).execute();
        dwTemplate.batchOps().insert(metricsBusinessList).execute();
    }

}

but i can't start this application and this is error message please help me

Exception encountered during context initialization -
 cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: 
 Error creating bean with name 'myServiceImpl': Unsatisfied dependency expressed through field 'template'; 
 nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: 
 Error creating bean with name 'CdcCassandraTemplate' 
 defined in class path resource [*/metricstore/config/CassandraDefaultConfig.class]: 
 Unsatisfied dependency expressed through method 'CdcCassandraTemplate' parameter 0; 
 nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException:
 Error creating bean with name 'CdcSessionFactory' defined in class path resource [*/metricstore/config/CassandraDefaultConfig.class]:
 Unsatisfied dependency expressed through method 'CdcSessionFactory' parameter 1; 
 nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: 
 Error creating bean with name 'CdcConverter' defined in class path resource [*/metricstore/config/CassandraDefaultConfig.class]: 
 Unsatisfied dependency expressed through method 'CdcConverter' parameter 0; 
 nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: 
 Error creating bean with name 'CdcMappingContext' defined in class path resource [*/metricstore/config/CassandraDefaultConfig.class]:
 Unsatisfied dependency expressed through method 'CdcMappingContext' parameter 0; 
 nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: 
 Error creating bean with name 'org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration':
 Unsatisfied dependency expressed through constructor parameter 0;
 nested exception is org.springframework.beans.factory.BeanCreationException:
 Error creating bean with name 'session' defined in class path resource [*/metricstore/config/CassandraConfig.class]:
 Invocation of init method failed; nested exception is com.datastax.oss.driver.api.core.AllNodesFailedException:
 Could not reach any contact point, make sure you've provided valid addresses 
 (showing first 1 nodes, use getAllErrors() for more): Node(endPoint=XXX.com:9042, hostId=null, hashCode=6567721a):
 [com.datastax.oss.driver.api.core.DriverTimeoutException: 
 [s2|control|id: 0x81729d70, L:/198.18.0.1:50305 - R:XXX.com/102.168.2.52:9042] 
 Protocol initialization request, step 1 (OPTIONS): timed out after 500 ms] "}
mp911de commented 11 months ago

The exception reports

DriverTimeoutException: [s2|control|id: 0x81729d70, L:/198.18.0.1:50305 - R:XXX.com/102.168.2.52:9042] Protocol initialization request, step 1 (OPTIONS): timed out after 500 ms]

This is a hint that your infrastructure either doesn't respond in time or that the service listening at 102.168.2.52:9042 is defunkt. Please ensure that your database service is healthy. Other than that, your configuration looks fine. You could simplify it even more by reusing CassandraMappingContext and CassandraConverter beans.

yzy-1995 commented 11 months ago

thank you,you are right ,colleague give me prod link,this is causing the connection to fail.