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;