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.net.*;
020import java.util.*;
021
022import org.apache.juneau.commons.bean.BeanType;
023import org.apache.juneau.commons.bean.PropertyNamerULC;
024
025/**
026 * Server-side representation of an <a class="doclink" href="https://datatracker.ietf.org/doc/html/rfc9728">RFC 9728</a>
027 * Protected Resource Metadata (PRM) document, emitted by the {@code 2026-07-28} MCP resource server from its
028 * {@code .well-known/oauth-protected-resource} endpoint so a client can discover which authorization server(s) protect
029 * this MCP server.
030 *
031 * <p>
032 * The {@link BeanType#propertyNamer() property namer} maps the camel-case Java properties to the snake-case wire field
033 * names RFC 9728 mandates ({@code resource}, {@code authorization_servers}, {@code scopes_supported},
034 * {@code bearer_methods_supported}), so Juneau bean serialization produces JSON that parses cleanly on the client side
035 * via {@code org.apache.juneau.rest.client.mcp.auth.McpProtectedResourceMetadata} /
036 * {@code McpProtectedResourceMetadataClient}.
037 *
038 * <h5 class='section'>Client/server split:</h5>
039 * <p>
040 * This intentionally duplicates the shape of the client-side
041 * {@code org.apache.juneau.rest.client.mcp.auth.McpProtectedResourceMetadata} record; the
042 * two live in different modules with different dependency footprints (the client parses via Nimbus; the server emits via
043 * Juneau marshalling).  A shared, dependency-neutral bean may replace both later.
044 *
045 * @since 10.0.0
046 */
047@BeanType(propertyNamer = PropertyNamerULC.class)
048public class McpProtectedResourceMetadata {
049
050   private URI resource;
051   private List<URI> authorizationServers;
052   private Set<String> scopesSupported;
053   private Set<String> bearerMethodsSupported;
054
055   /**
056    * The {@code resource} field &mdash; this server's canonical resource identifier (RFC 9728 &sect;2).
057    *
058    * @return The resource identifier, or <jk>null</jk> if not set.
059    */
060   public URI getResource() {
061      return resource;
062   }
063
064   /**
065    * Sets the {@code resource} identifier.
066    *
067    * @param value The new value.  Can be <jk>null</jk> to unset.
068    * @return This object (for method chaining).
069    */
070   public McpProtectedResourceMetadata setResource(URI value) {
071      resource = value;
072      return this;
073   }
074
075   /**
076    * The {@code authorization_servers} field &mdash; the issuer URIs of the authorization servers that mint tokens for
077    * this resource (RFC 9728 &sect;2).
078    *
079    * @return The authorization-server issuer URIs, or <jk>null</jk> if not set.
080    */
081   public List<URI> getAuthorizationServers() {
082      return authorizationServers;
083   }
084
085   /**
086    * Sets the {@code authorization_servers} list.
087    *
088    * @param value The new value.  Can be <jk>null</jk> to unset.
089    * @return This object (for method chaining).
090    */
091   public McpProtectedResourceMetadata setAuthorizationServers(List<URI> value) {
092      authorizationServers = value;
093      return this;
094   }
095
096   /**
097    * The {@code scopes_supported} field &mdash; the OAuth scopes this resource understands (RFC 9728 &sect;2).
098    *
099    * @return The supported scopes, or <jk>null</jk> if not set.
100    */
101   public Set<String> getScopesSupported() {
102      return scopesSupported;
103   }
104
105   /**
106    * Sets the {@code scopes_supported} set.
107    *
108    * @param value The new value.  Can be <jk>null</jk> to unset.
109    * @return This object (for method chaining).
110    */
111   public McpProtectedResourceMetadata setScopesSupported(Set<String> value) {
112      scopesSupported = value;
113      return this;
114   }
115
116   /**
117    * The {@code bearer_methods_supported} field &mdash; the RFC 6750 methods by which a bearer token may be presented
118    * (RFC 9728 &sect;2).  This server accepts the {@code header} method only.
119    *
120    * @return The supported bearer methods, or <jk>null</jk> if not set.
121    */
122   public Set<String> getBearerMethodsSupported() {
123      return bearerMethodsSupported;
124   }
125
126   /**
127    * Sets the {@code bearer_methods_supported} set.
128    *
129    * @param value The new value.  Can be <jk>null</jk> to unset.
130    * @return This object (for method chaining).
131    */
132   public McpProtectedResourceMetadata setBearerMethodsSupported(Set<String> value) {
133      bearerMethodsSupported = value;
134      return this;
135   }
136}