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 committed Jun 29, 2023
1 parent 0b39358 commit 0626ad2
Show file tree
Hide file tree
Showing 7 changed files with 211 additions and 31 deletions.
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
Expand Up @@ -13,7 +13,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 +77,66 @@ 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());
Integration integration = yamlMapper.readValue(input, Integration.class);

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

for (var flow : integration.getSpec().get_flows()) {
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);
}

if (integration.getSpec().get_flows() != null) {
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;
}

@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,22 @@ 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 -> {
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());
}
}
this.getSpec().get_flows().add(flow);
});
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package io.kaoto.backend.model.deployment.camelroute;

import java.util.List;
import java.util.Map;

import io.kaoto.backend.model.parameter.Parameter;
import io.kaoto.backend.model.step.Step;

public class IntegrationFlow {
private List<Step> steps;
private List<Parameter> parameters;
private Map<String, Object> metadata;

public List<Step> getSteps() {
return steps;
}

public void setSteps(final List<Step> steps) {
this.steps = steps;
}

public Map<String, Object> getMetadata() {
return metadata;
}

public void setMetadata(final Map<String, Object> metadata) {
this.metadata = metadata;
}

public List<Parameter> getParameters() {
return parameters;
}

public void setParameters(
final List<Parameter> parameters) {
this.parameters = parameters;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof IntegrationFlow that)) return false;

if (getSteps() != null ? !getSteps().equals(that.getSteps()) : that.getSteps() != null) return false;
if (getParameters() != null ? !getParameters().equals(that.getParameters()) : that.getParameters() != null)
return false;
return getMetadata() != null ? getMetadata().equals(that.getMetadata()) : that.getMetadata() == null;
}

@Override
public int hashCode() {
int result = getSteps() != null ? getSteps().hashCode() : 0;
result = 31 * result + (getParameters() != null ? getParameters().hashCode() : 0);
result = 31 * result + (getMetadata() != null ? getMetadata().hashCode() : 0);
return result;
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -68,20 +68,14 @@ void parseFlows() {
" steps:",
" - to:",
" uri: log:tick",
"---",
"apiVersion: camel.apache.org/v1",
"kind: Integration",
"metadata:",
" name: bye.yaml",
"spec:",
" flows:",
" - from:",
" uri: timer:tock",
" parameters:",
" period: '3000'",
" steps:",
" - to:",
" uri: log:tock")) + System.lineSeparator();
" uri: log:tock"
)) + System.lineSeparator();

var parsed = stepParserService.getParsedFlows(yaml);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,29 @@ void parse() {
assertThat(yaml).isEqualToNormalizingNewlines(integration);
}

@Test
void parseMultipleRoutes() throws Exception {
String input = new String(Objects.requireNonNull(
this.getClass().getResourceAsStream("integration-multiroute.yaml"))
.readAllBytes(), StandardCharsets.UTF_8);
var parsed = service.getParsedFlows(input);
assertThat(parsed).hasSize(3);
var metadata = parsed.get(0);
assertThat(metadata.getSteps()).isNull();
assertThat(metadata.getParameters()).isEmpty();
assertThat(metadata.getMetadata().get("name")).isEqualTo("multiroute-integration-example");
var flow1 = parsed.get(1);
assertThat(flow1.getMetadata()).isEmpty();
assertThat(flow1.getParameters()).isEmpty();
assertThat(flow1.getSteps()).extracting(Step::getName).containsExactly("timer", "activemq", "log");
var flow2 = parsed.get(2);
assertThat(flow2.getMetadata()).isEmpty();
assertThat(flow2.getParameters()).isEmpty();
assertThat(flow2.getSteps()).extracting(Step::getName).containsExactly("timer", "activemq", "log");
var yaml = deploymentService.parse(parsed);
assertThat(yaml).isEqualToNormalizingNewlines(input);
}

@ParameterizedTest
@ValueSource(strings = {"invalid/dropbox-sink.kamelet.yaml", "invalid/twitter-search-source-binding.yaml",
"route.yaml"})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: camel.apache.org/v1
kind: Integration
metadata:
name: multiroute-integration-example
spec:
flows:
- from:
uri: timer:tick
parameters:
period: '5000'
steps:
- to:
uri: activemq:queue:myQueue
- to:
uri: log:save
- from:
uri: timer:tick2
parameters:
period: '5000'
steps:
- to:
uri: activemq:queue:myQueue2
- to:
uri: log:save2

0 comments on commit 0626ad2

Please sign in to comment.