Skip to content

Commit

Permalink
Fix logging IP version 6 addresses with scope in RediscoveryImpl
Browse files Browse the repository at this point in the history
The `Inet6Address.getHostAddress()` returns a string with `%scope-id` in the end if it is scoped. For instance, `fe80:0:0:0:ce66:1564:db8q:94b6%6`.

The `RediscoveryImpl` error handling logic used to construct a log message with such address that it would log using the `Logger.warn(String, Object...)` method.

However, some implementations of the `Logger` interface supply the values given directly to the `String.format(String, Object...)` method. In those cases, the precense of the `%6` part in the log message string results in a `java.util.UnknownFormatConversionException: Conversion = '6'` exception.

This update fixed this issue by supplying the address separately, thus letting the logging implementations to do the formatting.
  • Loading branch information
injectives committed Jun 21, 2023
1 parent 2660b23 commit 4b8ec49
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -316,13 +316,11 @@ private ClusterComposition handleRoutingProcedureError(
throw new CompletionException(error);
}

// Retriable error happened during discovery.
DiscoveryException discoveryError =
new DiscoveryException(format(RECOVERABLE_ROUTING_ERROR, routerAddress), error);
// Retryable error happened during discovery.
var discoveryError = new DiscoveryException(format(RECOVERABLE_ROUTING_ERROR, routerAddress), error);
Futures.combineErrors(baseError, discoveryError); // we record each failure here
String warningMessage = format(RECOVERABLE_DISCOVERY_ERROR_WITH_SERVER, routerAddress);
log.warn(warningMessage);
log.debug(warningMessage, discoveryError);
log.warn(RECOVERABLE_DISCOVERY_ERROR_WITH_SERVER, routerAddress);
log.debug(format(RECOVERABLE_DISCOVERY_ERROR_WITH_SERVER, routerAddress), discoveryError);
routingTable.forget(routerAddress);
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.startsWith;
Expand All @@ -54,6 +56,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
Expand Down Expand Up @@ -525,6 +528,35 @@ void shouldFailImmediatelyOnUnsupportedFeatureException() {
verify(table).forget(A);
}

@Test
void shouldLogScopedIPV6AddressWithStringFormattingLogger() throws UnknownHostException {
// GIVEN
var initialRouter = new BoltServerAddress("initialRouter", 7687);
var compositionProvider = compositionProviderMock(Collections.emptyMap());
var resolver = resolverMock(initialRouter, initialRouter);
var domainNameResolver = mock(DomainNameResolver.class);
var address = mock(InetAddress.class);
given(address.getHostAddress()).willReturn("fe80:0:0:0:ce66:1564:db8q:94b6%6");
given(domainNameResolver.resolve(initialRouter.host())).willReturn(new InetAddress[] {address});
var table = routingTableMock(true);
var pool = mock(ConnectionPool.class);
given(pool.acquire(any(), any()))
.willReturn(CompletableFuture.failedFuture(new ServiceUnavailableException("not available")));
var logging = mock(Logging.class);
var logger = mock(Logger.class);
given(logging.getLog(any(Class.class))).willReturn(logger);
doAnswer(invocationOnMock -> String.format(invocationOnMock.getArgument(0), invocationOnMock.getArgument(1)))
.when(logger)
.warn(any());
var rediscovery =
new RediscoveryImpl(initialRouter, compositionProvider, resolver, logging, domainNameResolver);

// WHEN & THEN
assertThrows(
ServiceUnavailableException.class,
() -> await(rediscovery.lookupClusterComposition(table, pool, Collections.emptySet(), null, null)));
}

private Rediscovery newRediscovery(
BoltServerAddress initialRouter,
ClusterCompositionProvider compositionProvider,
Expand Down

0 comments on commit 4b8ec49

Please sign in to comment.