Field Mapping

The Dynamic Message Mapper uses the fieldMappings attribute to define the mappings. Underneath this is a map representing the target message structure. For each leaf field, the Dynamic Message Mapper can specify a string value, which is a path to the source message field that is placed in this field.

The target message fields and the source message fields are validated when parsing the configuration, as shown in the following example:

fieldMappings:
  Mtx5GMsg:
    Request!Mtx5GChargingDataRequest:
      InvocationSequenceNumber: "ChargingDataRequest.invocationSequenceNumber"
      InvocationTimestamp: "ChargingDataRequest.invocationTimeStamp"
      MultiUnitUsageArray:
        RatingGroup: "ChargingDataRequest.multipleUnitUsage.ratingGroup"
        RequestedUnit:
          DownlinkVolume: "ChargingDataRequest.multipleUnitUsage.requestedUnit.downlinkVolume"
          ServiceSpecificUnits: "ChargingDataRequest.multipleUnitUsage.requestedUnit.serviceSpecificUnits"
          Time: "ChargingDataRequest.multipleUnitUsage.requestedUnit.time"
          TotalVolume: "ChargingDataRequest.multipleUnitUsage.requestedUnit.totalVolume"
          UplinkVolume: "ChargingDataRequest.multipleUnitUsage.requestedUnit.uplinkVolume"
        UpfId: "ChargingDataRequest.multipleUnitUsage.uPFID"

For target message leaf fields, you can define more complex mapping instructions using an in-line object, rather than a simple string. These mapping instructions can include setting a default value for a field or a custom field value mapper.

The following example shows a more complex mapping:

fieldMappings:
  Mtx5GMsg:
    Request!Mtx5GChargingDataRequest:
      InvocationSequenceNumber: "ChargingDataRequest.invocationSequenceNumber"
      InvocationTimestamp: "ChargingDataRequest.invocationTimeStamp"
      MultiUnitUsageArray:
        RatingGroup: "ChargingDataRequest.multipleUnitUsage.ratingGroup"
        RequestedUnit:
          DownlinkVolume: "ChargingDataRequest.multipleUnitUsage.requestedUnit.downlinkVolume"
          ServiceSpecificUnits: "ChargingDataRequest.multipleUnitUsage.requestedUnit.serviceSpecificUnits"
          Time: "ChargingDataRequest.multipleUnitUsage.requestedUnit.time"
          TotalVolume: "ChargingDataRequest.multipleUnitUsage.requestedUnit.totalVolume"
          UplinkVolume: "ChargingDataRequest.multipleUnitUsage.requestedUnit.uplinkVolume"
        UpfId: "ChargingDataRequest.multipleUnitUsage.uPFID"
      SubscriberId: "ChargingDataRequest.subscriberIdentifier"
      TriggerArray:
        MaxChargingConditionChangeCount: "ChargingDataRequest.triggers.maxNumberOfccc"
        TimeLimit: "ChargingDataRequest.triggers.timeLimit"
        TriggerCategory: {from: "ChargingDataRequest.triggers.triggerCategory", fieldValueMapperName: "string.Enum5GTriggerCategory"}
        TriggerType: {from: "ChargingDataRequest.triggers.triggerType", fieldValueMapperName: "string.Enum5GTriggerType", default: "3"}
        VolumeLimit: "ChargingDataRequest.triggers.volumeLimit"
        VolumeLimit64: "ChargingDataRequest.triggers.volumeLimit64"
      HeaderData:
        SessionId: "#params.SessionId"
    Op: "#params.Operation"

In the example, the value of Mtx5GMsg.Request.TriggerArray.TriggerType uses the string.Enum5GTriggerType field value mapper to convert from the incoming string type to the MDC integer type. If there is no value, it defaults to 3. The Mtx5GMsg.Request.TriggerArray.TriggerCategory also uses a field value mapper (string.Enum5GTriggerCategory) but does not give a default value.

Note: The example is for illustrative purposes only and does not reflect the logic for this message type.

Behavior of Defaults

A default value can only be applied to a leaf field and is only when the parent field (branch) is created. This is typically triggered by a peer of this field being mapped from a value in the source message. If there are no mappings that cause the parent branch to be created, then the default is never applied. Additionally, the default value is mapped to the target field. Any custom field value mapper is not applied, although some basic type conversion is applied to map from string to the data type for the target field.

Mapping for Empty Objects

By default, if a source message has an empty object, the corresponding object in the response is not created. For example, the following mapping configuration:
fieldMappings:
  simpleObject:
    attributeOne: "Response.simpleObject.attributeOne"
    attributeTwo: "Response.simpleObject.attributeTwo"
and the following source message:
{
  "simpleObject": {}
}
produces the following target message with an empty object:
{ }
To ensure that an object is created, even if it is empty, you must add a mapping property of _from to the target object. This property has a string value that points to the object in the source that causes its creation. For example, to fix the preceding issue, update the mapping as follows:
fieldMappings:
  simpleObject:
    _from: "Response.simpleObject"
    attributeOne: "Response.simpleObject.attributeOne"
    attributeTwo: "Response.simpleObject.attributeTwo"
This mapping produces the following target message with an empty object:
{
  "simpleObject": {}
}