Use parameters passed by UI to customise docker-compose
Docker compose will be dynamically created based on the paramenters passed from the UI.
The possible configurations are:
- aggregation time
- data time frame
- project prefix
- credentials
Feature: Issue 9907
Change-Id: I4366b4d054a51c3e5fff9274c21580ce6a0e10f3
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticDashboardSetup.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticDashboardSetup.scala
index fc53340..10a0f52 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticDashboardSetup.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticDashboardSetup.scala
@@ -17,6 +17,8 @@
import java.nio.charset.StandardCharsets
import java.nio.file.{Files, Path}
+import com.googlesource.gerrit.plugins.analytics.wizard.model.ETLConfig
+
trait ConfigWriter {
def write(outputPath: Path, out: String)
}
@@ -27,8 +29,10 @@
}
}
-case class AnalyticDashboardSetup(name: String, dockerComposeYamlPath: Path, gerritLocalUrl: URL)(
- implicit val writer: ConfigWriter) {
+case class AnalyticDashboardSetup(name: String,
+ dockerComposeYamlPath: Path,
+ gerritLocalUrl: URL,
+ etlConfig: ETLConfig)(implicit val writer: ConfigWriter) {
// Docker doesn't like container names with '/', hence the replace with '-'
// Furthermore timestamp has been added to avoid conflicts among container names, i.e.:
@@ -36,6 +40,17 @@
// would be potentially in conflict with another 'foo-bar' project's one
private val sanitisedName =
s"${name.replace("/", "-")}-${System.currentTimeMillis}"
+ private def analyticsArgs: String = {
+ val args = List(
+ Since(etlConfig.since.map(_.toString)),
+ Until(etlConfig.until.map(_.toString)),
+ ProjectPrefix(etlConfig.projectPrefix),
+ Aggregate(Some(etlConfig.aggregate.entryName)),
+ Password(etlConfig.password),
+ Username(etlConfig.username)
+ ).filter(_.value.isDefined) mkString " "
+ s"$args --writeNotProcessedEventsTo file:///tmp/failed-events -e gerrit/analytics"
+ }
private val dockerComposeTemplate = {
s"""
|version: '3'
@@ -48,7 +63,7 @@
| environment:
| - ES_HOST=elasticsearch
| - GERRIT_URL=${gerritLocalUrl.getProtocol}://gerrit:${gerritLocalUrl.getPort}
- | - ANALYTICS_ARGS=--since 2000-06-01 --aggregate email_hour --writeNotProcessedEventsTo file:///tmp/failed-events -e gerrit/analytics
+ | - ANALYTICS_ARGS=$analyticsArgs
| networks:
| - ek
| links:
@@ -102,3 +117,28 @@
object AnalyticDashboardSetup {
implicit val writer = new ConfigWriterImpl()
}
+
+sealed trait AnalyticsOption {
+ val name: String
+ val value: Option[String]
+
+ override def toString: String = s"$name ${value.getOrElse("")}"
+}
+case class Since(value: Option[String]) extends AnalyticsOption {
+ val name = "--since"
+}
+case class Until(value: Option[String]) extends AnalyticsOption {
+ val name = "--until"
+}
+case class ProjectPrefix(value: Option[String]) extends AnalyticsOption {
+ val name = "--prefix"
+}
+case class Aggregate(value: Option[String]) extends AnalyticsOption {
+ val name = "--aggregate"
+}
+case class Password(value: Option[String]) extends AnalyticsOption {
+ val name = "--password"
+}
+case class Username(value: Option[String]) extends AnalyticsOption {
+ val name = "--username"
+}
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticsWizardActions.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticsWizardActions.scala
index 835fd77..a364bb3 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticsWizardActions.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticsWizardActions.scala
@@ -58,7 +58,8 @@
AnalyticDashboardSetup(
input.dashboardName,
dataPath.resolve(s"docker-compose.${input.dashboardName}.yaml"),
- gerritLocalUrl
+ gerritLocalUrl,
+ etlConfig
).createDashboardSetupFile()
Response.created(s"Dashboard configuration created for $encodedName!")
case Failure(exception) =>
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/model/ETLConfig.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/model/ETLConfig.scala
index 2766d45..78d2289 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/model/ETLConfig.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/model/ETLConfig.scala
@@ -17,6 +17,7 @@
import java.time.LocalDate
import java.time.format.DateTimeFormatter
+import enumeratum.EnumEntry.Snakecase
import enumeratum._
import scala.util.{Failure, Success, Try}
@@ -31,7 +32,7 @@
username: Option[String],
password: Option[String])
-sealed trait AggregationType extends EnumEntry
+sealed trait AggregationType extends EnumEntry with Snakecase
object AggregationType extends Enum[AggregationType] {
val values = findValues
@@ -92,7 +93,7 @@
private def validateAggregate(
value: String): Either[AggregateValidationError, AggregationType] = {
val maybeAggregate =
- AggregationType.withNameInsensitiveOption(Option(value).getOrElse("email").replace("_", ""))
+ AggregationType.withNameInsensitiveOption(Option(value).getOrElse("email"))
Either.cond(maybeAggregate.isDefined, maybeAggregate.get, AggregateValidationError(value))
}
}
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticDashboardSetupSpec.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticDashboardSetupSpec.scala
index 0f91888..74daff4 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticDashboardSetupSpec.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticDashboardSetupSpec.scala
@@ -3,7 +3,11 @@
import java.io.File
import java.net.URL
import java.nio.file.Path
+import java.time.LocalDate
+import java.time.format.DateTimeFormatter
+import com.googlesource.gerrit.plugins.analytics.wizard.model.AggregationType.{Email, EmailYear}
+import com.googlesource.gerrit.plugins.analytics.wizard.model.ETLConfig
import org.scalatest.{FlatSpec, Matchers}
class AnalyticDashboardSetupSpec extends FlatSpec with Matchers {
@@ -19,10 +23,56 @@
implicit val writer = new MockWriter()
val composeYamlFile = File.createTempFile(getClass.getName, ".yaml").toPath
- val ads = AnalyticDashboardSetup("aProject",
- composeYamlFile,
- new URL("http://gerrit_local_ip_address:8080"))
+ val ads =
+ AnalyticDashboardSetup("aProject",
+ composeYamlFile,
+ new URL("http://gerrit_local_ip_address:8080"),
+ ETLConfig(Email, None, None, None, None, None, None, None, None))
ads.createDashboardSetupFile()
gotFilename shouldBe Some(composeYamlFile)
}
+
+ it should "create a config file with correct analytics args" in {
+ var gotFilename: Option[Path] = None
+ var dockerCompose: String = ""
+ class MockWriter extends ConfigWriter {
+ override def write(filename: Path, out: String): Unit = {
+ gotFilename = Some(filename)
+ dockerCompose = out
+ }
+ }
+ implicit val writer = new MockWriter()
+
+ val dateSince = "2018-10-10"
+ val localDateSince = LocalDate.parse(dateSince, DateTimeFormatter.ofPattern("yyyy-MM-dd"))
+ val dateUntil = "2018-10-20"
+ val localDateUntil = LocalDate.parse(dateUntil, DateTimeFormatter.ofPattern("yyyy-MM-dd"))
+ val prefix = "myProjectPrefix"
+ val password = "myPassword"
+ val username = "myUsername"
+ val composeYamlFile = File.createTempFile(getClass.getName, ".yaml").toPath
+ val ads =
+ AnalyticDashboardSetup(
+ "aProject",
+ composeYamlFile,
+ new URL("http://gerrit_local_ip_address:8080"),
+ ETLConfig(EmailYear,
+ Some(prefix),
+ Some(localDateSince),
+ Some(localDateUntil),
+ None,
+ None,
+ None,
+ Some(username),
+ Some(password))
+ )
+ ads.createDashboardSetupFile()
+ gotFilename shouldBe Some(composeYamlFile)
+ dockerCompose should include("--aggregate email_year")
+ dockerCompose should include(s"--until $dateUntil")
+ dockerCompose should include(s"--since $dateSince")
+ dockerCompose should include(s"--prefix $prefix")
+ dockerCompose should include(s"--password $password")
+ dockerCompose should include(s"--username $username")
+ }
}