-
-
Notifications
You must be signed in to change notification settings - Fork 301
/
Copy pathServiceBusBuilder.cs
143 lines (119 loc) · 5.78 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
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);
}
/// <inheritdoc />
public override ServiceBusContainer Build()
{
Validate();
return new 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)
.WithNetwork(new NetworkBuilder().Build())
.WithNetworkAliases(ServiceBusNetworkAlias)
.WithPortBinding(ServiceBusPort, true)
.WithMsSqlContainer()
.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));
}
/// <summary>
/// Configures the dependent MSSQL container.
/// </summary>
/// <returns>A configured instance of <see cref="ServiceBusBuilder" />.</returns>
private ServiceBusBuilder WithMsSqlContainer()
{
var msSqlContainer = new MsSqlBuilder()
.WithNetwork(DockerResourceConfiguration.Networks.Single())
.WithNetworkAliases(DatabaseNetworkAlias)
.Build();
return Merge(DockerResourceConfiguration, new ServiceBusConfiguration(databaseContainer: msSqlContainer))
.WithEnvironment("MSSQL_SA_PASSWORD", MsSqlBuilder.DefaultPassword)
.WithEnvironment("SQL_SERVER", DatabaseNetworkAlias);
}
/// <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;
}
}
}