Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
1e27fec
feat: implemented export of chains as Camel K custom resource
SSNikolaevich Nov 1, 2025
7270aa8
feat: implemented insertion of beans into XML DSL
SSNikolaevich Nov 11, 2025
c5259a7
feat: implemented some of metadata beans
SSNikolaevich Nov 12, 2025
05a97cc
feat: added ServiceCallInfo bean builder
SSNikolaevich Nov 18, 2025
f2201d8
feat: added prefix to bean names
SSNikolaevich Nov 18, 2025
54b101c
feat: added beans binders
SSNikolaevich Nov 19, 2025
f9db8d6
fix: version string follows a semantic version rules
SSNikolaevich Nov 24, 2025
2656423
feat: implemented insertion of route info beans into XML DSL
SSNikolaevich Nov 24, 2025
bd4cb1a
fix: refactored code to add explicit place to create multiple resourc…
SSNikolaevich Nov 24, 2025
98caf87
fix: refactored code that builds resources to deploy
SSNikolaevich Nov 25, 2025
aa7f92b
feat: implemented insertion of SdsTriggerInfo bean
SSNikolaevich Nov 25, 2025
c348ff2
feat: changed naming of flows configmaps
SSNikolaevich Nov 27, 2025
e9d9b55
feat: fixed naming issues
SSNikolaevich Nov 27, 2025
ca0d2fa
feat: added environment traits to generated resource
SSNikolaevich Nov 27, 2025
2404b71
fix: fixed name generation issues
SSNikolaevich Nov 27, 2025
39f28a7
fix: added image pool policy to resource build options
SSNikolaevich Nov 27, 2025
f51d941
fix: added generation of service
SSNikolaevich Nov 28, 2025
f4f0a13
fix: added cloud service name to environment
SSNikolaevich Dec 1, 2025
23c0e99
feat: added service account name placeholder
SSNikolaevich Dec 2, 2025
4bbca2c
feat: enhanced k8s resource name validation
SSNikolaevich Dec 2, 2025
60ae00b
feat: added generation of ServiceMonitor resource
SSNikolaevich Dec 2, 2025
645cefd
Merge branch 'main' into camel-k-cr
SSNikolaevich Dec 3, 2025
1c1acd8
feat: added support for Camel K integrations as domains
SSNikolaevich Dec 5, 2025
13c43ca
fix: made optional -v\d+ suffix in default domain name pattern
SSNikolaevich Dec 8, 2025
a36d698
feat: added bean builder for JMS elements
SSNikolaevich Dec 10, 2025
054f129
Merge branch 'main' into camel-k-cr
SSNikolaevich Jan 28, 2026
7b5c8f2
Merge branch 'main' into camel-k-cr
SSNikolaevich Jan 28, 2026
3442201
feat: implemented direct deployment to K8s
SSNikolaevich Feb 2, 2026
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 @@ -23,6 +23,7 @@ public final class BuilderConstants {
public static final String ROUTES = "routes";
public static final String ROUTE = "route";
public static final String ID = "id";
public static final String GROUP = "group";
public static final String FROM = "from";
public static final String ON_COMPLETION = "onCompletion";
public static final String ON_COMPLETION_ID_POSTFIX = "-on-completion";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
package org.qubership.integration.platform.runtime.catalog.builder;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.qubership.integration.platform.runtime.catalog.model.ChainRoute;
import org.qubership.integration.platform.runtime.catalog.model.library.ElementDescriptor;
import org.qubership.integration.platform.runtime.catalog.model.library.ElementType;
import org.qubership.integration.platform.runtime.catalog.persistence.configs.entity.chain.Dependency;
import org.qubership.integration.platform.runtime.catalog.persistence.configs.entity.chain.element.ChainElement;
import org.qubership.integration.platform.runtime.catalog.persistence.configs.entity.chain.element.ContainerChainElement;
import org.qubership.integration.platform.runtime.catalog.service.library.LibraryElementsService;
import org.qubership.integration.platform.runtime.catalog.util.ElementUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

import static org.qubership.integration.platform.runtime.catalog.model.constant.CamelNames.CONTAINER;

@Slf4j
@Component
public class ChainRouteBuilder {
private final LibraryElementsService libraryService;
private final ElementUtils elementUtils;

@Autowired
public ChainRouteBuilder(
LibraryElementsService libraryService,
ElementUtils elementUtils
) {
this.libraryService = libraryService;
this.elementUtils = elementUtils;
}

public List<ChainRoute> build(List<ChainElement> elements) {
List<ChainElement> startElements = elementUtils.splitCompositeTriggers(elements)
.stream()
.filter(chainElement -> {
ElementDescriptor descriptor = libraryService.getElementDescriptor(chainElement);
boolean elementHasNoParent = chainElement.getParent() == null
|| CONTAINER.equals(chainElement.getParent().getType());
return descriptor != null
&& (descriptor.getType() == ElementType.TRIGGER
|| descriptor.getType() == ElementType.REUSE
|| (descriptor.getType() == ElementType.COMPOSITE_TRIGGER
&& elementHasNoParent
&& chainElement.getInputDependencies().isEmpty()));
})
.collect(Collectors.toList());

return collectRoutes(startElements);
}

private List<ChainRoute> collectRoutes(List<ChainElement> startElements) {
List<ChainRoute> routes = new LinkedList<>();
Map<String, ChainRoute> elementToRoute = new HashMap<>(); // map of elements where key is "to" element id and value is its route
Deque<Pair<ChainElement, ChainRoute>> stack = new LinkedList<>();
for (ChainElement startElement : startElements) {
ChainRoute route = !BuilderConstants.REUSE_ELEMENT_TYPE.equals(startElement.getType())
? new ChainRoute()
: new ChainRoute(startElement.getOriginalId());
routes.add(route);
stack.push(Pair.of(startElement, route));

if (startElement.getType().startsWith(BuilderConstants.SFTP_TRIGGER_PREFIX)) {
route.setCustomIdPlaceholder(BuilderConstants.DEPLOYMENT_ID_PLACEHOLDER + "-" + startElement.getId());
}
}
while (!stack.isEmpty()) {
Pair<ChainElement, ChainRoute> currentElement = stack.pop();
ChainElement current = currentElement.getLeft();
ChainRoute currentRoute = currentElement.getRight();
ElementDescriptor elementDescriptor = libraryService.getElementDescriptor(current);
ElementType elementType = elementDescriptor.getType();

if (currentRoute.getElements().isEmpty()) {
elementToRoute.put(current.getId(), currentRoute);
}
currentRoute.getElements().add(current);

//Condition that decide route need to be finished
boolean completeRoute =
elementType == ElementType.TRIGGER
|| (elementType == ElementType.COMPOSITE_TRIGGER)
|| current.getOutputDependencies().size() != 1;

for (Dependency dependency : current.getOutputDependencies()) {
ChainElement nextElement = dependency.getElementTo();
if (elementToRoute.containsKey(nextElement.getId())) { // if a route with nextElement already exists
ChainRoute nextRoute = elementToRoute.get(nextElement.getId());
currentRoute.getNextRoutes().add(nextRoute);
} else {
ChainRoute route = currentRoute;
if (completeRoute || nextElement.getInputDependencies().size() > 1) {
route = new ChainRoute(); // start new route
routes.add(route);
currentRoute.getNextRoutes().add(route);
}
stack.push(Pair.of(dependency.getElementTo(), route));
}
}

if (current instanceof ContainerChainElement && elementType != ElementType.CONTAINER) {
if (!elementDescriptor.isOldStyleContainer()) {
List<ChainRoute> containerRoutes = collectContainerSubRoutes(
(ContainerChainElement) current,
elementToRoute,
stack
);
routes.addAll(containerRoutes);
continue;
}

// this block is used for deprecated containers that cannot contain logically nested
// dependent elements within themselves. It can be removed when such containers are
// completely removed from the project
for (ChainElement element : ((ContainerChainElement) current).getElements()) {
ChainRoute branchRoute = new ChainRoute(element.getId());
routes.add(branchRoute);
for (Dependency outputDependency : element.getOutputDependencies()) {
ChainElement nextElement = outputDependency.getElementTo();
branchRoute.getNextRoutes().add(extractNextRoute(nextElement, routes, elementToRoute, stack));
}
}
}
}
return routes;
}

private List<ChainRoute> collectContainerSubRoutes(
ContainerChainElement containerElement,
Map<String, ChainRoute> elementToRoute,
Deque<Pair<ChainElement, ChainRoute>> elementRouteStack
) {
List<ChainRoute> routes = new LinkedList<>();
ElementDescriptor elementDescriptor = libraryService.getElementDescriptor(containerElement);
if (!elementDescriptor.getAllowedChildren().isEmpty()) {
for (ChainElement child : containerElement.getElements()) {
if (!(child instanceof ContainerChainElement childContainer)) {
ChainRoute branchRoute = new ChainRoute(child.getId());
routes.add(branchRoute);
branchRoute.getNextRoutes().add(extractNextRoute(child, routes, elementToRoute, elementRouteStack));
continue;
}

addContainerRoutes(routes, childContainer, elementToRoute, elementRouteStack);
}
return routes;
}

addContainerRoutes(routes, containerElement, elementToRoute, elementRouteStack);
return routes;
}

private void addContainerRoutes(
List<ChainRoute> routes,
ContainerChainElement containerElement,
Map<String, ChainRoute> elementToRoute,
Deque<Pair<ChainElement, ChainRoute>> elementRouteStack
) {
ChainRoute containerRoute = new ChainRoute(containerElement.getId());
routes.add(containerRoute);

List<ChainElement> startElements = containerElement.getElements().stream()
.filter(element -> element.getInputDependencies().isEmpty())
.toList();
if (startElements.size() == 1) {
elementRouteStack.push(Pair.of(startElements.get(0), containerRoute));
return;
}

for (ChainElement startElement : startElements) {
ChainRoute nextRoute = extractNextRoute(startElement, routes, elementToRoute, elementRouteStack);
containerRoute.getNextRoutes().add(nextRoute);
}
}

private ChainRoute extractNextRoute(
ChainElement element,
List<ChainRoute> routes,
Map<String, ChainRoute> elementToRoute,
Deque<Pair<ChainElement, ChainRoute>> elementRouteStack
) {
if (elementToRoute.containsKey(element.getId())) {
return elementToRoute.get(element.getId());
}

ChainRoute newRoute = new ChainRoute();
routes.add(newRoute);
elementRouteStack.push(Pair.of(element, newRoute));
/* the nextElement can be 'nextElement' of
another element in case of merging branches into one element,
and we need to find existing route in elementToRoute map */
elementToRoute.put(element.getId(), newRoute);
return newRoute;
}
}
Loading