diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.docker/src/org/springframework/ide/eclipse/boot/dash/docker/runtarget/DockerRunTarget.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.docker/src/org/springframework/ide/eclipse/boot/dash/docker/runtarget/DockerRunTarget.java index 5f9145e6c..e34c9c8b9 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.docker/src/org/springframework/ide/eclipse/boot/dash/docker/runtarget/DockerRunTarget.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.docker/src/org/springframework/ide/eclipse/boot/dash/docker/runtarget/DockerRunTarget.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020 Pivotal, Inc. + * Copyright (c) 2020, 2024 Pivotal, 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 @@ -14,6 +14,7 @@ import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashC import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.DEVTOOLS; import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.INSTANCES; import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.LIVE_PORT; +import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.ACTIVE_PROFILES; import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.NAME; import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.PROGRESS; import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.RUN_STATE_ICN; @@ -168,6 +169,7 @@ implements RemoteRunTarget, ProjectDeploymentT NAME, PROGRESS, LIVE_PORT, + ACTIVE_PROFILES, DEVTOOLS, INSTANCES, DEFAULT_PATH, diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/labels/BootDashLabels.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/labels/BootDashLabels.java index 926b33414..c81ba9276 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/labels/BootDashLabels.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/labels/BootDashLabels.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015, 2023 Pivotal, Inc. + * Copyright (c) 2015, 2024 Pivotal, 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 @@ -15,6 +15,7 @@ import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashC import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.HOST; import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.INSTANCES; import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.LIVE_PORT; +import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.ACTIVE_PROFILES; import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.NAME; import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.PROGRESS; import static org.springframework.ide.eclipse.boot.dash.views.sections.BootDashColumn.PROJECT; @@ -40,6 +41,7 @@ import org.springframework.ide.eclipse.boot.dash.model.BootDashElement; import org.springframework.ide.eclipse.boot.dash.model.BootDashModel; import org.springframework.ide.eclipse.boot.dash.model.ButtonModel; import org.springframework.ide.eclipse.boot.dash.model.ClasspathPropertyTester; +import org.springframework.ide.eclipse.boot.dash.model.Failable; import org.springframework.ide.eclipse.boot.dash.model.RefreshState; import org.springframework.ide.eclipse.boot.dash.model.RunState; import org.springframework.ide.eclipse.boot.dash.model.TagUtils; @@ -444,6 +446,36 @@ public class BootDashLabels implements Disposable { styledLabel = new StyledString(textLabel, stylers.color(color)); } } + } else if (column == ACTIVE_PROFILES) { + RunState runState = element.getRunState(); + ImmutableSet activeProfiles = ImmutableSet.of(); + boolean liveProfilesAvailable = false; + if (runState == RunState.RUNNING || runState == RunState.DEBUGGING) { + Failable> liveProfiles = element.getLiveProfiles(); + if (!liveProfiles.hasFailed()) { + activeProfiles = liveProfiles.getValue(); + liveProfilesAvailable = true; + } else { + activeProfiles = element.getActiveProfiles(); + } + } else { + activeProfiles = element.getActiveProfiles(); + } + String textLabel; + if (activeProfiles.isEmpty() || (activeProfiles.size() == 1 && activeProfiles.iterator().next().isBlank())) { + textLabel = ""; + } else { + StringBuilder str = new StringBuilder(); + str.append(activeProfiles.size() == 1 ? "profile: " : "profiles: "); + str.append(String.join(",", activeProfiles)); + textLabel = str.toString(); + } + if (stylers == null) { + label = textLabel; + } else { + Color color = liveProfilesAvailable ? colorGreen() : colorGrey(); + styledLabel = new StyledString(textLabel, stylers.color(color)); + } } else if (column==DEFAULT_PATH) { String path = element.getDefaultRequestMappingPath(); if (stylers == null) { diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/AbstractLaunchConfigurationsDashElement.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/AbstractLaunchConfigurationsDashElement.java index 33f3df086..86cbb6856 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/AbstractLaunchConfigurationsDashElement.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/AbstractLaunchConfigurationsDashElement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015, 2023 Pivotal, Inc. + * Copyright (c) 2015, 2024 Pivotal, 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 @@ -14,6 +14,7 @@ import java.time.Duration; import java.util.Collection; import java.util.EnumSet; import java.util.List; +import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -38,9 +39,11 @@ import org.springframework.ide.eclipse.boot.dash.util.CollectionUtils; import org.springframework.ide.eclipse.boot.dash.util.LaunchConfRunStateTracker; import org.springframework.ide.eclipse.boot.dash.util.RunStateTracker.RunStateListener; import org.springframework.ide.eclipse.boot.launch.BootLaunchConfigurationDelegate; +import org.springframework.ide.eclipse.boot.launch.BootLsCommandUtils; import org.springframework.ide.eclipse.boot.launch.cli.CloudCliServiceLaunchConfigurationDelegate; import org.springframework.ide.eclipse.boot.launch.util.BootDebugUITools; import org.springframework.ide.eclipse.boot.launch.util.BootLaunchUtils; +import org.springframework.ide.eclipse.boot.launch.util.JMXClient; import org.springframework.ide.eclipse.boot.launch.util.SpringApplicationLifeCycleClientManager; import org.springframework.ide.eclipse.boot.launch.util.SpringApplicationLifecycleClient; import org.springframework.ide.eclipse.boot.util.RetryUtil; @@ -58,6 +61,7 @@ import org.springsource.ide.eclipse.commons.ui.launch.LaunchUtils; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.google.gson.reflect.TypeToken; /** * Abstracts out the commonalities between {@link BootProjectDashElement} and {@link LaunchConfDashElement}. Each can @@ -91,6 +95,7 @@ public abstract class AbstractLaunchConfigurationsDashElement extends Wrappin private PollingLiveExp>> liveRequestMappings; private PollingLiveExp> liveBeans; private PollingLiveExp> liveEnv; + private PollingLiveExp>> liveProfiles; public AbstractLaunchConfigurationsDashElement(LocalBootDashModel bootDashModel, T delegate) { super(bootDashModel, delegate); @@ -591,6 +596,42 @@ public abstract class AbstractLaunchConfigurationsDashElement extends Wrappin } } + @Override + public Failable> getLiveProfiles() { + synchronized (this) { + if (liveProfiles == null) { + liveProfiles = PollingLiveExp.create(Failable.>error(MissingLiveInfoMessages.NOT_YET_COMPUTED), () -> { + try { + String localJmxUrl = JMXClient.createLocalJmxUrl(getJmxPort()); + if (localJmxUrl == null) { + return Failable.error(getBootDashModel().getRunTarget().getType().getMissingLiveInfoMessages().getMissingInfoMessage(getName(), "profiles")); + } + String[] o = BootLsCommandUtils.executeCommand(TypeToken.get(String[].class), "sts/livedata/get", Map.of( + "endpoint", "profiles", + "processKey", localJmxUrl + )).get().orElse(new String[0]); + liveProfiles.refreshOnce(); + return Failable.of(ImmutableSet.copyOf(o)); + } catch (Exception e) { + return Failable.error(getBootDashModel().getRunTarget().getType().getMissingLiveInfoMessages().getMissingInfoMessage(getName(), "profiles")); + } + }); + addElementState(liveProfiles); + addDisposableChild(liveProfiles); + runState.addListener((e, runstate) -> { + if (READY_STATES.contains(runstate)) { + // After the app is running refresh for 5 sec every 1 sec until active profiles are fetched + liveProfiles.sleepBetweenRefreshes(Duration.ofSeconds(1)); + liveProfiles.refreshFor(Duration.ofSeconds(5)); + } else { + liveProfiles.refreshOnce(); + } + }); + } + return liveProfiles.getValue(); + } + } + private int getJmxPort() { for (ILaunchConfiguration c : getLaunchConfigs()) { for (ILaunch l : LaunchUtils.getLaunches(c)) { @@ -684,4 +725,16 @@ public abstract class AbstractLaunchConfigurationsDashElement extends Wrappin return (LocalRunTarget) super.getTarget(); } + @Override + public ImmutableSet getActiveProfiles() { + ILaunchConfiguration launchConfig = getActiveConfig(); + if (launchConfig != null) { + String profile = BootLaunchConfigurationDelegate.getProfile(launchConfig); + if (profile != null) { + return ImmutableSet.of(profile); + } + } + return ImmutableSet.of(); + } + } diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/BootDashElement.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/BootDashElement.java index b26844abf..d9e5acd79 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/BootDashElement.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/BootDashElement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015, 2020 Pivotal, Inc. + * Copyright (c) 2015, 2024 Pivotal, 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 @@ -70,6 +70,11 @@ public interface BootDashElement extends App, Taggable { */ Failable getLiveEnv(); + /** + * Get the live profiles from a running process + */ + Failable> getLiveProfiles(); + /** * Get the 'active' launch configuration. This may be null. *

@@ -109,6 +114,7 @@ public interface BootDashElement extends App, Taggable { ObservableSet getChildren(); ImmutableSet getLaunchConfigs(); ImmutableSet getLivePorts(); + ImmutableSet getActiveProfiles(); /** * Fetch the parent of a BDE. If this is a nested BDE then the parent will be diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/BootProjectDashElement.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/BootProjectDashElement.java index b7a68854a..11dee52a0 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/BootProjectDashElement.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/BootProjectDashElement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015, 2021 Pivotal, Inc. + * Copyright (c) 2015, 2024 Pivotal, 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 @@ -71,7 +71,7 @@ public class BootProjectDashElement extends AbstractLaunchConfigurationsDashElem private ObservableSet children; private ObservableSet ports; - private AsyncLiveExpression hasMainMethod = new AsyncLiveExpression( + private AsyncLiveExpression hasMainMethod = new AsyncLiveExpression<>( false, "Search main' method in project " + (getProject() != null && getProject().getName() != null ? "'" + getProject().getName() + "'": "UNKNOWQN"), null, diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/LocalCloudServiceDashElement.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/LocalCloudServiceDashElement.java index 2bf7cadfd..d8cc2f531 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/LocalCloudServiceDashElement.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/LocalCloudServiceDashElement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015, 2017 Pivotal, Inc. + * Copyright (c) 2015, 2024 Pivotal, 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 @@ -162,7 +162,7 @@ public class LocalCloudServiceDashElement extends AbstractLaunchConfigurationsDa protected LiveExpression createPortExpression(final LiveExpression runState) { if (CloudCliServiceLaunchConfigurationDelegate.isSingleProcessServiceConfig(getActiveConfig())) { - AsyncLiveExpression exp = new AsyncLiveExpression(-1, "Refreshing port info for "+getName()) { + AsyncLiveExpression exp = new AsyncLiveExpression<>(-1, "Refreshing port info for "+getName()) { { //Doesn't really depend on runState, but should be recomputed when runState changes. dependsOn(runState); diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/LocalRunTarget.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/LocalRunTarget.java index 9515589e3..4a079cba4 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/LocalRunTarget.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/LocalRunTarget.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015, 2023 Pivotal, Inc. + * Copyright (c) 2015, 2024 Pivotal, 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 @@ -27,6 +27,7 @@ public class LocalRunTarget extends AbstractRunTarget { NAME, DEVTOOLS, LIVE_PORT, + ACTIVE_PROFILES, INSTANCES, DEFAULT_PATH, TAGS diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/GenericRemoteAppElement.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/GenericRemoteAppElement.java index 45a6290de..c1eeedad1 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/GenericRemoteAppElement.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/GenericRemoteAppElement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020 Pivotal Software, Inc. + * Copyright (c) 2020, 2024 Pivotal Software, 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 @@ -13,6 +13,7 @@ package org.springframework.ide.eclipse.boot.dash.model.remote; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.concurrent.CompletableFuture; @@ -66,6 +67,7 @@ import org.springframework.ide.eclipse.boot.dash.model.actuator.ActuatorClient; import org.springframework.ide.eclipse.boot.dash.model.actuator.JMXActuatorClient; import org.springframework.ide.eclipse.boot.dash.model.actuator.RequestMapping; import org.springframework.ide.eclipse.boot.dash.model.actuator.env.LiveEnvModel; +import org.springframework.ide.eclipse.boot.launch.BootLsCommandUtils; import org.springsource.ide.eclipse.commons.core.pstore.IPropertyStore; import org.springsource.ide.eclipse.commons.core.pstore.PropertyStoreApi; import org.springsource.ide.eclipse.commons.core.pstore.PropertyStores; @@ -85,6 +87,7 @@ import org.springsource.ide.eclipse.commons.livexp.util.OldValueDisposer; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet.Builder; +import com.google.gson.reflect.TypeToken; public class GenericRemoteAppElement extends WrappingBootDashElement implements Deletable, AppContext, Styleable, ElementStateListener, JmxConnectable, LiveDataCapableElement { @@ -457,6 +460,10 @@ public class GenericRemoteAppElement extends WrappingBootDashElement imp return getRunStateExp().getValue(); } + public ImmutableSet getActiveProfiles() { + return ImmutableSet.of(); + } + private LiveExpression getRunStateExp() { return jmxRunStateTracker.augmentedRunState; } @@ -681,6 +688,7 @@ public class GenericRemoteAppElement extends WrappingBootDashElement imp private LiveExpression>> liveRequestMappings; private LiveExpression> liveEnv; private LiveExpression> liveBeans; + private LiveExpression>> liveProfiles; @Override public Failable> getLiveRequestMappings() { @@ -715,6 +723,43 @@ public class GenericRemoteAppElement extends WrappingBootDashElement imp return liveRequestMappings.getValue(); } + @Override + public Failable> getLiveProfiles() { + synchronized (this) { + if (liveProfiles == null) { + final LiveExpression> actuatorUrls = getActuatorUrls(); + liveProfiles = new AsyncLiveExpression<>(Failable.error(MissingLiveInfoMessages.NOT_YET_COMPUTED), "Fetch active profiles for '"+getStyledName(null).getString()+"'") { + @Override + protected Failable> compute() { + Set targets = actuatorUrls.getValue(); + if (targets!=null && !targets.isEmpty()) { + if (targets.size() == 1) { + String target = targets.iterator().next(); + try { + String[] o = BootLsCommandUtils.executeCommand(TypeToken.get(String[].class), "sts/livedata/get", Map.of( + "endpoint", "profiles", + "processKey", target + )).get().orElse(new String[0]); + return Failable.of(ImmutableSet.copyOf(o)); + } catch (Exception e) { + return Failable.error(getBootDashModel().getRunTarget().getType().getMissingLiveInfoMessages().getMissingInfoMessage(getStyledName(null).getString(), "profiles")); + } + } else { + return Failable.error(buffer -> buffer.p("More than one child can provide live data. Please select one.")); + } + } + return Failable.error(getBootDashModel().getRunTarget().getType().getMissingLiveInfoMessages().getMissingInfoMessage(getStyledName(null).getString(), "profiles")); + } + + }; + liveProfiles.dependsOn(actuatorUrls); + addElementState(liveProfiles); + addDisposableChild(liveProfiles); + } + } + return liveProfiles.getValue(); + } + @Override public Failable getLiveEnv() { synchronized (this) { diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/views/sections/BootDashColumn.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/views/sections/BootDashColumn.java index afa15fa01..57068cb8f 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/views/sections/BootDashColumn.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/views/sections/BootDashColumn.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015, 2023 Pivotal, Inc. + * Copyright (c) 2015, 2024 Pivotal, 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 @@ -29,6 +29,7 @@ public class BootDashColumn { public static final BootDashColumn NAME = new BootDashColumn("NAME"); public static final BootDashColumn HOST = new BootDashColumn("HOST"); public static final BootDashColumn LIVE_PORT = new BootDashColumn("LIVE_PORT"); + public static final BootDashColumn ACTIVE_PROFILES = new BootDashColumn("ACTIVE_PROFILES"); public static final BootDashColumn DEFAULT_PATH = new BootDashColumn("DEFAULT_PATH"); public static final BootDashColumn TAGS = new BootDashColumn("TAGS"); public static final BootDashColumn DEVTOOLS = new BootDashColumn("DEVTOOLS"); diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.launch/src/org/springframework/ide/eclipse/boot/launch/BootLsCommandUtils.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.launch/src/org/springframework/ide/eclipse/boot/launch/BootLsCommandUtils.java index e51285df8..e692197c4 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.launch/src/org/springframework/ide/eclipse/boot/launch/BootLsCommandUtils.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.launch/src/org/springframework/ide/eclipse/boot/launch/BootLsCommandUtils.java @@ -44,7 +44,7 @@ public class BootLsCommandUtils { public static CompletableFuture> executeCommand(TypeToken resType, String cmd, Object... params) { return getLanguageServers(cmd).computeFirst(ls -> ls.getWorkspaceService().executeCommand(new ExecuteCommandParams( cmd, - ImmutableList.of(params) + ImmutableList.copyOf(params) ))).thenApply(o -> o.map(v -> GSON.fromJson(GSON.toJsonTree(v), resType))); } 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 a57a81bbc..408c5a1eb 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 @@ -295,7 +295,8 @@ public class SpringProcessCommandHandler { String endpoint = getArgumentByKey(params, "endpoint"); if (processKey != null) { SpringProcessLiveData data = connectorService.getLiveData(processKey); - switch(endpoint) { + if (data != null) { + switch(endpoint) { case "properties": { return CompletableFuture.completedFuture(data.getLiveProperties()); } @@ -324,10 +325,13 @@ public class SpringProcessCommandHandler { return CompletableFuture.completedFuture(data.getActiveProfiles()); } default: {} + } + } else { + return CompletableFuture.failedFuture(new IllegalStateException("Live Data is not yet available!")); } } - return CompletableFuture.completedFuture(null); + return CompletableFuture.failedFuture(new IllegalStateException("Live process key is missing from the request parameters!")); } private CompletableFuture handleLiveMetricsProcessRequest(ExecuteCommandParams params) {