Skip to content

Commit

Permalink
feat(RouteConfiguration): Add support for RouteConfiguration entity
Browse files Browse the repository at this point in the history
This commit adds support for RouteConfiguration entity.

fix: #492

Temp: Remove constructor parameter type from AbstractCamelVisualEntity

Temp: Make OnException inherit from AbstractCamelVisualEntity

Temp: Restore getArray util function

Temp: Remove duplicated methods in OnException

Temp: Remove duplicated methods in CamelRouteConfiguration

Temp: Refactor getNodeLabel

Temp: Rework errorHandler node label

Temp: Remove more duplicated methods in OnException

Temp: Add intercept, interceptFrom, interceptSendToEndpoint and onCompletion
  • Loading branch information
lordrip committed Apr 15, 2024
1 parent 9010c88 commit fa84c30
Show file tree
Hide file tree
Showing 29 changed files with 962 additions and 291 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
*/
public class CamelYamlDslSchemaProcessor {
private static final String PROCESSOR_DEFINITION = "org.apache.camel.model.ProcessorDefinition";
private static final String ROUTE_CONFIGURATION_DEFINITION = "org.apache.camel.model.RouteConfigurationDefinition";
private static final String LOAD_BALANCE_DEFINITION = "org.apache.camel.model.LoadBalanceDefinition";
private static final String EXPRESSION_SUB_ELEMENT_DEFINITION = "org.apache.camel.model.ExpressionSubElementDefinition";
private static final String SAGA_DEFINITION = "org.apache.camel.model.SagaDefinition";
Expand Down Expand Up @@ -212,9 +213,10 @@ public Map<String, ObjectNode> getProcessors() throws Exception {
var processors = relocatedDefinitions
.withObject(PROCESSOR_DEFINITION)
.withObject("/properties");
addRouteConfigurationProcessors(relocatedDefinitions, processors);

var answer = new LinkedHashMap<String, ObjectNode>();
for( var processorEntry : processors) {
for (var processorEntry : processors) {
var processorFQCN = getNameFromRef((ObjectNode)processorEntry);
if (processorBlocklist.contains(processorFQCN)) {
continue;
Expand Down Expand Up @@ -266,6 +268,22 @@ public Map<String, ObjectNode> getProcessors() throws Exception {
return answer;
}

private void addRouteConfigurationProcessors(ObjectNode relocatedDefinitions, ObjectNode processors) {
var routeConfigurationProcessor = relocatedDefinitions
.withObject(ROUTE_CONFIGURATION_DEFINITION)
.withObject("/properties");
var interceptProcessor = routeConfigurationProcessor.withObject("intercept").withObject("items").withObject("properties");
var interceptFromProcessor = routeConfigurationProcessor.withObject("interceptFrom").withObject("items").withObject("properties");
var interceptSendToEndpointProcessor = routeConfigurationProcessor.withObject("interceptSendToEndpoint").withObject("items").withObject("properties");
var onExceptionProcessor = routeConfigurationProcessor.withObject("onException").withObject("items").withObject("properties");
var onCompletionProcessor = routeConfigurationProcessor.withObject("onCompletion").withObject("items").withObject("properties");
processors.setAll(interceptProcessor);
processors.setAll(interceptFromProcessor);
processors.setAll(interceptSendToEndpointProcessor);
processors.setAll(onExceptionProcessor);
processors.setAll(onCompletionProcessor);
}

private ObjectNode extractFromOneOf(String name, ObjectNode definition) throws Exception {
if (!definition.has("oneOf")) {
return definition;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ public void testModelEnumParameter() throws Exception {

@Test
public void testGetPatternCatalog() throws Exception {
assertTrue(processorCatalog.size() > 55 && processorCatalog.size() < 65);
assertTrue(processorCatalog.size() > 55 && processorCatalog.size() < 70);
var choiceModel = processorCatalog.withObject("/choice").withObject("/model");
assertEquals("choice", choiceModel.get("name").asText());
var aggregateSchema = processorCatalog.withObject("/aggregate").withObject("/propertiesSchema");
Expand All @@ -231,6 +231,11 @@ public void testGetPatternCatalog() throws Exception {
assertEquals("object", parameters.get("type").asText());
}

@Test
public void testRouteConfigurationCatalog() throws Exception {
List.of("intercept", "interceptFrom", "interceptSendToEndpoint", "onCompletion", "onException").forEach(name -> assertTrue(entityCatalog.has(name), name));
}

@Test
public void testPatternEnumParameter() throws Exception {
checkEnumParameters(processorCatalog);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,9 @@ export class CanvasService {
this.edges = [];
this.visitedNodes = [];

const firstChild = vizNode.getChildren()?.[0];
if (vizNode.data.isGroup && firstChild) {
this.appendNodesAndEdges(firstChild);
const children = vizNode.getChildren();
if (vizNode.data.isGroup && children) {
children.forEach((child) => this.appendNodesAndEdges(child));
const containerId = vizNode.getBaseEntity()?.getId() ?? 'Unknown';
const group = this.getContainer(containerId, {
label: containerId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import {
Layer,
isNode,
observer,
withSelection,
withContextMenu,
withSelection,
} from '@patternfly/react-topology';
import { FunctionComponent } from 'react';
import { AddStepMode } from '../../../models/visualization/base-visual-entity';
import { CanvasNode } from '../Canvas/canvas.models';
import { ItemInsertChildNode } from './ItemInsertChildNode';
import { ItemRemoveGroup } from './ItemRemoveGroup';

type IDefaultGroup = Parameters<typeof DefaultGroup>[0];
Expand Down Expand Up @@ -44,5 +46,10 @@ const CustomGroup: FunctionComponent<ICustomGroup> = observer(({ element, ...res
});

export const CustomGroupWithSelection = withContextMenu(() => [
<ItemInsertChildNode
key="context-menu-item-insert-special"
data-testid="context-menu-item-insert-special"
mode={AddStepMode.InsertSpecialChildStep}
/>,
<ItemRemoveGroup key="context-menu-container-remove" data-testid="context-menu-container-remove" />,
])(withSelection()(CustomGroup));
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { ItemAddNode } from './ItemAddNode';
import { ItemInsertChildNode } from './ItemInsertChildNode';
import { ItemRemoveNode } from './ItemRemoveNode';
import { ItemReplaceNode } from './ItemReplaceNode';
import { ItemRemoveGroup } from './ItemRemoveGroup';

interface CustomNodeProps extends WithSelectionProps {
element: Node<CanvasNode, CanvasNode['data']>;
Expand Down Expand Up @@ -78,4 +79,5 @@ export const CustomNodeWithSelection: typeof DefaultNode = withContextMenu(() =>
/>,
<ItemReplaceNode key="context-menu-item-replace" data-testid="context-menu-item-replace" />,
<ItemRemoveNode key="context-menu-item-remove" data-testid="context-menu-item-remove" />,
<ItemRemoveGroup key="context-menu-container-remove" data-testid="context-menu-container-remove" />,
])(withSelection()(CustomNode) as typeof DefaultNode) as typeof DefaultNode;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { TrashIcon } from '@patternfly/react-icons';
import { ContextMenuItem, ElementContext, ElementModel, GraphElement } from '@patternfly/react-topology';
import { FunctionComponent, useCallback, useContext } from 'react';
import { FunctionComponent, useCallback, useContext, useMemo } from 'react';
import { IDataTestID } from '../../../models';
import { EntitiesContext } from '../../../providers/entities.provider';
import { CanvasNode } from '../Canvas/canvas.models';
Expand All @@ -10,15 +10,20 @@ export const ItemRemoveGroup: FunctionComponent<IDataTestID> = (props) => {
const element: GraphElement<ElementModel, CanvasNode['data']> = useContext(ElementContext);
const vizNode = element.getData()?.vizNode;
const flowId = vizNode?.getBaseEntity()?.getId();
const shouldRender = useMemo(() => {
const nodeInteractions = vizNode?.getNodeInteraction() ?? { canRemoveFlow: false };

return nodeInteractions.canRemoveFlow;
}, [vizNode]);

const onRemoveGroup = useCallback(() => {
entitiesContext?.camelResource.removeEntity(flowId);
entitiesContext?.updateEntitiesFromCamelResource();
}, [entitiesContext]);
}, [entitiesContext, flowId]);

return (
return shouldRender ? (
<ContextMenuItem onClick={onRemoveGroup} data-testid={props['data-testid']}>
<TrashIcon /> Delete
</ContextMenuItem>
);
) : null;
};
2 changes: 1 addition & 1 deletion packages/ui/src/models/camel/camel-resource.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe('createCamelResource', () => {
expect(resource.getType()).toEqual(SourceSchemaType.Route);
expect(resource.getVisualEntities().length).toEqual(1);
const vis = resource.getVisualEntities()[0] as CamelRouteVisualEntity;
expect(vis.route.from?.uri).toBeDefined();
expect(vis.flow.from?.uri).toBeDefined();
});

// TODO
Expand Down
10 changes: 10 additions & 0 deletions packages/ui/src/models/camel/camel-route-resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ import { createCamelPropertiesSorter, isDefined } from '../../utils';
import { AddStepMode } from '../visualization/base-visual-entity';
import { CamelRouteVisualEntity, isCamelFrom, isCamelRoute } from '../visualization/flows';
import { CamelErrorHandlerVisualEntity } from '../visualization/flows/camel-error-handler-visual-entity';
import { CamelInterceptFromVisualEntity } from '../visualization/flows/camel-intercept-from-visual-entity';
import { CamelInterceptSendToEndpointVisualEntity } from '../visualization/flows/camel-intercept-send-to-endpoint-visual-entity';
import { CamelInterceptVisualEntity } from '../visualization/flows/camel-intercept-visual-entity';
import { CamelOnCompletionVisualEntity } from '../visualization/flows/camel-on-completion-visual-entity';
import { CamelOnExceptionVisualEntity } from '../visualization/flows/camel-on-exception-visual-entity';
import { CamelRestConfigurationVisualEntity } from '../visualization/flows/camel-rest-configuration-visual-entity';
import { CamelRouteConfigurationVisualEntity } from '../visualization/flows/camel-route-configuration-visual-entity';
import { NonVisualEntity } from '../visualization/flows/non-visual-entity';
import { CamelComponentFilterService } from '../visualization/flows/support/camel-component-filter.service';
import { CamelRouteVisualEntityData } from '../visualization/flows/support/camel-component-types';
Expand All @@ -18,8 +23,13 @@ import { SourceSchemaType } from './source-schema-type';
export class CamelRouteResource implements CamelResource, BeansAwareResource {
static readonly SUPPORTED_ENTITIES = [
CamelOnExceptionVisualEntity,
CamelOnCompletionVisualEntity,
CamelErrorHandlerVisualEntity,
CamelRestConfigurationVisualEntity,
CamelRouteConfigurationVisualEntity,
CamelInterceptVisualEntity,
CamelInterceptFromVisualEntity,
CamelInterceptSendToEndpointVisualEntity,
] as const;
static readonly PARAMETERS_ORDER = ['id', 'description', 'uri', 'parameters', 'steps'];
readonly sortFn = createCamelPropertiesSorter(CamelRouteResource.PARAMETERS_ORDER) as (
Expand Down
5 changes: 5 additions & 0 deletions packages/ui/src/models/camel/entities/base-entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ export const enum EntityType {
Pipe = 'pipe',
Rest = 'rest',
RestConfiguration = 'restConfiguration',
RouteConfiguration = 'routeConfiguration',
Intercept = 'intercept',
InterceptFrom = 'interceptFrom',
InterceptSendToEndpoint = 'interceptSendToEndpoint',
OnCompletion = 'onCompletion',
Beans = 'beans',
Metadata = 'metadata',
PipeErrorHandler = 'pipeErrorHandler',
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/models/camel/kamelet-resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export class KameletResource extends CamelKResource implements RouteTemplateBean
* the CamelRouteVisualEntity.
*/
set(this.resource, 'metadata.name', this.flow.getId());
set(this.resource, 'spec.template.from', this.flow.route.from);
set(this.resource, 'spec.template.from', this.flow.flow.from);
set(this.resource, 'spec.template.beans', this.beans?.parent.beans);
return this.resource as IKameletDefinition;
}
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/models/visualization/base-visual-entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,5 @@ export interface NodeInteraction {
canHaveSpecialChildren: boolean;
canReplaceStep: boolean;
canRemoveStep: boolean;
canRemoveFlow: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe('AbstractCamelVisualEntity', () => {
const newUri = 'timer:MyTimer';
abstractVisualEntity.updateModel('from', { uri: newUri });

expect(abstractVisualEntity.route.from.uri).toEqual(newUri);
expect(abstractVisualEntity.flow.from.uri).toEqual(newUri);
});

it('should delegate the serialization to the `CamelComponentSchemaService`', () => {
Expand Down
Loading

0 comments on commit fa84c30

Please sign in to comment.