Skip to content

Commit

Permalink
Topology creates edge between consumer-producer
Browse files Browse the repository at this point in the history
  • Loading branch information
mgubaidullin committed Oct 20, 2023
1 parent 31a94c6 commit 8807c3e
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 38 deletions.
6 changes: 1 addition & 5 deletions karavan-core/src/core/api/CamelDefinitionApiExt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -690,11 +690,7 @@ export class CamelDefinitionApiExt {
return [];
};

static getParametersValue = (
element: CamelElement | undefined,
propertyName: string,
pathParameter?: boolean,
): any => {
static getParametersValue = (element: CamelElement | undefined, propertyName: string, pathParameter?: boolean): any => {
if (element && (element as any).parameters) {
return (element as any).parameters[propertyName];
}
Expand Down
16 changes: 9 additions & 7 deletions karavan-core/src/core/api/CamelUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,15 @@ export class CamelUtil {
}
};

static getKameletProperties = (element: any): Property[] => {
static getKameletProperties = (element: any, requiredOnly: boolean = false): Property[] => {
const kamelet = CamelUtil.getKamelet(element);
return kamelet ? KameletApi.getKameletProperties(kamelet?.metadata.name) : [];
const props:Property[] = kamelet ? KameletApi.getKameletProperties(kamelet?.metadata.name) : [];
if (requiredOnly) {
const required = kamelet?.spec.definition.required;
return props.filter(value => required?.includes(value.id));
} else {
return props;
}
};

static getKameletRequiredParameters = (element: any): string[] => {
Expand Down Expand Up @@ -229,11 +235,7 @@ export class CamelUtil {
if (!CamelUtil.isKameletComponent(element)) {
const requiredProperties = CamelUtil.getComponentProperties(element).filter(p => p.required);
for (const property of requiredProperties) {
const value = CamelDefinitionApiExt.getParametersValue(
element,
property.name,
property.kind === 'path',
);
const value = CamelDefinitionApiExt.getParametersValue(element, property.name, property.kind === 'path');
if (value === undefined || (property.type === 'string' && value.trim().length === 0)) {
result[0] = false;
result[1].push(`${property.displayName} is required`);
Expand Down
62 changes: 58 additions & 4 deletions karavan-core/src/core/api/TopologyUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ import {
import { ComponentApi } from './ComponentApi';
import { CamelDefinitionApiExt } from './CamelDefinitionApiExt';
import { CamelDisplayUtil } from './CamelDisplayUtil';
import { CamelMetadataApi } from '../model/CamelMetadata';
import { CamelUtil } from './CamelUtil';

const outgoingDefinitions: string[] = ['ToDefinition', 'KameletDefinition', 'ToDynamicDefinition', "PollEnrichDefinition", "EnrichDefinition", "WireTapDefinition", "SagaDefinition"];

Expand All @@ -58,6 +60,48 @@ export class TopologyUtils {
(TopologyUtils.isComponentInternal(component.component.label) || TopologyUtils.hasInternalUri(element));
}

static getConnectorType = (element: CamelElement): 'component' | 'kamelet' => {
return CamelUtil.isKameletComponent(element) ? 'kamelet' : 'component';
}

static cutKameletUriSuffix = (uri: string): string => {
if (uri.endsWith("-sink")) {
return uri.substring(0, uri.length - 5);
} else if (uri.endsWith("-source")) {
return uri.substring(0, uri.length - 7);
} 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 className = element.dslName;
if (className === 'FromDefinition' || className === 'ToDefinition') {
if (!CamelUtil.isKameletComponent(element)) {
const requiredProperties = CamelUtil.getComponentProperties(element).filter(p => p.required);
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 + "&";
}
}
} else {
const requiredProperties = CamelUtil.getKameletProperties(element, true);
for (const property of requiredProperties) {
const value = CamelDefinitionApiExt.getParametersValue(element, property.id);
if (value !== undefined && property.type === 'string' && value.trim().length > 0) {
result = result + property.id + "=" + value + "&";
}
}
}
}
return result;
}

static isComponentInternal = (label: string): boolean => {
const labels = label.split(",");
if (labels.includes('core') && (
Expand Down Expand Up @@ -143,7 +187,9 @@ export class TopologyUtils {
const id = 'incoming-' + r.id;
const title = CamelDisplayUtil.getTitle(r.from);
const type = TopologyUtils.isElementInternalComponent(r.from) ? 'internal' : 'external';
return new TopologyIncomingNode(id, type, r.id, title, filename, r.from);
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)
})
Expand Down Expand Up @@ -177,7 +223,9 @@ export class TopologyUtils {
const id = 'outgoing-' + route.id + '-' + e.id;
const title = CamelDisplayUtil.getTitle(e);
const type = TopologyUtils.isElementInternalComponent(e) ? 'internal' : 'external';
result.push(new TopologyOutgoingNode(id, type, route.id, title, filename, e));
const connectorType = TopologyUtils.getConnectorType(e);
const uniqueUri = TopologyUtils.getUniqueUri(e);
result.push(new TopologyOutgoingNode(id, type, connectorType, route.id, title, filename, e, uniqueUri));
})
})

Expand Down Expand Up @@ -213,8 +261,6 @@ export class TopologyUtils {
return result;
}



static getNodeIdByUriAndName(tins: TopologyIncomingNode[], uri: string, name: string): string | undefined {
if (uri && name) {
const node = tins
Expand Down Expand Up @@ -242,6 +288,14 @@ export class TopologyUtils {
}
}

static getNodeIdByUniqueUri(tins: TopologyIncomingNode[], uniqueUri: string): string | undefined {
const node = tins
.filter(r => r.uniqueUri === uniqueUri).at(0);
if (node) {
return node.id;
}
}

static getRouteIdByUri(tins: TopologyIncomingNode[], uri: string): string | undefined {
const parts = uri.split(":");
if (parts.length > 1) {
Expand Down
18 changes: 14 additions & 4 deletions karavan-core/src/core/model/TopologyDefinition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,23 @@ export class TopologyRestNode {
export class TopologyIncomingNode {
id: string;
type: 'internal' | 'external';
connectorType: 'component' | 'kamelet';
routeId: string;
title: string;
fileName: string;
from: FromDefinition;

constructor(id: string, type: 'internal' | 'external', routeId: string, title: string, fileName: string, from: FromDefinition) {
uniqueUri?: string;


constructor(id: string, type: "internal" | "external", connectorType: "component" | "kamelet", routeId: string, title: string, fileName: string, from: FromDefinition, uniqueUri: string) {
this.id = id;
this.type = type;
this.connectorType = connectorType;
this.routeId = routeId;
this.title = title;
this.fileName = fileName;
this.from = from;
this.uniqueUri = uniqueUri;
}
}

Expand All @@ -75,17 +80,22 @@ export class TopologyRouteNode {
export class TopologyOutgoingNode {
id: string;
type: 'internal' | 'external';
connectorType: 'component' | 'kamelet';
routeId: string;
title: string;
fileName: string;
step: CamelElement;
uniqueUri?: string;

constructor(id: string, type: 'internal' | 'external', routeId: string, title: string, fileName: string, step: CamelElement) {

constructor(id: string, type: "internal" | "external", connectorType: "component" | "kamelet", routeId: string, title: string, fileName: string, step: CamelElement, uniqueUri: string) {
this.id = id;
this.type = type
this.type = type;
this.connectorType = connectorType;
this.routeId = routeId;
this.title = title;
this.fileName = fileName;
this.step = step;
this.uniqueUri = uniqueUri;
}
}
74 changes: 63 additions & 11 deletions karavan-designer/public/example/demo.camel.yaml
Original file line number Diff line number Diff line change
@@ -1,20 +1,72 @@
- route:
id: route-fbf9
id: route-605c
from:
uri: activemq
id: from-3131
parameters:
destinationName: test
steps:
- marshal:
id: marshal-1452
- log:
message: ${body}
id: log-c8e7
- route:
id: route-e4bb
from:
uri: kamelet:beer-source
id: from-9d5b
uri: kamelet:timer-source
id: from-dd68
parameters:
message: '1111'
steps:
- to:
uri: activemq
id: to-0fd2
id: to-4fca
parameters:
destinationName: test
- route:
id: route-0a30
from:
uri: amqp
id: from-ca7d
parameters:
destinationName: hello
steps:
- log:
message: ${body}
id: log-d0f4
- to:
uri: asterisk
id: to-b9ca
uri: kamelet:kafka-not-secured-sink
id: to-c86f
parameters:
topic: topic1
bootstrapServers: localhost:9092
- route:
id: route-e39c
from:
uri: kamelet:kafka-not-secured-source
id: from-d419
parameters:
bootstrapServers: localhost:9092
topic: topic1
steps:
- to:
uri: aws2-ec2
id: to-3c6a
uri: direct
id: to-7401
parameters:
name: hello
- route:
id: route-605c
id: route-be79
from:
uri: activemq
id: from-3131
uri: kamelet:kafka-not-secured-source
id: from-27e8
parameters:
bootstrapServers: localhost:9092
topic: topic2
- route:
id: hello
from:
uri: direct
id: from-db43
parameters:
name: hello
7 changes: 6 additions & 1 deletion karavan-designer/src/topology/CustomNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,16 @@ function getIcon(data: any) {
const CustomNode: React.FC<any> = observer(({ element, ...rest }) => {

const data = element.getData();
const badge:string = data.badge?.substring(0,1).toUpperCase();

return (
<DefaultNode
badge={badge}
showStatusDecorator
className="common-node"
element={element} {...rest}
scaleLabel={false}
element={element}
{...rest}
>
{getIcon(data)}
</DefaultNode>
Expand Down
31 changes: 26 additions & 5 deletions karavan-designer/src/topology/TopologyApi.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ import {
TopologyRestNode,
TopologyRouteNode
} from "karavan-core/lib/model/TopologyDefinition";
import CustomGroup from "./CustomGroup";
import CustomEdge from "./CustomEdge";
import {IntegrationFile} from "./TopologyStore";
import CustomGroup from "./CustomGroup";

const NODE_DIAMETER = 60;

Expand All @@ -62,7 +62,7 @@ export function getIncomingNodes(tins: TopologyIncomingNode[]): NodeModel[] {
status: NodeStatus.default,
data: {
isAlternate: false,
badge: tin.type,
badge: tin.connectorType,
icon: 'element',
type: 'step',
step: tin.from,
Expand Down Expand Up @@ -110,7 +110,7 @@ export function getOutgoingNodes(tons: TopologyOutgoingNode[]): NodeModel[] {
icon: 'element',
type: 'step',
step: tin.step,
badge: tin.type,
badge: tin.connectorType,
fileName: tin.fileName
}
}
Expand Down Expand Up @@ -146,6 +146,26 @@ export function getOutgoingEdges(tons: TopologyOutgoingNode[]): EdgeModel[] {
});
}

export function getExternalEdges(tons: TopologyOutgoingNode[], tins: TopologyIncomingNode[]): EdgeModel[] {
const result: EdgeModel[]= [];
tons.filter(ton => ton.type === 'external').forEach((ton, index) => {
const uniqueUri = ton.uniqueUri;
if (uniqueUri) {
const target = TopologyUtils.getNodeIdByUniqueUri(tins, uniqueUri);
const node: EdgeModel = {
id: 'external-' + ton.id + '-' + index,
type: 'edge',
source: ton.id,
target: target,
edgeStyle: EdgeStyle.dotted,
animationSpeed: EdgeAnimationSpeed.slow
}
if (target) result.push(node);
}
});
return result;
}

export function getRestNodes(tins: TopologyRestNode[]): NodeModel[] {
return tins.map(tin => {
return {
Expand Down Expand Up @@ -217,8 +237,8 @@ export function getModel(files: IntegrationFile[]): Model {
const nodes: NodeModel[] = [];
const groups: NodeModel[] = troutes.map(r => {
const children = [r.id]
children.push(... tins.filter(i => i.routeId === r.routeId && i.type === 'external').map(i => i.id));
children.push(... tons.filter(i => i.routeId === r.routeId && i.type === 'external').map(i => i.id));
children.push(...tins.filter(i => i.routeId === r.routeId && i.type === 'external').map(i => i.id));
children.push(...tons.filter(i => i.routeId === r.routeId && i.type === 'external').map(i => i.id));
return {
id: 'group-' + r.routeId,
children: children,
Expand All @@ -242,6 +262,7 @@ export function getModel(files: IntegrationFile[]): Model {
edges.push(...getOutgoingEdges(tons));
edges.push(...getRestEdges(trestns, tins));
edges.push(...getInternalEdges(tons, tins));
edges.push(...getExternalEdges(tons,tins));

return {nodes: nodes, edges: edges, graph: {id: 'g1', type: 'graph', layout: 'Dagre'}};
}
Expand Down
1 change: 0 additions & 1 deletion karavan-designer/src/topology/TopologyTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ export function TopologyTab (props: Props) {
}

const controller = React.useMemo(() => {
console.log(props.files)
const model = getModel(props.files);
const newController = new Visualization();
newController.registerLayoutFactory((_, graph) => new DagreLayout(graph));
Expand Down

0 comments on commit 8807c3e

Please sign in to comment.