001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.rest.server.mcp.v20260728; 018 019import java.util.*; 020 021/** 022 * Binding-owned, immutable-after-construction cache configuration for a v2 {@link McpRevision}. 023 * 024 * <p> 025 * Applications populate one {@link McpCacheConfig} and pass it to 026 * {@link McpRevision#McpRevision(org.apache.juneau.bean.mcp.v20260728.ServerCapabilities, McpCacheConfig)}. Every 027 * setter validates its {@link McpCacheHint} argument eagerly (including entries assigned via 028 * {@link #setResourceReadOverrides(Map)}), so an invalid TTL fails at configuration time rather than at dispatch 029 * time. 030 * 031 * <p> 032 * This type holds no resolution logic; precedence between {@link #getDefaultHint()}, the per-method hints, and 033 * {@link #getResourceReadOverrides()} is owned by {@link McpRevision}. 034 */ 035public class McpCacheConfig { 036 037 private McpCacheHint defaultHint; 038 private McpCacheHint toolsList; 039 private McpCacheHint promptsList; 040 private McpCacheHint resourcesList; 041 private McpCacheHint resourceTemplatesList; 042 private McpCacheHint resourcesRead; 043 private McpCacheHint serverDiscover; 044 private Map<String,McpCacheHint> resourceReadOverrides = new LinkedHashMap<>(); 045 046 private static McpCacheHint validate(McpCacheHint value) { 047 if (value != null && value.getTtlMs() != null && value.getTtlMs() < 0) 048 throw new IllegalArgumentException("ttlMs " + value.getTtlMs() + " is below minimum 0"); 049 return value; 050 } 051 052 /** 053 * The fallback hint applied when a method-specific hint is not configured. 054 * 055 * @return The hint, or {@code null} if not set. 056 */ 057 public McpCacheHint getDefaultHint() { 058 return defaultHint; 059 } 060 061 /** 062 * Sets the fallback hint. 063 * 064 * @param value The new value. Can be {@code null} to unset the property. 065 * @return This object. 066 */ 067 public McpCacheConfig setDefaultHint(McpCacheHint value) { 068 defaultHint = validate(value); 069 return this; 070 } 071 072 /** 073 * The hint applied to {@code tools/list}. 074 * 075 * @return The hint, or {@code null} if not set. 076 */ 077 public McpCacheHint getToolsList() { 078 return toolsList; 079 } 080 081 /** 082 * Sets the hint applied to {@code tools/list}. 083 * 084 * @param value The new value. Can be {@code null} to unset the property. 085 * @return This object. 086 */ 087 public McpCacheConfig setToolsList(McpCacheHint value) { 088 toolsList = validate(value); 089 return this; 090 } 091 092 /** 093 * The hint applied to {@code prompts/list}. 094 * 095 * @return The hint, or {@code null} if not set. 096 */ 097 public McpCacheHint getPromptsList() { 098 return promptsList; 099 } 100 101 /** 102 * Sets the hint applied to {@code prompts/list}. 103 * 104 * @param value The new value. Can be {@code null} to unset the property. 105 * @return This object. 106 */ 107 public McpCacheConfig setPromptsList(McpCacheHint value) { 108 promptsList = validate(value); 109 return this; 110 } 111 112 /** 113 * The hint applied to {@code resources/list}. 114 * 115 * @return The hint, or {@code null} if not set. 116 */ 117 public McpCacheHint getResourcesList() { 118 return resourcesList; 119 } 120 121 /** 122 * Sets the hint applied to {@code resources/list}. 123 * 124 * @param value The new value. Can be {@code null} to unset the property. 125 * @return This object. 126 */ 127 public McpCacheConfig setResourcesList(McpCacheHint value) { 128 resourcesList = validate(value); 129 return this; 130 } 131 132 /** 133 * The hint applied to {@code resources/templates/list}. 134 * 135 * @return The hint, or {@code null} if not set. 136 */ 137 public McpCacheHint getResourceTemplatesList() { 138 return resourceTemplatesList; 139 } 140 141 /** 142 * Sets the hint applied to {@code resources/templates/list}. 143 * 144 * @param value The new value. Can be {@code null} to unset the property. 145 * @return This object. 146 */ 147 public McpCacheConfig setResourceTemplatesList(McpCacheHint value) { 148 resourceTemplatesList = validate(value); 149 return this; 150 } 151 152 /** 153 * The hint applied to {@code resources/read} when no per-URI override matches. 154 * 155 * @return The hint, or {@code null} if not set. 156 */ 157 public McpCacheHint getResourcesRead() { 158 return resourcesRead; 159 } 160 161 /** 162 * Sets the hint applied to {@code resources/read} when no per-URI override matches. 163 * 164 * @param value The new value. Can be {@code null} to unset the property. 165 * @return This object. 166 */ 167 public McpCacheConfig setResourcesRead(McpCacheHint value) { 168 resourcesRead = validate(value); 169 return this; 170 } 171 172 /** 173 * The hint applied to {@code server/discover}. 174 * 175 * @return The hint, or {@code null} if not set. 176 */ 177 public McpCacheHint getServerDiscover() { 178 return serverDiscover; 179 } 180 181 /** 182 * Sets the hint applied to {@code server/discover}. 183 * 184 * @param value The new value. Can be {@code null} to unset the property. 185 * @return This object. 186 */ 187 public McpCacheConfig setServerDiscover(McpCacheHint value) { 188 serverDiscover = validate(value); 189 return this; 190 } 191 192 /** 193 * Per-URI hint overrides for {@code resources/read}, keyed by exact resource URI. 194 * 195 * <p> 196 * Returns an unmodifiable view (in insertion order) so callers cannot bypass validation via direct mutation. 197 * 198 * @return An unmodifiable map. Never {@code null}. 199 */ 200 public Map<String,McpCacheHint> getResourceReadOverrides() { 201 return Collections.unmodifiableMap(resourceReadOverrides); 202 } 203 204 /** 205 * Replaces the per-URI hint overrides. 206 * 207 * @param value The new value (or {@code null} to clear). Every entry is validated; a {@code null} URI key is 208 * rejected. 209 * @return This object. 210 */ 211 public McpCacheConfig setResourceReadOverrides(Map<String,McpCacheHint> value) { 212 var copy = new LinkedHashMap<String,McpCacheHint>(); 213 if (value != null) 214 value.forEach((uri, hint) -> putValidated(copy, uri, hint)); 215 resourceReadOverrides = copy; 216 return this; 217 } 218 219 /** 220 * Adds or replaces a single per-URI hint override. 221 * 222 * @param uri The exact resource URI. Must not be {@code null}. 223 * @param hint The hint. Can be {@code null}. 224 * @return This object. 225 */ 226 public McpCacheConfig addResourceReadOverride(String uri, McpCacheHint hint) { 227 putValidated(resourceReadOverrides, uri, hint); 228 return this; 229 } 230 231 private static void putValidated(Map<String,McpCacheHint> target, String uri, McpCacheHint hint) { 232 if (uri == null) 233 throw new IllegalArgumentException("resourceReadOverrides URI must not be null"); 234 target.put(uri, validate(hint)); 235 } 236}