Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
switschel committed Jan 15, 2025
2 parents 1e65f63 + f181dd6 commit e71949b
Show file tree
Hide file tree
Showing 14 changed files with 70 additions and 29 deletions.
18 changes: 10 additions & 8 deletions INSTALLATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,35 +33,37 @@ Make sure that you subscribe the microservice to your tenant when prompted

### Web app

The frontend can be used in two variants in your tenant:
The frontend can be deployed in your tenant:

1. As a **UI Plugin** to extend existing applications
2. As a **Blueprint** standalone Application selectable from the App switcher
1. As a **Blueprint** standalone Application selectable from the App switcher

> **_NOTE:_** The option to deploy the dynamic mapper as plugin is deprecated.
#### Community store (Preferred)

The Web App is part of the community store and should be available directly in your tenant under
"Administration" -> "Ecosystem" -> "Extensions" -> "Dynamic-mapping". Here you have the choice to install it as a plugin or as a blueprint app.

##### Plugin
> **_NOTE:_** The option to deploy the dynamic mapper as plugin is deprecated.
##### ~~Plugin~~

> **_NOTE:_** For a plugin we need to clone the Administration app to add the plugin to it
> **_NOTE:_** ~~For a plugin we need to clone the Administration app to add the plugin to i~~
Go to "All Applications" and click on "Add Application". Select "Duplicate existing application" and afterward "Administration".
~~Go to "All Applications" and click on "Add Application". Select "Duplicate existing application" and afterward "Administration".~~

<p align="center">
<img src="resources/image/Dynamic_Mapper_DuplicateApp.png" style="width: 40%;" />
</p>
<br/>

Now select the cloned Administration App and go to the "Plugin" Tab. Click on "Install Plugin" and select "Dynamic Data Mapper Widget"
~~Now select the cloned Administration App and go to the "Plugin" Tab. Click on "Install Plugin" and select "Dynamic Data Mapper Widget"~~

<p align="center">
<img src="resources/image/Dynamic_Mapper_Installation_Plugin.png" style="width: 50%;" />
</p>
<br/>

After successfully adding the plugin you need to refresh the Administration App by pressing F5 and you should see a new navigation entry "Dynamic Mapping"
~~After successfully adding the plugin you need to refresh the Administration App by pressing F5 and you should see a new navigation entry "Dynamic Mapping"~~

<p align="center">
<img src="resources/image/Dynamic_Mapper_WebAppPlugin.png" style="width: 40%;" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,34 @@ public static String[] splitTopicExcludingSeparatorAsArray(String topic) {
return topic.split("\\/");
}

public static String[] splitTopicExcludingSeparatorIncludingLeagingSlashAsArray(String topic) {
String topix = topic.trim().replaceAll("\\/{1,}$", ""); // Remove trailing slashes only
if (topix.startsWith("//")) { // If multiple leading slashes
topix = "/" + topix.replaceAll("^/+", ""); // Replace with single slash
}

// Special handling for the first slash
if (topix.startsWith("/")) {
String[] parts = topix.substring(1).split("\\/");
String[] result = new String[parts.length + 1];
result[0] = "/";
System.arraycopy(parts, 0, result, 1, parts.length);
return result;
}

return topix.split("\\/");
}

public static List<String> splitTopicExcludingSeparatorAsList(String topic) {
return new ArrayList<String>(
Arrays.asList(Mapping.splitTopicExcludingSeparatorAsArray(topic)));
}

public static List<String> splitTopicExcludingSeparatorIncludingLeagingSlashAsList(String topic) {
return new ArrayList<String>(
Arrays.asList(Mapping.splitTopicExcludingSeparatorIncludingLeagingSlashAsArray(topic)));
}

/*
* only one substitution can be marked with definesIdentifier == true
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public void enrichPayload(ProcessingContext<T> context) {
String tenant = context.getTenant();
Object payloadObject = context.getPayload();

List<String> splitTopicAsList = Mapping.splitTopicExcludingSeparatorAsList(context.getTopic());
List<String> splitTopicAsList = Mapping.splitTopicExcludingSeparatorIncludingLeagingSlashAsList(context.getTopic());
if (payloadObject instanceof Map) {
((Map) payloadObject).put(Mapping.TOKEN_TOPIC_LEVEL, splitTopicAsList);
if (context.isSupportsMessageContext() && context.getKey() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public ProcessingContext<T> substituteInTargetAndSend(ProcessingContext<T> conte
* step 0 patch payload with dummy property _TOPIC_LEVEL_ in case the content
* is required in the payload for a substitution
*/
List<String> splitTopicExAsList = Mapping.splitTopicExcludingSeparatorAsList(context.getTopic());
List<String> splitTopicExAsList = Mapping.splitTopicExcludingSeparatorIncludingLeagingSlashAsList(context.getTopic());
payloadTarget.put("$", Mapping.TOKEN_TOPIC_LEVEL, splitTopicExAsList);
if (mapping.supportsMessageContext) {
Map<String, String> cod = new HashMap<String, String>() {
Expand Down
16 changes: 8 additions & 8 deletions dynamic-mapping-ui/cumulocity.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ export default {
noAppSwitcher: false,
package: 'blueprint',
isPackage: true,
exports: [
{
name: 'Dynamic Mapping Mapper Plugin',
module: 'DynamicMappingModule',
path: './src/dynamic-mapping.module.ts',
description: 'Adds a Dynamic Mapping Mapper Plugin'
}
]
// exports: [
// {
// name: 'Dynamic Mapping Mapper Plugin',
// module: 'DynamicMappingModule',
// path: './src/dynamic-mapping.module.ts',
// description: 'Adds a Dynamic Mapping Mapper Plugin'
// }
// ]
},
buildTime: {
copy: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
RepairStrategy,
getPathTargetForDeviceIdentifiers, transformGenericPath2C8YPath
} from '../../../shared';
import { splitTopicExcludingSeparator } from '../../shared/util';
import { splitTopicExcludingSeparatorIncludingLeagingSlash } from '../../shared/util';
import { C8YAgent } from '../c8y-agent.service';
import {
IDENTITY,
Expand Down Expand Up @@ -65,7 +65,7 @@ export abstract class BaseProcessorInbound {

enrichPayload(context: ProcessingContext): void {
const { payload } = context;
const topicLevels = splitTopicExcludingSeparator(context.topic);
const topicLevels = splitTopicExcludingSeparatorIncludingLeagingSlash(context.topic);
payload[TOKEN_TOPIC_LEVEL] = topicLevels;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import * as _ from 'lodash';
import { API, Mapping, MappingType, RepairStrategy } from '../../../shared';
import {
TOKEN_TOPIC_LEVEL,
splitTopicExcludingSeparator,
splitTopicExcludingSeparatorIncludingLeagingSlash,
splitTopicIncludingSeparator
} from '../../shared/util';
import { C8YAgent } from '../c8y-agent.service';
Expand Down Expand Up @@ -72,7 +72,7 @@ export abstract class BaseProcessorOutbound {
* step 0 patch payload with dummy property _TOPIC_LEVEL_ in case the content
* is required in the payload for a substitution
*/
const splitTopicExAsList: string[] = splitTopicExcludingSeparator(
const splitTopicExAsList: string[] = splitTopicExcludingSeparatorIncludingLeagingSlash(
context.topic
);
payloadTarget[TOKEN_TOPIC_LEVEL] = splitTopicExAsList;
Expand Down
16 changes: 16 additions & 0 deletions dynamic-mapping-ui/src/mapping/shared/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,22 @@ export function splitTopicExcludingSeparator(topic: string): string[] {
return topix.split(/\//g);
}

export function splitTopicExcludingSeparatorIncludingLeagingSlash(topic: string): string[] {
let topix = topic;
topix = topix.trim().replace(/(\/{1,}$)/g, ''); // Remove trailing slashes
if (topix.startsWith('//')) { // If there are multiple leading slashes
topix = '/' + topix.replace(/^\/+/, ''); // Replace with single slash
}

// Special handling for the first slash
if (topix.startsWith('/')) {
const parts = topix.substring(1).split(/\//g);
return ['/'].concat(parts);
}

return topix.split(/\//g);
}

export function splitTopicIncludingSeparator(topic: string): string[] {
const topix = topic;
return topix.split(/(?<=\/)|(?=\/)/g);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ import {
expandExternalTemplate,
isTypeOf,
reduceSourceTemplate,
splitTopicExcludingSeparator
splitTopicExcludingSeparatorIncludingLeagingSlash
} from '../shared/util';
import { EditSubstitutionComponent } from '../substitution/edit/edit-substitution-modal.component';
import { SubstitutionRendererComponent } from '../substitution/substitution-grid.component';
Expand Down Expand Up @@ -566,7 +566,7 @@ export class MappingStepperComponent implements OnInit, OnDestroy {
this.mapping
);
} else {
const levels: string[] = splitTopicExcludingSeparator(
const levels: string[] = splitTopicExcludingSeparatorIncludingLeagingSlash(
this.mapping.mappingTopicSample
);
this.targetTemplate = expandExternalTemplate(
Expand Down Expand Up @@ -694,7 +694,7 @@ export class MappingStepperComponent implements OnInit, OnDestroy {
}

private expandTemplates() {
const levels: string[] = splitTopicExcludingSeparator(
const levels: string[] = splitTopicExcludingSeparatorIncludingLeagingSlash(
this.mapping.direction == Direction.INBOUND
? this.mapping.mappingTopicSample
: this.mapping.publishTopicSample
Expand Down Expand Up @@ -772,7 +772,7 @@ export class MappingStepperComponent implements OnInit, OnDestroy {
this.sourceTemplate = expandExternalTemplate(
this.sourceTemplate,
this.mapping,
splitTopicExcludingSeparator(this.mapping.mappingTopicSample)
splitTopicExcludingSeparatorIncludingLeagingSlash(this.mapping.mappingTopicSample)
);
} else {
this.sourceTemplate = expandC8YTemplate(
Expand Down Expand Up @@ -800,7 +800,7 @@ export class MappingStepperComponent implements OnInit, OnDestroy {
this.sourceTemplate = expandExternalTemplate(
this.sourceTemplate,
this.mapping,
splitTopicExcludingSeparator(this.mapping.mappingTopicSample)
splitTopicExcludingSeparatorIncludingLeagingSlash(this.mapping.mappingTopicSample)
);
} else {
this.sourceTemplate = expandC8YTemplate(
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed resources/samples/SampleMappings_13.xlsx
Binary file not shown.
Binary file not shown.
Binary file added resources/samples/SampleMappings_14.xlsx
Binary file not shown.
4 changes: 2 additions & 2 deletions resources/samples/mappings-INBOUND.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
"mappingType": "JSON",
"substitutions": [
{
"pathSource": "_TOPIC_LEVEL_[0]&\"_\"&_TOPIC_LEVEL_[1]&\"_\"&$substringBefore(_TOPIC_LEVEL_[2],\"_\")",
"pathSource": "_TOPIC_LEVEL_[1]&\"_\"&_TOPIC_LEVEL_[2]&\"_\"&$substringBefore(_TOPIC_LEVEL_[3],\"_\")",
"pathTarget": "_IDENTITY_.externalId",
"repairStrategy": "DEFAULT",
"expandArray": false
},
{
"pathSource": "$substringAfter(_TOPIC_LEVEL_[2],\"_\")",
"pathSource": "$substringAfter(_TOPIC_LEVEL_[3],\"_\")",
"pathTarget": "type",
"repairStrategy": "DEFAULT",
"expandArray": false
Expand Down

0 comments on commit e71949b

Please sign in to comment.