WIP:test: HandoverIT-POC - splitted up code into smaller classes -- ALIGN
[demos/kafka/chat] / src / test / java / de / juplo / kafka / chat / backend / HandoverITContainers.java
1 package de.juplo.kafka.chat.backend;
2
3 import lombok.extern.slf4j.Slf4j;
4 import org.awaitility.Awaitility;
5 import org.springframework.http.HttpStatus;
6 import org.springframework.web.reactive.function.client.WebClient;
7 import org.testcontainers.containers.BindMode;
8 import org.testcontainers.containers.GenericContainer;
9 import org.testcontainers.containers.Network;
10 import org.testcontainers.containers.output.Slf4jLogConsumer;
11 import org.testcontainers.containers.wait.strategy.Wait;
12 import org.testcontainers.images.ImagePullPolicy;
13 import org.testcontainers.utility.DockerImageName;
14 import reactor.core.publisher.Mono;
15
16 import java.time.Duration;
17 import java.util.Arrays;
18
19
20 @Slf4j
21 public abstract class AbstractContainerTemplates
22 {
23   static final ImagePullPolicy NEVER_PULL = imageName -> false;
24
25
26   final Network network = Network.newNetwork();
27   final GenericContainer haproxy, backend1, backend2, backend3;
28
29
30   AbstractContainerTemplates()
31   {
32     haproxy = createHaproxyContainer();
33     backend1 = createBackendContainer("1");
34     backend2 = createBackendContainer("2");
35     backend3 = createBackendContainer("3");
36   }
37
38
39   void setUpExtra() throws Exception
40   {
41     log.info("This setup does not need any extra containers");
42   }
43
44   void setUp() throws Exception
45   {
46     setUpExtra();
47     haproxy.start();
48     backend1.start();
49     // backend2.start();
50     // backend3.start();
51
52     Awaitility
53         .await()
54         .atMost(Duration.ofMinutes(10))
55         .until(() -> WebClient
56             .create("http://localhost:" + backend1.getMappedPort(8080))
57             .get()
58             .uri("/actuator/health")
59             .exchangeToMono(response ->
60             {
61               if (response.statusCode().equals(HttpStatus.OK))
62               {
63                 return response
64                     .bodyToMono(StatusTO.class)
65                     .map(StatusTO::getStatus)
66                     .map(status -> status.equalsIgnoreCase("UP"));
67               }
68               else
69               {
70                 return Mono.just(false);
71               }
72             })
73             .block());
74
75     haproxy
76         .getDockerClient()
77         .killContainerCmd(haproxy.getContainerId())
78         .withSignal("HUP")
79         .exec();
80
81
82     Awaitility
83         .await()
84         .atMost(Duration.ofMinutes(10))
85         .until(() -> WebClient
86             .create("http://localhost:" + haproxy.getMappedPort(8400))
87             .get()
88             .uri("/actuator/health")
89             .exchangeToMono(response ->
90             {
91               if (response.statusCode().equals(HttpStatus.OK))
92               {
93                 return response
94                     .bodyToMono(StatusTO.class)
95                     .map(StatusTO::getStatus)
96                     .map(status -> status.equalsIgnoreCase("UP"));
97               }
98               else
99               {
100                 return Mono.just(false);
101               }
102             })
103             .block());
104   }
105
106   abstract String[] getBackendCommand();
107
108   final GenericContainer createHaproxyContainer()
109   {
110     return new GenericContainer(DockerImageName.parse("haproxytech/haproxy-debian:2.8"))
111         .withNetwork(network)
112         .withNetworkAliases("haproxy")
113         .withClasspathResourceMapping(
114             "haproxy.cfg",
115             "/usr/local/etc/haproxy/haproxy.cfg",
116             BindMode.READ_ONLY)
117         .withClasspathResourceMapping(
118             "sharding.map",
119             "/usr/local/etc/haproxy/sharding.map",
120             BindMode.READ_WRITE)
121         .withExposedPorts(8400, 8401, 8404)
122         .withLogConsumer(new Slf4jLogConsumer(log, true).withPrefix("HAPROXY"));
123   }
124
125   final GenericContainer createBackendContainer(String id)
126   {
127     return new GenericContainer(DockerImageName.parse("juplo/chat-backend:0.0.1-SNAPSHOT"))
128       .withImagePullPolicy(NEVER_PULL)
129       .withNetwork(network)
130       .withNetworkAliases("backend-ID".replaceAll("ID", id))
131       .withCommand(Arrays.stream(getBackendCommand())
132           .map(commandPart -> commandPart.replaceAll("ID", id))
133           .toArray(size -> new String[size]))
134       .withExposedPorts(8080)
135       .waitingFor(Wait.forLogMessage(".*Started\\ ChatBackendApplication.*\\n", 1))
136       .withLogConsumer(new Slf4jLogConsumer(
137           log,
138           true
139           )
140           .withPrefix("BACKEND-ID".replaceAll("ID", id)));
141   }
142 }