Skip to content

Commit 060581d

Browse files
committed
Remove pluggable docker compose ReadinessCheck
Remove pluggable `ReadinessCheck` interface and only use the `TcpConnectServiceReadinessCheck` implementation for now. We may re-introduce pluggable checks in a future version. See gh-35544
1 parent 3d41e41 commit 060581d

File tree

6 files changed

+26
-117
lines changed

6 files changed

+26
-117
lines changed

spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/readiness/ServiceNotReadyException.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,8 @@
2424
* @author Moritz Halbritter
2525
* @author Andy Wilkinson
2626
* @author Phillip Webb
27-
* @since 3.1.0
28-
* @see ServiceReadinessCheck
2927
*/
30-
public class ServiceNotReadyException extends RuntimeException {
28+
class ServiceNotReadyException extends RuntimeException {
3129

3230
private final RunningService service;
3331

@@ -40,11 +38,7 @@ public class ServiceNotReadyException extends RuntimeException {
4038
this.service = service;
4139
}
4240

43-
/**
44-
* Return the service that was not ready.
45-
* @return the non-ready service
46-
*/
47-
public RunningService getService() {
41+
RunningService getService() {
4842
return this.service;
4943
}
5044

spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/readiness/ServiceReadinessCheck.java

Lines changed: 0 additions & 47 deletions
This file was deleted.

spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/readiness/ServiceReadinessChecks.java

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,10 @@
3232
import org.springframework.boot.docker.compose.core.RunningService;
3333
import org.springframework.core.env.Environment;
3434
import org.springframework.core.io.support.SpringFactoriesLoader;
35-
import org.springframework.core.io.support.SpringFactoriesLoader.ArgumentResolver;
3635
import org.springframework.core.log.LogMessage;
3736

3837
/**
39-
* A collection of {@link ServiceReadinessCheck} instances that can be used to
40-
* {@link #wait() wait} for {@link RunningService services} to be ready.
38+
* Utility used to {@link #wait() wait} for {@link RunningService services} to be ready.
4139
*
4240
* @author Moritz Halbritter
4341
* @author Andy Wilkinson
@@ -58,7 +56,7 @@ public class ServiceReadinessChecks {
5856

5957
private final ReadinessProperties properties;
6058

61-
private final List<ServiceReadinessCheck> checks;
59+
private final TcpConnectServiceReadinessCheck check;
6260

6361
public ServiceReadinessChecks(ClassLoader classLoader, Environment environment, Binder binder) {
6462
this(Clock.systemUTC(), ServiceReadinessChecks::sleep,
@@ -68,15 +66,11 @@ public ServiceReadinessChecks(ClassLoader classLoader, Environment environment,
6866

6967
ServiceReadinessChecks(Clock clock, Consumer<Duration> sleep, SpringFactoriesLoader loader, ClassLoader classLoader,
7068
Environment environment, Binder binder,
71-
Function<ReadinessProperties.Tcp, ServiceReadinessCheck> tcpCheckFactory) {
72-
ArgumentResolver argumentResolver = ArgumentResolver.of(ClassLoader.class, classLoader)
73-
.and(Environment.class, environment)
74-
.and(Binder.class, binder);
69+
Function<ReadinessProperties.Tcp, TcpConnectServiceReadinessCheck> tcpCheckFactory) {
7570
this.clock = clock;
7671
this.sleep = sleep;
7772
this.properties = ReadinessProperties.get(binder);
78-
this.checks = new ArrayList<>(loader.load(ServiceReadinessCheck.class, argumentResolver));
79-
this.checks.add(tcpCheckFactory.apply(this.properties.getTcp()));
73+
this.check = tcpCheckFactory.apply(this.properties.getTcp());
8074
}
8175

8276
/**
@@ -106,16 +100,14 @@ private List<ServiceNotReadyException> check(List<RunningService> runningService
106100
continue;
107101
}
108102
logger.trace(LogMessage.format("Checking readiness of service '%s'", service));
109-
for (ServiceReadinessCheck check : this.checks) {
110-
try {
111-
check.check(service);
112-
logger.trace(LogMessage.format("Service '%s' is ready", service));
113-
}
114-
catch (ServiceNotReadyException ex) {
115-
logger.trace(LogMessage.format("Service '%s' is not ready", service), ex);
116-
exceptions = (exceptions != null) ? exceptions : new ArrayList<>();
117-
exceptions.add(ex);
118-
}
103+
try {
104+
this.check.check(service);
105+
logger.trace(LogMessage.format("Service '%s' is ready", service));
106+
}
107+
catch (ServiceNotReadyException ex) {
108+
logger.trace(LogMessage.format("Service '%s' is not ready", service), ex);
109+
exceptions = (exceptions != null) ? exceptions : new ArrayList<>();
110+
exceptions.add(ex);
119111
}
120112
}
121113
return (exceptions != null) ? exceptions : Collections.emptyList();

spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/readiness/TcpConnectServiceReadinessCheck.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,13 @@
2424
import org.springframework.boot.docker.compose.core.RunningService;
2525

2626
/**
27-
* Default {@link ServiceReadinessCheck} that checks readiness by connecting to the
28-
* exposed TCP ports.
27+
* Checks readiness by connecting to the exposed TCP ports.
2928
*
3029
* @author Moritz Halbritter
3130
* @author Andy Wilkinson
3231
* @author Phillip Webb
3332
*/
34-
class TcpConnectServiceReadinessCheck implements ServiceReadinessCheck {
33+
class TcpConnectServiceReadinessCheck {
3534

3635
private static final String DISABLE_LABEL = "org.springframework.boot.readiness-check.tcp.disable";
3736

@@ -41,8 +40,7 @@ class TcpConnectServiceReadinessCheck implements ServiceReadinessCheck {
4140
this.properties = properties;
4241
}
4342

44-
@Override
45-
public void check(RunningService service) {
43+
void check(RunningService service) {
4644
if (service.labels().containsKey(DISABLE_LABEL)) {
4745
return;
4846
}

spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/readiness/ServiceReadinessChecksTests.java

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,16 @@
2525

2626
import org.junit.jupiter.api.BeforeEach;
2727
import org.junit.jupiter.api.Test;
28-
import org.mockito.ArgumentMatchers;
2928

3029
import org.springframework.boot.context.properties.bind.Binder;
3130
import org.springframework.boot.docker.compose.core.RunningService;
32-
import org.springframework.core.env.Environment;
33-
import org.springframework.core.io.support.SpringFactoriesLoader.ArgumentResolver;
3431
import org.springframework.core.test.io.support.MockSpringFactoriesLoader;
3532
import org.springframework.mock.env.MockEnvironment;
3633

3734
import static org.assertj.core.api.Assertions.assertThat;
3835
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
39-
import static org.mockito.ArgumentMatchers.eq;
4036
import static org.mockito.BDDMockito.given;
41-
import static org.mockito.BDDMockito.then;
4237
import static org.mockito.Mockito.mock;
43-
import static org.mockito.Mockito.spy;
4438

4539
/**
4640
* Tests for {@link ServiceReadinessChecks}.
@@ -67,8 +61,6 @@ class ServiceReadinessChecksTests {
6761

6862
private List<RunningService> runningServices;
6963

70-
private final MockServiceReadinessCheck mockTcpCheck = new MockServiceReadinessCheck();
71-
7264
@BeforeEach
7365
void setup() {
7466
this.clock = mock(Clock.class);
@@ -81,42 +73,25 @@ void setup() {
8173
this.runningServices = List.of(this.runningService);
8274
}
8375

84-
@Test
85-
void loadCanResolveArguments() {
86-
this.loader = spy(MockSpringFactoriesLoader.class);
87-
createChecks();
88-
then(this.loader).should()
89-
.load(eq(ServiceReadinessCheck.class), ArgumentMatchers.<ArgumentResolver>assertArg((argumentResolver) -> {
90-
assertThat(argumentResolver.resolve(ClassLoader.class)).isEqualTo(this.classLoader);
91-
assertThat(argumentResolver.resolve(Environment.class)).isEqualTo(this.environment);
92-
assertThat(argumentResolver.resolve(Binder.class)).isEqualTo(this.binder);
93-
}));
94-
}
95-
9676
@Test
9777
void waitUntilReadyWhenImmediatelyReady() {
9878
MockServiceReadinessCheck check = new MockServiceReadinessCheck();
99-
this.loader.addInstance(ServiceReadinessCheck.class, check);
100-
createChecks().waitUntilReady(this.runningServices);
79+
createChecks(check).waitUntilReady(this.runningServices);
10180
assertThat(check.getChecked()).contains(this.runningService);
102-
assertThat(this.mockTcpCheck.getChecked()).contains(this.runningService);
10381
}
10482

10583
@Test
10684
void waitUntilReadyWhenTakesTimeToBeReady() {
10785
MockServiceReadinessCheck check = new MockServiceReadinessCheck(2);
108-
this.loader.addInstance(ServiceReadinessCheck.class, check);
109-
createChecks().waitUntilReady(this.runningServices);
86+
createChecks(check).waitUntilReady(this.runningServices);
11087
assertThat(check.getChecked()).hasSize(2).contains(this.runningService);
111-
assertThat(this.mockTcpCheck.getChecked()).contains(this.runningService);
11288
}
11389

11490
@Test
11591
void waitUntilReadyWhenTimeout() {
11692
MockServiceReadinessCheck check = new MockServiceReadinessCheck(Integer.MAX_VALUE);
117-
this.loader.addInstance(ServiceReadinessCheck.class, check);
11893
assertThatExceptionOfType(ReadinessTimeoutException.class)
119-
.isThrownBy(() -> createChecks().waitUntilReady(this.runningServices))
94+
.isThrownBy(() -> createChecks(check).waitUntilReady(this.runningServices))
12095
.satisfies((ex) -> assertThat(ex.getSuppressed()).hasSize(1));
12196
assertThat(check.getChecked()).hasSizeGreaterThan(10);
12297
}
@@ -125,25 +100,23 @@ void waitUntilReadyWhenTimeout() {
125100
void waitForWhenServiceHasDisableLabelDoesNotCheck() {
126101
given(this.runningService.labels()).willReturn(Map.of("org.springframework.boot.readiness-check.disable", ""));
127102
MockServiceReadinessCheck check = new MockServiceReadinessCheck();
128-
this.loader.addInstance(ServiceReadinessCheck.class, check);
129-
createChecks().waitUntilReady(this.runningServices);
103+
createChecks(check).waitUntilReady(this.runningServices);
130104
assertThat(check.getChecked()).isEmpty();
131-
assertThat(this.mockTcpCheck.getChecked()).isEmpty();
132105
}
133106

134107
void sleep(Duration duration) {
135108
this.now = this.now.plus(duration);
136109
}
137110

138-
private ServiceReadinessChecks createChecks() {
111+
private ServiceReadinessChecks createChecks(TcpConnectServiceReadinessCheck check) {
139112
return new ServiceReadinessChecks(this.clock, this::sleep, this.loader, this.classLoader, this.environment,
140-
this.binder, (properties) -> this.mockTcpCheck);
113+
this.binder, (properties) -> check);
141114
}
142115

143116
/**
144-
* Mock {@link ServiceReadinessCheck}.
117+
* Mock {@link TcpConnectServiceReadinessCheck}.
145118
*/
146-
static class MockServiceReadinessCheck implements ServiceReadinessCheck {
119+
static class MockServiceReadinessCheck extends TcpConnectServiceReadinessCheck {
147120

148121
private final Integer failUntil;
149122

@@ -154,6 +127,7 @@ static class MockServiceReadinessCheck implements ServiceReadinessCheck {
154127
}
155128

156129
MockServiceReadinessCheck(Integer failUntil) {
130+
super(null);
157131
this.failUntil = failUntil;
158132
}
159133

spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/docker-compose.adoc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,6 @@ You can also change timeout values in your `application.properties` or `applicat
184184

185185
The overall timeout can be configured using configprop:spring.docker.compose.readiness.timeout[].
186186

187-
TIP: You can also provide your own `ServiceReadinessCheck` implementations and register them in the `spring.factories` file.
188-
189187

190188

191189
[[features.docker-compose.lifecycle]]

0 commit comments

Comments
 (0)