|
10 | 10 | import java.util.concurrent.atomic.AtomicReference; |
11 | 11 | import java.util.function.BiFunction; |
12 | 12 |
|
| 13 | +import org.slf4j.LoggerFactory; |
| 14 | + |
| 15 | +import ch.qos.logback.classic.Level; |
| 16 | +import ch.qos.logback.classic.Logger; |
| 17 | +import ch.qos.logback.classic.spi.ILoggingEvent; |
| 18 | +import ch.qos.logback.core.read.ListAppender; |
13 | 19 | import io.modelcontextprotocol.client.McpClient; |
14 | 20 | import io.modelcontextprotocol.client.transport.HttpClientStreamableHttpTransport; |
15 | 21 | import io.modelcontextprotocol.common.McpTransportContext; |
|
41 | 47 | import org.junit.jupiter.api.BeforeEach; |
42 | 48 | import org.junit.jupiter.api.Test; |
43 | 49 | import org.junit.jupiter.api.Timeout; |
44 | | - |
45 | 50 | import org.springframework.mock.web.MockHttpServletRequest; |
46 | 51 | import org.springframework.mock.web.MockHttpServletResponse; |
47 | 52 | import org.springframework.web.client.RestClient; |
@@ -766,61 +771,65 @@ void testThrownMcpErrorAndJsonRpcError() throws Exception { |
766 | 771 | } |
767 | 772 |
|
768 | 773 | @Test |
769 | | - void testInitializedNotificationCallReturnsAccepted() throws Exception { |
770 | | - var mcpServer = McpServer.sync(mcpStatelessServerTransport) |
771 | | - .serverInfo("test-server", "1.0.0") |
772 | | - .capabilities(ServerCapabilities.builder().build()) |
773 | | - .build(); |
774 | | - |
775 | | - McpSchema.JSONRPCNotification notification = new McpSchema.JSONRPCNotification(McpSchema.JSONRPC_VERSION, |
776 | | - McpSchema.METHOD_NOTIFICATION_INITIALIZED, null); |
777 | | - |
778 | | - MockHttpServletRequest request = new MockHttpServletRequest("POST", CUSTOM_MESSAGE_ENDPOINT); |
779 | | - MockHttpServletResponse response = new MockHttpServletResponse(); |
780 | | - |
781 | | - byte[] content = JSON_MAPPER.writeValueAsBytes(notification); |
782 | | - request.setContent(content); |
783 | | - request.addHeader("Content-Type", "application/json"); |
784 | | - request.addHeader("Content-Length", Integer.toString(content.length)); |
785 | | - request.addHeader("Accept", APPLICATION_JSON + ", " + TEXT_EVENT_STREAM); |
786 | | - request.addHeader("Cache-Control", "no-cache"); |
787 | | - request.addHeader(HttpHeaders.PROTOCOL_VERSION, ProtocolVersions.MCP_2025_03_26); |
| 774 | + void testInitializedNotificationDoesNotLogWarn() { |
| 775 | + Logger handlerLogger = (Logger) LoggerFactory |
| 776 | + .getLogger("io.modelcontextprotocol.server.DefaultMcpStatelessServerHandler"); |
| 777 | + ListAppender<ILoggingEvent> logAppender = new ListAppender<>(); |
| 778 | + logAppender.start(); |
| 779 | + handlerLogger.addAppender(logAppender); |
788 | 780 |
|
789 | | - mcpStatelessServerTransport.service(request, response); |
| 781 | + try { |
| 782 | + var mcpServer = McpServer.sync(mcpStatelessServerTransport) |
| 783 | + .serverInfo("test-server", "1.0.0") |
| 784 | + .capabilities(ServerCapabilities.builder().build()) |
| 785 | + .build(); |
790 | 786 |
|
791 | | - assertThat(response.getStatus()).isEqualTo(202); |
792 | | - assertThat(response.getContentAsByteArray()).isEmpty(); |
| 787 | + try (var mcpClient = clientBuilder.build()) { |
| 788 | + mcpClient.initialize(); // automatically sends notifications/initialized |
| 789 | + } |
| 790 | + finally { |
| 791 | + mcpServer.close(); |
| 792 | + } |
| 793 | + } |
| 794 | + finally { |
| 795 | + handlerLogger.detachAppender(logAppender); |
| 796 | + logAppender.stop(); |
| 797 | + } |
793 | 798 |
|
794 | | - mcpServer.close(); |
| 799 | + assertThat(logAppender.list).noneMatch(event -> event.getLevel() == Level.WARN |
| 800 | + && (event.getFormattedMessage().contains(McpSchema.METHOD_NOTIFICATION_INITIALIZED) |
| 801 | + || event.getFormattedMessage().contains("Missing handler for request type"))); |
795 | 802 | } |
796 | 803 |
|
797 | 804 | @Test |
798 | | - void testRootsListChangedNotificationCallReturnsAccepted() throws Exception { |
799 | | - var mcpServer = McpServer.sync(mcpStatelessServerTransport) |
800 | | - .serverInfo("test-server", "1.0.0") |
801 | | - .capabilities(ServerCapabilities.builder().build()) |
802 | | - .build(); |
803 | | - |
804 | | - McpSchema.JSONRPCNotification notification = new McpSchema.JSONRPCNotification(McpSchema.JSONRPC_VERSION, |
805 | | - McpSchema.METHOD_NOTIFICATION_ROOTS_LIST_CHANGED, null); |
806 | | - |
807 | | - MockHttpServletRequest request = new MockHttpServletRequest("POST", CUSTOM_MESSAGE_ENDPOINT); |
808 | | - MockHttpServletResponse response = new MockHttpServletResponse(); |
809 | | - |
810 | | - byte[] content = JSON_MAPPER.writeValueAsBytes(notification); |
811 | | - request.setContent(content); |
812 | | - request.addHeader("Content-Type", "application/json"); |
813 | | - request.addHeader("Content-Length", Integer.toString(content.length)); |
814 | | - request.addHeader("Accept", APPLICATION_JSON + ", " + TEXT_EVENT_STREAM); |
815 | | - request.addHeader("Cache-Control", "no-cache"); |
816 | | - request.addHeader(HttpHeaders.PROTOCOL_VERSION, ProtocolVersions.MCP_2025_03_26); |
| 805 | + void testRootsListChangedNotificationDoesNotLogWarn() { |
| 806 | + Logger handlerLogger = (Logger) LoggerFactory.getLogger(DefaultMcpStatelessServerHandler.class); |
| 807 | + ListAppender<ILoggingEvent> logAppender = new ListAppender<>(); |
| 808 | + logAppender.start(); |
| 809 | + handlerLogger.addAppender(logAppender); |
817 | 810 |
|
818 | | - mcpStatelessServerTransport.service(request, response); |
| 811 | + try { |
| 812 | + var mcpServer = McpServer.sync(mcpStatelessServerTransport) |
| 813 | + .serverInfo("test-server", "1.0.0") |
| 814 | + .capabilities(ServerCapabilities.builder().build()) |
| 815 | + .build(); |
819 | 816 |
|
820 | | - assertThat(response.getStatus()).isEqualTo(202); |
821 | | - assertThat(response.getContentAsByteArray()).isEmpty(); |
| 817 | + try (var mcpClient = clientBuilder.build()) { |
| 818 | + mcpClient.initialize(); |
| 819 | + mcpClient.rootsListChangedNotification(); |
| 820 | + } |
| 821 | + finally { |
| 822 | + mcpServer.close(); |
| 823 | + } |
| 824 | + } |
| 825 | + finally { |
| 826 | + handlerLogger.detachAppender(logAppender); |
| 827 | + logAppender.stop(); |
| 828 | + } |
822 | 829 |
|
823 | | - mcpServer.close(); |
| 830 | + assertThat(logAppender.list).noneMatch(event -> event.getLevel() == Level.WARN |
| 831 | + && (event.getFormattedMessage().contains(McpSchema.METHOD_NOTIFICATION_ROOTS_LIST_CHANGED) |
| 832 | + || event.getFormattedMessage().contains("Missing handler for request type"))); |
824 | 833 | } |
825 | 834 |
|
826 | 835 | private double evaluateExpression(String expression) { |
|
0 commit comments