Skip to content

Commit

Permalink
Merge pull request #330 from AxonFramework/bug/327-instance-without-c…
Browse files Browse the repository at this point in the history
…ommand-handlers

[#327] Default local `ServiceInstance` to a fixed `URI` i.o. `null`
  • Loading branch information
smcvb authored Oct 26, 2023
2 parents d5ae1db + fcbf525 commit de3d3d6
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@

import org.axonframework.commandhandling.distributed.CommandMessageFilter;
import org.axonframework.common.AxonConfigurationException;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;

import java.net.URI;
import java.util.concurrent.atomic.AtomicReference;

/**
Expand All @@ -42,7 +44,7 @@ public abstract class AbstractCapabilityDiscoveryMode<B extends CapabilityDiscov
*/
protected AbstractCapabilityDiscoveryMode(Builder<B> builder) {
builder.validate();
localInstance = new AtomicReference<>();
localInstance = new AtomicReference<>(FixedURIServiceInstance.INSTANCE);
localCapabilities = new AtomicReference<>(DefaultMemberCapabilities.INCAPABLE_MEMBER);
}

Expand Down Expand Up @@ -76,4 +78,23 @@ protected abstract static class Builder<B extends CapabilityDiscoveryMode> {
*/
protected abstract void validate();
}

/**
* This no-op version of the {@link DefaultServiceInstance} enforces the {@link ServiceInstance#getUri()} to a fixed
* empty {@link URI}. Through this, there's always a {@code ServiceInstance} present that will never match others.
* <p>
* This no-op version is the default local {@code ServiceInstance}, ensuring that when
* {@link #updateLocalCapabilities(ServiceInstance, int, CommandMessageFilter)} is never invoked (when an instance
* has zero command handlers) it will still play nicely in the discovery mechanism.
*/
private static class FixedURIServiceInstance extends DefaultServiceInstance {

private static final ServiceInstance INSTANCE = new FixedURIServiceInstance();
private static final URI FIXED_URI = URI.create("");

@Override
public URI getUri() {
return FIXED_URI;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ void setUp() {
}

@Test
void testGetLocalMemberCapabilitiesReturnsIncapableMemberIfLocalCapabilitiesIsNeverUpdated() {
void getLocalMemberCapabilitiesReturnsIncapableMemberIfLocalCapabilitiesIsNeverUpdated() {
SerializedMemberCapabilities result = ((RestCapabilityDiscoveryMode) testSubject).getLocalMemberCapabilities();

DefaultMemberCapabilities deserializableResult =
Expand All @@ -76,7 +76,7 @@ void testGetLocalMemberCapabilitiesReturnsIncapableMemberIfLocalCapabilitiesIsNe
}

@Test
void testGetLocalMemberCapabilitiesReturnsUpdatedLocalCapabilities() {
void getLocalMemberCapabilitiesReturnsUpdatedLocalCapabilities() {
testSubject.updateLocalCapabilities(localInstance, LOAD_FACTOR, COMMAND_MESSAGE_FILTER);

SerializedMemberCapabilities result = ((RestCapabilityDiscoveryMode) testSubject).getLocalMemberCapabilities();
Expand All @@ -88,7 +88,7 @@ void testGetLocalMemberCapabilitiesReturnsUpdatedLocalCapabilities() {
}

@Test
void testCapabilitiesReturnsLocalCapabilitiesIfLocalServiceInstanceIsUsed() {
void capabilitiesReturnsLocalCapabilitiesIfLocalServiceInstanceIsUsed() {
testSubject.updateLocalCapabilities(localInstance, LOAD_FACTOR, COMMAND_MESSAGE_FILTER);

Optional<MemberCapabilities> resultCapabilities = testSubject.capabilities(localInstance);
Expand All @@ -101,7 +101,7 @@ void testCapabilitiesReturnsLocalCapabilitiesIfLocalServiceInstanceIsUsed() {
}

@Test
void testCapabilitiesReturnsLocalCapabilitiesIfServiceInstanceUriMatches() {
void capabilitiesReturnsLocalCapabilitiesIfServiceInstanceUriMatches() {
URI testURI = URI.create("http://remote");
when(localInstance.getUri()).thenReturn(testURI);

Expand All @@ -120,9 +120,8 @@ void testCapabilitiesReturnsLocalCapabilitiesIfServiceInstanceUriMatches() {
}

@Test
void testCapabilitiesGetsCapabilitiesThroughRestTemplate() {
void capabilitiesGetsCapabilitiesThroughRestTemplate() {
MemberCapabilities expectedCapabilities = new DefaultMemberCapabilities(LOAD_FACTOR, COMMAND_MESSAGE_FILTER);
testSubject.updateLocalCapabilities(localInstance, LOAD_FACTOR, COMMAND_MESSAGE_FILTER);

URI testURI = URI.create("http://remote");
ServiceInstance testServiceInstance = mock(ServiceInstance.class);
Expand Down Expand Up @@ -158,7 +157,7 @@ void testCapabilitiesGetsCapabilitiesThroughRestTemplate() {
}

@Test
void testCapabilitiesRethrowsHttpClientErrorExceptionAsServiceInstanceClientException() {
void capabilitiesRethrowsHttpClientErrorExceptionAsServiceInstanceClientException() {
testSubject.updateLocalCapabilities(localInstance, LOAD_FACTOR, COMMAND_MESSAGE_FILTER);

when(restTemplate.exchange(
Expand All @@ -182,7 +181,7 @@ void testCapabilitiesRethrowsHttpClientErrorExceptionAsServiceInstanceClientExce
}

@Test
void testCapabilitiesReturnsIncapableMemberWhenNonHttpClientErrorExceptionIsThrown() {
void capabilitiesReturnsIncapableMemberWhenNonHttpClientErrorExceptionIsThrown() {
testSubject.updateLocalCapabilities(localInstance, LOAD_FACTOR, COMMAND_MESSAGE_FILTER);

when(restTemplate.exchange(
Expand Down

0 comments on commit de3d3d6

Please sign in to comment.