This is an automated email from the ASF dual-hosted git repository.
zehnder pushed a commit to branch
3282-dd-regex-based-preprocessing-rule-to-adapters
in repository https://gitbox.apache.org/repos/asf/streampipes.git
The following commit(s) were added to
refs/heads/3282-dd-regex-based-preprocessing-rule-to-adapters by this push:
new bbc0a69844 feat(#3282): Add a regex rule for string event properties
to connect
bbc0a69844 is described below
commit bbc0a69844b0260a5010d431d30b6edb2f4bc5be
Author: Philipp Zehnder <[email protected]>
AuthorDate: Mon Oct 7 15:43:28 2024 +0200
feat(#3282): Add a regex rule for string event properties to connect
---
.../connect/TransformationRuleUpdateVisitor.java | 8 ++
.../rules/TransformationRuleDescription.java | 2 +
.../storage/couchdb/serializer/GsonSerializer.java | 3 +
.../connect/regexRule/expectedReplaceAllFalse.csv | 2 +
.../connect/regexRule/expectedReplaceAllTrue.csv | 2 +
.../expectedReplaceAllTrueWithEmptyString.csv | 2 +
ui/cypress/fixtures/connect/regexRule/input.csv | 2 +
.../utils/connect/ConnectEventSchemaUtils.ts | 17 +++-
.../connect/rules/deleteTransformationRule.spec.ts | 12 +--
ui/cypress/tests/connect/rules/regexRule.spec.ts | 107 +++++++++++++++++++++
.../src/lib/model/gen/streampipes-model-client.ts | 5 +-
.../src/lib/model/gen/streampipes-model.ts | 37 ++++++-
.../src/lib/model/types/data-type.ts | 4 +
ui/src/app/connect/connect.module.ts | 2 +
.../edit-regex-transformation.component.html | 52 ++++++++++
.../edit-regex-transformation.component.scss | 17 ++++
.../edit-regex-transformation.component.ts | 29 ++++++
.../edit-value-transformation.component.html | 10 ++
.../edit-value-transformation.component.ts | 1 +
.../edit-event-property.component.html | 12 +--
.../edit-event-property.component.ts | 18 ++++
.../services/transformation-rule.service.ts | 63 ++++++++++++
22 files changed, 383 insertions(+), 24 deletions(-)
diff --git
a/streampipes-extensions-management/src/main/java/org/apache/streampipes/extensions/management/connect/TransformationRuleUpdateVisitor.java
b/streampipes-extensions-management/src/main/java/org/apache/streampipes/extensions/management/connect/TransformationRuleUpdateVisitor.java
index ef357e4c48..9661b7705c 100644
---
a/streampipes-extensions-management/src/main/java/org/apache/streampipes/extensions/management/connect/TransformationRuleUpdateVisitor.java
+++
b/streampipes-extensions-management/src/main/java/org/apache/streampipes/extensions/management/connect/TransformationRuleUpdateVisitor.java
@@ -31,6 +31,7 @@ import
org.apache.streampipes.model.connect.rules.value.AddTimestampRuleDescript
import
org.apache.streampipes.model.connect.rules.value.AddValueTransformationRuleDescription;
import
org.apache.streampipes.model.connect.rules.value.ChangeDatatypeTransformationRuleDescription;
import
org.apache.streampipes.model.connect.rules.value.CorrectionValueTransformationRuleDescription;
+import
org.apache.streampipes.model.connect.rules.value.RegexTransformationRuleDescription;
import
org.apache.streampipes.model.connect.rules.value.TimestampTranfsformationRuleDescription;
import
org.apache.streampipes.model.connect.rules.value.UnitTransformRuleDescription;
import org.apache.streampipes.model.schema.EventProperty;
@@ -80,6 +81,13 @@ public class TransformationRuleUpdateVisitor implements
ITransformationRuleVisit
}
}
+ @Override
+ public void visit(RegexTransformationRuleDescription rule) {
+ if (containsKey(rule.getRuntimeKey())) {
+ validRules.add(rule);
+ }
+ }
+
@Override
public void visit(EventRateTransformationRuleDescription rule) {
// Do nothing
diff --git
a/streampipes-model/src/main/java/org/apache/streampipes/model/connect/rules/TransformationRuleDescription.java
b/streampipes-model/src/main/java/org/apache/streampipes/model/connect/rules/TransformationRuleDescription.java
index 0ea2194456..94b1817e8f 100644
---
a/streampipes-model/src/main/java/org/apache/streampipes/model/connect/rules/TransformationRuleDescription.java
+++
b/streampipes-model/src/main/java/org/apache/streampipes/model/connect/rules/TransformationRuleDescription.java
@@ -28,6 +28,7 @@ import
org.apache.streampipes.model.connect.rules.value.AddTimestampRuleDescript
import
org.apache.streampipes.model.connect.rules.value.AddValueTransformationRuleDescription;
import
org.apache.streampipes.model.connect.rules.value.ChangeDatatypeTransformationRuleDescription;
import
org.apache.streampipes.model.connect.rules.value.CorrectionValueTransformationRuleDescription;
+import
org.apache.streampipes.model.connect.rules.value.RegexTransformationRuleDescription;
import
org.apache.streampipes.model.connect.rules.value.TimestampTranfsformationRuleDescription;
import
org.apache.streampipes.model.connect.rules.value.UnitTransformRuleDescription;
import org.apache.streampipes.model.shared.annotation.TsModel;
@@ -47,6 +48,7 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonSubTypes.Type(CreateNestedRuleDescription.class),
@JsonSubTypes.Type(DeleteRuleDescription.class),
@JsonSubTypes.Type(RenameRuleDescription.class),
+ @JsonSubTypes.Type(RegexTransformationRuleDescription.class),
@JsonSubTypes.Type(MoveRuleDescription.class),
@JsonSubTypes.Type(ChangeDatatypeTransformationRuleDescription.class),
@JsonSubTypes.Type(CorrectionValueTransformationRuleDescription.class),
diff --git
a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/serializer/GsonSerializer.java
b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/serializer/GsonSerializer.java
index 685db7ee03..fee35a57a3 100644
---
a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/serializer/GsonSerializer.java
+++
b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/serializer/GsonSerializer.java
@@ -35,6 +35,7 @@ import
org.apache.streampipes.model.connect.rules.value.AddTimestampRuleDescript
import
org.apache.streampipes.model.connect.rules.value.AddValueTransformationRuleDescription;
import
org.apache.streampipes.model.connect.rules.value.ChangeDatatypeTransformationRuleDescription;
import
org.apache.streampipes.model.connect.rules.value.CorrectionValueTransformationRuleDescription;
+import
org.apache.streampipes.model.connect.rules.value.RegexTransformationRuleDescription;
import
org.apache.streampipes.model.connect.rules.value.TimestampTranfsformationRuleDescription;
import
org.apache.streampipes.model.connect.rules.value.UnitTransformRuleDescription;
import org.apache.streampipes.model.grounding.TopicDefinition;
@@ -94,6 +95,8 @@ public class GsonSerializer {
builder.registerTypeAdapterFactory(RuntimeTypeAdapterFactory.of(TransformationRuleDescription.class,
"sourceType")
.registerSubtype(RenameRuleDescription.class,
"org.apache.streampipes.model.RenameRuleDescription")
+ .registerSubtype(RegexTransformationRuleDescription.class,
+
"org.apache.streampipes.model.RegexTransformationRuleDescription")
.registerSubtype(MoveRuleDescription.class,
"org.apache.streampipes.model.MoveRuleDescription")
.registerSubtype(DeleteRuleDescription.class,
"org.apache.streampipes.model.DeleteRuleDescription")
.registerSubtype(CreateNestedRuleDescription.class,
"org.apache.streampipes.model.CreateNestedRuleDescription")
diff --git a/ui/cypress/fixtures/connect/regexRule/expectedReplaceAllFalse.csv
b/ui/cypress/fixtures/connect/regexRule/expectedReplaceAllFalse.csv
new file mode 100644
index 0000000000..f951ba2245
--- /dev/null
+++ b/ui/cypress/fixtures/connect/regexRule/expectedReplaceAllFalse.csv
@@ -0,0 +1,2 @@
+density;sensorId
+122.0;aensor01
diff --git a/ui/cypress/fixtures/connect/regexRule/expectedReplaceAllTrue.csv
b/ui/cypress/fixtures/connect/regexRule/expectedReplaceAllTrue.csv
new file mode 100644
index 0000000000..cbff946483
--- /dev/null
+++ b/ui/cypress/fixtures/connect/regexRule/expectedReplaceAllTrue.csv
@@ -0,0 +1,2 @@
+density;sensorId
+122.0;aenaor01
diff --git
a/ui/cypress/fixtures/connect/regexRule/expectedReplaceAllTrueWithEmptyString.csv
b/ui/cypress/fixtures/connect/regexRule/expectedReplaceAllTrueWithEmptyString.csv
new file mode 100644
index 0000000000..91547295c5
--- /dev/null
+++
b/ui/cypress/fixtures/connect/regexRule/expectedReplaceAllTrueWithEmptyString.csv
@@ -0,0 +1,2 @@
+density;sensorId
+122.0;enor01
diff --git a/ui/cypress/fixtures/connect/regexRule/input.csv
b/ui/cypress/fixtures/connect/regexRule/input.csv
new file mode 100644
index 0000000000..78eb36e07f
--- /dev/null
+++ b/ui/cypress/fixtures/connect/regexRule/input.csv
@@ -0,0 +1,2 @@
+timestamp;density;sensorId
+1720018277000;122.0;sensor01
diff --git a/ui/cypress/support/utils/connect/ConnectEventSchemaUtils.ts
b/ui/cypress/support/utils/connect/ConnectEventSchemaUtils.ts
index 6bcfe2b231..b8cdfeabeb 100644
--- a/ui/cypress/support/utils/connect/ConnectEventSchemaUtils.ts
+++ b/ui/cypress/support/utils/connect/ConnectEventSchemaUtils.ts
@@ -255,6 +255,10 @@ export class ConnectEventSchemaUtils {
cy.get('#event-schema-next-button').parent().should('not.be.disabled');
}
+ public static schemaPreviewResultEvent() {
+ return cy.dataCy('schema-preview-result-event', { timeout: 10000 });
+ }
+
public static finishEventSchemaConfiguration() {
// Click next
cy.dataCy('sp-connect-schema-editor', { timeout: 10000 }).should(
@@ -270,7 +274,18 @@ export class ConnectEventSchemaUtils {
ConnectEventSchemaUtils.validateRuntimeName(propertyName);
}
- //
+ public static regexValueInput() {
+ return cy.dataCy('regex-value');
+ }
+
+ public static regexReplaceWithValueInput() {
+ return cy.dataCy('regex-replace-with-value');
+ }
+
+ public static regexReplaceAllCheckbox() {
+ return cy.dataCy('regex-replace-all-value');
+ }
+
/**
* Function to escape special characters in a string for use in Cypress
* selectors
diff --git a/ui/cypress/tests/connect/rules/deleteTransformationRule.spec.ts
b/ui/cypress/tests/connect/rules/deleteTransformationRule.spec.ts
index ad558ab8d2..19efb96b46 100644
--- a/ui/cypress/tests/connect/rules/deleteTransformationRule.spec.ts
+++ b/ui/cypress/tests/connect/rules/deleteTransformationRule.spec.ts
@@ -37,7 +37,7 @@ describe('Connect delete rule transformation', () => {
ConnectEventSchemaUtils.deleteProperty('reserved bit_1');
ConnectEventSchemaUtils.deleteProperty('reserved bit_2');
- cy.dataCy('schema-preview-result-event').should(
+ ConnectEventSchemaUtils.schemaPreviewResultEvent().should(
'have.text',
'{\u00A0\u00A0\u00A0\u00A0"timestamp":\u00A01715356080000}',
);
@@ -69,7 +69,7 @@ describe('Connect delete rule transformation', () => {
ConnectEventSchemaUtils.deleteProperty('child');
// The resulting string contains non-breaking spaces character (\u00A0)
- cy.dataCy('schema-preview-result-event').should(
+ ConnectEventSchemaUtils.schemaPreviewResultEvent().should(
'have.text',
'{\u00A0\u00A0\u00A0\u00A0"parent":\u00A0{\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0"child_two":\u00A0"textTwo"\u00A0\u00A0\u00A0\u00A0},\u00A0\u00A0\u00A0\u00A0"timestamp":\u00A01667904471000}',
);
@@ -78,7 +78,7 @@ describe('Connect delete rule transformation', () => {
// Test to delete the parent property
ConnectEventSchemaUtils.deleteProperty('parent');
- cy.dataCy('schema-preview-result-event').should(
+ ConnectEventSchemaUtils.schemaPreviewResultEvent().should(
'have.text',
'{\u00A0\u00A0\u00A0\u00A0"timestamp":\u00A01667904471000}',
@@ -88,7 +88,7 @@ describe('Connect delete rule transformation', () => {
ConnectEventSchemaUtils.deleteProperty('child');
ConnectEventSchemaUtils.deleteProperty('child_two');
- cy.dataCy('schema-preview-result-event').should(
+ ConnectEventSchemaUtils.schemaPreviewResultEvent().should(
'have.text',
'{\u00A0\u00A0\u00A0\u00A0"parent":\u00A0{},\u00A0\u00A0\u00A0\u00A0"timestamp":\u00A01667904471000}',
);
@@ -97,7 +97,7 @@ describe('Connect delete rule transformation', () => {
// Test to delete the parent property
ConnectEventSchemaUtils.deleteProperty('parent');
- cy.dataCy('schema-preview-result-event').should(
+ ConnectEventSchemaUtils.schemaPreviewResultEvent().should(
'have.text',
'{\u00A0\u00A0\u00A0\u00A0"timestamp":\u00A01667904471000}',
@@ -109,7 +109,7 @@ describe('Connect delete rule transformation', () => {
ConnectEventSchemaUtils.deleteProperty('child');
ConnectEventSchemaUtils.deleteProperty('child_two');
- cy.dataCy('schema-preview-result-event').should(
+ ConnectEventSchemaUtils.schemaPreviewResultEvent().should(
'have.text',
'{\u00A0\u00A0\u00A0\u00A0"parent":\u00A0{},\u00A0\u00A0\u00A0\u00A0"timestamp":\u00A01667904471000}',
);
diff --git a/ui/cypress/tests/connect/rules/regexRule.spec.ts
b/ui/cypress/tests/connect/rules/regexRule.spec.ts
new file mode 100644
index 0000000000..c9ac4d194a
--- /dev/null
+++ b/ui/cypress/tests/connect/rules/regexRule.spec.ts
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ * 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 { ConnectUtils } from '../../../support/utils/connect/ConnectUtils';
+import { ConnectEventSchemaUtils } from
'../../../support/utils/connect/ConnectEventSchemaUtils';
+import { ConnectBtns } from '../../../support/utils/connect/ConnectBtns';
+import { FileManagementUtils } from
'../../../support/utils/FileManagementUtils';
+
+describe('Connect value rule transformations', () => {
+ beforeEach('Setup Test', () => {
+ cy.initStreamPipesTest();
+ FileManagementUtils.addFile('connect/regexRule/input.csv');
+ });
+
+ it('Perform Test Replace All True', () => {
+ runTest('aenaor01', 'a', true, 'expectedReplaceAllTrue.csv');
+ });
+
+ it('Perform Test Replace All False', () => {
+ runTest('aensor01', 'a', false, 'expectedReplaceAllFalse.csv');
+ });
+
+ it('Perform Test Replace With Empty String', () => {
+ runTest(
+ 'enor01',
+ '',
+ true,
+ 'expectedReplaceAllTrueWithEmptyString.csv',
+ );
+ });
+
+ function runTest(
+ expectedPreview: string,
+ replaceWith: string,
+ replaceAll: boolean,
+ expecedCsvFile: string,
+ ) {
+ const adapterConfiguration =
+ ConnectUtils.setUpPreprocessingRuleTest(false);
+
+ // Ensure regex input is not shown for number property
+ ConnectEventSchemaUtils.clickEditProperty('density');
+ ConnectEventSchemaUtils.regexValueInput().should('not.exist');
+ ConnectBtns.saveEditProperty().click();
+ ConnectEventSchemaUtils.clickEditProperty('sensorId');
+ ConnectEventSchemaUtils.regexValueInput().should('be.visible');
+
+ // Validate that preview works
+ ConnectEventSchemaUtils.regexValueInput().type('s');
+ if (replaceWith !== '') {
+ ConnectEventSchemaUtils.regexReplaceWithValueInput().type(
+ replaceWith,
+ );
+ }
+ if (replaceAll) {
+ ConnectEventSchemaUtils.regexReplaceAllCheckbox().click();
+ }
+
+ ConnectBtns.saveEditProperty().click();
+
+ ConnectEventSchemaUtils.schemaPreviewResultEvent().should(
+ 'contain.text',
+ expectedPreview,
+ );
+ ConnectEventSchemaUtils.markPropertyAsTimestamp('timestamp');
+ ConnectEventSchemaUtils.finishEventSchemaConfiguration();
+
+ ConnectUtils.tearDownPreprocessingRuleTest(
+ adapterConfiguration,
+ 'cypress/fixtures/connect/regexRule/' + expecedCsvFile,
+ true,
+ );
+ }
+});
diff --git
a/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model-client.ts
b/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model-client.ts
index 4cbe0f01c0..a71be226f2 100644
---
a/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model-client.ts
+++
b/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model-client.ts
@@ -16,13 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
-
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
-// Generated using typescript-generator version 3.2.1263 on 2024-09-08
22:18:46.
+// Generated using typescript-generator version 3.2.1263 on 2024-10-07
13:58:29.
-import { Storable } from './streampipes-model';
+import { Storable } from '@streampipes/platform-services';
export class Group implements Storable {
elementId: string;
diff --git
a/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model.ts
b/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model.ts
index 1ae8e4e32d..e5faa9118d 100644
---
a/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model.ts
+++
b/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model.ts
@@ -16,11 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
-
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
-// Generated using typescript-generator version 3.2.1263 on 2024-09-30
14:11:40.
+// Generated using typescript-generator version 3.2.1263 on 2024-10-07
13:58:27.
export class NamedStreamPipesEntity implements Storable {
'@class':
@@ -209,6 +208,7 @@ export class TransformationRuleDescription {
|
'org.apache.streampipes.model.connect.rules.value.AddValueTransformationRuleDescription'
|
'org.apache.streampipes.model.connect.rules.value.TimestampTranfsformationRuleDescription'
|
'org.apache.streampipes.model.connect.rules.value.UnitTransformRuleDescription'
+ |
'org.apache.streampipes.model.connect.rules.value.RegexTransformationRuleDescription'
|
'org.apache.streampipes.model.connect.rules.value.ChangeDatatypeTransformationRuleDescription'
|
'org.apache.streampipes.model.connect.rules.value.CorrectionValueTransformationRuleDescription'
|
'org.apache.streampipes.model.connect.rules.stream.StreamTransformationRuleDescription'
@@ -261,6 +261,8 @@ export class TransformationRuleDescription {
return DeleteRuleDescription.fromData(data);
case
'org.apache.streampipes.model.connect.rules.schema.RenameRuleDescription':
return RenameRuleDescription.fromData(data);
+ case
'org.apache.streampipes.model.connect.rules.value.RegexTransformationRuleDescription':
+ return RegexTransformationRuleDescription.fromData(data);
case
'org.apache.streampipes.model.connect.rules.schema.MoveRuleDescription':
return MoveRuleDescription.fromData(data);
case
'org.apache.streampipes.model.connect.rules.value.ChangeDatatypeTransformationRuleDescription':
@@ -282,6 +284,7 @@ export class ValueTransformationRuleDescription extends
TransformationRuleDescri
|
'org.apache.streampipes.model.connect.rules.value.AddValueTransformationRuleDescription'
|
'org.apache.streampipes.model.connect.rules.value.TimestampTranfsformationRuleDescription'
|
'org.apache.streampipes.model.connect.rules.value.UnitTransformRuleDescription'
+ |
'org.apache.streampipes.model.connect.rules.value.RegexTransformationRuleDescription'
|
'org.apache.streampipes.model.connect.rules.value.ChangeDatatypeTransformationRuleDescription'
|
'org.apache.streampipes.model.connect.rules.value.CorrectionValueTransformationRuleDescription';
@@ -316,6 +319,8 @@ export class ValueTransformationRuleDescription extends
TransformationRuleDescri
return CorrectionValueTransformationRuleDescription.fromData(
data,
);
+ case
'org.apache.streampipes.model.connect.rules.value.RegexTransformationRuleDescription':
+ return RegexTransformationRuleDescription.fromData(data);
}
}
}
@@ -3061,6 +3066,30 @@ export class QuantitativeValue extends
ValueSpecification {
}
}
+export class RegexTransformationRuleDescription extends
ValueTransformationRuleDescription {
+ '@class':
'org.apache.streampipes.model.connect.rules.value.RegexTransformationRuleDescription';
+ 'regex': string;
+ 'replaceAll': boolean;
+ 'replaceWith': string;
+ 'runtimeKey': string;
+
+ static 'fromData'(
+ data: RegexTransformationRuleDescription,
+ target?: RegexTransformationRuleDescription,
+ ): RegexTransformationRuleDescription {
+ if (!data) {
+ return data;
+ }
+ const instance = target || new RegexTransformationRuleDescription();
+ super.fromData(data, instance);
+ instance.regex = data.regex;
+ instance.replaceAll = data.replaceAll;
+ instance.replaceWith = data.replaceWith;
+ instance.runtimeKey = data.runtimeKey;
+ return instance;
+ }
+}
+
export class RemoveDuplicatesTransformationRuleDescription extends
StreamTransformationRuleDescription {
'@class':
'org.apache.streampipes.model.connect.rules.stream.RemoveDuplicatesTransformationRuleDescription';
'filterTimeWindow': string;
@@ -4080,6 +4109,7 @@ export type TransformationRuleDescriptionUnion =
| CreateNestedRuleDescription
| DeleteRuleDescription
| RenameRuleDescription
+ | RegexTransformationRuleDescription
| MoveRuleDescription
| ChangeDatatypeTransformationRuleDescription
| CorrectionValueTransformationRuleDescription;
@@ -4100,7 +4130,8 @@ export type ValueTransformationRuleDescriptionUnion =
| AddValueTransformationRuleDescription
| TimestampTranfsformationRuleDescription
| UnitTransformRuleDescription
- | CorrectionValueTransformationRuleDescription;
+ | CorrectionValueTransformationRuleDescription
+ | RegexTransformationRuleDescription;
function __getCopyArrayFn<T>(itemCopyFn: (item: T) => T): (array: T[]) => T[] {
return (array: T[]) => __copyArray(array, itemCopyFn);
diff --git
a/ui/projects/streampipes/platform-services/src/lib/model/types/data-type.ts
b/ui/projects/streampipes/platform-services/src/lib/model/types/data-type.ts
index 077b9b9741..74e75ac9ea 100644
--- a/ui/projects/streampipes/platform-services/src/lib/model/types/data-type.ts
+++ b/ui/projects/streampipes/platform-services/src/lib/model/types/data-type.ts
@@ -41,4 +41,8 @@ export class DataType {
public static isBooleanType(datatype: string): boolean {
return datatype === DataType.BOOLEAN;
}
+
+ public static isStringType(datatype: string): boolean {
+ return datatype === DataType.STRING;
+ }
}
diff --git a/ui/src/app/connect/connect.module.ts
b/ui/src/app/connect/connect.module.ts
index 0d0e598a31..f66f7edebb 100644
--- a/ui/src/app/connect/connect.module.ts
+++ b/ui/src/app/connect/connect.module.ts
@@ -104,6 +104,7 @@ import { AdapterStatusLightComponent } from
'./components/existing-adapters/adap
import { SpAdapterDeploymentSettingsComponent } from
'./components/adapter-configuration/adapter-settings/adapter-deployment-settings/adapter-deployment-settings.component';
import { SpAdapterDocumentationDialogComponent } from
'./dialog/adapter-documentation/adapter-documentation-dialog.component';
import { AdapterDetailsDataComponent } from
'./components/adapter-details/adapter-details-data/adapter-details-data.component';
+import { EditRegexTransformationComponent } from
'./dialog/edit-event-property/components/edit-regex-transformation/edit-regex-transformation.component';
@NgModule({
imports: [
@@ -204,6 +205,7 @@ import { AdapterDetailsDataComponent } from
'./components/adapter-details/adapte
DeleteAdapterDialogComponent,
EventSchemaComponent,
EditEventPropertyComponent,
+ EditRegexTransformationComponent,
EventPropertyRowComponent,
EditUnitTransformationComponent,
EditSchemaTransformationComponent,
diff --git
a/ui/src/app/connect/dialog/edit-event-property/components/edit-regex-transformation/edit-regex-transformation.component.html
b/ui/src/app/connect/dialog/edit-event-property/components/edit-regex-transformation/edit-regex-transformation.component.html
new file mode 100644
index 0000000000..e75269a4c2
--- /dev/null
+++
b/ui/src/app/connect/dialog/edit-event-property/components/edit-regex-transformation/edit-regex-transformation.component.html
@@ -0,0 +1,52 @@
+<!--
+ ~ 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.
+ ~
+ -->
+
+<div fxLayout="column" fxLayoutAlign="start">
+ <div fxFlex="50" fxLayoutAlign="start center">
+ <mat-form-field class="w-100" color="accent">
+ <input
+ matInput
+ type="text"
+ name="regex"
+ placeholder="Regular expression"
+ data-cy="regex-value"
+ [(ngModel)]="cachedProperty.additionalMetadata.regex"
+ />
+ </mat-form-field>
+ </div>
+ <div fxFlex="50" fxLayoutAlign="start center">
+ <mat-form-field class="w-100" color="accent">
+ <input
+ matInput
+ type="text"
+ name="replaceWith"
+ placeholder="Replace with"
+ data-cy="regex-replace-with-value"
+ [(ngModel)]="cachedProperty.additionalMetadata.replaceWith"
+ />
+ </mat-form-field>
+ </div>
+ <div fxFlex="50" fxLayoutAlign="start center">
+ <mat-checkbox
+ data-cy="regex-replace-all-value"
+ [(ngModel)]="cachedProperty.additionalMetadata.replaceAll"
+ >
+ <span>Replace All Occurrences</span>
+ </mat-checkbox>
+ </div>
+</div>
diff --git
a/ui/src/app/connect/dialog/edit-event-property/components/edit-regex-transformation/edit-regex-transformation.component.scss
b/ui/src/app/connect/dialog/edit-event-property/components/edit-regex-transformation/edit-regex-transformation.component.scss
new file mode 100644
index 0000000000..13cbc4aacb
--- /dev/null
+++
b/ui/src/app/connect/dialog/edit-event-property/components/edit-regex-transformation/edit-regex-transformation.component.scss
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ *
+ */
diff --git
a/ui/src/app/connect/dialog/edit-event-property/components/edit-regex-transformation/edit-regex-transformation.component.ts
b/ui/src/app/connect/dialog/edit-event-property/components/edit-regex-transformation/edit-regex-transformation.component.ts
new file mode 100644
index 0000000000..f926738e0e
--- /dev/null
+++
b/ui/src/app/connect/dialog/edit-event-property/components/edit-regex-transformation/edit-regex-transformation.component.ts
@@ -0,0 +1,29 @@
+/*
+ * 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 { Component, Input } from '@angular/core';
+import { EventPropertyUnion } from '@streampipes/platform-services';
+
+@Component({
+ selector: 'sp-edit-regex-transformation',
+ templateUrl: './edit-regex-transformation.component.html',
+ styleUrl: './edit-regex-transformation.component.scss',
+})
+export class EditRegexTransformationComponent {
+ @Input() cachedProperty: EventPropertyUnion;
+}
diff --git
a/ui/src/app/connect/dialog/edit-event-property/components/edit-value-transformation/edit-value-transformation.component.html
b/ui/src/app/connect/dialog/edit-event-property/components/edit-value-transformation/edit-value-transformation.component.html
index 5986d8137d..9cfb5cc517 100644
---
a/ui/src/app/connect/dialog/edit-event-property/components/edit-value-transformation/edit-value-transformation.component.html
+++
b/ui/src/app/connect/dialog/edit-event-property/components/edit-value-transformation/edit-value-transformation.component.html
@@ -60,4 +60,14 @@
/>
</mat-form-field>
</sp-ep-settings-section>
+ <sp-ep-settings-section
+ sectionTitle="Regex Value Transformation"
+ sectionDescription="Transforms the original field values using the
provided regex"
+ fxLayout="column"
+ fxFlex="100"
+ *ngIf="isStringProperty"
+ >
+ <sp-edit-regex-transformation [cachedProperty]="cachedProperty">
+ </sp-edit-regex-transformation>
+ </sp-ep-settings-section>
</div>
diff --git
a/ui/src/app/connect/dialog/edit-event-property/components/edit-value-transformation/edit-value-transformation.component.ts
b/ui/src/app/connect/dialog/edit-event-property/components/edit-value-transformation/edit-value-transformation.component.ts
index fd87bf99a1..73238f6d3c 100644
---
a/ui/src/app/connect/dialog/edit-event-property/components/edit-value-transformation/edit-value-transformation.component.ts
+++
b/ui/src/app/connect/dialog/edit-event-property/components/edit-value-transformation/edit-value-transformation.component.ts
@@ -40,6 +40,7 @@ export class EditValueTransformationComponent implements
OnInit {
@Input() isListProperty: boolean;
@Input() isPrimitiveProperty: boolean;
@Input() isNumericProperty: boolean;
+ @Input() isStringProperty: boolean;
addedByUser: boolean;
staticValue: string;
diff --git
a/ui/src/app/connect/dialog/edit-event-property/edit-event-property.component.html
b/ui/src/app/connect/dialog/edit-event-property/edit-event-property.component.html
index 0fe15aea50..cc7aad6cad 100644
---
a/ui/src/app/connect/dialog/edit-event-property/edit-event-property.component.html
+++
b/ui/src/app/connect/dialog/edit-event-property/edit-event-property.component.html
@@ -82,6 +82,7 @@
[isNestedProperty]="isEventPropertyNested"
[isListProperty]="isEventPropertyList"
[isPrimitiveProperty]="isEventPropertyPrimitive"
+ [isStringProperty]="isStringProperty"
#valueTransformationComponent
>
</sp-edit-value-transformation>
@@ -98,17 +99,6 @@
</sp-edit-unit-transformation>
</div>
</form>
-
- <!-- <sp-edit-event-property-primitive-->
- <!-- *ngIf="isEventPropertyPrimitive"-->
- <!--
[isTimestampProperty]="isTimestampProperty"-->
- <!-- [cachedProperty]="cachedProperty"-->
- <!--
(isNumericDataType)="isNumericDataType($event)">-->
- <!-- </sp-edit-event-property-primitive>-->
- <!-- <sp-edit-event-property-list-->
- <!-- *ngIf="isEventPropertyList"-->
- <!-- [cachedProperty]="cachedProperty">-->
- <!-- </sp-edit-event-property-list>-->
</div>
</div>
<mat-divider></mat-divider>
diff --git
a/ui/src/app/connect/dialog/edit-event-property/edit-event-property.component.ts
b/ui/src/app/connect/dialog/edit-event-property/edit-event-property.component.ts
index 0cff8aefd4..ea7f191aca 100644
---
a/ui/src/app/connect/dialog/edit-event-property/edit-event-property.component.ts
+++
b/ui/src/app/connect/dialog/edit-event-property/edit-event-property.component.ts
@@ -66,6 +66,7 @@ export class EditEventPropertyComponent implements OnInit {
isEventPropertyNested: boolean;
isEventPropertyList: boolean;
isNumericProperty: boolean;
+ isStringProperty: boolean;
isSaveBtnEnabled: boolean;
private propertyForm: UntypedFormGroup;
@@ -89,6 +90,9 @@ export class EditEventPropertyComponent implements OnInit {
this.isNumericProperty =
SemanticType.isNumber(this.cachedProperty) ||
DataType.isNumberType((this.cachedProperty as any).runtimeType);
+ this.isStringProperty = DataType.isStringType(
+ (this.cachedProperty as any).runtimeType,
+ );
this.createForm();
}
@@ -116,6 +120,13 @@ export class EditEventPropertyComponent implements OnInit {
ep.additionalMetadata.formatString;
result.additionalMetadata.multiplier =
ep.additionalMetadata.multiplier;
+
+ result.additionalMetadata.regex =
+ ep.additionalMetadata.regex || undefined;
+ result.additionalMetadata.replaceWith =
+ ep.additionalMetadata.replaceWith || undefined;
+ result.additionalMetadata.replaceAll =
+ ep.additionalMetadata.replaceAll || undefined;
}
(result as any).staticValue = (ep as any).staticValue;
@@ -177,6 +188,13 @@ export class EditEventPropertyComponent implements OnInit {
this.cachedProperty.additionalMetadata.correctionValue;
this.property.additionalMetadata.operator =
this.cachedProperty.additionalMetadata.operator;
+
+ this.property.additionalMetadata.regex =
+ this.cachedProperty.additionalMetadata.regex;
+ this.property.additionalMetadata.replaceWith =
+ this.cachedProperty.additionalMetadata.replaceWith;
+ this.property.additionalMetadata.replaceAll =
+ this.cachedProperty.additionalMetadata.replaceAll;
}
this.dialogRef.close({ data: this.property });
this.shepherdService.trigger('adapter-field-changed');
diff --git a/ui/src/app/connect/services/transformation-rule.service.ts
b/ui/src/app/connect/services/transformation-rule.service.ts
index b79883961a..5d87c36d69 100644
--- a/ui/src/app/connect/services/transformation-rule.service.ts
+++ b/ui/src/app/connect/services/transformation-rule.service.ts
@@ -31,6 +31,7 @@ import {
EventSchema,
MoveRuleDescription,
PropertyScope,
+ RegexTransformationRuleDescription,
RenameRuleDescription,
SemanticType,
TimestampTranfsformationRuleDescription,
@@ -100,6 +101,13 @@ export class TransformationRuleService {
// Scale
transformationRuleDescriptions = transformationRuleDescriptions
+ .concat(
+ this.getRegexTransformationRules(
+ targetSchema.eventProperties,
+ originalSchema,
+ targetSchema,
+ ),
+ )
.concat(
this.getCorrectionValueRules(
targetSchema.eventProperties,
@@ -671,4 +679,59 @@ export class TransformationRuleService {
return filteredResult;
}
+
+ private getRegexTransformationRules(
+ eventProperties: EventPropertyUnion[],
+ oldEventSchema: EventSchema,
+ newEventSchema: EventSchema,
+ ) {
+ const result: RegexTransformationRuleDescription[] = [];
+
+ eventProperties.forEach(eventProperty => {
+ if (eventProperty instanceof EventPropertyPrimitive) {
+ const newRuntimeName = this.getCompleteRuntimeNameKey(
+ newEventSchema.eventProperties,
+ eventProperty.elementId,
+ );
+
+ if (
+ eventProperty.additionalMetadata?.regex &&
+ eventProperty.additionalMetadata?.regex != ''
+ ) {
+ const rule =
+
this.createRegexTransformationRuleDescriptionFromEventProperty(
+ newRuntimeName,
+ eventProperty,
+ );
+
+ result.push(rule);
+ }
+ } else if (eventProperty instanceof EventPropertyNested) {
+ result.push(
+ ...this.getRegexTransformationRules(
+ eventProperty.eventProperties,
+ oldEventSchema,
+ newEventSchema,
+ ),
+ );
+ }
+ });
+
+ return result;
+ }
+
+ private createRegexTransformationRuleDescriptionFromEventProperty(
+ newRuntimeName: string,
+ eventProperty: EventPropertyPrimitive,
+ ) {
+ const rule: RegexTransformationRuleDescription =
+ new RegexTransformationRuleDescription();
+ rule['@class'] =
+
'org.apache.streampipes.model.connect.rules.value.RegexTransformationRuleDescription';
+ rule.runtimeKey = newRuntimeName;
+ rule.regex = eventProperty.additionalMetadata.regex;
+ rule.replaceWith = eventProperty.additionalMetadata.replaceWith ?? '';
+ rule.replaceAll = eventProperty.additionalMetadata.replaceAll ?? false;
+ return rule;
+ }
}