diff --git a/headless-services/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CfJsonParamsProvider.java b/headless-services/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CfJsonParamsProvider.java index a6103105b..43ecf0553 100644 --- a/headless-services/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CfJsonParamsProvider.java +++ b/headless-services/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CfJsonParamsProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Pivotal, Inc. + * Copyright (c) 2017, 2018 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 @@ -37,12 +37,6 @@ public class CfJsonParamsProvider implements ClientParamsProvider { private static final String NO_NETWORK_CONNECTION = "No connection to Cloud Foundry"; private static final String NO_ORG_SPACE = "No org/space selected"; - private static final String TARGET = "Target"; - private static final String REFRESH_TOKEN = "RefreshToken"; - private static final String SSL_DISABLED = "SSLDisabled"; - private static final String ORG_NAME = "OrgName"; - private static final String SPACE_NAME = "SpaceName"; - private static final String PROP_NO_TARGETS_FOUND = "noTargetsFound"; private static final String PROP_UNAUTHORISED = "unauthorised"; private static final String PROP_NO_NETWORK_CONNECTION = "noNetworkConnection"; @@ -51,12 +45,11 @@ public class CfJsonParamsProvider implements ClientParamsProvider { private Supplier> paramsSupplier; private Map messages; - public CfJsonParamsProvider(List json, Map messages) { + public CfJsonParamsProvider(List targets, Map messages) { this.messages = messages; - this.paramsSupplier = Suppliers.memoize(() -> json + this.paramsSupplier = Suppliers.memoize(() -> targets .stream() - .filter(o -> o instanceof Map) - .map(m -> parseCfClientParams((Map)m)) + .map(t -> parseCfClientParams(t)) .filter(Objects::nonNull) .collect(Collectors.toList())); } @@ -70,23 +63,22 @@ public class CfJsonParamsProvider implements ClientParamsProvider { return params; } - private static CFClientParams parseCfClientParams(Map userData) { - String refreshToken = (String) userData.get(REFRESH_TOKEN); + private static CFClientParams parseCfClientParams(CfTargetsInfo.Target target) { + String refreshToken = target.getRefreshToken(); // Only support connecting to CF via refresh token for now if (StringUtil.hasText(refreshToken)) { CFCredentials credentials = CFCredentials.fromRefreshToken(refreshToken); - boolean sslDisabled = (Boolean) userData.get(SSL_DISABLED); - String target = (String) userData.get(TARGET); - String orgName = (String) userData.get(ORG_NAME); - String spaceName = (String) userData.get(SPACE_NAME); - if (target != null && StringUtil.hasText(orgName) && StringUtil.hasText(spaceName)) { - return new CFClientParams(target, null, credentials, orgName, spaceName, sslDisabled); + boolean sslDisabled = target.getSslDisabled(); + String api = target.getApi(); + String orgName = target.getOrg(); + String spaceName = target.getSpace(); + if (api != null && StringUtil.hasText(orgName) && StringUtil.hasText(spaceName)) { + return new CFClientParams(api, null, credentials, orgName, spaceName, sslDisabled); } } return null; } - @Override public CFParamsProviderMessages getMessages() { return new CFParamsProviderMessages() { diff --git a/headless-services/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CfTargetsInfo.java b/headless-services/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CfTargetsInfo.java new file mode 100644 index 000000000..b35fe53dd --- /dev/null +++ b/headless-services/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CfTargetsInfo.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2018 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal Software, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget; + +import java.util.List; +import java.util.Map; + +/** + * JSON-friendly representation of Cloud Foundry targets, used for integrations that need + * to serialise CF target information for transmission (e.g. between a client and server) + *

+ * WARNING: As this is used to serialise and deserialise between client and server, this exact type is used on both client and server. + * Therefore making changes to this class requires changes in the client side as well. For example, see the identical copy of this class in: + * org.springframework.ide.eclipse.boot.dash.cloudfoundry.CfTargetsInfo + * + */ +public class CfTargetsInfo { + + private List cfTargets; + private Map cfDiagnosticMessages; + + public List getCfTargets() { + return cfTargets; + } + + public void setCfTargets(List cfTargets) { + this.cfTargets = cfTargets; + } + + public Map getCfDiagnosticMessages() { + return this.cfDiagnosticMessages; + } + + public void setCfDiagnosticMessages(Map cfDiagnosticMessages) { + this.cfDiagnosticMessages = cfDiagnosticMessages; + } + + public static class Target { + private String api; + private String org; + private String space; + + private boolean sslDisabled; + private String refreshToken; + + public String getApi() { + return api; + } + + public void setApi(String api) { + this.api = api; + } + + public String getOrg() { + return org; + } + + public void setOrg(String org) { + this.org = org; + } + + public void setSpace(String space) { + this.space = space; + } + + public String getSpace() { + return space; + } + + public boolean getSslDisabled() { + return sslDisabled; + } + + public void setSslDisabled(boolean sslDisabled) { + this.sslDisabled = sslDisabled; + } + + public String getRefreshToken() { + return refreshToken; + } + + public void setRefreshToken(String refreshToken) { + this.refreshToken = refreshToken; + } + } +} diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/Settings.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/Settings.java index 7cb37eac9..aba146527 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/Settings.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/Settings.java @@ -70,6 +70,10 @@ public class Settings { return getRawProperty(settings, names, 0); } + public JsonElement getRawSettings() { + return settings; + } + private static JsonElement getRawProperty(JsonElement settings, String[] names, int i) { if (i >= names.length) { return settings; diff --git a/headless-services/manifest-yaml-language-server/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java b/headless-services/manifest-yaml-language-server/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java index 8fdebae36..3ff475f97 100644 --- a/headless-services/manifest-yaml-language-server/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java +++ b/headless-services/manifest-yaml-language-server/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java @@ -29,6 +29,8 @@ import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CFTar import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CfCliParamsProvider; import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CfClientConfig; import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CfJsonParamsProvider; +import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CfTargetsInfo; +import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CfTargetsInfo.Target; import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.ClientParamsProvider; import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.NoTargetsException; import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.DefaultCloudFoundryClientFactoryV2; @@ -136,10 +138,9 @@ public class ManifestYamlLanguageServer extends SimpleLanguageServer { documents.onHover(hoverEngine); workspace.onDidChangeConfiguraton(settings -> { - //TODO code below needs to convert to a "nicer" Java representation of the CF client params, than just a Map with nested structures - Map asMap = getAs(Map.class, settings, "cfClientParams"); - if (asMap != null) { - applyCfLoginParameterSettings(asMap); + CfTargetsInfo info = fromJson(CfTargetsInfo.class, settings); + if (info != null) { + applyCfLoginParameterSettings(info); } }); } @@ -148,6 +149,18 @@ public class ManifestYamlLanguageServer extends SimpleLanguageServer { return cfClientConfig; } + protected T fromJson(Class klass, Settings settings) { + try { + JsonElement rawData = settings.getRawSettings(); + if (rawData != null) { + return gson.fromJson(rawData, klass); + } + } catch (JsonSyntaxException e) { + log.error("", e); + } + return null; + } + protected T getAs(Class klass, Settings settings, String... names) { try { JsonElement data = settings.getRawProperty(names); @@ -161,12 +174,12 @@ public class ManifestYamlLanguageServer extends SimpleLanguageServer { } @SuppressWarnings("unchecked") - private void applyCfLoginParameterSettings(Map cfClientParamsData) { - if (cfClientParamsData.get("parameters") instanceof List) { - List loginParams = (List) cfClientParamsData.get("parameters"); + private void applyCfLoginParameterSettings(CfTargetsInfo info) { + List cfTargets = info.getCfTargets(); + if (cfTargets != null) { - CfJsonParamsProvider cfClientParamsProvider = new CfJsonParamsProvider(loginParams, - (Map) cfClientParamsData.get("messages")); + CfJsonParamsProvider cfClientParamsProvider = new CfJsonParamsProvider(cfTargets, + info.getCfDiagnosticMessages()); cfClientConfig.setClientParamsProvider(new ClientParamsProvider() { @@ -193,7 +206,7 @@ public class ManifestYamlLanguageServer extends SimpleLanguageServer { @Override public CFParamsProviderMessages getMessages() { - return cfClientParamsData.isEmpty() ? defaultClientParamsProvider.getMessages() + return cfTargets.isEmpty() ? defaultClientParamsProvider.getMessages() : cfClientParamsProvider.getMessages(); } diff --git a/headless-services/manifest-yaml-language-server/src/test/resources/cf-targets1.json b/headless-services/manifest-yaml-language-server/src/test/resources/cf-targets1.json index 6a37cd070..add7825c4 100644 --- a/headless-services/manifest-yaml-language-server/src/test/resources/cf-targets1.json +++ b/headless-services/manifest-yaml-language-server/src/test/resources/cf-targets1.json @@ -1,20 +1,24 @@ { - "cfClientParams": { - "parameters": [ - { - "Target": "https://api.system.demo-gcp.springapps.io", - "OrgName": "system", - "SpaceName": "p-dataflow", - "RefreshToken": "eyJhbGciOiJSUzI1N", - "SSLDisabled": true - }, - { - "Target": "https://api.run.pivotal.io", - "OrgName": "test", - "SpaceName": "spring-testing", - "RefreshToken": "eyJhbGciOiJSUzI1N", - "SSLDisabled": true - } - ] + "cfTargets": [ + { + "api":"https://api.system.demo-gcp.springapps.io", + "org":"system", + "space": "p-dataflow", + "refreshToken": "eyJhbGciOiJSUzI1N", + "sslDisabled": true + }, + { + "api":"https://api.run.pivotal.io", + "org":"test", + "space": "spring-testing", + "refreshToken": "eyJhbGciOiJSUzI1N", + "sslDisabled": true + } + ], + "cfDiagnosticMessages": { + "noTargetsFound": "No Cloud Foundry targets found: Connect CF Target(s) in Boot Dashboard or login via CF CLI", + "unauthorised": "Permission denied: Verify credentials to CF Target from Boot Dashboard or CF CLI are correct", + "noNetworkConnection": "No connection to Cloud Foundry: Connect CF Target via Boot Dashboard or login via CF CLI or verify network connections", + "noOrgSpace": "No org/space selected: Connect CF Target in Boot Dashboard or login via CF CLI" } -} +} \ No newline at end of file