Skip to content

Commit 11d94b2

Browse files
committed
Code review
code review
1 parent 7ef2899 commit 11d94b2

13 files changed

Lines changed: 444 additions & 28 deletions

File tree

api/revapi.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@
4545
"code": "java.method.addedToInterface",
4646
"new": "method io.smallrye.mutiny.Uni<java.lang.Void> io.smallrye.stork.api.ServiceRegistrar<MetadataKeyType extends java.lang.Enum<MetadataKeyType> & io.smallrye.stork.api.MetadataKey>::registerServiceInstance(java.lang.String, java.lang.String, java.util.List<java.lang.String>, io.smallrye.stork.api.Metadata<MetadataKeyType>, java.lang.String, int)",
4747
"justification": "Added tags parameter to support tagging service instances at registration time."
48+
},
49+
{
50+
"ignore": true,
51+
"code": "java.method.addedToInterface",
52+
"new": "method io.smallrye.mutiny.Uni<java.lang.Void> io.smallrye.stork.api.ServiceRegistrar<MetadataKeyType extends java.lang.Enum<MetadataKeyType> & io.smallrye.stork.api.MetadataKey>::registerServiceInstance(java.lang.String, java.util.List<java.lang.String>, io.smallrye.stork.api.Metadata<MetadataKeyType>, java.lang.String, int)",
53+
"justification": "Added tags-only registration method (without instanceName) as a default method, backward-compatible."
4854
}
4955
]
5056
}

api/src/main/java/io/smallrye/stork/api/Service.java

Lines changed: 103 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,10 @@ public ServiceRegistrar getServiceRegistrar() {
239239
* @return a {@link Uni} completing when the registration is done
240240
*/
241241
public Uni<Void> registerInstance(String ipAddress, int port) {
242+
if (serviceRegistrar == null) {
243+
return Uni.createFrom()
244+
.failure(new UnsupportedOperationException("This service has no service registrar configured."));
245+
}
242246
return serviceRegistrar.registerServiceInstance(serviceName, ipAddress, port);
243247
}
244248

@@ -250,11 +254,44 @@ public Uni<Void> registerInstance(String ipAddress, int port) {
250254
* @param port the port of the instance
251255
* @return a {@link Uni} completing when the registration is done
252256
*/
253-
public Uni<Void> registerInstance(String instanceName, String ipAddress, int port) {
257+
public Uni<Void> registerNamedInstance(String instanceName, String ipAddress, int port) {
258+
if (serviceRegistrar == null) {
259+
return Uni.createFrom()
260+
.failure(new UnsupportedOperationException("This service has no service registrar configured."));
261+
}
254262
return serviceRegistrar.registerServiceInstance(serviceName, instanceName, Metadata.empty(), ipAddress, port);
255263
}
256264

257-
public Uni<Void> registerInstance(String instanceName, List<String> tags, String ipAddress, int port) {
265+
/**
266+
* Registers a service instance with tags.
267+
*
268+
* @param tags the tags to associate with this instance
269+
* @param ipAddress the IP address of the instance
270+
* @param port the port of the instance
271+
* @return a {@link Uni} completing when the registration is done
272+
*/
273+
public Uni<Void> registerInstance(List<String> tags, String ipAddress, int port) {
274+
if (serviceRegistrar == null) {
275+
return Uni.createFrom()
276+
.failure(new UnsupportedOperationException("This service has no service registrar configured."));
277+
}
278+
return serviceRegistrar.registerServiceInstance(serviceName, tags, Metadata.empty(), ipAddress, port);
279+
}
280+
281+
/**
282+
* Registers a service instance with an explicit instance name and tags.
283+
*
284+
* @param instanceName the unique identifier for this instance in the registry
285+
* @param tags the tags to associate with this instance
286+
* @param ipAddress the IP address of the instance
287+
* @param port the port of the instance
288+
* @return a {@link Uni} completing when the registration is done
289+
*/
290+
public Uni<Void> registerNamedInstance(String instanceName, List<String> tags, String ipAddress, int port) {
291+
if (serviceRegistrar == null) {
292+
return Uni.createFrom()
293+
.failure(new UnsupportedOperationException("This service has no service registrar configured."));
294+
}
258295
return serviceRegistrar.registerServiceInstance(serviceName, instanceName, tags, Metadata.empty(), ipAddress, port);
259296
}
260297

@@ -265,31 +302,79 @@ public Uni<Void> registerInstance(String instanceName, List<String> tags, String
265302
* @return a {@link Uni} completing when the registration is done
266303
*/
267304
public Uni<Void> registerInstance(ServiceRegistrar.RegistrarOptions options) {
305+
if (serviceRegistrar == null) {
306+
return Uni.createFrom()
307+
.failure(new UnsupportedOperationException("This service has no service registrar configured."));
308+
}
268309
return serviceRegistrar.registerServiceInstance(options);
269310
}
270311

312+
/**
313+
* @deprecated Use {@link #registerInstance(String, int)} instead. The service name is already
314+
* known by this {@link Service} instance.
315+
*/
316+
@Deprecated(forRemoval = true)
317+
public Uni<Void> registerInstance(String serviceName, String ipAddress, int port) {
318+
return registerInstance(ipAddress, port);
319+
}
320+
321+
/**
322+
* @deprecated Use {@link #registerNamedInstance(String, String, int)} instead. The service name
323+
* is already known by this {@link Service} instance.
324+
*/
325+
@Deprecated(forRemoval = true)
326+
public Uni<Void> registerInstance(String serviceName, String instanceName, String ipAddress, int port) {
327+
return registerNamedInstance(instanceName, ipAddress, port);
328+
}
329+
271330
/**
272331
* Deregisters all instances of this service.
273332
*
274333
* @return a {@link Uni} completing when the deregistration is done
275-
* @deprecated Prefer {@link #deregisterServiceInstance(String, int)} or
276-
* {@link #deregisterServiceInstance(String)} to target a specific instance.
334+
* @deprecated Prefer {@link #deregisterNamedInstance(String)} or
335+
* {@link #deregisterServiceInstance(String, int)} to target a specific instance.
277336
*/
278337
@Deprecated(forRemoval = true)
279338
public Uni<Void> deregisterServiceInstance() {
339+
if (serviceRegistrar == null) {
340+
return Uni.createFrom()
341+
.failure(new UnsupportedOperationException("This service has no service registrar configured."));
342+
}
280343
return serviceRegistrar.deregisterServiceInstance(serviceName);
281344
}
282345

346+
/**
347+
* @deprecated Use {@link #deregisterServiceInstance()} instead. The service name is already
348+
* known by this {@link Service} instance.
349+
*/
350+
@Deprecated(forRemoval = true)
351+
public Uni<Void> deregisterServiceInstance(String serviceName) {
352+
return deregisterServiceInstance();
353+
}
354+
283355
/**
284356
* Deregisters the service instance identified by the given instance name.
285357
*
286358
* @param instanceName the registration ID of the instance to deregister
287359
* @return a {@link Uni} completing when the deregistration is done
288360
*/
289-
public Uni<Void> deregisterServiceInstance(String instanceName) {
361+
public Uni<Void> deregisterNamedInstance(String instanceName) {
362+
if (serviceRegistrar == null) {
363+
return Uni.createFrom()
364+
.failure(new UnsupportedOperationException("This service has no service registrar configured."));
365+
}
290366
return serviceRegistrar.deregisterServiceInstance(serviceName, instanceName);
291367
}
292368

369+
/**
370+
* @deprecated Use {@link #deregisterNamedInstance(String)} instead. The service name is already
371+
* known by this {@link Service} instance.
372+
*/
373+
@Deprecated(forRemoval = true)
374+
public Uni<Void> deregisterServiceInstance(String serviceName, String instanceName) {
375+
return deregisterNamedInstance(instanceName);
376+
}
377+
293378
/**
294379
* Deregisters the service instance identified by the given IP address and port.
295380
*
@@ -298,9 +383,22 @@ public Uni<Void> deregisterServiceInstance(String instanceName) {
298383
* @return a {@link Uni} completing when the deregistration is done
299384
*/
300385
public Uni<Void> deregisterServiceInstance(String ipAddress, int port) {
386+
if (serviceRegistrar == null) {
387+
return Uni.createFrom()
388+
.failure(new UnsupportedOperationException("This service has no service registrar configured."));
389+
}
301390
return serviceRegistrar.deregisterServiceInstance(serviceName, ipAddress, port);
302391
}
303392

393+
/**
394+
* @deprecated Use {@link #deregisterServiceInstance(String, int)} instead. The service name is
395+
* already known by this {@link Service} instance.
396+
*/
397+
@Deprecated(forRemoval = true)
398+
public Uni<Void> deregisterServiceInstance(String serviceName, String ipAddress, int port) {
399+
return deregisterServiceInstance(ipAddress, port);
400+
}
401+
304402
public ObservationCollector getObservations() {
305403
return observations;
306404
}

api/src/main/java/io/smallrye/stork/api/ServiceRegistrar.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,29 @@ default void checkRegistrarOptionsNotNull(RegistrarOptions options) {
3232

3333
default Uni<Void> registerServiceInstance(String serviceName, Metadata<MetadataKeyType> metadata, String ipAddress,
3434
int defaultPort) {
35-
return registerServiceInstance(serviceName, null, metadata, ipAddress, defaultPort);
35+
return registerServiceInstance(serviceName, (String) null, metadata, ipAddress, defaultPort);
36+
}
37+
38+
default Uni<Void> registerServiceInstance(String serviceName, List<String> tags,
39+
Metadata<MetadataKeyType> metadata, String ipAddress, int defaultPort) {
40+
return registerServiceInstance(serviceName, null, tags, metadata, ipAddress, defaultPort);
3641
}
3742

3843
Uni<Void> registerServiceInstance(String serviceName, String instanceName, Metadata<MetadataKeyType> metadata,
3944
String ipAddress, int defaultPort);
4045

41-
Uni<Void> registerServiceInstance(String serviceName, String instanceName, List<String> tags,
42-
Metadata<MetadataKeyType> metadata, String ipAddress, int defaultPort);
46+
default Uni<Void> registerServiceInstance(String serviceName, String instanceName, List<String> tags,
47+
Metadata<MetadataKeyType> metadata, String ipAddress, int defaultPort) {
48+
return registerServiceInstance(serviceName, instanceName, metadata, ipAddress, defaultPort);
49+
}
4350

4451
default Uni<Void> registerServiceInstance(RegistrarOptions options) {
4552
checkRegistrarOptionsNotNull(options);
4653
checkAddressNotNull(options.ipAddress());
4754

48-
return registerServiceInstance(options.serviceName(), options.ipAddress(), options.defaultPort());
55+
return registerServiceInstance(options.serviceName(), null, options.tags() != null ? options.tags() : List.of(),
56+
Metadata.empty(), options.ipAddress(),
57+
options.defaultPort());
4958
}
5059

5160
@Deprecated
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package io.smallrye.stork.api;
2+
3+
import java.util.List;
4+
5+
import org.junit.jupiter.api.Assertions;
6+
import org.junit.jupiter.api.Test;
7+
8+
import io.smallrye.mutiny.Uni;
9+
import io.smallrye.stork.api.observability.NoopObservationCollector;
10+
11+
class ServiceTest {
12+
13+
private static Service newServiceWithoutRegistrar() {
14+
return new Service("my-service", "round-robin", "test-discovery", new NoopObservationCollector(),
15+
serviceInstances -> {
16+
throw new AssertionError("Load balancer should not be used in this test");
17+
},
18+
() -> Uni.createFrom().item(List.of()), null, false);
19+
}
20+
21+
@Test
22+
void registerInstanceShouldFailWhenRegistrarIsMissing() {
23+
Service service = newServiceWithoutRegistrar();
24+
25+
UnsupportedOperationException exception = Assertions.assertThrows(UnsupportedOperationException.class,
26+
() -> service.registerInstance("127.0.0.1", 8080).await().indefinitely());
27+
28+
Assertions.assertEquals("This service has no service registrar configured.", exception.getMessage());
29+
}
30+
31+
@Test
32+
void registerNamedInstanceShouldFailWhenRegistrarIsMissing() {
33+
Service service = newServiceWithoutRegistrar();
34+
35+
Assertions.assertThrows(UnsupportedOperationException.class,
36+
() -> service.registerNamedInstance("instance-1", "127.0.0.1", 8080).await().indefinitely());
37+
}
38+
39+
@Test
40+
void deregisterNamedInstanceShouldFailWhenRegistrarIsMissing() {
41+
Service service = newServiceWithoutRegistrar();
42+
43+
Assertions.assertThrows(UnsupportedOperationException.class,
44+
() -> service.deregisterNamedInstance("instance-1").await().indefinitely());
45+
}
46+
47+
@Test
48+
void deregisterByAddressShouldFailWhenRegistrarIsMissing() {
49+
Service service = newServiceWithoutRegistrar();
50+
51+
Assertions.assertThrows(UnsupportedOperationException.class,
52+
() -> service.deregisterServiceInstance("127.0.0.1", 8080).await().indefinitely());
53+
}
54+
55+
@Test
56+
void registerWithOptionsShouldFailWhenRegistrarIsMissing() {
57+
Service service = newServiceWithoutRegistrar();
58+
59+
ServiceRegistrar.RegistrarOptions options = new ServiceRegistrar.RegistrarOptions(
60+
"my-service", "127.0.0.1", 8080, List.of("tag-1"), null);
61+
62+
Assertions.assertThrows(UnsupportedOperationException.class,
63+
() -> service.registerInstance(options).await().indefinitely());
64+
}
65+
66+
@Test
67+
void registerWithTagsShouldFailWhenRegistrarIsMissing() {
68+
Service service = newServiceWithoutRegistrar();
69+
70+
Assertions.assertThrows(UnsupportedOperationException.class,
71+
() -> service.registerInstance(List.of("v1.0"), "127.0.0.1", 8080).await().indefinitely());
72+
}
73+
74+
@Test
75+
void registerNamedInstanceWithTagsShouldFailWhenRegistrarIsMissing() {
76+
Service service = newServiceWithoutRegistrar();
77+
78+
Assertions.assertThrows(UnsupportedOperationException.class,
79+
() -> service.registerNamedInstance("instance-1", List.of("v1.0"), "127.0.0.1", 8080).await()
80+
.indefinitely());
81+
}
82+
83+
@Test
84+
void deregisterAllShouldFailWhenRegistrarIsMissing() {
85+
Service service = newServiceWithoutRegistrar();
86+
87+
Assertions.assertThrows(UnsupportedOperationException.class,
88+
() -> service.deregisterServiceInstance().await().indefinitely());
89+
}
90+
}

docs/docs/service-registration/custom-service-registration.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ Finally, you can implement your own service deregistration mechanism in `deregis
8888
The default implementations of the second and third methods fall back to the first, which may deregister **all** instances.
8989
**Custom registrar implementations should override at least one of the specific-instance methods** to provide precise, instance-level deregistration and avoid unintended side effects.
9090

91+
Note that the `Service` class wraps these with simpler methods that do not require passing the service name:
92+
`deregisterNamedInstance(instanceName)`, `deregisterServiceInstance(ipAddress, port)`, and the deprecated no-arg `deregisterServiceInstance()`.
93+
9194

9295
## Using your service registrar using the programmatic API
9396

docs/docs/service-registration/overview.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ SmallRye Stork now supports deregistration of service instances from a central r
3939
This feature complements the registration mechanism.
4040

4141
This operation is typically should be triggered when a service instance is shut down or no longer available, helping maintain a consistent and accurate service registry.
42-
To enable service deregistration, you can invoke the `deregisterServiceInstance` method on the `ServiceRegistrar` implementation programmatically.
43-
To target a specific instance, prefer one of these overloads:
42+
To enable service deregistration, you can invoke the deregistration methods on the `Service` instance programmatically.
43+
To target a specific instance, prefer one of these methods:
4444

45-
- `deregisterServiceInstance(serviceName, instanceName)` — deregisters the instance registered under the given name.
46-
- `deregisterServiceInstance(serviceName, ipAddress, port)` — deregisters the instance identified by IP and port.
45+
- `deregisterNamedInstance(instanceName)` — deregisters the instance registered under the given name.
46+
- `deregisterServiceInstance(ipAddress, port)` — deregisters the instance identified by IP and port.
4747

48-
The single-argument overload `deregisterServiceInstance(serviceName)` deregisters **all** instances of the service.
48+
The no-argument overload `deregisterServiceInstance()` deregisters **all** instances of the service and is deprecated, prefer one of the specific methods above.
4949

5050
**Note**: When used in standalone mode, Stork does **not** automatically handle service instance registration or deregistration.
5151
However, when using the quarkus-stork-registration extension within a Quarkus application,

docs/snippets/examples/AcmeRegistrarApiUsage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public void example(StorkServiceRegistry stork) {
1414
new AcmeLoadBalancerConfiguration().withMyAttribute("my-value"),new AcmeRegistrarConfiguration())
1515
);
1616

17-
stork.getService("my-service").registerInstance("my-service", "localhost",
17+
stork.getService("my-service").registerNamedInstance("my-instance", "localhost",
1818
9000);
1919
}
2020

0 commit comments

Comments
 (0)