Skip to content

Commit f7b6748

Browse files
Introduce health-check-interval module parameter (#1853)
LMCROSSITXSADEPLOY-3316
1 parent 5632d9c commit f7b6748

10 files changed

Lines changed: 360 additions & 3 deletions

File tree

multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/adapters/RawCloudProcess.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ public CloudProcess derive() {
2323
Integer healthCheckTimeout = null;
2424
String healthCheckHttpEndpoint = null;
2525
Integer healthCheckInvocationTimeout = null;
26+
Integer healthCheckInterval = null;
2627
if (healthCheck.getData() != null) {
2728
Data healthCheckData = healthCheck.getData();
2829
healthCheckTimeout = healthCheckData.getTimeout();
2930
healthCheckInvocationTimeout = healthCheckData.getInvocationTimeout();
3031
healthCheckHttpEndpoint = healthCheckData.getEndpoint();
32+
healthCheckInterval = healthCheckData.getInterval();
3133
}
3234
Integer readinessHealthCheckInvocationTimeout = null;
3335
String readinessHealthCheckHttpEndpoint = null;
@@ -49,6 +51,7 @@ public CloudProcess derive() {
4951
.healthCheckHttpEndpoint(healthCheckHttpEndpoint)
5052
.healthCheckTimeout(healthCheckTimeout)
5153
.healthCheckInvocationTimeout(healthCheckInvocationTimeout)
54+
.healthCheckInterval(healthCheckInterval)
5255
.readinessHealthCheckType(readinessHealthCheckType.getType()
5356
.getValue())
5457
.readinessHealthCheckHttpEndpoint(readinessHealthCheckHttpEndpoint)

multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/domain/CloudProcess.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ public abstract class CloudProcess extends CloudEntity implements Derivable<Clou
2929
@Nullable
3030
public abstract Integer getHealthCheckTimeout();
3131

32+
@Nullable
33+
public abstract Integer getHealthCheckInterval();
34+
3235
@Nullable
3336
public abstract Integer getReadinessHealthCheckInterval();
3437

multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/domain/Staging.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ public interface Staging {
5050
@Nullable
5151
String getHealthCheckHttpEndpoint();
5252

53+
/**
54+
* @return health check interval in seconds (liveness)
55+
*/
56+
@Nullable
57+
Integer getHealthCheckInterval();
58+
5359
/**
5460
* @return readiness health check interval
5561
*/

multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/rest/CloudControllerRestClientImpl.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ private HealthCheck buildHealthCheck(Staging staging) {
445445
.endpoint(staging.getHealthCheckHttpEndpoint())
446446
.timeout(staging.getHealthCheckTimeout())
447447
.invocationTimeout(staging.getInvocationTimeout())
448+
.interval(staging.getHealthCheckInterval())
448449
.build())
449450
.build();
450451
}

multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/lib/domain/HealthCheckInfo.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@ public class HealthCheckInfo {
1010
private final String type;
1111
private final Integer timeout;
1212
private final Integer invocationTimeout;
13+
private final Integer interval;
1314
private final String httpEndpoint;
1415

15-
private HealthCheckInfo(String type, Integer timeout, Integer invocationTimeout, String httpEndpoint) {
16+
private HealthCheckInfo(String type, Integer timeout, Integer invocationTimeout, Integer interval, String httpEndpoint) {
1617
this.type = type;
1718
this.timeout = timeout;
1819
this.invocationTimeout = invocationTimeout;
20+
this.interval = interval;
1921
this.httpEndpoint = httpEndpoint;
2022
}
2123

@@ -26,16 +28,18 @@ public static HealthCheckInfo fromStaging(Staging staging) {
2628
}
2729
var timeout = staging.getHealthCheckTimeout();
2830
var invocationTimeout = staging.getInvocationTimeout();
31+
var interval = staging.getHealthCheckInterval();
2932
var httpEndpoint = staging.getHealthCheckHttpEndpoint();
30-
return new HealthCheckInfo(type, timeout, invocationTimeout, httpEndpoint);
33+
return new HealthCheckInfo(type, timeout, invocationTimeout, interval, httpEndpoint);
3134
}
3235

3336
public static HealthCheckInfo fromProcess(CloudProcess process) {
3437
var type = process.getHealthCheckType();
3538
var timeout = process.getHealthCheckTimeout();
3639
var invocationTimeout = process.getHealthCheckInvocationTimeout();
40+
var interval = process.getHealthCheckInterval();
3741
var httpEndpoint = process.getHealthCheckHttpEndpoint();
38-
return new HealthCheckInfo(type.toString(), timeout, invocationTimeout, httpEndpoint);
42+
return new HealthCheckInfo(type.toString(), timeout, invocationTimeout, interval, httpEndpoint);
3943
}
4044

4145
public String getType() {
@@ -50,6 +54,10 @@ public Integer getInvocationTimeout() {
5054
return invocationTimeout;
5155
}
5256

57+
public Integer getInterval() {
58+
return interval;
59+
}
60+
5361
public String getHttpEndpoint() {
5462
return httpEndpoint;
5563
}
@@ -66,6 +74,7 @@ public boolean equals(Object obj) {
6674
return Objects.equals(getType(), other.getType())
6775
&& Objects.equals(getTimeout(), other.getTimeout())
6876
&& Objects.equals(getInvocationTimeout(), other.getInvocationTimeout())
77+
&& Objects.equals(getInterval(), other.getInterval())
6978
&& Objects.equals(getHttpEndpoint(), other.getHttpEndpoint());
7079
}
7180
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package org.cloudfoundry.multiapps.controller.client.facade.adapters;
2+
3+
import org.cloudfoundry.client.v3.Metadata;
4+
import org.cloudfoundry.client.v3.processes.Data;
5+
import org.cloudfoundry.client.v3.processes.HealthCheck;
6+
import org.cloudfoundry.client.v3.processes.HealthCheckType;
7+
import org.cloudfoundry.client.v3.processes.ProcessRelationships;
8+
import org.cloudfoundry.client.v3.processes.ProcessResource;
9+
import org.cloudfoundry.client.v3.processes.ReadinessHealthCheck;
10+
import org.cloudfoundry.client.v3.processes.ReadinessHealthCheckType;
11+
import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudProcess;
12+
import org.cloudfoundry.multiapps.controller.client.facade.domain.ImmutableCloudProcess;
13+
import org.junit.jupiter.api.Test;
14+
15+
import static org.junit.jupiter.api.Assertions.assertEquals;
16+
import static org.junit.jupiter.api.Assertions.assertNull;
17+
18+
class RawCloudProcessTest {
19+
20+
private static final String COMMAND = "bundle exec rackup";
21+
private static final Integer DISK_IN_MB = 1024;
22+
private static final Integer INSTANCES = 2;
23+
private static final Integer MEMORY_IN_MB = 512;
24+
private static final String HTTP_ENDPOINT = "/health";
25+
private static final Integer TIMEOUT = 30;
26+
private static final Integer INVOCATION_TIMEOUT = 5;
27+
private static final Integer INTERVAL = 10;
28+
private static final String READINESS_HTTP_ENDPOINT = "/ready";
29+
private static final Integer READINESS_INVOCATION_TIMEOUT = 4;
30+
private static final Integer READINESS_INTERVAL = 8;
31+
32+
@Test
33+
void testDeriveWithFullHealthCheckDataIncludingInterval() {
34+
RawCloudProcess raw = ImmutableRawCloudProcess.of(buildProcessResource(HealthCheckType.HTTP, buildHealthCheckData(),
35+
ReadinessHealthCheckType.HTTP,
36+
buildReadinessHealthCheckData()));
37+
38+
CloudProcess derived = raw.derive();
39+
40+
assertEquals(buildExpected(org.cloudfoundry.multiapps.controller.client.facade.domain.HealthCheckType.HTTP, INTERVAL,
41+
ReadinessHealthCheckType.HTTP.getValue()),
42+
derived);
43+
}
44+
45+
@Test
46+
void testDeriveWithMissingHealthCheckDataLeavesIntervalNull() {
47+
// healthCheck.getData() returns null -> all four health-check Integer/String fields stay null
48+
RawCloudProcess raw = ImmutableRawCloudProcess.of(buildProcessResource(HealthCheckType.PORT, null,
49+
ReadinessHealthCheckType.PORT, null));
50+
51+
CloudProcess derived = raw.derive();
52+
53+
assertEquals(org.cloudfoundry.multiapps.controller.client.facade.domain.HealthCheckType.PORT, derived.getHealthCheckType());
54+
assertNull(derived.getHealthCheckTimeout());
55+
assertNull(derived.getHealthCheckInvocationTimeout());
56+
assertNull(derived.getHealthCheckHttpEndpoint());
57+
assertNull(derived.getHealthCheckInterval());
58+
assertNull(derived.getReadinessHealthCheckInvocationTimeout());
59+
assertNull(derived.getReadinessHealthCheckHttpEndpoint());
60+
assertNull(derived.getReadinessHealthCheckInterval());
61+
}
62+
63+
@Test
64+
void testDeriveWithHealthCheckDataPresentButIntervalNull() {
65+
Data dataWithoutInterval = Data.builder()
66+
.endpoint(HTTP_ENDPOINT)
67+
.timeout(TIMEOUT)
68+
.invocationTimeout(INVOCATION_TIMEOUT)
69+
.build();
70+
RawCloudProcess raw = ImmutableRawCloudProcess.of(buildProcessResource(HealthCheckType.HTTP, dataWithoutInterval,
71+
ReadinessHealthCheckType.PORT, null));
72+
73+
CloudProcess derived = raw.derive();
74+
75+
assertEquals(TIMEOUT, derived.getHealthCheckTimeout());
76+
assertEquals(INVOCATION_TIMEOUT, derived.getHealthCheckInvocationTimeout());
77+
assertEquals(HTTP_ENDPOINT, derived.getHealthCheckHttpEndpoint());
78+
assertNull(derived.getHealthCheckInterval());
79+
}
80+
81+
private static ProcessResource buildProcessResource(HealthCheckType healthCheckType, Data healthCheckData,
82+
ReadinessHealthCheckType readinessHealthCheckType, Data readinessHealthCheckData) {
83+
HealthCheck.Builder healthCheckBuilder = HealthCheck.builder()
84+
.type(healthCheckType);
85+
if (healthCheckData != null) {
86+
healthCheckBuilder.data(healthCheckData);
87+
}
88+
ReadinessHealthCheck.Builder readinessBuilder = ReadinessHealthCheck.builder()
89+
.type(readinessHealthCheckType);
90+
if (readinessHealthCheckData != null) {
91+
readinessBuilder.data(readinessHealthCheckData);
92+
}
93+
return ProcessResource.builder()
94+
.id(RawCloudEntityTest.GUID_STRING)
95+
.createdAt(RawCloudEntityTest.CREATED_AT_STRING)
96+
.updatedAt(RawCloudEntityTest.UPDATED_AT_STRING)
97+
.command(COMMAND)
98+
.diskInMb(DISK_IN_MB)
99+
.instances(INSTANCES)
100+
.memoryInMb(MEMORY_IN_MB)
101+
.type("web")
102+
.metadata(Metadata.builder()
103+
.build())
104+
.relationships(ProcessRelationships.builder()
105+
.build())
106+
.healthCheck(healthCheckBuilder.build())
107+
.readinessHealthCheck(readinessBuilder.build())
108+
.build();
109+
}
110+
111+
private static Data buildHealthCheckData() {
112+
return Data.builder()
113+
.endpoint(HTTP_ENDPOINT)
114+
.timeout(TIMEOUT)
115+
.invocationTimeout(INVOCATION_TIMEOUT)
116+
.interval(INTERVAL)
117+
.build();
118+
}
119+
120+
private static Data buildReadinessHealthCheckData() {
121+
return Data.builder()
122+
.endpoint(READINESS_HTTP_ENDPOINT)
123+
.invocationTimeout(READINESS_INVOCATION_TIMEOUT)
124+
.interval(READINESS_INTERVAL)
125+
.build();
126+
}
127+
128+
private static CloudProcess buildExpected(org.cloudfoundry.multiapps.controller.client.facade.domain.HealthCheckType type,
129+
Integer interval, String readinessHealthCheckType) {
130+
return ImmutableCloudProcess.builder()
131+
.command(COMMAND)
132+
.instances(INSTANCES)
133+
.memoryInMb(MEMORY_IN_MB)
134+
.diskInMb(DISK_IN_MB)
135+
.healthCheckType(type)
136+
.healthCheckHttpEndpoint(HTTP_ENDPOINT)
137+
.healthCheckTimeout(TIMEOUT)
138+
.healthCheckInvocationTimeout(INVOCATION_TIMEOUT)
139+
.healthCheckInterval(interval)
140+
.readinessHealthCheckType(readinessHealthCheckType)
141+
.readinessHealthCheckHttpEndpoint(READINESS_HTTP_ENDPOINT)
142+
.readinessHealthCheckInvocationTimeout(READINESS_INVOCATION_TIMEOUT)
143+
.readinessHealthCheckInterval(READINESS_INTERVAL)
144+
.build();
145+
}
146+
}

0 commit comments

Comments
 (0)