1+ namespace Testcontainers . Mosquitto ;
2+
3+ /// <inheritdoc cref="ContainerBuilder{TBuilderEntity, TContainerEntity, TConfigurationEntity}" />
4+ [ PublicAPI ]
5+ public sealed class MosquittoBuilder : ContainerBuilder < MosquittoBuilder , MosquittoContainer , MosquittoConfiguration >
6+ {
7+ public const string MosquittoImage = "eclipse-mosquitto:2.0" ;
8+
9+ public const ushort MqttPort = 1883 ;
10+
11+ public const ushort MqttTlsPort = 8883 ;
12+
13+ public const ushort MqttWsPort = 8080 ;
14+
15+ public const ushort MqttWssPort = 8081 ;
16+
17+ public const string CertificateFilePath = "/etc/mosquitto/certs/server.crt" ;
18+
19+ public const string CertificateKeyFilePath = "/etc/mosquitto/certs/server.key" ;
20+
21+ /// <summary>
22+ /// Initializes a new instance of the <see cref="MosquittoBuilder" /> class.
23+ /// </summary>
24+ public MosquittoBuilder ( )
25+ : this ( new MosquittoConfiguration ( ) )
26+ {
27+ DockerResourceConfiguration = Init ( ) . DockerResourceConfiguration ;
28+ }
29+
30+ /// <summary>
31+ /// Initializes a new instance of the <see cref="MosquittoBuilder" /> class.
32+ /// </summary>
33+ /// <param name="resourceConfiguration">The Docker resource configuration.</param>
34+ public MosquittoBuilder ( MosquittoConfiguration resourceConfiguration )
35+ : base ( resourceConfiguration )
36+ {
37+ DockerResourceConfiguration = resourceConfiguration ;
38+ }
39+
40+ /// <inheritdoc />
41+ protected override MosquittoConfiguration DockerResourceConfiguration { get ; }
42+
43+ /// <summary>
44+ /// Sets the public certificate and private key to enable TLS.
45+ /// </summary>
46+ /// <param name="certificate">The public certificate in PEM format.</param>
47+ /// <param name="certificateKey">The private key associated with the certificate in PEM format.</param>
48+ /// <returns>A configured instance of <see cref="MosquittoBuilder" />.</returns>
49+ public MosquittoBuilder WithCertificate ( string certificate , string certificateKey )
50+ {
51+ return Merge ( DockerResourceConfiguration , new MosquittoConfiguration ( certificate : certificate , certificateKey : certificateKey ) )
52+ . WithPortBinding ( MqttTlsPort , true )
53+ . WithPortBinding ( MqttWssPort , true )
54+ . WithResourceMapping ( Encoding . Default . GetBytes ( certificate ) , CertificateFilePath )
55+ . WithResourceMapping ( Encoding . Default . GetBytes ( certificateKey ) , CertificateKeyFilePath ) ;
56+ }
57+
58+ /// <inheritdoc />
59+ public override MosquittoContainer Build ( )
60+ {
61+ Validate ( ) ;
62+
63+ // Maybe we should move this into the startup callback.
64+ var mosquittoConfig = new StringWriter ( ) ;
65+ mosquittoConfig . NewLine = "\n " ;
66+
67+ mosquittoConfig . WriteLine ( "per_listener_settings true" ) ;
68+ mosquittoConfig . WriteLine ( "log_dest stdout" ) ;
69+ mosquittoConfig . WriteLine ( "log_type information" ) ;
70+
71+ mosquittoConfig . WriteLine ( ) ;
72+ mosquittoConfig . WriteLine ( "persistence false" ) ;
73+ mosquittoConfig . WriteLine ( "persistence_location /mosquitto/data/" ) ;
74+
75+ mosquittoConfig . WriteLine ( ) ;
76+ mosquittoConfig . WriteLine ( "# MQTT, unencrypted, unauthenticated" ) ;
77+ mosquittoConfig . WriteLine ( $ "listener { MqttPort } 0.0.0.0") ;
78+ mosquittoConfig . WriteLine ( "protocol mqtt" ) ;
79+ mosquittoConfig . WriteLine ( "allow_anonymous true" ) ;
80+
81+ mosquittoConfig . WriteLine ( ) ;
82+ mosquittoConfig . WriteLine ( "# MQTT over WebSockets, unencrypted, unauthenticated" ) ;
83+ mosquittoConfig . WriteLine ( $ "listener { MqttWsPort } 0.0.0.0") ;
84+ mosquittoConfig . WriteLine ( "protocol websockets" ) ;
85+ mosquittoConfig . WriteLine ( "allow_anonymous true" ) ;
86+
87+ if ( DockerResourceConfiguration . TlsEnabled )
88+ {
89+ mosquittoConfig . WriteLine ( ) ;
90+ mosquittoConfig . WriteLine ( "# MQTT, encrypted, unauthenticated" ) ;
91+ mosquittoConfig . WriteLine ( $ "listener { MqttTlsPort } 0.0.0.0") ;
92+ mosquittoConfig . WriteLine ( "protocol mqtt" ) ;
93+ mosquittoConfig . WriteLine ( "allow_anonymous true" ) ;
94+ mosquittoConfig . WriteLine ( "tls_version tlsv1.2" ) ;
95+ mosquittoConfig . WriteLine ( $ "certfile { CertificateFilePath } ") ;
96+ mosquittoConfig . WriteLine ( $ "keyfile { CertificateKeyFilePath } ") ;
97+
98+ mosquittoConfig . WriteLine ( ) ;
99+ mosquittoConfig . WriteLine ( "# MQTT over WebSockets, encrypted, unauthenticated" ) ;
100+ mosquittoConfig . WriteLine ( $ "listener { MqttWssPort } 0.0.0.0") ;
101+ mosquittoConfig . WriteLine ( "protocol websockets" ) ;
102+ mosquittoConfig . WriteLine ( "allow_anonymous true" ) ;
103+ mosquittoConfig . WriteLine ( "tls_version tlsv1.2" ) ;
104+ mosquittoConfig . WriteLine ( $ "certfile { CertificateFilePath } ") ;
105+ mosquittoConfig . WriteLine ( $ "keyfile { CertificateKeyFilePath } ") ;
106+ }
107+
108+ var mosquittoBuilder = WithResourceMapping ( Encoding . Default . GetBytes ( mosquittoConfig . ToString ( ) ) , "/mosquitto/config/mosquitto.conf" ) ;
109+ return new MosquittoContainer ( mosquittoBuilder . DockerResourceConfiguration ) ;
110+ }
111+
112+ /// <inheritdoc />
113+ protected override MosquittoBuilder Init ( )
114+ {
115+ return base . Init ( )
116+ . WithImage ( MosquittoImage )
117+ . WithPortBinding ( MqttPort , true )
118+ . WithPortBinding ( MqttWsPort , true )
119+ . WithWaitStrategy ( Wait . ForUnixContainer ( ) . UntilMessageIsLogged ( "mosquitto.*running" ) ) ;
120+ }
121+
122+ /// <inheritdoc />
123+ protected override MosquittoBuilder Clone ( IResourceConfiguration < CreateContainerParameters > resourceConfiguration )
124+ {
125+ return Merge ( DockerResourceConfiguration , new MosquittoConfiguration ( resourceConfiguration ) ) ;
126+ }
127+
128+ /// <inheritdoc />
129+ protected override MosquittoBuilder Clone ( IContainerConfiguration resourceConfiguration )
130+ {
131+ return Merge ( DockerResourceConfiguration , new MosquittoConfiguration ( resourceConfiguration ) ) ;
132+ }
133+
134+ /// <inheritdoc />
135+ protected override MosquittoBuilder Merge ( MosquittoConfiguration oldValue , MosquittoConfiguration newValue )
136+ {
137+ return new MosquittoBuilder ( new MosquittoConfiguration ( oldValue , newValue ) ) ;
138+ }
139+ }
0 commit comments