简体   繁体   中英

Jolt Transformation of JSON with mutual exclusion

I am trying to transform input JSON using JOLT spec. My input has a response element which can have a single text (Case 1) value OR a JSON element (Case 2) like below

JOLT Spec:

[
  {
    "operation": "shift",
    "spec": {
      "@(1,status)": {
        "@(2,output)": {
          "response": "statusMessage"
        },
        "TERMINATED": {
          "@(2,status)": "statusMessage"
        },
        "FAILED": {
          "@(2,response)": "statusMessage"
        },
        "COMPLETED": {
          "@(2,status)": "statusMessage"
        }
      },
      "status": "status"
    }
  }
]

Input (Non-JSON response element) . ----Case 1

{
  "createTime": 1555623377858,
  "updateTime": 1555623378681,
  "status": "FAILED",
  "output": {
    "response": "Connection error."
  }
}

Input (JSON response element) . ----Case 2

{
  "createTime": 1555623377858,
  "updateTime": 1555623378681,
  "status": "FAILED",
  "output": {
    "response": {
      "headers": {
        "ETag": [
          "W/\"5-fy9qFc+NorJ+Wkr0e1jnrXHAs9k\""
        ],
        "Connection": [
          "keep-alive"
        ],
        "Content-Length": [
          "5"
        ],
        "Date": [
          "Thu, 18 Apr 2019 21:36:18 GMT"
        ],
        "Content-Type": [
          "text/html; charset=utf-8"
        ],
        "X-Powered-By": [
          "Express"
        ]
      },
      "reasonPhrase": "Internal Server Error",
      "body": "Error",
      "statusCode": 500
    }
  }
}

How do I specify JOLT spec if I want to assign "reasonPhrase" to statusMessage in the case where the response has JSON element?

My output should look like below

Case 1 response should look like.
{
  "statusMessage" : "Connection Error",
  "status" : "FAILED"
}

Case 2 response should look like this.
{
  "statusMessage" : "Internal Server Error",
  "status" : "FAILED"
}

I think I got it to work with either of the following specs:

1)

[
  {
    "operation": "modify-overwrite-beta",
    "spec": {
      "statusMessage": "@(1,output.response)"
    }
  },
  {
    "operation": "modify-overwrite-beta",
    "spec": {
      "statusMessage": "@(1,output.response.reasonPhrase)"
    }
  },
  {
    "operation": "shift",
    "spec": {
      "status": "status",
      "statusMessage": "statusMessage"
    }
  }
]

The first spec in the chain will store the response value into the statusMessage field. The second will overwrite the statusMessage field with the nested reasonPhrase value (if it exists). The last spec in the chain just keeps the status and statusMessage fields.

2)

[
  {
    "operation": "shift",
    "spec": {
      "output": {
        "response": {
          "@(1,response)": "statusMessage[]",
          "headers": {
            "@(1,reasonPhrase)": "statusMessage[]"
          }
        }
      },
      "status": "status"
    }
  },
  {
    "operation": "modify-overwrite-beta",
    "spec": {
      "statusMessage": "=lastElement(@(1,statusMessage))"
    }
  }
]

It creates an array called statusMessage , if response is a string there will be one element in the array, if it is nested there will be two elements in the array and the second one is the desired status message. So the second spec overwrites the statusMessage field with the last element in its array.

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