diff --git a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFClientParamsFactory.java b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFClientParamsFactory.java index 29a1f9a5d..d4804cc27 100644 --- a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFClientParamsFactory.java +++ b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFClientParamsFactory.java @@ -16,18 +16,22 @@ import java.util.List; import javax.inject.Provider; /** - * Resolves Cloud Foundry client parameters from registered params providers + * Resolves Cloud Foundry client parameters from params providers (for example, + * a provider would be a cf CLI config parser that parses params from the CLI + * config.json file) * */ public class CFClientParamsFactory { public static final CFClientParamsFactory INSTANCE = new CFClientParamsFactory(); - @SuppressWarnings("unchecked") private List>> providers = new ArrayList<>(); private CFClientParamsFactory() { - // Singleton + // For now, only support cf CLI. + // Maybe in the future other ways of retrieving client params can be + // supported + // in addition to the cf CLI config. addProvider(new CfCliParamsProvider()); } diff --git a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFTarget.java b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFTarget.java index 3f41c055e..c6fb4158b 100644 --- a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFTarget.java +++ b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFTarget.java @@ -17,6 +17,12 @@ import java.util.logging.Logger; import org.springframework.ide.vscode.commons.cloudfoundry.client.CFBuildpack; import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.ClientRequests; +/** + * + * Wrapper around a {@link ClientRequests} that may contain cached information + * like buildpacks + * + */ public class CFTarget { private final CFClientParams params; @@ -34,18 +40,17 @@ public class CFTarget { this.requests = requests; this.targetName = targetName; } - + public CFClientParams getParams() { return params; } - public List getBuildpacks() { if (buildpacks == null) { try { - buildpacks=getClientRequests().getBuildpacks(); + buildpacks = getClientRequests().getBuildpacks(); } catch (Exception e) { - logger .log(Level.SEVERE, e.getMessage(), e); + logger.log(Level.SEVERE, e.getMessage(), e); } } return buildpacks; @@ -63,6 +68,4 @@ public class CFTarget { public String toString() { return "CFClientTarget [params=" + params + ", targetName=" + targetName + "]"; } - - } diff --git a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFTargetsFactory.java b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFTargetsFactory.java index 4b0c923e9..4e67f4853 100644 --- a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFTargetsFactory.java +++ b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFTargetsFactory.java @@ -16,6 +16,7 @@ import java.util.List; import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.ClientRequests; import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.CloudFoundryClientFactory; import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.DefaultCloudFoundryClientFactoryV2; +import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.ClientTimeouts; /** * Creates targets given a client parameters factory and a client factory. @@ -25,10 +26,12 @@ public class CFTargetsFactory { private final CloudFoundryClientFactory clientFactory; private final CFClientParamsFactory paramsFactory; + private final ClientTimeouts timeouts; - public CFTargetsFactory(CFClientParamsFactory paramsFactory, CloudFoundryClientFactory clientFactory) { + public CFTargetsFactory(CFClientParamsFactory paramsFactory, CloudFoundryClientFactory clientFactory, ClientTimeouts timeouts) { this.clientFactory = clientFactory; this.paramsFactory = paramsFactory; + this.timeouts = timeouts; } /** @@ -41,7 +44,7 @@ public class CFTargetsFactory { List targets = new ArrayList<>(); if (allParams != null) { for (CFClientParams parameters : allParams) { - ClientRequests requests = clientFactory.getClient(parameters); + ClientRequests requests = clientFactory.getClient(parameters, timeouts); if (requests != null) { targets.add(new CFTarget(parameters, requests, getTargetName(parameters))); } @@ -64,11 +67,11 @@ public class CFTargetsFactory { } } - public static CFTargetsFactory createDefaultV2TargetsFactory() { + public static CFTargetsFactory createDefaultV2TargetsFactory(ClientTimeouts timeouts) { CloudFoundryClientFactory clientFactory = DefaultCloudFoundryClientFactoryV2.INSTANCE; CFClientParamsFactory paramsFactory = CFClientParamsFactory.INSTANCE; - return new CFTargetsFactory(paramsFactory, clientFactory); + return new CFTargetsFactory(paramsFactory, clientFactory, timeouts); } } diff --git a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/v2/ClientTimeouts.java b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/v2/ClientTimeouts.java new file mode 100644 index 000000000..6dcc3cbd7 --- /dev/null +++ b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/v2/ClientTimeouts.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2017 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.cloudfoundry.client.v2; + +import java.time.Duration; + +public class ClientTimeouts { + + public static final ClientTimeouts DEFAULT_TIMEOUTS = new ClientTimeouts(); + + private static final Duration APP_START_TIMEOUT = Duration.ofMillis(60*10); + private static final Duration GET_SERVICES_TIMEOUT = Duration.ofSeconds(60); + private static final Duration GET_SPACES_TIMEOUT = Duration.ofSeconds(20); + private static final Duration GET_USERNAME_TIMEOUT = Duration.ofSeconds(5); + + + public Duration getServicesTimeout() { + return GET_SERVICES_TIMEOUT; + } + + public Duration getSpacesTimeout() { + return GET_SPACES_TIMEOUT; + } + + public Duration getUsernameTimeout() { + return GET_USERNAME_TIMEOUT; + } + + public Duration getAppStartTimeout() { + return APP_START_TIMEOUT; + } + + public Duration getBuildpacksTimeout() { + return Duration.ofSeconds(10); + } + +} diff --git a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/v2/CloudFoundryClientFactory.java b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/v2/CloudFoundryClientFactory.java index 89e5a9d68..98b127487 100644 --- a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/v2/CloudFoundryClientFactory.java +++ b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/v2/CloudFoundryClientFactory.java @@ -14,6 +14,6 @@ import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CFCli public interface CloudFoundryClientFactory { - ClientRequests getClient(CFClientParams params) throws Exception; + ClientRequests getClient(CFClientParams params, ClientTimeouts timeouts) throws Exception; } \ No newline at end of file diff --git a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/v2/DefaultClientRequestsV2.java b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/v2/DefaultClientRequestsV2.java index 49ddefe6a..7387eb290 100644 --- a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/v2/DefaultClientRequestsV2.java +++ b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/v2/DefaultClientRequestsV2.java @@ -99,11 +99,7 @@ import reactor.core.publisher.Mono; */ public class DefaultClientRequestsV2 implements ClientRequests { - private static final Duration APP_START_TIMEOUT = Duration.ofMillis(60*10); - private static final Duration GET_SERVICES_TIMEOUT = Duration.ofSeconds(60); - private static final Duration GET_SPACES_TIMEOUT = Duration.ofSeconds(20); - private static final Duration GET_USERNAME_TIMEOUT = Duration.ofSeconds(5); - private static final Logger logger = Logger.getLogger(DefaultClientRequestsV2.class.getName()); + private static final Logger logger = Logger.getLogger(DefaultClientRequestsV2.class.getName()); private static final boolean DEBUG = false; @@ -150,8 +146,10 @@ public class DefaultClientRequestsV2 implements ClientRequests { private Mono info; private Mono spaceId; private AbstractUaaTokenProvider _tokenProvider; + + private final ClientTimeouts timeouts; - public DefaultClientRequestsV2(CloudFoundryClientCache clients, CFClientParams params) { + public DefaultClientRequestsV2(CloudFoundryClientCache clients, CFClientParams params, ClientTimeouts timeouts) { this.params = params; CFClientProvider provider = clients.getOrCreate(params.getUsername(), params.getCredentials(), params.getHost(), params.skipSslValidation()); this._client = provider.client; @@ -167,6 +165,9 @@ public class DefaultClientRequestsV2 implements ClientRequests { this.orgId = getOrgId(); this.spaceId = getSpaceId(); this.info = client_getInfo().cache(); + + // timeouts must never be null + this.timeouts = timeouts != null ? timeouts : ClientTimeouts.DEFAULT_TIMEOUTS; } private Mono client_createOperations(OrganizationSummary org) { @@ -311,7 +312,7 @@ public class DefaultClientRequestsV2 implements ClientRequests { @Override public List getServices() throws Exception { - return ReactorUtils.get(GET_SERVICES_TIMEOUT, CancelationTokens.NULL, + return ReactorUtils.get(timeouts.getServicesTimeout(), CancelationTokens.NULL, log("operations.services.listInstances()", _operations .services() @@ -400,7 +401,7 @@ public class DefaultClientRequestsV2 implements ClientRequests { @Override public void restartApplication(String appName, CancelationToken cancelationToken) throws Exception { - ReactorUtils.get(APP_START_TIMEOUT, cancelationToken, + ReactorUtils.get(timeouts.getAppStartTimeout(), cancelationToken, restartApp(appName) ); } @@ -493,7 +494,7 @@ public class DefaultClientRequestsV2 implements ClientRequests { @Override public List getSpaces() throws Exception { - Object it = ReactorUtils.get(GET_SPACES_TIMEOUT, log("operations.organizations().list()", + Object it = ReactorUtils.get(timeouts.getSpacesTimeout(), log("operations.organizations().list()", _operations.organizations() .list() ) @@ -551,7 +552,7 @@ public class DefaultClientRequestsV2 implements ClientRequests { @Override public List getBuildpacks() throws Exception { //XXX CF V2: getBuilpacks using 'operations' API. - return ReactorUtils.get( + return ReactorUtils.get(timeouts.getBuildpacksTimeout(), PaginationUtils.requestClientV2Resources((page) -> { return client_listBuildpacks(page); }) @@ -617,7 +618,7 @@ public class DefaultClientRequestsV2 implements ClientRequests { @Override public void push(CFPushArguments params, CancelationToken cancelationToken) throws Exception { String appName = params.getAppName(); - ReactorUtils.get(APP_START_TIMEOUT, cancelationToken, + ReactorUtils.get(timeouts.getAppStartTimeout(), cancelationToken, ifApplicationExists(appName, ((app) -> pushExisting(app, params)), firstPush(params) @@ -1326,7 +1327,7 @@ public class DefaultClientRequestsV2 implements ClientRequests { public Mono getUserName() { return log("uaa.getUsername", _uaa.getUsername() - ).timeout(GET_USERNAME_TIMEOUT); + ).timeout(timeouts.getUsernameTimeout()); } } diff --git a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/v2/DefaultCloudFoundryClientFactoryV2.java b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/v2/DefaultCloudFoundryClientFactoryV2.java index 5eb6f09c6..d5b4c201c 100644 --- a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/v2/DefaultCloudFoundryClientFactoryV2.java +++ b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/v2/DefaultCloudFoundryClientFactoryV2.java @@ -19,15 +19,22 @@ public class DefaultCloudFoundryClientFactoryV2 implements CloudFoundryClientFac /** * Use 'INSTANCE' constant instead. This class is a singleton. */ - private DefaultCloudFoundryClientFactoryV2() {} + private DefaultCloudFoundryClientFactoryV2() { + } private CloudFoundryClientCache cache = new CloudFoundryClientCache(); - /* (non-Javadoc) - * @see org.springframework.ide.vscode.commons.cloudfoundry.client.v2.CloudFoundryClientFactory#getClient(org.springframework.ide.vscode.commons.cloudfoundry.client.target.CFClientParams) + /* + * (non-Javadoc) + * + * @see org.springframework.ide.vscode.commons.cloudfoundry.client.v2. + * CloudFoundryClientFactory#getClient(org.springframework.ide.vscode. + * commons.cloudfoundry.client.cftarget.CFClientParams, + * org.springframework.ide.vscode.commons.cloudfoundry.client.v2. + * RequestTimeouts) */ @Override - public ClientRequests getClient(CFClientParams params) throws Exception { - return new DefaultClientRequestsV2(cache, params); + public ClientRequests getClient(CFClientParams params, ClientTimeouts timeouts) throws Exception { + return new DefaultClientRequestsV2(cache, params, timeouts); } } diff --git a/vscode-extensions/commons/commons-cf/src/test/java/org/springframework/ide/vscode/commons/cloudfoundry/client/CFClientTest.java b/vscode-extensions/commons/commons-cf/src/test/java/org/springframework/ide/vscode/commons/cloudfoundry/client/CFClientTest.java index 1fcdaf2d2..66818226b 100644 --- a/vscode-extensions/commons/commons-cf/src/test/java/org/springframework/ide/vscode/commons/cloudfoundry/client/CFClientTest.java +++ b/vscode-extensions/commons/commons-cf/src/test/java/org/springframework/ide/vscode/commons/cloudfoundry/client/CFClientTest.java @@ -19,6 +19,7 @@ import org.junit.Test; import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CFClientParamsFactory; import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CFTarget; import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CFTargetsFactory; +import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.ClientTimeouts; import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.CloudFoundryClientFactory; import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.DefaultCloudFoundryClientFactoryV2; @@ -31,7 +32,7 @@ public class CFClientTest { CFClientParamsFactory paramsFactory = CFClientParamsFactory.INSTANCE; CloudFoundryClientFactory clientFactory = DefaultCloudFoundryClientFactoryV2.INSTANCE; - CFTargetsFactory targets = new CFTargetsFactory(paramsFactory, clientFactory); + CFTargetsFactory targets = new CFTargetsFactory(paramsFactory, clientFactory, ClientTimeouts.DEFAULT_TIMEOUTS); CFTarget target = targets.getTargets().get(0); List buildPacks = target.getBuildpacks(); diff --git a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/Main.java b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/Main.java index 7876bd711..e072d659e 100644 --- a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/Main.java +++ b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/Main.java @@ -1,3 +1,13 @@ +/******************************************************************************* + * Copyright (c) 2016 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ package org.springframework.ide.vscode.manifest.yaml; import java.io.IOException; diff --git a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java index 2c6027516..6d19ad923 100644 --- a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java +++ b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java @@ -1,5 +1,16 @@ +/******************************************************************************* + * Copyright (c) 2016, 2017 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ package org.springframework.ide.vscode.manifest.yaml; +import java.time.Duration; import java.util.Collection; import javax.inject.Provider; @@ -8,6 +19,7 @@ import org.eclipse.lsp4j.CompletionOptions; import org.eclipse.lsp4j.ServerCapabilities; import org.eclipse.lsp4j.TextDocumentSyncKind; import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CFTargetsFactory; +import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.ClientTimeouts; import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngine; import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter; import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfoProvider; @@ -35,6 +47,16 @@ public class ManifestYamlLanguageServer extends SimpleLanguageServer { private Yaml yaml = new Yaml(); private YamlSchema schema; private CFTargetsFactory cfTargetsFactory; + + private static final ClientTimeouts VSCODE_CF_CLIENT_TIMEOUTS = new ClientTimeouts() { + + @Override + public Duration getServicesTimeout() { + // Use shorter timeouts for services because it is used in dynamic + // values for content assist + return Duration.ofSeconds(15); + } + }; public ManifestYamlLanguageServer() { @@ -79,7 +101,7 @@ public class ManifestYamlLanguageServer extends SimpleLanguageServer { private CFTargetsFactory getCFTargetsFactory() { if (cfTargetsFactory == null) { - cfTargetsFactory = CFTargetsFactory.createDefaultV2TargetsFactory(); + cfTargetsFactory = CFTargetsFactory.createDefaultV2TargetsFactory(VSCODE_CF_CLIENT_TIMEOUTS); } return cfTargetsFactory; }