Class CloudStub

java.lang.Object
io.cloudstub.core.CloudStub
All Implemented Interfaces:
AutoCloseable

public final class CloudStub extends Object implements AutoCloseable
Entry point for the CloudStub framework.

Boots an embedded HTTP server on a random available port, redirects all AWS SDK v2 traffic to that port via the aws.endpoint-url system property, and invokes every CloudStubService discovered on the classpath to register their stubs.

This class coordinates lifecycle and exposes the public API; the work of each concern is delegated to focused collaborators in io.cloudstub.core.internal: building the server (WireMockServerFactory), choosing the state store (StateStoreFactory), discovering and registering modules (ModuleInitializer), translating the request journal (RequestHistory), and the SDK endpoint override (AwsEndpointOverride).

Typical usage in a JUnit 6 test:

 @BeforeAll
 static void start() { cloudMock = new CloudStub(); cloudMock.start(); }

 @AfterAll
 static void stop() { cloudMock.stop(); }
 

Or with try-with-resources:

 try (CloudStub cm = new CloudStub()) {
     cm.start();
     // run tests
 }
 
  • Field Details

    • DEFAULT_MAX_REQUEST_HISTORY

      public static final int DEFAULT_MAX_REQUEST_HISTORY
      Default cap on retained request-history entries; bounds memory in long-lived processes.
      See Also:
  • Constructor Details

    • CloudStub

      public CloudStub()
  • Method Details

    • withStoreDirectory

      public CloudStub withStoreDirectory(Path directory)
      Configures a directory for persistent state storage. State written to the store will survive a CloudStub restart. When not set, an in-memory store is used (state lost on stop).

      Must be called before start().

      Parameters:
      directory - directory where the state file is written (a cloudstub-state.log append-only log by default; see withPersistenceBackend(io.cloudstub.core.StatePersistence))
      Throws:
      CloudStubAlreadyStartedException - if already started
    • withPersistenceBackend

      public CloudStub withPersistenceBackend(StatePersistence backend)
      Selects the persistent state backend used when a store directory is configured via withStoreDirectory(java.nio.file.Path). Defaults to StatePersistence.APPEND_LOG, whose write cost scales with the change rather than the whole store. Has no effect on an in-memory store (no directory set). Must be called before start().
      Throws:
      CloudStubAlreadyStartedException - if already started
    • withMaxRequestHistory

      public CloudStub withMaxRequestHistory(int maxEntries)
      Caps the number of request-history entries retained in memory. Older entries are discarded once the limit is reached, bounding memory use in a long-lived standalone process. A value of 0 or less retains an unbounded history. Defaults to DEFAULT_MAX_REQUEST_HISTORY. Must be called before start().
      Throws:
      CloudStubAlreadyStartedException - if already started
    • withPort

      public CloudStub withPort(int port)
      Binds the server to a specific port instead of a random available one. Must be called before start().
      Throws:
      CloudStubAlreadyStartedException - if already started
    • withEnabledServices

      public CloudStub withEnabledServices(Collection<String> serviceIds)
      Restricts ServiceLoader discovery to the given service IDs. Only discovered modules whose CloudStubService.serviceId() is in serviceIds are registered; all others are ignored. Modules added via withService(io.cloudstub.core.spi.CloudStubService) are always registered and are not affected by this filter.

      Passing null (the default) registers every discovered module. Must be called before start().

      Throws:
      CloudStubAlreadyStartedException - if the instance is already started
    • withService

      public CloudStub withService(CloudStubService service)
      Registers a service module explicitly, in addition to any modules discovered via ServiceLoader. Must be called before start().

      Useful in module-level tests where the test classpath structure may prevent ServiceLoader from discovering the module under test automatically.

      Throws:
      CloudStubAlreadyStartedException - if already started
    • start

      public void start()
      Starts the embedded server, registers all discovered service stubs, and injects aws.endpoint-url so the AWS SDK v2 routes traffic locally.
      Throws:
      CloudStubAlreadyStartedException - if this instance is already started
    • stop

      public void stop()
      Stops the embedded server and removes the aws.endpoint-url system property. Safe to call on an instance that was never started.
    • stateStore

      public StateStore stateStore()
      Returns the shared state store. Only valid after start(). Exposed for direct state inspection in tests and for the REST API.
      Throws:
      CloudStubNotStartedException - if not yet started
    • port

      public int port()
      Returns the port the server is listening on. Only valid after start().
    • startedAt

      public Instant startedAt()
      Returns the instant the server was started. Only valid after start().
    • modules

      public List<ModuleStatus> modules()
      Returns a live snapshot of all loaded modules and their registered stubs. Only valid after start().
    • requestHistory

      public List<RequestRecord> requestHistory()
      Returns all requests served since startup, newest first. Only valid after start().
    • requestHistory

      public List<RequestRecord> requestHistory(String serviceId)
      Returns all requests served to the given service since startup, newest first. Unmatched requests (null serviceId) are excluded. Only valid after start().
    • clearHistory

      public void clearHistory()
      Clears the captured request history, leaving registered stubs and stored state intact. Only valid after start().
    • simulateThrottle

      public void simulateThrottle(String serviceId)
      Causes all stubs for serviceId to return an AWS-style throttling error (HTTP 400, ThrottlingException) for the duration of the current test.

      Call clearFaults(String) or clearAllFaults() to restore normal behaviour.

      Throws:
      CloudStubNotStartedException - if not yet started
    • simulateTimeout

      public void simulateTimeout(String serviceId)
      Causes all stubs for serviceId to respond after a long fixed delay, triggering the AWS SDK's call timeout exception.
      Throws:
      CloudStubNotStartedException - if not yet started
    • simulateNetworkBrownout

      public void simulateNetworkBrownout(String serviceId, double rate)
      Causes approximately rate fraction of requests to serviceId to fail with a connection reset; the remainder are served normally.

      Use rate = 0.0 or rate = 1.0 for deterministic test assertions. Fractional rates are statistical and unsuitable for exact-count assertions.

      Parameters:
      rate - fraction of requests to fault, in [0.0, 1.0]
      Throws:
      CloudStubNotStartedException - if not yet started
    • clearFaults

      public void clearFaults(String serviceId)
      Removes all active fault stubs for serviceId, restoring normal stub behaviour.
      Throws:
      CloudStubNotStartedException - if not yet started
    • clearAllFaults

      public void clearAllFaults()
      Removes all active fault stubs for every service. Safe to call even when no faults are active.

      Called automatically by CloudStubExtension after each test method.

    • close

      public void close()
      Specified by:
      close in interface AutoCloseable