Show active profile for app in BootDash
This commit is contained in:
@@ -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<String> activeProfiles = ImmutableSet.of();
|
||||
boolean liveProfilesAvailable = false;
|
||||
if (runState == RunState.RUNNING || runState == RunState.DEBUGGING) {
|
||||
Failable<ImmutableSet<String>> 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) {
|
||||
|
||||
@@ -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<T> extends Wrappin
|
||||
private PollingLiveExp<Failable<ImmutableList<RequestMapping>>> liveRequestMappings;
|
||||
private PollingLiveExp<Failable<LiveBeansModel>> liveBeans;
|
||||
private PollingLiveExp<Failable<LiveEnvModel>> liveEnv;
|
||||
private PollingLiveExp<Failable<ImmutableSet<String>>> liveProfiles;
|
||||
|
||||
public AbstractLaunchConfigurationsDashElement(LocalBootDashModel bootDashModel, T delegate) {
|
||||
super(bootDashModel, delegate);
|
||||
@@ -591,6 +596,42 @@ public abstract class AbstractLaunchConfigurationsDashElement<T> extends Wrappin
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Failable<ImmutableSet<String>> getLiveProfiles() {
|
||||
synchronized (this) {
|
||||
if (liveProfiles == null) {
|
||||
liveProfiles = PollingLiveExp.create(Failable.<ImmutableSet<String>>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<T> extends Wrappin
|
||||
return (LocalRunTarget) super.getTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableSet<String> getActiveProfiles() {
|
||||
ILaunchConfiguration launchConfig = getActiveConfig();
|
||||
if (launchConfig != null) {
|
||||
String profile = BootLaunchConfigurationDelegate.getProfile(launchConfig);
|
||||
if (profile != null) {
|
||||
return ImmutableSet.of(profile);
|
||||
}
|
||||
}
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<LiveEnvModel> getLiveEnv();
|
||||
|
||||
/**
|
||||
* Get the live profiles from a running process
|
||||
*/
|
||||
Failable<ImmutableSet<String>> getLiveProfiles();
|
||||
|
||||
/**
|
||||
* Get the 'active' launch configuration. This may be null.
|
||||
* <p>
|
||||
@@ -109,6 +114,7 @@ public interface BootDashElement extends App, Taggable {
|
||||
ObservableSet<BootDashElement> getChildren();
|
||||
ImmutableSet<ILaunchConfiguration> getLaunchConfigs();
|
||||
ImmutableSet<Integer> getLivePorts();
|
||||
ImmutableSet<String> getActiveProfiles();
|
||||
|
||||
/**
|
||||
* Fetch the parent of a BDE. If this is a nested BDE then the parent will be
|
||||
|
||||
@@ -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<BootDashElement> children;
|
||||
private ObservableSet<Integer> ports;
|
||||
|
||||
private AsyncLiveExpression<Boolean> hasMainMethod = new AsyncLiveExpression<Boolean>(
|
||||
private AsyncLiveExpression<Boolean> hasMainMethod = new AsyncLiveExpression<>(
|
||||
false,
|
||||
"Search main' method in project " + (getProject() != null && getProject().getName() != null ? "'" + getProject().getName() + "'": "UNKNOWQN"),
|
||||
null,
|
||||
|
||||
@@ -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<Integer> createPortExpression(final LiveExpression<RunState> runState) {
|
||||
if (CloudCliServiceLaunchConfigurationDelegate.isSingleProcessServiceConfig(getActiveConfig())) {
|
||||
AsyncLiveExpression<Integer> exp = new AsyncLiveExpression<Integer>(-1, "Refreshing port info for "+getName()) {
|
||||
AsyncLiveExpression<Integer> exp = new AsyncLiveExpression<>(-1, "Refreshing port info for "+getName()) {
|
||||
{
|
||||
//Doesn't really depend on runState, but should be recomputed when runState changes.
|
||||
dependsOn(runState);
|
||||
|
||||
@@ -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<Void> {
|
||||
NAME,
|
||||
DEVTOOLS,
|
||||
LIVE_PORT,
|
||||
ACTIVE_PROFILES,
|
||||
INSTANCES,
|
||||
DEFAULT_PATH,
|
||||
TAGS
|
||||
|
||||
@@ -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<String> implements Deletable, AppContext, Styleable, ElementStateListener, JmxConnectable, LiveDataCapableElement {
|
||||
|
||||
@@ -457,6 +460,10 @@ public class GenericRemoteAppElement extends WrappingBootDashElement<String> imp
|
||||
return getRunStateExp().getValue();
|
||||
}
|
||||
|
||||
public ImmutableSet<String> getActiveProfiles() {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
private LiveExpression<RunState> getRunStateExp() {
|
||||
return jmxRunStateTracker.augmentedRunState;
|
||||
}
|
||||
@@ -681,6 +688,7 @@ public class GenericRemoteAppElement extends WrappingBootDashElement<String> imp
|
||||
private LiveExpression<Failable<ImmutableList<RequestMapping>>> liveRequestMappings;
|
||||
private LiveExpression<Failable<LiveEnvModel>> liveEnv;
|
||||
private LiveExpression<Failable<LiveBeansModel>> liveBeans;
|
||||
private LiveExpression<Failable<ImmutableSet<String>>> liveProfiles;
|
||||
|
||||
@Override
|
||||
public Failable<ImmutableList<RequestMapping>> getLiveRequestMappings() {
|
||||
@@ -715,6 +723,43 @@ public class GenericRemoteAppElement extends WrappingBootDashElement<String> imp
|
||||
return liveRequestMappings.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Failable<ImmutableSet<String>> getLiveProfiles() {
|
||||
synchronized (this) {
|
||||
if (liveProfiles == null) {
|
||||
final LiveExpression<Set<String>> actuatorUrls = getActuatorUrls();
|
||||
liveProfiles = new AsyncLiveExpression<>(Failable.error(MissingLiveInfoMessages.NOT_YET_COMPUTED), "Fetch active profiles for '"+getStyledName(null).getString()+"'") {
|
||||
@Override
|
||||
protected Failable<ImmutableSet<String>> compute() {
|
||||
Set<String> 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<LiveEnvModel> getLiveEnv() {
|
||||
synchronized (this) {
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user