21
21
import java .util .stream .Collectors ;
22
22
23
23
/**
24
- * <p>Container for LocalStack, 'A fully functional local AWS cloud stack'.</p>
25
- * <p>{@link LocalStackContainer#withServices(Service...)} should be used to select which services
26
- * are to be launched. See {@link Service} for available choices.
24
+ * Testcontainers implementation for LocalStack.
27
25
*/
28
26
@ Slf4j
29
27
public class LocalStackContainer extends GenericContainer <LocalStackContainer > {
30
28
31
29
static final int PORT = 4566 ;
32
30
31
+ @ Deprecated
33
32
private static final String HOSTNAME_EXTERNAL_ENV_VAR = "HOSTNAME_EXTERNAL" ;
34
33
34
+ private static final String LOCALSTACK_HOST_ENV_VAR = "LOCALSTACK_HOST" ;
35
+
35
36
private final List <EnabledService > services = new ArrayList <>();
36
37
37
38
private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName .parse ("localstack/localstack" );
@@ -66,6 +67,8 @@ public class LocalStackContainer extends GenericContainer<LocalStackContainer> {
66
67
*/
67
68
private final boolean servicesEnvVarRequired ;
68
69
70
+ private final boolean isVersion2 ;
71
+
69
72
/**
70
73
* @deprecated use {@link LocalStackContainer(DockerImageName)} instead
71
74
*/
@@ -92,18 +95,31 @@ public LocalStackContainer(final DockerImageName dockerImageName) {
92
95
/**
93
96
* @param dockerImageName image name to use for Localstack
94
97
* @param useLegacyMode if true, each AWS service is exposed on a different port
98
+ * @deprecated use {@link LocalStackContainer(DockerImageName)} instead
95
99
*/
100
+ @ Deprecated
96
101
public LocalStackContainer (final DockerImageName dockerImageName , boolean useLegacyMode ) {
97
102
super (dockerImageName );
98
103
dockerImageName .assertCompatibleWith (DEFAULT_IMAGE_NAME );
99
104
100
105
this .legacyMode = useLegacyMode ;
101
- this .servicesEnvVarRequired = isServicesEnvVarRequired (dockerImageName .getVersionPart ());
106
+ String version = dockerImageName .getVersionPart ();
107
+ this .servicesEnvVarRequired = isServicesEnvVarRequired (version );
108
+ this .isVersion2 = isVersion2 (version );
102
109
103
110
withFileSystemBind (DockerClientFactory .instance ().getRemoteDockerUnixSocketPath (), "/var/run/docker.sock" );
104
111
waitingFor (Wait .forLogMessage (".*Ready\\ .\n " , 1 ));
105
112
}
106
113
114
+ private static boolean isVersion2 (String version ) {
115
+ if (version .equals ("latest" )) {
116
+ return true ;
117
+ }
118
+
119
+ ComparableVersion comparableVersion = new ComparableVersion (version );
120
+ return comparableVersion .isGreaterThanOrEqualTo ("2.0.0" );
121
+ }
122
+
107
123
private static boolean isServicesEnvVarRequired (String version ) {
108
124
if (version .equals ("latest" )) {
109
125
return false ;
@@ -141,7 +157,7 @@ private static boolean shouldRunInLegacyMode(String version) {
141
157
protected void configure () {
142
158
super .configure ();
143
159
144
- if (servicesEnvVarRequired ) {
160
+ if (this . servicesEnvVarRequired ) {
145
161
Preconditions .check ("services list must not be empty" , !services .isEmpty ());
146
162
}
147
163
@@ -152,26 +168,30 @@ protected void configure() {
152
168
}
153
169
}
154
170
171
+ if (this .isVersion2 ) {
172
+ resolveHostname (LOCALSTACK_HOST_ENV_VAR );
173
+ } else {
174
+ resolveHostname (HOSTNAME_EXTERNAL_ENV_VAR );
175
+ }
176
+
177
+ exposePorts ();
178
+ }
179
+
180
+ private void resolveHostname (String envVar ) {
155
181
String hostnameExternalReason ;
156
- if (getEnvMap ().containsKey (HOSTNAME_EXTERNAL_ENV_VAR )) {
182
+ if (getEnvMap ().containsKey (envVar )) {
157
183
// do nothing
158
184
hostnameExternalReason = "explicitly as environment variable" ;
159
185
} else if (getNetwork () != null && getNetworkAliases () != null && getNetworkAliases ().size () >= 1 ) {
160
- withEnv (HOSTNAME_EXTERNAL_ENV_VAR , getNetworkAliases ().get (getNetworkAliases ().size () - 1 )); // use the last network alias set
186
+ withEnv (envVar , getNetworkAliases ().get (getNetworkAliases ().size () - 1 )); // use the last network alias set
161
187
hostnameExternalReason = "to match last network alias on container with non-default network" ;
162
188
} else {
163
- withEnv (HOSTNAME_EXTERNAL_ENV_VAR , getHost ());
189
+ withEnv (envVar , getHost ());
164
190
hostnameExternalReason = "to match host-routable address for container" ;
165
191
}
166
- logger ()
167
- .info (
168
- "{} environment variable set to {} ({})" ,
169
- HOSTNAME_EXTERNAL_ENV_VAR ,
170
- getEnvMap ().get (HOSTNAME_EXTERNAL_ENV_VAR ),
171
- hostnameExternalReason
172
- );
173
192
174
- exposePorts ();
193
+ logger ()
194
+ .info ("{} environment variable set to {} ({})" , envVar , getEnvMap ().get (envVar ), hostnameExternalReason );
175
195
}
176
196
177
197
private void exposePorts () {
0 commit comments