diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/HttpActuatorConnection.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/HttpActuatorConnection.java index 2e5edd84d0..bfa174bd9a 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/HttpActuatorConnection.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/HttpActuatorConnection.java @@ -11,6 +11,7 @@ package org.springframework.ide.vscode.boot.java.livehover.v2; import java.io.IOException; +import java.net.URI; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; @@ -28,8 +29,10 @@ public class HttpActuatorConnection implements ActuatorConnection { private Gson gson; private RestTemplate restTemplate; + private String actuatorUrl; public HttpActuatorConnection(String actuatorUrl) { + this.actuatorUrl = actuatorUrl; this.restTemplate = new RestTemplateBuilder().rootUri(actuatorUrl).build(); this.gson = new Gson(); } @@ -80,11 +83,12 @@ public String getBeans() throws IOException { @Override public String getLiveMetrics(String metricName, String tags) throws IOException { UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromPath("/metrics/"+metricName); - if (tags != null) { + if (tags != null && !tags.isBlank()) { uriBuilder.queryParam("tag", tags); } - String url = uriBuilder.encode().toUriString(); - return restTemplate.getForObject(url, String.class); + // /{ownerId}/new cases make REST Template URI template handler to think that {ownerId} is a URI parameter which it is not. + String url = actuatorUrl + uriBuilder.toUriString(); + return restTemplate.getForObject(URI.create(url), String.class); } @Override @@ -95,8 +99,9 @@ public String getMetrics(String metric, Map tags) throws IOExcep uriBuilder.queryParam("tag", e.getKey() + ":" + e.getValue()); } } - String url = uriBuilder.encode().toUriString(); - return restTemplate.getForObject(url, String.class); + // /{ownerId}/new cases make REST Template URI template handler to think that {ownerId} is a URI parameter which it is not. + String url = actuatorUrl + uriBuilder.toUriString(); + return restTemplate.getForObject(URI.create(url), String.class); } @Override diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/Measurements.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/Measurements.java index e46f5ca1a0..2f64a4a24e 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/Measurements.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/Measurements.java @@ -1,16 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2022 VMware, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware, Inc. - initial API and implementation + *******************************************************************************/ package org.springframework.ide.vscode.boot.java.livehover.v2; public class Measurements { private String statistic; - private Long value; + private Double value; public String getStatistic() { return statistic; } - public Long getValue() { + public Double getValue() { return value; } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/ProcessType.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/ProcessType.java index 64ca2c47bb..1bfce5916d 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/ProcessType.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/ProcessType.java @@ -1,3 +1,13 @@ +/******************************************************************************* + * Copyright (c) 2022 VMware, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware, Inc. - initial API and implementation + *******************************************************************************/ package org.springframework.ide.vscode.boot.java.livehover.v2; public enum ProcessType { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessCommandHandler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessCommandHandler.java index 5509388ffc..905a9a53d0 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessCommandHandler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessCommandHandler.java @@ -301,11 +301,11 @@ private CompletableFuture handleLiveMetricsProcessRequest(ExecuteCommand String metricName = getArgumentByKey(params, "metricName"); if (processKey != null) { switch(metricName) { - case "gcPauses": { + case SpringProcessConnectorService.GC_PAUSES: { SpringProcessGcPausesMetricsLiveData data = connectorService.getGcPausesMetricsLiveData(processKey); return CompletableFuture.completedFuture(data.getGcPausesMetrics()); } - case "memory": { + case SpringProcessConnectorService.MEMORY: { SpringProcessMemoryMetricsLiveData data = connectorService.getMemoryMetricsLiveData(processKey); return CompletableFuture.completedFuture(data.getMemoryMetrics()); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessConnectorService.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessConnectorService.java index 1b9c4cf9ad..a8f5e3a011 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessConnectorService.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessConnectorService.java @@ -29,6 +29,10 @@ */ public class SpringProcessConnectorService { + private static final String METRICS = "metrics"; + public static final String GC_PAUSES = "gcPauses"; + public static final String MEMORY = "memory"; + private static final Logger log = LoggerFactory.getLogger(SpringProcessConnectorService.class); private final SpringProcessLiveDataProvider liveDataProvider; @@ -171,8 +175,8 @@ private void scheduleConnect(ProgressTask progressTask, String processKey, Sprin progressTask.progressDone(); refreshProcess(new SpringProcessParams(processKey, "", "", "")); - refreshProcess(new SpringProcessParams(processKey, "metrics", "memory", "area:heap")); - refreshProcess(new SpringProcessParams(processKey, "metrics", "gcPauses", "")); + refreshProcess(new SpringProcessParams(processKey, METRICS, MEMORY, "area:heap")); + refreshProcess(new SpringProcessParams(processKey, METRICS, GC_PAUSES, "")); } catch (Exception e) { log.info("problem occured during process connect", e); @@ -232,7 +236,7 @@ private void scheduleRefresh(ProgressTask progressTask, SpringProcessParams spri try { progressTask.progressEvent(progressMessage); - if(endpoint.equals("metrics") && metricName.equals("memory")) { + if(METRICS.equals(endpoint) && MEMORY.equals(metricName)) { SpringProcessMemoryMetricsLiveData newMetricsLiveData = connector.refreshMemoryMetrics(this.liveDataProvider.getCurrent(processKey), metricName, springProcessParams.getTags()); if (newMetricsLiveData != null) { @@ -243,7 +247,7 @@ private void scheduleRefresh(ProgressTask progressTask, SpringProcessParams spri this.connectedSuccess.put(processKey, true); } - } else if(endpoint.equals("metrics") && metricName.equals("gcPauses")) { + } else if(METRICS.equals(endpoint) && GC_PAUSES.equals(metricName)) { SpringProcessGcPausesMetricsLiveData newMetricsLiveData = connector.refreshGcPausesMetrics(this.liveDataProvider.getCurrent(processKey), metricName, springProcessParams.getTags()); if (newMetricsLiveData != null) { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessLiveDataExtractorOverHttp.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessLiveDataExtractorOverHttp.java index 78d329dd70..5568461983 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessLiveDataExtractorOverHttp.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessLiveDataExtractorOverHttp.java @@ -23,6 +23,8 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.web.client.HttpClientErrorException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableList; @@ -198,7 +200,7 @@ public SpringProcessGcPausesMetricsLiveData retrieveLiveGcPausesMetricsData(Proc } } - LiveMemoryMetricsModel metrics = getLiveMetrics(connection, metricName, tags); + LiveMemoryMetricsModel metrics = getLiveMetrics(connection, "jvm.gc.pause", tags); if(metrics != null) { memoryMetricsList.add(metrics); } @@ -240,7 +242,12 @@ public RequestMappingMetrics getRequestMappingMetrics(String[] paths, String[] r return RequestMappingMetrics.parse(metricsData); } catch (IOException e) { - // ignore + } catch (HttpClientErrorException e) { + if (e.getStatusCode() != null && e.getStatusCode() == HttpStatus.NOT_FOUND) { + // not found 404 - don't log it - means metric is unavailable + } else { + log.error("", e); + } } catch (Exception e) { log.error("", e); }