JOLT Transform - pattern matching - json

I am trying to transform input fields by matching pattern like "*|*|*" where the words are separated by |. However, I am not able to get it working. If I replace | by :, the spec works. Is there a special meaning to |, how can use this as part of regular expressions?
Input :
{
"items": [
{
"itemId": "1234500AA",
"additionalData": "12345|20001|3000"
}
]
}
Spec :
[
{
"operation": "shift",
"spec": {
"items": {
"*": {
"itemId": "ID",
"additionalData": {
"*|*|*": {
"$(0,1)": ["cartMenuItems[&3].baseProductId", "cartMenuItems[&3].mdmId"],
"$(0,2)": "cartMenuItems[&3].code",
"$(0,3)": "cartMenuItems[&3].sku"
}
}
}
}
}
}
]
Output Expected :
{
"ID": "1234500AA",
"cartMenuItems": [
{
"baseProductId": "12345",
"mdmId": "12345",
"code": "20001",
"sku": "3000"
}
]
}
However, I get an error like below:
JOLT Chainr encountered an exception constructing Transform
className:com.bazaarvoice.jolt.Shiftr at index:0.

Jolt doesn't seem to like | (as you would need to escape them), you could replace the | :
[
{
"operation": "modify-overwrite-beta",
"spec": {
"items": {
"*": {
"additionalDataTemp": "=split('\\|',#(1,additionalData))",
"additionalData": "=concat(#(1,additionalDataTemp[0]),'_',#(1,additionalDataTemp[1]),'_',#(1,additionalDataTemp[2]))"
}
}
}
},
{
"operation": "shift",
"spec": {
"items": {
"*": {
"itemId": "ID",
"additionalData": {
"*_*_*": {
"$(0,1)": ["cartMenuItems[&3].baseProductId", "cartMenuItems[&3].mdmId"],
"$(0,2)": "cartMenuItems[&3].code",
"$(0,3)": "cartMenuItems[&3].sku"
}
}
}
}
}
}
]
Or another way of doing it would be:
[
{
"operation": "modify-overwrite-beta",
"spec": {
"items": {
"*": {
"additionalData": "=split('\\|', #(1,additionalData))",
"baseProductId": "#(1,additionalData[0])",
"mdmId": "#(1,additionalData[0])",
"code": "#(1,additionalData[1])",
"sku": "#(1,additionalData[2])"
}
}
}
},
{
"operation": "shift",
"spec": {
"items": {
"*": {
"itemId": "ID",
"*": "cartMenuItems[0].&"
}
}
}
},
{
"operation": "remove",
"spec": {
"cartMenuItems": {
"*": {
"additionalData": ""
}
}
}
}
]

Related

Masking cards usgins jolt

How can I iterate through list and replace some elements in it? I have this input
{
"clients": [
{
"clientId": "166734",
"info": {
"cards": [
"378282246310005",
"371449635398431"
]
}
}
]
}
I want mask cards like this "cards" : [ "3782*****0005", "3714*****8431" ]
You can use shift transformations to convert the cards array to indexed and 0,1,** labeled objects in order to prepare for modify transformation spec in which substring and concat functions are used such as
[
{
"operation": "shift",
"spec": {
"clients": {
"*": {
"*": "&2[#2].&",
"info": {
"cards": {
"*": {
"#": "&5[#5].&3.&2.&1.&"
}
}
}
}
}
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"clients": {
"*": {
"info": {
"cards": {
"*": {
"p1": "=substring(#(1,&1),0,4)",
"p2": "=substring(#(1,&1),11,15)",
"cs": "=concat(#(1,p1),'********',#(1,p2))"
}
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"clients": {
"*": {
"*": "&2[#2].&",
"info": {
"cards": {
"*": {
"cs": "&5[#5].&3.&2[]"
}
}
}
}
}
}
}
]

Jolt Spec for masking cards

How can I iterate through list and replace some elements in it?
I have this input
{
"clients": [
{
"clientId": "166734",
"info": {
"cards": [
"378282246310005",
"371449635398431"
]
}
}
]
}
What I expect cards will looks like this "cards" : [ "3782", "3714" ]
But in my spec do not work substring
[
{
"operation": "modify-overwrite-beta",
"spec": {
"clients": {
"*": {
"info": {
"cards": {
"*": "=substring(#(1,&),0,#(1,4))"
}
}
}
}
}
}
]
Note 1:
You should not use #(1,&) for getting an array index.
#(1,&) says: Go up 1 level (cards) and get 0 and 1 key from the array with &. But You have an array and should get the index from it.
You can say get & in an array like this: #(1,[&])
Note 2:
For getting the first 4 elements in the string you don't need the #(1,4). just say 4
Simpler solution:
We can get the current level without going up 1 level with #(0) or #0: #0,0,4
[
{
"operation": "modify-overwrite-beta",
"spec": {
"clients": {
"*": {
"info": {
"cards": {
"*": "=substring(#0,0,4)"
}
}
}
}
}
}
]
You can use shift transformations to tame the cards array in order to prepare for modify transformation spec such as
[
{
"operation": "shift",
"spec": {
"clients": {
"*": {
"*": "&2[#2].&",
"info": {
"cards": {
"*": {
"#": "&5[#5].&3.&2.&"
}
}
}
}
}
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"clients": {
"*": {
"info": {
"cards": {
"*": "=substring(#(1,&),0,4)"
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"clients": {
"*": {
"*": "&2[#2].&",
"info": {
"cards": {
"*": "&4[#4].&2.&1[#1]"
}
}
}
}
}
}
]
If there can always only exist two components for cards then we make the whole spec shorter by using [first/last]Element functions, otherwise use "=(#(1,cards[0/1]))" by individually writing such as
[
{
"operation": "modify-overwrite-beta",
"spec": {
"clients": {
"*": {
"info": {
"c0": "=firstElement(#(1,cards))", //or "=(#(1,cards[0]))"
"c1": "=lastElement(#(1,cards))", //or "=(#(1,cards[1]))"
"cards0": "=substring(#(1,c0),0,4)",
"cards1": "=substring(#(1,c1),0,4)"
}
}
}
}
},
{
"operation": "shift",
"spec": {
"clients": {
"*": {
"*": "&2[#2].&",
"info": {
"*s*": "&3[#3].&1.&(0,1)s"
}
}
}
}
}
]

Conversion of if/else based JSON by using Jolt

I have two following json input and i want to convert it into expected output by jolt
input - 1
{
"alert_array": {
"alerts": [
{
"id": "1234",
"data": {
"parameter": [
{
"key": "level",
"value": "93.5"
}
]
}
}
]
}
}
input - 2
{
"alert_array": {
"alerts": [
{
"id": "1234",
"data": {}
}
]
}
}
expected output - 1
{
"alertArray": [
{
"id": "1234",
"properties": [
{
"key": "level",
"value": "93.5"
}
]
}
]
}
expected output - 2
{
"alertArray": [
{
"id": "1234",
"properties": []
}
]
}
In input-1 data contain some parameter but in input-2 data object is blank
You can use default transformation along with shift transformations
in order to add "properties": [] for the empty case of "data" object for the both of the input
JSON values such as
[
{
"operation": "shift",
"spec": {
"*": {
"alerts": {
"*": {
"id": "alertArray.&",
"*": {
"*": {
"*": {
"id": "alertArray.properties[&1].key",
"*": "alertArray.properties[&1].&"
}
}
}
}
}
}
}
},
{
"operation": "default",
"spec": {
"*": {
"properties": []
}
}
},
{
"operation": "shift",
"spec": {
"*": "&[]"
}
}
]
the demo for the first case :
the demo for the second case :
If there was no such need(to fill up for the "data"), then the following single spec would be sufficient :
[
{
"operation": "shift",
"spec": {
"*": {
"alerts": {
"*": {
"id": "alertArray[&1].&",
"*": {
"*": {
"*": {
"id": "alertArray[&4].properties[&1].key",
"*": "alertArray[&4].properties[&1].&"
}
}
}
}
}
}
}
}
]

With JOLT need to Transform JSON object with If Then Else Condition

Below is my Input Json
[
{
"correlationId": "12345",
"payloadFormat": "Money",
"payload": {
"DE35": "123654ABC54678",
"DE45": "898454PQR54678"
}
}
]
I need to Trnsaform this json in such a way if DE35 has value say of substring 6-9 then take DE35 value in Transform Json, if DE35 do not have value then Take DE45 value in transform Json.
So output will be if DE35 Available then
[ {
"COR_ID" : "12345",
"payloadFormat" : "Money",
"EXT_SERV_CD":"ABC"
} ]
if DE35 is not available then the output should be
[ {
"COR_ID" : "12345",
"payloadFormat" : "Money",
"EXT_SERV_CD":"PQR"
} ]
I am using Below JOLT spec to do Transformation but it is not working.
[
{
"operation": "shift",
"spec": {
"*": {
"#": "&",
"payload": {
"DE|DE35": "&2.payload.TMPDE35"
}
}
}
}, {
"operation": "modify-default-beta",
"spec": {
"*": {
"payload": {
"DE35Val": "=substring(#(1,TMPDE35), 6, 9)"
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"#": "&",
"payload": {
"DE|DE45": "&2.payload.TMPDE45"
}
}
}
}, {
"operation": "modify-default-beta",
"spec": {
"*": {
"payload": {
"DE45Val": "=substring(#(1,TMPDE45), 6, 9)"
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"correlationId": "[&1].COR_ID",
"payloadFormat": "[&1].payloadFormat",
"payload": {
"DE35Val": {
"ABC": {
"DE35Val": "[#3].payload.EXT_SERV_CD"
},
"false": {
"DE45Val": "[#3].payload.EXT_SERV_CD"
}
}
}
}
}
}
]
Please suggest where I am making mistake.
This spec should work for you
[
{
"operation": "modify-default-beta",
"spec": {
"*": {
"TmpDE35": "=substring(#(1,payload.DE35), 6, 9)",
"TmpDE45": "=substring(#(1,payload.DE45), 6, 9)"
}
}
},
{
"operation": "modify-default-beta",
"spec": {
"*": {
"Tmp35_45": "=concat(#(1,TmpDE35), #(1,TmpDE45))"
}
}
},
{
"operation": "modify-default-beta",
"spec": {
"*": {
"EXT_SERV_CD": "=substring(#(1,Tmp35_45), 0, 3)"
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"*": "[&1].&",
"Tmp*": null,
"payload": null
}
}
}
]
The solution idea:
Move the substrings of the DE35, DE45 fields to the TmpDE35, TmpDE45
Concatenate TmpDE35, TMPDE45 and store it in the Tmp35_45. If TmpE35 is empty then the first 3 characters will come from TmpDE45
Get the substring Tmp35_45
Clean up, shift

Struggling with JOLT concat

I'm struggling with transformation using JOLT.
Input:
{
"records": [
{"counters": "Item1 Item2 Item3 Item4 Item5 Item6",
"values": "V1 V2 V3 V4 V5 V6"},
{"counters": "Item7 Item8 Item9 Item10 Item11",
"values": "V7 V8 V9 V10 V11"},
{"counters": "Item12 Item13",
"values": "V12 V13"},
{"counters": "Item14",
"values": "V14"}
]
}
Desired output:
{
"xItem1" : "V1",
"xItem2" : "V2",
"xItem3" : "V3",
"xItem4" : "V4",
"xItem5" : "V5",
"xItem6" : "V6",
"xItem7" : "V7",
"xItem8" : "V8",
"xItem9" : "V9",
"xItem10" : "V10",
"xItem11" : "V11",
"xItem12" : "V12",
"xItem13" : "V13",
"xItem14" : "V14"
}
I've almost managed it using this jolt (by replacing toUpper step with the one adding desired "x"):
[
{
"operation": "modify-overwrite-beta",
"spec": {
"records": {
"*": {
"counters": "=split(' ',#(1,counters))",
"values": "=split(' ',#(1,values))"
}
}
}
},
{
"operation": "shift",
"spec": {
"records": {
"*": {
"counters": { "*": "counters[]" },
"values": { "*": "values[]" }
}
}
}
},
{ // ...concat() must instead of toUpper...
"operation": "modify-overwrite-beta",
"spec": {
"counters": {
"*": "=toUpper"
}
}
},
{
"operation": "shift",
"spec": {
"counters": {
"*": {
"*": {
"#(3,values[#2])": "&"
}
}
}
}
}
]
but can't get the last step done - trying all the options, but concat returns either "x" or ItemX, but not xItemX...
Thanks
Not sure if this is what you need, but you dont really need to use concat to add an x to the attributes name, just add x to the rule followed by the &:
[
{
"operation": "modify-overwrite-beta",
"spec": {
"records": {
"*": {
"counters": "=split(' ',#(1,counters))",
"values": "=split(' ',#(1,values))"
}
}
}
},
{
"operation": "shift",
"spec": {
"records": {
"*": {
"counters": { "*": "counters[]" },
"values": { "*": "values[]" }
}
}
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"counters": {
"*": "=toUpper"
}
}
},
{
"operation": "shift",
"spec": {
"counters": {
"*": {
"*": {
"#(3,values[#2])": "x&"
}
}
}
}
}
]