eclipse-ditto/ditto

Mapping outgoing messages not working

MichaelEFlip opened this issue · 3 comments

I am trying to change the content of outgoing messages and want to use outgoing message mapping.
Incoming message mapping I got to work.

I tried directly the following samples (and also tried to adapt them). But I always get the same error message:
2024-06-13 18:15:30,544 INFO [8589e846-e1b3-4328-963d-c42b58c66d2b][] o.e.d.c.s.m.InboundDispatchingSink - Got exception <connectivity:message.mapping.failed> when processing external message with mapper <javascript>: <The external message with content-type '<unspecified>' could not be mapped.>

I tried the following outgoing message mappers:
https://eclipse.dev/ditto/connectivity-mapping.html#mapping-outgoing-messages
https://docs.bosch-iot-suite.com/things/tutorials/public-cloud-integration/azure-iot-hub-http/#configure-payload-mapping

Hi @MichaelEFlip
Please share your outgoing mapping script so that we are able to investigate issues with it..

I think I found the reason for the problem. I am using now the following connection and mapping:

connection

{
  "id": "553d425f-af8d-413f-bbba-e405770c426f",
  "name": null,
  "connectionType": "mqtt",
  "connectionStatus": "open",
  "uri": "tcp://mosquitto-second:1883",
  "sources": [
    {
      "addresses": [
        "test/#"
      ],
      "consumerCount": 1,
      "qos": 0,
      "authorizationContext": [
        "nginx:ditto"
      ],
      "headerMapping": {},
      "replyTarget": {
        "address": "{{header:reply-to}}",
        "headerMapping": {},
        "expectedResponseTypes": [
          "response",
          "error"
        ],
        "enabled": true
      }
    }
  ],
  "targets": [
    {
      "address": "test/{{ thing:id }}",
      "topics": [
        "_/_/things/twin/events",
        "_/_/things/live/messages"
      ],
      "qos": 0,
      "authorizationContext": [
        "nginx:ditto"
      ],
      "headerMapping": {},
      "payloadMapping": [
        "javascript"
      ]
    }
  ],
  "clientCount": 1,
  "failoverEnabled": true,
  "validateCertificates": true,
  "processorPoolSize": 1,
  "mappingDefinitions": {
    "javascript": {
      "mappingEngine": "JavaScript",
      "options": {
        "outgoingScript": "function mapFromDittoProtocolMsg(namespace, name, group, channel, criterion,\n                                 action, path, dittoHeaders, value, status, extra) {\n\n  let headers = dittoHeaders;\n  let payload = {\n      \"methodName\": action,\n      \"responseTimeoutInSeconds\": parseInt(dittoHeaders.timeout),\n      \"payload\": value\n  };\n  let textPayload = JSON.stringify(payload);\n  let bytePayload = null;\n  let contentType = 'application/json';\n\n  return Ditto.buildExternalMsg(headers, textPayload, bytePayload, contentType);\n}"
      }
    }
  },
  "tags": []
}

outgoing mapping

function mapFromDittoProtocolMsg(namespace, name, group, channel, criterion,
                                 action, path, dittoHeaders, value, status, extra) {

  let headers = dittoHeaders;
  let payload = {
      "methodName": action,
      "responseTimeoutInSeconds": parseInt(dittoHeaders.timeout),
      "payload": value
  };
  let textPayload = JSON.stringify(payload);
  let bytePayload = null;
  let contentType = 'application/json';

  return Ditto.buildExternalMsg(headers, textPayload, bytePayload, contentType);
}

I narrowed it down to the following setting of the connection:

"payloadMapping": [
        "javascript"
      ]

Without that setting it does not seem to work, repectivly it will send outgoing messages in plain ditto payload format.

I started my tests with the following example: https://github.com/eclipse-ditto/ditto-examples/blob/master/mqtt-bidirectional/README.md#Payloadmapping

Here the "payloadMapping" setting does not seem to be present in the example. So I think it is not a problem of ditto, but perhaps of the documentation / example.

@MichaelEFlip thanks for providing an update and solution to your question 👍