简体   繁体   中英

mulesoft dataweave 2.0 mapObject recursion match JSON values

I have a kafka message listener connector and after that there is the connector 'Avro Scheme' by mulesoft. Now this Avro Scheme connector replaces parts of my JSON where there is a validation error. I'm trying to see where & what exception occured.

I have following payload:

 [ { "movementId": "a4fa404e-6983-11ed-a1eb-0242ac120002", "movementNumber": "123456789", "movementDate": "2022-11-22", "originLocationId": { "localizedMessage": "Invalid UUID string: ipsum et", "kind": "AvroReadingException", "cause": null, "message": "Invalid UUID string: ipsum et", "stackTrace": [ ], "suppressed": [ ] }, "originLocationCode": "jos", "actDepartureDateTime": "2022-11-21T11:08:17.057", "estArrivalDateTime": "2022-11-21T11:08:17.057", "delays": null, "event": { "id": { "localizedMessage": "Invalid UUID string: Excepteur", "kind": "AvroReadingException", "cause": null, "message": "Invalid UUID string: Excepteur", "stackTrace": [ ], "suppressed": [ ] }, "created": "2022-11-21T11:08:17.057", "source": { "application": "TEST", "server": "aute reprehenderit et", "instance": "exercitation" } } } ]

Now I need to fetch the paths of all the JSON objects where the value 'AvroReadingException' occurs. It doesn't really matter if it is the full path to the JSON key, but something to identify where the exception was thrown.

In given example the expected result could be:

 [ { "originLocationId": "Invalid UUID string: ipsum et" }, { "event.id": "Invalid UUID string: Excepteur" } [

I started with following test, but cannot seem to get it to work:

 %dw 2.0 output application/json fun test(root, value, opt) = do { value match { case arr is Array -> value map (value, index) -> test(null, value, null) case obj is Object -> value mapObject { ($$): test($$, $, root) } else -> if (value is String and (value contains 'AvroReadingException')) value ++ "------" ++ opt else "++++" } } --- test(null, payload, null)

Thanks in advance!

You can use the following. I have broken the logic in multiple functions to make it more readable.

%dw 2.0
output application/json

// This is just a small utility function to easily concatenate strings to get path
fun appendToPath(currentPath, pathToAppend) = 
    if(isEmpty(currentPath)) pathToAppend
    else currentPath ++ "." ++ pathToAppend

fun isRequiredExceptionObject(data) = 
    (data is Object) and (data.kind == "AvroReadingException")

/**
 * This is the recursive function. The path is basically the path
 * that has been collected till now. For example. In your case
 * for calculating "event.id", when the function is called recursively this value will be "event"
 */
fun getAvroReadingExceptions(validationPayload: Object, path="") = 
    entriesOf(validationPayload)
    reduce ((item, accumulator = {}) -> 
        item.value match {
            
            case value if(isRequiredExceptionObject(value)) -> {
                    (accumulator),
                    (path appendToPath item.key): value.message
            }
            case is Object -> {
                (accumulator),
                (getAvroReadingExceptions(item.value, path appendToPath item.key))
            }
            case is Array -> {
                (accumulator),
                (item.value map getAvroReadingExceptions($, path appendToPath item.key ++ "[$($$)]"))
            }

            else -> accumulator
        }
    )
---
payload map getAvroReadingExceptions($)

This also handles internal arrays. I have used the following input and added an array arrayTest which has 3 elements, among which 2 has a field that is AvroReadingException .

[
  {
    "movementId": "a4fa404e-6983-11ed-a1eb-0242ac120002",
    "movementNumber": "123456789",
    "movementDate": "2022-11-22",
    "originLocationId": {
      "localizedMessage": "Invalid UUID string: ipsum et",
      "kind": "AvroReadingException",
      "cause": null,
      "message": "Invalid UUID string: ipsum et",
      "stackTrace": [
        
      ],
      "suppressed": [
        
      ]
    },
    "originLocationCode": "jos",
    "actDepartureDateTime": "2022-11-21T11:08:17.057",
    "estArrivalDateTime": "2022-11-21T11:08:17.057",
    "delays": null,
    "event": {
      "id": {
        "localizedMessage": "Invalid UUID string: Excepteur",
        "kind": "AvroReadingException",
        "cause": null,
        "message": "Invalid UUID string: Excepteur",
        "stackTrace": [
          
        ],
        "suppressed": [
          
        ]
      },
      "created": "2022-11-21T11:08:17.057",
      "source": {
        "application": "TEST",
        "server": "aute reprehenderit et",
        "instance": "exercitation"
      }
    },
    "arrayTest": [
      {
        "field1": "sdf",
        "field2": {
          "localizedMessage": "Invalid UUID string in array: element3",
          "kind": "AvroReadingException",
          "cause": null,
          "message": "Invalid UUID string in array: element1",
          "stackTrace": [
            
          ],
          "suppressed": [
            
          ]
        }
      },
      {
        "field1": "sdf",
        "field2": "sdf"
      },
      {
        "field1": "sdf",
        "field2": {
          "localizedMessage": "Invalid UUID string in array: element3",
          "kind": "AvroReadingException",
          "cause": null,
          "message": "Invalid UUID string in array: element3",
          "stackTrace": [
            
          ],
          "suppressed": [
            
          ]
        }
      }
    ]
  }
]

This is the output from the Dataweave

[
  {
    "originLocationId": "Invalid UUID string: ipsum et",
    "event.id": "Invalid UUID string: Excepteur",
    "arrayTest[0].field2": "Invalid UUID string in array: element1",
    "arrayTest[2].field2": "Invalid UUID string in array: element3"
  }
]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM