Class Soklet

java.lang.Object
com.soklet.Soklet
All Implemented Interfaces:
AutoCloseable

@ThreadSafe public final class Soklet extends Object implements AutoCloseable
Soklet's main class - manages one or more configured transport servers (HttpServer, SseServer, and/or McpServer) using the provided system configuration.

// Use out-of-the-box defaults
SokletConfig config = SokletConfig.withHttpServer(
  HttpServer.fromPort(8080)
).build();

try (Soklet soklet = Soklet.fromConfig(config)) {
  soklet.start();
  System.out.println("Soklet started, press [enter] to exit");
  soklet.awaitShutdown(ShutdownTrigger.ENTER_KEY);
}

Soklet also offers an off-network Simulator concept via runSimulator(SokletConfig, Consumer), useful for integration testing.

Given a Resource Method...

public class HelloResource {
  @GET("/hello")
  public String hello(@QueryParameter String name) {
    return String.format("Hello, %s", name);
  }
}
...we might test it like this:
@Test
public void integrationTest() {
  // Just use your app's existing configuration
  SokletConfig config = obtainMySokletConfig();

  // Instead of running on a real HTTP server that listens on a port,
  // a non-network Simulator is provided against which you can
  // issue requests and receive responses.
  Soklet.runSimulator(config, (simulator -> {
    // Construct a request
    Request request = Request.withPath(HttpMethod.GET, "/hello")
      .queryParameters(Map.of("name", Set.of("Mark")))
      .build();

    // Perform the request and get a handle to the response
    HttpRequestResult result = simulator.performHttpRequest(request);
    MarshaledResponse marshaledResponse = result.getMarshaledResponse();

    // Verify status code
    Integer expectedCode = 200;
    Integer actualCode = marshaledResponse.getStatusCode();
    assertEquals(expectedCode, actualCode, "Bad status code");

    // Verify response body
    marshaledResponse.getBody().ifPresentOrElse(body -> {
      String expectedBody = "Hello, Mark";
      byte[] bytes = ((MarshaledResponseBody.Bytes) body).getBytes();
      String actualBody = new String(bytes, StandardCharsets.UTF_8);
      assertEquals(expectedBody, actualBody, "Bad response body");
    }, () -> {
      Assertions.fail("No response body");
    });
  }));
}

The Simulator also supports Server-Sent Events.

Integration testing documentation is available at https://www.soklet.com/docs/testing.

Author:
Mark Allen
  • Method Details

    • fromConfig

      public static @NonNull Soklet fromConfig(@NonNull SokletConfig sokletConfig)
      Acquires a Soklet instance with the given configuration.
      Parameters:
      sokletConfig - configuration that drives the Soklet system
      Returns:
      a Soklet instance
    • start

      public void start()
      Starts the managed server instance[s].

      If the managed server[s] are already started, this is a no-op.

    • stop

      public void stop()
      Stops the managed server instance[s].

      If the managed server[s] are already stopped, this is a no-op.

    • awaitShutdown

      public void awaitShutdown(@Nullable ShutdownTrigger... shutdownTriggers) throws InterruptedException
      Blocks the current thread until JVM shutdown (SIGTERM/SIGINT/System.exit(...) and so forth), or if one of the provided shutdownTriggers occurs.

      This method will automatically invoke this instance's stop() method once it becomes unblocked.

      Notes regarding ShutdownTrigger.ENTER_KEY:

      Parameters:
      shutdownTriggers - additional trigger[s] which signal that shutdown should occur, e.g. ShutdownTrigger.ENTER_KEY for "enter key pressed"
      Throws:
      InterruptedException - if the current thread has its interrupted status set on entry to this method, or is interrupted while waiting
    • close

      public void close()
      Synonym for stop().
      Specified by:
      close in interface AutoCloseable
    • isStarted

      Is any managed transport server started?
      Returns:
      true if at least one configured transport server is started, false otherwise
    • runSimulator

      public static void runSimulator(@NonNull SokletConfig sokletConfig, @NonNull Consumer<Simulator> simulatorConsumer)
      Runs Soklet with special non-network "simulator" implementations of the configured transport servers - useful for integration testing.

      See https://www.soklet.com/docs/testing for how to write these tests.

      Parameters:
      sokletConfig - configuration that drives the Soklet system
      simulatorConsumer - code to execute within the context of the simulator