Automatically setup an analytics dashboard
This plugin allows to add a step in the github gerrit workflow configuration
to automatically setup an analytics dashboard.
At the moment it is creating a customised docker-compose file that can
be used to spin up the resuorces needed for the dashboard.
Change-Id: If77502e0ff3b28355b87eed2e7fb0b65dbaf1eda
diff --git a/.gitignore b/.gitignore
index 9c07d4a..b4790c7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,9 @@
*.class
*.log
+/bin/
+.project
+.classpath
+.settings/
+.idea
+target
+.DS_Store
diff --git a/build.sbt b/build.sbt
new file mode 100644
index 0000000..7b9e7ea
--- /dev/null
+++ b/build.sbt
@@ -0,0 +1,31 @@
+enablePlugins(GitVersioning)
+
+val gerritApiVersion = "2.15.1"
+val pluginName = "analytics-wizard"
+
+git.useGitDescribe := true
+
+lazy val root = (project in file("."))
+ .settings(
+ name := pluginName,
+
+ scalaVersion := "2.12.5",
+
+ libraryDependencies ++= Seq(
+ "com.google.inject" % "guice" % "3.0" % Provided,
+ "com.google.gerrit" % "gerrit-plugin-api" % gerritApiVersion % Provided withSources(),
+ "com.google.code.gson" % "gson" % "2.7" % Provided,
+
+ "org.scalatest" %% "scalatest" % "3.0.4" % Test,
+ "net.codingwell" %% "scala-guice" % "4.1.0" % Test),
+
+ assemblyJarName in assembly := s"$pluginName.jar",
+
+ packageOptions in(Compile, packageBin) += Package.ManifestAttributes(
+ ("Gerrit-ApiType", "plugin"),
+ ("Gerrit-PluginName", pluginName),
+ ("Gerrit-Module", "com.googlesource.gerrit.plugins.analytics.wizard.Module"),
+ ("Implementation-Title", "Analytics plugin wizard")
+ )
+ )
+
diff --git a/project/build.properties b/project/build.properties
new file mode 100644
index 0000000..9abea12
--- /dev/null
+++ b/project/build.properties
@@ -0,0 +1 @@
+sbt.version=1.0.3
diff --git a/project/plugins.sbt b/project/plugins.sbt
new file mode 100644
index 0000000..45f9d0f
--- /dev/null
+++ b/project/plugins.sbt
@@ -0,0 +1,4 @@
+logLevel := Level.Warn
+addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6")
+addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "0.9.3")
+addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.2.4")
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
new file mode 100644
index 0000000..ada25a1
--- /dev/null
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticDashboardSetup.scala
@@ -0,0 +1,64 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.googlesource.gerrit.plugins.analytics.wizard
+
+import java.io.PrintWriter
+
+trait ConfigWriter {
+ def write(filename: String, out: String)
+}
+
+class ConfigWriterImpl extends ConfigWriter {
+ def write(filename: String, out: String) = {
+ val p = new PrintWriter(filename)
+ p.write(out)
+ p.close()
+ }
+}
+
+case class AnalyticDashboardSetup(name: String, config: Option[String] = None)(
+ implicit val writer: ConfigWriter) {
+
+ private val dockerComposeTemplate = { (name: String) =>
+ s"""
+ |version: '3'
+ |services:
+ | kibana:
+ | build: kibana
+ | container_name: "kibana-for-${name}-project"
+ | environment:
+ | SERVER_BASEPATH: "/kibana"
+ | depends_on:
+ | - elasticsearch
+ | elasticsearch:
+ | build: elasticsearch
+ | container_name: "es-for-${name}-project"
+ | environment:
+ | - ES_JAVA_OPTS=-Xmx4g -Xms4g
+ | - http.host=0.0.0.0
+ | volumes:
+ | - es-indexes:/usr/share/elasticsearch/data
+ """.stripMargin
+ }
+
+ val configFileName = s"/tmp/docker-compose.${name}.yaml"
+ def createDashboardSetupFile(): Unit = {
+ writer.write(configFileName, dockerComposeTemplate(name))
+ }
+
+}
+
+object AnalyticDashboardSetup {
+ implicit val writer = new ConfigWriterImpl()
+}
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
new file mode 100644
index 0000000..f0f6632
--- /dev/null
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticsWizardActions.scala
@@ -0,0 +1,55 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.googlesource.gerrit.plugins.analytics.wizard
+
+import com.google.gerrit.extensions.restapi.{
+ Response,
+ RestModifyView,
+ RestReadView
+}
+import com.google.gerrit.server.project.ProjectResource
+import com.google.inject.Inject
+
+import scala.io.Source
+
+import AnalyticDashboardSetup.writer
+
+class GetAnalyticsStack @Inject()() extends RestReadView[ProjectResource] {
+ override def apply(
+ resource: ProjectResource): Response[AnalyticDashboardSetup] = {
+
+ val projectName = resource.getControl.getProject.getName
+ Response.ok(
+ AnalyticDashboardSetup(
+ projectName,
+ Some(
+ Source
+ .fromFile(s"/tmp/docker-compose.${projectName}.yaml")
+ .getLines
+ .mkString)))
+ }
+}
+
+class Input(var dashboardName: String)
+
+class PutAnalyticsStack @Inject()()
+ extends RestModifyView[ProjectResource, Input] {
+ override def apply(resource: ProjectResource,
+ input: Input): Response[String] = {
+
+ val projectName = resource.getControl.getProject.getName
+ AnalyticDashboardSetup(projectName).createDashboardSetupFile()
+ Response.created(s"Dashboard configuration created for $projectName!")
+ }
+}
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/Module.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/Module.scala
new file mode 100644
index 0000000..36d21dd
--- /dev/null
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/Module.scala
@@ -0,0 +1,31 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.googlesource.gerrit.plugins.analytics.wizard
+
+import com.google.gerrit.extensions.restapi.RestApiModule
+import com.google.gerrit.server.project.ProjectResource.PROJECT_KIND
+import com.google.inject.AbstractModule
+
+class Module extends AbstractModule {
+
+ override protected def configure() {
+ install(new RestApiModule() {
+ override protected def configure() = {
+ get(PROJECT_KIND, "stack").to(classOf[GetAnalyticsStack])
+
+ put(PROJECT_KIND, "stack").to(classOf[PutAnalyticsStack])
+ }
+ })
+ }
+}
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
new file mode 100644
index 0000000..717d213
--- /dev/null
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/wizard/AnalyticDashboardSetupSpec.scala
@@ -0,0 +1,21 @@
+package com.googlesource.gerrit.plugins.analytics.wizard
+
+import org.scalatest.{FlatSpec, Matchers}
+
+class AnalyticDashboardSetupSpec extends FlatSpec with Matchers {
+ behavior of "AnalyticDashboardSetup"
+
+ it should "create a config file with correct name" in {
+ var gotFilename: Option[String] = None
+ class MockWriter extends ConfigWriter {
+ override def write(filename: String, out: String): Unit = {
+ gotFilename = Some(filename)
+ }
+ }
+ implicit val writer = new MockWriter()
+
+ val ads = AnalyticDashboardSetup("aProject")
+ ads.createDashboardSetupFile()
+ gotFilename shouldBe Some(ads.configFileName)
+ }
+}