Skip to content
This repository has been archived by the owner on Nov 27, 2023. It is now read-only.

fix: Integration CRD: Missing multiple route support #734

Merged
merged 1 commit into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,8 @@ void beans() throws Exception {
@ParameterizedTest
@ValueSource(strings = {"Camel Route#route-multi.yaml", "KameletBinding#kamelet-binding-multi.yaml",
"Kamelet#eip.kamelet.yaml", "Kamelet#kamelet-multi.yaml", "Camel Route#rest-dsl-multi.yaml",
"Camel Route#route-with-beans.yaml", "Integration#integration.yaml"})
"Camel Route#route-with-beans.yaml", "Integration#integration.yaml",
"Integration#integration-multiroute.yaml"})
void roundTrip(String file) throws IOException {

String[] parameters = file.split("#");
Expand Down Expand Up @@ -467,7 +468,8 @@ void uniqueName() throws IOException {
@ParameterizedTest
@ValueSource(strings = {"Kamelet#eip.kamelet.yaml", "Integration#integration.yaml",
"Camel Route#route-with-beans.yaml", "Camel Route#rest-dsl-multi.yaml",
"KameletBinding#kamelet-binding.yaml", "Kamelet#kamelet2.yaml"})
"KameletBinding#kamelet-binding.yaml", "Kamelet#kamelet2.yaml",
"Integration#integration-multiroute.yaml"})
void changeNameAndDescription(String file) throws IOException {

String[] parameters = file.split("#");
Expand Down Expand Up @@ -528,9 +530,9 @@ void changeNameAndDescription(String file) throws IOException {
switch (parameters[0]) {
case "Kamelet":
case "Kamelet Binding":
case "Integration":
assertTrue(sourceCode.contains(" name: " + randomGeneratedName));
break;
case "Integration":
case "Camel Route":
assertTrue(sourceCode.contains(" id: " + randomGeneratedName));
break;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
apiVersion: camel.apache.org/v1
kind: Integration
metadata:
name: multiroute-integration-example
spec:
flows:
- route:
id: timer-amq-log
from:
uri: timer:tick
parameters:
period: '5000'
steps:
- to:
uri: activemq:queue:myQueue
- to:
uri: log:save
- route:
id: timer-amq-log2
from:
uri: timer:tick2
parameters:
period: '5000'
steps:
- to:
uri: activemq:queue:myQueue2
- to:
uri: log:save2
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ spec:
dependencies:
- mvn:something.something
flows:
- from:
uri: timer:tick
parameters:
period: '5000'
steps:
- to:
uri: activemq:queue:myQueue
- to:
uri: log:save
- route:
id: timer-amq-log
from:
uri: timer:tick
parameters:
period: '5000'
steps:
- to:
uri: activemq:queue:myQueue
- to:
uri: log:save
integrationKit:
apiVersion: patatas
fieldPath: fieldPathy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import io.kaoto.backend.api.service.step.parser.camelroute.IntegrationStepParserService;
import io.kaoto.backend.model.deployment.Deployment;
import io.kaoto.backend.model.deployment.camelroute.Integration;
import io.kaoto.backend.model.deployment.camelroute.IntegrationFlow;
import io.kaoto.backend.model.parameter.Parameter;
import io.kaoto.backend.model.step.Step;
import io.opentelemetry.api.trace.Span;
Expand Down Expand Up @@ -51,26 +52,39 @@ public IntegrationDeploymentGeneratorService() {

@Override
public String parse(final List<Step> steps, final Map<String, Object> metadata, final List<Parameter> parameters) {
List<IntegrationFlow> parsedList = new LinkedList<>();
if (steps != null) {
var parsed = new IntegrationFlow();
parsed.setSteps(steps);
parsedList.add(parsed);
}
return kdgs.getYAML(new Integration(
steps != null ? new LinkedList<>(steps) : List.of(),
parsedList,
metadata != null ? new LinkedHashMap<>(metadata) : Map.of(),
catalog),
new IntegrationRepresenter());
}

@Override
public String parse(List<StepParserService.ParseResult<Step>> flows) {
StringBuilder sb = new StringBuilder();

StepParserService.ParseResult<Step> last = flows.stream().reduce((a, b) -> b).orElseThrow();
flows.stream().forEachOrdered(stepParseResult -> {
sb.append(
parse(stepParseResult.getSteps(), stepParseResult.getMetadata(), stepParseResult.getParameters()));
if (stepParseResult != last) {
sb.append("---" + System.lineSeparator());
List<IntegrationFlow> parsedList = new LinkedList<>();
Map<String, Object> metadata = null;
for (var f : flows) {
if (f.getSteps() != null) {
var iflow = new IntegrationFlow();
iflow.setSteps(f.getSteps());
iflow.setMetadata(f.getMetadata());
iflow.setParameters(f.getParameters());
parsedList.add(iflow);
} else if (f.getMetadata() != null) {
metadata = f.getMetadata();
}
});
return sb.toString();
}
return kdgs.getYAML(new Integration(
parsedList,
metadata != null ? new LinkedHashMap<>(metadata) : Map.of(),
catalog),
new IntegrationRepresenter());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package io.kaoto.backend.api.service.step.parser.camelroute;

import java.io.IOException;

import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.node.ObjectNode;

import io.kaoto.backend.model.deployment.kamelet.Flow;
import io.kaoto.backend.model.deployment.kamelet.step.From;
import io.kaoto.backend.model.deployment.rest.Rest;

public class FlowDeserializer extends StdDeserializer<Flow> {
protected FlowDeserializer() {
this(null);
}

protected FlowDeserializer(Class<?> vc) {
super(vc);
}

@Override
public Flow deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
Flow flow = new Flow();
var root = p.getCodec().readTree(p);
if (((ObjectNode)root).has("route")) {
var route = ((ObjectNode)root).get("route");
if (route.has("id")) {
flow.setId(route.get("id").asText());
}
if (route.has("route-configuration-id")) {
flow.setRouteConfigurationId(route.get("route-configuration-id").asText());
}
if (route.has("description")) {
flow.setDescription(route.get("description").asText());
}
if (route.has("from")) {
var from = ctxt.readTreeAsValue(route.get("from"), From.class);
flow.setFrom(from);
}
}
if (((ObjectNode)root).has("from")) {
var from = ctxt.readTreeAsValue((JsonNode)root.get("from"), From.class);
flow.setFrom(from);
}
if (((ObjectNode)root).has("rest")) {
var rest = ctxt.readTreeAsValue((JsonNode)root.get("rest"), Rest.class);
flow.setRest(rest);
}
return flow;
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package io.kaoto.backend.api.service.step.parser.camelroute;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import io.kaoto.backend.api.service.step.parser.StepParserService;
import io.kaoto.backend.api.service.step.parser.kamelet.KameletStepParserService;
import io.kaoto.backend.model.deployment.camelroute.Integration;
import io.kaoto.backend.model.deployment.kamelet.Flow;
import io.kaoto.backend.model.deployment.kamelet.FlowStep;
import io.kaoto.backend.model.step.Step;
import io.quarkus.runtime.annotations.RegisterForReflection;
Expand All @@ -13,7 +15,7 @@
import jakarta.inject.Inject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
Expand Down Expand Up @@ -77,12 +79,71 @@ public ParseResult<Step> deepParse(final String input) {

@Override
public List<ParseResult<Step>> getParsedFlows(String input) {
var res = new LinkedList<ParseResult<Step>>();
String[] splitCRDs = input.split(System.lineSeparator() + "---" + System.lineSeparator());
for (var crd : splitCRDs) {
res.add(deepParse(crd));
if (!appliesTo(input)) {
throw new IllegalArgumentException(
"Wrong format provided. This is not parseable by us.");
}
return res;

List<ParseResult<Step>> answer = new ArrayList<>();
ParseResult<Step> metadata = new ParseResult<>();
metadata.setParameters(new ArrayList<>());
answer.add(metadata);
try {
ObjectMapper yamlMapper = new ObjectMapper(new YAMLFactory());
var module = new SimpleModule();
module.addDeserializer(Flow.class, new FlowDeserializer());
yamlMapper.registerModule(module);
Integration integration = yamlMapper.readValue(input, Integration.class);

ksps.processMetadata(metadata, integration.getMetadata());

if (integration.getSpec().get_flows() != null) {
integration.getSpec().get_flows().forEach(f -> processFlows(answer, f));
integration.getSpec().get_flows().clear();
}

//Let's store the spec to make sure we don't lose anything else
((Map<String, Object>)metadata
.getMetadata()
.get("additionalProperties"))
.put("spec", integration.getSpec());
if (integration.getMetadata().getAnnotations().containsKey("description")) {
metadata.getMetadata().put("description",
integration.getMetadata().getAnnotations().get("description"));
}

} catch (Exception e) {
throw new IllegalArgumentException("Error trying to parse.", e);
}

return answer;
}

private void processFlows(List<ParseResult<Step>> answer, Flow flow) {
ParseResult<Step> res = new ParseResult<>();
res.setParameters(new ArrayList<>());
List<Step> steps = new ArrayList<>();
res.setSteps(steps);
steps.add(ksps.processStep(flow.getFrom(), true, false));
if (flow.getFrom().getSteps() != null) {
for (FlowStep step : flow.getFrom().getSteps()) {
//end is always false in this case because we can always edit one step after it
steps.add(ksps.processStep(step, false, false));
}
}
if (res.getMetadata() == null) {
res.setMetadata(new LinkedHashMap<>());
}
if (flow.getId() != null) {
res.getMetadata().put("name", flow.getId());
}
if (flow.getRouteConfigurationId() != null) {
res.getMetadata().put("route-configuration-id", flow.getRouteConfigurationId());
}
if (flow.getDescription() != null) {
res.getMetadata().put("description", flow.getDescription());
}
answer.add(res);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import io.kaoto.backend.KamelPopulator;
import io.kaoto.backend.api.metadata.catalog.StepCatalog;
import io.kaoto.backend.model.deployment.kamelet.Flow;
import io.kaoto.backend.model.step.Step;
import io.quarkus.runtime.annotations.RegisterForReflection;
import org.apache.camel.v1.IntegrationStatus;

Expand Down Expand Up @@ -47,7 +46,8 @@ public Integration() {

}

public Integration(final List<Step> steps, final Map<String, Object> metadata, final StepCatalog catalog) {
public Integration(
final List<IntegrationFlow> flowList, final Map<String, Object> metadata, final StepCatalog catalog) {
this.setMetadata(new ObjectMeta());
this.getMetadata().setName(metadata.getOrDefault("name", "").toString());
this.getMetadata().setAdditionalProperties(
Expand All @@ -68,10 +68,23 @@ public Integration(final List<Step> steps, final Map<String, Object> metadata, f
this.setSpec(new IntegrationSpec());
}
this.getSpec().set_flows(new ArrayList<>());
var flow = new Flow();
flow.setFrom(new KamelPopulator(catalog).getFlow(steps));
this.getSpec().get_flows().add(flow);
flowList.forEach(iflow -> processFlow(iflow, this.getSpec().get_flows(), catalog));
}


private void processFlow(IntegrationFlow iflow, List<Flow> flowList, StepCatalog catalog) {
var flow = new Flow();
flow.setFrom(new KamelPopulator(catalog).getFlow(iflow.getSteps()));
if (iflow.getMetadata() != null) {
if (iflow.getMetadata().get("name") != null) {
flow.setId(iflow.getMetadata().get("name").toString());
}
if (iflow.getMetadata().get("route-configuration-id") != null) {
flow.setRouteConfigurationId(iflow.getMetadata().get("route-configuration-id").toString());
}
if (iflow.getMetadata().get("description") != null) {
flow.setDescription(iflow.getMetadata().get("description").toString());
}
}
flowList.add(flow);
}
}
Loading