Skip to content

Commit

Permalink
[gh-832] Auto-connect to boot app to fetch live data
Browse files Browse the repository at this point in the history
  • Loading branch information
BoykoAlex committed Sep 8, 2022
1 parent 7ea2e15 commit c51b97a
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -327,5 +327,11 @@
class="org.springframework.ide.eclipse.boot.dash.remoteapps.RemoteAppsFromBootDash">
</injection>
</extension>
<extension
point="org.eclipse.core.runtime.preferences">
<initializer
class="org.springframework.ide.eclipse.boot.dash.prefs.PrefsInitializer">
</initializer>
</extension>

</plugin>
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,42 @@
*******************************************************************************/
package org.springframework.ide.eclipse.boot.dash;

import java.time.Duration;
import java.util.List;
import java.util.Map;

import org.eclipse.core.net.proxy.IProxyService;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext;
import org.springframework.ide.eclipse.boot.dash.liveprocess.CommandInfo;
import org.springframework.ide.eclipse.boot.dash.liveprocess.LiveProcessCommandsExecutor;
import org.springframework.ide.eclipse.boot.dash.liveprocess.LiveProcessCommandsExecutor.Server;
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.Flux;
import reactor.core.publisher.Mono;

/**
* The activator class controls the plug-in life cycle
*/
Expand All @@ -32,6 +54,8 @@ public class BootDashActivator extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "org.springframework.ide.eclipse.boot.dash"; //$NON-NLS-1$

public static final String PREF_LIVE_INFORMATION_AUTO_CONNECT = "boot-java.live-information.automatic-connection.on";

public static final String DT_ICON_ID = "devttools";
public static final String MANIFEST_ICON = "manifest";
public static final String CLOUD_ICON = "cloud";
Expand Down Expand Up @@ -80,6 +104,7 @@ public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
new M2ELogbackCustomizer().schedule();
connectToLaunchedBootApps();
}

/*
Expand Down Expand Up @@ -166,4 +191,64 @@ public static IEclipsePreferences getPreferences() {
return InstanceScope.INSTANCE.getNode(PLUGIN_ID);
}

private final RunStateListener<ILaunchConfiguration> RUN_STATE_LISTENER = new RunStateListener<ILaunchConfiguration>() {

@Override
public void stateChanged(ILaunchConfiguration owner) {
if (BootLaunchConfigurationDelegate.getEnableJmx(owner)) {
LocalBootDashModel localModel = (LocalBootDashModel) getModel().getSectionByTargetId(RunTargets.LOCAL.getId());
LaunchConfRunStateTracker tracker = localModel.getLaunchConfRunStateTracker();
RunState state = tracker.getState(owner);
if (state == RunState.RUNNING || state == RunState.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) {
List<Server> servers = LiveProcessCommandsExecutor.getDefault()
.getLanguageServers();

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();

}
}
}
}
}

}
}
};

private void connectToLaunchedBootApps() {
updateRunStateListening();

getPreferenceStore().addPropertyChangeListener(new IPropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent event) {
if (PREF_LIVE_INFORMATION_AUTO_CONNECT.equals(event.getProperty())) {
updateRunStateListening();
}
}
});

}

private void updateRunStateListening() {
LocalBootDashModel localModel = (LocalBootDashModel) getModel().getSectionByTargetId(RunTargets.LOCAL.getId());
LaunchConfRunStateTracker tracker = localModel.getLaunchConfRunStateTracker();
if (getPreferenceStore().getBoolean(PREF_LIVE_INFORMATION_AUTO_CONNECT)) {
tracker.addListener(RUN_STATE_LISTENER);
} else {
tracker.removeListener(RUN_STATE_LISTENER);
}
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2019 Pivotal Software, Inc.
* Copyright (c) 2019, 2022 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
Expand Down Expand Up @@ -50,11 +50,10 @@ public Flux<CommandInfo> listCommands() {

@Override
public Mono<Void> executeCommand(CommandInfo cmd) {
return Mono.fromFuture(ls.getWorkspaceService().executeCommand(new ExecuteCommandParams(
return Mono.fromRunnable(() -> ls.getWorkspaceService().executeCommand(new ExecuteCommandParams(
cmd.command,
ImmutableList.of(cmd.info)
)))
.then();
)));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2020 Pivotal, Inc.
* Copyright (c) 2020, 2022 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
Expand Down Expand Up @@ -36,6 +36,7 @@ public void init(IWorkbench workbench) {
@Override
protected void createFieldEditors() {
Composite parent = getFieldEditorParent();
addField(new BooleanFieldEditor(BootDashActivator.PREF_LIVE_INFORMATION_AUTO_CONNECT, "Auto Connect to launched Boot app to show Live Information", parent));
for (RunTargetType rtt : BootDashActivator.getDefault().getModel().getRunTargetTypes()) {
if (rtt.supportsDeletion()) {
addField(new BooleanFieldEditor(DeleteElementsAction.PREF_SKIP_CONFIRM_DELETE(rtt), "Skip Delete Element Confirmation ("+rtt.getName()+")", parent));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*******************************************************************************
* 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.eclipse.boot.dash.prefs;

import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
import org.eclipse.jface.preference.IPreferenceStore;
import org.springframework.ide.eclipse.boot.dash.BootDashActivator;

public class PrefsInitializer extends AbstractPreferenceInitializer {

public PrefsInitializer() {
}

@Override
public void initializeDefaultPreferences() {
IPreferenceStore preferenceStore = BootDashActivator.getDefault().getPreferenceStore();
preferenceStore.setDefault(BootDashActivator.PREF_LIVE_INFORMATION_AUTO_CONNECT, true);
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017, 2019 Pivotal, Inc.
* Copyright (c) 2017, 2022 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
Expand Down Expand Up @@ -83,9 +83,6 @@ protected void createFieldEditors() {

addField(new BooleanFieldEditor(Constants.PREF_SCAN_JAVA_TEST_SOURCES, "Scan Java test sources", fieldEditorParent));

addField(new BooleanFieldEditor(Constants.PREF_LIVE_INFORMATION_AUTOMATIC_TRACKING_ENABLED, "Live Information - Automatic Process Tracking Enabled", fieldEditorParent));
addField(new StringFieldEditor(Constants.PREF_LIVE_INFORMATION_AUTOMATIC_TRACKING_DELAY, "Live Information - Automatic Process Tracking Delay in ms", fieldEditorParent));

addField(new StringFieldEditor(Constants.PREF_LIVE_INFORMATION_FETCH_DATA_RETRY_MAX_NO, "Live Information - Max number of retries (before giving up)", fieldEditorParent));
addField(new StringFieldEditor(Constants.PREF_LIVE_INFORMATION_FETCH_DATA_RETRY_DELAY_IN_SECONDS, "Live Information - Delay between retries in seconds", fieldEditorParent));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017, 2019 Pivotal, Inc.
* Copyright (c) 2017, 2022 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
Expand All @@ -17,9 +17,6 @@ public class Constants {

public static final String PLUGIN_ID = "org.springframework.tooling.boot.ls";

public static final String PREF_LIVE_INFORMATION_AUTOMATIC_TRACKING_ENABLED = "boot-java.live-information.automatic-tracking.on";
public static final String PREF_LIVE_INFORMATION_AUTOMATIC_TRACKING_DELAY = "boot-java.live-information.automatic-tracking.delay";

public static final String PREF_LIVE_INFORMATION_FETCH_DATA_RETRY_MAX_NO = "boot-java.live-information.fetch-data.max-retries";
public static final String PREF_LIVE_INFORMATION_FETCH_DATA_RETRY_DELAY_IN_SECONDS = "boot-java.live-information.fetch-data.retry-delay-in-seconds";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017, 2020 Pivotal, Inc.
* Copyright (c) 2017, 2022 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
Expand Down Expand Up @@ -156,7 +156,6 @@ private void sendConfiguration() {
Map<String, Object> settings = new HashMap<>();
Map<String, Object> bootJavaObj = new HashMap<>();
Map<String, Object> liveInformation = new HashMap<>();
Map<String, Object> liveInformationAutomaticTracking = new HashMap<>();
Map<String, Object> liveInformationFetchData = new HashMap<>();
Map<String, Object> supportXML = new HashMap<>();
Map<String, Object> bootChangeDetection = new HashMap<>();
Expand All @@ -166,13 +165,9 @@ private void sendConfiguration() {

IPreferenceStore preferenceStore = BootLanguageServerPlugin.getDefault().getPreferenceStore();

liveInformationAutomaticTracking.put("on", preferenceStore.getBoolean(Constants.PREF_LIVE_INFORMATION_AUTOMATIC_TRACKING_ENABLED));
liveInformationAutomaticTracking.put("delay", preferenceStore.getInt(Constants.PREF_LIVE_INFORMATION_AUTOMATIC_TRACKING_DELAY));

liveInformationFetchData.put("max-retries", preferenceStore.getInt(Constants.PREF_LIVE_INFORMATION_FETCH_DATA_RETRY_MAX_NO));
liveInformationFetchData.put("retry-delay-in-seconds", preferenceStore.getInt(Constants.PREF_LIVE_INFORMATION_FETCH_DATA_RETRY_DELAY_IN_SECONDS));

liveInformation.put("automatic-tracking", liveInformationAutomaticTracking);
liveInformation.put("fetch-data", liveInformationFetchData);

supportXML.put("on", preferenceStore.getBoolean(Constants.PREF_SUPPORT_SPRING_XML_CONFIGS));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017, 2019 Pivotal, Inc.
* Copyright (c) 2017, 2022 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
Expand Down Expand Up @@ -28,8 +28,6 @@ public PrefsInitializer() {
public void initializeDefaultPreferences() {
IPreferenceStore preferenceStore = BootLanguageServerPlugin.getDefault().getPreferenceStore();

preferenceStore.setDefault(Constants.PREF_LIVE_INFORMATION_AUTOMATIC_TRACKING_ENABLED, true);
preferenceStore.setDefault(Constants.PREF_LIVE_INFORMATION_AUTOMATIC_TRACKING_DELAY, 5000);
preferenceStore.setDefault(Constants.PREF_LIVE_INFORMATION_FETCH_DATA_RETRY_MAX_NO, 10);
preferenceStore.setDefault(Constants.PREF_LIVE_INFORMATION_FETCH_DATA_RETRY_DELAY_IN_SECONDS, 3);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.eclipse.lsp4j.ExecuteCommandParams;
import org.slf4j.Logger;
Expand Down

0 comments on commit c51b97a

Please sign in to comment.