Fix generation of support bundles multiple times

Don't reuse the zip output stream across calls so to allow the
collection of server data multiple times.

Change-Id: I8cf1337e0c0133bec166e81f6b457878d1e103e8
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/support/GerritSupportServlet.scala b/src/main/scala/com/googlesource/gerrit/plugins/support/GerritSupportServlet.scala
index a88c9e8..60bc037 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/support/GerritSupportServlet.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/support/GerritSupportServlet.scala
@@ -46,7 +46,7 @@
     processor.processRequest(request.body) match {
       case Success(zipped) =>
         Created("OK", Map(
-          "Location" -> s"${request.getRequestURI}/${zipped.filename}"))
+          "Location" -> s"${request.getRequestURI}/${zipped.getName}"))
       case Failure(e) => {
         log.error(s"Error serving POST ${request.getRequestURI}", e)
         InternalServerError(reason = e.getLocalizedMessage)
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/support/RequestProcessor.scala b/src/main/scala/com/googlesource/gerrit/plugins/support/RequestProcessor.scala
index 5277fc2..e022cb0 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/support/RequestProcessor.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/support/RequestProcessor.scala
@@ -14,6 +14,8 @@
 
 package com.googlesource.gerrit.plugins.support
 
+import java.io.File
+
 import com.google.gson.{Gson, JsonElement, JsonObject}
 import com.google.inject.{Inject, Injector, Singleton}
 
@@ -25,22 +27,16 @@
                                  gson: Gson,
                                  commandFactory: GerritSupportCommandFactory) {
 
-  def processRequest(body: String): Try[SupportBundleBuilder] = {
+  def processRequest(body: String): Try[File] = {
     Try {
       val requestJson = gson.fromJson(body, classOf[JsonElement]).getAsJsonObject
-
-      try {
+      zipped.build {
         requestJson
           .entrySet().asScala
           .filter(_.getValue.getAsBoolean)
           .map(_.getKey)
           .map(commandFactory.apply)
           .map(_.execute)
-          .foreach(zipped.write)
-        zipped
-
-      } finally {
-        zipped.build
       }
     }
   }
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/support/SupportBundle.scala b/src/main/scala/com/googlesource/gerrit/plugins/support/SupportBundle.scala
index 345acfd..2232f09 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/support/SupportBundle.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/support/SupportBundle.scala
@@ -51,24 +51,22 @@
 
   import SupportBundle._
 
-  lazy val timestamp = DateTimeFormat.forPattern("yyyyMMdd-HHmmss").print(new DateTime)
+  private def timestamp = DateTimeFormat.forPattern("yyyyMMdd-HHmmss").print(new DateTime)
 
-  lazy val filename = BundleName(timestamp, UUID.randomUUID)
+  private def newBundleName = BundleName(timestamp, UUID.randomUUID)
 
-  lazy val file = directory.resolve(filename).toFile
-
-  lazy val zip = new ZipOutputStream(new FileOutputStream(file))
+  private def newFile = directory.resolve(newBundleName).toFile
 
   val UTF8 = Charset.forName("UTF-8")
 
-  def write(file: CommandResult): SupportBundleBuilder = {
-    zip.putNextEntry(new ZipEntry(file.entryName))
-    zip.write(gson.toJson(file.content).getBytes(UTF8))
-    this
-  }
-
-  def build() = {
-    zip.close
+  def build(results: TraversableOnce[CommandResult]): File = {
+    val file = newFile
+    val zipBundle =  new ZipOutputStream(new FileOutputStream(file))
+    results.foreach { result =>
+      zipBundle.putNextEntry(new ZipEntry(result.entryName))
+      zipBundle.write(gson.toJson(result.content).getBytes(UTF8))
+    }
+    zipBundle.close()
     file
   }
 }
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/support/GerritSupportTest.scala b/src/test/scala/com/googlesource/gerrit/plugins/support/GerritSupportTest.scala
index 953ac03..db30eae 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/support/GerritSupportTest.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/support/GerritSupportTest.scala
@@ -55,7 +55,7 @@
   }
 
   "Bundle builder" should "create an output zip file" in {
-    val zipFile = new SupportBundleBuilder(tmpPath.toPath, new Gson).build
+    val zipFile = new SupportBundleBuilder(tmpPath.toPath, new Gson).build(Seq())
 
     zipFile should (be a 'file
       and endWithExtension("zip"))
@@ -63,8 +63,7 @@
 
   it should "create a one entry in the output zip file" in {
     val file = new SupportBundleBuilder(tmpPath.toPath, new Gson)
-      .write(CommandResult("foo", new JsonPrimitive("bar")))
-      .build
+      .build(Seq(CommandResult("foo", new JsonPrimitive("bar"))))
 
     val zipEntries = new ZipFile(file).entries.asScala
     zipEntries should have size (1)
@@ -72,8 +71,7 @@
 
   it should "add the Json primitive into the zip entry" in {
     val file = new SupportBundleBuilder(tmpPath.toPath, new Gson)
-      .write(CommandResult("entry-name", new JsonPrimitive("foo")))
-      .build
+      .build(Seq(CommandResult("entry-name", new JsonPrimitive("foo"))))
 
     val zipEntries = new ZipFile(file).entries.asScala.toSeq
     zipEntries.map(_.getName) should contain("entry-name")