|
33 | 33 | import java.util.concurrent.CopyOnWriteArrayList; |
34 | 34 | import java.util.function.BiFunction; |
35 | 35 |
|
| 36 | +import static io.modelcontextprotocol.spec.McpError.RESOURCE_NOT_FOUND; |
| 37 | + |
36 | 38 | /** |
37 | 39 | * A stateless MCP server implementation for use with Streamable HTTP transport types. It |
38 | 40 | * allows simple horizontal scalability since it does not maintain a session and does not |
@@ -478,23 +480,24 @@ private List<ResourceTemplate> getResourceTemplates() { |
478 | 480 |
|
479 | 481 | private McpStatelessRequestHandler<McpSchema.ReadResourceResult> resourcesReadRequestHandler() { |
480 | 482 | return (ctx, params) -> { |
481 | | - McpSchema.ReadResourceRequest resourceRequest = jsonMapper.convertValue(params, |
482 | | - new TypeRef<McpSchema.ReadResourceRequest>() { |
483 | | - }); |
| 483 | + McpSchema.ReadResourceRequest resourceRequest = jsonMapper.convertValue(params, new TypeRef<>() { |
| 484 | + }); |
484 | 485 | var resourceUri = resourceRequest.uri(); |
485 | | - |
486 | | - McpStatelessServerFeatures.AsyncResourceSpecification specification = this.resources.values() |
487 | | - .stream() |
488 | | - .filter(resourceSpecification -> this.uriTemplateManagerFactory |
489 | | - .create(resourceSpecification.resource().uri()) |
490 | | - .matches(resourceUri)) |
491 | | - .findFirst() |
492 | | - .orElseThrow(() -> new McpError("Resource not found: " + resourceUri)); |
493 | | - |
494 | | - return specification.readHandler().apply(ctx, resourceRequest); |
| 486 | + return asyncResourceSpecification(resourceUri).map(spec -> spec.readHandler().apply(ctx, resourceRequest)) |
| 487 | + .orElseGet(() -> Mono.error(RESOURCE_NOT_FOUND.apply(resourceUri))); |
495 | 488 | }; |
496 | 489 | } |
497 | 490 |
|
| 491 | + private Optional<McpStatelessServerFeatures.AsyncResourceSpecification> asyncResourceSpecification( |
| 492 | + String resourceUri) { |
| 493 | + return resources.values() |
| 494 | + .stream() |
| 495 | + .filter(resourceSpecification -> this.uriTemplateManagerFactory |
| 496 | + .create(resourceSpecification.resource().uri()) |
| 497 | + .matches(resourceUri)) |
| 498 | + .findFirst(); |
| 499 | + } |
| 500 | + |
498 | 501 | // --------------------------------------- |
499 | 502 | // Prompt Management |
500 | 503 | // --------------------------------------- |
@@ -612,10 +615,10 @@ private McpStatelessRequestHandler<McpSchema.CompleteResult> completionCompleteR |
612 | 615 | } |
613 | 616 |
|
614 | 617 | if (type.equals("ref/resource") && request.ref() instanceof McpSchema.ResourceReference resourceReference) { |
615 | | - McpStatelessServerFeatures.AsyncResourceSpecification resourceSpec = this.resources |
| 618 | + McpStatelessServerFeatures.AsyncResourceSpecification resourceSpec = resources |
616 | 619 | .get(resourceReference.uri()); |
617 | 620 | if (resourceSpec == null) { |
618 | | - return Mono.error(new McpError("Resource not found: " + resourceReference.uri())); |
| 621 | + return Mono.error(RESOURCE_NOT_FOUND.apply(resourceReference.uri())); |
619 | 622 | } |
620 | 623 | if (!uriTemplateManagerFactory.create(resourceSpec.resource().uri()) |
621 | 624 | .getVariableNames() |
|
0 commit comments