Skip to content

Commit

Permalink
Fix kamelet binding edge and added layout constraints
Browse files Browse the repository at this point in the history
  • Loading branch information
karthikjeeyar committed Jan 21, 2022
1 parent 3f8c8cb commit 6b2011a
Show file tree
Hide file tree
Showing 15 changed files with 113 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ type PodOverviewItemProps = {
const PodsOverviewList: React.FC<PodOverviewListProps> = ({ pods }) => (
<ul className="list-group">
{_.map(pods, (pod) => (
<PodOverviewItem key={pod.metadata?.uid} pod={pod} />
<PodOverviewItem key={pod.metadata.uid} pod={pod} />
))}
</ul>
);
Expand Down
3 changes: 3 additions & 0 deletions frontend/packages/knative-plugin/console-extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -1570,6 +1570,9 @@
"adapt": {
"$codeRef": "knativeTopologySidebar.getEventSinkPodsApdapter"
}
},
"flags": {
"required": ["KNATIVE_SERVING", "KNATIVE_EVENTING"]
}
}
]
8 changes: 4 additions & 4 deletions frontend/packages/knative-plugin/src/actions/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,13 +277,13 @@ export const topologyServerlessActionsFilter = (
};

export const useKnativeEventSinkActionProvider = (element: Node) => {
const resource = element.getData()?.resources?.obj;
const type = element.getType();
const resource = element.getData()?.resources?.obj || {};
const [k8sModel] = useK8sModel(referenceFor(resource));
const actions = React.useMemo(() => {
if (type !== TYPE_EVENT_SINK) return undefined;
const type = element.getType();
if (type !== TYPE_EVENT_SINK || !k8sModel) return undefined;
return k8sModel && resource ? getCommonResourceActions(k8sModel, resource) : undefined;
}, [type, k8sModel, resource]);
}, [element, k8sModel, resource]);

return React.useMemo(() => {
if (!actions) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
K8sResourceKind,
} from '@console/internal/module/k8s';
import { TopologyDataResources } from '@console/topology/src/topology-types';
import { CamelKameletModel, DomainMappingModel } from '../..';
import {
SERVERLESS_FUNCTION_LABEL,
EVENTING_IMC_KIND,
Expand All @@ -23,6 +22,8 @@ import {
EVENT_SOURCE_PING_KIND,
} from '../../const';
import {
CamelKameletModel,
DomainMappingModel,
ServiceModel,
RevisionModel,
RouteModel,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { AbstractAnchor, Point } from '@patternfly/react-topology';

export default class EventSinkSourceAnchor extends AbstractAnchor {
getLocation(): Point {
return this.getReferencePoint();
}

getReferencePoint(): Point {
const bounds = this.owner.getBounds();
return new Point(bounds.right(), bounds.y + bounds.height / 2);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { AbstractAnchor, Point } from '@patternfly/react-topology';
import { EVENT_MARKER_RADIUS } from '../../const';

export default class EventSinkTargetAnchor extends AbstractAnchor {
getLocation(): Point {
return this.getReferencePoint();
}

getReferencePoint(): Point {
const bounds = this.owner.getBounds();
return new Point(bounds.x - EVENT_MARKER_RADIUS, bounds.y + bounds.height / 2);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ type EventSinkLinkProps = {
};

const EventSinkLink: React.FC<EventSinkLinkProps> = ({ element, ...others }) => {
const markerPoint = element.getStartPoint();
const markerPoint = element.getEndPoint();

return (
<BaseEdge className="odc-event-source-link" element={element} {...others}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
createSvgIdUrl,
WithCreateConnectorProps,
Edge,
useAnchor,
AnchorEnd,
} from '@patternfly/react-topology';
import * as classNames from 'classnames';
import {
Expand All @@ -31,7 +33,8 @@ import {
} from '@console/topology/src/filters';
import { getEventSourceIcon } from '../../../utils/get-knative-icon';
import { usePodsForRevisions } from '../../../utils/usePodsForRevisions';
import { TYPE_KAFKA_CONNECTION_LINK } from '../../const';
import { TYPE_EVENT_SINK_LINK, TYPE_KAFKA_CONNECTION_LINK } from '../../const';
import EventSinkTargetAnchor from '../anchors/EventSinkTargetAnchor';

import './EventSource.scss';

Expand Down Expand Up @@ -59,6 +62,7 @@ const EventSink: React.FC<EventSinkProps> = ({
onHideCreateConnector,
}) => {
const svgAnchorRef = useSvgAnchor();
useAnchor(EventSinkTargetAnchor, AnchorEnd.target, TYPE_EVENT_SINK_LINK);
const [hover, hoverRef] = useHover();
const groupRefs = useCombineRefs(dragNodeRef, dndDropRef, hoverRef);
const { data, resources, resource } = element.getData();
Expand All @@ -72,7 +76,7 @@ const EventSink: React.FC<EventSinkProps> = ({
const isKafkaConnectionLinkPresent =
element.getSourceEdges()?.filter((edge: Edge) => edge.getType() === TYPE_KAFKA_CONNECTION_LINK)
.length > 0;
const revisionIds = resources.revisions.map((revision) => revision.metadata.uid);
const revisionIds = resources.revisions?.map((revision) => revision.metadata.uid);
const { loaded, loadError, pods } = usePodsForRevisions(revisionIds, resource.metadata.namespace);
const donutStatus = React.useMemo(() => {
if (loaded && !loadError) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ import {
EventingBrokerModel,
EventingSubscriptionModel,
} from '../../../models';
import { TYPE_EVENT_SINK_LINK } from '../../const';
import EventSinkSourceAnchor from '../anchors/EventSinkSourceAnchor';
import PubSubSourceAnchor from '../anchors/PubSubSourceAnchor';
import PubSubTargetAnchor from '../anchors/PubSubTargetAnchor';

Expand Down Expand Up @@ -76,6 +78,7 @@ const EventingPubSubNode: React.FC<EventingPubSubNodeProps> = ({
useAnchor(PubSubTargetAnchor, AnchorEnd.target);
useAnchor(RectAnchor, AnchorEnd.source, TYPE_AGGREGATE_EDGE);
useAnchor(RectAnchor, AnchorEnd.target, TYPE_AGGREGATE_EDGE);
useAnchor(EventSinkSourceAnchor, AnchorEnd.source, TYPE_EVENT_SINK_LINK);
const [hover, hoverRef] = useHover();

const { t } = useTranslation();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export const getKnativeTopologyDataModel = (
if (n.type === NodeType.KnService) {
if (
camelSinkKameletBindings.findIndex((binding) =>
n.resource.metadata?.labels?.[CAMEL_SOURCE_INTEGRATION].startsWith(
n.resource.metadata?.labels?.[CAMEL_SOURCE_INTEGRATION]?.startsWith(
binding.metadata?.name,
),
) > -1
Expand All @@ -112,7 +112,7 @@ export const getKnativeTopologyDataModel = (
if (n.type === NodeType.Revision) {
if (
camelSinkKameletBindings.findIndex((binding) =>
n.resource.metadata?.labels?.[CAMEL_SOURCE_INTEGRATION].startsWith(
n.resource.metadata?.labels?.[CAMEL_SOURCE_INTEGRATION]?.startsWith(
binding.metadata?.name,
),
) > -1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -746,24 +746,25 @@ const getEventSourcesData = (sinkUri: string, resources) => {
const getApiGroup = (apiVersion: string) => groupVersionFor(apiVersion)?.group;

export const getEventSinkTopologyEdgeItems = (resource: K8sResourceKind, resources) => {
const uid = resource?.metadata?.uid;
const target = resource?.spec?.source?.ref;
let sinkTarget;
const targetRef = referenceFor(target);
if (target?.kind === EventingBrokerModel.kind) {
sinkTarget = resources.brokers.data.find((broker) => broker.metadata.name === target.name);
const targetUid = resource?.metadata?.uid;
const source = resource?.spec?.source?.ref;
if (!targetUid || !source) return [];
let sinkSource;
const targetRef = referenceFor(source);
if (source?.kind === EventingBrokerModel.kind) {
sinkSource = resources.brokers.data.find((broker) => broker.metadata.name === source.name);
} else {
sinkTarget = resources[targetRef].data.find((res) => res.metadata.name === target.name);
sinkSource = resources[targetRef].data.find((res) => res.metadata.name === source.name);
}

if (sinkTarget) {
if (sinkSource) {
return [
{
id: `${uid}_${sinkTarget.metadata.uid}`,
id: `${sinkSource.metadata.uid}_${targetUid}`,
type: EdgeType.EventSink,
label: i18next.t('knative-plugin~Event sink connector'),
target: sinkTarget.metadata.uid,
source: uid,
target: targetUid,
source: sinkSource.metadata.uid,
},
];
}
Expand Down Expand Up @@ -1119,30 +1120,17 @@ export const createEventSinkTopologyNodeData = (
resource: K8sResourceKind,
overviewItem: OverviewItem,
type: string,
defaultIcon: string,
operatorBackedService: boolean = false,
): TopologyDataObject => {
const { monitoringAlerts = [] } = overviewItem;
const dcUID = _.get(resource, 'metadata.uid');
const deploymentsLabels = _.get(resource, 'metadata.labels', {});
const deploymentsAnnotations = _.get(resource, 'metadata.annotations', {});

const builderImageIcon =
getImageForIconClass(`icon-${deploymentsLabels['app.openshift.io/runtime']}`) ||
getImageForIconClass(`icon-${deploymentsLabels['app.kubernetes.io/name']}`);
return {
id: dcUID,
name: resource?.metadata.name || deploymentsLabels['app.kubernetes.io/instance'],
name: resource?.metadata.name,
type,
resource,
resources: { ...overviewItem, isOperatorBackedService: operatorBackedService },
data: {
monitoringAlerts,
kind: referenceFor(resource),
editURL: deploymentsAnnotations['app.openshift.io/edit-url'],
vcsURI: deploymentsAnnotations['app.openshift.io/vcs-uri'],
vcsRef: deploymentsAnnotations['app.openshift.io/vcs-ref'],
builderImage: builderImageIcon || defaultIcon,
isKnativeResource: type === NodeType.EventSink,
kameletType: KameletType.Sink,
},
Expand All @@ -1160,12 +1148,7 @@ export const transformKnNodeData = (
const item = createKnativeDeploymentItems(res, resources, utils);
switch (type) {
case NodeType.EventSink: {
const data = createEventSinkTopologyNodeData(
res,
item,
type,
getImageForIconClass(`icon-openshift`),
);
const data = createEventSinkTopologyNodeData(res, item, type);
const itemData = getOwnedEventSinkData(res, data, resources);
knDataModel.nodes.push(...getKnativeTopologyNodeItems(res, type, itemData, resources));
knDataModel.edges.push(...getEventSinkTopologyEdgeItems(res, resources));
Expand Down Expand Up @@ -1312,15 +1295,15 @@ export const isOperatorBackedKnResource = (
export const getKameletSinkAndSourceBindings = (resources) => {
const camelKameletBindingResources: K8sResourceKind[] = resources?.kameletbindings?.data ?? [];
const camelKameletResources: K8sResourceKind[] =
resources?.kamelets.data.length > 0
? resources?.kamelets?.data
resources?.kamelets?.data?.length > 0
? resources.kamelets.data
: resources?.kameletGlobalNS?.data ?? [];
const sinkCamelKameletResources: K8sResourceKind[] = camelKameletResources.filter(
(camelKamelet) => camelKamelet.metadata.labels['camel.apache.org/kamelet.type'] === 'sink',
);
return camelKameletBindingResources.reduce(
({ camelSinkKameletBindings: sink, camelSourceKameletBindings: source }, binding) => {
const sinkResource = binding.spec.sink.ref.name;
const sinkResource = binding?.spec?.sink?.ref?.name;
sinkCamelKameletResources.findIndex(
(kameletSink) => kameletSink.metadata.name === sinkResource,
) > -1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
TYPE_EVENT_PUB_SUB,
TYPE_EVENT_PUB_SUB_LINK,
TYPE_SINK_URI,
TYPE_EVENT_SINK_LINK,
} from '../const';

const getNodeTimeStamp = (node: ColaNode): Date => {
Expand All @@ -37,7 +38,9 @@ const alignNodeConnector = (
e.element.getType() === type &&
!e.target.isFixed &&
!e.source.isFixed &&
(e.target.element === g.element || e.target.element.getParent() === g.element),
(e.target.element === g.element ||
e.source.element === g.element ||
e.target.element.getParent() === g.element),
)
.sort((l1: ColaLink, l2: ColaLink) => nodeSorter(l1.source, l2.source));
if (connectorLinks.length) {
Expand Down Expand Up @@ -68,14 +71,26 @@ const alignNodeConnector = (
offset: nextOffset + link.source.height / 2,
});
}
// Keep the event sources to the left
constraints.push({
axis: 'x',
left: link.source.index,
right: filteredNode.index,
gap: serviceDistance + link.source.width / 2 + options.linkDistance,
equality: true,
});

if (type === TYPE_EVENT_SINK_LINK) {
// Keep the event sink to the right
constraints.push({
axis: 'x',
left: link.source.index,
right: link.target.index,
gap: serviceDistance + link.source.width / 2 + options.linkDistance,
equality: true,
});
} else {
// Keep the event sources to the left
constraints.push({
axis: 'x',
left: link.source.index,
right: filteredNode.index,
gap: serviceDistance + link.source.width / 2 + options.linkDistance,
equality: true,
});
}
nextOffset += link.source.height;
});
constraints.push(linkNodeConstraint);
Expand Down Expand Up @@ -142,7 +157,21 @@ export const layoutConstraints = (
options,
filteredNode,
);
constraints = [...constraints, ...pubSubLinksConnector, ...eventSourceLinksConnector];

const eventSinkLinksConnector = alignNodeConnector(
edges,
TYPE_EVENT_SINK_LINK,
g,
options,
filteredNode,
);

constraints = [
...constraints,
...eventSourceLinksConnector,
...pubSubLinksConnector,
...eventSinkLinksConnector,
];
});
return constraints;
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@ import * as React from 'react';
import { Edge } from '@patternfly/react-topology';
import TopologyEdgeResourcesPanel from '@console/topology/src/components/side-bar/TopologyEdgeResourcesPanel';
import {
TYPE_EVENT_SINK_LINK,
TYPE_EVENT_SOURCE_LINK,
TYPE_KAFKA_CONNECTION_LINK,
TYPE_REVISION_TRAFFIC,
} from '../const';

export const getKnativeConnectorSidepanelResourceSection = (element: Edge) => {
if (
![TYPE_REVISION_TRAFFIC, TYPE_EVENT_SOURCE_LINK, TYPE_KAFKA_CONNECTION_LINK].includes(
element.getType(),
)
![
TYPE_REVISION_TRAFFIC,
TYPE_EVENT_SOURCE_LINK,
TYPE_KAFKA_CONNECTION_LINK,
TYPE_EVENT_SINK_LINK,
].includes(element.getType())
) {
return undefined;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const getKnativeSidepanelEventSinkSection = (element: GraphElement) => {
export const usePodsForEventSink = (resource: K8sResourceKind, data) => {
const { t } = useTranslation();
const { pods, loaded, loadError } = usePodsForRevisions(
data?.revisions.map((r) => r.metadata.uid) ?? '',
data?.revisions?.map((r) => r.metadata.uid) ?? '',
resource.metadata.namespace,
);
return React.useMemo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { WatchK8sResources } from '@console/dynamic-plugin-sdk';
import { FirehoseResource } from '@console/internal/components/utils';
import { K8sResourceKind, PodKind, referenceForModel } from '@console/internal/module/k8s';
import { KafkaConnectionModel } from '@console/rhoas-plugin/src/models';
import { CamelKameletModel, GLOBAL_OPERATOR_NS } from '..';
import { KNATIVE_SERVING_LABEL } from '../const';
import { GLOBAL_OPERATOR_NS, KNATIVE_SERVING_LABEL } from '../const';
import {
CamelKameletModel,
ServiceModel,
RevisionModel,
ConfigurationModel,
Expand Down

0 comments on commit 6b2011a

Please sign in to comment.