or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

access-methods.mdconfiguration.mddeprecated-api.mdindex.md
tile.json

deprecated-api.mddocs/

Deprecated Declarative Configuration

Legacy declarative methods for configuring RabbitMQ entities (queues, exchanges, bindings, users, virtual hosts, policies, and permissions). These methods are deprecated in favor of using the inherited execInContainer(String...) method to execute rabbitmqadmin or rabbitmqctl commands directly, or using the RabbitMQ Java client API for queue/exchange/binding operations.

Migration Guide

All deprecated methods internally execute rabbitmqadmin commands after the container starts. For better control and to use the latest RabbitMQ features, prefer using execInContainer() directly or the AMQP client API:

// Instead of deprecated methods:
container.withQueue("my-queue").withExchange("my-exchange", "direct");

// Use execInContainer:
container.start();
container.execInContainer("rabbitmqadmin", "declare", "queue", "name=my-queue");
container.execInContainer("rabbitmqadmin", "declare", "exchange", "name=my-exchange", "type=direct");

// Or use AMQP client (recommended for queues/exchanges/bindings):
ConnectionFactory factory = new ConnectionFactory();
factory.setUri(container.getAmqpUrl());
factory.setUsername(container.getAdminUsername());
factory.setPassword(container.getAdminPassword());
try (Connection connection = factory.newConnection();
     Channel channel = connection.createChannel()) {
    channel.queueDeclare("my-queue", false, false, false, null);
    channel.exchangeDeclare("my-exchange", "direct", true);
}

Important Notes for Agents:

  • All deprecated methods must be called before start()
  • Deprecated methods execute commands after container startup
  • execInContainer() can only be called after start() returns
  • Check ExecResult.getExitCode() to verify command success
  • Use ExecResult.getStdout() and ExecResult.getStderr() for debugging
  • rabbitmqadmin requires management plugin (included in -management image variants)
  • rabbitmqctl is always available and more reliable for basic operations
  • Commands execute synchronously and block until completion
  • AMQP client API is recommended for queues, exchanges, and bindings (most reliable)
  • rabbitmqctl is recommended for users, vhosts, permissions, and policies (most reliable)
  • rabbitmqadmin is useful for complex management operations but requires management plugin
  • Error handling is more explicit with ExecResult than with deprecated methods
  • Deprecated methods may not support all RabbitMQ features and versions
  • Future RabbitMQ versions may require different command syntax (deprecated methods may break)

Migration Strategy:

  1. Replace queue/exchange/binding operations with AMQP client API (recommended)
  2. Replace user/vhost/permission/policy operations with rabbitmqctl via execInContainer()
  3. Replace plugin operations with rabbitmq-plugins via execInContainer()
  4. Always check ExecResult exit codes for command success
  5. Use ExecResult stdout/stderr for debugging failed commands

Capabilities

Plugin Management

Enable RabbitMQ plugins during container startup.

/**
 * Enables RabbitMQ plugins.
 * @deprecated use execInContainer(String...) instead
 * @param pluginNames Plugin names to enable
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withPluginsEnabled(String... pluginNames)

Deprecated Usage:

RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container.withPluginsEnabled("rabbitmq_shovel", "rabbitmq_federation");
container.start();

Recommended Alternative:

RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container.start();

// Enable plugins using rabbitmq-plugins command
ExecResult result = container.execInContainer(
    "rabbitmq-plugins", "enable", "rabbitmq_shovel", "rabbitmq_federation");
if (result.getExitCode() != 0) {
    throw new RuntimeException("Failed to enable plugins: " + result.getStderr());
}

// Verify plugins are enabled
ExecResult listResult = container.execInContainer(
    "rabbitmq-plugins", "list");
System.out.println("Enabled plugins: " + listResult.getStdout());

Error Handling:

container.start();
ExecResult result = container.execInContainer(
    "rabbitmq-plugins", "enable", "rabbitmq_shovel");

if (result.getExitCode() == 0) {
    System.out.println("Plugin enabled: " + result.getStdout());
} else {
    System.err.println("Failed to enable plugin: " + result.getStderr());
    // Handle error - plugin may not exist or already enabled
    // Check stderr for specific error message
}

Plugin Already Enabled:

// Enable plugin (idempotent - safe to call multiple times)
ExecResult result = container.execInContainer(
    "rabbitmq-plugins", "enable", "rabbitmq_shovel");

if (result.getExitCode() == 0) {
    // Plugin enabled or already enabled
} else {
    // Plugin may not exist or error occurred
    throw new RuntimeException("Failed to enable plugin: " + result.getStderr());
}

Queue Declaration

Declare RabbitMQ queues with various configuration options.

/**
 * Declares a queue with default settings.
 * @deprecated use execInContainer(String...) or AMQP client instead
 * @param name Queue name
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withQueue(String name)

/**
 * Declares a queue in a specific virtual host.
 * @deprecated use execInContainer(String...) or AMQP client instead
 * @param vhost Virtual host name
 * @param name Queue name
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withQueue(String vhost, String name)

/**
 * Declares a queue with full configuration options.
 * @deprecated use execInContainer(String...) or AMQP client instead
 * @param name Queue name
 * @param autoDelete Auto-delete when unused
 * @param durable Survive broker restart
 * @param arguments Additional queue arguments (e.g., TTL, max length)
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withQueue(
    String name,
    boolean autoDelete,
    boolean durable,
    Map<String, Object> arguments
)

/**
 * Declares a queue in a virtual host with full configuration options.
 * @deprecated use execInContainer(String...) or AMQP client instead
 * @param vhost Virtual host name
 * @param name Queue name
 * @param autoDelete Auto-delete when unused
 * @param durable Survive broker restart
 * @param arguments Additional queue arguments
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withQueue(
    String vhost,
    String name,
    boolean autoDelete,
    boolean durable,
    Map<String, Object> arguments
)

Deprecated Usage:

Map<String, Object> args = new HashMap<>();
args.put("x-message-ttl", 60000);
args.put("x-max-length", 1000);

RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container.withQueue("my-queue", false, true, args);
container.start();

Recommended Alternative (AMQP Client - Most Reliable):

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.util.HashMap;
import java.util.Map;

RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container.start();

ConnectionFactory factory = new ConnectionFactory();
factory.setUri(container.getAmqpUrl());
factory.setUsername(container.getAdminUsername());
factory.setPassword(container.getAdminPassword());

try (Connection connection = factory.newConnection();
     Channel channel = connection.createChannel()) {
    
    Map<String, Object> args = new HashMap<>();
    args.put("x-message-ttl", 60000);
    args.put("x-max-length", 1000);
    
    channel.queueDeclare("my-queue", true, false, false, args);
}

Alternative (rabbitmqadmin):

import org.testcontainers.containers.ExecResult;
import com.fasterxml.jackson.databind.ObjectMapper;

RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container.start();

// Prepare arguments as JSON
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> args = new HashMap<>();
args.put("x-message-ttl", 60000);
args.put("x-max-length", 1000);
String argsJson = mapper.writeValueAsString(args);

// Declare queue using rabbitmqadmin
ExecResult result = container.execInContainer(
    "rabbitmqadmin", "declare", "queue",
    "name=my-queue",
    "auto_delete=false",
    "durable=true",
    "arguments=" + argsJson
);

if (result.getExitCode() != 0) {
    throw new RuntimeException("Failed to declare queue: " + result.getStderr());
}

Queue Declaration in Virtual Host:

container.start();

// Create vhost first
container.execInContainer("rabbitmqctl", "add_vhost", "test-vhost");

// Declare queue in vhost using AMQP client
ConnectionFactory factory = new ConnectionFactory();
factory.setUri(container.getAmqpUrl());
factory.setUsername(container.getAdminUsername());
factory.setPassword(container.getAdminPassword());
factory.setVirtualHost("test-vhost");

try (Connection connection = factory.newConnection();
     Channel channel = connection.createChannel()) {
    channel.queueDeclare("my-queue", true, false, false, null);
}

Exchange Declaration

Declare RabbitMQ exchanges with various types and configuration options.

/**
 * Declares an exchange with default settings.
 * @deprecated use execInContainer(String...) or AMQP client instead
 * @param name Exchange name
 * @param type Exchange type ("direct", "fanout", "topic", "headers")
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withExchange(String name, String type)

/**
 * Declares an exchange in a specific virtual host.
 * @deprecated use execInContainer(String...) or AMQP client instead
 * @param vhost Virtual host name
 * @param name Exchange name
 * @param type Exchange type
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withExchange(String vhost, String name, String type)

/**
 * Declares an exchange with full configuration options.
 * @deprecated use execInContainer(String...) or AMQP client instead
 * @param name Exchange name
 * @param type Exchange type
 * @param autoDelete Auto-delete when unused
 * @param internal Internal exchange (cannot be published to directly)
 * @param durable Survive broker restart
 * @param arguments Additional exchange arguments
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withExchange(
    String name,
    String type,
    boolean autoDelete,
    boolean internal,
    boolean durable,
    Map<String, Object> arguments
)

/**
 * Declares an exchange in a virtual host with full configuration options.
 * @deprecated use execInContainer(String...) or AMQP client instead
 * @param vhost Virtual host name
 * @param name Exchange name
 * @param type Exchange type
 * @param autoDelete Auto-delete when unused
 * @param internal Internal exchange
 * @param durable Survive broker restart
 * @param arguments Additional exchange arguments
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withExchange(
    String vhost,
    String name,
    String type,
    boolean autoDelete,
    boolean internal,
    boolean durable,
    Map<String, Object> arguments
)

Deprecated Usage:

RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container
    .withExchange("my-exchange", "topic")
    .withExchange("logs-exchange", "fanout", false, false, true, Collections.emptyMap());
container.start();

Recommended Alternative (AMQP Client - Most Reliable):

RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container.start();

try (Connection connection = factory.newConnection();
     Channel channel = connection.createChannel()) {
    
    // Declare topic exchange
    channel.exchangeDeclare("my-exchange", "topic", true);
    
    // Declare fanout exchange
    channel.exchangeDeclare("logs-exchange", "fanout", true, false, null);
}

Alternative (rabbitmqadmin):

RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container.start();

// Declare exchanges using rabbitmqadmin
ExecResult result1 = container.execInContainer(
    "rabbitmqadmin", "declare", "exchange", 
    "name=my-exchange", "type=topic");
    
ExecResult result2 = container.execInContainer(
    "rabbitmqadmin", "declare", "exchange",
    "name=logs-exchange",
    "type=fanout",
    "auto_delete=false",
    "internal=false",
    "durable=true"
);

if (result1.getExitCode() != 0 || result2.getExitCode() != 0) {
    throw new RuntimeException("Failed to declare exchanges");
}

Binding Declaration

Create bindings between exchanges and queues or between exchanges.

/**
 * Creates a binding between source and destination.
 * @deprecated use execInContainer(String...) or AMQP client instead
 * @param source Source exchange name
 * @param destination Destination queue or exchange name
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withBinding(String source, String destination)

/**
 * Creates a binding in a specific virtual host.
 * @deprecated use execInContainer(String...) or AMQP client instead
 * @param vhost Virtual host name
 * @param source Source exchange name
 * @param destination Destination name
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withBinding(String vhost, String source, String destination)

/**
 * Creates a binding with full configuration options.
 * @deprecated use execInContainer(String...) or AMQP client instead
 * @param source Source exchange name
 * @param destination Destination name
 * @param arguments Binding arguments
 * @param routingKey Routing key for the binding
 * @param destinationType Type of destination ("queue" or "exchange")
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withBinding(
    String source,
    String destination,
    Map<String, Object> arguments,
    String routingKey,
    String destinationType
)

/**
 * Creates a binding in a virtual host with full configuration.
 * @deprecated use execInContainer(String...) or AMQP client instead
 * @param vhost Virtual host name
 * @param source Source exchange name
 * @param destination Destination name
 * @param arguments Binding arguments
 * @param routingKey Routing key
 * @param destinationType Type of destination
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withBinding(
    String vhost,
    String source,
    String destination,
    Map<String, Object> arguments,
    String routingKey,
    String destinationType
)

Deprecated Usage:

RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container
    .withExchange("my-exchange", "topic")
    .withQueue("my-queue")
    .withBinding("my-exchange", "my-queue", Collections.emptyMap(), "routing.key", "queue");
container.start();

Recommended Alternative (AMQP Client - Most Reliable):

RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container.start();

// Create exchange and queue first
try (Connection conn = factory.newConnection();
     Channel channel = conn.createChannel()) {
    channel.exchangeDeclare("my-exchange", "topic");
    channel.queueDeclare("my-queue", false, false, false, null);
    channel.queueBind("my-queue", "my-exchange", "routing.key");
}

Alternative (rabbitmqadmin):

container.start();
container.execInContainer("rabbitmqadmin", "declare", "exchange", 
    "name=my-exchange", "type=topic");
container.execInContainer("rabbitmqadmin", "declare", "queue", "name=my-queue");
container.execInContainer(
    "rabbitmqadmin", "declare", "binding",
    "source=my-exchange",
    "destination=my-queue",
    "routing_key=routing.key",
    "destination_type=queue"
);

User Management

Create RabbitMQ users with optional tags.

/**
 * Adds a user with no tags.
 * @deprecated use execInContainer(String...) instead
 * @param name Username
 * @param password Password
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withUser(String name, String password)

/**
 * Adds a user with specified tags.
 * @deprecated use execInContainer(String...) instead
 * @param name Username
 * @param password Password
 * @param tags User tags (e.g., "administrator", "monitoring")
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withUser(String name, String password, Set<String> tags)

Deprecated Usage:

Set<String> tags = new HashSet<>(Arrays.asList("administrator", "monitoring"));
RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container.withUser("testuser", "testpass", tags);
container.start();

Recommended Alternative (rabbitmqctl - Most Reliable):

RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container.start();

// Create user using rabbitmqctl (more reliable than rabbitmqadmin)
ExecResult result = container.execInContainer(
    "rabbitmqctl", "add_user", "testuser", "testpass");
    
if (result.getExitCode() != 0) {
    throw new RuntimeException("Failed to create user: " + result.getStderr());
}

// Set user tags
ExecResult tagsResult = container.execInContainer(
    "rabbitmqctl", "set_user_tags", "testuser", "administrator", "monitoring");
    
if (tagsResult.getExitCode() != 0) {
    throw new RuntimeException("Failed to set user tags: " + tagsResult.getStderr());
}

Alternative (rabbitmqadmin):

container.start();
ExecResult result = container.execInContainer(
    "rabbitmqadmin", "declare", "user",
    "name=testuser",
    "password=testpass",
    "tags=administrator,monitoring"
);

if (result.getExitCode() != 0) {
    throw new RuntimeException("Failed to create user: " + result.getStderr());
}

User Already Exists:

// Check if user exists first
ExecResult checkResult = container.execInContainer(
    "rabbitmqctl", "list_users");
    
if (checkResult.getStdout().contains("testuser")) {
    // User exists - update password or skip
    container.execInContainer(
        "rabbitmqctl", "change_password", "testuser", "newpassword");
} else {
    // User doesn't exist - create
    container.execInContainer(
        "rabbitmqctl", "add_user", "testuser", "testpass");
}

Virtual Host Management

Create and configure virtual hosts.

/**
 * Creates a virtual host.
 * @deprecated use execInContainer(String...) instead
 * @param name Virtual host name
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withVhost(String name)

/**
 * Creates a virtual host with tracing option.
 * @deprecated use execInContainer(String...) instead
 * @param name Virtual host name
 * @param tracing Enable tracing
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withVhost(String name, boolean tracing)

/**
 * Sets virtual host limits.
 * @deprecated use execInContainer(String...) instead
 * @param vhost Virtual host name
 * @param name Limit name (e.g., "max-connections", "max-queues")
 * @param value Limit value
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withVhostLimit(String vhost, String name, int value)

Deprecated Usage:

RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container
    .withVhost("test-vhost", true)
    .withVhostLimit("test-vhost", "max-connections", 100);
container.start();

Recommended Alternative (rabbitmqctl - Most Reliable):

RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container.start();

// Create vhost using rabbitmqctl
ExecResult vhostResult = container.execInContainer(
    "rabbitmqctl", "add_vhost", "test-vhost");
    
if (vhostResult.getExitCode() != 0) {
    throw new RuntimeException("Failed to create vhost: " + vhostResult.getStderr());
}

// Enable tracing (if supported)
ExecResult traceResult = container.execInContainer(
    "rabbitmqctl", "trace_on", "-p", "test-vhost");
    
// Set vhost limits using rabbitmqctl
ExecResult limitResult = container.execInContainer(
    "rabbitmqctl", "set_vhost_limits", "-p", "test-vhost",
    "{\"max-connections\":100}");
    
if (limitResult.getExitCode() != 0) {
    throw new RuntimeException("Failed to set vhost limits: " + limitResult.getStderr());
}

Alternative (rabbitmqadmin):

container.start();
container.execInContainer("rabbitmqadmin", "declare", "vhost", 
    "name=test-vhost", "tracing=true");
container.execInContainer(
    "rabbitmqadmin", "declare", "vhost_limit",
    "vhost=test-vhost",
    "name=max-connections",
    "value=100"
);

Permission Management

Set user permissions for virtual hosts.

/**
 * Sets user permissions for a virtual host.
 * @deprecated use execInContainer(String...) instead
 * @param vhost Virtual host name
 * @param user Username
 * @param configure Configure permission pattern (regex)
 * @param write Write permission pattern (regex)
 * @param read Read permission pattern (regex)
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withPermission(
    String vhost,
    String user,
    String configure,
    String write,
    String read
)

Deprecated Usage:

RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container.withPermission("test-vhost", "testuser", ".*", ".*", ".*");
container.start();

Recommended Alternative (rabbitmqctl - Most Reliable):

RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container.start();

// Set permissions using rabbitmqctl
ExecResult result = container.execInContainer(
    "rabbitmqctl", "set_permissions", "-p", "test-vhost",
    "testuser", ".*", ".*", ".*");
    
if (result.getExitCode() != 0) {
    throw new RuntimeException("Failed to set permissions: " + result.getStderr());
}

Alternative (rabbitmqadmin):

container.start();
container.execInContainer(
    "rabbitmqadmin", "declare", "permission",
    "vhost=test-vhost",
    "user=testuser",
    "configure=.*",
    "write=.*",
    "read=.*"
);

Policy Management

Create policies and operator policies for queues and exchanges.

/**
 * Creates a policy with basic settings.
 * @deprecated use execInContainer(String...) instead
 * @param name Policy name
 * @param pattern Pattern to match queue/exchange names (regex)
 * @param definition Policy definition (key-value map)
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withPolicy(
    String name,
    String pattern,
    Map<String, Object> definition
)

/**
 * Creates a policy in a specific virtual host.
 * @deprecated use execInContainer(String...) instead
 * @param vhost Virtual host name
 * @param name Policy name
 * @param pattern Pattern to match queue/exchange names
 * @param definition Policy definition
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withPolicy(
    String vhost,
    String name,
    String pattern,
    Map<String, Object> definition
)

/**
 * Creates a policy with full configuration options.
 * @deprecated use execInContainer(String...) instead
 * @param name Policy name
 * @param pattern Pattern to match queue/exchange names
 * @param definition Policy definition
 * @param priority Policy priority (higher values take precedence)
 * @param applyTo Apply to "queues", "exchanges", or "all"
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withPolicy(
    String name,
    String pattern,
    Map<String, Object> definition,
    int priority,
    String applyTo
)

/**
 * Creates an operator policy with basic settings.
 * Operator policies override regular policies.
 * @deprecated use execInContainer(String...) instead
 * @param name Operator policy name
 * @param pattern Pattern to match queue/exchange names
 * @param definition Policy definition
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withOperatorPolicy(
    String name,
    String pattern,
    Map<String, Object> definition
)

/**
 * Creates an operator policy with full configuration options.
 * @deprecated use execInContainer(String...) instead
 * @param name Operator policy name
 * @param pattern Pattern to match queue/exchange names
 * @param definition Policy definition
 * @param priority Policy priority
 * @param applyTo Apply to "queues", "exchanges", or "all"
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withOperatorPolicy(
    String name,
    String pattern,
    Map<String, Object> definition,
    int priority,
    String applyTo
)

Deprecated Usage:

Map<String, Object> definition = new HashMap<>();
definition.put("max-length", 1000);
definition.put("overflow", "reject-publish");

RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container.withPolicy("length-limit", "^logs\\..*", definition, 10, "queues");
container.start();

Recommended Alternative (rabbitmqctl - Most Reliable):

import com.fasterxml.jackson.databind.ObjectMapper;

RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container.start();

// Prepare policy definition as JSON
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> definition = new HashMap<>();
definition.put("max-length", 1000);
definition.put("overflow", "reject-publish");
String definitionJson = mapper.writeValueAsString(definition);

// Create policy using rabbitmqctl
ExecResult result = container.execInContainer(
    "rabbitmqctl", "set_policy",
    "length-limit",
    "^logs\\..*",
    definitionJson,
    "--priority", "10",
    "--apply-to", "queues"
);

if (result.getExitCode() != 0) {
    throw new RuntimeException("Failed to create policy: " + result.getStderr());
}

Alternative (rabbitmqadmin):

container.start();
ObjectMapper mapper = new ObjectMapper();
String definitionJson = mapper.writeValueAsString(definition);

container.execInContainer(
    "rabbitmqadmin", "declare", "policy",
    "name=length-limit",
    "pattern=^logs\\..*",
    "priority=10",
    "apply-to=queues",
    "definition=" + definitionJson
);

Parameter Management

Set RabbitMQ parameters for components.

/**
 * Sets a RabbitMQ parameter.
 * @deprecated use execInContainer(String...) instead
 * @param component Component name (e.g., "federation-upstream")
 * @param name Parameter name
 * @param value Parameter value (JSON string)
 * @return This container for method chaining
 */
@Deprecated
public RabbitMQContainer withParameter(String component, String name, String value)

Deprecated Usage:

RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container.withParameter("federation-upstream", "my-upstream", 
    "{\"uri\":\"amqp://server\"}");
container.start();

Recommended Alternative (rabbitmqctl - Most Reliable):

RabbitMQContainer container = new RabbitMQContainer(
    DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
container.start();

// Set parameter using rabbitmqctl
ExecResult result = container.execInContainer(
    "rabbitmqctl", "set_parameter",
    "federation-upstream",
    "my-upstream",
    "{\"uri\":\"amqp://server\"}"
);

if (result.getExitCode() != 0) {
    throw new RuntimeException("Failed to set parameter: " + result.getStderr());
}

Alternative (rabbitmqadmin):

container.start();
container.execInContainer(
    "rabbitmqadmin", "declare", "parameter",
    "component=federation-upstream",
    "name=my-upstream",
    "value={\"uri\":\"amqp://server\"}"
);

Complete Migration Example

import org.testcontainers.containers.RabbitMQContainer;
import org.testcontainers.containers.ExecResult;
import org.testcontainers.utility.DockerImageName;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.Map;

public class RabbitMQTest {
    
    @Test
    public void testWithModernAPI() throws Exception {
        RabbitMQContainer container = new RabbitMQContainer(
            DockerImageName.parse("rabbitmq:3.7.25-management-alpine"));
        container.start();
        
        // Create connection
        ConnectionFactory factory = new ConnectionFactory();
        factory.setUri(container.getAmqpUrl());
        factory.setUsername(container.getAdminUsername());
        factory.setPassword(container.getAdminPassword());
        
        try (Connection connection = factory.newConnection();
             Channel channel = connection.createChannel()) {
            
            // Declare exchange and queue using AMQP (recommended)
            channel.exchangeDeclare("test-exchange", "topic", true);
            channel.queueDeclare("test-queue", true, false, false, null);
            channel.queueBind("test-queue", "test-exchange", "test.routing.key");
            
            // Create user using rabbitmqctl (recommended)
            ExecResult userResult = container.execInContainer(
                "rabbitmqctl", "add_user", "testuser", "testpass");
            if (userResult.getExitCode() != 0) {
                throw new RuntimeException("Failed to create user");
            }
            
            // Set permissions using rabbitmqctl (recommended)
            ExecResult permResult = container.execInContainer(
                "rabbitmqctl", "set_permissions", "-p", "/",
                "testuser", ".*", ".*", ".*");
            if (permResult.getExitCode() != 0) {
                throw new RuntimeException("Failed to set permissions");
            }
            
            // Create policy using rabbitmqctl (recommended)
            ObjectMapper mapper = new ObjectMapper();
            Map<String, Object> policyDef = new HashMap<>();
            policyDef.put("max-length", 100);
            String policyJson = mapper.writeValueAsString(policyDef);
            
            ExecResult policyResult = container.execInContainer(
                "rabbitmqctl", "set_policy",
                "test-policy",
                "^test-.*",
                policyJson,
                "--priority", "10",
                "--apply-to", "queues"
            );
            if (policyResult.getExitCode() != 0) {
                throw new RuntimeException("Failed to create policy");
            }
        }
    }
}

Summary

All deprecated methods provide declarative configuration that is executed after container startup. While still functional, these methods are deprecated because:

  1. They limit access to newer RabbitMQ features
  2. Direct command execution provides better error messages
  3. The rabbitmqadmin/rabbitmqctl CLI tools offer more flexibility
  4. Future RabbitMQ versions may require different command syntax
  5. AMQP client API is more reliable and type-safe for queue/exchange/binding operations
  6. Error handling is more explicit with ExecResult
  7. Command execution can be verified with exit codes
  8. Deprecated methods may not support all RabbitMQ configuration options
  9. Direct command execution allows for more complex configuration scenarios
  10. AMQP client API provides better type safety and compile-time checking

For new code, always prefer:

  • AMQP client API for queues, exchanges, and bindings (most reliable, type-safe)
  • rabbitmqctl for users, vhosts, permissions, and policies (most reliable, always available)
  • rabbitmqadmin for management operations (requires management plugin, more features)
  • execInContainer() for any custom RabbitMQ operations

Migration Checklist:

  • Replace withQueue() with AMQP client channel.queueDeclare()
  • Replace withExchange() with AMQP client channel.exchangeDeclare()
  • Replace withBinding() with AMQP client channel.queueBind() or channel.exchangeBind()
  • Replace withUser() with execInContainer("rabbitmqctl", "add_user", ...)
  • Replace withVhost() with execInContainer("rabbitmqctl", "add_vhost", ...)
  • Replace withPermission() with execInContainer("rabbitmqctl", "set_permissions", ...)
  • Replace withPolicy() with execInContainer("rabbitmqctl", "set_policy", ...)
  • Replace withPluginsEnabled() with execInContainer("rabbitmq-plugins", "enable", ...)
  • Add error handling with ExecResult.getExitCode() checks
  • Test all migrated operations to ensure they work correctly