-
-
Notifications
You must be signed in to change notification settings - Fork 297
/
Copy pathServiceBusBuilder.cs
168 lines (141 loc) · 6.8 KB
/
ServiceBusBuilder.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
namespace Testcontainers.ServiceBus;
/// <inheritdoc cref="ContainerBuilder{TBuilderEntity, TContainerEntity, TConfigurationEntity}" />
[PublicAPI]
public sealed class ServiceBusBuilder : ContainerBuilder<ServiceBusBuilder, ServiceBusContainer, ServiceBusConfiguration>
{
public const string ServiceBusNetworkAlias = "servicebus-container";
public const string DatabaseNetworkAlias = "database-container";
public const string ServiceBusImage = "mcr.microsoft.com/azure-messaging/servicebus-emulator:latest";
public const ushort ServiceBusPort = 5672;
private const string AcceptLicenseAgreementEnvVar = "ACCEPT_EULA";
private const string AcceptLicenseAgreement = "Y";
private const string DeclineLicenseAgreement = "N";
/// <summary>
/// Initializes a new instance of the <see cref="ServiceBusBuilder" /> class.
/// </summary>
public ServiceBusBuilder()
: this(new ServiceBusConfiguration())
{
DockerResourceConfiguration = Init().DockerResourceConfiguration;
}
/// <summary>
/// Initializes a new instance of the <see cref="ServiceBusBuilder" /> class.
/// </summary>
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
private ServiceBusBuilder(ServiceBusConfiguration resourceConfiguration)
: base(resourceConfiguration)
{
DockerResourceConfiguration = resourceConfiguration;
}
/// <inheritdoc />
protected override ServiceBusConfiguration DockerResourceConfiguration { get; }
/// <summary>
/// Accepts the license agreement.
/// </summary>
/// <remarks>
/// When <paramref name="acceptLicenseAgreement" /> is set to <c>true</c>, the Azure Service Bus Emulator <see href="https://github.com/Azure/azure-service-bus-emulator-installer/blob/main/EMULATOR_EULA.txt">license</see> is accepted.
/// </remarks>
/// <param name="acceptLicenseAgreement">A boolean value indicating whether the Azure Service Bus Emulator license agreement is accepted.</param>
/// <returns>A configured instance of <see cref="ServiceBusBuilder" />.</returns>
public ServiceBusBuilder WithAcceptLicenseAgreement(bool acceptLicenseAgreement)
{
var licenseAgreement = acceptLicenseAgreement ? AcceptLicenseAgreement : DeclineLicenseAgreement;
return WithEnvironment(AcceptLicenseAgreementEnvVar, licenseAgreement);
}
/// <summary>
/// Sets the dependent MSSQL container for the Azure Service Bus Emulator.
/// </summary>
/// <remarks>
/// This method allows an existing MSSQL container to be attached to the Azure Service
/// Bus Emulator. The containers must be on the same network to enable communication
/// between them.
/// </remarks>
/// <param name="network">The network to connect the container to.</param>
/// <param name="container">The MSSQL container.</param>
/// <param name="networkAlias">The MSSQL container network alias.</param>
/// <param name="password">The MSSQL container password.</param>
/// <returns>A configured instance of <see cref="ServiceBusBuilder" />.</returns>
public ServiceBusBuilder WithMsSqlContainer(
INetwork network,
MsSqlContainer container,
string networkAlias,
string password = MsSqlBuilder.DefaultPassword)
{
return Merge(DockerResourceConfiguration, new ServiceBusConfiguration(databaseContainer: container))
.DependsOn(container)
.WithNetwork(network)
.WithNetworkAliases(ServiceBusNetworkAlias)
.WithEnvironment("SQL_SERVER", networkAlias)
.WithEnvironment("MSSQL_SA_PASSWORD", password);
}
/// <inheritdoc />
public override ServiceBusContainer Build()
{
Validate();
if (DockerResourceConfiguration.DatabaseContainer != null)
{
return new ServiceBusContainer(DockerResourceConfiguration);
}
// If the user has not provided an existing MSSQL container instance,
// we configure one.
var network = new NetworkBuilder()
.Build();
var container = new MsSqlBuilder()
.WithNetwork(network)
.WithNetworkAliases(DatabaseNetworkAlias)
.Build();
var serviceBusContainer = WithMsSqlContainer(network, container, DatabaseNetworkAlias);
return new ServiceBusContainer(serviceBusContainer.DockerResourceConfiguration);
}
/// <inheritdoc />
protected override void Validate()
{
const string message = "The image '{0}' requires you to accept a license agreement.";
base.Validate();
Predicate<ServiceBusConfiguration> licenseAgreementNotAccepted = value =>
!value.Environments.TryGetValue(AcceptLicenseAgreementEnvVar, out var licenseAgreementValue) || !AcceptLicenseAgreement.Equals(licenseAgreementValue, StringComparison.Ordinal);
_ = Guard.Argument(DockerResourceConfiguration, nameof(DockerResourceConfiguration.Image))
.ThrowIf(argument => licenseAgreementNotAccepted(argument.Value), argument => throw new ArgumentException(string.Format(message, DockerResourceConfiguration.Image.FullName), argument.Name));
}
/// <inheritdoc />
protected override ServiceBusBuilder Init()
{
return base.Init()
.WithImage(ServiceBusImage)
.WithPortBinding(ServiceBusPort, true)
.WithWaitStrategy(Wait.ForUnixContainer()
.UntilMessageIsLogged("Emulator Service is Successfully Up!")
.AddCustomWaitStrategy(new WaitTwoSeconds()));
}
/// <inheritdoc />
protected override ServiceBusBuilder Clone(IResourceConfiguration<CreateContainerParameters> resourceConfiguration)
{
return Merge(DockerResourceConfiguration, new ServiceBusConfiguration(resourceConfiguration));
}
/// <inheritdoc />
protected override ServiceBusBuilder Clone(IContainerConfiguration resourceConfiguration)
{
return Merge(DockerResourceConfiguration, new ServiceBusConfiguration(resourceConfiguration));
}
/// <inheritdoc />
protected override ServiceBusBuilder Merge(ServiceBusConfiguration oldValue, ServiceBusConfiguration newValue)
{
return new ServiceBusBuilder(new ServiceBusConfiguration(oldValue, newValue));
}
/// <inheritdoc cref="IWaitUntil" />
/// <remarks>
/// This is a workaround to ensure that the wait strategy does not indicate
/// readiness too early:
/// https://github.com/Azure/azure-service-bus-emulator-installer/issues/35#issuecomment-2497164533.
/// </remarks>
private sealed class WaitTwoSeconds : IWaitUntil
{
/// <inheritdoc />
public async Task<bool> UntilAsync(IContainer container)
{
await Task.Delay(TimeSpan.FromSeconds(2))
.ConfigureAwait(false);
return true;
}
}
}