Class SecuredExampleServer

java.lang.Object
org.apache.juneau.examples.mcp.secured.SecuredExampleServer
All Implemented Interfaces:
AutoCloseable

public final class SecuredExampleServer extends Object implements AutoCloseable
Boots SecuredExampleMcpServer on an embedded Jetty server, alongside an in-process OfflineAuthorizationServer that stands in for a real OAuth 2.1 authorization server.

Mirrors ExampleServer (read that class first — this one only documents what is different). Run main to start both servers on fixed ports and print everything a SecuredExampleClient run needs to copy: the endpoint, the offline authorization server's token endpoint, and the randomly-generated demo client id/secret. The in-process end-to-end test uses start(0) to boot on an OS-assigned ephemeral port instead.

The resource URL is resolved before the secured servlet is even constructed. SecuredExampleMcpServer needs its own address up front (see its class javadoc), which is awkward on an OS-assigned ephemeral port because normally nothing knows that port until Jetty finishes starting. The fix: ServerConnector.open() can be, and by Jetty's own convention normally is (see Server.doStart()'s "open network connector to ensure ports are available" step), called to bind the listening socket BEFORE the rest of the server starts. Calling it ourselves, one step earlier than usual, lets us read ServerConnector.getLocalPort() immediately — before building SecuredExampleMcpServer or starting the Microservice at all. Jetty's own Server.start() then finds the connector already open and skips rebinding it.

  • Field Details

  • Method Details

    • start

      public static SecuredExampleServer start(int port) throws Exception
      Starts the secured example MCP server and its offline authorization server.
      Parameters:
      port - The TCP port the MCP server listens on, or 0 to let the OS assign an ephemeral port. (The offline authorization server always uses its own separate OS-assigned ephemeral port.)
      Returns:
      A running server handle. Close it (or call close()) to stop both servers.
      Throws:
      Exception - If either server fails to start.
    • getRootUrl

      public URI getRootUrl()
      Returns the root URL the secured MCP server is listening on (e.g. http://localhost:10001/).
      Returns:
      The root URL. Never null.
    • getAuthServer

      Returns the offline authorization server backing this instance, so a caller (e.g. the end-to-end test, or main(String[]) printing a startup banner) can read its token endpoint and demo credentials.
      Returns:
      The offline authorization server. Never null.
    • close

      public void close() throws Exception
      Specified by:
      close in interface AutoCloseable
      Throws:
      Exception
    • main

      public static void main(String[] args) throws Exception
      Runs both servers until the process is killed, printing everything SecuredExampleClient needs.

      M10: the token endpoint is no longer printed here — SecuredExampleClient now discovers it itself via RFC 9728 PRM + RFC 8414 discovery, exactly as a real client would, so only the endpoint and demo client credentials need to be copied.

      Parameters:
      args - Optional single argument: the port the MCP server listens on (defaults to DEFAULT_PORT).
      Throws:
      Exception - If either server fails to start.