Removed CF target caching

Clients should be cached and reused when possible, but not the targets
as the external targets configuration (e.g. CLI config) can change while
the language server is running.
This commit is contained in:
nsingh
2017-01-09 15:00:35 -08:00
parent c66b6565d0
commit e01d439b2b
6 changed files with 122 additions and 103 deletions

View File

@@ -21,16 +21,21 @@ import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.DefaultClou
* Creates targets given a client parameters factory and a client factory.
*
*/
public class CFTargets {
public class CFTargetsFactory {
private final CFClientParamsFactory paramsFactory;
private final CloudFoundryClientFactory clientFactory;
private final CFClientParamsFactory paramsFactory;
public CFTargets(CFClientParamsFactory paramsFactory, CloudFoundryClientFactory clientFactory) {
this.paramsFactory = paramsFactory;
public CFTargetsFactory(CFClientParamsFactory paramsFactory, CloudFoundryClientFactory clientFactory) {
this.clientFactory = clientFactory;
this.paramsFactory = paramsFactory;
}
/**
*
* @return up-to-date list of CF targets.
* @throws Exception
*/
public List<CFTarget> getTargets() throws Exception {
List<CFClientParams> allParams = paramsFactory.getParams();
List<CFTarget> targets = new ArrayList<>();
@@ -59,10 +64,11 @@ public class CFTargets {
}
}
public static CFTargets createDefaultV2Targets() {
CFClientParamsFactory paramsFactory = CFClientParamsFactory.INSTANCE;
public static CFTargetsFactory createDefaultV2TargetsFactory() {
CloudFoundryClientFactory clientFactory = DefaultCloudFoundryClientFactoryV2.INSTANCE;
return new CFTargets(paramsFactory, clientFactory);
CFClientParamsFactory paramsFactory = CFClientParamsFactory.INSTANCE;
return new CFTargetsFactory(paramsFactory, clientFactory);
}
}

View File

@@ -18,7 +18,7 @@ import org.junit.Ignore;
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.CFTargets;
import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CFTargetsFactory;
import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.CloudFoundryClientFactory;
import org.springframework.ide.vscode.commons.cloudfoundry.client.v2.DefaultCloudFoundryClientFactoryV2;
@@ -31,7 +31,7 @@ public class CFClientTest {
CFClientParamsFactory paramsFactory = CFClientParamsFactory.INSTANCE;
CloudFoundryClientFactory clientFactory = DefaultCloudFoundryClientFactoryV2.INSTANCE;
CFTargets targets = new CFTargets(paramsFactory, clientFactory);
CFTargetsFactory targets = new CFTargetsFactory(paramsFactory, clientFactory);
CFTarget target = targets.getTargets().get(0);
List<CFBuildpack> buildPacks = target.getBuildpacks();

View File

@@ -0,0 +1,52 @@
/*******************************************************************************
* 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.manifest.yaml;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.inject.Provider;
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.yaml.schema.YValueHint;
import com.google.common.collect.Lists;
public abstract class AbstractCFHintsProvider implements Provider<Collection<YValueHint>> {
private final CFTargetsFactory targetsFactory;
public AbstractCFHintsProvider(CFTargetsFactory targetsFactory) {
this.targetsFactory = targetsFactory;
}
/**
*
* @return non-null list of targets. May be empty if no targets available.
* @throws Exception
* if error when creating the targets
*/
protected List<CFTarget> getUpdatedCFTargets() throws Exception {
if (targetsFactory != null) {
// Do not cache the targets. They may change (e.g. if using cf
// CLI config, if CLI targets another API or org/space, the list
// of targets fetched from the factory also
// needs to be up-to-date)
List<CFTarget> updatedTargets = targetsFactory.getTargets();
if (updatedTargets != null) {
Lists.newArrayList(updatedTargets.iterator());
}
}
return Collections.emptyList();
}
}

View File

@@ -16,48 +16,45 @@ import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Provider;
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFBuildpack;
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.yaml.schema.BasicYValueHint;
import org.springframework.ide.vscode.commons.yaml.schema.YValueHint;
public class ManifestYamlCFBuildpacksProvider implements Provider<Collection<YValueHint>> {
public class ManifestYamlCFBuildpacksProvider extends AbstractCFHintsProvider {
private final List<CFTarget> targets;
private static final Logger logger = Logger.getLogger(ManifestYamlCFBuildpacksProvider.class.getName());
public ManifestYamlCFBuildpacksProvider(List<CFTarget> targets) {
this.targets = targets;
public ManifestYamlCFBuildpacksProvider(CFTargetsFactory targetsFactory) {
super(targetsFactory);
}
@Override
public Collection<YValueHint> get() {
List<YValueHint> hints = new ArrayList<>();
if (targets != null) {
try {
// Do not cache the targets. They may change (e.g. if using cf
// CLI config, if CLI targets another API or org/space, the list
// of targets fetched from the factory also
// needs to be up-to-date)
List<CFTarget> targets = getUpdatedCFTargets();
for (CFTarget cfTarget : targets) {
List<CFBuildpack> buildpacks;
try {
buildpacks = cfTarget.getBuildpacks();
if (buildpacks != null) {
for (CFBuildpack buildpack : buildpacks) {
String name = buildpack.getName();
String label = getBuildpackLabel(cfTarget, buildpack);
YValueHint hint = new BasicYValueHint(name, label);
if (!hints.contains(hint)) {
hints.add(hint);
}
List<CFBuildpack> buildpacks = cfTarget.getBuildpacks();
if (buildpacks != null) {
for (CFBuildpack buildpack : buildpacks) {
String name = buildpack.getName();
String label = getBuildpackLabel(cfTarget, buildpack);
YValueHint hint = new BasicYValueHint(name, label);
if (!hints.contains(hint)) {
hints.add(hint);
}
}
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
return hints;
}

View File

@@ -16,47 +16,47 @@ import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Provider;
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFServiceInstance;
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.yaml.schema.BasicYValueHint;
import org.springframework.ide.vscode.commons.yaml.schema.YValueHint;
public class ManifestYamlCFServicesProvider implements Provider<Collection<YValueHint>> {
public class ManifestYamlCFServicesProvider extends AbstractCFHintsProvider {
private final List<CFTarget> targets;
private static final Logger logger = Logger.getLogger(ManifestYamlCFServicesProvider.class.getName());
public ManifestYamlCFServicesProvider(List<CFTarget> targets) {
this.targets = targets;
public ManifestYamlCFServicesProvider(CFTargetsFactory targetsFactory) {
super(targetsFactory);
}
@Override
public Collection<YValueHint> get() {
List<YValueHint> hints = new ArrayList<>();
try {
List<CFTarget> targets = getUpdatedCFTargets();
if (targets != null) {
for (CFTarget cfTarget : targets) {
try {
List<CFServiceInstance> services = cfTarget.getClientRequests().getServices();
if (services != null) {
for (CFServiceInstance service : services) {
String name = service.getName();
String label = getServiceLabel(cfTarget, service);
YValueHint hint = new BasicYValueHint(name, label);
if (!hints.contains(hint)) {
hints.add(hint);
}
List<CFServiceInstance> services = cfTarget.getClientRequests().getServices();
if (services != null) {
for (CFServiceInstance service : services) {
String name = service.getName();
String label = getServiceLabel(cfTarget, service);
YValueHint hint = new BasicYValueHint(name, label);
if (!hints.contains(hint)) {
hints.add(hint);
}
}
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
}
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
return hints;
}

View File

@@ -1,17 +1,13 @@
package org.springframework.ide.vscode.manifest.yaml;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Provider;
import org.eclipse.lsp4j.CompletionOptions;
import org.eclipse.lsp4j.ServerCapabilities;
import org.eclipse.lsp4j.TextDocumentSyncKind;
import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CFTarget;
import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CFTargets;
import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CFTargetsFactory;
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;
@@ -33,27 +29,21 @@ import org.springframework.ide.vscode.commons.yaml.schema.YamlSchema;
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureProvider;
import org.yaml.snakeyaml.Yaml;
import com.google.common.collect.ImmutableList;
public class ManifestYamlLanguageServer extends SimpleLanguageServer {
private static final Provider<Collection<YValueHint>> NO_PROVIDER = () -> ImmutableList.of();
private static Logger logger = Logger.getLogger(ManifestYamlLanguageServer.class.getName());
private Yaml yaml = new Yaml();
private YamlSchema schema;
private CFTargets cfTargets;
private CFTargetsFactory cfTargetsFactory;
public ManifestYamlLanguageServer() {
SimpleTextDocumentService documents = getTextDocumentService();
YamlASTProvider parser = new YamlParser(yaml);
CFTargets cfTargets = getCFTargets();
Provider<Collection<YValueHint>> buildPacksProvider = getBuildpacksProvider(cfTargets);
Provider<Collection<YValueHint>> servicesProvider = getServicesProvider(cfTargets);
Provider<Collection<YValueHint>> buildPacksProvider = getBuildpacksProvider();
Provider<Collection<YValueHint>> servicesProvider = getServicesProvider();
schema = new ManifestYmlSchema(buildPacksProvider, servicesProvider);
@@ -87,45 +77,19 @@ public class ManifestYamlLanguageServer extends SimpleLanguageServer {
documents.onHover(hoverEngine ::getHover);
}
private CFTargets getCFTargets() {
// TODO: probably shouldn't be cached as targets can change during a language server session
if (cfTargets == null) {
cfTargets = CFTargets.createDefaultV2Targets();
private CFTargetsFactory getCFTargetsFactory() {
if (cfTargetsFactory == null) {
cfTargetsFactory = CFTargetsFactory.createDefaultV2TargetsFactory();
}
return cfTargets;
return cfTargetsFactory;
}
private Provider<Collection<YValueHint>> getBuildpacksProvider(CFTargets targets) {
try {
if (targets != null) {
List<CFTarget> cfTargets = targets.getTargets();
if (cfTargets != null && !cfTargets.isEmpty()) {;
return new ManifestYamlCFBuildpacksProvider(cfTargets);
}
}
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
return NO_PROVIDER;
private Provider<Collection<YValueHint>> getBuildpacksProvider() {
return new ManifestYamlCFBuildpacksProvider(getCFTargetsFactory());
}
private Provider<Collection<YValueHint>> getServicesProvider(CFTargets targets) {
try {
if (targets != null) {
List<CFTarget> cfTargets = targets.getTargets();
if (cfTargets != null && !cfTargets.isEmpty()) {
return new ManifestYamlCFServicesProvider(cfTargets);
}
}
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
return null;
private Provider<Collection<YValueHint>> getServicesProvider() {
return new ManifestYamlCFServicesProvider(getCFTargetsFactory());
}
@Override