Remove deprecated APIs and modules for 1.0.0 release (#807)
- Remove mcp-json-jackson module (JacksonMcpJsonMapper, DefaultJsonSchemaValidator) - Remove deprecated session interfaces (McpServerSession, McpClientSession methods) - Remove deprecated server methods (loggingNotification, McpAsyncServerExchange constructor) - Remove deprecated schema definitions and constructors (McpSchema, McpError, tool/content classes) - Replace generic McpError with appropriate exception types (IllegalStateException, IllegalArgumentException) - Update all tests to use current APIs --------- Signed-off-by: Dariusz Jędrzejczyk <dariusz.jedrzejczyk@broadcom.com>
This commit is contained in:
parent
77bc64abb8
commit
4c1c3d8d5c
6 changed files with 261 additions and 1940 deletions
|
|
@ -9,10 +9,10 @@ import java.util.List;
|
|||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import io.modelcontextprotocol.json.McpJsonDefaults;
|
||||
import io.modelcontextprotocol.json.TypeRef;
|
||||
import io.modelcontextprotocol.spec.McpClientTransport;
|
||||
import io.modelcontextprotocol.spec.McpSchema;
|
||||
import io.modelcontextprotocol.spec.ProtocolVersions;
|
||||
import io.modelcontextprotocol.spec.McpSchema.JSONRPCNotification;
|
||||
import io.modelcontextprotocol.spec.McpSchema.JSONRPCRequest;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
|
@ -29,7 +29,7 @@ public class MockMcpClientTransport implements McpClientTransport {
|
|||
|
||||
private final BiConsumer<MockMcpClientTransport, McpSchema.JSONRPCMessage> interceptor;
|
||||
|
||||
private String protocolVersion = McpSchema.LATEST_PROTOCOL_VERSION;
|
||||
private String protocolVersion = ProtocolVersions.MCP_2025_11_25;
|
||||
|
||||
public MockMcpClientTransport() {
|
||||
this((t, msg) -> {
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ class AsyncToolSpecificationBuilderTest {
|
|||
assertThat(specification).isNotNull();
|
||||
assertThat(specification.tool()).isEqualTo(tool);
|
||||
assertThat(specification.callHandler()).isNotNull();
|
||||
assertThat(specification.call()).isNull(); // deprecated field should be null
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -107,12 +106,8 @@ class AsyncToolSpecificationBuilderTest {
|
|||
|
||||
McpServerFeatures.AsyncToolSpecification specification = McpServerFeatures.AsyncToolSpecification.builder()
|
||||
.tool(tool)
|
||||
.callHandler((exchange, request) -> {
|
||||
return Mono.just(CallToolResult.builder()
|
||||
.content(List.of(new TextContent(expectedResult)))
|
||||
.isError(false)
|
||||
.build());
|
||||
})
|
||||
.callHandler((exchange, request) -> Mono.just(
|
||||
CallToolResult.builder().content(List.of(new TextContent(expectedResult))).isError(false).build()))
|
||||
.build();
|
||||
|
||||
CallToolRequest request = new CallToolRequest("calculator", Map.of());
|
||||
|
|
@ -127,54 +122,6 @@ class AsyncToolSpecificationBuilderTest {
|
|||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
void deprecatedConstructorShouldWorkCorrectly() {
|
||||
Tool tool = McpSchema.Tool.builder()
|
||||
.name("deprecated-tool")
|
||||
.title("A deprecated tool")
|
||||
.inputSchema(EMPTY_JSON_SCHEMA)
|
||||
.build();
|
||||
String expectedResult = "deprecated result";
|
||||
|
||||
// Test the deprecated constructor that takes a 'call' function
|
||||
McpServerFeatures.AsyncToolSpecification specification = new McpServerFeatures.AsyncToolSpecification(tool,
|
||||
(exchange,
|
||||
arguments) -> Mono.just(CallToolResult.builder()
|
||||
.content(List.of(new TextContent(expectedResult)))
|
||||
.isError(false)
|
||||
.build()));
|
||||
|
||||
assertThat(specification).isNotNull();
|
||||
assertThat(specification.tool()).isEqualTo(tool);
|
||||
assertThat(specification.call()).isNotNull(); // deprecated field should be set
|
||||
assertThat(specification.callHandler()).isNotNull(); // should be automatically
|
||||
// created
|
||||
|
||||
// Test that the callTool function works (it should delegate to the call function)
|
||||
CallToolRequest request = new CallToolRequest("deprecated-tool", Map.of("arg1", "value1"));
|
||||
Mono<CallToolResult> resultMono = specification.callHandler().apply(null, request);
|
||||
|
||||
StepVerifier.create(resultMono).assertNext(result -> {
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.content()).hasSize(1);
|
||||
assertThat(result.content().get(0)).isInstanceOf(TextContent.class);
|
||||
assertThat(((TextContent) result.content().get(0)).text()).isEqualTo(expectedResult);
|
||||
assertThat(result.isError()).isFalse();
|
||||
}).verifyComplete();
|
||||
|
||||
// Test that the deprecated call function also works directly
|
||||
Mono<CallToolResult> callResultMono = specification.call().apply(null, request.arguments());
|
||||
|
||||
StepVerifier.create(callResultMono).assertNext(result -> {
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.content()).hasSize(1);
|
||||
assertThat(result.content().get(0)).isInstanceOf(TextContent.class);
|
||||
assertThat(((TextContent) result.content().get(0)).text()).isEqualTo(expectedResult);
|
||||
assertThat(result.isError()).isFalse();
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void fromSyncShouldConvertSyncToolSpecificationCorrectly() {
|
||||
Tool tool = McpSchema.Tool.builder()
|
||||
|
|
@ -200,8 +147,6 @@ class AsyncToolSpecificationBuilderTest {
|
|||
assertThat(asyncSpec).isNotNull();
|
||||
assertThat(asyncSpec.tool()).isEqualTo(tool);
|
||||
assertThat(asyncSpec.callHandler()).isNotNull();
|
||||
assertThat(asyncSpec.call()).isNull(); // should be null since sync spec doesn't
|
||||
// have deprecated call
|
||||
|
||||
// Test that the converted async specification works correctly
|
||||
CallToolRequest request = new CallToolRequest("sync-tool", Map.of("param", "value"));
|
||||
|
|
@ -216,59 +161,6 @@ class AsyncToolSpecificationBuilderTest {
|
|||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
void fromSyncShouldConvertSyncToolSpecificationWithDeprecatedCallCorrectly() {
|
||||
Tool tool = McpSchema.Tool.builder()
|
||||
.name("sync-deprecated-tool")
|
||||
.title("A sync tool with deprecated call")
|
||||
.inputSchema(EMPTY_JSON_SCHEMA)
|
||||
.build();
|
||||
String expectedResult = "sync deprecated result";
|
||||
McpAsyncServerExchange nullExchange = null; // Mock or create a suitable exchange
|
||||
// if needed
|
||||
|
||||
// Create a sync tool specification using the deprecated constructor
|
||||
McpServerFeatures.SyncToolSpecification syncSpec = new McpServerFeatures.SyncToolSpecification(tool,
|
||||
(exchange, arguments) -> CallToolResult.builder()
|
||||
.content(List.of(new TextContent(expectedResult)))
|
||||
.isError(false)
|
||||
.build());
|
||||
|
||||
// Convert to async using fromSync
|
||||
McpServerFeatures.AsyncToolSpecification asyncSpec = McpServerFeatures.AsyncToolSpecification
|
||||
.fromSync(syncSpec);
|
||||
|
||||
assertThat(asyncSpec).isNotNull();
|
||||
assertThat(asyncSpec.tool()).isEqualTo(tool);
|
||||
assertThat(asyncSpec.callHandler()).isNotNull();
|
||||
assertThat(asyncSpec.call()).isNotNull(); // should be set since sync spec has
|
||||
// deprecated call
|
||||
|
||||
// Test that the converted async specification works correctly via callTool
|
||||
CallToolRequest request = new CallToolRequest("sync-deprecated-tool", Map.of("param", "value"));
|
||||
Mono<CallToolResult> resultMono = asyncSpec.callHandler().apply(nullExchange, request);
|
||||
|
||||
StepVerifier.create(resultMono).assertNext(result -> {
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.content()).hasSize(1);
|
||||
assertThat(result.content().get(0)).isInstanceOf(TextContent.class);
|
||||
assertThat(((TextContent) result.content().get(0)).text()).isEqualTo(expectedResult);
|
||||
assertThat(result.isError()).isFalse();
|
||||
}).verifyComplete();
|
||||
|
||||
// Test that the deprecated call function also works
|
||||
Mono<CallToolResult> callResultMono = asyncSpec.call().apply(nullExchange, request.arguments());
|
||||
|
||||
StepVerifier.create(callResultMono).assertNext(result -> {
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.content()).hasSize(1);
|
||||
assertThat(result.content().get(0)).isInstanceOf(TextContent.class);
|
||||
assertThat(((TextContent) result.content().get(0)).text()).isEqualTo(expectedResult);
|
||||
assertThat(result.isError()).isFalse();
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void fromSyncShouldReturnNullWhenSyncSpecIsNull() {
|
||||
assertThat(McpServerFeatures.AsyncToolSpecification.fromSync(null)).isNull();
|
||||
|
|
@ -302,7 +194,8 @@ class AsyncToolSpecificationBuilderTest {
|
|||
void defaultShouldThrowOnInvalidName() {
|
||||
Tool invalidTool = Tool.builder().name("invalid tool name").build();
|
||||
|
||||
assertThatThrownBy(() -> McpServer.async(transportProvider).tool(invalidTool, (exchange, args) -> null))
|
||||
assertThatThrownBy(
|
||||
() -> McpServer.async(transportProvider).toolCall(invalidTool, (exchange, request) -> null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessageContaining("invalid characters");
|
||||
}
|
||||
|
|
@ -312,7 +205,7 @@ class AsyncToolSpecificationBuilderTest {
|
|||
System.setProperty(ToolNameValidator.STRICT_VALIDATION_PROPERTY, "false");
|
||||
Tool invalidTool = Tool.builder().name("invalid tool name").build();
|
||||
|
||||
assertThatCode(() -> McpServer.async(transportProvider).tool(invalidTool, (exchange, args) -> null))
|
||||
assertThatCode(() -> McpServer.async(transportProvider).toolCall(invalidTool, (exchange, request) -> null))
|
||||
.doesNotThrowAnyException();
|
||||
assertThat(logAppender.list).hasSize(1);
|
||||
}
|
||||
|
|
@ -323,7 +216,7 @@ class AsyncToolSpecificationBuilderTest {
|
|||
|
||||
assertThatCode(() -> McpServer.async(transportProvider)
|
||||
.strictToolNameValidation(false)
|
||||
.tool(invalidTool, (exchange, args) -> null)).doesNotThrowAnyException();
|
||||
.toolCall(invalidTool, (exchange, request) -> null)).doesNotThrowAnyException();
|
||||
assertThat(logAppender.list).hasSize(1);
|
||||
}
|
||||
|
||||
|
|
@ -334,7 +227,7 @@ class AsyncToolSpecificationBuilderTest {
|
|||
|
||||
assertThatThrownBy(() -> McpServer.async(transportProvider)
|
||||
.strictToolNameValidation(true)
|
||||
.tool(invalidTool, (exchange, args) -> null)).isInstanceOf(IllegalArgumentException.class)
|
||||
.toolCall(invalidTool, (exchange, request) -> null)).isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessageContaining("invalid characters");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ class McpAsyncServerExchangeTests {
|
|||
@Test
|
||||
void testLoggingNotificationWithNullMessage() {
|
||||
StepVerifier.create(exchange.loggingNotification(null)).verifyErrorSatisfies(error -> {
|
||||
assertThat(error).isInstanceOf(McpError.class).hasMessage("Logging message must not be null");
|
||||
assertThat(error).isInstanceOf(IllegalStateException.class).hasMessage("Logging message must not be null");
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -301,7 +301,8 @@ class McpAsyncServerExchangeTests {
|
|||
@Test
|
||||
void testCreateElicitationWithNullCapabilities() {
|
||||
// Given - Create exchange with null capabilities
|
||||
McpAsyncServerExchange exchangeWithNullCapabilities = new McpAsyncServerExchange(mockSession, null, clientInfo);
|
||||
McpAsyncServerExchange exchangeWithNullCapabilities = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
null, clientInfo, McpTransportContext.EMPTY);
|
||||
|
||||
McpSchema.ElicitRequest elicitRequest = McpSchema.ElicitRequest.builder()
|
||||
.message("Please provide your name")
|
||||
|
|
@ -309,7 +310,7 @@ class McpAsyncServerExchangeTests {
|
|||
|
||||
StepVerifier.create(exchangeWithNullCapabilities.createElicitation(elicitRequest))
|
||||
.verifyErrorSatisfies(error -> {
|
||||
assertThat(error).isInstanceOf(McpError.class)
|
||||
assertThat(error).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Client must be initialized. Call the initialize method first!");
|
||||
});
|
||||
|
||||
|
|
@ -324,15 +325,15 @@ class McpAsyncServerExchangeTests {
|
|||
.roots(true)
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange exchangeWithoutElicitation = new McpAsyncServerExchange(mockSession,
|
||||
capabilitiesWithoutElicitation, clientInfo);
|
||||
McpAsyncServerExchange exchangeWithoutElicitation = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithoutElicitation, clientInfo, McpTransportContext.EMPTY);
|
||||
|
||||
McpSchema.ElicitRequest elicitRequest = McpSchema.ElicitRequest.builder()
|
||||
.message("Please provide your name")
|
||||
.build();
|
||||
|
||||
StepVerifier.create(exchangeWithoutElicitation.createElicitation(elicitRequest)).verifyErrorSatisfies(error -> {
|
||||
assertThat(error).isInstanceOf(McpError.class)
|
||||
assertThat(error).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Client must be configured with elicitation capabilities");
|
||||
});
|
||||
|
||||
|
|
@ -348,8 +349,8 @@ class McpAsyncServerExchangeTests {
|
|||
.elicitation()
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange exchangeWithElicitation = new McpAsyncServerExchange(mockSession,
|
||||
capabilitiesWithElicitation, clientInfo);
|
||||
McpAsyncServerExchange exchangeWithElicitation = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithElicitation, clientInfo, McpTransportContext.EMPTY);
|
||||
|
||||
// Create a complex elicit request with schema
|
||||
java.util.Map<String, Object> requestedSchema = new java.util.HashMap<>();
|
||||
|
|
@ -391,8 +392,8 @@ class McpAsyncServerExchangeTests {
|
|||
.elicitation()
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange exchangeWithElicitation = new McpAsyncServerExchange(mockSession,
|
||||
capabilitiesWithElicitation, clientInfo);
|
||||
McpAsyncServerExchange exchangeWithElicitation = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithElicitation, clientInfo, McpTransportContext.EMPTY);
|
||||
|
||||
McpSchema.ElicitRequest elicitRequest = McpSchema.ElicitRequest.builder()
|
||||
.message("Please provide sensitive information")
|
||||
|
|
@ -418,8 +419,8 @@ class McpAsyncServerExchangeTests {
|
|||
.elicitation()
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange exchangeWithElicitation = new McpAsyncServerExchange(mockSession,
|
||||
capabilitiesWithElicitation, clientInfo);
|
||||
McpAsyncServerExchange exchangeWithElicitation = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithElicitation, clientInfo, McpTransportContext.EMPTY);
|
||||
|
||||
McpSchema.ElicitRequest elicitRequest = McpSchema.ElicitRequest.builder()
|
||||
.message("Please provide your information")
|
||||
|
|
@ -445,8 +446,8 @@ class McpAsyncServerExchangeTests {
|
|||
.elicitation()
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange exchangeWithElicitation = new McpAsyncServerExchange(mockSession,
|
||||
capabilitiesWithElicitation, clientInfo);
|
||||
McpAsyncServerExchange exchangeWithElicitation = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithElicitation, clientInfo, McpTransportContext.EMPTY);
|
||||
|
||||
McpSchema.ElicitRequest elicitRequest = McpSchema.ElicitRequest.builder()
|
||||
.message("Please provide your name")
|
||||
|
|
@ -467,7 +468,8 @@ class McpAsyncServerExchangeTests {
|
|||
@Test
|
||||
void testCreateMessageWithNullCapabilities() {
|
||||
|
||||
McpAsyncServerExchange exchangeWithNullCapabilities = new McpAsyncServerExchange(mockSession, null, clientInfo);
|
||||
McpAsyncServerExchange exchangeWithNullCapabilities = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
null, clientInfo, McpTransportContext.EMPTY);
|
||||
|
||||
McpSchema.CreateMessageRequest createMessageRequest = McpSchema.CreateMessageRequest.builder()
|
||||
.messages(Arrays
|
||||
|
|
@ -476,7 +478,7 @@ class McpAsyncServerExchangeTests {
|
|||
|
||||
StepVerifier.create(exchangeWithNullCapabilities.createMessage(createMessageRequest))
|
||||
.verifyErrorSatisfies(error -> {
|
||||
assertThat(error).isInstanceOf(McpError.class)
|
||||
assertThat(error).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Client must be initialized. Call the initialize method first!");
|
||||
});
|
||||
|
||||
|
|
@ -492,8 +494,8 @@ class McpAsyncServerExchangeTests {
|
|||
.roots(true)
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange exchangeWithoutSampling = new McpAsyncServerExchange(mockSession,
|
||||
capabilitiesWithoutSampling, clientInfo);
|
||||
McpAsyncServerExchange exchangeWithoutSampling = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithoutSampling, clientInfo, McpTransportContext.EMPTY);
|
||||
|
||||
McpSchema.CreateMessageRequest createMessageRequest = McpSchema.CreateMessageRequest.builder()
|
||||
.messages(Arrays
|
||||
|
|
@ -501,7 +503,7 @@ class McpAsyncServerExchangeTests {
|
|||
.build();
|
||||
|
||||
StepVerifier.create(exchangeWithoutSampling.createMessage(createMessageRequest)).verifyErrorSatisfies(error -> {
|
||||
assertThat(error).isInstanceOf(McpError.class)
|
||||
assertThat(error).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Client must be configured with sampling capabilities");
|
||||
});
|
||||
|
||||
|
|
@ -517,8 +519,8 @@ class McpAsyncServerExchangeTests {
|
|||
.sampling()
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange exchangeWithSampling = new McpAsyncServerExchange(mockSession, capabilitiesWithSampling,
|
||||
clientInfo);
|
||||
McpAsyncServerExchange exchangeWithSampling = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithSampling, clientInfo, McpTransportContext.EMPTY);
|
||||
|
||||
McpSchema.CreateMessageRequest createMessageRequest = McpSchema.CreateMessageRequest.builder()
|
||||
.messages(Arrays
|
||||
|
|
@ -553,8 +555,8 @@ class McpAsyncServerExchangeTests {
|
|||
.sampling()
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange exchangeWithSampling = new McpAsyncServerExchange(mockSession, capabilitiesWithSampling,
|
||||
clientInfo);
|
||||
McpAsyncServerExchange exchangeWithSampling = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithSampling, clientInfo, McpTransportContext.EMPTY);
|
||||
|
||||
// Create request with image content
|
||||
McpSchema.CreateMessageRequest createMessageRequest = McpSchema.CreateMessageRequest.builder()
|
||||
|
|
@ -588,8 +590,8 @@ class McpAsyncServerExchangeTests {
|
|||
.sampling()
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange exchangeWithSampling = new McpAsyncServerExchange(mockSession, capabilitiesWithSampling,
|
||||
clientInfo);
|
||||
McpAsyncServerExchange exchangeWithSampling = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithSampling, clientInfo, McpTransportContext.EMPTY);
|
||||
|
||||
McpSchema.CreateMessageRequest createMessageRequest = McpSchema.CreateMessageRequest.builder()
|
||||
.messages(Arrays
|
||||
|
|
@ -612,8 +614,8 @@ class McpAsyncServerExchangeTests {
|
|||
.sampling()
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange exchangeWithSampling = new McpAsyncServerExchange(mockSession, capabilitiesWithSampling,
|
||||
clientInfo);
|
||||
McpAsyncServerExchange exchangeWithSampling = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithSampling, clientInfo, McpTransportContext.EMPTY);
|
||||
|
||||
McpSchema.CreateMessageRequest createMessageRequest = McpSchema.CreateMessageRequest.builder()
|
||||
.messages(Arrays.asList(new McpSchema.SamplingMessage(McpSchema.Role.USER,
|
||||
|
|
@ -662,7 +664,7 @@ class McpAsyncServerExchangeTests {
|
|||
@Test
|
||||
void testPingWithMcpError() {
|
||||
// Given - Mock an MCP-specific error during ping
|
||||
McpError mcpError = new McpError("Server unavailable");
|
||||
McpError mcpError = McpError.builder(McpSchema.ErrorCodes.INTERNAL_ERROR).message("Server unavailable").build();
|
||||
when(mockSession.sendRequest(eq(McpSchema.METHOD_PING), eq(null), any(TypeRef.class)))
|
||||
.thenReturn(Mono.error(mcpError));
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import java.util.Arrays;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.modelcontextprotocol.common.McpTransportContext;
|
||||
import io.modelcontextprotocol.spec.McpError;
|
||||
import io.modelcontextprotocol.spec.McpSchema;
|
||||
import io.modelcontextprotocol.spec.McpServerSession;
|
||||
|
|
@ -54,7 +55,8 @@ class McpSyncServerExchangeTests {
|
|||
|
||||
clientInfo = new McpSchema.Implementation("test-client", "1.0.0");
|
||||
|
||||
asyncExchange = new McpAsyncServerExchange(mockSession, clientCapabilities, clientInfo);
|
||||
asyncExchange = new McpAsyncServerExchange("testSessionId", mockSession, clientCapabilities, clientInfo,
|
||||
McpTransportContext.EMPTY);
|
||||
exchange = new McpSyncServerExchange(asyncExchange);
|
||||
}
|
||||
|
||||
|
|
@ -212,7 +214,7 @@ class McpSyncServerExchangeTests {
|
|||
|
||||
@Test
|
||||
void testLoggingNotificationWithNullMessage() {
|
||||
assertThatThrownBy(() -> exchange.loggingNotification(null)).isInstanceOf(McpError.class)
|
||||
assertThatThrownBy(() -> exchange.loggingNotification(null)).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Logging message must not be null");
|
||||
}
|
||||
|
||||
|
|
@ -294,8 +296,8 @@ class McpSyncServerExchangeTests {
|
|||
@Test
|
||||
void testCreateElicitationWithNullCapabilities() {
|
||||
// Given - Create exchange with null capabilities
|
||||
McpAsyncServerExchange asyncExchangeWithNullCapabilities = new McpAsyncServerExchange(mockSession, null,
|
||||
clientInfo);
|
||||
McpAsyncServerExchange asyncExchangeWithNullCapabilities = new McpAsyncServerExchange("testSessionId",
|
||||
mockSession, null, clientInfo, McpTransportContext.EMPTY);
|
||||
McpSyncServerExchange exchangeWithNullCapabilities = new McpSyncServerExchange(
|
||||
asyncExchangeWithNullCapabilities);
|
||||
|
||||
|
|
@ -304,7 +306,7 @@ class McpSyncServerExchangeTests {
|
|||
.build();
|
||||
|
||||
assertThatThrownBy(() -> exchangeWithNullCapabilities.createElicitation(elicitRequest))
|
||||
.isInstanceOf(McpError.class)
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Client must be initialized. Call the initialize method first!");
|
||||
|
||||
// Verify that sendRequest was never called due to null capabilities
|
||||
|
|
@ -318,8 +320,8 @@ class McpSyncServerExchangeTests {
|
|||
.roots(true)
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange asyncExchangeWithoutElicitation = new McpAsyncServerExchange(mockSession,
|
||||
capabilitiesWithoutElicitation, clientInfo);
|
||||
McpAsyncServerExchange asyncExchangeWithoutElicitation = new McpAsyncServerExchange("testSessionId",
|
||||
mockSession, capabilitiesWithoutElicitation, clientInfo, McpTransportContext.EMPTY);
|
||||
McpSyncServerExchange exchangeWithoutElicitation = new McpSyncServerExchange(asyncExchangeWithoutElicitation);
|
||||
|
||||
McpSchema.ElicitRequest elicitRequest = McpSchema.ElicitRequest.builder()
|
||||
|
|
@ -327,7 +329,7 @@ class McpSyncServerExchangeTests {
|
|||
.build();
|
||||
|
||||
assertThatThrownBy(() -> exchangeWithoutElicitation.createElicitation(elicitRequest))
|
||||
.isInstanceOf(McpError.class)
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Client must be configured with elicitation capabilities");
|
||||
|
||||
// Verify that sendRequest was never called due to missing elicitation
|
||||
|
|
@ -342,8 +344,8 @@ class McpSyncServerExchangeTests {
|
|||
.elicitation()
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange asyncExchangeWithElicitation = new McpAsyncServerExchange(mockSession,
|
||||
capabilitiesWithElicitation, clientInfo);
|
||||
McpAsyncServerExchange asyncExchangeWithElicitation = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithElicitation, clientInfo, McpTransportContext.EMPTY);
|
||||
McpSyncServerExchange exchangeWithElicitation = new McpSyncServerExchange(asyncExchangeWithElicitation);
|
||||
|
||||
// Create a complex elicit request with schema
|
||||
|
|
@ -386,8 +388,8 @@ class McpSyncServerExchangeTests {
|
|||
.elicitation()
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange asyncExchangeWithElicitation = new McpAsyncServerExchange(mockSession,
|
||||
capabilitiesWithElicitation, clientInfo);
|
||||
McpAsyncServerExchange asyncExchangeWithElicitation = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithElicitation, clientInfo, McpTransportContext.EMPTY);
|
||||
McpSyncServerExchange exchangeWithElicitation = new McpSyncServerExchange(asyncExchangeWithElicitation);
|
||||
|
||||
McpSchema.ElicitRequest elicitRequest = McpSchema.ElicitRequest.builder()
|
||||
|
|
@ -414,8 +416,8 @@ class McpSyncServerExchangeTests {
|
|||
.elicitation()
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange asyncExchangeWithElicitation = new McpAsyncServerExchange(mockSession,
|
||||
capabilitiesWithElicitation, clientInfo);
|
||||
McpAsyncServerExchange asyncExchangeWithElicitation = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithElicitation, clientInfo, McpTransportContext.EMPTY);
|
||||
McpSyncServerExchange exchangeWithElicitation = new McpSyncServerExchange(asyncExchangeWithElicitation);
|
||||
|
||||
McpSchema.ElicitRequest elicitRequest = McpSchema.ElicitRequest.builder()
|
||||
|
|
@ -442,8 +444,8 @@ class McpSyncServerExchangeTests {
|
|||
.elicitation()
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange asyncExchangeWithElicitation = new McpAsyncServerExchange(mockSession,
|
||||
capabilitiesWithElicitation, clientInfo);
|
||||
McpAsyncServerExchange asyncExchangeWithElicitation = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithElicitation, clientInfo, McpTransportContext.EMPTY);
|
||||
McpSyncServerExchange exchangeWithElicitation = new McpSyncServerExchange(asyncExchangeWithElicitation);
|
||||
|
||||
McpSchema.ElicitRequest elicitRequest = McpSchema.ElicitRequest.builder()
|
||||
|
|
@ -465,8 +467,8 @@ class McpSyncServerExchangeTests {
|
|||
@Test
|
||||
void testCreateMessageWithNullCapabilities() {
|
||||
|
||||
McpAsyncServerExchange asyncExchangeWithNullCapabilities = new McpAsyncServerExchange(mockSession, null,
|
||||
clientInfo);
|
||||
McpAsyncServerExchange asyncExchangeWithNullCapabilities = new McpAsyncServerExchange("testSessionId",
|
||||
mockSession, null, clientInfo, McpTransportContext.EMPTY);
|
||||
McpSyncServerExchange exchangeWithNullCapabilities = new McpSyncServerExchange(
|
||||
asyncExchangeWithNullCapabilities);
|
||||
|
||||
|
|
@ -476,7 +478,7 @@ class McpSyncServerExchangeTests {
|
|||
.build();
|
||||
|
||||
assertThatThrownBy(() -> exchangeWithNullCapabilities.createMessage(createMessageRequest))
|
||||
.isInstanceOf(McpError.class)
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Client must be initialized. Call the initialize method first!");
|
||||
|
||||
// Verify that sendRequest was never called due to null capabilities
|
||||
|
|
@ -491,8 +493,8 @@ class McpSyncServerExchangeTests {
|
|||
.roots(true)
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange asyncExchangeWithoutSampling = new McpAsyncServerExchange(mockSession,
|
||||
capabilitiesWithoutSampling, clientInfo);
|
||||
McpAsyncServerExchange asyncExchangeWithoutSampling = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithoutSampling, clientInfo, McpTransportContext.EMPTY);
|
||||
McpSyncServerExchange exchangeWithoutSampling = new McpSyncServerExchange(asyncExchangeWithoutSampling);
|
||||
|
||||
McpSchema.CreateMessageRequest createMessageRequest = McpSchema.CreateMessageRequest.builder()
|
||||
|
|
@ -501,7 +503,7 @@ class McpSyncServerExchangeTests {
|
|||
.build();
|
||||
|
||||
assertThatThrownBy(() -> exchangeWithoutSampling.createMessage(createMessageRequest))
|
||||
.isInstanceOf(McpError.class)
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Client must be configured with sampling capabilities");
|
||||
|
||||
// Verify that sendRequest was never called due to missing sampling capabilities
|
||||
|
|
@ -516,8 +518,8 @@ class McpSyncServerExchangeTests {
|
|||
.sampling()
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange asyncExchangeWithSampling = new McpAsyncServerExchange(mockSession,
|
||||
capabilitiesWithSampling, clientInfo);
|
||||
McpAsyncServerExchange asyncExchangeWithSampling = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithSampling, clientInfo, McpTransportContext.EMPTY);
|
||||
McpSyncServerExchange exchangeWithSampling = new McpSyncServerExchange(asyncExchangeWithSampling);
|
||||
|
||||
McpSchema.CreateMessageRequest createMessageRequest = McpSchema.CreateMessageRequest.builder()
|
||||
|
|
@ -553,8 +555,8 @@ class McpSyncServerExchangeTests {
|
|||
.sampling()
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange asyncExchangeWithSampling = new McpAsyncServerExchange(mockSession,
|
||||
capabilitiesWithSampling, clientInfo);
|
||||
McpAsyncServerExchange asyncExchangeWithSampling = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithSampling, clientInfo, McpTransportContext.EMPTY);
|
||||
McpSyncServerExchange exchangeWithSampling = new McpSyncServerExchange(asyncExchangeWithSampling);
|
||||
|
||||
// Create request with image content
|
||||
|
|
@ -589,8 +591,8 @@ class McpSyncServerExchangeTests {
|
|||
.sampling()
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange asyncExchangeWithSampling = new McpAsyncServerExchange(mockSession,
|
||||
capabilitiesWithSampling, clientInfo);
|
||||
McpAsyncServerExchange asyncExchangeWithSampling = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithSampling, clientInfo, McpTransportContext.EMPTY);
|
||||
McpSyncServerExchange exchangeWithSampling = new McpSyncServerExchange(asyncExchangeWithSampling);
|
||||
|
||||
McpSchema.CreateMessageRequest createMessageRequest = McpSchema.CreateMessageRequest.builder()
|
||||
|
|
@ -614,8 +616,8 @@ class McpSyncServerExchangeTests {
|
|||
.sampling()
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange asyncExchangeWithSampling = new McpAsyncServerExchange(mockSession,
|
||||
capabilitiesWithSampling, clientInfo);
|
||||
McpAsyncServerExchange asyncExchangeWithSampling = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithSampling, clientInfo, McpTransportContext.EMPTY);
|
||||
McpSyncServerExchange exchangeWithSampling = new McpSyncServerExchange(asyncExchangeWithSampling);
|
||||
|
||||
McpSchema.CreateMessageRequest createMessageRequest = McpSchema.CreateMessageRequest.builder()
|
||||
|
|
@ -662,7 +664,7 @@ class McpSyncServerExchangeTests {
|
|||
@Test
|
||||
void testPingWithMcpError() {
|
||||
// Given - Mock an MCP-specific error during ping
|
||||
McpError mcpError = new McpError("Server unavailable");
|
||||
McpError mcpError = McpError.builder(McpSchema.ErrorCodes.INTERNAL_ERROR).message("Server unavailable").build();
|
||||
when(mockSession.sendRequest(eq(McpSchema.METHOD_PING), eq(null), any(TypeRef.class)))
|
||||
.thenReturn(Mono.error(mcpError));
|
||||
|
||||
|
|
|
|||
|
|
@ -41,10 +41,26 @@ public class ResourceTemplateListingTest {
|
|||
void testResourceListingWithMixedResources() {
|
||||
// Create resource list with both regular and template resources
|
||||
List<McpSchema.Resource> allResources = List.of(
|
||||
new McpSchema.Resource("file:///test/doc1.txt", "Document 1", "text/plain", null, null),
|
||||
new McpSchema.Resource("file:///test/doc2.txt", "Document 2", "text/plain", null, null),
|
||||
new McpSchema.Resource("file:///test/{type}/document.txt", "Typed Document", "text/plain", null, null),
|
||||
new McpSchema.Resource("file:///users/{userId}/files/{fileId}", "User File", "text/plain", null, null));
|
||||
McpSchema.Resource.builder()
|
||||
.uri("file:///test/doc1.txt")
|
||||
.name("Document 1")
|
||||
.mimeType("text/plain")
|
||||
.build(),
|
||||
McpSchema.Resource.builder()
|
||||
.uri("file:///test/doc2.txt")
|
||||
.name("Document 2")
|
||||
.mimeType("text/plain")
|
||||
.build(),
|
||||
McpSchema.Resource.builder()
|
||||
.uri("file:///test/{type}/document.txt")
|
||||
.name("Typed Document")
|
||||
.mimeType("text/plain")
|
||||
.build(),
|
||||
McpSchema.Resource.builder()
|
||||
.uri("file:///users/{userId}/files/{fileId}")
|
||||
.name("User File")
|
||||
.mimeType("text/plain")
|
||||
.build());
|
||||
|
||||
// Apply the filter logic from McpAsyncServer line 438
|
||||
List<McpSchema.Resource> filteredResources = allResources.stream()
|
||||
|
|
@ -61,9 +77,16 @@ public class ResourceTemplateListingTest {
|
|||
void testResourceTemplatesListedSeparately() {
|
||||
// Create mixed resources
|
||||
List<McpSchema.Resource> resources = List.of(
|
||||
new McpSchema.Resource("file:///test/regular.txt", "Regular Resource", "text/plain", null, null),
|
||||
new McpSchema.Resource("file:///test/user/{userId}/profile.txt", "User Profile", "text/plain", null,
|
||||
null));
|
||||
McpSchema.Resource.builder()
|
||||
.uri("file:///test/regular.txt")
|
||||
.name("Regular Resource")
|
||||
.mimeType("text/plain")
|
||||
.build(),
|
||||
McpSchema.Resource.builder()
|
||||
.uri("file:///test/user/{userId}/profile.txt")
|
||||
.name("User Profile")
|
||||
.mimeType("text/plain")
|
||||
.build());
|
||||
|
||||
// Create explicit resource template
|
||||
McpSchema.ResourceTemplate explicitTemplate = new McpSchema.ResourceTemplate(
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@ class SyncToolSpecificationBuilderTest {
|
|||
assertThat(specification).isNotNull();
|
||||
assertThat(specification.tool()).isEqualTo(tool);
|
||||
assertThat(specification.callHandler()).isNotNull();
|
||||
assertThat(specification.call()).isNull(); // deprecated field should be null
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -140,7 +139,8 @@ class SyncToolSpecificationBuilderTest {
|
|||
void defaultShouldThrowOnInvalidName() {
|
||||
Tool invalidTool = Tool.builder().name("invalid tool name").build();
|
||||
|
||||
assertThatThrownBy(() -> McpServer.sync(transportProvider).tool(invalidTool, (exchange, args) -> null))
|
||||
assertThatThrownBy(
|
||||
() -> McpServer.sync(transportProvider).toolCall(invalidTool, (exchange, request) -> null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessageContaining("invalid characters");
|
||||
}
|
||||
|
|
@ -150,7 +150,7 @@ class SyncToolSpecificationBuilderTest {
|
|||
System.setProperty(ToolNameValidator.STRICT_VALIDATION_PROPERTY, "false");
|
||||
Tool invalidTool = Tool.builder().name("invalid tool name").build();
|
||||
|
||||
assertThatCode(() -> McpServer.sync(transportProvider).tool(invalidTool, (exchange, args) -> null))
|
||||
assertThatCode(() -> McpServer.sync(transportProvider).toolCall(invalidTool, (exchange, request) -> null))
|
||||
.doesNotThrowAnyException();
|
||||
assertThat(logAppender.list).hasSize(1);
|
||||
}
|
||||
|
|
@ -161,7 +161,7 @@ class SyncToolSpecificationBuilderTest {
|
|||
|
||||
assertThatCode(() -> McpServer.sync(transportProvider)
|
||||
.strictToolNameValidation(false)
|
||||
.tool(invalidTool, (exchange, args) -> null)).doesNotThrowAnyException();
|
||||
.toolCall(invalidTool, (exchange, request) -> null)).doesNotThrowAnyException();
|
||||
assertThat(logAppender.list).hasSize(1);
|
||||
}
|
||||
|
||||
|
|
@ -172,7 +172,7 @@ class SyncToolSpecificationBuilderTest {
|
|||
|
||||
assertThatThrownBy(() -> McpServer.sync(transportProvider)
|
||||
.strictToolNameValidation(true)
|
||||
.tool(invalidTool, (exchange, args) -> null)).isInstanceOf(IllegalArgumentException.class)
|
||||
.toolCall(invalidTool, (exchange, request) -> null)).isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessageContaining("invalid characters");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue