CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-micronaut--micronaut-context

Context module for the Micronaut Framework that extends the micronaut-inject module with additional bean container services such as job scheduling with @Scheduled, event listeners with @EventListener, and immutable configuration properties

Pending
Overview
Eval results
Files

server.mddocs/

Server Lifecycle

Embedded server abstraction and lifecycle management for web applications. Provides unified interface for different server implementations with comprehensive startup/shutdown coordination and server information access.

Capabilities

EmbeddedServer Interface

Core interface for embedded server implementations providing server metadata and lifecycle management.

/**
 * Interface for embedded server implementations
 * Extends EmbeddedApplication with server-specific functionality
 */
public interface EmbeddedServer extends EmbeddedApplication<EmbeddedServer> {
    
    /**
     * Get the port the server is listening on
     * @return Server port number
     */
    int getPort();
    
    /**
     * Get the host the server is bound to
     * @return Server host address
     */
    String getHost();
    
    /**
     * Get the URL scheme (protocol) used by the server
     * @return URL scheme (typically "http" or "https")
     */
    String getScheme();
    
    /**
     * Get the complete server URL
     * @return Full server URL including scheme, host, and port
     */
    URL getURL();
    
    /**
     * Get the server URI
     * @return Server URI
     */
    URI getURI();
    
    /**
     * Get the context path URI for the server
     * @return URI including context path if configured
     */
    URI getContextURI();
    
    /**
     * Check if the server should remain alive after startup
     * @return true if server should keep the JVM alive
     */
    boolean isKeepAlive();
}

Usage Examples:

import io.micronaut.runtime.server.EmbeddedServer;
import io.micronaut.runtime.Micronaut;

public class ServerInfoExample {
    
    public static void main(String[] args) {
        ApplicationContext context = Micronaut.run(ServerInfoExample.class, args);
        
        // Get embedded server information
        EmbeddedServer server = context.getBean(EmbeddedServer.class);
        
        System.out.println("Server Details:");
        System.out.println("  URL: " + server.getURL());
        System.out.println("  Host: " + server.getHost());
        System.out.println("  Port: " + server.getPort());
        System.out.println("  Scheme: " + server.getScheme());
        System.out.println("  Context URI: " + server.getContextURI());
        System.out.println("  Keep Alive: " + server.isKeepAlive());
        System.out.println("  Running: " + server.isRunning());
    }
}

// Service that uses server information
@Singleton
public class ServiceRegistrationService {
    
    private final EmbeddedServer server;
    
    public ServiceRegistrationService(EmbeddedServer server) {
        this.server = server;
    }
    
    public void registerWithServiceDiscovery() {
        String serviceUrl = server.getURL().toString();
        
        // Register this service instance
        ServiceRegistry.register(
            "my-service",
            serviceUrl,
            Map.of(
                "host", server.getHost(),
                "port", String.valueOf(server.getPort()),
                "scheme", server.getScheme()
            )
        );
    }
}

Server Lifecycle Events

Events fired during embedded server startup and shutdown phases.

/**
 * Event fired when EmbeddedServer completes startup
 * Indicates server is ready to accept HTTP requests
 */
public class ServerStartupEvent extends ApplicationStartupEvent {
    
    /**
     * Create server startup event
     * @param embeddedServer The server that completed startup
     */
    public ServerStartupEvent(EmbeddedServer embeddedServer);
    
    /**
     * Get the embedded server that started
     * @return EmbeddedServer instance
     */
    @Override
    public EmbeddedServer getSource();
}

/**
 * Event fired when EmbeddedServer begins shutdown
 * Server will no longer accept new requests after this event
 */
public class ServerShutdownEvent extends ApplicationEvent {
    
    /**
     * Create server shutdown event
     * @param embeddedServer The server that is shutting down
     */
    public ServerShutdownEvent(EmbeddedServer embeddedServer);
    
    /**
     * Get the embedded server that is shutting down
     * @return EmbeddedServer instance
     */
    @Override
    public EmbeddedServer getSource();
}

Usage Examples:

import io.micronaut.runtime.server.event.ServerStartupEvent;
import io.micronaut.runtime.server.event.ServerShutdownEvent;
import io.micronaut.runtime.event.annotation.EventListener;

@Singleton
public class ServerLifecycleManager {
    
    private static final Logger logger = LoggerFactory.getLogger(ServerLifecycleManager.class);
    
    @EventListener
    public void onServerStartup(ServerStartupEvent event) {
        EmbeddedServer server = event.getSource();
        
        logger.info("🚀 Server started successfully!");
        logger.info("   Server URL: {}", server.getURL());
        logger.info("   Host: {}", server.getHost());
        logger.info("   Port: {}", server.getPort());
        logger.info("   Scheme: {}", server.getScheme());
        
        // Perform startup tasks
        initializeHealthChecks(server);
        registerWithLoadBalancer(server);
        enableTrafficRouting(server);
        
        // Log startup time
        long startupTime = getStartupTime();
        logger.info("✅ Server ready in {}ms", startupTime);
    }
    
    @EventListener
    public void onServerShutdown(ServerShutdownEvent event) {
        EmbeddedServer server = event.getSource();
        
        logger.info("🛑 Server shutdown initiated");
        logger.info("   Server URL: {}", server.getURL());
        
        // Perform graceful shutdown tasks
        deregisterFromLoadBalancer(server);
        disableTrafficRouting(server);
        completeOngoingRequests();
        closeConnections();
        
        logger.info("✅ Server shutdown completed");
    }
    
    private void initializeHealthChecks(EmbeddedServer server) {
        // Start health check endpoints
        healthCheckService.start(server.getPort());
    }
    
    private void registerWithLoadBalancer(EmbeddedServer server) {
        // Register with external load balancer
        loadBalancerClient.register(
            server.getHost(), 
            server.getPort(),
            server.getScheme()
        );
    }
}

Server Configuration Integration

Working with server configuration and customization.

/**
 * Server configuration integration examples
 * Accessing and using server configuration
 */

// Configuration-driven server behavior
@Singleton
public class ServerConfigurationService {
    
    private final ServerConfiguration serverConfig;
    private final EmbeddedServer embeddedServer;
    
    public ServerConfigurationService(ServerConfiguration serverConfig,
                                    EmbeddedServer embeddedServer) {
        this.serverConfig = serverConfig;
        this.embeddedServer = embeddedServer;
    }
    
    @EventListener
    public void onServerStartup(ServerStartupEvent event) {
        // Validate server configuration matches expectations
        validateServerConfiguration();
        
        // Configure server-specific features
        configureServerFeatures();
    }
    
    private void validateServerConfiguration() {
        int actualPort = embeddedServer.getPort();
        int configuredPort = serverConfig.getPort();
        
        if (actualPort != configuredPort) {
            logger.warn("Server started on port {} but configured for port {}", 
                       actualPort, configuredPort);
        }
        
        String actualHost = embeddedServer.getHost();
        String configuredHost = serverConfig.getHost();
        
        if (!Objects.equals(actualHost, configuredHost)) {
            logger.info("Server host: actual={}, configured={}", 
                       actualHost, configuredHost);
        }
    }
}

// Custom server startup logic
@Singleton
public class CustomServerStartup {
    
    @EventListener
    public void onServerStartup(ServerStartupEvent event) {
        EmbeddedServer server = event.getSource();
        
        // Custom initialization based on server properties
        if ("https".equals(server.getScheme())) {
            enableSecurityFeatures();
        }
        
        if (server.getPort() == 443 || server.getPort() == 80) {
            enableProductionMode();
        }
        
        // Register custom endpoints
        registerCustomEndpoints(server);
    }
    
    private void registerCustomEndpoints(EmbeddedServer server) {
        String baseUrl = server.getURL().toString();
        
        // Register metrics endpoint
        endpointRegistry.register(baseUrl + "/metrics", metricsHandler);
        
        // Register admin endpoint
        if (isAdminEnabled()) {
            endpointRegistry.register(baseUrl + "/admin", adminHandler);
        }
    }
}

Server Environment Integration

Integration with different server environments and deployment scenarios.

@Singleton
public class EnvironmentAwareServerManager {
    
    private final Environment environment;
    
    public EnvironmentAwareServerManager(Environment environment) {
        this.environment = environment;
    }
    
    @EventListener
    public void onServerStartup(ServerStartupEvent event) {
        EmbeddedServer server = event.getSource();
        
        // Environment-specific server configuration
        if (environment.getActiveNames().contains("production")) {
            configureProductionServer(server);
        } else if (environment.getActiveNames().contains("development")) {
            configureDevelopmentServer(server);
        }
        
        // Cloud environment detection
        if (isRunningInCloud()) {
            configureCloudServer(server);
        }
        
        // Container environment detection
        if (isRunningInContainer()) {
            configureContainerServer(server);
        }
    }
    
    private void configureProductionServer(EmbeddedServer server) {
        logger.info("Configuring server for production environment");
        
        // Enable production features
        enableRequestLogging();
        enablePerformanceMonitoring();
        configureSecurityHeaders();
        
        // Validate production requirements
        if (!"https".equals(server.getScheme())) {
            logger.warn("Production server not using HTTPS: {}", server.getURL());
        }
    }
    
    private void configureDevelopmentServer(EmbeddedServer server) {
        logger.info("Configuring server for development environment");
        
        // Enable development features
        enableDebugEndpoints();
        enableHotReload();
        disableSecurityRestrictions();
        
        logger.info("Development server ready at: {}", server.getURL());
    }
    
    private boolean isRunningInCloud() {
        // Detect cloud environment (AWS, GCP, Azure, etc.)
        return environment.getProperty("cloud.platform").isPresent() ||
               System.getenv("AWS_REGION") != null ||
               System.getenv("GOOGLE_CLOUD_PROJECT") != null;
    }
    
    private boolean isRunningInContainer() {
        // Detect container environment (Docker, Kubernetes, etc.)
        return Files.exists(Paths.get("/.dockerenv")) ||
               System.getenv("KUBERNETES_SERVICE_HOST") != null;
    }
}

Server Health and Monitoring

Integration with health checks and monitoring systems.

@Singleton
public class ServerHealthManager {
    
    private final MeterRegistry meterRegistry;
    private final HealthAggregator healthAggregator;
    
    public ServerHealthManager(MeterRegistry meterRegistry,
                              HealthAggregator healthAggregator) {
        this.meterRegistry = meterRegistry;
        this.healthAggregator = healthAggregator;
    }
    
    @EventListener
    public void onServerStartup(ServerStartupEvent event) {
        EmbeddedServer server = event.getSource();
        
        // Register server metrics
        registerServerMetrics(server);
        
        // Initialize health checks
        initializeHealthChecks(server);
        
        // Start monitoring
        startServerMonitoring(server);
    }
    
    private void registerServerMetrics(EmbeddedServer server) {
        // Server information gauges
        Gauge.builder("server.port")
             .description("Server port number")
             .register(meterRegistry, server, s -> s.getPort());
             
        Gauge.builder("server.running")
             .description("Server running status")
             .register(meterRegistry, server, s -> s.isRunning() ? 1 : 0);
        
        // Server startup timer
        Timer.Sample startupTimer = Timer.start(meterRegistry);
        startupTimer.stop(Timer.builder("server.startup.time")
                               .description("Server startup time")
                               .register(meterRegistry));
    }
    
    private void initializeHealthChecks(EmbeddedServer server) {
        // Register server-specific health indicators
        healthAggregator.addHealthIndicator("server", () -> 
            server.isRunning() ? 
                HealthStatus.UP.describe("Server running on " + server.getURL()) :
                HealthStatus.DOWN.describe("Server not running")
        );
        
        // Port availability check
        healthAggregator.addHealthIndicator("server.port", () -> 
            isPortAccessible(server.getHost(), server.getPort()) ?
                HealthStatus.UP.describe("Port " + server.getPort() + " accessible") :
                HealthStatus.DOWN.describe("Port " + server.getPort() + " not accessible")
        );
    }
    
    @EventListener
    public void onServerShutdown(ServerShutdownEvent event) {
        // Record shutdown metrics
        meterRegistry.counter("server.shutdown.count").increment();
        
        // Update health status
        healthAggregator.updateHealthIndicator("server", 
            HealthStatus.DOWN.describe("Server shutting down"));
    }
}

Integration with External Systems

Examples of integrating server lifecycle with external systems.

@Singleton
public class ExternalSystemIntegration {
    
    private final ServiceDiscoveryClient serviceDiscovery;
    private final LoadBalancerClient loadBalancer;
    private final MetricsCollector metricsCollector;
    
    @EventListener
    @Async
    public CompletableFuture<Void> onServerStartup(ServerStartupEvent event) {
        return CompletableFuture.runAsync(() -> {
            EmbeddedServer server = event.getSource();
            
            try {
                // Register with service discovery
                registerWithServiceDiscovery(server);
                
                // Add to load balancer pool
                addToLoadBalancerPool(server);
                
                // Start external monitoring
                startExternalMonitoring(server);
                
                logger.info("Server successfully registered with external systems");
            } catch (Exception e) {
                logger.error("Failed to register with external systems", e);
                // Could trigger health check failure or retry logic
            }
        });
    }
    
    @EventListener
    @Async
    public CompletableFuture<Void> onServerShutdown(ServerShutdownEvent event) {
        return CompletableFuture.runAsync(() -> {
            EmbeddedServer server = event.getSource();
            
            try {
                // Graceful deregistration from external systems
                removeFromLoadBalancerPool(server);
                deregisterFromServiceDiscovery(server);
                stopExternalMonitoring(server);
                
                logger.info("Server successfully deregistered from external systems");
            } catch (Exception e) {
                logger.error("Error during external system deregistration", e);
            }
        });
    }
    
    private void registerWithServiceDiscovery(EmbeddedServer server) {
        ServiceInstance instance = ServiceInstance.builder()
            .instanceId(generateInstanceId())
            .serviceName("my-service")
            .host(server.getHost())
            .port(server.getPort())
            .secure("https".equals(server.getScheme()))
            .metadata(Map.of(
                "version", getApplicationVersion(),
                "environment", getCurrentEnvironment(),
                "contextPath", server.getContextURI().getPath()
            ))
            .build();
            
        serviceDiscovery.register(instance);
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-io-micronaut--micronaut-context

docs

events.md

index.md

runtime.md

scheduling.md

scopes.md

server.md

shutdown.md

tile.json