Default to using plugin data dir for new installations

Change Javamelody to default to using the <site_path>/data/javamelody
path for it's graph data. This makes it persist by default for
environments where /tmp is cleared after each reboot, or for containers
where it is lost on each container restart.

Javamelody defaults to using /tmp/javamelody/<app>_<hostname>. This can
be surprising as all other data from Gerrit is located under the sites
path.

Switch the code to use the same mechanism as the javamelody library to
determine the expected path for the system tmp directory, and should it
locate an existing /tmp/javamelody/ path, use the old path by default.

For all installations, if the user has not set the system property, then
if the old path does not exist, set the default path to
<site_path>/data/javamelody or use what the user has configured via
gerrit.config container.javaOptions value of
-Djavamelody.storage_directory parameter.

This should allow for metric data to be persisted by default through
system/container restarts.

Change-Id: I1ae7013d86cf429f0d15320aafdde18002409e78
diff --git a/src/main/java/com/googlesource/gerrit/plugins/javamelody/GerritMonitoringFilter.java b/src/main/java/com/googlesource/gerrit/plugins/javamelody/GerritMonitoringFilter.java
index c537800..60788a3 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/javamelody/GerritMonitoringFilter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/javamelody/GerritMonitoringFilter.java
@@ -14,10 +14,14 @@
 
 package com.googlesource.gerrit.plugins.javamelody;
 
+import com.google.gerrit.extensions.annotations.PluginData;
 import com.google.gerrit.httpd.AllRequestFilter;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.StringJoiner;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
@@ -27,6 +31,8 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import net.bull.javamelody.MonitoringFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 @Singleton
 class GerritMonitoringFilter extends AllRequestFilter {
@@ -75,8 +81,15 @@
   }
 
   static class JavamelodyFilter extends MonitoringFilter {
+    private static final Logger log = LoggerFactory.getLogger(JavamelodyFilter.class);
+    private static final String JAVAMELODY_PREFIX = "javamelody";
     private static final String HTTP_TRANSFORM_PATTERN = "http-transform-pattern";
-    private static final String GLOBAL_HTTP_TRANSFORM_PATTERN = "javamelody." + HTTP_TRANSFORM_PATTERN;
+    private static final String GLOBAL_HTTP_TRANSFORM_PATTERN =
+        String.format("%s.%s", JAVAMELODY_PREFIX, HTTP_TRANSFORM_PATTERN);
+    private static final String STORAGE_DIR = "storage-directory";
+    private static final String GLOBAL_STORAGE_DIR =
+        String.format("%s.%s", JAVAMELODY_PREFIX, STORAGE_DIR);
+
     static final String GERRIT_GROUPING =
         new StringJoiner("|")
             .add("[0-9a-f]{64}") // Long SHA for LFS
@@ -91,11 +104,23 @@
             .add("\\d+") // various ids e.g. change id
             .toString();
 
+    private final Path defaultDataDir;
+
+    @Inject
+    JavamelodyFilter(@PluginData Path defaultDataDir) {
+      this.defaultDataDir = defaultDataDir;
+    }
+
     @Override
     public void init(FilterConfig config) throws ServletException {
-      if (isHttpTransformPatternrUndefined(config)) {
+      if (isPropertyUndefined(config, HTTP_TRANSFORM_PATTERN, GLOBAL_HTTP_TRANSFORM_PATTERN)) {
         System.setProperty(GLOBAL_HTTP_TRANSFORM_PATTERN, GERRIT_GROUPING);
       }
+
+      if (isPropertyUndefined(config, STORAGE_DIR, GLOBAL_STORAGE_DIR)) {
+        System.setProperty(GLOBAL_STORAGE_DIR, getStorageDir());
+      }
+
       super.init(config);
     }
 
@@ -103,10 +128,29 @@
       return getMonitoringUrl(httpRequest);
     }
 
-    private boolean isHttpTransformPatternrUndefined(FilterConfig config) {
-      return System.getProperty(GLOBAL_HTTP_TRANSFORM_PATTERN) == null
-          && config.getServletContext().getInitParameter(GLOBAL_HTTP_TRANSFORM_PATTERN) == null
-          && config.getInitParameter(HTTP_TRANSFORM_PATTERN) == null;
+    private String getStorageDir() {
+      // default to old path for javamelody storage-directory if it exists
+      final Path tmp = Paths.get(System.getProperty("java.io.tmpdir")).resolve(JAVAMELODY_PREFIX);
+      if (Files.isDirectory(tmp)) {
+        return tmp.toString();
+      }
+
+      // put javamelody data in default plugin data dir
+      if (!Files.isDirectory(defaultDataDir)) {
+        try {
+          Files.createDirectories(defaultDataDir);
+        } catch (IOException e) {
+          log.error("Creation of javamelody data dir [{}] failed.", defaultDataDir, e);
+          throw new RuntimeException(e);
+        }
+      }
+      return defaultDataDir.toString();
+    }
+
+    private boolean isPropertyUndefined(FilterConfig config, String name, String globalName) {
+      return System.getProperty(globalName) == null
+          && config.getServletContext().getInitParameter(globalName) == null
+          && config.getInitParameter(name) == null;
     }
   }
 }