VOOZH about

URL: https://www.javacodegeeks.com/2015/09/spring-cloud-sidecar-initialization-of-nodes.html

⇱ Spring Cloud Sidecar - Initialization of Nodes - Java Code Geeks


In the last blog post I had described how the Sidecar application can be used for registering the Cassandra nodes with Eureka and more generally can be used for registering any non-JVM application with Eureka.

In this post I will cover how an application can go about querying the Sidecar registered nodes.

Discovering Registered Nodes – Post Initialization

If the registered nodes are not required during the bean initialization phase then discovering the nodes is fairly straightforward along these lines:

@Component
public class SampleCommandLineRunner implements CommandLineRunner {

 @Autowired
 private DiscoveryClient discoveryClient;

 @PostConstruct
 public void postConstruct() {
// System.out.println("Printing from postConstruct");
// printDiscoveredNodes();
 }

 @Override
 public void run(String... strings) throws Exception {
 System.out.println("Printing from run method");
 printDiscoveredNodes();
 }

 public void printDiscoveredNodes() {
 System.out.println(" Printing Discovered Nodes ");

 for (ServiceInstance instance: discoveryClient.getInstances("samplecassandra.vip")) {
 System.out.println("Host: Port = " + instance.getHost() + ":" + instance.getPort());
 }
 }
}

These would print the nodes registered with a name of “samplecasssandra.vip” VIP.

Note that the nodes are being printed from the run method which gets called past the initialization of Spring container. If however the nodes were attempted to be listed from one of the lifecycle stages say the postConstruct method then very likely an exception will be thrown (this behavior is seen with “Angel.SR3” release of Spring Cloud, but appears to work cleanly with “Brixton.*” versions)

Discovering Registered Nodes – During Initialization

Now if an application needs to discover the nodes during initialization the flow is a little more complicated, for a potential issue look at this ticket.

The DiscoveryClient is initialized very late in the Spring Lifecycle and if DiscoveryClient is used in any post-processing activity of a bean it is likely to give an exception.

As an example, say the Cassandra nodes registered using Sidecar is now used by an application to initialize Cassandra connectivity, a way to do it would be to create a wrapper around Cassandra connectivity this way:

import org.springframework.data.cassandra.core.CassandraTemplate;


public class CassandraTemplateWrapper extends CassandraTemplate {

 @Override
 public void afterPropertiesSet() {
 
 }
}

Here CassandraTemplate is being overridden to prevent the check in afterPropertiesSet method that a Cassandra session exists, as a session will be established much later in the start-up cycle.

A Cassandra session can be injected into this custom CassandraTemplate lazily in a bean that implements SmartLifecyle along these lines:

package mvctest.cassandra;

import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.SmartLifecycle;
import org.springframework.core.Ordered;
import org.springframework.data.cassandra.core.CassandraTemplate;
import org.springframework.stereotype.Component;

@Component("cassandraTemplate")
public class EurekaCassandraTemplateFactoryBean implements SmartLifecycle, FactoryBean<CassandraTemplate>, Ordered {

 ....


 @Override
 public boolean isAutoStartup() {
 return true;
 }

 @Override
 public void start() {
 LOGGER.info("About to start Discovery client lookup of Cassandra Cluster!!!");
 final Cluster cluster = this.eurekaClusterBuilder.build();
 Session session = cluster.connect(this.cassandraProperties.getKeyspace());
 this.cassandraTemplateWrapper.setSession(session);
 LOGGER.info("Completed Discovery client lookup of Cassandra Cluster!!!");
 running = true;
 }

 @Override
 public boolean isRunning() {
 return this.running;
 }

 @Override
 public int getPhase() {
 return Integer.MAX_VALUE;
 }

 @Override
 public int getOrder() {
 return 1;
 }
}

This way the Cassandra session can be created very late in the cycle. Somewhat rough, but the approach works.

  • If you are interested in exploring this sample further I have this code available in
    my github repo here.
Reference: Spring Cloud Sidecar – Initialization of Nodes from our JCG partner Biju Kunjummen at the all and sundry blog.
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

Thank you!

We will contact you soon.

👁 Photo of Biju Kunjummen
Biju Kunjummen
September 29th, 2015Last Updated: September 29th, 2015
0 97 2 minutes read
Subscribe

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Back to top button
Close
wpDiscuz