From 4b6245aa94305a660b53cb90efac618d0a3c19a8 Mon Sep 17 00:00:00 2001 From: varnson Date: Fri, 21 Aug 2026 10:42:56 +0800 Subject: [PATCH 1/2] add getHealthServices to support cached Signed-off-by: varnson --- .../cloud/consul/ConsulAutoConfiguration.java | 4 +--- .../cloud/consul/ConsulClient.java | 11 +++++++--- .../consul/ConsulClientIntegrationTests.java | 22 +++++++++++++++++++ 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulAutoConfiguration.java b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulAutoConfiguration.java index 673496ab9..26c01055e 100644 --- a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulAutoConfiguration.java +++ b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulAutoConfiguration.java @@ -24,7 +24,6 @@ import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; -import java.util.Collections; import org.aspectj.lang.annotation.Aspect; import org.slf4j.Logger; @@ -242,8 +241,7 @@ public boolean resolve(Object argument, MethodParameter parameter, HttpRequestVa } if (params.getConsistencyMode() != ConsulClient.ConsistencyMode.DEFAULT) { - builder.configureRequestParams( - map -> map.put(params.getConsistencyMode().getParamName(), Collections.emptyList())); + builder.addRequestParameter(params.getConsistencyMode().getParamName(), "true"); } if (params.getWaitTime() != -1) { diff --git a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulClient.java b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulClient.java index 369a5effb..ca9d9a573 100644 --- a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulClient.java +++ b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulClient.java @@ -108,6 +108,12 @@ ResponseEntity> getHealthServices(@PathVariable String servi @RequestParam boolean passing, @RequestHeader(name = ACL_TOKEN_HEADER, required = false) String aclToken, @RequestParam(required = false) List tag, QueryParams queryParams); + @GetExchange("/v1/health/service/{serviceName}") + ResponseEntity> getHealthServices(@PathVariable String serviceName, + @RequestParam boolean passing, @RequestHeader(name = ACL_TOKEN_HEADER, required = false) String aclToken, + @RequestParam(required = false) List tag, QueryParams queryParams, + @RequestParam(required = false) boolean cached); + @DeleteExchange("/v1/kv/{context}") ResponseEntity deleteKVValues(@PathVariable String context); @@ -182,12 +188,11 @@ public QueryParams(String datacenter, long waitTime, long index) { this(datacenter, ConsistencyMode.DEFAULT, waitTime, index, null); } - private QueryParams(String datacenter, ConsistencyMode consistencyMode, long waitTime, long index) { + public QueryParams(String datacenter, ConsistencyMode consistencyMode, long waitTime, long index) { this(datacenter, consistencyMode, waitTime, index, null); } - private QueryParams(String datacenter, ConsistencyMode consistencyMode, long waitTime, long index, - String near) { + public QueryParams(String datacenter, ConsistencyMode consistencyMode, long waitTime, long index, String near) { this.datacenter = datacenter; this.consistencyMode = consistencyMode; this.waitTime = waitTime; diff --git a/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulClientIntegrationTests.java b/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulClientIntegrationTests.java index d2aec3689..75c9dd55c 100644 --- a/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulClientIntegrationTests.java +++ b/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulClientIntegrationTests.java @@ -35,6 +35,7 @@ import org.testcontainers.utility.DockerImageName; import org.springframework.cloud.consul.model.http.event.Event; +import org.springframework.cloud.consul.model.http.health.HealthService; import org.springframework.cloud.consul.model.http.kv.GetValue; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -151,6 +152,27 @@ void getKVValues_WithWaitTimeAndIndexAndAclToken() { assertThat(value.getDecodedValue()).isEqualTo("test"); } + @Test + void getHealthService() { + + mockServerClient.when(request().withMethod("GET").withPath("/v1/health/service/testservice")) + .respond(response().withStatusCode(200)); + ResponseEntity> response = client.getHealthServices("testservice", true, "token12345", + List.of("tag1", "tag2"), + new ConsulClient.QueryParams(null, ConsulClient.ConsistencyMode.STALE, 3, 12345), true); + + mockServerClient.verify(request().withMethod("GET") + .withPath("/v1/health/service/testservice") + .withHeader(Header.header("X-Consul-Token", "token12345")) + .withQueryStringParameter("tag", "tag1", "tag2") + .withQueryStringParameter("passing", "true") + .withQueryStringParameter("stale", "true") + .withQueryStringParameter("wait", "3s") + .withQueryStringParameter("index", "12345") + .withQueryStringParameter("cached", "true"), VerificationTimes.exactly(1)); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + @Test void eventListWithWaitTimeAndIndex() { From 4cad28f2709939ee66d53f37550eaceabd0a42ce Mon Sep 17 00:00:00 2001 From: varnson Date: Fri, 21 Aug 2026 19:23:17 +0800 Subject: [PATCH 2/2] fix getHealthService:allow cached to be null Signed-off-by: varnson --- .../cloud/consul/ConsulAutoConfiguration.java | 2 +- .../cloud/consul/ConsulClient.java | 2 +- .../consul/ConsulClientIntegrationTests.java | 21 ++++++++++++++++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulAutoConfiguration.java b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulAutoConfiguration.java index 26c01055e..fa15f9feb 100644 --- a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulAutoConfiguration.java +++ b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulAutoConfiguration.java @@ -240,7 +240,7 @@ public boolean resolve(Object argument, MethodParameter parameter, HttpRequestVa builder.addRequestParameter("dc", params.getDatacenter()); } - if (params.getConsistencyMode() != ConsulClient.ConsistencyMode.DEFAULT) { + if (params.getConsistencyMode() != null && params.getConsistencyMode() != ConsulClient.ConsistencyMode.DEFAULT) { builder.addRequestParameter(params.getConsistencyMode().getParamName(), "true"); } diff --git a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulClient.java b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulClient.java index ca9d9a573..aad549806 100644 --- a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulClient.java +++ b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulClient.java @@ -112,7 +112,7 @@ ResponseEntity> getHealthServices(@PathVariable String servi ResponseEntity> getHealthServices(@PathVariable String serviceName, @RequestParam boolean passing, @RequestHeader(name = ACL_TOKEN_HEADER, required = false) String aclToken, @RequestParam(required = false) List tag, QueryParams queryParams, - @RequestParam(required = false) boolean cached); + @RequestParam(required = false) Boolean cached); @DeleteExchange("/v1/kv/{context}") ResponseEntity deleteKVValues(@PathVariable String context); diff --git a/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulClientIntegrationTests.java b/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulClientIntegrationTests.java index 75c9dd55c..a1812c6b8 100644 --- a/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulClientIntegrationTests.java +++ b/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulClientIntegrationTests.java @@ -153,7 +153,7 @@ void getKVValues_WithWaitTimeAndIndexAndAclToken() { } @Test - void getHealthService() { + void getHealthServiceWithCached() { mockServerClient.when(request().withMethod("GET").withPath("/v1/health/service/testservice")) .respond(response().withStatusCode(200)); @@ -173,6 +173,25 @@ void getHealthService() { assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); } + @Test + void getHealthServiceWithoutCached() { + + mockServerClient.when(request().withMethod("GET").withPath("/v1/health/service/testservice")) + .respond(response().withStatusCode(200)); + ResponseEntity> response = client.getHealthServices("testservice", true, "token12345", + List.of("tag1", "tag2"), + new ConsulClient.QueryParams(null, null, 3, 12345), null); + + mockServerClient.verify(request().withMethod("GET") + .withPath("/v1/health/service/testservice") + .withHeader(Header.header("X-Consul-Token", "token12345")) + .withQueryStringParameter("tag", "tag1", "tag2") + .withQueryStringParameter("passing", "true") + .withQueryStringParameter("wait", "3s") + .withQueryStringParameter("index", "12345"), VerificationTimes.exactly(1)); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + @Test void eventListWithWaitTimeAndIndex() {