Skip to content

Commit 28d8d48

Browse files
committed
Update docs for rabbitmq transport along with rabbitmq config validation
1 parent acb2510 commit 28d8d48

File tree

8 files changed

+267
-40
lines changed

8 files changed

+267
-40
lines changed

.editorconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ indent_size = 2
2626

2727
[*.md]
2828
trim_trailing_whitespace = false
29+
indent_size = 2
2930

3031
[*.cs]
3132
# Sort using and Import directives with System.* appearing first
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using FluentValidation;
2+
3+
namespace BuslyCLI.Config.Validators;
4+
5+
public class RabbitMQTransportConfigValidator : AbstractValidator<RabbitmqTransportConfig>
6+
{
7+
public RabbitMQTransportConfigValidator()
8+
{
9+
RuleFor(x => x.AmqpConnectionString)
10+
.NotEmpty();
11+
12+
RuleFor(x => x.ManagementApi)
13+
.SetValidator(new ManagementApiConfigValidator());
14+
}
15+
}
16+
17+
public class ManagementApiConfigValidator : AbstractValidator<ManagementApi>
18+
{
19+
public ManagementApiConfigValidator()
20+
{
21+
RuleFor(x => x)
22+
.Must(x =>
23+
(string.IsNullOrEmpty(x.UserName) && string.IsNullOrEmpty(x.Password)) // both empty
24+
|| (!string.IsNullOrEmpty(x.UserName) && !string.IsNullOrEmpty(x.Password)) // both set
25+
)
26+
.WithMessage("Username and Password are mutually dependent: if one is set, the other must also be set.");
27+
}
28+
}

src/BuslyCLI.Console/Factories/RawEndpointFactory.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,13 @@ private TransportDefinition CreateTransport(TransportConfig transportConfig)
4343

4444
private RabbitMQTransport CreateRabbitMQTransport(RabbitmqTransportConfig rabbitmqTransportConfig)
4545
{
46-
var t = new RabbitMQTransport(RoutingTopology.Conventional(QueueType.Quorum),
47-
rabbitmqTransportConfig.AmqpConnectionString)
46+
var t = new RabbitMQTransport(RoutingTopology.Conventional(QueueType.Quorum), rabbitmqTransportConfig.AmqpConnectionString);
47+
48+
if (rabbitmqTransportConfig.ManagementApi != null)
4849
{
49-
ManagementApiConfiguration = CreateManagementApiConfig(rabbitmqTransportConfig.ManagementApi)
50-
};
50+
t.ManagementApiConfiguration =
51+
CreateManagementApiConfig(rabbitmqTransportConfig.ManagementApi);
52+
}
5153
return t;
5254
}
5355

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
using Bogus;
2+
using BuslyCLI.Config;
3+
using BuslyCLI.Config.Validators;
4+
using FluentValidation.TestHelper;
5+
6+
namespace BuslyCLI.Console.Tests.Config.Validators;
7+
8+
[TestFixture]
9+
public class ManagementApiConfigValidatorTests
10+
{
11+
private readonly ManagementApiConfigValidator _validator;
12+
13+
public ManagementApiConfigValidatorTests()
14+
{
15+
_validator = new ManagementApiConfigValidator();
16+
}
17+
18+
// [Test]
19+
// public async Task ShouldErrorWhenAmqpConnectionStringIsNotPassed()
20+
// {
21+
// // Arrange
22+
// var rabbitmqTransportConfig = new ManagementApi()
23+
// {
24+
// AmqpConnectionString = null
25+
// };
26+
// // Act
27+
// var result = await _validator.TestValidateAsync(rabbitmqTransportConfig);
28+
//
29+
// // Assert
30+
// result.ShouldHaveValidationErrorFor(c => c.AmqpConnectionString)
31+
// .WithErrorMessage("'Amqp Connection String' must not be empty.");
32+
// }
33+
34+
[Test]
35+
public async Task ShouldNotErrorWhenOnlyAUrlStringIsPassed()
36+
{
37+
// Arrange
38+
var managementApi = new ManagementApi()
39+
{
40+
Url = "http://localhost:15672"
41+
};
42+
// Act
43+
var result = await _validator.TestValidateAsync(managementApi);
44+
45+
// Assert
46+
result.ShouldNotHaveValidationErrorFor(c => c.Url);
47+
}
48+
49+
[Test]
50+
public async Task ShouldNotErrorWhenOnlyCredentialsAreIsPassed()
51+
{
52+
// Arrange
53+
var managementApi = new ManagementApi()
54+
{
55+
UserName = new Faker().Internet.UserName(),
56+
Password = new Faker().Internet.Password()
57+
};
58+
// Act
59+
var result = await _validator.TestValidateAsync(managementApi);
60+
61+
// Assert
62+
result.ShouldNotHaveAnyValidationErrors();
63+
}
64+
65+
[Test]
66+
public async Task ShouldNotErrorWhenUrlAndCredentialsAreIsPassed()
67+
{
68+
// Arrange
69+
var managementApi = new ManagementApi()
70+
{
71+
Url = "http://localhost:15672",
72+
UserName = new Faker().Internet.UserName(),
73+
Password = new Faker().Internet.Password()
74+
};
75+
// Act
76+
var result = await _validator.TestValidateAsync(managementApi);
77+
78+
// Assert
79+
result.ShouldNotHaveAnyValidationErrors();
80+
}
81+
82+
[Test]
83+
public async Task ShouldErrorWhenUserNameIsPassedWithoutPassword()
84+
{
85+
// Arrange
86+
var managementApi = new ManagementApi()
87+
{
88+
UserName = new Faker().Internet.UserName()
89+
};
90+
// Act
91+
var result = await _validator.TestValidateAsync(managementApi);
92+
93+
// Assert
94+
result.ShouldHaveValidationErrors().WithErrorMessage("Username and Password are mutually dependent: if one is set, the other must also be set.");
95+
}
96+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using BuslyCLI.Config;
2+
using BuslyCLI.Config.Validators;
3+
using FluentValidation.TestHelper;
4+
5+
namespace BuslyCLI.Console.Tests.Config.Validators;
6+
7+
[TestFixture]
8+
public class RabbitMQTransportConfigValidatorTests
9+
{
10+
private readonly RabbitMQTransportConfigValidator _validator;
11+
12+
public RabbitMQTransportConfigValidatorTests()
13+
{
14+
_validator = new RabbitMQTransportConfigValidator();
15+
}
16+
17+
[Test]
18+
public async Task ShouldErrorWhenAmqpConnectionStringIsNotPassed()
19+
{
20+
// Arrange
21+
var rabbitmqTransportConfig = new RabbitmqTransportConfig()
22+
{
23+
AmqpConnectionString = null
24+
};
25+
// Act
26+
var result = await _validator.TestValidateAsync(rabbitmqTransportConfig);
27+
28+
// Assert
29+
result.ShouldHaveValidationErrorFor(c => c.AmqpConnectionString)
30+
.WithErrorMessage("'Amqp Connection String' must not be empty.");
31+
}
32+
33+
[Test]
34+
public async Task ShouldNotErrorWhenAmqpConnectionStringIsPassed()
35+
{
36+
// Arrange
37+
var rabbitmqTransportConfig = new RabbitmqTransportConfig()
38+
{
39+
AmqpConnectionString = "amqp://localhost"
40+
};
41+
// Act
42+
var result = await _validator.TestValidateAsync(rabbitmqTransportConfig);
43+
44+
// Assert
45+
result.ShouldNotHaveValidationErrorFor(c => c.AmqpConnectionString);
46+
}
47+
}

website/docs/transports/learning.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,20 @@ To use the Learning Transport, define it under `transports` and reference it as
1212
current-transport: local-learning
1313

1414
transports:
15-
- name: local-learning
16-
learning-transport-config:
17-
storage-directory: C:\Source\tutorials-quickstart\.learningtransport
18-
restrict-payload-size: true
15+
- name: local-learning
16+
learning-transport-config:
17+
storage-directory: C:\Source\tutorials-quickstart\.learningtransport
18+
restrict-payload-size: true
1919
```
2020
2121
---
2222
2323
## `learning-transport-config` Fields
2424

25-
| Field | Required | Type | Default | Description |
26-
| ----------------------- | -------- | ------- | ------- | ----------------------------------------------------------------------------------------------------- |
27-
| `storage-directory` | **Yes** | string | — | Absolute path where Learning Transport stores message files. Busly will not start without this value. |
28-
| `restrict-payload-size` | No | boolean | `true` | Enforces the NServiceBus payload size limit. Set to `false` if you need to send larger payloads. |
25+
| Field | Required | Type | Default | Description |
26+
| ----------------------- | -------- | ------- | ------- | ------------------------------------------------------------------------------------------------ |
27+
| `storage-directory` | **Yes** | string | — | Absolute path where Learning Transport stores message files. |
28+
| `restrict-payload-size` | No | boolean | `true` | Enforces the NServiceBus payload size limit. Set to `false` if you need to send larger payloads. |
2929

3030
---
3131

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# RabbitMQ
2+
3+
The **RabbitMQ Transport** is used to communicate to RabbitMQ.
4+
It is suitable for development, testing, and production environments.
5+
6+
## Configuration
7+
8+
To use the RabbitMQ Transport, define it under `transports` and reference it as `current-transport`.
9+
10+
### Example
11+
12+
```yaml
13+
current-transport: local-rabbitmq
14+
15+
transports:
16+
- name: local-rabbitmq
17+
rabbitmq-transport-config:
18+
amqp-connection-string: amqp://localhost
19+
```
20+
21+
---
22+
23+
## `rabbitmq-transport-config` Fields
24+
25+
| Field | Required | Type | Default | Description |
26+
| ------------------------ | -------- | ------ | ------- | ----------------------------------------------------------------- |
27+
| `amqp-connection-string` | **Yes** | string | — | Full AMQP connection string used to connect to RabbitMQ. |
28+
| `management-api` | No | object | — | Optional configuration to connect to the RabbitMQ Management API. |
29+
30+
---
31+
32+
## `management-api` Fields
33+
34+
| Field | Required | Type | Default | Description |
35+
| ---------- | -------- | ------ | ------- | ------------------------------------------------------------------------------------------------------------- |
36+
| `url` | No | string | — | Base URL for the RabbitMQ Management API. Example: http://localhost:15672. |
37+
| `username` | No | string | — | Username for authenticating with the Management API. If username is provided, password must also be provided. |
38+
| `password` | No | string | — | Password for authenticating with the Management API. If password is provided, username must also be provided. |
39+
40+
---
41+
42+
## Field Details
43+
44+
### `amqp-connection-string` (required)
45+
46+
A standard AMQP URI used to connect to RabbitMQ.
47+
48+
Examples:
49+
50+
```yaml
51+
amqp-connection-string: amqp://guest:guest@localhost:5672/
52+
```
53+
54+
```yaml
55+
amqp-connection-string: amqps://user:[email protected]:5671/my-vhost
56+
```
57+
58+
### `management-api` (optional)
59+
60+
Allows Busly to interact with the RabbitMQ Management API for monitoring or queue management.
61+
62+
Examples:
63+
64+
```yaml
65+
management-api:
66+
url: http://localhost:15672
67+
```
68+
69+
```yaml
70+
management-api:
71+
username: admin
72+
password: hello123!
73+
```
74+
75+
```yaml
76+
management-api:
77+
url: http://localhost:15672
78+
username: admin
79+
password: hello123!
80+
```

0 commit comments

Comments
 (0)