Store docker-compose generate files under data

Rely on the plugin's data directory to store the generated YAML
docker-compose file, so that they will be kept across restarts.

Change-Id: I96d1176b999c924758f76b0492a648a1386b535c
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 aec2268..1c07435 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
@@ -14,20 +14,20 @@
 package com.googlesource.gerrit.plugins.analytics.wizard
 
 import java.io.PrintWriter
+import java.nio.charset.{Charset, StandardCharsets}
+import java.nio.file.{Files, Path}
 
 trait ConfigWriter {
-  def write(filename: String, out: String)
+  def write(outputPath: Path, out: String)
 }
 
 class ConfigWriterImpl extends ConfigWriter {
-  def write(filename: String, out: String) = {
-    val p = new PrintWriter(filename)
-    p.write(out)
-    p.close()
+  def write(outputPath: Path, out: String) {
+    Files.write(outputPath, out.getBytes(StandardCharsets.UTF_8))
   }
 }
 
-case class AnalyticDashboardSetup(name: String, config: Option[String] = None)(
+case class AnalyticDashboardSetup(name: String, dockerComposeYamlPath: Path)(
     implicit val writer: ConfigWriter) {
 
   private val dockerComposeTemplate = { (name: String) =>
@@ -68,9 +68,8 @@
      """.stripMargin
   }
 
-  val configFileName = s"/tmp/docker-compose.${name}.yaml"
   def createDashboardSetupFile(): Unit = {
-    writer.write(configFileName, dockerComposeTemplate(name))
+    writer.write(dockerComposeYamlPath, dockerComposeTemplate(name))
   }
 
 }
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 44a5512..f63447c 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
@@ -14,6 +14,7 @@
 package com.googlesource.gerrit.plugins.analytics.wizard
 
 import java.nio.charset.StandardCharsets.UTF_8
+import java.nio.file.Path
 
 import com.google.common.io.ByteStreams
 import com.google.gerrit.extensions.restapi.{
@@ -25,10 +26,11 @@
 import com.google.gerrit.server.project.ProjectResource
 import com.google.inject.Inject
 import AnalyticDashboardSetup.writer
+import com.google.gerrit.extensions.annotations.PluginData
 
 import scala.io.Source
 
-class GetAnalyticsStack @Inject()() extends RestReadView[ProjectResource] {
+class GetAnalyticsStack @Inject()(@PluginData val dataPath: Path) extends RestReadView[ProjectResource] {
   override def apply(
       resource: ProjectResource): Response[AnalyticDashboardSetup] = {
 
@@ -36,29 +38,25 @@
     Response.ok(
       AnalyticDashboardSetup(
         projectName,
-        Some(
-          Source
-            .fromFile(s"/tmp/docker-compose.${projectName}.yaml")
-            .getLines
-            .mkString)))
+        dataPath.resolve(s"docker-compose.${projectName}.yaml")))
   }
 }
 
 class Input(var dashboardName: String)
 
-class PutAnalyticsStack @Inject()()
+class PutAnalyticsStack @Inject()(@PluginData val dataPath: Path)
     extends RestModifyView[ProjectResource, Input] {
   override def apply(resource: ProjectResource,
                      input: Input): Response[String] = {
 
     val projectName = resource.getControl.getProject.getName
-    AnalyticDashboardSetup(projectName).createDashboardSetupFile()
+    AnalyticDashboardSetup(projectName, dataPath.resolve(s"docker-compose.${projectName}.yaml")).createDashboardSetupFile()
     Response.created(s"Dashboard configuration created for $projectName!")
   }
 }
 
 class DockerComposeCommand(var action: String)
-class PostAnalyticsStack @Inject()()
+class PostAnalyticsStack @Inject()(@PluginData val dataPath: Path)
     extends RestModifyView[ProjectResource, DockerComposeCommand] {
   override def apply(resource: ProjectResource,
                      input: DockerComposeCommand): Response[String] = {
@@ -67,8 +65,8 @@
     val pb = new ProcessBuilder(
       "docker-compose",
       "-f",
-      s"/tmp/docker-compose.${projectName}.yaml",
-      input.action.toLowerCase) // XXX validate command!
+      s"${dataPath.toFile.getAbsolutePath}/docker-compose.${projectName}.yaml",
+      input.action.toLowerCase)
     pb.redirectErrorStream(true)
 
     val ps: Process = pb.start
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 717d213..c7e0519 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
@@ -1,21 +1,25 @@
 package com.googlesource.gerrit.plugins.analytics.wizard
 
+import java.io.File
+import java.nio.file.Path
+
 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
+    var gotFilename: Option[Path] = None
     class MockWriter extends ConfigWriter {
-      override def write(filename: String, out: String): Unit = {
+      override def write(filename: Path, out: String): Unit = {
         gotFilename = Some(filename)
       }
     }
     implicit val writer = new MockWriter()
 
-    val ads = AnalyticDashboardSetup("aProject")
+    val composeYamlFile = File.createTempFile(getClass.getName, ".yaml").toPath
+    val ads = AnalyticDashboardSetup("aProject", composeYamlFile)
     ads.createDashboardSetupFile()
-    gotFilename shouldBe Some(ads.configFileName)
+    gotFilename shouldBe Some(composeYamlFile)
   }
 }