CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-quarkus--quarkus-devservices-deployment

Quarkus deployment module that provides automatic configuration and orchestration of development services using Docker Compose

Pending
Overview
Eval results
Files

console-commands.mddocs/

Console Commands

Development-time CLI commands for listing DevServices, viewing logs, and managing container lifecycle during development.

Capabilities

DevServicesCommand

Parent group command that provides the main entry point for DevServices CLI operations with subcommand management.

/**
 * Group command definition for DevServices CLI operations
 */
@GroupCommandDefinition(name = "devservices", description = "Dev Service Commands")
public class DevServicesCommand implements GroupCommand {
    
    /**
     * Creates a DevServices command group with service descriptions
     * @param serviceDescriptions List of available dev service descriptions
     */
    public DevServicesCommand(List<DevServiceDescriptionBuildItem> serviceDescriptions);
    
    /**
     * Gets the list of available subcommands
     * @return List containing list and logs commands
     */
    @Override
    public List<Command> getCommands();
    
    /**
     * Executes the group command (shows help)
     * @param commandInvocation Command invocation context
     * @return SUCCESS status
     */
    @Override
    public CommandResult execute(CommandInvocation commandInvocation);
    
    /**
     * Finds a dev service by name
     * @param devServiceName Name of the service to find
     * @return Optional containing the service description if found
     */
    static Optional<DevServiceDescriptionBuildItem> findDevService(String devServiceName);
}

Usage Examples:

// Creating DevServices command in build step
@BuildStep
public ConsoleCommandBuildItem createDevServicesCommand(
    List<DevServiceDescriptionBuildItem> serviceDescriptions) {
    
    DevServicesCommand devServicesCommand = new DevServicesCommand(serviceDescriptions);
    return new ConsoleCommandBuildItem(devServicesCommand);
}

// Using the command programmatically
List<DevServiceDescriptionBuildItem> services = getAvailableServices();
DevServicesCommand command = new DevServicesCommand(services);

// Get available subcommands
List<Command> subcommands = command.getCommands();
for (Command cmd : subcommands) {
    System.out.println("Available command: " + cmd.getClass().getSimpleName());
}

// Find specific service
Optional<DevServiceDescriptionBuildItem> postgres = 
    DevServicesCommand.findDevService("PostgreSQL Dev Service");
    
if (postgres.isPresent()) {
    DevServiceDescriptionBuildItem service = postgres.get();
    System.out.println("Found service: " + service.getName());
    System.out.println("Description: " + service.getDescription());
    
    if (service.hasContainerInfo()) {
        String containerId = service.getContainerInfo().id();
        System.out.println("Container ID: " + containerId);
    }
}

DevServiceCompleter

Command completion support for DevService names, providing autocomplete functionality in the CLI.

/**
 * Command completer for DevService names
 */
public static class DevServiceCompleter extends SetCompleter {
    
    /**
     * Provides completion options for DevService names
     * @param soFar Current input string
     * @return Set of matching service names
     */
    @Override
    protected Set<String> allOptions(String soFar);
}

DevServicesListCommand

Command implementation that lists all running DevServices with their status and configuration information.

/**
 * Command to list all running dev services
 */
@CommandDefinition(name = "list", description = "List of dev services")
public class DevServicesListCommand implements Command {
    
    /**
     * Executes the list command, displaying all dev services
     * @param commandInvocation Command invocation context
     * @return SUCCESS status
     */
    @Override
    public CommandResult execute(CommandInvocation commandInvocation);
}

Usage Examples:

// Example output when running 'devservices list' command:
/*
PostgreSQL Dev Service
  Container: 1a2b3c4d5e6f  /postgres-dev  postgres:13
  Network: bridge - 0.0.0.0:5432->5432/tcp
  Exec command: docker exec -it 1a2b3c4d /bin/bash
  Injected config: - quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/quarkus

Redis Dev Service  
  Container: 9f8e7d6c5b4a  /redis-dev  redis:6-alpine
  Network: bridge - 0.0.0.0:6379->6379/tcp
  Exec command: docker exec -it 9f8e7d6c /bin/bash
  Injected config: - quarkus.redis.hosts=redis://localhost:6379

Compose Dev Services
  Project: my-app-devservices, Services: database, message-queue
  Injected config: - DATABASE_URL=postgresql://localhost:5433/mydb
                  - RABBITMQ_URL=amqp://localhost:5672
*/

// Programmatic usage
DevServicesListCommand listCommand = new DevServicesListCommand();
CommandInvocation mockInvocation = createMockInvocation();
CommandResult result = listCommand.execute(mockInvocation);

if (result == CommandResult.SUCCESS) {
    System.out.println("Successfully listed dev services");
}

DevServicesLogsCommand

Command implementation that displays container logs for a specific DevService with optional following and tailing support.

/**
 * Command to display container logs for a dev service
 */
@CommandDefinition(name = "logs", description = "Print container logs")
public class DevServicesLogsCommand implements Command {
    
    /**
     * Dev Service name (required argument with completion support)
     */
    @Argument(required = true, description = "Dev Service name", completer = DevServiceCompleter.class)
    private String devService;
    
    /**
     * Follow logs in real-time
     */
    @Option(name = "follow", shortName = 'f', description = "Follow container logs", hasValue = false, defaultValue = "false")
    private boolean follow;
    
    /**
     * Number of lines to tail (-1 for all)
     */
    @Option(name = "tail", shortName = 't', description = "Tail container logs", defaultValue = "-1")
    private int tail;
    
    /**
     * Executes the logs command
     * @param commandInvocation Command invocation context
     * @return SUCCESS if service found and logs displayed, FAILURE otherwise
     */
    @Override
    public CommandResult execute(CommandInvocation commandInvocation);
}

Usage Examples:

// Command line usage examples:

// Show all logs for a service
// > devservices logs "PostgreSQL Dev Service"

// Follow logs in real-time
// > devservices logs -f "PostgreSQL Dev Service" 

// Show last 50 lines and follow
// > devservices logs -t 50 -f "Redis Dev Service"

// Just last 100 lines
// > devservices logs --tail 100 "Compose Dev Services"

// Programmatic usage
DevServicesLogsCommand logsCommand = new DevServicesLogsCommand();

// Set command arguments programmatically (normally done by CLI framework)
setCommandArgument(logsCommand, "devService", "PostgreSQL Dev Service");
setCommandOption(logsCommand, "follow", true);
setCommandOption(logsCommand, "tail", 50);

CommandInvocation invocation = createCommandInvocation();
CommandResult result = logsCommand.execute(invocation);

if (result == CommandResult.SUCCESS) {
    System.out.println("Successfully displayed logs");
} else {
    System.err.println("Failed to find service or display logs");
}

// Example log output:
/*
2024-01-15 10:30:25.123 UTC [1] LOG:  database system was shut down at 2024-01-15 10:30:20 UTC
2024-01-15 10:30:25.125 UTC [1] LOG:  database system is ready to accept connections
2024-01-15 10:30:25.126 UTC [7] LOG:  autovacuum launcher started
2024-01-15 10:30:30.445 UTC [8] LOG:  connection received: host=172.17.0.1 port=54321
2024-01-15 10:30:30.447 UTC [8] LOG:  connection authorized: user=quarkus database=quarkus
*/

ContainerLogForwarder

Manages log forwarding from containers to the application logging system with start/stop lifecycle control.

/**
 * Forwards container logs to application logging system
 */
public class ContainerLogForwarder implements Closeable {
    
    /**
     * Creates a log forwarder for a dev service
     * @param devService Dev service description containing container info
     */
    public ContainerLogForwarder(DevServiceDescriptionBuildItem devService);
    
    /**
     * Gets the associated dev service
     * @return Dev service description
     */
    public DevServiceDescriptionBuildItem getDevService();
    
    /**
     * Checks if log forwarding is currently active
     * @return true if logs are being forwarded
     */
    public boolean isRunning();
    
    /**
     * Starts log forwarding from the container
     */
    public void start();
    
    /**
     * Stops log forwarding and cleans up resources
     */
    @Override
    public void close();
}

Usage Examples:

// Managing log forwarders for dev services
Map<String, ContainerLogForwarder> logForwarders = new HashMap<>();

// Create log forwarders for all services with containers
for (DevServiceDescriptionBuildItem service : serviceDescriptions) {
    if (service.hasContainerInfo()) {
        String containerId = service.getContainerInfo().id();
        ContainerLogForwarder forwarder = new ContainerLogForwarder(service);
        logForwarders.put(containerId, forwarder);
    }
}

// Start log forwarding for all services
for (ContainerLogForwarder forwarder : logForwarders.values()) {
    if (!forwarder.isRunning()) {
        forwarder.start();
        System.out.println("Started log forwarding for: " + 
                          forwarder.getDevService().getName());
    }
}

// Toggle log forwarding based on user preference
boolean enableLogForwarding = getUserPreference();

for (ContainerLogForwarder forwarder : logForwarders.values()) {
    if (enableLogForwarding && !forwarder.isRunning()) {
        forwarder.start();
    } else if (!enableLogForwarding && forwarder.isRunning()) {
        forwarder.close();
    }
}

// Cleanup when shutting down
try {
    for (ContainerLogForwarder forwarder : logForwarders.values()) {
        if (forwarder.isRunning()) {
            forwarder.close();
        }
    }
} catch (Exception e) {
    System.err.println("Error during log forwarder cleanup: " + e.getMessage());
}

// Example logged output format:
/*
2024-01-15 10:30:25.123 INFO  [PostgreSQL Dev Service] [1a2b3c4d] 2024-01-15 10:30:25.123 UTC [1] LOG:  database system is ready to accept connections
2024-01-15 10:30:26.234 ERROR [Redis Dev Service] [9f8e7d6c] 1:M 15 Jan 2024 10:30:26.234 # Warning: no config file specified, using the default config
2024-01-15 10:30:27.345 INFO  [Message Queue] [5a6b7c8d] 2024-01-15 10:30:27.345 [info] <0.123.0> accepting AMQP connection <0.456.0> (127.0.0.1:54321 -> 127.0.0.1:5672)
*/

// Using with try-with-resources
try (ContainerLogForwarder forwarder = new ContainerLogForwarder(serviceDescription)) {
    forwarder.start();
    
    // Do work while logs are being forwarded
    performDevelopmentTasks();
    
    // Forwarder automatically closed when leaving try block
}

Integration with Quarkus Console

These commands integrate with the Quarkus development console through build steps:

@BuildStep(onlyIf = { IsDevelopment.class })
public void registerConsoleCommands(
    List<DevServiceDescriptionBuildItem> serviceDescriptions,
    BuildProducer<ConsoleCommandBuildItem> commandProducer) {
    
    // Register the DevServices command group
    DevServicesCommand devServicesCommand = new DevServicesCommand(serviceDescriptions);
    commandProducer.produce(new ConsoleCommandBuildItem(devServicesCommand));
}

Console Integration Features

The commands are available in the Quarkus development console and provide:

  • Interactive Command Completion: Service names auto-complete when typing commands
  • Real-time Log Streaming: The logs command can follow container output in real-time
  • Container Inspection: Easy access to container details and configurations
  • Development Workflow Integration: Seamless integration with hot reload and continuous testing

Usage in Development Mode

When running Quarkus in development mode (mvn quarkus:dev), the DevServices commands become available:

2024-01-15 10:30:25,123 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2024-01-15 10:30:25,124 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, devservices-deployment, ...]

Tests paused
Press [SPACE] to restart, [e] to edit command line args (currently ''), [r] to resume testing, [o] Toggle test output, [h] for more options>

# Available DevServices commands:
# devservices list - List all running dev services
# devservices logs <service-name> - Show logs for a specific service

The console provides immediate feedback and allows developers to inspect and manage their development services without leaving the development environment.

Install with Tessl CLI

npx tessl i tessl/maven-io-quarkus--quarkus-devservices-deployment

docs

compose-files.md

compose-project.md

console-commands.md

devservices-processing.md

index.md

tile.json