Skip to content

Commit 2a50fd8

Browse files
committed
feat: add support for postgresql
1 parent a5192fa commit 2a50fd8

File tree

3 files changed

+169
-0
lines changed

3 files changed

+169
-0
lines changed

build.sbt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,17 @@ val `docker-controller-scala-mysql` = (project in file("docker-controller-scala-
162162
)
163163
).dependsOn(`docker-controller-scala-core`, `docker-controller-scala-scalatest` % Test)
164164

165+
val `docker-controller-scala-postgresql` = (project in file("docker-controller-scala-postgresql"))
166+
.settings(baseSettings)
167+
.settings(
168+
name := "docker-controller-scala-postgresql",
169+
libraryDependencies ++= Seq(
170+
scalatest.scalatest % Test,
171+
logback.classic % Test,
172+
"org.postgresql" % "postgresql" % "42.2.22" % Test
173+
)
174+
).dependsOn(`docker-controller-scala-core`, `docker-controller-scala-scalatest` % Test)
175+
165176
val `docker-controller-scala-redis` = (project in file("docker-controller-scala-redis"))
166177
.settings(baseSettings)
167178
.settings(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package com.github.j5ik2o.dockerController.postgresql
2+
3+
import com.github.dockerjava.api.DockerClient
4+
import com.github.dockerjava.api.command.CreateContainerCmd
5+
import com.github.dockerjava.api.model.HostConfig.newHostConfig
6+
import com.github.dockerjava.api.model.{ ExposedPort, Ports }
7+
import com.github.j5ik2o.dockerController.DockerControllerImpl
8+
import com.github.j5ik2o.dockerController.postgresql.PostgreSQLController.{
9+
DefaultContainerPort,
10+
DefaultImageName,
11+
DefaultImageTag
12+
}
13+
14+
import scala.concurrent.duration._
15+
16+
object PostgreSQLController {
17+
final val DefaultImageName: String = "postgres"
18+
final val DefaultImageTag: Option[String] = Some("13")
19+
final val DefaultContainerPort: Int = 5432
20+
21+
def apply(
22+
dockerClient: DockerClient,
23+
outputFrameInterval: FiniteDuration = 500.millis,
24+
imageName: String = DefaultImageName,
25+
imageTag: Option[String] = DefaultImageTag,
26+
envVars: Map[String, String] = Map.empty
27+
)(
28+
hostPort: Int,
29+
userName: String,
30+
password: Option[String] = None,
31+
databaseName: Option[String] = None,
32+
initDbArgs: Option[String] = None,
33+
initDbWalDir: Option[String] = None,
34+
hostAuthMethod: Option[String] = None,
35+
pgData: Option[String] = None
36+
): PostgreSQLController =
37+
new PostgreSQLController(dockerClient, outputFrameInterval, imageName, imageTag, envVars)(
38+
hostPort,
39+
userName,
40+
password,
41+
databaseName,
42+
initDbArgs,
43+
initDbWalDir,
44+
hostAuthMethod,
45+
pgData
46+
)
47+
}
48+
49+
class PostgreSQLController(
50+
dockerClient: DockerClient,
51+
outputFrameInterval: FiniteDuration = 500.millis,
52+
imageName: String = DefaultImageName,
53+
imageTag: Option[String] = DefaultImageTag,
54+
envVars: Map[String, String] = Map.empty
55+
)(
56+
hostPort: Int,
57+
userName: String,
58+
password: Option[String] = None,
59+
databaseName: Option[String] = None,
60+
initDbArgs: Option[String] = None,
61+
initDbWalDir: Option[String] = None,
62+
hostAuthMethod: Option[String] = None,
63+
pgData: Option[String] = None
64+
) extends DockerControllerImpl(dockerClient, outputFrameInterval)(imageName, imageTag) {
65+
66+
private val environmentVariables: Map[String, String] = {
67+
envVars ++
68+
Map[String, String](
69+
"POSTGRES_USER" -> userName
70+
) ++
71+
password.map(s => Map("POSTGRES_PASSWORD" -> s)).getOrElse(Map.empty) ++
72+
databaseName.map(s => Map("POSTGRES_DB" -> s)).getOrElse(Map.empty) ++
73+
initDbArgs.map(s => Map("POSTGRES_INITDB_ARGS" -> s)).getOrElse(Map.empty) ++
74+
initDbWalDir.map(s => Map("POSTGRES_INITDB_WALDIR" -> s)).getOrElse(Map.empty) ++
75+
hostAuthMethod.map(s => Map("POSTGRES_HOST_AUTH_METHOD" -> s)).getOrElse(Map.empty) ++
76+
pgData.map(s => Map("PGDATA" -> s)).getOrElse(Map.empty)
77+
}
78+
79+
override protected def newCreateContainerCmd(): CreateContainerCmd = {
80+
val containerPort = ExposedPort.tcp(DefaultContainerPort)
81+
val portBinding = new Ports()
82+
portBinding.bind(containerPort, Ports.Binding.bindPort(hostPort))
83+
super
84+
.newCreateContainerCmd()
85+
.withEnv(environmentVariables.map { case (k, v) => s"$k=$v" }.toArray: _*)
86+
.withExposedPorts(containerPort)
87+
.withHostConfig(newHostConfig().withPortBindings(portBinding))
88+
}
89+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package com.github.j5ik2o.dockerController.postgresql
2+
3+
import com.github.j5ik2o.dockerController.{
4+
DockerController,
5+
DockerControllerSpecSupport,
6+
RandomPortUtil,
7+
WaitPredicates
8+
}
9+
import org.scalatest.freespec.AnyFreeSpec
10+
11+
import java.sql.{ Connection, DriverManager, ResultSet, Statement }
12+
import scala.concurrent.duration._
13+
import scala.util.control.NonFatal
14+
15+
class PostgreSQLControllerSpec extends AnyFreeSpec with DockerControllerSpecSupport {
16+
val testTimeFactor: Int = sys.env.getOrElse("TEST_TIME_FACTOR", "1").toInt
17+
logger.debug(s"testTimeFactor = $testTimeFactor")
18+
19+
val hostPort: Int = RandomPortUtil.temporaryServerPort()
20+
val rootUserName: String = "postgres"
21+
val rootPassword: Option[String] = Some("test")
22+
23+
val controller: PostgreSQLController = PostgreSQLController(dockerClient)(hostPort, rootUserName, rootPassword)
24+
override protected val dockerControllers: Vector[DockerController] = Vector(controller)
25+
26+
override protected val waitPredicatesSettings: Map[DockerController, WaitPredicateSetting] =
27+
Map(
28+
controller -> WaitPredicateSetting(
29+
Duration.Inf,
30+
WaitPredicates.forListeningHostTcpPort(
31+
dockerHost,
32+
hostPort,
33+
(1 * testTimeFactor).seconds,
34+
Some((5 * testTimeFactor).seconds)
35+
)
36+
)
37+
)
38+
39+
"MySQLController" - {
40+
"run" in {
41+
var conn: Connection = null
42+
var stmt: Statement = null
43+
var resultSet: ResultSet = null
44+
try {
45+
Class.forName("org.postgresql.Driver")
46+
conn = DriverManager.getConnection(
47+
s"jdbc:postgresql://$dockerHost:$hostPort/postgres",
48+
rootUserName,
49+
rootPassword.get
50+
)
51+
stmt = conn.createStatement
52+
resultSet = stmt.executeQuery("SELECT 1 FROM DUAL")
53+
while (resultSet.next())
54+
assert(resultSet.getInt(1) == 1)
55+
} catch {
56+
case NonFatal(ex) =>
57+
ex.printStackTrace()
58+
fail("occurred error", ex)
59+
} finally {
60+
if (resultSet != null)
61+
resultSet.close()
62+
if (stmt != null)
63+
stmt.close()
64+
if (conn != null)
65+
conn.close()
66+
}
67+
}
68+
}
69+
}

0 commit comments

Comments
 (0)