This is an automated email from the ASF dual-hosted git repository.

zehnder pushed a commit to branch 
3054-editing-adapter-fails-when-field-has-custom-runtime-name-with-opc-ua-adapter
in repository https://gitbox.apache.org/repos/asf/streampipes.git


The following commit(s) were added to 
refs/heads/3054-editing-adapter-fails-when-field-has-custom-runtime-name-with-opc-ua-adapter
 by this push:
     new cde51d8767 feat(#3054): Change delimiter for nested property structure
cde51d8767 is described below

commit cde51d8767be49903c85471caf17b099b6ea187d
Author: Philipp Zehnder <[email protected]>
AuthorDate: Thu Aug 15 09:14:42 2024 +0200

    feat(#3054): Change delimiter for nested property structure
---
 .../connect/shared/preprocessing/utils/Utils.java  |   6 +-
 .../fixtures/connect/schemaRules/expected.csv      |   4 +-
 ui/cypress/fixtures/connect/schemaRules/input.csv  |   4 +-
 ui/cypress/support/utils/connect/ConnectBtns.ts    |   6 +
 .../utils/connect/ConnectEventSchemaUtils.ts       |  39 ++-
 .../connect/editAdapterValuesAndFields.spec.ts     |  13 +-
 .../tests/connect/rules/schemaRules.smoke.spec.ts  |   9 +-
 .../services/transformation-rule.service.spec.ts   | 267 ---------------------
 .../services/transformation-rule.service.ts        |  17 +-
 9 files changed, 69 insertions(+), 296 deletions(-)

diff --git 
a/streampipes-connect-shared/src/main/java/org/apache/streampipes/connect/shared/preprocessing/utils/Utils.java
 
b/streampipes-connect-shared/src/main/java/org/apache/streampipes/connect/shared/preprocessing/utils/Utils.java
index 50a5a5681c..db16dd24b3 100644
--- 
a/streampipes-connect-shared/src/main/java/org/apache/streampipes/connect/shared/preprocessing/utils/Utils.java
+++ 
b/streampipes-connect-shared/src/main/java/org/apache/streampipes/connect/shared/preprocessing/utils/Utils.java
@@ -26,8 +26,10 @@ import java.util.List;
 
 public class Utils {
 
+  private static final String DELIMITER = "<-=>";
+
   public static String getLastKey(String s) {
-    String[] list = s.split("\\.");
+    String[] list = s.split(DELIMITER);
     if (list.length == 0) {
       return s;
     } else {
@@ -36,7 +38,7 @@ public class Utils {
   }
 
   public static List<String> toKeyArray(String s) {
-    String[] split = s.split("\\.");
+    String[] split = s.split(DELIMITER);
     if (split.length == 0) {
       return List.of(s);
     } else {
diff --git a/ui/cypress/fixtures/connect/schemaRules/expected.csv 
b/ui/cypress/fixtures/connect/schemaRules/expected.csv
index 411fac981c..18ccb6566e 100644
--- a/ui/cypress/fixtures/connect/schemaRules/expected.csv
+++ b/ui/cypress/fixtures/connect/schemaRules/expected.csv
@@ -1,2 +1,2 @@
-count;staticPropertyName;temperature
-122.0;id1;11.0
+count;dot;staticPropertyName;temperature
+122.0;special_char_in_column_name;id1;11.0
diff --git a/ui/cypress/fixtures/connect/schemaRules/input.csv 
b/ui/cypress/fixtures/connect/schemaRules/input.csv
index be4e9eff3b..8514e3310d 100644
--- a/ui/cypress/fixtures/connect/schemaRules/input.csv
+++ b/ui/cypress/fixtures/connect/schemaRules/input.csv
@@ -1,2 +1,2 @@
-timestamp;count;density;temperature
-1720018277000;122.0;62.0;11
+timestamp;count;density;temperature;contains.dot
+1720018277000;122.0;62.0;11;special_char_in_column_name
diff --git a/ui/cypress/support/utils/connect/ConnectBtns.ts 
b/ui/cypress/support/utils/connect/ConnectBtns.ts
index f31db5f0e8..52055e0ae9 100644
--- a/ui/cypress/support/utils/connect/ConnectBtns.ts
+++ b/ui/cypress/support/utils/connect/ConnectBtns.ts
@@ -111,6 +111,12 @@ export class ConnectBtns {
         });
     }
 
+    public static runtimeNameInput() {
+        return cy.dataCy('connect-edit-field-runtime-name', {
+            timeout: 10000,
+        });
+    }
+
     // ========================================================================
 
     // =====================  Format configurations  ==========================
diff --git a/ui/cypress/support/utils/connect/ConnectEventSchemaUtils.ts 
b/ui/cypress/support/utils/connect/ConnectEventSchemaUtils.ts
index 1e302003ec..6bcfe2b231 100644
--- a/ui/cypress/support/utils/connect/ConnectEventSchemaUtils.ts
+++ b/ui/cypress/support/utils/connect/ConnectEventSchemaUtils.ts
@@ -127,6 +127,26 @@ export class ConnectEventSchemaUtils {
         cy.dataCy('sp-save-edit-property').click();
     }
 
+    public static renameProperty(
+        fromRuntimeName: string,
+        toRuntimeName: string,
+    ) {
+        ConnectEventSchemaUtils.clickEditProperty(fromRuntimeName);
+        ConnectEventSchemaUtils.setRuntimeName(toRuntimeName);
+        ConnectBtns.saveEditProperty().click();
+    }
+
+    public static setRuntimeName(newRuntimeName: string) {
+        ConnectBtns.runtimeNameInput().clear().type(newRuntimeName);
+    }
+
+    public static validateRuntimeName(expectedRuntimeName: string) {
+        ConnectBtns.runtimeNameInput().should(
+            'have.value',
+            expectedRuntimeName,
+        );
+    }
+
     public static unitTransformation(
         propertyName: string,
         fromUnit: string,
@@ -244,13 +264,20 @@ export class ConnectEventSchemaUtils {
     }
 
     public static clickEditProperty(propertyName: string) {
-        cy.dataCy('edit-' + propertyName.toLowerCase(), {
+        cy.dataCy(`edit-${ConnectEventSchemaUtils.escape(propertyName)}`, {
             timeout: 10000,
         }).click();
-        cy.dataCy('connect-edit-field-runtime-name').should(
-            'have.value',
-            propertyName,
-            { timeout: 10000 },
-        );
+        ConnectEventSchemaUtils.validateRuntimeName(propertyName);
+    }
+
+    //
+    /**
+     * Function to escape special characters in a string for use in Cypress
+     * selectors
+     */
+    public static escape(selector: string): string {
+        return selector
+            .replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1')
+            .toLowerCase();
     }
 }
diff --git a/ui/cypress/tests/connect/editAdapterValuesAndFields.spec.ts 
b/ui/cypress/tests/connect/editAdapterValuesAndFields.spec.ts
index 52269352a0..86800e448b 100644
--- a/ui/cypress/tests/connect/editAdapterValuesAndFields.spec.ts
+++ b/ui/cypress/tests/connect/editAdapterValuesAndFields.spec.ts
@@ -19,6 +19,7 @@
 import { ConnectUtils } from '../../support/utils/connect/ConnectUtils';
 import { ConnectBtns } from '../../support/utils/connect/ConnectBtns';
 import { AdapterBuilder } from '../../support/builder/AdapterBuilder';
+import { ConnectEventSchemaUtils } from 
'../../support/utils/connect/ConnectEventSchemaUtils';
 
 describe('Test Edit Adapter', () => {
     beforeEach('Setup Test', () => {
@@ -42,9 +43,7 @@ describe('Test Edit Adapter', () => {
         cy.dataCy('connect-add-field-name-button').click();
         cy.dataCy('edit-density').click();
         // Change runtime name
-        cy.dataCy('connect-edit-field-runtime-name')
-            .clear()
-            .type('test-density');
+        ConnectBtns.runtimeNameInput().clear().type('test-density');
         // Change field semantic type
         cy.get('[id="domainproperty"]')
             .clear()
@@ -75,10 +74,8 @@ describe('Test Edit Adapter', () => {
         ConnectBtns.editAdapter().click();
         cy.contains('Next').click();
         cy.dataCy('edit-density').click();
-        cy.dataCy('connect-edit-field-runtime-name').should(
-            'have.value',
-            'test-density',
-        );
+        ConnectEventSchemaUtils.validateRuntimeName('test-density');
+
         cy.get('[id="domainproperty"]').should(
             'have.value',
             'http://schema.org/Numbers',
@@ -91,7 +88,7 @@ describe('Test Edit Adapter', () => {
         );
 
         // Delete inserted values in edit field
-        cy.dataCy('connect-edit-field-runtime-name').clear();
+        ConnectBtns.runtimeNameInput().clear();
         cy.get('[id="domainproperty"]').clear();
         ConnectBtns.changeRuntimeType()
             .click()
diff --git a/ui/cypress/tests/connect/rules/schemaRules.smoke.spec.ts 
b/ui/cypress/tests/connect/rules/schemaRules.smoke.spec.ts
index 673cf31ebf..63968cc478 100644
--- a/ui/cypress/tests/connect/rules/schemaRules.smoke.spec.ts
+++ b/ui/cypress/tests/connect/rules/schemaRules.smoke.spec.ts
@@ -23,10 +23,10 @@ import { ConnectEventSchemaUtils } from 
'../../../support/utils/connect/ConnectE
 describe('Connect schema rule transformations', () => {
     beforeEach('Setup Test', () => {
         cy.initStreamPipesTest();
-        FileManagementUtils.addFile('connect/schemaRules/input.csv');
     });
 
-    it('Perform Test', () => {
+    it('Test several schema rules', () => {
+        FileManagementUtils.addFile('connect/schemaRules/input.csv');
         const adapterConfiguration =
             ConnectUtils.setUpPreprocessingRuleTest(true);
 
@@ -36,7 +36,10 @@ describe('Connect schema rule transformations', () => {
         // Delete one property
         ConnectEventSchemaUtils.deleteProperty('density');
 
-        // Set data type to float
+        // Rename property with special char
+        ConnectEventSchemaUtils.renameProperty('contains.dot', 'dot');
+
+        // Set data type to integer
         ConnectEventSchemaUtils.changePropertyDataType(
             'temperature',
             'Integer',
diff --git a/ui/src/app/connect/services/transformation-rule.service.spec.ts 
b/ui/src/app/connect/services/transformation-rule.service.spec.ts
deleted file mode 100644
index a0030bf34f..0000000000
--- a/ui/src/app/connect/services/transformation-rule.service.spec.ts
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-import { TransformationRuleService } from './transformation-rule.service';
-import {
-    CreateNestedRuleDescription,
-    EventPropertyNested,
-    EventPropertyPrimitive,
-    EventPropertyUnion,
-    EventSchema,
-    MoveRuleDescription,
-    RenameRuleDescription,
-} from '@streampipes/platform-services';
-
-describe('TransformationRuleService', () => {
-    const service = new TransformationRuleService();
-
-    it('Get complete key from schema nested', () => {
-        const eventProperties: EventPropertyUnion[] = [];
-        const eventPropertyPrimitive: EventPropertyPrimitive =
-            new EventPropertyPrimitive();
-        eventPropertyPrimitive.elementId = 'id_1';
-        eventPropertyPrimitive.runtimeName = 'a';
-        const eventPropertyNested: EventPropertyNested =
-            new EventPropertyNested();
-        eventPropertyNested.elementId = 'id_2';
-        eventPropertyNested.runtimeName = 'b';
-        eventPropertyNested.eventProperties = [];
-        eventPropertyNested.eventProperties.push(eventPropertyPrimitive);
-        eventProperties.push(eventPropertyNested);
-
-        const result: string = service.getCompleteRuntimeNameKey(
-            eventProperties,
-            'id_1',
-        );
-
-        expect(result).toBe('b.a');
-    });
-
-    it('Get complete key from schema primitve', () => {
-        const eventProperties: EventPropertyUnion[] = [];
-        const eventPropertyPrimitive: EventPropertyPrimitive =
-            new EventPropertyPrimitive();
-        eventPropertyPrimitive.elementId = 'id_1';
-        eventPropertyPrimitive.runtimeName = 'a';
-
-        eventProperties.push(eventPropertyPrimitive);
-
-        const result: string = service.getCompleteRuntimeNameKey(
-            eventProperties,
-            'id_1',
-        );
-
-        expect(result).toBe('a');
-    });
-
-    it('check get all ids with one id', () => {
-        const eventProperties: EventPropertyUnion[] = [];
-        const eventPropertyPrimitive: EventPropertyPrimitive =
-            new EventPropertyPrimitive();
-        eventPropertyPrimitive.elementId = 'id_1';
-        eventProperties.push(eventPropertyPrimitive);
-
-        const result: string[] = service.getAllIds(eventProperties);
-        expect(result.length).toBe(1);
-        expect(result[0]).toBe('id_1');
-    });
-
-    it('check get all ids with multiple ids', () => {
-        const eventProperties: EventPropertyUnion[] = [];
-        const eventPropertyPrimitive: EventPropertyPrimitive =
-            new EventPropertyPrimitive();
-        eventPropertyPrimitive.elementId = 'id_1';
-        const eventPropertyPrimitive1: EventPropertyPrimitive =
-            new EventPropertyPrimitive();
-        eventPropertyPrimitive1.elementId = 'id_2';
-        const eventPropertyNested: EventPropertyNested =
-            new EventPropertyNested();
-        eventPropertyNested.elementId = 'id_3';
-        eventPropertyNested.eventProperties = [];
-        eventPropertyNested.eventProperties.push(eventPropertyPrimitive1);
-
-        eventProperties.push(eventPropertyPrimitive);
-        eventProperties.push(eventPropertyNested);
-
-        const result: string[] = service.getAllIds(eventProperties);
-        expect(result.length).toBe(3);
-        expect(result[0]).toBe('id_1');
-        expect(result[2]).toBe('id_2');
-        expect(result[1]).toBe('id_3');
-    });
-
-    it('Create Nested Rules simple', () => {
-        const oldEventSchema: EventSchema = new EventSchema();
-        oldEventSchema.eventProperties = [];
-
-        const newEventSchema: EventSchema = new EventSchema();
-        const propertyNested: EventPropertyNested = new EventPropertyNested();
-        propertyNested.eventProperties = [];
-        propertyNested.elementId = 'id';
-        propertyNested.runtimeName = 'a';
-        newEventSchema.eventProperties = [];
-        newEventSchema.eventProperties.push(propertyNested);
-
-        const result: CreateNestedRuleDescription[] =
-            service.getCreateNestedRules(
-                newEventSchema.eventProperties,
-                oldEventSchema,
-                newEventSchema,
-            );
-
-        expect(result.length).toBe(1);
-        expect(result[0].runtimeKey).toBe('a');
-    });
-
-    it('Create Nested Rules nested', () => {
-        const oldEventSchema: EventSchema = new EventSchema();
-        oldEventSchema.eventProperties = [];
-
-        const newEventSchema: EventSchema = new EventSchema();
-        newEventSchema.eventProperties = [];
-        const nestedNested: EventPropertyNested = new EventPropertyNested();
-        nestedNested.runtimeName = 'a';
-        nestedNested.elementId = 'deepnested';
-        nestedNested.eventProperties = [];
-
-        const nestedProperty: EventPropertyNested = new EventPropertyNested();
-        nestedProperty.runtimeName = 'b';
-        nestedNested.elementId = 'nested';
-        nestedProperty.eventProperties = [];
-        nestedNested.eventProperties.push(nestedProperty);
-        newEventSchema.eventProperties.push(nestedNested);
-
-        const result: CreateNestedRuleDescription[] =
-            service.getCreateNestedRules(
-                newEventSchema.eventProperties,
-                oldEventSchema,
-                newEventSchema,
-            );
-
-        expect(result.length).toBe(2);
-        expect(result[0].runtimeKey).toBe('a');
-        expect(result[1].runtimeKey).toBe('a.b');
-    });
-
-    it('Create Move Rules simple', () => {
-        const oldEventSchema: EventSchema = new EventSchema();
-        const oldPropertyToMove: EventPropertyPrimitive =
-            new EventPropertyPrimitive();
-        oldPropertyToMove.runtimeName = 'a';
-        oldPropertyToMove.elementId = 'a1';
-        const oldNestedProperty: EventPropertyNested =
-            new EventPropertyNested();
-        oldNestedProperty.runtimeName = 'b';
-        oldNestedProperty.elementId = 'b1';
-        oldNestedProperty.eventProperties = [];
-        oldEventSchema.eventProperties = [];
-        oldEventSchema.eventProperties.push(oldPropertyToMove);
-        oldEventSchema.eventProperties.push(oldNestedProperty);
-
-        const newEventSchema: EventSchema = new EventSchema();
-        newEventSchema.eventProperties = [];
-        const newPropertyToMove: EventPropertyPrimitive =
-            new EventPropertyPrimitive();
-        newPropertyToMove.runtimeName = 'a';
-        newPropertyToMove.elementId = 'a1';
-        const newNestedProperty: EventPropertyNested =
-            new EventPropertyNested();
-        newNestedProperty.runtimeName = 'b';
-        newNestedProperty.elementId = 'b1';
-        newNestedProperty.eventProperties = [];
-        newNestedProperty.eventProperties.push(newPropertyToMove);
-        newEventSchema.eventProperties.push(newNestedProperty);
-
-        const result: MoveRuleDescription[] = service.getMoveRules(
-            newEventSchema.eventProperties,
-            oldEventSchema,
-            newEventSchema,
-        );
-
-        expect(result.length).toBe(1);
-        expect(result[0].oldRuntimeKey).toBe('a');
-    });
-
-    it('Rename simple', () => {
-        const oldEventSchema: EventSchema = new EventSchema();
-        const oldEventPropertyPrimitive: EventPropertyPrimitive =
-            new EventPropertyPrimitive();
-        oldEventPropertyPrimitive.elementId = 'id_1';
-        oldEventPropertyPrimitive.runtimeName = 'a';
-        oldEventSchema.eventProperties = [];
-        oldEventSchema.eventProperties.push(oldEventPropertyPrimitive);
-
-        const newEventSchema: EventSchema = new EventSchema();
-        const newEventPropertyPrimitive: EventPropertyPrimitive =
-            new EventPropertyPrimitive();
-        newEventPropertyPrimitive.elementId = 'id_1';
-        newEventPropertyPrimitive.runtimeName = 'b';
-        newEventSchema.eventProperties = [];
-        newEventSchema.eventProperties.push(newEventPropertyPrimitive);
-
-        const result: RenameRuleDescription[] = service.getRenameRules(
-            newEventSchema.eventProperties,
-            oldEventSchema,
-            newEventSchema,
-        );
-
-        expect(result.length).toBe(1);
-        expect(result[0].oldRuntimeKey).toBe('a');
-        expect(result[0].newRuntimeKey).toBe('b');
-    });
-
-    it('Rename nested', () => {
-        const oldEventSchema: EventSchema = new EventSchema();
-        const oldNestedEventProperty: EventPropertyNested =
-            new EventPropertyNested();
-        oldNestedEventProperty.elementId = 'id_2';
-        oldNestedEventProperty.runtimeName = 'b';
-        oldNestedEventProperty.eventProperties = [];
-        const oldEventPropertyPrimitive: EventPropertyPrimitive =
-            new EventPropertyPrimitive();
-        oldEventPropertyPrimitive.elementId = 'id_1';
-        oldEventPropertyPrimitive.runtimeName = 'a';
-        oldNestedEventProperty.eventProperties.push(oldEventPropertyPrimitive);
-        oldEventSchema.eventProperties = [];
-        oldEventSchema.eventProperties.push(oldNestedEventProperty);
-
-        const newEventSchema: EventSchema = new EventSchema();
-        const newNestedEventProperty: EventPropertyNested =
-            new EventPropertyNested();
-        newNestedEventProperty.elementId = 'id_2';
-        newNestedEventProperty.runtimeName = 'b';
-        const newEventPropertyPrimitive: EventPropertyPrimitive =
-            new EventPropertyPrimitive();
-        newEventPropertyPrimitive.elementId = 'id_1';
-        newEventPropertyPrimitive.runtimeName = 'b';
-        newNestedEventProperty.eventProperties = [];
-        newNestedEventProperty.eventProperties.push(newEventPropertyPrimitive);
-        newEventSchema.eventProperties = [];
-        newEventSchema.eventProperties.push(newNestedEventProperty);
-
-        const result: RenameRuleDescription[] = service.getRenameRules(
-            newEventSchema.eventProperties,
-            oldEventSchema,
-            newEventSchema,
-        );
-
-        expect(result.length).toBe(1);
-        expect(result[0].oldRuntimeKey).toBe('b.a');
-        expect(result[0].newRuntimeKey).toBe('b.b');
-    });
-});
diff --git a/ui/src/app/connect/services/transformation-rule.service.ts 
b/ui/src/app/connect/services/transformation-rule.service.ts
index 443abebab9..2d04eb8876 100644
--- a/ui/src/app/connect/services/transformation-rule.service.ts
+++ b/ui/src/app/connect/services/transformation-rule.service.ts
@@ -46,6 +46,8 @@ export class TransformationRuleService {
         private staticValueTransformService: StaticValueTransformService,
     ) {}
 
+    private delimiter = '<-=>';
+
     public getTransformationRuleDescriptions(
         originalSchema: EventSchema,
         targetSchema: EventSchema,
@@ -183,22 +185,22 @@ export class TransformationRuleService {
                 if (keyOld && keyNew) {
                     const keyOldPrefix = keyOld.substr(
                         0,
-                        keyOld.lastIndexOf('.'),
+                        keyOld.lastIndexOf(this.delimiter),
                     );
                     const keyNewPrefix = keyNew.substr(
                         0,
-                        keyNew.lastIndexOf('.'),
+                        keyNew.lastIndexOf(this.delimiter),
                     );
 
                     if (keyOldPrefix !== keyNewPrefix) {
                         let keyOfOldValue = '';
                         if (keyOldPrefix === '') {
                             keyOfOldValue = keyNew.substr(
-                                keyNew.lastIndexOf('.') + 1,
+                                keyNew.lastIndexOf(this.delimiter) + 1,
                             );
                         } else {
                             keyOfOldValue = `${keyOldPrefix}.${keyNew.substr(
-                                keyNew.lastIndexOf('.') + 1,
+                                keyNew.lastIndexOf(this.delimiter) + 1,
                             )}`;
                         }
 
@@ -393,7 +395,10 @@ export class TransformationRuleService {
                         id,
                     );
                     if (methodResult != null) {
-                        result = eventProperty.runtimeName + '.' + 
methodResult;
+                        result =
+                            eventProperty.runtimeName +
+                            this.delimiter +
+                            methodResult;
                     }
                 }
             }
@@ -408,7 +413,7 @@ export class TransformationRuleService {
 
     public getRuntimeNameKey(completeKey: string): string {
         if (completeKey) {
-            const keyElements = completeKey.split('.');
+            const keyElements = completeKey.split(this.delimiter);
 
             if (keyElements.length === 0) {
                 return completeKey;

Reply via email to