diff --git a/core/src/main/java/com/minekube/connect/register/WatcherRegister.java b/core/src/main/java/com/minekube/connect/register/WatcherRegister.java index 4b8e7be28..0dc4e0e27 100644 --- a/core/src/main/java/com/minekube/connect/register/WatcherRegister.java +++ b/core/src/main/java/com/minekube/connect/register/WatcherRegister.java @@ -315,9 +315,14 @@ public void onProposal(SessionProposal proposal) { ).connect(); } catch (RuntimeException e) { reject(proposal, rejectionStatus(e)); - logger.warn("Rejected one Connect session proposal (category={}); " + + logger.warn("Rejected one Connect session proposal (category={}, message={}); " + "keeping WatchService active", - e.getClass().getSimpleName()); + e.getClass().getSimpleName(), e.getMessage()); + if (logger.isDebug()) { + logger.debug("Rejected one Connect session proposal (category={}, " + + "message={}); keeping WatchService active", + e.getClass().getSimpleName(), e.getMessage(), e); + } } catch (Error e) { reject(proposal, rejectionStatus(e)); throw e; diff --git a/core/src/test/java/com/minekube/connect/register/WatcherRegisterTest.java b/core/src/test/java/com/minekube/connect/register/WatcherRegisterTest.java index 597913cc2..d3ed1b053 100644 --- a/core/src/test/java/com/minekube/connect/register/WatcherRegisterTest.java +++ b/core/src/test/java/com/minekube/connect/register/WatcherRegisterTest.java @@ -8,6 +8,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; @@ -27,6 +28,7 @@ import com.minekube.connect.config.ConnectConfig; import com.minekube.connect.tunnel.p2p.Libp2pEndpoint; import com.minekube.connect.tunnel.Tunneler; +import com.minekube.connect.util.MessageFormatter; import com.minekube.connect.watch.SessionProposal; import com.minekube.connect.watch.WatchBootstrap; import com.minekube.connect.watch.WatchClient; @@ -34,6 +36,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.InetSocketAddress; +import java.util.ArrayList; import java.util.Base64; import java.util.List; import java.util.Map; @@ -439,6 +442,50 @@ void invalidWatchProposalCancelsPrivateAdmissionImmediately() throws Exception { } } + @Test + void rejectedProposalWarnCarriesTheExceptionMessage() throws Exception { + BedrockAdmissionCoordinator coordinator = new BedrockAdmissionCoordinator( + new VerifiedBedrockIdentityRegistry()); + try { + Fixture fixture = newFixture(coordinator); + ConnectLogger logger = (ConnectLogger) getField(fixture.register, "logger"); + List warns = new ArrayList<>(); + doAnswer(invocation -> { + Object[] raw = invocation.getRawArguments(); + warns.add(MessageFormatter.format((String) raw[0], (Object[]) raw[1])); + return null; + }).when(logger).warn(anyString(), any(Object[].class)); + + register = fixture.register; + register.start(); + ArgumentCaptor watcher = ArgumentCaptor.forClass(Watcher.class); + verify(fixture.watchClient).watch(watcher.capture()); + Session session = Session.newBuilder() + .setId("session-warn-message") + .setTunnelServiceAddr("wss://tunnel.example") + .setPlayer(Player.newBuilder() + .setAddr("127.0.0.1") + .setProfile(GameProfile.newBuilder() + .setId("00000000-0000-0000-0000-000000000001") + .setName("Player"))) + .build(); + SessionProposal superseded = coordinator.proposal( + session, reason -> {}, "endpoint-1", "org-1"); + SessionProposal current = coordinator.proposal( + session, reason -> {}, "endpoint-1", "org-1"); + + watcher.getValue().onProposal(superseded); + + assertFalse(warns.isEmpty(), "expected a proposal-rejection WARN"); + assertTrue(warns.stream().anyMatch(w -> w.contains("IllegalStateException") + && w.contains("expired or been superseded")), + "WARN must carry the exception message, got: " + warns); + coordinator.discard(current); + } finally { + coordinator.close(); + } + } + @Test void supersededProposalIsRejectedWithoutClosingTheWatchStream() throws Exception { BedrockAdmissionCoordinator coordinator = new BedrockAdmissionCoordinator(