This is an automated email from the ASF dual-hosted git repository.
marat pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git
The following commit(s) were added to refs/heads/main by this push:
new 789067cc Fix #1384
789067cc is described below
commit 789067cc71bc2821703af41de29a89c57fc4a8c6
Author: Marat Gubaidullin <[email protected]>
AuthorDate: Wed Aug 28 11:20:37 2024 -0400
Fix #1384
---
karavan-core/src/core/api/TopologyUtils.ts | 380 ++++++++++++++++-------------
1 file changed, 206 insertions(+), 174 deletions(-)
diff --git a/karavan-core/src/core/api/TopologyUtils.ts
b/karavan-core/src/core/api/TopologyUtils.ts
index 024f2d22..78e40888 100644
--- a/karavan-core/src/core/api/TopologyUtils.ts
+++ b/karavan-core/src/core/api/TopologyUtils.ts
@@ -39,45 +39,47 @@ import { CamelDefinitionApiExt } from
'./CamelDefinitionApiExt';
import { CamelDisplayUtil } from './CamelDisplayUtil';
import { CamelUtil } from './CamelUtil';
-const outgoingDefinitions: string[] = ['ToDefinition', 'KameletDefinition',
'ToDynamicDefinition', "PollEnrichDefinition", "EnrichDefinition",
"WireTapDefinition", "SagaDefinition"];
+const outgoingDefinitions: string[] = ['ToDefinition', 'KameletDefinition',
'ToDynamicDefinition', 'PollEnrichDefinition', 'EnrichDefinition',
'WireTapDefinition', 'SagaDefinition'];
export class ChildElement {
- constructor(public name: string = '', public className: string = '',
public multiple: boolean = false) {}
+ constructor(public name: string = '', public className: string = '',
public multiple: boolean = false) {
+ }
}
export class TopologyUtils {
- private constructor() {}
+ private constructor() {
+ }
static getOutgoingDefinitions = (): string[] => {
return outgoingDefinitions;
- }
+ };
static isElementInternalComponent = (element: CamelElement): boolean => {
const uri = (element as any).uri;
const component = ComponentApi.findByName(uri);
if (INTERNAL_COMPONENTS.includes(uri?.split(':')?.[0])) return true;
return component !== undefined && component.component.remote !== true;
- }
+ };
static getConnectorType = (element: CamelElement): 'component' | 'kamelet'
=> {
return CamelUtil.isKameletComponent(element) ? 'kamelet' : 'component';
- }
+ };
static cutKameletUriSuffix = (uri: string): string => {
- if (uri.endsWith("-sink")) {
+ if (uri.endsWith('-sink')) {
return uri.substring(0, uri.length - 5);
- } else if (uri.endsWith("-source")) {
+ } else if (uri.endsWith('-source')) {
return uri.substring(0, uri.length - 7);
- } else if (uri.endsWith("-action")) {
+ } else if (uri.endsWith('-action')) {
return uri.substring(0, uri.length - 7);
} else {
return uri;
}
- }
+ };
static getUniqueUri = (element: CamelElement): string => {
- const uri:string = (element as any).uri || '';
- let result = uri.startsWith("kamelet") ?
TopologyUtils.cutKameletUriSuffix(uri).concat(":") : uri.concat(":");
+ const uri: string = (element as any).uri || '';
+ let result = uri.startsWith('kamelet') ?
TopologyUtils.cutKameletUriSuffix(uri).concat(':') : uri.concat(':');
const className = element.dslName;
if (className === 'FromDefinition' || className === 'ToDefinition') {
if (!CamelUtil.isKameletComponent(element)) {
@@ -85,7 +87,7 @@ export class TopologyUtils {
for (const property of requiredProperties) {
const value =
CamelDefinitionApiExt.getParametersValue(element, property.name, property.kind
=== 'path');
if (value !== undefined && property.type === 'string' &&
value.trim().length > 0) {
- result = result + property.name + "=" + value + "&";
+ result = result + property.name + '=' + value + '&';
}
}
} else {
@@ -93,21 +95,21 @@ export class TopologyUtils {
for (const property of requiredProperties) {
const value =
CamelDefinitionApiExt.getParametersValue(element, property.id);
if (value !== undefined && property.type === 'string' &&
value.toString().trim().length > 0) {
- result = result + property.id + "=" + value + "&";
+ result = result + property.id + '=' + value + '&';
}
}
}
}
- return result.endsWith("&") ? result.substring(0, result.length - 1) :
result;
- }
+ return result.endsWith('&') ? result.substring(0, result.length - 1) :
result;
+ };
static hasDirectUri = (element: CamelElement): boolean => {
return this.hasUriStartWith(element, 'direct');
- }
+ };
static hasSedaUri = (element: CamelElement): boolean => {
return this.hasUriStartWith(element, 'seda');
- }
+ };
static hasUriStartWith = (element: CamelElement, text: string): boolean =>
{
if ((element as any).uri && typeof (element as any).uri === 'string') {
@@ -119,205 +121,235 @@ export class TopologyUtils {
} else {
return false;
}
- }
+ };
static findTopologyRestNodes = (integration: Integration[]):
TopologyRestNode[] => {
- const result:TopologyRestNode[] = [];
+ const result: TopologyRestNode[] = [];
integration.forEach(i => {
- const filename = i.metadata.name;
- const routes = i.spec.flows?.filter(flow => flow.dslName ===
'RestDefinition');
- routes?.forEach((rest: RestDefinition) => {
- const uris: string[] = [];
- rest?.get?.forEach((d: GetDefinition) => {
- if (d.to) uris.push(d.to);
- });
- rest?.post?.forEach((d: PostDefinition) => {
- if (d.to) uris.push(d.to);
- });
- rest?.put?.forEach((d: PutDefinition) => {
- if (d.to) uris.push(d.to);
- });
- rest?.delete?.forEach((d: DeleteDefinition) => {
- if (d.to) uris.push(d.to);
+ try {
+ const filename = i.metadata.name;
+ const routes = i.spec.flows?.filter(flow => flow.dslName ===
'RestDefinition');
+ routes?.forEach((rest: RestDefinition) => {
+ const uris: string[] = [];
+ rest?.get?.forEach((d: GetDefinition) => {
+ if (d.to) uris.push(d.to);
+ });
+ rest?.post?.forEach((d: PostDefinition) => {
+ if (d.to) uris.push(d.to);
+ });
+ rest?.put?.forEach((d: PutDefinition) => {
+ if (d.to) uris.push(d.to);
+ });
+ rest?.delete?.forEach((d: DeleteDefinition) => {
+ if (d.to) uris.push(d.to);
+ });
+ rest?.patch?.forEach((d: PatchDefinition) => {
+ if (d.to) uris.push(d.to);
+ });
+ rest?.head?.forEach((d: HeadDefinition) => {
+ if (d.to) uris.push(d.to);
+ });
+ const title = '' + (rest.description ? rest.description :
rest.id);
+ result.push(new TopologyRestNode(rest.path || '', '' +
rest.id, uris, title, filename, rest));
});
- rest?.patch?.forEach((d: PatchDefinition) => {
- if (d.to) uris.push(d.to);
- });
- rest?.head?.forEach((d: HeadDefinition) => {
- if (d.to) uris.push(d.to);
- });
- const title = '' + (rest.description ? rest.description :
rest.id);
- result.push(new TopologyRestNode(rest.path || '', '' +
rest.id, uris, title, filename, rest))
- })
- })
+ } catch (e) {
+ console.error(e);
+ }
+ });
return result;
};
static findTopologyIncomingNodes = (integration: Integration[]):
TopologyIncomingNode[] => {
- const result:TopologyIncomingNode[] = [];
+ const result: TopologyIncomingNode[] = [];
integration.forEach(i => {
- const filename = i.metadata.name;
- const routes = i.spec.flows?.filter(flow => flow.dslName ===
'RouteDefinition');
- const routeElements = routes?.map(r => {
- const id = 'incoming-' + r.id;
- const title = CamelDisplayUtil.getStepDescription(r.from);
- const type = TopologyUtils.isElementInternalComponent(r.from)
? 'internal' : 'external';
- const connectorType = TopologyUtils.getConnectorType(r.from);
- const uniqueUri = TopologyUtils.getUniqueUri(r.from);
- return new TopologyIncomingNode(id, type, connectorType, r.id,
title, filename, r.from, uniqueUri);
- }) || [];
- result.push(...routeElements)
- })
+ try {
+ const filename = i.metadata.name;
+ const routes = i.spec.flows?.filter(flow => flow.dslName ===
'RouteDefinition');
+ const routeElements = routes?.map(r => {
+ const id = 'incoming-' + r.id;
+ const title = CamelDisplayUtil.getStepDescription(r.from);
+ const type =
TopologyUtils.isElementInternalComponent(r.from) ? 'internal' : 'external';
+ const connectorType =
TopologyUtils.getConnectorType(r.from);
+ const uniqueUri = TopologyUtils.getUniqueUri(r.from);
+ return new TopologyIncomingNode(id, type, connectorType,
r.id, title, filename, r.from, uniqueUri);
+ }) || [];
+ result.push(...routeElements);
+ } catch (e) {
+ console.error(e);
+ }
+ });
return result;
- }
+ };
static findTopologyRouteNodes = (integration: Integration[]):
TopologyRouteNode[] => {
- const result:TopologyRouteNode[] = [];
+ const result: TopologyRouteNode[] = [];
integration.forEach(i => {
- const filename = i.metadata.name;
- const routes = i.spec.flows?.filter(flow => flow.dslName ===
'RouteDefinition');
- const routeElements = routes?.map(r => {
- const id = 'route-' + r.id;
- const title = '' + (r.description ? r.description : r.id)
- return new TopologyRouteNode(id, r.id, title, filename,
r.from, r);
- }) || [];
- result.push(...routeElements)
- })
+ try {
+ const filename = i.metadata.name;
+ const routes = i.spec.flows?.filter(flow => flow.dslName ===
'RouteDefinition');
+ const routeElements = routes?.map(r => {
+ const id = 'route-' + r.id;
+ const title = '' + (r.description ? r.description : r.id);
+ return new TopologyRouteNode(id, r.id, title, filename,
r.from, r);
+ }) || [];
+ result.push(...routeElements);
+ } catch (e) {
+ console.error(e);
+ }
+ });
return result;
- }
+ };
static findTopologyRouteConfigurationNodes = (integration: Integration[]):
TopologyRouteConfigurationNode[] => {
- const result:TopologyRouteConfigurationNode[] = [];
+ const result: TopologyRouteConfigurationNode[] = [];
integration.forEach(i => {
- const filename = i.metadata.name;
- const routes = i.spec.flows?.filter(flow => flow.dslName ===
'RouteConfigurationDefinition');
- const routeElements = routes?.map(r => {
- const id = 'route-' + r.id;
- const title = '' + (r.description ? r.description : r.id)
- return new TopologyRouteConfigurationNode(id, r.id, title,
filename, r);
- }) || [];
- result.push(...routeElements)
- })
+ try {
+ const filename = i.metadata.name;
+ const routes = i.spec.flows?.filter(flow => flow.dslName ===
'RouteConfigurationDefinition');
+ const routeElements = routes?.map(r => {
+ const id = 'route-' + r.id;
+ const title = '' + (r.description ? r.description : r.id);
+ return new TopologyRouteConfigurationNode(id, r.id, title,
filename, r);
+ }) || [];
+ result.push(...routeElements);
+ } catch (e) {
+ console.error(e);
+ }
+ });
return result;
- }
+ };
static findTopologyRouteOutgoingNodes = (integrations: Integration[]):
TopologyOutgoingNode[] => {
- const result:TopologyOutgoingNode[] = [];
+ const result: TopologyOutgoingNode[] = [];
integrations.forEach(i => {
- const filename = i.metadata.name;
- const routes = i.spec.flows?.filter(flow => flow.dslName ===
'RouteDefinition');
- routes?.forEach(route => {
- const from: FromDefinition = route.from;
- const elements = TopologyUtils.findOutgoingInStep(from, []);
- elements.forEach((e: any) => {
- const id = 'outgoing-' + route.id + '-' + e.id;
- const title = CamelDisplayUtil.getStepDescription(e);
- const type = TopologyUtils.isElementInternalComponent(e) ?
'internal' : 'external';
- const connectorType = TopologyUtils.getConnectorType(e);
- const uniqueUri = TopologyUtils.getUniqueUri(e);
- if (
- connectorType !== 'kamelet' ||
-
CamelUtil.getKamelet(e)?.metadata.labels['camel.apache.org/kamelet.type'] !==
'action'
- ) {
- result.push(new TopologyOutgoingNode(id, type,
connectorType, route.id, title, filename, e, uniqueUri));
- }
- })
- result.push(...TopologyUtils.findDeadLetterChannelNodes(route,
filename))
- })
-
- })
+ try {
+ const filename = i.metadata.name;
+ const routes = i.spec.flows?.filter(flow => flow.dslName ===
'RouteDefinition');
+ routes?.forEach(route => {
+ const from: FromDefinition = route.from;
+ const elements = TopologyUtils.findOutgoingInStep(from,
[]);
+ elements.forEach((e: any) => {
+ const id = 'outgoing-' + route.id + '-' + e.id;
+ const title = CamelDisplayUtil.getStepDescription(e);
+ const type =
TopologyUtils.isElementInternalComponent(e) ? 'internal' : 'external';
+ const connectorType =
TopologyUtils.getConnectorType(e);
+ const uniqueUri = TopologyUtils.getUniqueUri(e);
+ if (
+ connectorType !== 'kamelet' ||
+
CamelUtil.getKamelet(e)?.metadata.labels['camel.apache.org/kamelet.type'] !==
'action'
+ ) {
+ result.push(new TopologyOutgoingNode(id, type,
connectorType, route.id, title, filename, e, uniqueUri));
+ }
+ });
+
result.push(...TopologyUtils.findDeadLetterChannelNodes(route, filename));
+ });
+ } catch (e) {
+ console.error(e);
+ }
+ });
return result;
- }
+ };
- static findDeadLetterChannelNodes(route: RouteDefinition, filename:
string):TopologyOutgoingNode[] {
- const result:TopologyOutgoingNode[] = [];
- const deadLetterChannel = route.errorHandler?.deadLetterChannel;
- const deadLetterUri = deadLetterChannel?.deadLetterUri;
- if (deadLetterChannel !== undefined && deadLetterUri !== undefined) {
- const parts = deadLetterUri.split(':');
- if (parts.length > 1 && INTERNAL_COMPONENTS.includes(parts[0])) {
- const id = 'outgoing-' + route.id + '-' +
deadLetterChannel?.id;
- const title =
CamelDisplayUtil.getStepDescription(deadLetterChannel);
- const type = 'internal';
- const connectorType = 'component';
- result.push(new TopologyOutgoingNode(id, type, connectorType,
route.id || '', title, filename, deadLetterChannel, deadLetterUri));
+ static findDeadLetterChannelNodes(route: RouteDefinition, filename:
string): TopologyOutgoingNode[] {
+ const result: TopologyOutgoingNode[] = [];
+ try {
+ const deadLetterChannel = route.errorHandler?.deadLetterChannel;
+ const deadLetterUri = deadLetterChannel?.deadLetterUri;
+ if (deadLetterChannel !== undefined && deadLetterUri !==
undefined) {
+ const parts = deadLetterUri.split(':');
+ if (parts.length > 1 &&
INTERNAL_COMPONENTS.includes(parts[0])) {
+ const id = 'outgoing-' + route.id + '-' +
deadLetterChannel?.id;
+ const title =
CamelDisplayUtil.getStepDescription(deadLetterChannel);
+ const type = 'internal';
+ const connectorType = 'component';
+ result.push(new TopologyOutgoingNode(id, type,
connectorType, route.id || '', title, filename, deadLetterChannel,
deadLetterUri));
+ }
}
+ } catch (e) {
+ console.error(e);
}
return result;
}
static findTopologyRouteConfigurationOutgoingNodes = (integrations:
Integration[]): TopologyOutgoingNode[] => {
- const result:TopologyOutgoingNode[] = [];
+ const result: TopologyOutgoingNode[] = [];
integrations.forEach(i => {
- const filename = i.metadata.name;
- const rcs = i.spec.flows?.filter(flow => flow.dslName ===
'RouteConfigurationDefinition');
- rcs?.forEach((rc: RouteConfigurationDefinition) => {
- const children: CamelElement[] = [];
- children.push(...rc.intercept || []);
- children.push(...rc.interceptFrom || []);
- children.push(...rc.interceptSendToEndpoint || []);
- children.push(...rc.onCompletion || []);
- children.push(...rc.onException || []);
- children.forEach(child => {
- const elements = TopologyUtils.findOutgoingInStep(child,
[]);
- elements.forEach((e: any) => {
+ try {
+ const filename = i.metadata.name;
+ const rcs = i.spec.flows?.filter(flow => flow.dslName ===
'RouteConfigurationDefinition');
+ rcs?.forEach((rc: RouteConfigurationDefinition) => {
+ const children: CamelElement[] = [];
+ children.push(...rc.intercept || []);
+ children.push(...rc.interceptFrom || []);
+ children.push(...rc.interceptSendToEndpoint || []);
+ children.push(...rc.onCompletion || []);
+ children.push(...rc.onException || []);
+ children.forEach(child => {
+ const elements =
TopologyUtils.findOutgoingInStep(child, []);
+ elements.forEach((e: any) => {
+ const id = 'outgoing-' + rc.id + '-' + e.id;
+ const title =
CamelDisplayUtil.getStepDescription(e);
+ const type =
TopologyUtils.isElementInternalComponent(e) ? 'internal' : 'external';
+ const connectorType =
TopologyUtils.getConnectorType(e);
+ const uniqueUri = TopologyUtils.getUniqueUri(e);
+ result.push(new TopologyOutgoingNode(id, type,
connectorType, rc.id || 'undefined', title, filename, e, uniqueUri));
+ });
+ });
+ if (rc.errorHandler?.deadLetterChannel) {
+ const e = rc.errorHandler?.deadLetterChannel;
const id = 'outgoing-' + rc.id + '-' + e.id;
const title = CamelDisplayUtil.getStepDescription(e);
- const type =
TopologyUtils.isElementInternalComponent(e) ? 'internal' : 'external';
- const connectorType =
TopologyUtils.getConnectorType(e);
- const uniqueUri = TopologyUtils.getUniqueUri(e);
+ const comp = e?.deadLetterUri?.split(':')?.[0];
+ const type = INTERNAL_COMPONENTS.includes(comp) ?
'internal' : 'external';
+ const connectorType = 'component';
+ const uniqueUri = e?.deadLetterUri;
result.push(new TopologyOutgoingNode(id, type,
connectorType, rc.id || 'undefined', title, filename, e, uniqueUri));
- })
- })
- if (rc.errorHandler?.deadLetterChannel) {
- const e = rc.errorHandler?.deadLetterChannel
- const id = 'outgoing-' + rc.id + '-' + e.id;
- const title = CamelDisplayUtil.getStepDescription(e);
- const comp = e?.deadLetterUri?.split(':')?.[0];
- const type = INTERNAL_COMPONENTS.includes(comp) ?
'internal' : 'external';
- const connectorType = 'component';
- const uniqueUri = e?.deadLetterUri
- result.push(new TopologyOutgoingNode(id, type,
connectorType, rc.id || 'undefined', title, filename, e, uniqueUri));
- }
- })
-
- })
+ }
+ });
+ } catch (e) {
+ console.error(e);
+ }
+ });
return result;
- }
+ };
static findOutgoingInStep = (step: CamelElement, result: CamelElement[]):
CamelElement[] => {
if (step !== undefined) {
const el = (step as any);
- if (outgoingDefinitions.includes(el.dslName)) {
- result.push(step);
- } else {
- const childElements =
CamelDefinitionApiExt.getElementChildrenDefinition(el.dslName);
- childElements.forEach(child => {
- if (child.multiple) {
- const sub = (el[child.name] as CamelElement[]);
- TopologyUtils.findOutgoingInSteps(sub, result);
- } else {
- const sub = (el[child.name] as CamelElement);
- TopologyUtils.findOutgoingInStep(sub, result);
- }
- })
+ try {
+ if (outgoingDefinitions.includes(el.dslName)) {
+ result.push(step);
+ } else {
+ const childElements =
CamelDefinitionApiExt.getElementChildrenDefinition(el.dslName);
+ childElements.forEach(child => {
+ if (child.multiple) {
+ const sub = (el[child.name] as CamelElement[]);
+ TopologyUtils.findOutgoingInSteps(sub, result);
+ } else {
+ const sub = (el[child.name] as CamelElement);
+ TopologyUtils.findOutgoingInStep(sub, result);
+ }
+ });
+ }
+ } catch (e) {
+ console.error(e);
}
}
return result;
- }
+ };
static findOutgoingInSteps = (steps: CamelElement[], result:
CamelElement[]): CamelElement[] => {
if (steps !== undefined && steps.length > 0) {
- steps.forEach(step => TopologyUtils.findOutgoingInStep(step,
result))
+ steps.forEach(step => TopologyUtils.findOutgoingInStep(step,
result));
}
return result;
- }
+ };
static getNodeIdByUriAndName(tins: TopologyIncomingNode[], uri: string,
name: string): string | undefined {
if (uri && name) {
- const node = tins
+ const node = tins
.filter(r => r.from.uri === uri
- && (r?.from?.parameters?.name === name ||
r?.from?.parameters?.address === name)
+ && (r?.from?.parameters?.name === name ||
r?.from?.parameters?.address === name),
).at(0);
if (node) {
return node.id;
@@ -326,17 +358,17 @@ export class TopologyUtils {
}
static getNodeIdByUri(tins: TopologyIncomingNode[], uri: string): string |
undefined {
- const parts = uri.split(":");
+ const parts = uri.split(':');
if (parts.length > 1) {
- return TopologyUtils.getNodeIdByUriAndName(tins, parts[0],
parts[1])
+ return TopologyUtils.getNodeIdByUriAndName(tins, parts[0],
parts[1]);
}
}
static getRouteIdByUriAndName(tins: TopologyIncomingNode[], uri: string,
name: string): string | undefined {
if (uri && name) {
- const node = tins
+ const node = tins
.filter(r => r.from.uri === uri
- && (r?.from?.parameters?.name === name ||
r?.from?.parameters?.address === name)
+ && (r?.from?.parameters?.name === name ||
r?.from?.parameters?.address === name),
).at(0);
if (node) {
return 'route-' + node.routeId;
@@ -347,14 +379,14 @@ export class TopologyUtils {
static getNodeIdByUniqueUri(tins: TopologyIncomingNode[], uniqueUri:
string): string [] {
const result: string[] = [];
tins.filter(r => r.uniqueUri === uniqueUri)
- ?.forEach(node => result.push(node.id))
+ ?.forEach(node => result.push(node.id));
return result;
}
static getRouteIdByUri(tins: TopologyIncomingNode[], uri: string): string
| undefined {
- const parts = uri.split(":");
+ const parts = uri.split(':');
if (parts.length > 1) {
- return TopologyUtils.getRouteIdByUriAndName(tins, parts[0],
parts[1])
+ return TopologyUtils.getRouteIdByUriAndName(tins, parts[0],
parts[1]);
}
}
}