Skip to content
This repository has been archived by the owner on Nov 27, 2023. It is now read-only.

Commit

Permalink
fix(StepsService): Generate steady IDs for steps and branches
Browse files Browse the repository at this point in the history
At the moment, when a step is no longer available because it was removed,
or its id changed, we close the step's detail panel since is no longer
editing the right step.

This causes an issue with vscode since there's a circular dependency
between the integration JSON and the code editor. Long story short,
whenever there's an update of the integration JSON, the steps or
branch IDs change, forcing a new sync cycle from the kogito integration side.

A partial fix to this issue is to ensure that the IDs are consistent between syncs,
so this way the comparison inside of the KogitoEditorIntegrationProvider.tsx works.

fix: #1553
  • Loading branch information
lordrip committed Mar 30, 2023
1 parent 6184d81 commit a2bed61
Show file tree
Hide file tree
Showing 4 changed files with 795 additions and 16 deletions.
194 changes: 186 additions & 8 deletions src/services/stepsService.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import branchSteps from '../store/data/branchSteps';
import nestedBranch from '../store/data/kamelet.nested-branch.steps';
import steps from '../store/data/steps';
import { integrationSteps } from '../stubs';
import { StepsService } from './stepsService';
import { useIntegrationJsonStore, useNestedStepsStore, useVisualizationStore } from '@kaoto/store';
import { IStepProps, IStepPropsBranch, IStepPropsParameters, IViewProps } from '@kaoto/types';
Expand Down Expand Up @@ -140,10 +141,187 @@ describe('stepsService', () => {
/**
* regenerateUuids
*/
it('regenerateUuids(): should regenerate UUIDs for an array of steps', () => {
expect(StepsService.regenerateUuids(steps)[0].UUID).toBeDefined();
expect(StepsService.regenerateUuids(branchSteps)[0].UUID).toBeDefined();
expect(StepsService.regenerateUuids(branchSteps)[1].UUID).toBeDefined();
describe('regenerateUuids', () => {
it('should generate UUIDs for the main steps array', () => {
const result = StepsService.regenerateUuids(integrationSteps);

expect(result).toMatchObject<Partial<IStepProps>[]>([
{ UUID: 'timer-0' },
{ UUID: 'choice-1' },
]);
});

it('should generate UUIDs for branches', () => {
const result = StepsService.regenerateUuids(integrationSteps);

expect(result).toMatchObject<Partial<IStepProps>[]>([
{ UUID: 'timer-0', branches: [] },
{
UUID: 'choice-1',
branches: [
{ branchUuid: 'choice-1|branch-0', steps: expect.any(Array), identifier: 'true path' },
{ branchUuid: 'choice-1|branch-1', steps: expect.any(Array), identifier: 'otherwise' },
],
},
]);
});

it('should generate UUIDs for nested steps', () => {
const result = StepsService.regenerateUuids(integrationSteps);

expect(result).toMatchObject<Partial<IStepProps>[]>([
{ UUID: 'timer-0', branches: [] },
{
UUID: 'choice-1',
branches: [
{
branchUuid: 'choice-1|branch-0',
steps: [
{
UUID: 'choice-1|branch-0|log-0',
minBranches: 0,
maxBranches: 0,
name: 'log',
type: 'MIDDLE',
},
],
identifier: 'true path',
},
{
branchUuid: 'choice-1|branch-1',
steps: [
{
UUID: 'choice-1|branch-1|log-0',
minBranches: 0,
maxBranches: 0,
name: 'log',
type: 'MIDDLE',
},
],
identifier: 'otherwise',
},
],
},
]);
});

it('should generate UUIDs for nested steps at two levels deep', () => {
const copiedIntegrationSteps = JSON.parse(JSON.stringify(integrationSteps));
const nestedIntegrationSteps: IStepProps[] = copiedIntegrationSteps;
nestedIntegrationSteps[1].branches![0].steps = integrationSteps;

const result = StepsService.regenerateUuids(nestedIntegrationSteps);

expect(result).toMatchObject<Partial<IStepProps>[]>([
{ UUID: 'timer-0', branches: [] },
{
UUID: 'choice-1',
branches: [
{
branchUuid: 'choice-1|branch-0',
steps: [
{
UUID: 'choice-1|branch-0|timer-0',
minBranches: 0,
maxBranches: 0,
name: 'timer',
type: 'START',
branches: [],
},
{
UUID: 'choice-1|branch-0|choice-1',
minBranches: 1,
maxBranches: -1,
name: 'choice',
type: 'MIDDLE',
branches: [
{
branchUuid: 'choice-1|branch-0|choice-1|branch-0',
steps: [
{
UUID: 'choice-1|branch-0|choice-1|branch-0|log-0',
minBranches: 0,
maxBranches: 0,
name: 'log',
type: 'MIDDLE',
},
],
identifier: 'true path',
},
{
branchUuid: 'choice-1|branch-0|choice-1|branch-1',
steps: [
{
UUID: 'choice-1|branch-0|choice-1|branch-1|log-0',
minBranches: 0,
maxBranches: 0,
name: 'log',
type: 'MIDDLE',
},
],
identifier: 'otherwise',
},
],
},
],
identifier: 'true path',
},
{
branchUuid: 'choice-1|branch-1',
steps: [
{
UUID: 'choice-1|branch-1|log-0',
minBranches: 0,
maxBranches: 0,
name: 'log',
type: 'MIDDLE',
},
],
identifier: 'otherwise',
},
],
},
]);
});

it('should regenerate UUIDs when a branch is removed', () => {
const localIntegrationSteps = integrationSteps.slice(1);
const result = StepsService.regenerateUuids(localIntegrationSteps);

expect(result).toMatchObject<Partial<IStepProps>[]>([
{
UUID: 'choice-0',
branches: [
{
branchUuid: 'choice-0|branch-0',
steps: [
{
UUID: 'choice-0|branch-0|log-0',
minBranches: 0,
maxBranches: 0,
name: 'log',
type: 'MIDDLE',
},
],
identifier: 'true path',
},
{
branchUuid: 'choice-0|branch-1',
steps: [
{
UUID: 'choice-0|branch-1|log-0',
minBranches: 0,
maxBranches: 0,
name: 'log',
type: 'MIDDLE',
},
],
identifier: 'otherwise',
},
],
},
]);
});
});

it('supportsBranching(): should determine if the provided step supports branching', () => {
Expand Down Expand Up @@ -171,7 +349,7 @@ describe('stepsService', () => {
it('should return "false" for empty views', () => {
const result = StepsService.hasCustomStepExtension(
{ UUID: 'random-id' } as IStepProps,
[] as IViewProps[],
[] as IViewProps[]
);

expect(result).toBeFalsy();
Expand All @@ -180,7 +358,7 @@ describe('stepsService', () => {
it('should return "false" for a matching view with no URL available', () => {
const result = StepsService.hasCustomStepExtension(
{ UUID: 'random-id' } as IStepProps,
[{ step: 'random-id', url: '' }] as IViewProps[],
[{ step: 'random-id', url: '' }] as IViewProps[]
);

expect(result).toBeFalsy();
Expand All @@ -189,7 +367,7 @@ describe('stepsService', () => {
it('should return "false" for non-matching views', () => {
const result = StepsService.hasCustomStepExtension(
{ UUID: 'random-id' } as IStepProps,
[{ step: 'not-a-random-id', url: '/dev/null' }] as IViewProps[],
[{ step: 'not-a-random-id', url: '/dev/null' }] as IViewProps[]
);

expect(result).toBeFalsy();
Expand All @@ -198,7 +376,7 @@ describe('stepsService', () => {
it('should return "true" for matching views and an URL available', () => {
const result = StepsService.hasCustomStepExtension(
{ UUID: 'random-id' } as IStepProps,
[{ step: 'random-id', url: '/dev/null' }] as IViewProps[],
[{ step: 'random-id', url: '/dev/null' }] as IViewProps[]
);

expect(result).toBeTruthy();
Expand Down
17 changes: 9 additions & 8 deletions src/services/stepsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
IVizStepNode,
IVizStepNodeData,
} from '@kaoto/types';
import { findPath, getDeepValue, getRandomArbitraryNumber } from '@kaoto/utils';
import { findPath, getDeepValue } from '@kaoto/utils';

/**
* A collection of business logic to handle logical model objects of the integration,
Expand Down Expand Up @@ -459,19 +459,20 @@ export class StepsService {
* @param steps
* @param branchSteps
*/
static regenerateUuids(steps: IStepProps[], branchSteps: boolean = false): IStepProps[] {
static regenerateUuids(steps: IStepProps[], prefix: string = ''): IStepProps[] {
let newSteps = steps.slice();

newSteps.forEach((step, idx) => {
step.UUID = `${step.name}-${idx}`;
if (branchSteps) step.UUID = `${step.name}-${idx}-${getRandomArbitraryNumber()}`;
newSteps.forEach((step, stepIndex) => {
step.UUID = `${prefix}${step.name}-${stepIndex}`;

if (this.containsBranches(step)) {
step.branches!.forEach((branch) => {
branch.branchUuid = `b-${idx}-${getRandomArbitraryNumber()}`;
return newSteps.concat(StepsService.regenerateUuids(branch.steps, true));
step.branches?.forEach((branch, branchIndex) => {
branch.branchUuid = `${step.UUID}|branch-${branchIndex}`;
return newSteps.concat(StepsService.regenerateUuids(branch.steps, `${branch.branchUuid}|`));
});
}
});

return newSteps;
}

Expand Down
1 change: 1 addition & 0 deletions src/stubs/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './debezium-mongodb.step';
export * from './integration-steps';
export * from './steps';
Loading

0 comments on commit a2bed61

Please sign in to comment.