使用 jsonschema 验证值组合
Validating value combinations with jsonschema
我正在使用 jsonschema 来验证配置文件。
目前我 运行 无法验证嵌套属性的值组合。
我最初实现了 if/then/else,但在几次通过后没有看到预期的行为。
对开关、依赖项和最后使用蕴涵也进行了同样的操作。
这是我的架构:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"account_group": {
"type": "string"
},
"region": {
"type": "string",
"pattern": "^(us(-gov)?|ap|ca|cn|eu|sa)-(central|(north|south)?(east|west)?)-\d$"
},
"appid": {
"type": "string"
},
"services": {
"type": "object",
"minProperties": 1,
"patternProperties": {
"^[A-Za-z_]*$": {
"type": "object",
"properties": {
"source": {
"type": "string"
},
"port": {
"type": "number"
},
"cpu": {
"type": "number",
"enum": [256, 512, 1024, 2048, 4096]
},
"memory": {
"type": "number",
"enum": [0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30]
}
},
"required": [
"source",
"port",
"cpu",
"memory"
],
}
},
"additionalProperties": false
},
"stages": {
"type": "object",
"minProperties": 1
},
"workingDirectory": {
"type": "string"
}
},
"required": [
"name",
"account_group",
"appid",
"services"
]
}
注意:我删除了最新的 allOf 块以避免出现我已经测试过的损坏代码
我要完成的是验证正在解析的配置文件中 cpu/memory 值的正确组合并与模式进行比较。
组合是:
256/[0.5, 1, 2]
512/[1-4]
1024/[2-8]
2048/[2-16]
4096/[2-30]
有人可以建议适当的架构设计来验证这些组合吗?
本质上,如果 cpu 为 256,并且内存值不是 0.5、1、2,我需要验证失败 - 如果 cpu 为 512,并且内存值是任何值,则验证失败但是 1 - 4 等等
我已经得到了最接近的 using implication,但是我已经看到许多使用依赖关系的组合,这对我来说进一步混淆了水域。我个人认为 if/then/else 是最合乎逻辑的方法,但它没有产生预期的行为。
if
/then
是最好的选择。蕴涵模式也有效,但 if
/then
更好用。一般策略是为每个条件创建一个定义,然后使用 allOf
将它们组合起来。您当然可以将条件内联而不是使用 definitions
,但这种方式读起来更好,使维护更容易。我做了前两个来说明。您可以从那里推断。
{
"type": "object",
"properties": {
"source": { "type": "string" },
"port": { "type": "number" },
"cpu": { "enum": [256, 512, 1024, 2048, 4096] },
"memory": { "enum": [0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30] }
},
"required": ["source", "port", "cpu", "memory"],
"allOf": [
{ "$ref": "#/definitions/if-cpu-256-then-memory-0.5-1-2" },
{ "$ref": "#/definitions/if-cpu-512-then-memory-1-4" }
],
"definitions": {
"if-cpu-256-then-memory-0.5-1-2": {
"if": {
"properties": {
"cpu": { "const": 256 }
},
"required": ["cpu"]
},
"then": {
"properties": {
"memory": { "enum": [0.5, 1, 2] }
}
}
},
"if-cpu-512-then-memory-1-4": {
"if": {
"properties": {
"cpu": { "const": 512 }
},
"required": ["cpu"]
},
"then": {
"properties": {
"memory": { "minimum": 1, "maximum": 4 }
}
}
}
}
}
我正在使用 jsonschema 来验证配置文件。 目前我 运行 无法验证嵌套属性的值组合。
我最初实现了 if/then/else,但在几次通过后没有看到预期的行为。 对开关、依赖项和最后使用蕴涵也进行了同样的操作。
这是我的架构:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"account_group": {
"type": "string"
},
"region": {
"type": "string",
"pattern": "^(us(-gov)?|ap|ca|cn|eu|sa)-(central|(north|south)?(east|west)?)-\d$"
},
"appid": {
"type": "string"
},
"services": {
"type": "object",
"minProperties": 1,
"patternProperties": {
"^[A-Za-z_]*$": {
"type": "object",
"properties": {
"source": {
"type": "string"
},
"port": {
"type": "number"
},
"cpu": {
"type": "number",
"enum": [256, 512, 1024, 2048, 4096]
},
"memory": {
"type": "number",
"enum": [0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30]
}
},
"required": [
"source",
"port",
"cpu",
"memory"
],
}
},
"additionalProperties": false
},
"stages": {
"type": "object",
"minProperties": 1
},
"workingDirectory": {
"type": "string"
}
},
"required": [
"name",
"account_group",
"appid",
"services"
]
}
注意:我删除了最新的 allOf 块以避免出现我已经测试过的损坏代码
我要完成的是验证正在解析的配置文件中 cpu/memory 值的正确组合并与模式进行比较。
组合是:
256/[0.5, 1, 2]
512/[1-4]
1024/[2-8]
2048/[2-16]
4096/[2-30]
有人可以建议适当的架构设计来验证这些组合吗?
本质上,如果 cpu 为 256,并且内存值不是 0.5、1、2,我需要验证失败 - 如果 cpu 为 512,并且内存值是任何值,则验证失败但是 1 - 4 等等
我已经得到了最接近的 using implication,但是我已经看到许多使用依赖关系的组合,这对我来说进一步混淆了水域。我个人认为 if/then/else 是最合乎逻辑的方法,但它没有产生预期的行为。
if
/then
是最好的选择。蕴涵模式也有效,但 if
/then
更好用。一般策略是为每个条件创建一个定义,然后使用 allOf
将它们组合起来。您当然可以将条件内联而不是使用 definitions
,但这种方式读起来更好,使维护更容易。我做了前两个来说明。您可以从那里推断。
{
"type": "object",
"properties": {
"source": { "type": "string" },
"port": { "type": "number" },
"cpu": { "enum": [256, 512, 1024, 2048, 4096] },
"memory": { "enum": [0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30] }
},
"required": ["source", "port", "cpu", "memory"],
"allOf": [
{ "$ref": "#/definitions/if-cpu-256-then-memory-0.5-1-2" },
{ "$ref": "#/definitions/if-cpu-512-then-memory-1-4" }
],
"definitions": {
"if-cpu-256-then-memory-0.5-1-2": {
"if": {
"properties": {
"cpu": { "const": 256 }
},
"required": ["cpu"]
},
"then": {
"properties": {
"memory": { "enum": [0.5, 1, 2] }
}
}
},
"if-cpu-512-then-memory-1-4": {
"if": {
"properties": {
"cpu": { "const": 512 }
},
"required": ["cpu"]
},
"then": {
"properties": {
"memory": { "minimum": 1, "maximum": 4 }
}
}
}
}
}