Skip to content

Commit fa7a3d4

Browse files
committed
feat: add support for DockerController auto closing
1 parent 9d770a7 commit fa7a3d4

File tree

17 files changed

+116
-42
lines changed

17 files changed

+116
-42
lines changed

docker-controller-scala-core/src/main/scala/com/github/j5ik2o/dockerController/DockerComposeController.scala

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,17 @@ import scala.concurrent.duration.{ DurationInt, FiniteDuration }
1313

1414
object DockerComposeController {
1515

16-
def apply(dockerClient: DockerClient, outputFrameInterval: FiniteDuration = 500.millis)(
16+
def apply(
17+
dockerClient: DockerClient,
18+
isDockerClientAutoClose: Boolean = false,
19+
outputFrameInterval: FiniteDuration = 500.millis
20+
)(
1721
dockerComposeWorkingDir: File,
1822
ymlResourceName: String,
1923
environmentNames: Seq[String],
2024
context: Map[String, AnyRef]
2125
): DockerController =
22-
new DockerComposeController(dockerClient, outputFrameInterval)(
26+
new DockerComposeController(dockerClient, isDockerClientAutoClose, outputFrameInterval)(
2327
dockerComposeWorkingDir,
2428
ymlResourceName,
2529
environmentNames,
@@ -29,13 +33,17 @@ object DockerComposeController {
2933

3034
private[dockerController] class DockerComposeController(
3135
dockerClient: DockerClient,
36+
isDockerClientAutoClose: Boolean,
3237
outputFrameInterval: FiniteDuration = 500.millis
3338
)(
3439
val dockerComposeWorkingDir: File,
3540
val ymlResourceName: String,
3641
val environmentResourceNames: Seq[String],
3742
val context: Map[String, AnyRef]
38-
) extends DockerControllerImpl(dockerClient, outputFrameInterval)("docker/compose", Some("1.24.1")) {
43+
) extends DockerControllerImpl(dockerClient, isDockerClientAutoClose, outputFrameInterval)(
44+
"docker/compose",
45+
Some("1.24.1")
46+
) {
3947

4048
override protected def newCreateContainerCmd(): CreateContainerCmd = {
4149
val id = Base58.randomString(16)

docker-controller-scala-core/src/main/scala/com/github/j5ik2o/dockerController/DockerController.scala

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ trait DockerController {
3030

3131
def dockerClient: DockerClient
3232

33+
def isDockerClientAutoClose: Boolean
34+
35+
def dispose(): Unit
3336
def imageName: String
3437
def tag: Option[String]
3538

@@ -63,14 +66,20 @@ trait DockerController {
6366

6467
object DockerController {
6568

66-
def apply(dockerClient: DockerClient, outputFrameInterval: FiniteDuration = 500.millis)(
69+
def apply(
70+
dockerClient: DockerClient,
71+
isDockerClientAutoClose: Boolean = false,
72+
outputFrameInterval: FiniteDuration = 500.millis
73+
)(
6774
imageName: String,
6875
tag: Option[String] = None
69-
): DockerController = new DockerControllerImpl(dockerClient, outputFrameInterval)(imageName, tag)
76+
): DockerController =
77+
new DockerControllerImpl(dockerClient, isDockerClientAutoClose, outputFrameInterval)(imageName, tag)
7078
}
7179

7280
private[dockerController] class DockerControllerImpl(
7381
val dockerClient: DockerClient,
82+
val isDockerClientAutoClose: Boolean = false,
7483
outputFrameInterval: FiniteDuration = 500.millis
7584
)(
7685
val imageName: String,
@@ -152,21 +161,27 @@ private[dockerController] class DockerControllerImpl(
152161
dockerClient.stopContainerCmd(containerId.get)
153162
}
154163

155-
override def createContainer(f: CreateContainerCmd => CreateContainerCmd): CreateContainerResponse = {
164+
override def createContainer(f: CreateContainerCmd => CreateContainerCmd): CreateContainerResponse = synchronized {
156165
logger.debug("createContainer --- start")
157166
val configureFunction: CreateContainerCmd => CreateContainerCmd =
158167
cmdConfigures.map(_.createContainerCmdConfigure).getOrElse(identity)
159168
val result = f(configureFunction(newCreateContainerCmd())).exec()
160169
_containerId = Some(result.getId)
170+
sys.addShutdownHook {
171+
logger.debug("shutdownHook: start")
172+
dispose()
173+
logger.debug("shutdownHook: finish")
174+
}
161175
logger.debug("createContainer --- finish")
162176
result
163177
}
164178

165-
override def removeContainer(f: RemoveContainerCmd => RemoveContainerCmd): Unit = {
179+
override def removeContainer(f: RemoveContainerCmd => RemoveContainerCmd): Unit = synchronized {
166180
logger.debug("removeContainer --- start")
167181
val configureFunction: RemoveContainerCmd => RemoveContainerCmd =
168182
cmdConfigures.map(_.removeContainerCmdConfigure).getOrElse(identity)
169183
f(configureFunction(newRemoveContainerCmd())).exec()
184+
_containerId = None
170185
logger.debug("removeContainer --- finish")
171186
}
172187

@@ -326,4 +341,15 @@ private[dockerController] class DockerControllerImpl(
326341
override def removeNetwork(id: String, f: RemoveNetworkCmd => RemoveNetworkCmd): Unit = {
327342
f(dockerClient.removeNetworkCmd(id)).exec()
328343
}
344+
345+
override def dispose(): Unit = synchronized {
346+
logger.debug("dispose: start")
347+
if (containerId.isDefined) {
348+
removeContainer()
349+
if (isDockerClientAutoClose)
350+
dockerClient.close()
351+
}
352+
logger.debug("dispose: finish")
353+
}
354+
329355
}

docker-controller-scala-core/src/test/scala/com/github/j5ik2o/dockerController/DockerComposeController2Spec.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class DockerComposeController2Spec extends AnyFreeSpec with BeforeAndAfter with
6060
override protected def beforeAll(): Unit = {
6161
val buildDir: File = ResourceUtil.getBuildDir(getClass)
6262
val dockerComposeWorkingDir: File = new File(buildDir, "docker-compose")
63-
dockerController = DockerComposeController(dockerClient)(
63+
dockerController = DockerComposeController(dockerClient, isDockerClientAutoClose = true)(
6464
dockerComposeWorkingDir,
6565
"docker-compose-3.yml.ftl",
6666
Seq("settings.env.ftl"),
@@ -71,8 +71,7 @@ class DockerComposeController2Spec extends AnyFreeSpec with BeforeAndAfter with
7171
}
7272

7373
override protected def afterAll(): Unit = {
74-
dockerController.removeContainer()
75-
dockerClient.close()
74+
dockerController.dispose()
7675
}
7776

7877
before {

docker-controller-scala-core/src/test/scala/com/github/j5ik2o/dockerController/DockerComposeControllerSpec.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class DockerComposeControllerSpec extends AnyFreeSpec with BeforeAndAfter with B
5959
override protected def beforeAll(): Unit = {
6060
val buildDir: File = ResourceUtil.getBuildDir(getClass)
6161
val dockerComposeWorkingDir: File = new File(buildDir, "docker-compose")
62-
dockerController = DockerComposeController(dockerClient)(
62+
dockerController = DockerComposeController(dockerClient, isDockerClientAutoClose = true)(
6363
dockerComposeWorkingDir,
6464
"docker-compose-2.yml.ftl",
6565
Seq.empty,
@@ -70,8 +70,7 @@ class DockerComposeControllerSpec extends AnyFreeSpec with BeforeAndAfter with B
7070
}
7171

7272
override protected def afterAll(): Unit = {
73-
dockerController.removeContainer()
74-
dockerClient.close()
73+
dockerController.dispose()
7574
}
7675

7776
before {

docker-controller-scala-core/src/test/scala/com/github/j5ik2o/dockerController/DockerControllerSpec.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class DockerControllerSpec extends AnyFreeSpec with BeforeAndAfter with BeforeAn
4141
var dockerController: DockerController = _
4242

4343
override protected def beforeAll(): Unit = {
44-
dockerController = DockerController(dockerClient)(
44+
dockerController = DockerController(dockerClient, isDockerClientAutoClose = true)(
4545
imageName = "nginx",
4646
tag = Some("latest")
4747
).configureCreateContainerCmd { cmd =>
@@ -57,8 +57,7 @@ class DockerControllerSpec extends AnyFreeSpec with BeforeAndAfter with BeforeAn
5757
}
5858

5959
override protected def afterAll(): Unit = {
60-
dockerController.removeContainer()
61-
dockerClient.close()
60+
dockerController.dispose()
6261
}
6362

6463
before {

docker-controller-scala-dynamodb-local/src/main/scala/com/github/j5ik2o/dockerController/dynamodbLocal/DynamoDBLocalController.scala

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,34 @@ object DynamoDBLocalController {
1818

1919
def apply(
2020
dockerClient: DockerClient,
21+
isDockerClientAutoClose: Boolean = false,
2122
outputFrameInterval: FiniteDuration = 500.millis,
2223
imageName: String = DefaultImageName,
2324
imageTag: Option[String] = DefaultImageTag,
2425
envVars: Map[String, String] = Map.empty
2526
)(
2627
hostPort: Int
2728
): DynamoDBLocalController =
28-
new DynamoDBLocalController(dockerClient, outputFrameInterval, imageName, imageTag, envVars)(hostPort)
29+
new DynamoDBLocalController(
30+
dockerClient,
31+
isDockerClientAutoClose,
32+
outputFrameInterval,
33+
imageName,
34+
imageTag,
35+
envVars
36+
)(hostPort)
2937
}
3038

3139
class DynamoDBLocalController(
3240
dockerClient: DockerClient,
41+
isDockerClientAutoClose: Boolean = false,
3342
outputFrameInterval: FiniteDuration = 500.millis,
3443
imageName: String = DefaultImageName,
3544
imageTag: Option[String] = DefaultImageTag,
3645
envVars: Map[String, String] = Map.empty
3746
)(
3847
hostPort: Int
39-
) extends DockerControllerImpl(dockerClient, outputFrameInterval)(imageName, imageTag) {
48+
) extends DockerControllerImpl(dockerClient, isDockerClientAutoClose, outputFrameInterval)(imageName, imageTag) {
4049

4150
override protected def newCreateContainerCmd(): CreateContainerCmd = {
4251
val containerPort = ExposedPort.tcp(DefaultContainerPort)

docker-controller-scala-elasticmq/src/main/scala/com/github/j5ik2o/dockerController/elasticmq/ElasticMQController.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,25 +21,27 @@ object ElasticMQController {
2121

2222
def apply(
2323
dockerClient: DockerClient,
24+
isDockerClientAutoClose: Boolean = false,
2425
outputFrameInterval: FiniteDuration = 500.millis,
2526
imageName: String = DefaultImageName,
2627
imageTag: Option[String] = DefaultImageTag,
2728
envVars: Map[String, String] = Map.empty
2829
)(dockerHost: String, hostPorts: Seq[Int]): ElasticMQController =
29-
new ElasticMQController(dockerClient, outputFrameInterval, imageName, imageTag, envVars)(
30+
new ElasticMQController(dockerClient, isDockerClientAutoClose, outputFrameInterval, imageName, imageTag, envVars)(
3031
dockerHost,
3132
hostPorts
3233
)
3334
}
3435

3536
class ElasticMQController(
3637
dockerClient: DockerClient,
38+
isDockerClientAutoClose: Boolean = false,
3739
outputFrameInterval: FiniteDuration = 500.millis,
3840
imageName: String = DefaultImageName,
3941
imageTag: Option[String] = DefaultImageTag,
4042
envVars: Map[String, String] = Map.empty
4143
)(dockerHost: String, hostPorts: Seq[Int])
42-
extends DockerControllerImpl(dockerClient, outputFrameInterval)(imageName, imageTag) {
44+
extends DockerControllerImpl(dockerClient, isDockerClientAutoClose, outputFrameInterval)(imageName, imageTag) {
4345

4446
private val environmentVariables = Map(
4547
"JAVA_OPTS" -> "-Dconfig.override_with_env_vars=true",

docker-controller-scala-elasticsearch/src/main/scala/com/github/j5ik2o/dockerController/elasticsearch/ElasticsearchController.scala

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ object ElasticsearchController {
1616

1717
def apply(
1818
dockerClient: DockerClient,
19+
isDockerClientAutoClose: Boolean = false,
1920
outputFrameInterval: FiniteDuration = 500.millis,
2021
imageName: String = DefaultImageName,
2122
imageTag: Option[String] = DefaultImageTag,
@@ -24,19 +25,27 @@ object ElasticsearchController {
2425
hostPort1: Int,
2526
hostPort2: Int
2627
): ElasticsearchController =
27-
new ElasticsearchController(dockerClient, outputFrameInterval, imageName, imageTag, envVars)(hostPort1, hostPort2)
28+
new ElasticsearchController(
29+
dockerClient,
30+
isDockerClientAutoClose,
31+
outputFrameInterval,
32+
imageName,
33+
imageTag,
34+
envVars
35+
)(hostPort1, hostPort2)
2836
}
2937

3038
class ElasticsearchController(
3139
dockerClient: DockerClient,
40+
isDockerClientAutoClose: Boolean = false,
3241
outputFrameInterval: FiniteDuration = 500.millis,
3342
imageName: String = DefaultImageName,
3443
imageTag: Option[String] = DefaultImageTag,
3544
envVars: Map[String, String] = Map.empty
3645
)(
3746
hostPort1: Int,
3847
hostPort2: Int
39-
) extends DockerControllerImpl(dockerClient, outputFrameInterval)(imageName, imageTag) {
48+
) extends DockerControllerImpl(dockerClient, isDockerClientAutoClose, outputFrameInterval)(imageName, imageTag) {
4049

4150
private val environmentVariables = Map(
4251
"discovery.type" -> "single-node"

docker-controller-scala-kafka/src/main/scala/com/github/j5ik2o/dockerController/kafka/KafkaController.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ object KafkaController {
2020

2121
def apply(
2222
dockerClient: DockerClient,
23+
isDockerClientAutoClose: Boolean = false,
2324
outputFrameInterval: FiniteDuration = 500.millis,
2425
imageName: String = DefaultImageName,
2526
imageTag: Option[String] = DefaultImageTag,
@@ -29,7 +30,7 @@ object KafkaController {
2930
kafkaExternalHostPort: Int,
3031
createTopics: Seq[String] = Seq.empty
3132
): KafkaController =
32-
new KafkaController(dockerClient, outputFrameInterval, imageName, imageTag, envVars)(
33+
new KafkaController(dockerClient, isDockerClientAutoClose, outputFrameInterval, imageName, imageTag, envVars)(
3334
kafkaExternalHostName,
3435
kafkaExternalHostPort,
3536
createTopics
@@ -38,6 +39,7 @@ object KafkaController {
3839

3940
class KafkaController(
4041
dockerClient: DockerClient,
42+
isDockerClientAutoClose: Boolean = false,
4143
outputFrameInterval: FiniteDuration = 500.millis,
4244
imageName: String = DefaultImageName,
4345
imageTag: Option[String] = DefaultImageTag,
@@ -46,7 +48,7 @@ class KafkaController(
4648
kafkaExternalHostName: String,
4749
kafkaExternalHostPort: Int,
4850
createTopics: Seq[String]
49-
) extends DockerControllerImpl(dockerClient, outputFrameInterval)(imageName, imageTag) {
51+
) extends DockerControllerImpl(dockerClient, isDockerClientAutoClose, outputFrameInterval)(imageName, imageTag) {
5052
lazy val networkId: String =
5153
dockerClient.createNetworkCmd().withName("kafka-" + UUID.randomUUID().toString).exec().getId
5254

docker-controller-scala-localstack/src/main/scala/com/github/j5ik2o/dockerController/localstack/LocalStackController.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ object LocalStackController {
1515

1616
def apply(
1717
dockerClient: DockerClient,
18+
isDockerClientAutoClose: Boolean = false,
1819
outputFrameInterval: FiniteDuration = 500.millis,
1920
imageName: String = DefaultImageName,
2021
imageTag: Option[String] = DefaultImageTag,
@@ -27,7 +28,7 @@ object LocalStackController {
2728
hostNameExternal: Option[String] = None,
2829
defaultRegion: Option[String] = None
2930
): LocalStackController =
30-
new LocalStackController(dockerClient, outputFrameInterval, imageName, imageTag, envVars)(
31+
new LocalStackController(dockerClient, isDockerClientAutoClose, outputFrameInterval, imageName, imageTag, envVars)(
3132
services,
3233
edgeHostPort,
3334
hostPorts,
@@ -95,6 +96,7 @@ object Service {
9596

9697
class LocalStackController(
9798
dockerClient: DockerClient,
99+
isDockerClientAutoClose: Boolean = false,
98100
outputFrameInterval: FiniteDuration = 500.millis,
99101
imageName: String = DefaultImageName,
100102
imageTag: Option[String] = DefaultImageTag,
@@ -107,7 +109,7 @@ class LocalStackController(
107109
hostName: Option[String] = None,
108110
hostNameExternal: Option[String] = None,
109111
defaultRegion: Option[String] = None
110-
) extends DockerControllerImpl(dockerClient, outputFrameInterval)(imageName, imageTag) {
112+
) extends DockerControllerImpl(dockerClient, isDockerClientAutoClose, outputFrameInterval)(imageName, imageTag) {
111113

112114
private val environmentVariables: Map[String, String] = Map(
113115
"EAGER_SERVICE_LOADING" -> "1",

docker-controller-scala-memcached/src/main/scala/com/github/j5ik2o/dockerController/memcached/MemcachedController.scala

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,32 @@ object MemcachedController {
1616

1717
def apply(
1818
dockerClient: DockerClient,
19+
isDockerClientAutoClose: Boolean = false,
1920
outputFrameInterval: FiniteDuration = 500.millis,
2021
imageName: String = DefaultImageName,
2122
imageTag: Option[String] = DefaultImageTag,
2223
envVars: Map[String, String] = Map.empty
2324
)(
2425
hostPort: Int,
2526
prometheusEnabled: Boolean = false
26-
): MemcachedController = new MemcachedController(dockerClient, outputFrameInterval, imageName, imageTag, envVars)(
27-
hostPort,
28-
prometheusEnabled
29-
)
27+
): MemcachedController =
28+
new MemcachedController(dockerClient, isDockerClientAutoClose, outputFrameInterval, imageName, imageTag, envVars)(
29+
hostPort,
30+
prometheusEnabled
31+
)
3032
}
3133

3234
class MemcachedController(
3335
dockerClient: DockerClient,
36+
isDockerClientAutoClose: Boolean = false,
3437
outputFrameInterval: FiniteDuration = 500.millis,
3538
imageName: String = DefaultImageName,
3639
imageTag: Option[String] = DefaultImageTag,
3740
envVars: Map[String, String] = Map.empty
3841
)(
3942
hostPort: Int,
4043
prometheusEnabled: Boolean = false
41-
) extends DockerControllerImpl(dockerClient, outputFrameInterval)(imageName, imageTag) {
44+
) extends DockerControllerImpl(dockerClient, isDockerClientAutoClose, outputFrameInterval)(imageName, imageTag) {
4245

4346
private val environmentVariables = Map(
4447
"MEMCACHED_PROMETHEUS_ENABLED" -> prometheusEnabled.toString

0 commit comments

Comments
 (0)