Add a Dynamic 'Stemcells' model information provider
In preparation of implementing dynamic CA and checking of stemcells block.
This commit is contained in:
@@ -19,6 +19,7 @@ import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.ide.vscode.bosh.models.CachingModelProvider;
|
||||
import org.springframework.ide.vscode.bosh.models.CloudConfigModel;
|
||||
import org.springframework.ide.vscode.bosh.models.DynamicModelProvider;
|
||||
import org.springframework.ide.vscode.bosh.models.StemcellsModel;
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
import org.springframework.ide.vscode.commons.util.CollectorUtil;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
@@ -84,11 +85,17 @@ public class BoshDeploymentManifestSchema implements YamlSchema {
|
||||
private YType t_var_name_def;
|
||||
private final ASTTypeCache astTypes;
|
||||
private DynamicModelProvider<CloudConfigModel> cloudConfigProvider;
|
||||
private DynamicModelProvider<StemcellsModel> stemcellsProvider;
|
||||
private List<Pair<YType, YType>> defAndRefTypes;
|
||||
|
||||
public BoshDeploymentManifestSchema(ASTTypeCache astTypes, DynamicModelProvider<CloudConfigModel> cloudConfigProvider) {
|
||||
public BoshDeploymentManifestSchema(
|
||||
ASTTypeCache astTypes,
|
||||
DynamicModelProvider<CloudConfigModel> cloudConfigProvider,
|
||||
DynamicModelProvider<StemcellsModel> stemcellsProvider
|
||||
) {
|
||||
this.astTypes = astTypes;
|
||||
this.cloudConfigProvider = new CachingModelProvider<>(cloudConfigProvider);
|
||||
this.stemcellsProvider = new CachingModelProvider<>(stemcellsProvider);
|
||||
TYPE_UTIL = f.TYPE_UTIL;
|
||||
|
||||
V2_TOPLEVEL_TYPE = createV2Schema();
|
||||
@@ -228,7 +235,9 @@ public class BoshDeploymentManifestSchema implements YamlSchema {
|
||||
|
||||
YBeanType t_variable = f.ybean("Variable");
|
||||
addProp(t_variable, "name", t_var_name_def).isPrimary(true);
|
||||
addProp(t_variable, "type", f.yenum("VariableType", "certificate", "password", "rsa", "ssh")).isRequired(true);
|
||||
YType t_variable_type = f.yenum("VariableType", "certificate", "password", "rsa", "ssh")
|
||||
.parseWith(ValueParsers.NE_STRING); //Overrid the parser -> no errors / warnings... in theory there could be other valid values.
|
||||
addProp(t_variable, "type", t_variable_type).isRequired(true);
|
||||
addProp(t_variable, "options", t_params);
|
||||
addProp(v2Schema, "variables", f.yseq(t_variable));
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ package org.springframework.ide.vscode.bosh;
|
||||
|
||||
import org.springframework.ide.vscode.bosh.models.CloudConfigModel;
|
||||
import org.springframework.ide.vscode.bosh.models.DynamicModelProvider;
|
||||
import org.springframework.ide.vscode.bosh.models.StemcellsModel;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter;
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfoProvider;
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.VscodeHoverEngine;
|
||||
@@ -37,13 +38,13 @@ public class BoshLanguageServer extends SimpleLanguageServer {
|
||||
|
||||
private final VscodeCompletionEngineAdapter completionEngine;
|
||||
|
||||
public BoshLanguageServer(DynamicModelProvider<CloudConfigModel> cloudConfigProvider) {
|
||||
public BoshLanguageServer(DynamicModelProvider<CloudConfigModel> cloudConfigProvider, DynamicModelProvider<StemcellsModel> stemcellsProvider) {
|
||||
super("vscode-bosh");
|
||||
YamlAstCache asts = new YamlAstCache();
|
||||
SimpleTextDocumentService documents = getTextDocumentService();
|
||||
|
||||
ASTTypeCache astTypeCache = new ASTTypeCache();
|
||||
BoshDeploymentManifestSchema schema = new BoshDeploymentManifestSchema(astTypeCache, cloudConfigProvider);
|
||||
BoshDeploymentManifestSchema schema = new BoshDeploymentManifestSchema(astTypeCache, cloudConfigProvider, stemcellsProvider);
|
||||
|
||||
YamlStructureProvider structureProvider = YamlStructureProvider.DEFAULT;
|
||||
YamlAssistContextProvider contextProvider = new SchemaBasedYamlAssistContextProvider(schema);
|
||||
|
||||
@@ -17,6 +17,9 @@ import org.springframework.ide.vscode.commons.languageserver.LaunguageServerApp;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) throws IOException, InterruptedException {
|
||||
LaunguageServerApp.start(() -> new BoshLanguageServer(new BoshCommandCloudConfigProvider()));
|
||||
LaunguageServerApp.start(() -> new BoshLanguageServer(
|
||||
new BoshCommandCloudConfigProvider(),
|
||||
(dc) -> null //TODO: real model provider here!
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/*******************************************************************************
|
||||
* 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.bosh.models;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.Duration;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
import org.springframework.ide.vscode.commons.util.ExternalCommand;
|
||||
import org.springframework.ide.vscode.commons.util.ExternalProcess;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlFileAST;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlParser;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* Abstract base class to aid in implementing a Dynamic model provider that executes a bosh
|
||||
* command (with `--json`) swtich and then extracts information from its json output.
|
||||
*/
|
||||
public abstract class BoshCommandBasedModelProvider<T> implements DynamicModelProvider<T> {
|
||||
|
||||
private final YamlParser yamlParser;
|
||||
protected final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
protected Duration CMD_TIMEOUT = Duration.ofSeconds(10);
|
||||
|
||||
protected BoshCommandBasedModelProvider() {
|
||||
Representer representer = new Representer();
|
||||
representer.getPropertyUtils().setSkipMissingProperties(true);
|
||||
yamlParser = new YamlParser(new Yaml());
|
||||
}
|
||||
|
||||
/**
|
||||
* For deserializing the output from bosh cloud-config command.
|
||||
*/
|
||||
public static class BoshCommandResponse {
|
||||
private String[] blocks;
|
||||
|
||||
@JsonProperty("Blocks")
|
||||
public String[] getBlocks() {
|
||||
return blocks;
|
||||
}
|
||||
public void setBlocks(String[] blocks) {
|
||||
this.blocks = blocks;
|
||||
}
|
||||
}
|
||||
|
||||
protected String getBlock() throws Exception {
|
||||
String out = executeCommand(getCommand());
|
||||
BoshCommandResponse response = mapper.readValue(out, BoshCommandResponse.class);
|
||||
String[] blocks = response.getBlocks();
|
||||
Assert.isLegal(blocks!=null);
|
||||
Assert.isLegal(blocks.length==1);
|
||||
return blocks[0];
|
||||
}
|
||||
|
||||
protected JsonNode getJsonTree() throws Exception {
|
||||
String out = executeCommand(getCommand());
|
||||
return mapper.readTree(out);
|
||||
}
|
||||
|
||||
protected String executeCommand(ExternalCommand command) throws Exception {
|
||||
ExternalProcess process = new ExternalProcess(getWorkingDir(), command, true, CMD_TIMEOUT);
|
||||
String out = process.getOut();
|
||||
return out;
|
||||
}
|
||||
|
||||
protected File getWorkingDir() {
|
||||
return new File(".").getAbsoluteFile();
|
||||
}
|
||||
|
||||
protected abstract ExternalCommand getCommand();
|
||||
|
||||
protected YamlFileAST parseYaml(String block) throws Exception {
|
||||
TextDocument doc = new TextDocument(null, LanguageId.BOSH_CLOUD_CONFIG);
|
||||
doc.setText(block);
|
||||
YamlFileAST ast = yamlParser.getAST(doc);
|
||||
return ast;
|
||||
}
|
||||
}
|
||||
@@ -10,30 +10,18 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.bosh.models;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.Duration;
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
import org.springframework.ide.vscode.commons.util.CollectorUtil;
|
||||
import org.springframework.ide.vscode.commons.util.ExternalCommand;
|
||||
import org.springframework.ide.vscode.commons.util.ExternalProcess;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.NodeUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlFileAST;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlParser;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPath;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlTraversal;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* Concrete implementation of {@link CloudConfigProvider} that runs `bosh cloud-config` command
|
||||
@@ -41,33 +29,9 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
*
|
||||
* @author Kris De Volder
|
||||
*/
|
||||
public class BoshCommandCloudConfigProvider implements DynamicModelProvider<CloudConfigModel> {
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
final YamlParser yamlParser;
|
||||
|
||||
private Duration CMD_TIMEOUT = Duration.ofSeconds(10);
|
||||
public class BoshCommandCloudConfigProvider extends BoshCommandBasedModelProvider<CloudConfigModel> {
|
||||
|
||||
public BoshCommandCloudConfigProvider() {
|
||||
Representer representer = new Representer();
|
||||
representer.getPropertyUtils().setSkipMissingProperties(true);
|
||||
yamlParser = new YamlParser(new Yaml());
|
||||
}
|
||||
|
||||
/**
|
||||
* For deserializing the output from bosh cloud-config command.
|
||||
*/
|
||||
public static class CloudConfigResponse {
|
||||
private String[] blocks;
|
||||
|
||||
@JsonProperty("Blocks")
|
||||
public String[] getBlocks() {
|
||||
return blocks;
|
||||
}
|
||||
|
||||
public void setBlocks(String[] blocks) {
|
||||
this.blocks = blocks;
|
||||
}
|
||||
}
|
||||
|
||||
private static final YamlTraversal VM_TYPE_NAMES = YamlPath.EMPTY
|
||||
@@ -98,10 +62,8 @@ public class BoshCommandCloudConfigProvider implements DynamicModelProvider<Clou
|
||||
|
||||
@Override
|
||||
public CloudConfigModel getModel(DynamicSchemaContext dc) throws Exception {
|
||||
String block = getCloudConfigBlock();
|
||||
TextDocument doc = new TextDocument(null, LanguageId.BOSH_CLOUD_CONFIG);
|
||||
doc.setText(block);
|
||||
YamlFileAST ast = yamlParser.getAST(doc);
|
||||
String block = getBlock();
|
||||
YamlFileAST ast = parseYaml(block);
|
||||
return new CloudConfigModel() {
|
||||
@Override
|
||||
public Collection<String> getVMTypes() {
|
||||
@@ -141,15 +103,6 @@ public class BoshCommandCloudConfigProvider implements DynamicModelProvider<Clou
|
||||
};
|
||||
}
|
||||
|
||||
protected String getCloudConfigBlock() throws Exception{
|
||||
String out = executeBoshCloudConfigCommand();
|
||||
CloudConfigResponse response = mapper.readValue(out, CloudConfigResponse.class);
|
||||
String[] blocks = response.getBlocks();
|
||||
Assert.isLegal(blocks!=null);
|
||||
Assert.isLegal(blocks.length==1);
|
||||
return blocks[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure how long we wait for the command to fetch cloud config before
|
||||
* raising timeout exception. (The command may block for long amounts of time
|
||||
@@ -159,12 +112,9 @@ public class BoshCommandCloudConfigProvider implements DynamicModelProvider<Clou
|
||||
this.CMD_TIMEOUT = duration;
|
||||
}
|
||||
|
||||
protected String executeBoshCloudConfigCommand() throws Exception {
|
||||
ExternalCommand command = new ExternalCommand("bosh", "cloud-config", "--json");
|
||||
ExternalProcess process = new ExternalProcess(new File(".").getAbsoluteFile(), command, true, CMD_TIMEOUT);
|
||||
System.out.println("executeBoshCloudConfigCommand: "+process);
|
||||
String out = process.getOut();
|
||||
return out;
|
||||
@Override
|
||||
protected ExternalCommand getCommand() {
|
||||
return new ExternalCommand("bosh", "cloud-config", "--json");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*******************************************************************************
|
||||
* 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.bosh.models;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.CollectorUtil;
|
||||
import org.springframework.ide.vscode.commons.util.ExternalCommand;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPath;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlTraversal;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext;
|
||||
|
||||
public class BoshCommandStemcellsProvider extends BoshCommandBasedModelProvider<StemcellsModel> {
|
||||
|
||||
YamlTraversal STEMCELL_NAMES = YamlPath.EMPTY
|
||||
.thenValAt("Tables")
|
||||
.thenAnyChild()
|
||||
.thenValAt("Rows")
|
||||
.thenAnyChild()
|
||||
.thenValAt("name");
|
||||
|
||||
@Override
|
||||
public StemcellsModel getModel(DynamicSchemaContext dc) throws Exception {
|
||||
JSONCursor cursor = new JSONCursor(getJsonTree());
|
||||
return new StemcellsModel() {
|
||||
|
||||
@Override
|
||||
public Collection<String> getStemcellNames() {
|
||||
return getNames(STEMCELL_NAMES);
|
||||
}
|
||||
|
||||
private Collection<String> getNames(YamlTraversal path) {
|
||||
return path.traverseAmbiguously(cursor)
|
||||
.flatMap((cursor) -> {
|
||||
String text = cursor.target.asText();
|
||||
if (StringUtil.hasText(text)) {
|
||||
return Stream.of(text);
|
||||
} else {
|
||||
return Stream.empty();
|
||||
}
|
||||
})
|
||||
.collect(CollectorUtil.toImmutableSet());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ExternalCommand getCommand() {
|
||||
return new ExternalCommand("bosh", "stemcells", "--json");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,7 +3,8 @@ package org.springframework.ide.vscode.bosh.models;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext;
|
||||
|
||||
/**
|
||||
* Responsible for somehow obtaining {@link CloudConfigModel} relative to a {@link DynamicSchemaContext}
|
||||
* Responsible for somehow obtaining some type of `dynamic` model information relative
|
||||
* to a {@link DynamicSchemaContext}
|
||||
*/
|
||||
public interface DynamicModelProvider<T> {
|
||||
T getModel(DynamicSchemaContext dc) throws Exception;
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*******************************************************************************
|
||||
* 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.bosh.models;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlNavigable;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPath;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment;
|
||||
import org.springframework.ide.vscode.commons.yaml.util.Streams;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
/**
|
||||
* Allows using {@link YamlPath} / {@link YamlNavigable} on {@link JsonNode}s
|
||||
*/
|
||||
public class JSONCursor implements YamlNavigable<JSONCursor> {
|
||||
|
||||
public final JsonNode target;
|
||||
|
||||
public JSONCursor(JsonNode target) {
|
||||
super();
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<JSONCursor> traverseAmbiguously(YamlPathSegment s) {
|
||||
return oneStep(s).map(JSONCursor::new);
|
||||
}
|
||||
|
||||
private Stream<JsonNode> oneStep(YamlPathSegment s) {
|
||||
if (target==null) {
|
||||
return Stream.empty();
|
||||
}
|
||||
switch (s.getType()) {
|
||||
case KEY_AT_KEY: {
|
||||
return Streams.fromNullable(target.get(s.toPropString()));
|
||||
}
|
||||
case ANY_CHILD: {
|
||||
return Streams.fromIterable(target);
|
||||
}
|
||||
case VAL_AT_INDEX: {
|
||||
return Streams.fromNullable(target.get(s.toIndex()));
|
||||
}
|
||||
case VAL_AT_KEY: {
|
||||
return Streams.fromNullable(target.get(s.toPropString()));
|
||||
}
|
||||
default:
|
||||
throw new IllegalStateException("Missing case for "+s.getType());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ""+target;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*******************************************************************************
|
||||
* 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.bosh.models;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Represents Stemcells information as might be retrieved from bosh director.
|
||||
*/
|
||||
public interface StemcellsModel {
|
||||
|
||||
Collection<String> getStemcellNames();
|
||||
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.ide.vscode.bosh.mocks.MockCloudConfigProvider;
|
||||
import org.springframework.ide.vscode.bosh.models.BoshCommandBasedModelProvider;
|
||||
import org.springframework.ide.vscode.bosh.models.BoshCommandCloudConfigProvider;
|
||||
import org.springframework.ide.vscode.bosh.models.CloudConfigModel;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext;
|
||||
@@ -23,13 +24,13 @@ import com.google.common.collect.ImmutableMultiset;
|
||||
|
||||
public class BoshCommandCloudConfigProviderTest {
|
||||
|
||||
public final MockCloudConfigProvider mockProvider = new MockCloudConfigProvider();
|
||||
public final BoshCommandCloudConfigProvider mockProvider = new MockCloudConfigProvider();
|
||||
|
||||
// For local testing only... in CI builds we don't have the means to use a real bosh director and cli.
|
||||
// private BoshCommandCloudConfigProvider realProvider = new BoshCommandCloudConfigProvider();
|
||||
|
||||
@Test public void getVMTypes() throws Exception {
|
||||
BoshCommandCloudConfigProvider provider = mockProvider;
|
||||
BoshCommandBasedModelProvider<CloudConfigModel> provider = mockProvider;
|
||||
DynamicSchemaContext dc = Mockito.mock(DynamicSchemaContext.class);
|
||||
CloudConfigModel cloudConfig = provider.getModel(dc);
|
||||
|
||||
|
||||
@@ -20,7 +20,10 @@ import java.util.concurrent.TimeoutException;
|
||||
import org.eclipse.lsp4j.CompletionItem;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.ide.vscode.bosh.mocks.MockCloudConfigProvider;
|
||||
import org.springframework.ide.vscode.bosh.models.DynamicModelProvider;
|
||||
import org.springframework.ide.vscode.bosh.models.StemcellsModel;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaProblems;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.Editor;
|
||||
@@ -31,10 +34,11 @@ public class BoshEditorTest {
|
||||
LanguageServerHarness harness;
|
||||
|
||||
private MockCloudConfigProvider cloudConfigProvider = new MockCloudConfigProvider();
|
||||
private DynamicModelProvider<StemcellsModel> stemcellsProvider = Mockito.mock(DynamicModelProvider.class);
|
||||
|
||||
@Before public void setup() throws Exception {
|
||||
harness = new LanguageServerHarness(() -> {
|
||||
return new BoshLanguageServer(cloudConfigProvider)
|
||||
return new BoshLanguageServer(cloudConfigProvider, stemcellsProvider)
|
||||
.setMaxCompletions(100);
|
||||
},
|
||||
LanguageId.BOSH_DEPLOYMENT
|
||||
@@ -561,6 +565,20 @@ public class BoshEditorTest {
|
||||
editor.assertCompletionLabels("certificate", "password", "rsa", "ssh");
|
||||
}
|
||||
|
||||
@Test public void variablesBlockReconciling() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
"variables:\n" +
|
||||
"- name: admin-passcode\n" +
|
||||
" type: something-that-might-work-in-theory\n" + //shouldn't be a warning/error
|
||||
" bogus-propt: bah\n" +
|
||||
" options: {}"
|
||||
);
|
||||
editor.ignoreProblem(YamlSchemaProblems.MISSING_PROPERTY);
|
||||
editor.assertProblems(
|
||||
"bogus-propt|Unknown property"
|
||||
);
|
||||
}
|
||||
|
||||
@Test public void variablesBlockHovers() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
"variables:\n" +
|
||||
|
||||
@@ -19,7 +19,9 @@ import java.nio.file.Paths;
|
||||
import org.eclipse.lsp4j.InitializeResult;
|
||||
import org.eclipse.lsp4j.TextDocumentSyncKind;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.ide.vscode.bosh.mocks.MockCloudConfigProvider;
|
||||
import org.springframework.ide.vscode.bosh.models.DynamicModelProvider;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness;
|
||||
|
||||
public class BoshLanguageServerTest {
|
||||
@@ -31,7 +33,7 @@ public class BoshLanguageServerTest {
|
||||
@Test
|
||||
public void createAndInitializeServerWithWorkspace() throws Exception {
|
||||
LanguageServerHarness harness = new LanguageServerHarness(() ->
|
||||
new BoshLanguageServer(new MockCloudConfigProvider())
|
||||
new BoshLanguageServer(new MockCloudConfigProvider(), Mockito.mock(DynamicModelProvider.class))
|
||||
);
|
||||
File workspaceRoot = getTestResource("/workspace/");
|
||||
assertExpectedInitResult(harness.intialize(workspaceRoot));
|
||||
@@ -41,7 +43,7 @@ public class BoshLanguageServerTest {
|
||||
public void createAndInitializeServerWithoutWorkspace() throws Exception {
|
||||
File workspaceRoot = null;
|
||||
LanguageServerHarness harness = new LanguageServerHarness(() ->
|
||||
new BoshLanguageServer(new MockCloudConfigProvider())
|
||||
new BoshLanguageServer(new MockCloudConfigProvider(), Mockito.mock(DynamicModelProvider.class))
|
||||
);
|
||||
assertExpectedInitResult(harness.intialize(workspaceRoot));
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import java.util.concurrent.Callable;
|
||||
|
||||
import org.springframework.ide.vscode.bosh.BoshCommandCloudConfigProviderTest;
|
||||
import org.springframework.ide.vscode.bosh.models.BoshCommandCloudConfigProvider;
|
||||
import org.springframework.ide.vscode.commons.util.ExternalCommand;
|
||||
import org.springframework.ide.vscode.commons.util.IOUtil;
|
||||
|
||||
public final class MockCloudConfigProvider extends BoshCommandCloudConfigProvider {
|
||||
@@ -33,15 +34,15 @@ public final class MockCloudConfigProvider extends BoshCommandCloudConfigProvide
|
||||
* without requiring a real bosh setup.
|
||||
*/
|
||||
@Override
|
||||
protected String executeBoshCloudConfigCommand() throws Exception {
|
||||
protected String executeCommand(ExternalCommand cmd) throws Exception {
|
||||
readCount++;
|
||||
return cloudConfigCmdExecutor.call();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCloudConfigBlock() throws Exception {
|
||||
protected String getBlock() throws Exception {
|
||||
if (reader==null) {
|
||||
return super.getCloudConfigBlock();
|
||||
return super.getBlock();
|
||||
}
|
||||
readCount++;
|
||||
return reader.call();
|
||||
|
||||
@@ -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.bosh.models;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.ide.vscode.bosh.BoshCommandCloudConfigProviderTest;
|
||||
import org.springframework.ide.vscode.commons.util.IOUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
public class BoshCommandStemcellsProviderTest {
|
||||
|
||||
private static final String MOCK_DATA_RSRC = "/cmd-out/stemcells.json";;
|
||||
public BoshCommandStemcellsProvider provider = Mockito.spy(BoshCommandStemcellsProvider.class);
|
||||
|
||||
@Before
|
||||
public void settup() throws Exception {
|
||||
Mockito.doReturn(IOUtil.toString(BoshCommandCloudConfigProviderTest.class.getResourceAsStream(MOCK_DATA_RSRC)))
|
||||
.when(provider).executeCommand(Mockito.any());
|
||||
}
|
||||
|
||||
@Test public void getStemcellNames() throws Exception {
|
||||
assertEquals(ImmutableSet.of(
|
||||
"bosh-vsphere-esxi-centos-7-go_agent",
|
||||
"bosh-vsphere-esxi-ubuntu-trusty-go_agent"
|
||||
),
|
||||
provider.getModel(Mockito.mock(DynamicSchemaContext.class))
|
||||
.getStemcellNames()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"Tables": [
|
||||
{
|
||||
"Content": "stemcells",
|
||||
"Header": {
|
||||
"cid": "CID",
|
||||
"cpi": "CPI",
|
||||
"name": "Name",
|
||||
"os": "OS",
|
||||
"version": "Version"
|
||||
},
|
||||
"Rows": [
|
||||
{
|
||||
"cid": "sc-cd694110-4b23-4361-b5e7-b817874eadca",
|
||||
"cpi": "",
|
||||
"name": "bosh-vsphere-esxi-centos-7-go_agent",
|
||||
"os": "centos-7",
|
||||
"version": "3421.11"
|
||||
},
|
||||
{
|
||||
"cid": "sc-3378b7e1-5a80-4351-b521-7e9aeeb417bc",
|
||||
"cpi": "",
|
||||
"name": "bosh-vsphere-esxi-ubuntu-trusty-go_agent",
|
||||
"os": "ubuntu-trusty",
|
||||
"version": "3421.11"
|
||||
}
|
||||
],
|
||||
"Notes": [
|
||||
"(*) Currently deployed"
|
||||
]
|
||||
}
|
||||
],
|
||||
"Blocks": null,
|
||||
"Lines": [
|
||||
"Using environment '10.194.4.35' as client 'admin'",
|
||||
"Succeeded"
|
||||
]
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
package org.springframework.ide.vscode.commons.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
@@ -62,7 +63,7 @@ public class CollectorUtil {
|
||||
|
||||
@Override
|
||||
public Set<Collector.Characteristics> characteristics() {
|
||||
return ImmutableSet.of(Collector.Characteristics.UNORDERED);
|
||||
return EnumSet.of(Collector.Characteristics.UNORDERED);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -94,7 +95,39 @@ public class CollectorUtil {
|
||||
|
||||
@Override
|
||||
public Set<Collector.Characteristics> characteristics() {
|
||||
return ImmutableSet.of(Collector.Characteristics.UNORDERED);
|
||||
return EnumSet.of(Collector.Characteristics.UNORDERED);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <T> Collector<T, ArrayList<T>, ImmutableSet<T>> toImmutableSet() {
|
||||
return new Collector<T, ArrayList<T>, ImmutableSet<T>>() {
|
||||
|
||||
@Override
|
||||
public Supplier<ArrayList<T>> supplier() {
|
||||
return ArrayList::new;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiConsumer<ArrayList<T>, T> accumulator() {
|
||||
return (a, e) -> a.add(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryOperator<ArrayList<T>> combiner() {
|
||||
return (a1, a2) -> {
|
||||
a1.addAll(a2);
|
||||
return a1;
|
||||
};
|
||||
}
|
||||
@Override
|
||||
public Function<ArrayList<T>, ImmutableSet<T>> finisher() {
|
||||
return ImmutableSet::copyOf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Collector.Characteristics> characteristics() {
|
||||
return EnumSet.of(Collector.Characteristics.UNORDERED);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.springframework.ide.vscode.commons.yaml.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
public class Streams {
|
||||
|
||||
@@ -35,4 +35,8 @@ public class Streams {
|
||||
return e==null ? Stream.empty() : Stream.of(e);
|
||||
}
|
||||
|
||||
public static <T> Stream<T> fromIterable(Iterable<T> target) {
|
||||
return StreamSupport.stream(target.spliterator(), false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user