Wizard status endpoint

Reports the status of the Spark ETL job. Return codes:
- 500: any error occourred, i.e.: JSON parsing, can't find container, etc
- 202: still processing
- 204: successfully finished the import

Feature: Issue 9869
Change-Id: Ib556df76e45482b3662798b9fc1f5ae825f83281
diff --git a/build.sbt b/build.sbt
index 6a71bc2..40b5dd8 100644
--- a/build.sbt
+++ b/build.sbt
@@ -9,19 +9,15 @@
   .settings(
     name := pluginName,
     resolvers += Resolver.mavenLocal,
-
     scalaVersion := "2.11.8",
-
     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,
-
+      "com.google.gerrit" % "gerrit-plugin-api" % gerritApiVersion % Provided withSources (),
+      "com.spotify" % "docker-client" % "8.14.1",
       "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),
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 2c55c64..98bb03f 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
@@ -26,8 +26,10 @@
   RestReadView
 }
 import com.google.gerrit.server.project.ProjectResource
-import com.google.inject.Inject
+import com.google.inject.{ImplementedBy, Inject}
 import com.googlesource.gerrit.plugins.analytics.wizard.AnalyticDashboardSetup.writer
+import com.spotify.docker.client.{DefaultDockerClient, DockerClient}
+import com.spotify.docker.client.messages.ContainerInfo
 
 class Input(var dashboardName: String)
 
@@ -78,7 +80,30 @@
         throw new RestApiException(
           s"Failed with exit code: ${ps.exitValue} - $output")
     }
+  }
+}
 
+class GetAnalyticsStackStatus @Inject()(
+    @PluginData val dataPath: Path,
+    val dockerClientProvider: DockerClientProvider)
+    extends RestReadView[ProjectResource] {
+  override def apply(resource: ProjectResource): Response[String] = {
+    val containerName = "analytics-wizard_spark-gerrit-analytics-etl_1"
+    responseFromContainerInfo(
+      dockerClientProvider.client.inspectContainer(containerName))
+  }
+
+  private def responseFromContainerInfo(containerInfo: ContainerInfo) = {
+    containerInfo.state match {
+      case s if s.exitCode != 0 =>
+        throw new RestApiException(s"Data import failed")
+      case s if s.running =>
+        Response.withStatusCode(202, "processing")
+      case s if s.status == "exited" =>
+        //Spark ETL job exited successfully
+        Response.withStatusCode(204, "finished")
+      case _ => throw new RestApiException(s"Case not handled")
+    }
   }
 }
 
@@ -92,3 +117,12 @@
       case e: Throwable => throw new RuntimeException(e)
     }
 }
+
+@ImplementedBy(classOf[DockerClientProviderImpl])
+trait DockerClientProvider {
+  def client: DockerClient
+}
+
+class DockerClientProviderImpl extends DockerClientProvider {
+  def client: DockerClient = DefaultDockerClient.fromEnv.build
+}
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
index ef9d24a..5cea45b 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/Module.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/wizard/Module.scala
@@ -26,6 +26,8 @@
         put(PROJECT_KIND, "stack").to(classOf[PutAnalyticsStack])
 
         post(PROJECT_KIND, "server").to(classOf[PostAnalyticsStack])
+
+        get(PROJECT_KIND, "status").to(classOf[GetAnalyticsStackStatus])
       }
     })
   }