Prefer connecting via JMX to process. New UI for show/refresh/hide

This commit is contained in:
aboyko
2024-04-02 10:31:23 -04:00
parent 88ae9318ed
commit eb3d46d400
28 changed files with 622 additions and 189 deletions

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="target/classes"/>

View File

@@ -9,8 +9,8 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul
org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
org.eclipse.jdt.core.compiler.compliance=17
org.eclipse.jdt.core.compiler.problem.APILeak=warning
org.eclipse.jdt.core.compiler.problem.annotatedTypeArgumentToUnannotated=info
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
@@ -109,4 +109,4 @@ org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=11
org.eclipse.jdt.core.compiler.source=17

View File

@@ -0,0 +1 @@
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512.008 512.008" xml:space="preserve" fill="#000000"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <g> <g> <path style="fill:#868491;" d="M280.01,464.008h-48c-4.422,0-8,3.578-8,8v8c0,17.648,14.352,32,32,32s32-14.352,32-32v-8 C288.01,467.586,284.432,464.008,280.01,464.008z"></path> </g> <g> <path style="fill:#5C546A;" d="M256.002,464.008H232.01c-4.422,0-8,3.578-8,8v8c0,17.646,14.347,31.995,31.992,31.999 L256.002,464.008L256.002,464.008z"></path> </g> <g> <path style="fill:#B4B6BC;" d="M381.983,49.895c-37.391-35.141-86.367-52.742-137.734-49.52 C150.639,6.2,75.014,84.286,72.092,178.149c-2.156,69.547,34.375,133.578,95.344,167.117c15.156,8.344,24.57,24.367,24.57,41.828 v60.914c0,17.648,14.352,32,32,32h64c17.648,0,32-14.352,32-32v-60.914c0-17.445,9.484-33.508,24.766-41.93 c58.742-32.406,95.234-94.156,95.234-161.156C440.006,133.43,418.858,84.547,381.983,49.895z"></path> </g> <g> <circle style="fill:#FFFFFF;" cx="256.002" cy="184.008" r="128"></circle> </g> <g> <g> <path style="fill:#868491;" d="M283.986,232.008c-10.633,0-16.07-6.203-20.031-10.727c-3.492-3.984-4.883-5.273-8-5.273 c-3.102,0-4.484,1.289-7.961,5.266c-3.734,4.273-9.383,10.734-20.016,10.734c-10.625,0-16.273-6.461-20.008-10.734 c-3.477-3.977-4.859-5.266-7.961-5.266c-4.422,0-8-3.578-8-8s3.578-8,8-8c10.625,0,16.273,6.461,20.008,10.734 c3.477,3.977,4.859,5.266,7.961,5.266s4.492-1.289,7.969-5.266c3.734-4.273,9.383-10.734,20.008-10.734 c10.633,0,16.07,6.203,20.031,10.727c3.492,3.984,4.883,5.273,8,5.273c3.109,0,4.5-1.289,7.992-5.266 c3.742-4.273,9.391-10.734,20.031-10.734c4.422,0,8,3.578,8,8s-3.578,8-8,8c-3.117,0-4.508,1.289-8,5.273 C300.267,225.555,294.619,232.008,283.986,232.008z"></path> </g> </g> <g> <g> <path style="fill:#5C546A;" d="M232.002,384.008c-3.68,0-6.992-2.555-7.813-6.297l-40-184c-0.938-4.32,1.805-8.578,6.117-9.523 c4.344-0.953,8.578,1.805,9.523,6.117l40,184c0.938,4.32-1.805,8.578-6.117,9.523 C233.135,383.954,232.564,384.008,232.002,384.008z"></path> </g> </g> <g> <g> <path style="fill:#5C546A;" d="M280.017,384.008c-0.563,0-1.133-0.055-1.711-0.18c-4.313-0.945-7.055-5.203-6.117-9.523l40-184 c0.945-4.313,5.164-7.063,9.523-6.117c4.313,0.945,7.055,5.203,6.117,9.523l-40,184 C287.01,381.454,283.697,384.008,280.017,384.008z"></path> </g> </g> <g> <path style="fill:#B4B6BC;" d="M190.633,376.008c0.851,3.593,1.374,7.293,1.374,11.086v60.914c0,17.648,14.352,32,32,32h64 c17.648,0,32-14.352,32-32v-60.914c0-3.79,0.527-7.491,1.384-11.086H190.633z"></path> </g> <g> <path style="fill:#868491;" d="M256.002,376.008h-65.369c0.851,3.593,1.374,7.293,1.374,11.086v60.914c0,17.648,14.352,32,32,32 h31.995V376.008z"></path> </g> <g> <g> <rect x="256.002" y="400.008" style="fill:#868491;" width="64" height="16"></rect> </g> </g> <g> <g> <rect x="256.006" y="432.008" style="fill:#868491;" width="64" height="16"></rect> </g> </g> <g> <g> <rect x="192.002" y="400.008" style="fill:#5C546A;" width="64" height="16"></rect> </g> </g> <g> <g> <rect x="192.002" y="432.008" style="fill:#5C546A;" width="64" height="16"></rect> </g> </g> </g> </g></svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 512.008 512.008" xml:space="preserve">
<g>
<g>
<path style="fill:#868491;" d="M280.01,464.008h-48c-4.422,0-8,3.578-8,8v8c0,17.648,14.352,32,32,32s32-14.352,32-32v-8
C288.01,467.586,284.432,464.008,280.01,464.008z"/>
</g>
<g>
<path style="fill:#5C546A;" d="M256.002,464.008H232.01c-4.422,0-8,3.578-8,8v8c0,17.646,14.347,31.995,31.992,31.999
L256.002,464.008L256.002,464.008z"/>
</g>
<g>
<path style="fill:#FFCD00;" d="M381.983,49.895c-37.391-35.141-86.367-52.742-137.734-49.52
C150.639,6.2,75.014,84.286,72.092,178.149c-2.156,69.547,34.375,133.578,95.344,167.117c15.156,8.344,24.57,24.367,24.57,41.828
v60.914c0,17.648,14.352,32,32,32h64c17.648,0,32-14.352,32-32v-60.914c0-17.445,9.484-33.508,24.766-41.93
c58.742-32.406,95.234-94.156,95.234-161.156C440.006,133.43,418.858,84.547,381.983,49.895z"/>
</g>
<g>
<circle style="fill:#FFE671;" cx="256.002" cy="184.008" r="128"/>
</g>
<g>
<g>
<path style="fill:#FFFFFF;" d="M283.986,232.008c-10.633,0-16.07-6.203-20.031-10.727c-3.492-3.984-4.883-5.273-8-5.273
c-3.102,0-4.484,1.289-7.961,5.266c-3.734,4.273-9.383,10.734-20.016,10.734c-10.625,0-16.273-6.461-20.008-10.734
c-3.477-3.977-4.859-5.266-7.961-5.266c-4.422,0-8-3.578-8-8s3.578-8,8-8c10.625,0,16.273,6.461,20.008,10.734
c3.477,3.977,4.859,5.266,7.961,5.266s4.492-1.289,7.969-5.266c3.734-4.273,9.383-10.734,20.008-10.734
c10.633,0,16.07,6.203,20.031,10.727c3.492,3.984,4.883,5.273,8,5.273c3.109,0,4.5-1.289,7.992-5.266
c3.742-4.273,9.391-10.734,20.031-10.734c4.422,0,8,3.578,8,8s-3.578,8-8,8c-3.117,0-4.508,1.289-8,5.273
C300.267,225.555,294.619,232.008,283.986,232.008z"/>
</g>
</g>
<g>
<g>
<path style="fill:#5C546A;" d="M232.002,384.008c-3.68,0-6.992-2.555-7.813-6.297l-40-184c-0.938-4.32,1.805-8.578,6.117-9.523
c4.344-0.953,8.578,1.805,9.523,6.117l40,184c0.938,4.32-1.805,8.578-6.117,9.523
C233.135,383.954,232.564,384.008,232.002,384.008z"/>
</g>
</g>
<g>
<g>
<path style="fill:#5C546A;" d="M280.017,384.008c-0.563,0-1.133-0.055-1.711-0.18c-4.313-0.945-7.055-5.203-6.117-9.523l40-184
c0.945-4.313,5.164-7.063,9.523-6.117c4.313,0.945,7.055,5.203,6.117,9.523l-40,184
C287.01,381.454,283.697,384.008,280.017,384.008z"/>
</g>
</g>
<g>
<path style="fill:#B4B6BC;" d="M190.633,376.008c0.851,3.593,1.374,7.293,1.374,11.086v60.914c0,17.648,14.352,32,32,32h64
c17.648,0,32-14.352,32-32v-60.914c0-3.79,0.527-7.491,1.384-11.086H190.633z"/>
</g>
<g>
<path style="fill:#868491;" d="M256.002,376.008h-65.369c0.851,3.593,1.374,7.293,1.374,11.086v60.914c0,17.648,14.352,32,32,32
h31.995V376.008z"/>
</g>
<g>
<g>
<rect x="256.002" y="400.008" style="fill:#868491;" width="64" height="16"/>
</g>
</g>
<g>
<g>
<rect x="256.006" y="432.008" style="fill:#868491;" width="64" height="16"/>
</g>
</g>
<g>
<g>
<rect x="192.002" y="400.008" style="fill:#5C546A;" width="64" height="16"/>
</g>
</g>
<g>
<g>
<rect x="192.002" y="432.008" style="fill:#5C546A;" width="64" height="16"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2015, 2022 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
@@ -10,7 +10,6 @@
*******************************************************************************/
package org.springframework.ide.eclipse.boot.dash;
import java.time.Duration;
import java.util.Arrays;
import java.util.Map;
@@ -23,6 +22,7 @@ import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.ui.plugin.AbstractUIPlugin;
@@ -36,15 +36,12 @@ import org.springframework.ide.eclipse.boot.dash.model.BootDashModelContext;
import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel;
import org.springframework.ide.eclipse.boot.dash.model.DefaultBootDashModelContext;
import org.springframework.ide.eclipse.boot.dash.model.LocalBootDashModel;
import org.springframework.ide.eclipse.boot.dash.model.RunState;
import org.springframework.ide.eclipse.boot.dash.model.RunTargets;
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.springsource.ide.eclipse.commons.livexp.util.Log;
import reactor.core.publisher.Mono;
/**
* The activator class controls the plug-in life cycle
*/
@@ -195,35 +192,46 @@ public class BootDashActivator extends AbstractUIPlugin {
@Override
public void stateChanged(ILaunchConfiguration owner) {
if (BootLaunchConfigurationDelegate.getEnableJmx(owner) && BootLaunchConfigurationDelegate.getAutoConnect(owner)) {
if (BootLaunchConfigurationDelegate.getEnableJmx(owner)) {
IJavaProject project = JavaCore.create(BootLaunchConfigurationDelegate.getProject(owner));
try {
if (project != null && Arrays.stream(project.getResolvedClasspath(true)).anyMatch(BootPropertyTester::isActuatorJar)) {
LocalBootDashModel localModel = (LocalBootDashModel) getModel().getSectionByTargetId(RunTargets.LOCAL.getId());
LaunchConfRunStateTracker tracker = localModel.getLaunchConfRunStateTracker();
RunState state = tracker.getState(owner);
if (state == RunState.RUNNING || state == RunState.DEBUGGING) {
switch (tracker.getState(owner)) {
case RUNNING:
case DEBUGGING:
for (ILaunch l : DebugPlugin.getDefault().getLaunchManager().getLaunches()) {
if (l.getLaunchConfiguration() == owner) {
for (IProcess p : l.getProcesses()) {
String pid = p.getAttribute(IProcess.ATTR_PROCESS_ID);
if (pid != null) {
CommandInfo cmd = new CommandInfo("sts/livedata/connect",
Map.of("processKey", pid));
// The delay seems to be necessary for the moment. Although the process is created VM attach API may not work at early stages of the process run.
// "VirtualMachine.list()" call may not list the newly created process which means the process is gone and triggers disconnect.
// If lifecycle management is enabled the ready state seem to be a great indicator of a boot process fully started.
// TODO: explore health endpoint perhaps instead of ready state under Admin endpoint.
// Flux.fromIterable(servers).flatMap(s -> Mono.delay(Duration.ofMillis(500)).then(s.executeCommand(cmd))).subscribe();
Mono.delay(Duration.ofMillis(500)).then(LiveProcessCommandsExecutor.getDefault().executeCommand(cmd)).subscribe();
CommandInfo cmd = new CommandInfo("sts/livedata/localAdd", Map.of(
"host", "127.0.0.1",
"port", l.getAttribute(BootLaunchConfigurationDelegate.JMX_PORT),
"urlScheme", "http",
"jmxurl", "service:jmx:rmi:///jndi/rmi://127.0.0.1:%s/jmxrmi".formatted(l.getAttribute(BootLaunchConfigurationDelegate.JMX_PORT)),
"manualConnect", !BootLaunchConfigurationDelegate.getAutoConnect(owner),
"processId", pid,
"processName", owner.getAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, p.getLabel()),
"projectName", project.getProject().getName()
));
LiveProcessCommandsExecutor.getDefault().executeCommand(cmd).subscribe();
}
}
}
}
break;
case INACTIVE:
for (ILaunch l : DebugPlugin.getDefault().getLaunchManager().getLaunches()) {
if (l.getLaunchConfiguration() == owner && l.getAttribute(BootLaunchConfigurationDelegate.JMX_PORT) != null) {
String jmxUrl = "service:jmx:rmi:///jndi/rmi://127.0.0.1:%s/jmxrmi".formatted(l.getAttribute(BootLaunchConfigurationDelegate.JMX_PORT));
LiveProcessCommandsExecutor.getDefault().executeCommand("sts/livedata/localRemove", jmxUrl).subscribe();
}
}
default:
}
}
} catch (Exception e) {
getLog().error("Failed to connect to Boot app", e);

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2019 Pivotal Software, Inc.
* Copyright (c) 2019, 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
@@ -16,9 +16,9 @@ import java.util.Map.Entry;
public class CommandInfo {
public final String command;
public final Map<String,String> info;
public final Map<String,?> info;
public CommandInfo(String command, Map<String, String> info) {
public CommandInfo(String command, Map<String, ?> info) {
super();
this.command = command;
this.info = info;
@@ -27,7 +27,7 @@ public class CommandInfo {
@Override
public String toString() {
StringBuilder s = new StringBuilder("CommandInfo("+command+", {\n");
for (Entry<String, String> e : info.entrySet()) {
for (Entry<String, ?> e : info.entrySet()) {
s.append(" "+e.getKey() +": "+e.getValue()+"\n");
}
s.append("})");

View File

@@ -57,4 +57,12 @@ public final class DefaultLiveProcessCommandExecutor implements LiveProcessComma
))).thenAccept(l -> {}));
}
@Override
public Mono<Void> executeCommand(String command, Object... params) {
return Mono.fromFuture(BootLsCommandUtils.getLanguageServers(command).collectAll(ls -> ls.getWorkspaceService().executeCommand(new ExecuteCommandParams(
command,
ImmutableList.of(params)
))).thenAccept(l -> {}));
}
}

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2019, 2023 Pivotal Software, Inc.
* Copyright (c) 2019, 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
@@ -77,15 +77,24 @@ public class LiveDataConnectionManagementActions extends AbstractDisposable impl
public ExecuteCommandAction(CommandInfo commandInfo) {
super(params);
this.commandInfo = commandInfo;
String command = commandInfo.command;
int lastSlash = command.lastIndexOf("/");
String humanReadableCommand = command.substring(lastSlash+1);
humanReadableCommand = humanReadableCommand.substring(0, 1).toUpperCase() + humanReadableCommand.substring(1);
this.projectName = commandInfo.info.get("projectName");
label = humanReadableCommand + " "+commandInfo.info.get("label");
this.projectName = (String) commandInfo.info.get("projectName");
label = computeLabel(commandInfo);
this.setText(label);
}
private String computeLabel(CommandInfo commandInfo) {
switch (commandInfo.command) {
case "sts/livedata/connect":
return "Show Live Data from: %s".formatted(commandInfo.info.get("label"));
case "sts/livedata/refresh":
return "Refresh Live Data from: %s".formatted(commandInfo.info.get("label"));
case "sts/livedata/disconnect":
return "Hide Live Data from: %s".formatted(commandInfo.info.get("label"));
default:
}
return (String) commandInfo.info.get("label");
}
public String getProjectName() {
return projectName;
}
@@ -115,7 +124,7 @@ public class LiveDataConnectionManagementActions extends AbstractDisposable impl
}
public String getProcessId() {
return commandInfo.info.get("processId");
return (String) commandInfo.info.get("processId");
}
}

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2019, 2023 Pivotal Software, Inc.
* Copyright (c) 2019, 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
@@ -17,6 +17,7 @@ public interface LiveProcessCommandsExecutor {
Flux<CommandInfo> listCommands();
Mono<Void> executeCommand(CommandInfo cmd);
Mono<Void> executeCommand(String command, Object... params);
static LiveProcessCommandsExecutor getDefault() {
return new DefaultLiveProcessCommandExecutor();