From b07f3b0124015794b8f9ed6e1c00e3f57ed97183 Mon Sep 17 00:00:00 2001 From: Kris De Volder Date: Wed, 27 Mar 2019 16:03:51 -0700 Subject: [PATCH] Allow configuring urlScheme and port for remote apps --- .../boot/ls/BootLanguageServerPlugin.java | 8 ++-- .../DelegatingStreamConnectionProvider.java | 48 ++++++++++++++++++- .../boot/app/cli/LocalSpringBootApp.java | 5 ++ .../boot/app/cli/RemoteSpringBootApp.java | 19 ++++++-- .../commons/boot/app/cli/SpringBootApp.java | 1 + .../handlers/RemoteRunningAppsProvider.java | 39 ++++++++++++--- .../LiveAppURLSymbolProvider.java | 3 +- .../RequestMappingHoverProvider.java | 10 ++-- .../boot/java/requestmapping/UrlUtil.java | 25 ++++------ .../vscode-spring-boot/package.json | 12 ++++- 10 files changed, 134 insertions(+), 36 deletions(-) diff --git a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/BootLanguageServerPlugin.java b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/BootLanguageServerPlugin.java index d4ceff4e5..b4430f406 100644 --- a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/BootLanguageServerPlugin.java +++ b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/BootLanguageServerPlugin.java @@ -14,7 +14,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import org.apache.commons.lang3.tuple.Pair; import org.eclipse.jface.bindings.Binding; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.keys.IBindingService; @@ -97,9 +96,12 @@ public class BootLanguageServerPlugin extends AbstractUIPlugin { } } - private static LiveSetVariable> remoteBootApps = new LiveSetVariable<>(); + //Should support both older and current formats: + // - old format = org.apache.commons.lang3.tuple.Pair (jmxUrl,host) + // - new format = List containing upto 4 elements: jmxUrl, host, port, urlScheme. The last two are optional. + private static LiveSetVariable remoteBootApps = new LiveSetVariable<>(); - public static LiveSetVariable> getRemoteBootApps() { + public static LiveSetVariable getRemoteBootApps() { return remoteBootApps; } diff --git a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/DelegatingStreamConnectionProvider.java b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/DelegatingStreamConnectionProvider.java index 951417228..c9fd9ff1d 100644 --- a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/DelegatingStreamConnectionProvider.java +++ b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/DelegatingStreamConnectionProvider.java @@ -17,6 +17,7 @@ import java.net.URI; import java.nio.file.FileSystems; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -32,6 +33,7 @@ import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage; import org.eclipse.lsp4j.services.LanguageServer; import org.springframework.tooling.ls.eclipse.commons.LanguageServerCommonsActivator; import org.springsource.ide.eclipse.commons.livexp.core.ValueListener; +import org.springsource.ide.eclipse.commons.livexp.util.Log; import com.google.common.collect.ImmutableSet; @@ -53,7 +55,7 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi private LanguageServer languageServer; private final IPropertyChangeListener configListener = (e) -> sendConfiguration(); - private final ValueListener>> remoteAppsListener = (e, v) -> sendConfiguration(); + private final ValueListener> remoteAppsListener = (e, v) -> sendConfiguration(); public DelegatingStreamConnectionProvider() { LanguageServerCommonsActivator.logInfo("Entering DelegatingStreamConnectionProvider()"); @@ -137,6 +139,8 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi public class RemoteBootAppData { private String jmxurl; private String host; + private String urlScheme = "https"; + private String port = "443"; public RemoteBootAppData(String jmxurl, String host) { super(); this.jmxurl = jmxurl; @@ -154,6 +158,18 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi 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; + } } private void sendConfiguration() { @@ -173,7 +189,7 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi bootJavaObj.put("remote-apps", BootLanguageServerPlugin.getRemoteBootApps().getValues() .stream() - .map(pair -> new RemoteBootAppData(pair.getLeft(), pair.getRight())) + .map(this::parseData) .collect(Collectors.toList()) ); @@ -181,5 +197,33 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi this.languageServer.getWorkspaceService().didChangeConfiguration(new DidChangeConfigurationParams(settings)); } + + @SuppressWarnings("unchecked") + private RemoteBootAppData parseData(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 pair = (Pair) incomingData; + return new RemoteBootAppData(pair.getLeft(), pair.getRight()); + } else if (incomingData instanceof List) { + //Format since STS 4.2.0 + List list = (List) incomingData; + RemoteBootAppData app = new RemoteBootAppData(list.get(0), list.get(1)); + if (list.size()>=3) { + String portStr = list.get(2); + if (portStr!=null) { + app.setPort(portStr); + } + } + if (list.size()>=4) { + String urlScheme = list.get(3); + if (urlScheme!=null) { + app.setUrlScheme(urlScheme); + } + } + return app; + } + throw new IllegalArgumentException("Invalid remote app data: "+incomingData); + } } diff --git a/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/LocalSpringBootApp.java b/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/LocalSpringBootApp.java index 00527470a..90113c1a9 100644 --- a/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/LocalSpringBootApp.java +++ b/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/LocalSpringBootApp.java @@ -149,4 +149,9 @@ public class LocalSpringBootApp extends AbstractSpringBootApp { } super.dispose(); } + + @Override + public String getUrlScheme() throws Exception { + return "http"; + } } diff --git a/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/RemoteSpringBootApp.java b/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/RemoteSpringBootApp.java index 7ac7d00de..9fa35a21a 100644 --- a/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/RemoteSpringBootApp.java +++ b/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/RemoteSpringBootApp.java @@ -23,10 +23,13 @@ public class RemoteSpringBootApp extends AbstractSpringBootApp { private String jmxUrl; private String host = null; private String port = "443"; + private String urlScheme = "https"; - protected RemoteSpringBootApp(String jmxUrl, String host) { + protected RemoteSpringBootApp(String jmxUrl, String host, String port, String urlScheme) { this.jmxUrl = jmxUrl; this.host = host; + this.port = port; + this.urlScheme = urlScheme; } public void setHost(String host) { @@ -91,8 +94,18 @@ public class RemoteSpringBootApp extends AbstractSpringBootApp { return "Unknown"; } - public static SpringBootApp create(String jmxUrl, String host) { - return MemoizingProxy.create(RemoteSpringBootApp.class, Duration.ofMillis(4900), new Class[] {String.class, String.class}, jmxUrl, host); + public static SpringBootApp create(String jmxUrl, String host, String port, String urlScheme) { + return MemoizingProxy.create(RemoteSpringBootApp.class, Duration.ofMillis(4900), new Class[] {String.class, String.class, String.class, String.class}, + jmxUrl, host, port, urlScheme); + } + + @Override + public String getUrlScheme() { + return urlScheme; + } + + public void setUrlScheme(String urlScheme) { + this.urlScheme = urlScheme; } } diff --git a/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/SpringBootApp.java b/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/SpringBootApp.java index 0bf0c0554..45e9495b9 100644 --- a/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/SpringBootApp.java +++ b/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/SpringBootApp.java @@ -29,6 +29,7 @@ public interface SpringBootApp extends Disposable { String getProcessID(); String getHost() throws Exception; String getPort() throws Exception; + String getUrlScheme() throws Exception; String getContextPath() throws Exception; boolean hasUsefulJmxBeans(); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/RemoteRunningAppsProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/RemoteRunningAppsProvider.java index 818d29ca5..0505a22c2 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/RemoteRunningAppsProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/handlers/RemoteRunningAppsProvider.java @@ -32,6 +32,8 @@ public class RemoteRunningAppsProvider implements RunningAppProvider { public static class RemoteBootAppData { private String jmxurl; private String host; + private String urlScheme = "https"; + private String port = "443"; public String getJmxurl() { return jmxurl; @@ -45,12 +47,31 @@ public class RemoteRunningAppsProvider implements RunningAppProvider { 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; + } + @Override + public String toString() { + return "RemoteBootAppData [jmxurl=" + jmxurl + ", host=" + host + ", urlScheme=" + urlScheme + ", port=" + + port + "]"; + } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((host == null) ? 0 : host.hashCode()); result = prime * result + ((jmxurl == null) ? 0 : jmxurl.hashCode()); + result = prime * result + ((port == null) ? 0 : port.hashCode()); + result = prime * result + ((urlScheme == null) ? 0 : urlScheme.hashCode()); return result; } @Override @@ -72,14 +93,18 @@ public class RemoteRunningAppsProvider implements RunningAppProvider { return false; } else if (!jmxurl.equals(other.jmxurl)) return false; + if (port == null) { + if (other.port != null) + return false; + } else if (!port.equals(other.port)) + return false; + if (urlScheme == null) { + if (other.urlScheme != null) + return false; + } else if (!urlScheme.equals(other.urlScheme)) + return false; return true; } - @Override - public String toString() { - return "RemoteBootAppData [jmxurl=" + jmxurl + ", host=" + host + "]"; - } - - } private static Logger logger = LoggerFactory.getLogger(RemoteRunningAppsProvider.class); @@ -124,7 +149,7 @@ public class RemoteRunningAppsProvider implements RunningAppProvider { for (RemoteBootAppData key : newAppData) { remoteAppInstances.computeIfAbsent(key, (_key) -> { logger.info("Creating RemoteStringBootApp: "+_key); - return RemoteSpringBootApp.create(key.getJmxurl(), key.getHost()); + return RemoteSpringBootApp.create(key.getJmxurl(), key.getHost(), key.getPort(), key.getUrlScheme()); }); } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/LiveAppURLSymbolProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/LiveAppURLSymbolProvider.java index 063c7ce5c..5cf80e461 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/LiveAppURLSymbolProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/LiveAppURLSymbolProvider.java @@ -42,12 +42,13 @@ public class LiveAppURLSymbolProvider { SpringBootApp[] runningApps = runningAppProvider.getAllRunningSpringApps().toArray(new SpringBootApp[0]); for (SpringBootApp app : runningApps) { try { + String urlScheme = app.getUrlScheme(); String host = app.getHost(); String port = app.getPort(); String contextPath = app.getContextPath(); Stream urls = app.getRequestMappings().stream() .flatMap(rm -> Arrays.stream(rm.getSplitPath())) - .map(path -> UrlUtil.createUrl(host, port, path, contextPath)); + .map(path -> UrlUtil.createUrl(urlScheme, host, port, path, contextPath)); urls.forEach(url -> result.add(new SymbolInformation(url, SymbolKind.Method, new Location(url, new Range(new Position(0, 0), new Position(0, 1)))))); } catch (Exception e) { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/RequestMappingHoverProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/RequestMappingHoverProvider.java index 34c242561..0cdd0f740 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/RequestMappingHoverProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/RequestMappingHoverProvider.java @@ -229,6 +229,7 @@ public class RequestMappingHoverProvider implements HoverProvider { SpringBootApp app = mappingMethod.getT2(); String contextPath = app.getContextPath(); + String urlScheme = app.getUrlScheme(); String port = app.getPort(); String host = app.getHost(); @@ -241,7 +242,7 @@ public class RequestMappingHoverProvider implements HoverProvider { paths = new String[] {""}; } for (String path : paths) { - String url = UrlUtil.createUrl(host, port, path, contextPath); + String url = UrlUtil.createUrl(urlScheme, host, port, path, contextPath); urls.add(url); } } @@ -255,8 +256,9 @@ public class RequestMappingHoverProvider implements HoverProvider { Tuple2 mappingMethod = mappingMethods.get(i); SpringBootApp app = mappingMethod.getT2(); - String port = mappingMethod.getT2().getPort(); - String host = mappingMethod.getT2().getHost(); + String urlScheme = app.getUrlScheme(); + String port = app.getPort(); + String host = app.getHost(); String[] paths = mappingMethod.getT1().getSplitPath(); if (paths==null || paths.length==0) { @@ -268,7 +270,7 @@ public class RequestMappingHoverProvider implements HoverProvider { } String contextPath = app.getContextPath(); List renderableUrls = Arrays.stream(paths).flatMap(path -> { - String url = UrlUtil.createUrl(host, port, path, contextPath); + String url = UrlUtil.createUrl(urlScheme, host, port, path, contextPath); return Stream.of(Renderables.link(url, url), Renderables.lineBreak()); }) .collect(Collectors.toList()); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/UrlUtil.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/UrlUtil.java index 83bcf91d9..6dd1c21ba 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/UrlUtil.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/requestmapping/UrlUtil.java @@ -16,11 +16,6 @@ import com.google.common.collect.ImmutableSet; public class UrlUtil { - private static final ImmutableSet LOCALHOST_ALIASES = ImmutableSet.of( - "localhost", - "127.0.0.1" - ); - /** * Creates http URL string based on host, port and path * @param host @@ -29,7 +24,7 @@ public class UrlUtil { * @param contextPath * @return the resultant URL */ - public static String createUrl(String host, String port, String path, String contextPath) { + public static String createUrl(String urlScheme, String host, String port, String path, String contextPath) { if (path==null) { path = ""; } @@ -44,16 +39,16 @@ public class UrlUtil { } path = contextPath + path; } - if ("80".equals(port)) { - return "http://"+host+path; - } else if ("443".equals(port)) { - return "https://"+host+path; + String defaultPort = ""; + if (urlScheme.equals("http")) { + defaultPort = "80"; + } else if (urlScheme.equals("https")) { + defaultPort = "443"; + } + if (defaultPort.equals(port)) { + return urlScheme+"://"+host+path; } else { - if (LOCALHOST_ALIASES.contains(host)) { - return "http://" + host + ":" + port + path; - } else { - return "https://" + host + ":" + port + path; - } + return urlScheme+"://"+ host + ":" + port +path; } } } diff --git a/vscode-extensions/vscode-spring-boot/package.json b/vscode-extensions/vscode-spring-boot/package.json index c7071bdd5..b8b7faff6 100644 --- a/vscode-extensions/vscode-spring-boot/package.json +++ b/vscode-extensions/vscode-spring-boot/package.json @@ -97,8 +97,18 @@ }, "host": { "type": "string" + }, + "urlScheme": { + "type": "string" + }, + "port": { + "type": "number" } - } + }, + "required": [ + "jmxurl", + "host" + ] }, "description": "Array of jmx urls pointing to remote spring boot applications to poll for live hover information. A typical url looks something like this: `service:jmx:rmi://localhost:9111/jndi/rmi://localhost:9111/jmxrmi`" },