Skip to content

Commit

Permalink
Update to Camel K 2
Browse files Browse the repository at this point in the history
It is impacting mostly the Traits completion/validation

* Embed the Camel K CRDs for now. For next iteration, it would nice to:
use one from Camel K CRD jar (or another upstream artifact) and then
also allow possibility to load from the cluster
* Requires to use Jackson Dataformat loader as Snake Yaml one is less
permissive and throwing errors
* since kubernetes client 6.2.0, no more need of a specific mock
dependency fabric8io/kubernetes-client#3924
* No more providing default values as they not yet in CRD
apache/camel-k#4726
* Some description are now a lot less precise, adapted tests and
reported apache/camel-k#4727

Signed-off-by: Aurélien Pupier <apupier@redhat.com>
  • Loading branch information
apupier committed Sep 7, 2023
1 parent 69d24cf commit c78a72d
Show file tree
Hide file tree
Showing 11 changed files with 7,847 additions and 1,532 deletions.
16 changes: 8 additions & 8 deletions pom.xml
Expand Up @@ -49,15 +49,15 @@
<assertj.version>3.24.2</assertj.version>
<jgit.version>6.7.0.202309050840-r</jgit.version>
<camel.version>4.0.0</camel.version>
<camel.kamelet.catalog.version>3.21.0</camel.kamelet.catalog.version>
<camel.kamelet.catalog.version>4.0.0</camel.kamelet.catalog.version>
<camel.quarkus.version>3.2.0</camel.quarkus.version>
<roaster.version>2.29.0.Final</roaster.version>
<awaitility.version>4.2.0</awaitility.version>
<tyrus.version>2.1.3</tyrus.version>
<commons-text.version>1.10.0</commons-text.version>
<citrus.kafka.version>4.0.0-M2</citrus.kafka.version>
<kafka.clients.version>3.5.1</kafka.clients.version>
<kubernetes.client.version>6.1.1</kubernetes.client.version>
<kubernetes.client.version>6.4.1</kubernetes.client.version>
</properties>

<distributionManagement>
Expand Down Expand Up @@ -343,12 +343,6 @@
<artifactId>knative-client</artifactId>
<version>${kubernetes.client.version}</version>
</dependency>
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>knative-mock</artifactId>
<version>${kubernetes.client.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-server-mock</artifactId>
Expand All @@ -366,4 +360,10 @@
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>staging camel kamelets 4.0.0</id>
<url>https://repository.apache.org/content/repositories/orgapachecamel-1607</url>
</repository>
</repositories>
</project>
Expand Up @@ -25,10 +25,11 @@
import java.util.stream.Stream;

import org.apache.camel.catalog.CamelCatalog;
import org.apache.camel.v1.kameletspec.Definition;
import org.apache.camel.v1.kameletspec.definition.Properties;
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionItemKind;

import com.fasterxml.jackson.databind.JsonNode;
import com.github.cameltooling.lsp.internal.catalog.model.BaseOptionModel;
import com.github.cameltooling.lsp.internal.catalog.model.ComponentModel;
import com.github.cameltooling.lsp.internal.catalog.model.EndpointOptionModel;
Expand All @@ -40,8 +41,7 @@
import com.github.cameltooling.lsp.internal.instancemodel.OptionParamURIInstance;
import com.github.cameltooling.lsp.internal.instancemodel.PathParamURIInstance;

import io.fabric8.camelk.v1alpha1.JSONSchemaProp;
import io.fabric8.camelk.v1alpha1.JSONSchemaProps;
import io.fabric8.kubernetes.api.model.AnyType;

public class CamelOptionNamesCompletionsFuture implements Function<CamelCatalog, List<CompletionItem>> {

Expand Down Expand Up @@ -93,7 +93,7 @@ private Stream<CompletionItem> retrieveKameletProperties() {
.map(PathParamURIInstance::getValue)
.findAny();
if(kameletTemplateId.isPresent()) {
JSONSchemaProps kameletDefinition = kameletsCatalogManager.getCatalog().getKameletDefinition(kameletTemplateId.get());
Definition kameletDefinition = kameletsCatalogManager.getCatalog().getKameletDefinition(kameletTemplateId.get());
if(kameletDefinition != null) {
kameletProperties = kameletDefinition.getProperties().entrySet().stream().map(this::createCompletionItem);
}
Expand All @@ -102,10 +102,10 @@ private Stream<CompletionItem> retrieveKameletProperties() {
return kameletProperties;
}

private CompletionItem createCompletionItem(Entry<String, JSONSchemaProp> property) {
private CompletionItem createCompletionItem(Entry<String, Properties> property) {
String propertyName = property.getKey();
CompletionItem completionItem = new CompletionItem(propertyName);
JSONSchemaProp schema = property.getValue();
Properties schema = property.getValue();
String insertText = computeInsertText(propertyName, schema);
completionItem.setInsertText(insertText);
completionItem.setDocumentation(schema.getDescription());
Expand All @@ -117,11 +117,11 @@ private CompletionItem createCompletionItem(Entry<String, JSONSchemaProp> proper
return completionItem;
}

private String computeInsertText(String propertyName, JSONSchemaProp schema) {
JsonNode defaultValue = schema.getDefault();
private String computeInsertText(String propertyName, Properties schema) {
AnyType defaultValue = schema.get_default();
String insertText = propertyName + "=";
if(defaultValue != null && defaultValue.isValueNode()) {
insertText += defaultValue.asText();
if(defaultValue != null && defaultValue.getValue() != null) {
insertText += defaultValue.getValue().toString();
}
return insertText;
}
Expand Down
Expand Up @@ -29,7 +29,7 @@
import com.github.cameltooling.lsp.internal.catalog.util.KameletsCatalogManager;
import com.github.cameltooling.lsp.internal.instancemodel.PathParamURIInstance;

import io.fabric8.camelk.v1alpha1.Kamelet;
import org.apache.camel.v1.Kamelet;

public class KameletTemplateIdCompletionProvider {

Expand All @@ -54,7 +54,7 @@ public CompletableFuture<List<CompletionItem>> get(PathParamURIInstance pathPara
return CompletableFuture.completedFuture(completionItems);
}

private Collection<Kamelet> retrievePotentialKamelets(PathParamURIInstance pathParamURIInstance) {
private List<Kamelet> retrievePotentialKamelets(PathParamURIInstance pathParamURIInstance) {
KameletsCatalog kameletsCatalog = kameletsCatalogManager.getCatalog();
if(kameletsCatalog != null) {
if (pathParamURIInstance.getCamelUriInstance().isProducer()) {
Expand Down
Expand Up @@ -16,83 +16,125 @@
*/
package com.github.cameltooling.lsp.internal.completion.modeline;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Map;
import java.util.stream.Collectors;

import org.eclipse.lsp4j.CompletionItem;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.github.cameltooling.lsp.internal.completion.CompletionResolverUtils;
import com.github.cameltooling.lsp.internal.completion.FilterPredicateUtils;
import com.github.cameltooling.lsp.internal.modelinemodel.CamelKModelineTraitDefinition;
import com.github.cameltooling.lsp.internal.modelinemodel.CamelKModelineTraitDefinitionProperty;
import com.google.gson.Gson;
import com.github.cameltooling.lsp.internal.modelinemodel.CamelKModelineTraitOption;

import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
import io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaProps;

public class CamelKTraitManager {

private CamelKTraitManager() {

}

private static List<TraitDefinition> traits;
private static Map<String, JSONSchemaProps> traits;
private static ObjectMapper mapper = new ObjectMapper(new YAMLFactory());

public static List<TraitDefinition> getTraits() {
public static Map<String, JSONSchemaProps> getTraits() {
if(traits == null) {
InputStream inputStream = CamelKTraitManager.class.getResourceAsStream("/trait-catalog-camel_k-1.7.0.json");
String text = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines().collect(Collectors.joining("\n"));
traits = Arrays.asList(new Gson().fromJson(text, TraitDefinition[].class));
InputStream inputStreamCRD = CamelKTraitManager.class.getResourceAsStream("/camel.apache.org_integrations-2.0.1.yaml");
try {
CustomResourceDefinition crd = mapper.readValue(inputStreamCRD, CustomResourceDefinition.class);
JSONSchemaProps traitsSchema = retrieveTraitsDefinitionFromCamelKCRD(crd);
traits = traitsSchema.getProperties();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
traits = Collections.emptyMap();
}
}
return traits;
}

private static JSONSchemaProps retrieveTraitsDefinitionFromCamelKCRD(CustomResourceDefinition crd) {
return crd.getSpec().getVersions().get(0).getSchema().getOpenAPIV3Schema().getProperties().get("spec").getProperties().get("traits");
}

public static List<CompletionItem> getTraitDefinitionNameCompletionItems(String filter, CamelKModelineTraitDefinition camelKModelineTraitDefinition){
return getTraits().stream()
.map(traitDefinition -> traitDefinition.createCompletionItem(camelKModelineTraitDefinition))
.filter(FilterPredicateUtils.matchesCompletionFilter(filter))
return getTraits().entrySet().stream().map(entryTrait -> {
CompletionItem completionItem = new CompletionItem(entryTrait.getKey());
completionItem.setDocumentation(entryTrait.getValue().getDescription());
if(hasAPropertySpecified(camelKModelineTraitDefinition.getTraitOption())) {
completionItem.setInsertText(entryTrait.getKey());
} else {
completionItem.setInsertText(entryTrait.getKey() + ".");
}
CompletionResolverUtils.applyTextEditToCompletionItem(camelKModelineTraitDefinition, completionItem);
return completionItem;
}).filter(FilterPredicateUtils.matchesCompletionFilter(filter))
.collect(Collectors.toList());
}

private static boolean hasAPropertySpecified(CamelKModelineTraitOption camelKModelineTraitOption) {
return camelKModelineTraitOption.getTraitProperty() != null;
}

public static List<CompletionItem> getTraitPropertyNameCompletionItems(String filter, CamelKModelineTraitDefinitionProperty traitDefinitionProperty) {
Optional<TraitDefinition> traitDefinition = getTrait(traitDefinitionProperty.getTraitOption().getTraitDefinition().getValueAsString());
if(traitDefinition.isPresent()) {
return traitDefinition.get().getProperties().stream()
.map(traitProperty -> traitProperty.createCompletionItem(traitDefinitionProperty))
JSONSchemaProps traitDefinition = getTrait(traitDefinitionProperty.getTraitOption().getTraitDefinition().getValueAsString());
if(traitDefinition != null) {
return traitDefinition.getProperties().entrySet().stream()
.map(traitProperty -> {
CompletionItem completionItem = new CompletionItem(traitProperty.getKey());
completionItem.setDocumentation(traitProperty.getValue().getDescription());
CamelKModelineTraitOption traitOption = traitDefinitionProperty.getTraitOption();
if (hasAValueSpecified(traitOption)) {
completionItem.setInsertText(traitProperty.getKey());
} else {
completionItem.setInsertText(traitProperty.getKey() + "=");
}
CompletionResolverUtils.applyTextEditToCompletionItem(traitDefinitionProperty, completionItem);
return completionItem;
})
.filter(FilterPredicateUtils.matchesCompletionFilter(filter))
.collect(Collectors.toList());
}
return Collections.emptyList();
}

private static Optional<TraitDefinition> getTrait(String traitDefinitionName) {
return getTraits().stream().filter(traitdefinition -> traitDefinitionName.equals(traitdefinition.getName())).findFirst();
private static boolean hasAValueSpecified(CamelKModelineTraitOption traitOption) {
return traitOption.getValueAsString().contains("=");
}

private static JSONSchemaProps getTrait(String traitDefinitionName) {
return getTraits().get(traitDefinitionName);
}

public static String getDescription(String traitDefinitionName) {
Optional<TraitDefinition> traitDefinition = getTrait(traitDefinitionName);
if(traitDefinition.isPresent()) {
return traitDefinition.get().getDescription();
JSONSchemaProps traitDefinition = getTrait(traitDefinitionName);
if(traitDefinition != null) {
return traitDefinition.getDescription();
}
return null;
}

public static String getPropertyDescription(String traitDefinitionName, String traitPropertyName) {
Optional<TraitDefinition> traitDefinition = getTrait(traitDefinitionName);
if(traitDefinition.isPresent()) {
Optional<TraitProperty> traitProperty = getTraitProperty(traitDefinition.get(), traitPropertyName);
if(traitProperty.isPresent()) {
return traitProperty.get().getDescription();
JSONSchemaProps traitDefinition = getTrait(traitDefinitionName);
if(traitDefinition != null) {
JSONSchemaProps traitProperty = getTraitProperty(traitDefinition, traitPropertyName);
if(traitProperty != null) {
return traitProperty.getDescription();
}
}
return null;
}

private static Optional<TraitProperty> getTraitProperty(TraitDefinition traitDefinition, String traitPropertyName) {
return traitDefinition.getProperties().stream().filter(traitProperty -> traitPropertyName.equals(traitProperty.getName())).findFirst();
private static JSONSchemaProps getTraitProperty(JSONSchemaProps traitDefinition, String traitPropertyName) {
return traitDefinition.getProperties().get(traitPropertyName);
}

}
Expand Up @@ -30,8 +30,8 @@
import com.github.cameltooling.lsp.internal.catalog.util.KameletsCatalogManager;
import com.github.cameltooling.lsp.internal.settings.SettingsManager;

import io.fabric8.camelk.v1alpha1.JSONSchemaProp;
import io.fabric8.camelk.v1alpha1.Kamelet;
import org.apache.camel.v1.Kamelet;
import org.apache.camel.v1.kameletspec.definition.Properties;

/**
* For a Camel URI "timer:timerName?delay=10s", it represents "delay=10s"
Expand Down Expand Up @@ -94,7 +94,7 @@ public String getDescription(ComponentModel componentModel, KameletsCatalogManag
if(model != null) {
return model.getDescription();
} else if (ComponentNameConstants.COMPONENT_NAME_KAMELET.equalsIgnoreCase(componentModel.getScheme())) {
JSONSchemaProp prop = getKameletPropertyByKeyName(kameletCatalogManager, keyName);
Properties prop = getKameletPropertyByKeyName(kameletCatalogManager, keyName);
if (prop != null) {
return prop.getDescription();
}
Expand All @@ -112,7 +112,7 @@ public CamelURIInstance getCamelUriInstance() {
return camelURIInstance;
}

private JSONSchemaProp getKameletPropertyByKeyName(KameletsCatalogManager kameletCatalogManager, String keyName) {
private Properties getKameletPropertyByKeyName(KameletsCatalogManager kameletCatalogManager, String keyName) {
Optional<String> kameletTemplateId = this.getCamelUriInstance().getComponentAndPathUriElementInstance().getPathParams()
.stream()
.filter(pathParam -> pathParam.getPathParamIndex() == 0)
Expand Down
Expand Up @@ -28,6 +28,7 @@

import org.apache.camel.catalog.CamelCatalog;
import org.apache.camel.tooling.model.ComponentModel.EndpointOptionModel;
import org.apache.camel.v1.kameletspec.Definition;
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.TextDocumentItem;
import org.slf4j.Logger;
Expand All @@ -45,8 +46,6 @@
import com.github.cameltooling.lsp.internal.completion.KameletTemplateIdCompletionProvider;
import com.github.cameltooling.lsp.internal.settings.SettingsManager;

import io.fabric8.camelk.v1alpha1.JSONSchemaProps;

/**
* For a Camel URI "timer:timerName?delay=10s", it represents "timerName"
*/
Expand Down Expand Up @@ -195,7 +194,7 @@ public String getComponentName() {
@Override
public String getDescription(ComponentModel componentModel, KameletsCatalogManager kameletCatalogManager) {
if(pathParamIndex == 0 && ComponentNameConstants.COMPONENT_NAME_KAMELET.equals(getComponentName())) {
JSONSchemaProps kamelet = kameletCatalogManager.getCatalog().getKameletDefinition(getValue());
Definition kamelet = kameletCatalogManager.getCatalog().getKameletDefinition(getValue());
if(kamelet != null) {
return kamelet.getDescription();
}
Expand Down

0 comments on commit c78a72d

Please sign in to comment.