Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Routing Using Zuul, Hazelcast, and Docker

DZone's Guide to

Routing Using Zuul, Hazelcast, and Docker

This brief tutorial explains the methodology and provides the code to set up routing with Zuul, Hazelcast, and Docker.

· Microservices Zone ·
Free Resource

Containerized Microservices require new monitoring. See why a new APM approach is needed to even see containerized applications.

In this article, we will explain how we can use Zuul, Hazelcast, and Docker for routing. Please refer to the block diagram below:

Image title

First, we create a Spring Boot REST service, app1, which has a REST endpoint/process. It will return the string "App1 processing." This will run on port 8080.

package com.app1.app1;

@Controller
public class AppController {

    @RequestMapping(value="/process", method = RequestMethod.GET)
    public @ResponseBody String  showLoginPage(ModelMap model){
        return "Processing aap1";
    }
}

Similar to app1, create app2, with a REST endpoint/process. It will return the string "App2 processing." This will run on port 8080.

package com.app2.app2;

@Controller
public class AppController {
@RequestMapping(value="/process", method = RequestMethod.GET)
    public @ResponseBody String  showLoginPage(ModelMap model){
        return "Processing app2";
    }
}

We will run app1 in a Docker container with port mapping 7071:8080. This means any data coming to 7071 will go to Docker port 8080. 

Dockerfile:

FROM java:8 
COPY app1-0.0.1-SNAPSHOT.jar /home/app1-0.0.1-SNAPSHOT.jar
CMD ["java","-jar","/home/app1-0.0.1-SNAPSHOT.jar"]

Then create the image and container :

sudo docker build -t app1 .
sudo docker run -itd  -p 7071:8080 --name app1 app1

Similarly, run the Docker container app2.

Dockerfile:

FROM java:8 
COPY app1-0.0.1-SNAPSHOT.jar /home/app2-0.0.1-SNAPSHOT.jar
CMD ["java","-jar","/home/app2-0.0.1-SNAPSHOT.jar"]

Then create the image and container:

sudo docker build -t app2 .
sudo docker run -itd  -p 7072:8080 --name app2 app2

Create the Hazel Server cluster:

public class hazelcastServer {
  public static void main(String[] args) {
        ClientConfig clientConfig = new ClientConfig();        
        ClientNetworkConfig networkConfig = clientConfig.getNetworkConfig();
        networkConfig.addAddress("172.17.0.1:5701");        
        HazelcastInstance client = HazelcastClient.newHazelcastClient(clientConfig);
        IMap<String, String> map = client.getMap("route");      
        map.put("*", "/");
        System.out.println("Map Size:" + map.size());
    }  
}

Create the Hazelcast client and update routes:

public class hazelClient {
public static void main(String[] args) {
        Config cfg = new Config();
        HazelcastInstance instance = Hazelcast.newHazelcastInstance(cfg);      
        Map<String, String> route = instance.getMap("route");
        route.put("app1", "http://localhost:7071/");
        route.put("app2", "http://localhost:7072/");
    }
}

Run a Zuul app which uses the Hazelcast map to dynamic route requests. In this example, any request to /app1/** will go to localhost:7071 and any request to /app2/** will go to localhost:7072. localhost:7071 -> app1 Docker port 8080. localhost:7072 -> app2 Docker port 8080.

@SpringBootApplication
@EnableZuulProxy
public class Zuul 
{
    public static void main( String[] args )
    {
SpringApplication.run(Zuul.class, args);
    }
    @Bean
    public PreFilter preFilter() {
        return new PreFilter();
    }
    @Bean
    public PostFilter postFilter() {
        return new PostFilter();
    }
    @Bean
    public ErrorFilter errorFilter() {
        return new ErrorFilter();
    }
    @Bean
    public RouteFilter routeFilter() {
        return new RouteFilter();
    }    
}

Finally, create a service which will read the Hazelcast map and create a route dynamically:

@Service
public class ZuulDynamicRoutingService {

 @Autowired
 private ZuulProperties zuulProperties;

 @Autowired
 private ZuulHandlerMapping zuulHandlerMapping;

 IMap < String, String > map = null;

 @PostConstruct
 public void initialize() {

  ClientConfig clientConfig = new ClientConfig();
  ClientNetworkConfig networkConfig = clientConfig.getNetworkConfig();
  networkConfig.addAddress("172.17.0.1:5701");
  HazelcastInstance client = HazelcastClient.newHazelcastClient(clientConfig);
  map = client.getMap("route");

  for (String m: map.keySet()) {
   zuulProperties.getRoutes().put(m,
    new ZuulRoute(m, "/" + m + "/**", null, map.get(m), true, false, new HashSet()));
  }
  zuulProperties.getRoutes().put("default",
   new ZuulRoute("default", "/**", null, "http://localhost:8080/", true, false, new HashSet()));
  zuulHandlerMapping.setDirty(true);

 }

 // Call this method to synch with Hazelcase Map
 public void addDynamicRoute() {
  System.out.println("DynamicRoute");
  for (String m: map.keySet()) {
   if (!zuulProperties.getRoutes().containsKey(m)) {
    zuulProperties.getRoutes().put(m,
     new ZuulRoute(m, "/" + m + "/**", null, map.get(m), true, false, new HashSet()));
   }
  }
  zuulHandlerMapping.setDirty(true);
 }

}

That is how to set up routing with Zuul, Hazelcast, and Docker.

Automatically manage containers and microservices with better control and performance using Instana APM. Try it for yourself today.

Topics:
hazelcast ,zuul ,docker ,routing ,microservices ,tutorial

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}