forked from modelcontextprotocol/java-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWebMvcSseIntegrationTests.java
More file actions
124 lines (97 loc) · 3.87 KB
/
Copy pathWebMvcSseIntegrationTests.java
File metadata and controls
124 lines (97 loc) · 3.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
* Copyright 2024 - 2024 the original author or authors.
*/
package io.modelcontextprotocol.server;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.Duration;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleState;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.function.RouterFunction;
import org.springframework.web.servlet.function.ServerResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.AbstractMcpClientServerIntegrationTests;
import io.modelcontextprotocol.client.McpClient;
import io.modelcontextprotocol.client.transport.HttpClientSseClientTransport;
import io.modelcontextprotocol.client.transport.WebFluxSseClientTransport;
import io.modelcontextprotocol.server.McpServer.AsyncSpecification;
import io.modelcontextprotocol.server.McpServer.SingleSessionSyncSpecification;
import io.modelcontextprotocol.server.transport.WebMvcSseServerTransportProvider;
import reactor.core.scheduler.Schedulers;
class WebMvcSseIntegrationTests extends AbstractMcpClientServerIntegrationTests {
private static final int PORT = TestUtil.findAvailablePort();
private static final String MESSAGE_ENDPOINT = "/mcp/message";
private WebMvcSseServerTransportProvider mcpServerTransportProvider;
@Override
protected void prepareClients(int port, String mcpEndpoint) {
clientBuilders.put("httpclient",
McpClient.sync(HttpClientSseClientTransport.builder("http://localhost:" + port).build())
.requestTimeout(Duration.ofHours(10)));
clientBuilders.put("webflux", McpClient
.sync(WebFluxSseClientTransport.builder(WebClient.builder().baseUrl("http://localhost:" + port)).build())
.requestTimeout(Duration.ofHours(10)));
}
@Configuration
@EnableWebMvc
static class TestConfig {
@Bean
public WebMvcSseServerTransportProvider webMvcSseServerTransportProvider() {
return WebMvcSseServerTransportProvider.builder()
.objectMapper(new ObjectMapper())
.messageEndpoint(MESSAGE_ENDPOINT)
.build();
}
@Bean
public RouterFunction<ServerResponse> routerFunction(WebMvcSseServerTransportProvider transportProvider) {
return transportProvider.getRouterFunction();
}
}
private TomcatTestUtil.TomcatServer tomcatServer;
@BeforeEach
public void before() {
tomcatServer = TomcatTestUtil.createTomcatServer("", PORT, TestConfig.class);
try {
tomcatServer.tomcat().start();
assertThat(tomcatServer.tomcat().getServer().getState()).isEqualTo(LifecycleState.STARTED);
}
catch (Exception e) {
throw new RuntimeException("Failed to start Tomcat", e);
}
prepareClients(PORT, MESSAGE_ENDPOINT);
// Get the transport from Spring context
mcpServerTransportProvider = tomcatServer.appContext().getBean(WebMvcSseServerTransportProvider.class);
}
@AfterEach
public void after() {
reactor.netty.http.HttpResources.disposeLoopsAndConnections();
if (mcpServerTransportProvider != null) {
mcpServerTransportProvider.closeGracefully().block();
}
Schedulers.shutdownNow();
if (tomcatServer.appContext() != null) {
tomcatServer.appContext().close();
}
if (tomcatServer.tomcat() != null) {
try {
tomcatServer.tomcat().stop();
tomcatServer.tomcat().destroy();
}
catch (LifecycleException e) {
throw new RuntimeException("Failed to stop Tomcat", e);
}
}
}
@Override
protected AsyncSpecification<?> prepareAsyncServerBuilder() {
return McpServer.async(mcpServerTransportProvider);
}
@Override
protected SingleSessionSyncSpecification prepareSyncServerBuilder() {
return McpServer.sync(mcpServerTransportProvider);
}
}