Adapt boot.ls and manifest.ls for refactored boot.dash.cf api

This commit is contained in:
Kris De Volder
2020-02-05 15:18:46 -08:00
parent 74d8aef562
commit 83e84e5863
10 changed files with 124 additions and 161 deletions

View File

@@ -26,10 +26,11 @@ Require-Bundle: org.eclipse.jdt.launching;bundle-version="3.9.0",
org.springsource.ide.eclipse.commons.livexp,
org.apache.commons.lang3,
org.eclipse.wst.sse.ui;bundle-version="1.5.0";resolution:=optional,
org.json;bundle-version="1.0.0",
org.eclipse.jdt.annotation,
org.eclipse.mylyn.wikitext.markdown,
org.eclipse.mylyn.wikitext
org.eclipse.mylyn.wikitext,
org.springframework.ide.eclipse.boot.dash;bundle-version="3.9.12",
com.google.gson
Import-Package: com.google.common.base,
com.google.common.collect,
com.google.gson;version="2.7.0",

View File

@@ -366,5 +366,11 @@
name="Spring - Live Process Information"
requiresUIAccess="false"/>
</extension>
<extension
point="org.springframework.ide.eclipse.boot.dash.injections">
<injection
class="org.springframework.tooling.boot.ls.BootDashInjections">
</injection>
</extension>
</plugin>

View File

@@ -0,0 +1,28 @@
/*******************************************************************************
* Copyright (c) 2019 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.tooling.boot.ls;
import org.springframework.ide.eclipse.boot.dash.di.EclipseBeanLoader;
import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext;
import org.springframework.ide.eclipse.boot.dash.model.DefaultBootDashModelContext;
import org.springframework.ide.eclipse.boot.dash.remoteapps.RemoteBootAppsDataHolder;
import org.springframework.tooling.boot.ls.prefs.RemoteAppsFromPrefsDataContributor;
/**
* Contributes bean definitions to {@link DefaultBootDashModelContext}
*/
public class BootDashInjections implements EclipseBeanLoader.Contribution {
@Override
public void applyBeanDefinitions(SimpleDIContext context) throws Exception {
context.defInstance(RemoteBootAppsDataHolder.Contributor.class, RemoteAppsFromPrefsDataContributor.INSTANCE);
}
}

View File

@@ -21,6 +21,7 @@ import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.keys.IBindingService;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import org.springframework.ide.eclipse.boot.dash.remoteapps.RemoteBootAppsDataHolder;
import org.springsource.ide.eclipse.commons.livexp.core.LiveSetVariable;
/**
@@ -101,14 +102,4 @@ public class BootLanguageServerPlugin extends AbstractUIPlugin {
});
}
}
//Should support both older and current formats:
// - old format = org.apache.commons.lang3.tuple.Pair<L, R><String,String> (jmxUrl,host)
// - new format = List<String> containing upto 4 elements: jmxUrl, host, port, urlScheme. The last two are optional.
private static LiveSetVariable<Object> remoteBootApps = new LiveSetVariable<>();
public static LiveSetVariable<Object> getRemoteBootApps() {
return remoteBootApps;
}
}

View File

@@ -16,6 +16,7 @@ import java.io.OutputStream;
import java.net.URI;
import java.nio.file.FileSystems;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
@@ -34,6 +35,8 @@ import org.eclipse.lsp4j.InitializeResult;
import org.eclipse.lsp4j.jsonrpc.messages.Message;
import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage;
import org.eclipse.lsp4j.services.LanguageServer;
import org.springframework.ide.eclipse.boot.dash.remoteapps.RemoteBootAppsDataHolder;
import org.springframework.ide.eclipse.boot.dash.remoteapps.RemoteBootAppsDataHolder.RemoteAppData;
import org.springframework.tooling.boot.ls.prefs.RemoteAppsPrefs;
import org.springframework.tooling.ls.eclipse.commons.LanguageServerCommonsActivator;
import org.springsource.ide.eclipse.commons.livexp.core.ValueListener;
@@ -60,12 +63,10 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
private ResourceListener fResourceListener;
private LanguageServer languageServer;
private final IPropertyChangeListener configListener = (e) -> sendConfiguration();
private final ValueListener<ImmutableSet<Object>> remoteAppsListener = (e, v) -> sendConfiguration();
private final ValueListener<ImmutableSet<RemoteAppData>> remoteAppsListener = (e, v) -> sendConfiguration();
private long timestampBeforeStart;
private long timestampWhenInitialized;
private Disposable remoteAppsPrefsListener;
public DelegatingStreamConnectionProvider() {
LanguageServerCommonsActivator.logInfo("Entering DelegatingStreamConnectionProvider()");
@@ -90,7 +91,6 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
public void start() throws IOException {
this.timestampBeforeStart = System.currentTimeMillis();
this.provider.start();
this.remoteAppsPrefsListener = RemoteAppsPrefs.addListener(this::sendConfiguration);
}
@Override
@@ -115,12 +115,7 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
ResourcesPlugin.getWorkspace().removeResourceChangeListener(fResourceListener);
fResourceListener = null;
}
BootLanguageServerPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(configListener);
BootLanguageServerPlugin.getRemoteBootApps().removeListener(remoteAppsListener);
if (remoteAppsPrefsListener!=null) {
remoteAppsPrefsListener.dispose();
remoteAppsPrefsListener = null;
}
RemoteBootAppsDataHolder.getDefault().getRemoteApps().removeListener(remoteAppsListener);
}
@Override
@@ -133,11 +128,6 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
this.timestampWhenInitialized = System.currentTimeMillis();
LanguageServerCommonsActivator.logInfo("Boot LS startup time from start to initialized: " + (timestampWhenInitialized - timestampBeforeStart) + "ms");
sendConfiguration();
// Add config listener
BootLanguageServerPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(configListener);
// Add resource listener
ResourcesPlugin.getWorkspace().addResourceChangeListener(fResourceListener = new ResourceListener(languageServer, Arrays.asList(
FileSystems.getDefault().getPathMatcher("glob:**/pom.xml"),
@@ -150,81 +140,11 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
)));
//Add remote boot apps listener
BootLanguageServerPlugin.getRemoteBootApps().addListener(remoteAppsListener);
RemoteBootAppsDataHolder.getDefault().getRemoteApps().addListener(remoteAppsListener);
}
}
}
public class RemoteBootAppData {
private String jmxurl;
private String host;
private String urlScheme = "https";
private String port = "443";
private boolean keepChecking = true;
//keepChecking defaults to true. Boot dash automatic remote apps should override this explicitly.
//Reason. All other 'sources' of remote apps are 'manual' and we want them to default to
//'keepChecking' even if the user doesn't set this to true manually.
private String processId = null;
public RemoteBootAppData() {
}
public RemoteBootAppData(String jmxurl, String host) {
super();
this.jmxurl = jmxurl;
this.host = host;
}
public String getJmxurl() {
return jmxurl;
}
public void setJmxurl(String jmxurl) {
this.jmxurl = jmxurl;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getUrlScheme() {
return urlScheme;
}
public void setUrlScheme(String urlScheme) {
this.urlScheme = urlScheme;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
public boolean isKeepChecking() {
return keepChecking;
}
public void setKeepChecking(boolean keepChecking) {
this.keepChecking = keepChecking;
}
public String getProcessId() {
return processId;
}
public void getProcessId(String processId) {
this.processId = processId;
}
}
private void sendConfiguration() {
Map<String, Object> settings = new HashMap<>();
@@ -259,8 +179,7 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
bootJavaObj.put("change-detection", bootChangeDetection);
bootJavaObj.put("scan-java-test-sources", scanTestJavaSources);
bootJavaObj.put("remote-apps", getAllRemoteApps()
);
bootJavaObj.put("remote-apps", getAllRemoteApps());
settings.put("boot-java", bootJavaObj);
@@ -270,30 +189,21 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
/**
* Combines remote boot app data from all configuration sources.
*/
protected List<RemoteBootAppData> getAllRemoteApps() {
ImmutableSet<Object> fromBootDash = BootLanguageServerPlugin.getRemoteBootApps().getValues();
List<List<String>> fromUserPrefs = new RemoteAppsPrefs().getRemoteAppData();
Set<Object> combined = new LinkedHashSet<>();
combined.addAll(fromBootDash);
combined.addAll(fromUserPrefs);
return combined
.stream()
.map(this::parseData)
.collect(Collectors.toList());
protected Collection<RemoteAppData> getAllRemoteApps() {
return RemoteBootAppsDataHolder.getDefault().getRemoteApps().getValues();
}
@SuppressWarnings("unchecked")
private RemoteBootAppData parseData(Object incomingData) {
private RemoteAppData parseLegacyData(Object incomingData) {
if (incomingData instanceof Pair) {
//Format prior to STS 4.2.0. Still supported to allows STS 3.9.8 and older to
// send data from its boot dash in the old format.
Pair<String,String> pair = (Pair<String, String>) incomingData;
return new RemoteBootAppData(pair.getLeft(), pair.getRight());
return new RemoteAppData(pair.getLeft(), pair.getRight());
} else if (incomingData instanceof List) {
//Format since STS 4.2.0
List<String> list = (List<String>) incomingData;
RemoteBootAppData app = new RemoteBootAppData(list.get(0), list.get(1));
RemoteAppData app = new RemoteAppData(list.get(0), list.get(1));
if (list.size()>=3) {
String portStr = list.get(2);
if (portStr!=null) {
@@ -315,7 +225,7 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
} else if (incomingData instanceof Map) {
Gson gson = new Gson();
JsonElement tree = gson.toJsonTree(incomingData);
return gson.fromJson(tree, RemoteBootAppData.class);
return gson.fromJson(tree, RemoteAppData.class);
}
throw new IllegalArgumentException("Invalid remote app data: "+incomingData);
}

View File

@@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright (c) 2019 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.tooling.boot.ls.prefs;
import org.springframework.ide.eclipse.boot.dash.remoteapps.RemoteBootAppsDataHolder;
import org.springframework.ide.eclipse.boot.dash.remoteapps.RemoteBootAppsDataHolder.RemoteAppData;
import org.springsource.ide.eclipse.commons.livexp.core.ObservableSet;
import org.springsource.ide.eclipse.commons.livexp.ui.Disposable;
import com.google.common.collect.ImmutableSet;
public class RemoteAppsFromPrefsDataContributor implements RemoteBootAppsDataHolder.Contributor {
public static final RemoteAppsFromPrefsDataContributor INSTANCE = new RemoteAppsFromPrefsDataContributor();
private RemoteAppsPrefs prefs = new RemoteAppsPrefs();
private RemoteAppsFromPrefsDataContributor() {}
private ObservableSet<RemoteAppData> remoteApps = ObservableSet.create(() -> ImmutableSet.copyOf(prefs.getRemoteAppData()));
{
Disposable d = RemoteAppsPrefs.addListener(remoteApps::refresh);
//TODO: wire up disposing the above disposable.
//Note: at the time this code was written proper disposing wasn't done because the
//SimpleDIContext does not yet support it and ...
//This does not really matter because this data contributor is only a singleton.
}
@Override
public ObservableSet<RemoteAppData> getRemoteApps() {
return remoteApps;
}
}

View File

@@ -8,31 +8,26 @@
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.tooling.boot.ls.prefs;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.ide.eclipse.boot.dash.remoteapps.RemoteBootAppsDataHolder.RemoteAppData;
import org.springframework.tooling.boot.ls.BootLanguageServerPlugin;
import org.springsource.ide.eclipse.commons.livexp.ui.Disposable;
import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil;
import org.springsource.ide.eclipse.commons.livexp.util.Log;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.gson.Gson;
public class RemoteAppsPrefs {
public static final String REMOTE_APPS_KEY = "remote-apps";
private IEclipsePreferences prefs = BootLanguageServerPlugin.getPreferences();
private static final RemoteAppData[] NO_APPS = {};
private IEclipsePreferences prefs = BootLanguageServerPlugin.getPreferences();
public void setRawJson(String json) {
prefs.put(REMOTE_APPS_KEY, json);
}
@@ -41,43 +36,24 @@ public class RemoteAppsPrefs {
return prefs.get(REMOTE_APPS_KEY, "");
}
public List<List<String>> getRemoteAppData() {
public RemoteAppData[] getRemoteAppData() {
String json = getRawJson();
try {
return parse(json);
RemoteAppData[] parsed = parse(json);
if (parsed!=null) {
for (RemoteAppData remoteAppData : parsed) {
remoteAppData.setKeepChecking(true);
}
return parsed;
}
} catch (Exception e) {
Log.warn("Problem parsing manually configured boot remote apps data: "+ExceptionUtil.getMessage(e));
return ImmutableList.of();
}
return NO_APPS;
}
public static List<List<String>> parse(String json) throws JSONException {
Builder<List<String>> buider = ImmutableList.builder();
if (!json.trim().equals("")) {
JSONArray remoteApps = new JSONArray(json);
for (int i = 0; i < remoteApps.length(); i++) {
JSONObject app = remoteApps.getJSONObject(i);
String host = app.getString("host");
String jmxUrl = app.getString("jmxurl");
String port = app.optString("port");
String urlScheme = app.optString("urlScheme");
if (host!=null && jmxUrl!=null) {
//Not using ImmutableList because it doesn't allow null values in elements.
ArrayList<String> remoteApp = new ArrayList<>(4);
remoteApp.add(jmxUrl);
remoteApp.add(host);
if (urlScheme!=null) {
remoteApp.add(port); //could be null!
remoteApp.add(urlScheme);
} else if (host!=null) {
remoteApp.add(port);
//don't need to add urlScheme because we know it is null
}
buider.add(remoteApp);
}
}
}
return buider.build();
public static RemoteAppData[] parse(String json) {
return new Gson().fromJson(json, RemoteAppData[].class);
}
public static Disposable addListener(Runnable runnable) {
@@ -95,5 +71,4 @@ public class RemoteAppsPrefs {
private static IEclipsePreferences getPreferences() {
return BootLanguageServerPlugin.getPreferences();
}
}

View File

@@ -1,3 +1,13 @@
/*******************************************************************************
* Copyright (c) 2019 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.tooling.boot.ls.prefs;
import org.eclipse.jface.layout.GridDataFactory;

View File

@@ -21,7 +21,8 @@ Require-Bundle: org.eclipse.jdt.launching;bundle-version="3.8.0",
org.springframework.ide.eclipse.boot.dash,
org.springsource.ide.eclipse.commons.livexp,
io.projectreactor.reactor-core,
org.reactivestreams.reactive-streams
org.reactivestreams.reactive-streams,
org.springframework.ide.eclipse.boot.dash.cf;bundle-version="3.9.12"
Import-Package: org.eclipse.jface.preference,
org.osgi.framework
Export-Package: org.springframework.tooling.cloudfoundry.manifest.ls

View File

@@ -17,13 +17,13 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.springframework.ide.eclipse.boot.dash.BootDashActivator;
import org.springframework.ide.eclipse.boot.dash.cf.client.ClientRequests;
import org.springframework.ide.eclipse.boot.dash.cf.client.v2.DefaultClientRequestsV2;
import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryRunTarget;
import org.springframework.ide.eclipse.boot.dash.cf.runtarget.CloudFoundryTargetProperties;
import org.springframework.ide.eclipse.boot.dash.cloudfoundry.CfTargetsInfo;
import org.springframework.ide.eclipse.boot.dash.cloudfoundry.CfTargetsInfo.Target;
import org.springframework.ide.eclipse.boot.dash.cloudfoundry.CfTargetsInfo.TargetDiagnosticMessages;
import org.springframework.ide.eclipse.boot.dash.cloudfoundry.CloudFoundryRunTarget;
import org.springframework.ide.eclipse.boot.dash.cloudfoundry.CloudFoundryTargetProperties;
import org.springframework.ide.eclipse.boot.dash.cloudfoundry.client.ClientRequests;
import org.springframework.ide.eclipse.boot.dash.cloudfoundry.client.v2.DefaultClientRequestsV2;
import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel;
import org.springframework.ide.eclipse.boot.dash.model.RunTarget;
import org.springsource.ide.eclipse.commons.livexp.core.ValueListener;