Skip to content

Commit

Permalink
Upgrade JSON schema validator
Browse files Browse the repository at this point in the history
This seems to have introduced better evaluation of `allOf` and `oneOf` references.

However, it does seem to introduce a bug which causes it not to consider properties in nested schemas more than 1 level deep when evaluating `unevaluatedProperties`: networknt/json-schema-validator#1123

Therefore, a hack was introduced to make sure validation succeeds.. Note that not all concrete types are currently evaluated (#404), so there are many other schemas which would also fail if they were to be evaluated, and they would need to apply a similar fix.
  • Loading branch information
Whathecode committed Oct 28, 2024
1 parent 60197c6 commit 0eadde6
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 7 deletions.
2 changes: 1 addition & 1 deletion rpc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ dependencies {
implementation "org.reflections:reflections:${versions.reflections}"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:${versions.serialization}"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${versions.coroutines}"
implementation "com.networknt:json-schema-validator:1.0.67"
implementation "com.networknt:json-schema-validator:1.5.2"
implementation "commons-io:commons-io:${versions.apacheCommons}"

def generateForProjects = coreModules + commonModule
Expand Down
6 changes: 5 additions & 1 deletion rpc/schemas/common/devices/PrimaryDeviceConfiguration.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@
}
],
"$defs": {
"HACK-SEE-ISSUE-492": true,
"PrimaryDeviceConfiguration": {
"$anchor": "PrimaryDeviceConfiguration",
"allOf": [ { "$ref": "DeviceConfiguration.json#DeviceConfiguration" } ],
"properties": {
"isPrimaryDevice": { "const": true }
"isPrimaryDevice": { "const": true },

"roleName": { "$ref": "#/$defs/HACK-SEE-ISSUE-492" },
"defaultSamplingConfiguration": { "$ref": "#/$defs/HACK-SEE-ISSUE-492" }
},
"required": [ "isPrimaryDevice" ]
}
Expand Down
6 changes: 5 additions & 1 deletion rpc/schemas/studies/users/ParticipantGroupStatus.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
{ "$ref": "#/$defs/Stopped" }
],
"$defs": {
"HACK-SEE-ISSUE-492": true,
"ParticipantGroupStatus": {
"type": "object",
"properties": {
Expand All @@ -23,7 +24,10 @@
"allOf": [ { "$ref": "#/$defs/ParticipantGroupStatus" } ],
"properties": {
"invitedOn": { "type": "string", "format": "date-time" },
"studyDeploymentStatus": { "$ref": "../../deployments/StudyDeploymentStatus.json" }
"studyDeploymentStatus": { "$ref": "../../deployments/StudyDeploymentStatus.json" },

"id": { "$ref": "#/$defs/HACK-SEE-ISSUE-492" },
"participants": { "$ref": "#/$defs/HACK-SEE-ISSUE-492" }
},
"required": [ "invitedOn", "studyDeploymentStatus" ]
},
Expand Down
8 changes: 4 additions & 4 deletions rpc/src/test/kotlin/dk/cachet/carp/rpc/JsonSchemasTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,20 @@ class JsonSchemasTest
val requestErrors = requestSchema.validate( requestJson )
check( requestErrors.isEmpty() )
{
"JSON schema \"${requestSchema.currentUri}\" " +
"JSON schema \"${requestSchema.schemaLocation}\" " +
"doesn't match generated JSON example of \"${r.requestObject.klass}\": $requestErrors"
}

// Validate response.
val requestObjectName = r.requestObject.klass.simpleName
val responseSchemaNode = requestSchema.getRefSchemaNode( "#/\$defs/$requestObjectName/Response" )
val responseSchema = schemaFactory.getSchema( requestSchema.currentUri, responseSchemaNode )
val responseSchema = schemaFactory.getSchema( requestSchema.schemaLocation, responseSchemaNode )
val responseJson = mapper.readTree( r.response.json )
val responseErrors = responseSchema.validate( responseJson )
check( responseErrors.isEmpty() )
{
"JSON schema response defined in \"${requestSchema.currentUri}\" for \"$requestObjectName\" " +
"doesn't match generated JSON example of \"${r.response.klass}\": $responseErrors"
"JSON schema response defined in \"${requestSchema.schemaLocation}\" for \"$requestObjectName\" " +
"doesn't match generated JSON example of \"${r.response.klass.simpleName}\": $responseErrors"
}
}
}
Expand Down

0 comments on commit 0eadde6

Please sign in to comment.