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

Commit

Permalink
fix: Integration CRD: Missing multiple route support
Browse files Browse the repository at this point in the history
Fixes: #733
  • Loading branch information
igarashitm authored and Delawen committed Jun 30, 2023
1 parent 8227241 commit 5f0b26f
Show file tree
Hide file tree
Showing 11 changed files with 322 additions and 43 deletions.
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

0 comments on commit 5f0b26f

Please sign in to comment.