json to case classes extraction giving error - json

I have a json from which i have to populate the value to the scala case classes but it's giving error while I'm populating it.
I'm using lift json 3.3.0 for converting
Scala Case Classes
package sampling
case class JobJson(name:String,id:String,dataflowId:String,properties:Properties)
case class Properties(activities:List[Activity],activityGroup:List[ActivityGroup])
case class Activity(name:String,types:String,id:String,inputs:List[Inputs],outputs:List[Outputs],runtimeInfo:Map[String,Any],start:String,end:String)
case class Inputs(properties:InputProperties,sourceConnection:SourceConnection)
case class InputProperties(structure:List[Structure],translator:List[Translator])
case class Structure(index:Int,name:String,dataType:String)
case class Translator(index:Int,name:String,dataType:String)
case class SourceConnection(connectionType:String,fileName:String,linkedService:String,location:String,datasetId:String,datafileId:String)
case class Outputs(properties:OutputProperties,destConnection:DestConnection)
case class OutputProperties(structure:List[OutputStructure],translator:String)
case class OutputStructure(index:Int,name:String,dataType:String)
case class DestConnection(connectionType:String,fileName:String,linkedService:String,location:String,datasetId:String,datafileId:String)
case class ActivityGroup(name:String,id:String,properties:ActivityGroupProperty)
case class ActivityGroupProperty(activityList:List[ActivityList])
case class ActivityList(id:String,order:String)
Code Where getting populated
implicit val formats = net.liftweb.json.DefaultFormats;
val p= parse(json).extract[JobJson];
println(p);
JSON
{
"name": "new flow test 3",
"id": "2e456f79-b62d-44df-a809-18a2e0af9377",
"dataflowId": "2e456f79-b62d-44df-a809-18a2e0af9377",
"properties": {
"Activities": [
{
"name": "Time Series Anamoly Detection",
"types": "Robust Principal Component Analysis",
"id": "g0a1",
"inputs": [
{
"properties": {
"structure": [
{
"index": 1,
"name": "Survived",
"dataType": "integer"
},
{
"index": 2,
"name": "Pclass",
"dataType": "integer"
}
],
"translator": [
{
"index": 1,
"name": "Survived",
"dataType": "integer"
},
{
"index": 2,
"name": "Pclass",
"dataType": "integer"
}
]
},
"sourceConnection": {
"connectionType": "AzureBlob",
"fileName": "Titanic.csv",
"linkedService": "sasurl",
"location": "wasbs://DFC33643-64A3-4A15-B3C0-17AA97C37FFD#olympusstoragedev.blob.core.windows.net/F2E42EC7-635E-4522-8EB2-2270D7AB4387/F011ED33-FBF3-46FB-BB0B-A797734257FC/pqlzn.csv",
"datasetId": "F2E42EC7-635E-4522-8EB2-2270D7AB4387",
"datafileId": "F011ED33-FBF3-46FB-BB0B-A797734257FC"
}
}
],
"outputs": [
{
"properties": {
"structure": [
{
"index": 1,
"name": "Survived",
"dataType": "integer"
},
{
"index": 2,
"name": "Pclass",
"dataType": "integer"
}
],
"translator": null
},
"destConnection": {
"connectionType": "AzureBlob",
"fileName": "Titanic.csv",
"linkedService": "sasurl",
"location": "wasbs://DFC33643-64A3-4A15-B3C0-17AA97C37FFD#olympusstoragedev.blob.core.windows.net/F2E42EC7-635E-4522-8EB2-2270D7AB4387/F011ED33-FBF3-46FB-BB0B-A797734257FC/pqlzn.csv",
"datasetId": "F2E42EC7-635E-4522-8EB2-2270D7AB4387",
"datafileId": "F011ED33-FBF3-46FB-BB0B-A797734257FC"
}
}
],
"runtimeInfo": {
"metric": "Survived",
"defineOutput": "Exclude Anomaly",
"selectDateColumn": "Pclass"
},
"start": "st",
"end": "end"
},
{
"name": "Seetal Dataset",
"types": "output",
"id": "g0a2",
"inputs": [
{
"properties": {
"structure": [
{
"index": 1,
"name": "Survived",
"dataType": "integer"
},
{
"index": 2,
"name": "Pclass",
"dataType": "integer"
}
],
"translator": [
{
"index": 1,
"name": "Survived",
"dataType": "integer"
},
{
"index": 2,
"name": "Pclass",
"dataType": "integer"
}
]
},
"sourceConnection": {
"connectionType": "AzureBlob",
"fileName": "Titanic.csv",
"linkedService": "sasurl",
"location": "wasbs://DFC33643-64A3-4A15-B3C0-17AA97C37FFD#olympusstoragedev.blob.core.windows.net/F2E42EC7-635E-4522-8EB2-2270D7AB4387/F011ED33-FBF3-46FB-BB0B-A797734257FC/pqlzn.csv",
"datasetId": "F2E42EC7-635E-4522-8EB2-2270D7AB4387",
"datafileId": "F011ED33-FBF3-46FB-BB0B-A797734257FC"
}
}
],
"outputs": [
{
"properties": {
"structure": [
{
"index": 1,
"name": "Survived",
"dataType": "integer"
},
{
"index": 2,
"name": "Pclass",
"dataType": "integer"
}
],
"translator": null
},
"destConnection": {
"connectionType": "AzureBlob",
"fileName": "Titanic.csv",
"linkedService": "sasurl",
"location": "wasbs://DFC33643-64A3-4A15-B3C0-17AA97C37FFD#olympusstoragedev.blob.core.windows.net/F2E42EC7-635E-4522-8EB2-2270D7AB4387/F011ED33-FBF3-46FB-BB0B-A797734257FC/F011ED33-FBF3-46FB-BB0B-A797734257FC.csv",
"datasetId": "F2E42EC7-635E-4522-8EB2-2270D7AB4387",
"datafileId": "F011ED33-FBF3-46FB-BB0B-A797734257FC"
}
}
],
"runtimeInfo": {
},
"start": "st",
"end": "end"
}
],
"activityGroup": [
{
"name": "grp1",
"id": "g0",
"properties": {
"activityList": [
{
"id": "g0a0",
"order": "0"
},
{
"id": "g0a1",
"order": "1"
},
{
"id": "g0a2",
"order": "2"
}
]
}
}
]
}
}
Error
Exception in thread "main" net.liftweb.json.MappingException: No usable value for properties
No usable value for activities
No usable value for types
Did not find value which can be converted into java.lang.String
at net.liftweb.json.Meta$.fail(Meta.scala:227)
at net.liftweb.json.Extraction$.mkValue$1(Extraction.scala:438)
at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:385)
at net.liftweb.json.Extraction$$anonfun$15.apply(Extraction.scala:260)
at net.liftweb.json.Extraction$$anonfun$15.apply(Extraction.scala:260)
at scala.collection.immutable.List.map(List.scala:277)
at net.liftweb.json.Extraction$.instantiate$1(Extraction.scala:260)
at net.liftweb.json.Extraction$.newInstance$1(Extraction.scala:308)
at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:379)
at net.liftweb.json.Extraction$.extract0(Extraction.scala:444)
at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$extract0(Extraction.scala:206)
at net.liftweb.json.Extraction$.extract(Extraction.scala:43)
at net.liftweb.json.JsonAST$JValue.extract(JsonAST.scala:704)
at sampling.Main$.delayedEndpoint$sampling$Main$1(Main.scala:417)
at sampling.Main$delayedInit$body.apply(Main.scala:68)
at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App$$anonfun$main$1.apply(App.scala:76)
at scala.App$$anonfun$main$1.apply(App.scala:76)
at scala.collection.immutable.List.foreach(List.scala:381)
at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
at scala.App$class.main(App.scala:76)
at sampling.Main$.main(Main.scala:68)
at sampling.Main.main(Main.scala)
Caused by: net.liftweb.json.MappingException: No usable value for activities
No usable value for types
Did not find value which can be converted into java.lang.String
at net.liftweb.json.Meta$.fail(Meta.scala:227)
at net.liftweb.json.Extraction$.mkValue$1(Extraction.scala:438)
at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:385)
at net.liftweb.json.Extraction$$anonfun$15.apply(Extraction.scala:260)
at net.liftweb.json.Extraction$$anonfun$15.apply(Extraction.scala:260)
at scala.collection.immutable.List.map(List.scala:273)
at net.liftweb.json.Extraction$.instantiate$1(Extraction.scala:260)
at net.liftweb.json.Extraction$.newInstance$1(Extraction.scala:308)
at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:379)
at net.liftweb.json.Extraction$.mkValue$1(Extraction.scala:431)
... 22 more
Caused by: net.liftweb.json.MappingException: No usable value for types
Though i'm doint it correctly why I'm getting error. I have rechecked it many times

Related

extract collection from json based on a condition using logic app

I am trying to Extract and sum a particular value using group by from json collection in azure logic app. Trying to achieve this by applying "Condition" connector. My Json file looks like below:
"Release": [
{
"O_Id": "D_13211175",
"R_ID": "D_132111751",
"Res": [
{
"A_Id": "32323222",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 1,
"RL_Id": "1",
"Unique_Identifier": "5970703818904601622__1",
},
{
"A_Id": "32323223",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 1,
"RL_Id": "1",
"Unique_Identifier": "5970703818904692717__1",
},
]
}
]
I want to calculate the sum of Qty group by I_Id from array Res using logic app connector "Condition".
Note: As Res is an array, there can be repetition I_Id with same value, hence, the requirement to get the Qty count based on I_Id
There are few ways to achieve your requirement but here is one of the workaround that worked when reproduced from our end.
Firstly, I have initialised a temporary integer variable to iterated inside the "Res" Array using Until Loop by checking the length of "Res" using the below expression.
length(body('Parse_JSON')?['Release']?[0]?['Res'])
Inside Until I have used condition action to check if I_Id is same using the below expression to the left.
body('Parse_JSON')?['Release']?[0]?['Res']?[variables('temp')]?['I_Id']
and below expression to the right
body('Parse_JSON')?['Release']?[0]?['Res']?[add(variables('temp'),1)]?['I_Id']
Then if the condition satisfies I'm adding the Qty using the expression as below.
add(body('Parse_JSON')?['Release']?[0]?['Res']?[variables('temp')]?['Qty'],body('Parse_JSON')?['Release']?[0]?['Res']?[add(variables('temp'),1)]?['Qty'])
Here is the flow of my logic app
[Optional step]
Considering the bigger picture, I have initialzed another variable quantity and added the resultant of Compose 4 to Qty variable
RESULTS:
Considering the below sample JSON
{
"Release": [
{
"O_Id": "D_13211175",
"R_ID": "D_132111751",
"Res": [
{
"A_Id": "32323222",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 1,
"RL_Id": "1",
"Unique_Identifier": "5970703818904601622__1"
},
{
"A_Id": "32323223",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 1,
"RL_Id": "1",
"Unique_Identifier": "5970703818904692717__1"
},
{
"A_Id": "32323223",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 5,
"RL_Id": "1",
"Unique_Identifier": "5970703818904692717__1"
}
]
}
]
}
Here is the result
To avoid confusion try the below code view in your resource
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose": {
"inputs": {
"Release": [
{
"O_Id": "D_13211175",
"R_ID": "D_132111751",
"Res": [
{
"A_Id": "32323222",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 1,
"RL_Id": "1",
"Unique_Identifier": "5970703818904601622__1"
},
{
"A_Id": "32323223",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 1,
"RL_Id": "1",
"Unique_Identifier": "5970703818904692717__1"
},
{
"A_Id": "32323223",
"F_Qty": 1,
"I_Id": "828929",
"OL_Id": "1",
"Qty": 5,
"RL_Id": "1",
"Unique_Identifier": "5970703818904692717__1"
}
]
}
]
},
"runAfter": {},
"type": "Compose"
},
"Compose_3": {
"inputs": "#variables('Qty')",
"runAfter": {
"Until": [
"Succeeded"
]
},
"type": "Compose"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "temp",
"type": "integer",
"value": 0
}
]
},
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_2": {
"inputs": {
"variables": [
{
"name": "Qty",
"type": "integer",
"value": 0
}
]
},
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Parse_JSON": {
"inputs": {
"content": "#outputs('Compose')",
"schema": {
"properties": {
"Release": {
"items": {
"properties": {
"O_Id": {
"type": "string"
},
"R_ID": {
"type": "string"
},
"Res": {
"items": {
"properties": {
"A_Id": {
"type": "string"
},
"F_Qty": {
"type": "integer"
},
"I_Id": {
"type": "string"
},
"OL_Id": {
"type": "string"
},
"Qty": {
"type": "integer"
},
"RL_Id": {
"type": "string"
},
"Unique_Identifier": {
"type": "string"
}
},
"required": [
"A_Id",
"F_Qty",
"I_Id",
"OL_Id",
"Qty",
"RL_Id",
"Unique_Identifier"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"O_Id",
"R_ID",
"Res"
],
"type": "object"
},
"type": "array"
}
},
"type": "object"
}
},
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "ParseJson"
},
"Until": {
"actions": {
"Condition": {
"actions": {
"Compose_2": {
"inputs": "#add(outputs('Compose_4'),variables('Qty'))",
"runAfter": {
"Compose_4": [
"Succeeded"
]
},
"type": "Compose"
},
"Compose_4": {
"inputs": "#add(body('Parse_JSON')?['Release']?[0]?['Res']?[variables('temp')]?['Qty'],body('Parse_JSON')?['Release']?[0]?['Res']?[add(variables('temp'),1)]?['Qty'])",
"runAfter": {},
"type": "Compose"
},
"Set_variable": {
"inputs": {
"name": "Qty",
"value": "#outputs('Compose_2')"
},
"runAfter": {
"Compose_2": [
"Succeeded"
]
},
"type": "SetVariable"
}
},
"expression": {
"and": [
{
"equals": [
"#body('Parse_JSON')?['Release']?[0]?['Res']?[variables('temp')]?['I_Id']",
"#body('Parse_JSON')?['Release']?[0]?['Res']?[add(variables('temp'),1)]?['I_Id']"
]
}
]
},
"runAfter": {},
"type": "If"
},
"Increment_variable": {
"inputs": {
"name": "temp",
"value": 1
},
"runAfter": {
"Condition": [
"Succeeded"
]
},
"type": "IncrementVariable"
}
},
"expression": "#equals(variables('temp'), length(body('Parse_JSON')?['Release']?[0]?['Res']))",
"limit": {
"count": 60,
"timeout": "PT1H"
},
"runAfter": {
"Initialize_variable_2": [
"Succeeded"
]
},
"type": "Until"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}

Removing entire object from JSON file based on key value pair

I been struggling removing set-off objects from Json file. I tried with jq json parser method but nothing has worked out. Could someone please help on this.
What am looking for is – Wherever the below key and value pair are present in a file, the entire object should be removed.
{"name": "exception"}
Input:
{
"results": [
{
"id": "a21f5193-881e-11eb-a0c1-3726f4a71fa9",
"retailerId": "1",
"category": "exception",
"context": {
"sourceEvents": [
"902bd449-881e-11eb-b603-29eb6c297e7d"
],
"entityType": "ORDER"
},
"eventStatus": "FAILED",
"attributes": [
{
"name": "exception",
"value": {
"code": 400,
"message": "Failed to execute http call",
"stackTrace": [
{
"fileName": "ReadOnlyFluentApiClient.java",
"className": "com.fluentretail.api.v2.client.ReadOnlyFluentApiClient"
}
],
"suppressed": [],
"suppressedExceptions": []
},
"type": "OBJECT"
},
{
"name": "lastRule",
"value": "ETOSUAT.base.ProposedFulfilmentWithoutInventory",
"type": "String"
},
{
"name": "lastRuleSet",
"value": "FindAndCreateDigitalFulfilment",
"type": "String"
},
{
"name": "message",
"value": "Failed to execute http call",
"type": "String"
}
],
"source": null,
"generatedBy": "Rubix User",
"generatedOn": "2021-03-18T19:17:51.517+0000"
},
{
"id": "a21f5193-881e-11eb-a0c1-3726f4a71fa9",
"retailerId": "1",
"category": "exception",
"context": {
"sourceEvents": [
"902bd449-881e-11eb-b603-29eb6c297e7d"
],
"entityType": "ORDER"
},
"eventStatus": "FAILED",
"attributes": [
{
"name": "exception",
"value": {
"code": 400,
"message": "Failed to execute http call",
"stackTrace": [
{
"fileName": "ReadOnlyFluentApiClient.java",
"className": "com.fluentretail.api.v2.client.ReadOnlyFluentApiClient"
}
],
"suppressed": [],
"suppressedExceptions": []
},
"type": "OBJECT"
},
{
"name": "lastRule",
"value": "ETOSUAT.base.ProposedFulfilmentWithoutInventory",
"type": "String"
},
{
"name": "lastRuleSet",
"value": "FindAndCreateDigitalFulfilment",
"type": "String"
},
{
"name": "message",
"value": "Failed to execute http call",
"type": "String"
}
],
"source": null,
"generatedBy": "Rubix User",
"generatedOn": "2021-03-18T19:17:51.517+0000"
}
]
}
Expected output is -
{
"results": [
{
"id": "a21f5193-881e-11eb-a0c1-3726f4a71fa9",
"retailerId": "1",
"category": "exception",
"context": {
"sourceEvents": [
"902bd449-881e-11eb-b603-29eb6c297e7d"
],
"entityType": "ORDER"
},
"eventStatus": "FAILED",
"attributes": [
{
"name": "lastRule",
"value": "ETOSUAT.base.ProposedFulfilmentWithoutInventory",
"type": "String"
},
{
"name": "lastRuleSet",
"value": "FindAndCreateDigitalFulfilment",
"type": "String"
},
{
"name": "message",
"value": "Failed to execute http call",
"type": "String"
}
],
"source": null,
"generatedBy": "Rubix User",
"generatedOn": "2021-03-18T19:17:51.517+0000"
},
{
"id": "a21f5193-881e-11eb-a0c1-3726f4a71fa9",
"retailerId": "1",
"category": "exception",
"context": {
"sourceEvents": [
"902bd449-881e-11eb-b603-29eb6c297e7d"
],
"entityType": "ORDER"
},
"eventStatus": "FAILED",
"attributes": [
{
"name": "lastRule",
"value": "ETOSUAT.base.ProposedFulfilmentWithoutInventory",
"type": "String"
},
{
"name": "lastRuleSet",
"value": "FindAndCreateDigitalFulfilment",
"type": "String"
},
{
"name": "message",
"value": "Failed to execute http call",
"type": "String"
}
],
"source": null,
"generatedBy": "Rubix User",
"generatedOn": "2021-03-18T19:17:51.517+0000"
}
]
}
del(..|select(type=="object" and .name=="exception"))
Try it at https://jqplay.org/s/il12Ribpdb
walk(if type=="object" and .name == "exception"
then empty else . end)
Equivalently:
walk(select(type=="object" and .name == "exception" | not))

JSON Schema with Nested Objects with different properties

The entire JSON file is rather large so I've only taken out the subsection I've had an issue with.
{
"diagrams": {
"5f759d15cd046720c28531dd": {
"_id": "5f759d15cd046720c28531dd",
"offsetX": 320,
"offsetY": 42,
"zoom": 80,
"modified": 1604279356,
"nodes": {
"5f9f5c3ccd046720c28531e4": {
"nodeID": "5f9f5c3ccd046720c28531e4",
"type": "start",
"coords": [
360,
120
],
"data": {
"name": "Start",
"color": "standard",
"ports": [
{
"type": "",
"target": "5f9f5c3ccd046720c28531e6"
}
],
"steps": []
}
},
"5f9f5c3ccd046720c28531e5": {
"nodeID": "5f9f5c3ccd046720c28531e5",
"type": "block",
"coords": [
760,
120
],
"data": {
"name": "Help Message",
"color": "standard",
"steps": [
"5f9f5c3ccd046720c28531e6",
"5f9f5c3ccd046720c28531e7"
]
}
},
"5f9f5c3ccd046720c28531e6": {
"nodeID": "5f9f5c3ccd046720c28531e6",
"type": "speak",
"data": {
"randomize": false,
"dialogs": [
{
"voice": "Alexa",
"content": "You said help. Do you want to continue?"
}
],
"ports": [
{
"type": "",
"target": "5f9f5c3ccd046720c28531e7"
}
]
}
},
"5f9f5c3ccd046720c28531e7": {
"nodeID": "5f9f5c3ccd046720c28531e7",
"type": "interaction",
"data": {
"name": "Choice",
"else": {
"type": "path",
"randomize": false,
"reprompts": []
},
"choices": [
{
"intent": "",
"mappings": []
},
{
"intent": "",
"mappings": []
}
],
"reprompt": null,
"ports": [
{
"type": "else",
"target": null
},
{
"type": "",
"target": null
},
{
"type": "",
"target": "5f9f5c3ccd046720c28531e9"
}
]
}
},
"5f9f5c3ccd046720c28531e8": {
"nodeID": "5f9f5c3ccd046720c28531e8",
"type": "block",
"coords": [
1170,
260
],
"data": {
"name": "Exit",
"color": "standard",
"steps": [
"5f9f5c3ccd046720c28531e9"
]
}
},
"5f9f5c3ccd046720c28531e9": {
"nodeID": "5f9f5c3ccd046720c28531e9",
"type": "exit",
"data": {
"ports": []
}
}
},
"children": [],
"creatorID": 42661,
"variables": [],
"name": "Help Flow",
"versionID": "5f759d15cd046720c28531db"
}
}
}
The Current JSON Schema Definition I have is:
{
"$schema":"http://json-schema.org/schema#",
"type":"object",
"properties":{
"diagrams":{
"type":"object"
}
},
"required":[
"diagrams",
]
}
The problem I am having is that within diagrams contains multiple objects with a random string as the name e.g "5f759d15cd046720c28531dd".
Then within that object there are properties such as (_id, offsetX) which I want to express as well as a nodes object, which again contains multiple objects with arbitrary names e.g ("5f9f5c3ccd046720c28531e4", "5f9f5c3ccd046720c28531e5", ...) which have a unique node definition where some nodes have different properties to other nodes (nodeID, type, data vs nodeID, type, data, coords).
My question is with all these arbitrary things such as random names as well as different properties per each node. How do I turn it into 1 JSON schema definition which covers all the cases of how a diagram/node can be made.
You can do this with additionalProperties or patternProperties.
additionalProperties applies to any property that isn't declared in properties or patternProperties.
{
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"_id": { ... },
"offsetX": { ... },
...
}
}
}
Your property names appear to always be hex numbers. If you want to enforce that those property names are always hex numbers, you can use patternProperties. Any property that matches the regex must conform to that schema.
{
"type": "object",
"patternProperties": {
"^[0-9a-f]{24}$": {
"type": "object",
"properties": {
"_id": { ... },
"offsetX": { ... },
...
}
}
},
"additionalProperties": false
}

Parse JSON with map of list

I am new to scala and JSON parsing and need some help. I need to parse the complex JSON (below) to get the values of "name" in "dimension" key i.e I need PLATFORM and OS_VERSION.
I tried multiple options, but it is not working. Any help is appreciated
This is a snippet of the code I tried, but I am not able to proceed further in parsing the list. I believe the 'ANY' keyword is causing some mismatch / issues.
import org.json4s._
import org.json4s.jackson.JsonMethods._
implicit val formats = org.json4s.DefaultFormats
val mapJSON = parse(tmp).extract[Map[String, Any]]
println(mapJSON)
//for ((k,v) <- mapJSON) printf("key: %s, value: %s\n", k, v)
val list_map = mapJSON("dimensions")
{
"uuid": "uuidddd",
"last_modified": 1559080222953,
"version": "2.6.1.0",
"name": "FULL_DAY_2_mand_date",
"is_draft": false,
"model_name": "FULL_DAY_1_may05",
"description": "",
"null_string": null,
"dimensions": [
{
"name": "PLATFORM",
"table": "tbl1",
"column": "PLATFORM",
"derived": null
},
{
"name": "OS_VERSION",
"table": "tbl1",
"column": "OS_VERSION",
"derived": null
},
],
"measures": [
{
"name": "_COUNT_",
"function": {
"expression": "COUNT",
"parameter": {
"type": "constant",
"value": "1"
},
"returntype": "bigint"
}
},
{
"name": "UU",
"function": {
"expression": "COUNT_DISTINCT",
"parameter": {
"type": "column",
"value": "tbl1.USER_ID"
},
"returntype": "hllc(12)"
}
},
{
"name": "CONT_SIZE",
"function": {
"expression": "SUM",
"parameter": {
"type": "column",
"value": "tbl1.SIZE"
},
"returntype": "bigint"
}
},
{
"name": "CONT_COUNT",
"function": {
"expression": "SUM",
"parameter": {
"type": "column",
"value": "tbl1.COUNT"
},
"returntype": "bigint"
}
}
],
"dictionaries": [],
"rowkey": {
"rowkey_columns": [
{
"column": "tbl1.OS_VERSION",
"encoding": "dict",
"encoding_version": 1,
"isShardBy": false
},
{
"column": "tbl1.PLATFORM",
"encoding": "dict",
"encoding_version": 1,
"isShardBy": false
},
{
"column": "tbl1.DEVICE_FAMILY",
"encoding": "dict",
"encoding_version": 1,
"isShardBy": false
}
]
},
"hbase_mapping": {
"column_family": [
{
"name": "F1",
"columns": [
{
"qualifier": "M",
"measure_refs": [
"_COUNT_",
"CONT_SIZE",
"CONT_COUNT"
]
}
]
},
{
"name": "F2",
"columns": [
{
"qualifier": "M",
"measure_refs": [
"UU"
]
}
]
}
]
},
"aggregation_groups": [
{
"includes": [
"tbl1.PLATFORM",
"tbl1.OS_VERSION"
],
"select_rule": {
"hierarchy_dims": [],
"mandatory_dims": [
"tbl1.DATE_HR"
],
"joint_dims": []
}
}
],
"signature": "ttrrs==",
"notify_list": [],
"status_need_notify": [
"ERROR",
"DISCARDED",
"SUCCEED"
],
"partition_date_start": 0,
"partition_date_end": 3153600000000,
"auto_merge_time_ranges": [
604800000,
2419200000
],
"volatile_range": 0,
"retention_range": 0,
"engine_type": 4,
"storage_type": 2,
"override_kylin_properties": {
"job.queuename": "root.production.P0",
"is-mandatory-only-valid": "true"
},
"cuboid_black_list": [],
"parent_forward": 3,
"mandatory_dimension_set_list": [],
"snapshot_table_desc_list": []
}
You need to make more specific classes for parsing the data, something like this:
case class Dimension(name: String, table: String, column: String)
case class AllData(uuid: String, dimensions: List[Dimension])
val data = parse(tmp).extract[AllData]
val names = data.dimensions.map(_.name)

JSON Schema validation is not working

I have a json response like below. In the views array may or may not contain actions array.
In the reponse If any of view array contains actions object , then i have to validate that actions data with json schema(schema1.json)
And in the schema i mentioned the action propertes like(type,label,localizedlabel) as required ones.
But when I modify key or value type of this type,label,localizedlabel in the response does not output any errors.
Tested via( https://www.jsonschemavalidator.net/). what wrong with my schema?
How can i validate actions object only whenever it present inside any of view array?
schema1.json
{
"$id": "",
"type": "array",
"items": {
"$id": "/items",
"type": "object",
"properties": {
"name": {
"$id": "/items/properties/name",
"type": "string",
"title": "The Name Schema ",
"default": "",
"examples": [
"Preview"
]
},
"displayOrder": {
"$id": "/items/properties/displayOrder",
"type": "integer",
"title": "The Displayorder Schema ",
"default": 0,
"examples": [
1
]
},
"actions": {
"$id": "/items/properties/actions",
"type": "array",
"items": {
"$id": "/items/properties/actions/items",
"type": "object",
"properties": {
"type": {
"$id": "/items/properties/actions/items/properties/type",
"type": "string",
"title": "The Type Schema ",
"default": "",
"examples": [
"watch"
]
},
"label": {
"$id": "/items/properties/actions/items/properties/label",
"type": "string",
"title": "The Label Schema ",
"default": "",
"examples": [
"Watch"
]
},
"localizedLabel": {
"$id": "/items/properties/actions/items/properties/localizedLabel",
"type": "object",
"properties": {
"ENG": {
"$id": "/items/properties/actions/items/properties/localizedLabel/properties/ENG",
"type": "string",
"title": "The Eng Schema ",
"default": "",
"examples": [
"Watch"
]
},
"ESP": {
"$id": "/items/properties/actions/items/properties/localizedLabel/properties/ESP",
"type": "string",
"title": "The Esp Schema ",
"default": "",
"examples": [
"Ver"
]
}
}
}
},
"required": [
"type",
"label",
"localizedLabel"
]
}
},
"localizedName": {
"$id": "/items/properties/localizedName",
"type": "object",
"properties": {
"ENG": {
"$id": "/items/properties/localizedName/properties/ENG",
"type": "string",
"title": "The Eng Schema ",
"default": "",
"examples": [
"Preview"
]
},
"ESP": {
"$id": "/items/properties/localizedName/properties/ESP",
"type": "string",
"title": "The Esp Schema ",
"default": "",
"examples": [
"Adelanto"
]
}
}
}
},
"required": [
"actions"
]
}
}
response json
[{
"season": 2017,
"teamData": {
"awayTeam": {
"id": 6,
"city": "Dallas",
"name": "Mavericks",
"abbr": "DAL",
"color": "#0B51A1"
},
"homeTeam": {
"id": 8,
"city": "Detroit",
"name": "Pistons",
"abbr": "DET",
"color": "#990300"
}
},
"views": [{
"name": "Preview",
"displayOrder": 1,
"groups": [{
"type": "static",
"displayOrder": 1,
"tiles": [{
"context": "event",
"collection": "event",
"auditType": "pregame-preview",
"displayOrder": 1,
"_id": "5ac58ea21ee2112b33291f1c",
"eventId": 2018040608,
"dimensions": {
"width": 372,
"height": 375
},
"tileId": "36b154e719d7d8397da487cbc4e5f7d1",
"renderTime": "2018-04-05T02:49:05+00:00",
"dataTime": "2018-04-05T02:48:58+00:00",
"dataStamp": 1522896538,
"location": "http://test.com/2018040608/static/pre-event/pregame-preview/1522896538.png",
"tile_type": "static"
}
]
}
],
"actions": [{
"type": "watch",
"label": "Watch",
"localizedLabel": {
"ENG": "Watch",
"ESP": "Ver"
}
}, {
"type": "record",
"label": "Record",
"localizedLabel": {
"ENG": "Record",
"ESP": "Grabar"
}
}, {
"type": "tile_overlay",
"label": "Current Standings",
"tili": {
"context": "event",
"collection": "event",
"auditType": "full-standings",
"_id": "5ac6f9de2ccaf768d092c918",
"eventId": 2018040608,
"dimensions": {
"width": 1140,
"height": 660
},
"tileId": "852f92537e68dc99b54f1228459ec9ef",
"renderTime": "2018-04-06T04:38:54+00:00",
"dataTime": "2018-04-06T04:38:52+00:00",
"dataStamp": 1522989532,
"location": "http://test.com/2018040608/static/pre-event/full-standings/1522989532.png"
},
"localizedLabel": {
"ENG": "Current Standings",
"ESP": "Posición actual"
}
}, {
"type": "favorite",
"label": "Favorite",
"localizedLabel": {
"ENG": "Favorite",
"ESP": "Favorito"
}
}
],
"localizedName": {
"ENG": "Preview",
"ESP": "Adelanto"
}
}, {
"name": "Team Stats",
"displayOrder": 2,
"groups": [{
"type": "static",
"displayOrder": 1,
"tiles": [{
"context": "event",
"collection": "event",
"auditType": "pregame-team_stats",
"displayOrder": 1,
"_id": "5ac6755a4f82eb58a5eae6a6",
"eventId": 2018040608,
"dimensions": {
"width": 372,
"height": 510
},
"tileId": "1302dc16c9fe68c3e6edadd98afce2bc",
"renderTime": "2018-04-05T19:13:30+00:00",
"dataTime": "2018-04-05T19:13:28+00:00",
"dataStamp": 1522955608,
"location": "http://test.com/2018040608/static/pre-event/pregame-team_stats/1522955608.png",
"tile_type": "static"
}
]
}
],
"localizedName": {
"ENG": "Team Stats",
"ESP": "Estadísticas del equipo"
}
}, {
"name": "Leaders",
"displayOrder": 3,
"groups": [{
"type": "static",
"displayOrder": 1,
"tiles": [{
"context": "event",
"collection": "event",
"auditType": "pregame-leaders",
"displayOrder": 1,
"_id": "5ac26eb31ee2112b3328b00c",
"eventId": 2018040608,
"dimensions": {
"width": 372,
"height": 510
},
"tileId": "96abc24c47d61327426ef2b24281acbf",
"renderTime": "2018-04-02T17:55:57+00:00",
"dataTime": "2018-04-02T17:55:54+00:00",
"dataStamp": 1522691754,
"location": "http://test.com/2018040608/static/pre-event/pregame-leaders/1522691754.png",
"tile_type": "static"
}
]
}
],
"localizedName": {
"ENG": "Leaders",
"ESP": "Líderes"
}
}
]
}
]
There's nothing wrong with your schema. It should do what you need if used properly. Because it only describes the "views" part of the schema you would need to iterate through your response and pass just the "views" part of each item to the validator one at a time.
Or, you could add enough of the response structure to the schema to validate everything at once. Then you could just pass your whole response to the validator.
{
"type": "array",
"items": {
"type": "object",
"properties": {
"views": { "$ref": "schema1.json" }
}
}
}