From 2801a82b5469c20cf4962773b3d5a872abeedfcb Mon Sep 17 00:00:00 2001 From: Yamada Mikio Date: Tue, 23 Jun 2026 17:14:09 +0900 Subject: [PATCH 1/7] Make it possible to permit empty endpoints in CD endpoint groups --- .../armeria/CentralDogmaEndpointGroup.java | 25 ++++++++++++++++--- .../CentralDogmaEndpointGroupBuilder.java | 6 +++-- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java index 9e74b9a80..9861236a7 100644 --- a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java +++ b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java @@ -73,7 +73,7 @@ public final class CentralDogmaEndpointGroup extends DynamicEndpointGroup { public static CentralDogmaEndpointGroup ofWatcher(Watcher watcher, EndpointListDecoder endpointListDecoder) { return new CentralDogmaEndpointGroup<>(EndpointSelectionStrategy.weightedRoundRobin(), - watcher, endpointListDecoder); + watcher, endpointListDecoder, false); } /** @@ -107,13 +107,30 @@ public static CentralDogmaEndpointGroup of(CentralDogma centralDogma, */ public static CentralDogmaEndpointGroupBuilder builder(Watcher watcher, EndpointListDecoder endpointListDecoder) { - return new CentralDogmaEndpointGroupBuilder<>(watcher, endpointListDecoder); + return new CentralDogmaEndpointGroupBuilder<>(watcher, endpointListDecoder, false); + } + + /** + * Returns a new {@link CentralDogmaEndpointGroupBuilder} with the {@link Watcher} + * and {@link EndpointListDecoder}. You can create a {@link Watcher} using {@link CentralDogma}: + * + *
{@code
+     * CentralDogma centralDogma = ...
+     * Query query = ... // The query to the entry that contains the list of endpoints.
+     * Watcher watcher = centralDogma.fileWatcher(projectName, repositoryName, query);
+     * }
+ */ + public static CentralDogmaEndpointGroupBuilder builder(Watcher watcher, + EndpointListDecoder endpointListDecoder, + boolean allowEmptyEndpoints) { + return new CentralDogmaEndpointGroupBuilder<>(watcher, endpointListDecoder, allowEmptyEndpoints); } CentralDogmaEndpointGroup(EndpointSelectionStrategy strategy, Watcher instanceListWatcher, - EndpointListDecoder endpointListDecoder) { - super(strategy); + EndpointListDecoder endpointListDecoder, + boolean allowEmptyEndpoints) { + super(strategy, allowEmptyEndpoints); this.instanceListWatcher = requireNonNull(instanceListWatcher, "instanceListWatcher"); this.endpointListDecoder = requireNonNull(endpointListDecoder, "endpointListDecoder"); registerWatcher(); diff --git a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java index cbb167c02..340b03e23 100644 --- a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java +++ b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java @@ -32,11 +32,13 @@ public final class CentralDogmaEndpointGroupBuilder { private final Watcher watcher; private final EndpointListDecoder endpointListDecoder; + private final boolean allowEmptyEndpoints; private EndpointSelectionStrategy selectionStrategy = EndpointSelectionStrategy.weightedRoundRobin(); - CentralDogmaEndpointGroupBuilder(Watcher watcher, EndpointListDecoder endpointListDecoder) { + CentralDogmaEndpointGroupBuilder(Watcher watcher, EndpointListDecoder endpointListDecoder, boolean allowEmptyEndpoints) { this.watcher = requireNonNull(watcher, "watcher"); this.endpointListDecoder = requireNonNull(endpointListDecoder, "endpointListDecoder"); + this.allowEmptyEndpoints = allowEmptyEndpoints; } /** @@ -52,6 +54,6 @@ public CentralDogmaEndpointGroupBuilder selectionStrategy(EndpointSelectionStrat * from an entry in Central Dogma. */ public CentralDogmaEndpointGroup build() { - return new CentralDogmaEndpointGroup<>(selectionStrategy, watcher, endpointListDecoder); + return new CentralDogmaEndpointGroup<>(selectionStrategy, watcher, endpointListDecoder, allowEmptyEndpoints); } } From 0fab12313c82239a90cf1fd4ced7e74f2e39659c Mon Sep 17 00:00:00 2001 From: Yamada Mikio Date: Tue, 23 Jun 2026 17:29:39 +0900 Subject: [PATCH 2/7] Comply with checkstyle --- .../client/armeria/CentralDogmaEndpointGroupBuilder.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java index 340b03e23..ac279948a 100644 --- a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java +++ b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java @@ -35,7 +35,8 @@ public final class CentralDogmaEndpointGroupBuilder { private final boolean allowEmptyEndpoints; private EndpointSelectionStrategy selectionStrategy = EndpointSelectionStrategy.weightedRoundRobin(); - CentralDogmaEndpointGroupBuilder(Watcher watcher, EndpointListDecoder endpointListDecoder, boolean allowEmptyEndpoints) { + CentralDogmaEndpointGroupBuilder(Watcher watcher, EndpointListDecoder endpointListDecoder, + boolean allowEmptyEndpoints) { this.watcher = requireNonNull(watcher, "watcher"); this.endpointListDecoder = requireNonNull(endpointListDecoder, "endpointListDecoder"); this.allowEmptyEndpoints = allowEmptyEndpoints; @@ -54,6 +55,7 @@ public CentralDogmaEndpointGroupBuilder selectionStrategy(EndpointSelectionStrat * from an entry in Central Dogma. */ public CentralDogmaEndpointGroup build() { - return new CentralDogmaEndpointGroup<>(selectionStrategy, watcher, endpointListDecoder, allowEmptyEndpoints); + return new CentralDogmaEndpointGroup<>(selectionStrategy, watcher, endpointListDecoder, + allowEmptyEndpoints); } } From 2c0f916beca87d7fcc427528e264de78d835407b Mon Sep 17 00:00:00 2001 From: Yamada Mikio Date: Tue, 23 Jun 2026 18:00:00 +0900 Subject: [PATCH 3/7] Permit empty if we're configured to allow empty --- .../centraldogma/client/armeria/CentralDogmaEndpointGroup.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java index 9861236a7..cf6d4c7bf 100644 --- a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java +++ b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java @@ -140,7 +140,7 @@ private void registerWatcher() { instanceListWatcher.watch((revision, instances) -> { try { final List newEndpoints = endpointListDecoder.decode(instances); - if (newEndpoints.isEmpty()) { + if (newEndpoints.isEmpty() && !allowsEmptyEndpoints()) { logger.info("Not refreshing the endpoint list of {} because it's empty. {}", instanceListWatcher, revision); return; From 7c5dd47ae3adcb6e52751a2ad9617acc650bae20 Mon Sep 17 00:00:00 2001 From: Yamada Mikio Date: Wed, 24 Jun 2026 09:10:22 +0900 Subject: [PATCH 4/7] Add explanatory javadoc --- .../client/armeria/CentralDogmaEndpointGroup.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java index cf6d4c7bf..1fa9fe182 100644 --- a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java +++ b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java @@ -119,6 +119,10 @@ public static CentralDogmaEndpointGroupBuilder builder(Watcher watcher * Query query = ... // The query to the entry that contains the list of endpoints. * Watcher watcher = centralDogma.fileWatcher(projectName, repositoryName, query); * } + * + * @param allowEmptyEndpoints if true, allow the group to start up with no endpoints instead of erroring, + * and allow the list of endpoints to become empty instead of always retaining + * the last non-empty version */ public static CentralDogmaEndpointGroupBuilder builder(Watcher watcher, EndpointListDecoder endpointListDecoder, From 5100eda72f7047bc2919f3ba1691609a4784c8be Mon Sep 17 00:00:00 2001 From: Yamada Mikio Date: Wed, 24 Jun 2026 12:20:03 +0900 Subject: [PATCH 5/7] Move parameter to builder rather than factory --- .../client/armeria/CentralDogmaEndpointGroup.java | 15 --------------- .../armeria/CentralDogmaEndpointGroupBuilder.java | 11 ++++++++++- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java index 1fa9fe182..1d4d71ff6 100644 --- a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java +++ b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java @@ -95,21 +95,6 @@ public static CentralDogmaEndpointGroup of(CentralDogma centralDogma, endpointListDecoder); } - /** - * Returns a new {@link CentralDogmaEndpointGroupBuilder} with the {@link Watcher} - * and {@link EndpointListDecoder}. You can create a {@link Watcher} using {@link CentralDogma}: - * - *
{@code
-     * CentralDogma centralDogma = ...
-     * Query query = ... // The query to the entry that contains the list of endpoints.
-     * Watcher watcher = centralDogma.fileWatcher(projectName, repositoryName, query);
-     * }
- */ - public static CentralDogmaEndpointGroupBuilder builder(Watcher watcher, - EndpointListDecoder endpointListDecoder) { - return new CentralDogmaEndpointGroupBuilder<>(watcher, endpointListDecoder, false); - } - /** * Returns a new {@link CentralDogmaEndpointGroupBuilder} with the {@link Watcher} * and {@link EndpointListDecoder}. You can create a {@link Watcher} using {@link CentralDogma}: diff --git a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java index ac279948a..ccd2f11d5 100644 --- a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java +++ b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java @@ -32,7 +32,7 @@ public final class CentralDogmaEndpointGroupBuilder { private final Watcher watcher; private final EndpointListDecoder endpointListDecoder; - private final boolean allowEmptyEndpoints; + private boolean allowEmptyEndpoints; private EndpointSelectionStrategy selectionStrategy = EndpointSelectionStrategy.weightedRoundRobin(); CentralDogmaEndpointGroupBuilder(Watcher watcher, EndpointListDecoder endpointListDecoder, @@ -58,4 +58,13 @@ public CentralDogmaEndpointGroup build() { return new CentralDogmaEndpointGroup<>(selectionStrategy, watcher, endpointListDecoder, allowEmptyEndpoints); } + + /** + * @param allowEmptyEndpoints if true, allow the group to start up with no endpoints instead of erroring, + * and allow the list of endpoints to become empty instead of always retaining + * the last non-empty version + */ + public void setAllowEmptyEndpoints(boolean allowEmptyEndpoints) { + this.allowEmptyEndpoints = allowEmptyEndpoints; + } } From 9d2358bafd1920b3d7445e0f12997374d793eb2a Mon Sep 17 00:00:00 2001 From: Yamada Mikio Date: Wed, 24 Jun 2026 12:37:11 +0900 Subject: [PATCH 6/7] Checkstyle --- .../client/armeria/CentralDogmaEndpointGroupBuilder.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java index ccd2f11d5..6d36f3ac7 100644 --- a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java +++ b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java @@ -60,9 +60,9 @@ public CentralDogmaEndpointGroup build() { } /** - * @param allowEmptyEndpoints if true, allow the group to start up with no endpoints instead of erroring, - * and allow the list of endpoints to become empty instead of always retaining - * the last non-empty version + * If set to true, allow the group to start up with no endpoints instead of erroring, + * and allow the list of endpoints to become empty instead of always retaining + * the last non-empty version. */ public void setAllowEmptyEndpoints(boolean allowEmptyEndpoints) { this.allowEmptyEndpoints = allowEmptyEndpoints; From 493ba0dc235efcf229d56cf14830b14ea1d99153 Mon Sep 17 00:00:00 2001 From: Yamada Mikio Date: Wed, 24 Jun 2026 16:18:17 +0900 Subject: [PATCH 7/7] Finish the adjustments --- .../client/armeria/CentralDogmaEndpointGroup.java | 9 ++------- .../client/armeria/CentralDogmaEndpointGroupBuilder.java | 7 +++---- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java index 1d4d71ff6..311371736 100644 --- a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java +++ b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroup.java @@ -104,15 +104,10 @@ public static CentralDogmaEndpointGroup of(CentralDogma centralDogma, * Query query = ... // The query to the entry that contains the list of endpoints. * Watcher watcher = centralDogma.fileWatcher(projectName, repositoryName, query); * } - * - * @param allowEmptyEndpoints if true, allow the group to start up with no endpoints instead of erroring, - * and allow the list of endpoints to become empty instead of always retaining - * the last non-empty version */ public static CentralDogmaEndpointGroupBuilder builder(Watcher watcher, - EndpointListDecoder endpointListDecoder, - boolean allowEmptyEndpoints) { - return new CentralDogmaEndpointGroupBuilder<>(watcher, endpointListDecoder, allowEmptyEndpoints); + EndpointListDecoder endpointListDecoder) { + return new CentralDogmaEndpointGroupBuilder<>(watcher, endpointListDecoder); } CentralDogmaEndpointGroup(EndpointSelectionStrategy strategy, diff --git a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java index 6d36f3ac7..5e6a4aa33 100644 --- a/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java +++ b/client/java-armeria/src/main/java/com/linecorp/centraldogma/client/armeria/CentralDogmaEndpointGroupBuilder.java @@ -35,11 +35,9 @@ public final class CentralDogmaEndpointGroupBuilder { private boolean allowEmptyEndpoints; private EndpointSelectionStrategy selectionStrategy = EndpointSelectionStrategy.weightedRoundRobin(); - CentralDogmaEndpointGroupBuilder(Watcher watcher, EndpointListDecoder endpointListDecoder, - boolean allowEmptyEndpoints) { + CentralDogmaEndpointGroupBuilder(Watcher watcher, EndpointListDecoder endpointListDecoder) { this.watcher = requireNonNull(watcher, "watcher"); this.endpointListDecoder = requireNonNull(endpointListDecoder, "endpointListDecoder"); - this.allowEmptyEndpoints = allowEmptyEndpoints; } /** @@ -64,7 +62,8 @@ public CentralDogmaEndpointGroup build() { * and allow the list of endpoints to become empty instead of always retaining * the last non-empty version. */ - public void setAllowEmptyEndpoints(boolean allowEmptyEndpoints) { + public CentralDogmaEndpointGroupBuilder setAllowEmptyEndpoints(boolean allowEmptyEndpoints) { this.allowEmptyEndpoints = allowEmptyEndpoints; + return this; } }