Merge branch 'stable-2.14' into stable-2.15
* stable-2.14:
Update bazlets to latest stable-2.14 to build with 2.14.14 API
Update bazlets to latest stable-2.14 to build with 2.14.13 API
Update bazlets to latest stable-2.14 to use 2.14.12 API
Allow access using Basic Authentication prefix
Update javamelody-core to 1.74.0
Prefer Javamelody's own configuration constants
Allow access to metrics from Prometheus
Migrate `tools/bazel.rc` to `.bazelrc`
Delegate canMonitor() check to the MonitorFilter
Update javamelody-core to 1.73.1
Change-Id: I0d954515d2043a03ca4560b2d494b38867419b59
diff --git a/tools/bazel.rc b/.bazelrc
similarity index 100%
rename from tools/bazel.rc
rename to .bazelrc
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl
index 28ca83b..895cfc5 100644
--- a/external_plugin_deps.bzl
+++ b/external_plugin_deps.bzl
@@ -3,8 +3,8 @@
def external_plugin_deps():
maven_jar(
name = 'javamelody-core',
- artifact = 'net.bull.javamelody:javamelody-core:1.72.0',
- sha1 = '199beaab8db0abb45b9c3bad58bf2659d2f96499',
+ artifact = 'net.bull.javamelody:javamelody-core:1.74.0',
+ sha1 = '208ab93932b32be209d264502ed153f18034500f',
)
maven_jar(
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 c23044f..488fe94 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/javamelody/GerritMonitoringFilter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/javamelody/GerritMonitoringFilter.java
@@ -36,6 +36,9 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.bull.javamelody.MonitoringFilter;
+import net.bull.javamelody.Parameter;
+import net.bull.javamelody.internal.common.HttpParameter;
+import net.bull.javamelody.internal.common.Parameters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,12 +46,10 @@
class GerritMonitoringFilter extends AllRequestFilter {
private static final Logger log = LoggerFactory.getLogger(GerritMonitoringFilter.class);
private final JavamelodyFilter monitoring;
- private final CapabilityChecker capabilityChecker;
@Inject
- GerritMonitoringFilter(JavamelodyFilter monitoring, CapabilityChecker capabilityChecker) {
+ GerritMonitoringFilter(JavamelodyFilter monitoring) {
this.monitoring = monitoring;
- this.capabilityChecker = capabilityChecker;
}
@Override
@@ -62,7 +63,7 @@
HttpServletResponse httpResponse = (HttpServletResponse) response;
HttpServletRequest httpRequest = (HttpServletRequest) request;
- if (canMonitor(httpRequest)) {
+ if (monitoring.canMonitor(httpRequest)) {
monitoring.doFilter(request, response, chain);
} else {
httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Forbidden access");
@@ -79,21 +80,19 @@
monitoring.destroy();
}
- private boolean canMonitor(HttpServletRequest httpRequest) {
- if (httpRequest.getRequestURI().equals(monitoring.getJavamelodyUrl(httpRequest))) {
- return capabilityChecker.canMonitor();
- }
- return true;
- }
-
static class JavamelodyFilter extends MonitoringFilter {
private static final String JAVAMELODY_PREFIX = "javamelody";
- private static final String HTTP_TRANSFORM_PATTERN = "http-transform-pattern";
+ private static final String HTTP_TRANSFORM_PATTERN = Parameter.HTTP_TRANSFORM_PATTERN.getCode();
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 STORAGE_DIR = Parameter.STORAGE_DIRECTORY.getCode();
private static final String GLOBAL_STORAGE_DIR =
String.format("%s.%s", JAVAMELODY_PREFIX, STORAGE_DIR);
+ private static final String PROMETHEUS_BEARER_TOKEN = "prometheusBearerToken";
+ private static final String FORMAT_PROMETHEUS = "prometheus";
+ private static final String AUTHORIZATION_HEADER = "Authorization";
+ private final CapabilityChecker capabilityChecker;
+ private final boolean useBearerTokenForPrometheus;
static final String GERRIT_GROUPING =
new StringJoiner("|")
@@ -111,14 +110,18 @@
private final PluginConfig cfg;
private final Path defaultDataDir;
+ private String authenticatedMonitoringUrl;
@Inject
JavamelodyFilter(
PluginConfigFactory cfgFactory,
@PluginName String pluginName,
- @PluginData Path defaultDataDir) {
+ @PluginData Path defaultDataDir,
+ CapabilityChecker capabilityChecker) {
this.defaultDataDir = defaultDataDir;
this.cfg = cfgFactory.getFromGerritConfig(pluginName);
+ this.capabilityChecker = capabilityChecker;
+ this.useBearerTokenForPrometheus = isPropertyInPluginConfig(PROMETHEUS_BEARER_TOKEN);
}
@Override
@@ -140,6 +143,20 @@
return getMonitoringUrl(httpRequest);
}
+ @Override
+ protected String getMonitoringUrl(HttpServletRequest httpRequest) {
+ if (authenticatedMonitoringUrl == null) {
+ authenticatedMonitoringUrl =
+ httpRequest.getContextPath() + "/a" + Parameters.getMonitoringPath();
+ }
+
+ if (httpRequest.getRequestURI().equals(authenticatedMonitoringUrl)) {
+ return authenticatedMonitoringUrl;
+ }
+
+ return super.getMonitoringUrl(httpRequest);
+ }
+
private String getTransformPattern() {
return cfg.getString(HTTP_TRANSFORM_PATTERN, GERRIT_GROUPING);
}
@@ -176,5 +193,28 @@
&& config.getServletContext().getInitParameter(globalName) == null
&& config.getInitParameter(name) == null;
}
+
+ boolean canMonitor(HttpServletRequest httpRequest) {
+ if (httpRequest.getRequestURI().equals(getJavamelodyUrl(httpRequest))) {
+ /* Exception when access to metrics for Prometheus using Bearer Token
+ * without going through any Gerrit Authentication step.
+ * Enable to access the Prometheus metrics ONLY and nothing else, skipping
+ * any authentication and ACL check.
+ */
+ if (useBearerTokenForPrometheus
+ && httpRequest.getHeader(AUTHORIZATION_HEADER) != null
+ && FORMAT_PROMETHEUS.equals(HttpParameter.FORMAT.getParameterFrom(httpRequest))) {
+ return canMonitorFromPrometheusUsingBearerToken(httpRequest);
+ }
+ return capabilityChecker.canMonitor();
+ }
+ return true;
+ }
+
+ private boolean canMonitorFromPrometheusUsingBearerToken(HttpServletRequest httpRequest) {
+ return httpRequest
+ .getHeader(AUTHORIZATION_HEADER)
+ .equals("Bearer " + cfg.getString(PROMETHEUS_BEARER_TOKEN));
+ }
}
}
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index dd74e42..4eaa5ba 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -23,6 +23,20 @@
: Whether it is allowed to show top menu in Gerrit UI.
By default true.
+<a id="prometheusBearerToken">
+`plugin.@PLUGIN@.prometheusBearerToken`
+: Bearer token for allowing Prometheus to query JavaMelody data
+ through its scraper.
+ When defined, access to the /monitoring?format=prometheus URL
+ does not require any authentication and do not check any ACL related
+ to the ViewMetrics global capability. Any access to the other monitoring
+ screen and URLs will still require standard authentication and authorization checks.
+ See <a href="https://github.com/javamelody/javamelody/wiki/UserGuideAdvanced#exposing-metrics-to-prometheus">JavaMelody-Prometheus</a>
+ configuration for more details and
+ <a href="https://prometheus.io/docs/prometheus/latest/configuration/configuration/">Prometheus documentation</a>
+ for how to configure the integration with Prometheus.
+ By default undefined.
+
<a id="storage-directory">
`plugin.@PLUGIN@.storage-directory`
: The directory in which to store data files. Javamelody, by default,