rsmp_schema 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/rsmp_schema/convert/export/json_schema.rb +96 -54
- data/lib/rsmp_schema/schema.rb +80 -24
- data/lib/rsmp_schema/version.rb +1 -1
- data/lib/rsmp_schema.rb +2 -0
- data/schemas/tlc/1.0.10/sxl.yaml +20 -65
- data/schemas/tlc/1.0.13/sxl.yaml +20 -80
- data/schemas/tlc/1.0.14/sxl.yaml +20 -80
- data/schemas/tlc/1.0.15/sxl.yaml +20 -87
- data/schemas/tlc/1.0.7/sxl.yaml +20 -61
- data/schemas/tlc/1.0.8/sxl.yaml +20 -65
- data/schemas/tlc/1.0.9/sxl.yaml +20 -65
- data/schemas/tlc/1.1/alarms/A0303.json +111 -0
- data/schemas/tlc/1.1/alarms/A0304.json +137 -0
- data/schemas/tlc/1.1/alarms/alarms.json +33 -1
- data/schemas/tlc/1.1/commands/M0001.json +2 -2
- data/schemas/tlc/1.1/commands/M0005.json +1 -1
- data/schemas/tlc/1.1/commands/M0013.json +1 -1
- data/schemas/tlc/1.1/commands/M0019.json +1 -1
- data/schemas/tlc/1.1/commands/M0022.json +335 -0
- data/schemas/tlc/1.1/commands/M0023.json +64 -0
- data/schemas/tlc/1.1/commands/commands.json +32 -0
- data/schemas/tlc/1.1/statuses/S0001.json +3 -3
- data/schemas/tlc/1.1/statuses/S0002.json +1 -1
- data/schemas/tlc/1.1/statuses/S0003.json +1 -1
- data/schemas/tlc/1.1/statuses/S0004.json +1 -1
- data/schemas/tlc/1.1/statuses/S0007.json +1 -1
- data/schemas/tlc/1.1/statuses/S0008.json +1 -1
- data/schemas/tlc/1.1/statuses/S0009.json +1 -1
- data/schemas/tlc/1.1/statuses/S0010.json +1 -1
- data/schemas/tlc/1.1/statuses/S0011.json +1 -1
- data/schemas/tlc/1.1/statuses/S0012.json +1 -1
- data/schemas/tlc/1.1/statuses/S0013.json +2 -2
- data/schemas/tlc/1.1/statuses/S0020.json +1 -1
- data/schemas/tlc/1.1/statuses/S0032.json +96 -0
- data/schemas/tlc/1.1/statuses/S0033.json +93 -0
- data/schemas/tlc/1.1/statuses/S0034.json +40 -0
- data/schemas/tlc/1.1/statuses/S0205.json +8 -2
- data/schemas/tlc/1.1/statuses/S0206.json +8 -2
- data/schemas/tlc/1.1/statuses/S0207.json +8 -2
- data/schemas/tlc/1.1/statuses/S0208.json +72 -18
- data/schemas/tlc/1.1/statuses/statuses.json +48 -0
- data/schemas/tlc/1.1/sxl.yaml +596 -241
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d77598d55d8ad5356f08539dae9c80c2f0887240f3d7cc45fe8f81a39e22467f
|
4
|
+
data.tar.gz: 376dde9dc8d380588293178dba3b968ac8a558c52832804e0aea5c0d065627f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f49e353daeca137c0a542dfad6f49f6c927786fbef5f3b8242bf9dd29f091e398ef10ba206ebf71a64c8d64f258400c0b3b24c87b4e62cc39aaa6dd3d76bbbaa
|
7
|
+
data.tar.gz: 7c0565ff56406fbfc56f6b711e1b26a42d9bf1a50b708ed659b53628963f42b37922814ed2e0f517c302dd205ffbf888d22bd11f93be9a875f88ab84d6241dbc
|
data/Gemfile.lock
CHANGED
@@ -21,67 +21,61 @@ module RSMP
|
|
21
21
|
JSON.generate(item,@@json_options)
|
22
22
|
end
|
23
23
|
|
24
|
+
# convert a yaml item to json schema
|
24
25
|
def self.build_value item
|
25
26
|
out = {}
|
27
|
+
out['description'] = item['description'] if item['description']
|
26
28
|
|
27
|
-
if item['
|
28
|
-
|
29
|
+
if item['type'] =~/_list$/
|
30
|
+
handle_string_list item, out
|
31
|
+
else
|
32
|
+
handle_types item, out
|
33
|
+
handle_enum item, out
|
34
|
+
handle_pattern item, out
|
29
35
|
end
|
36
|
+
wrap_refs out
|
37
|
+
end
|
30
38
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
value_list = item["values"].keys.join('|')
|
45
|
-
out['pattern'] = /(?-mix:^(#{value_list})(?:,(#{value_list}))*$)/
|
46
|
-
end
|
47
|
-
|
48
|
-
if item["pattern"]
|
49
|
-
puts "Warning: Pattern not support for lists: #{item.inspect}"
|
50
|
-
end
|
39
|
+
# convert an item which is not a string-list, to json schema
|
40
|
+
def self.handle_types item, out
|
41
|
+
case item['type']
|
42
|
+
when "string", "base64"
|
43
|
+
out["type"] = "string"
|
44
|
+
when "boolean"
|
45
|
+
out["$ref"] = "../../../core/3.1.1/definitions.json#/boolean"
|
46
|
+
when "timestamp"
|
47
|
+
out["$ref"] = "../../../core/3.1.1/definitions.json#/timestamp"
|
48
|
+
when "integer", "ordinal", "unit", "scale", "long"
|
49
|
+
out["$ref"] = "../../../core/3.1.1/definitions.json#/integer"
|
50
|
+
when 'array' # a json array
|
51
|
+
build_json_array item['items'], out
|
51
52
|
else
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
when "boolean"
|
56
|
-
out["$ref"] = "../../../core/3.1.1/definitions.json#/boolean"
|
57
|
-
when "timestamp"
|
58
|
-
out["$ref"] = "../../../core/3.1.1/definitions.json#/timestamp"
|
59
|
-
when "integer", "ordinal", "unit", "scale", "long"
|
60
|
-
out["$ref"] = "../../../core/3.1.1/definitions.json#/integer"
|
61
|
-
else
|
62
|
-
out["type"] = "string"
|
63
|
-
end
|
64
|
-
|
65
|
-
if item["values"]
|
66
|
-
case item["values"]
|
67
|
-
when Hash
|
68
|
-
out["enum"] = item["values"].keys.sort
|
69
|
-
when Array
|
70
|
-
out["enum"] = item["values"].sort
|
71
|
-
else
|
72
|
-
raise "Error: Values must be specified as either a Hash or an Array"
|
73
|
-
end
|
74
|
-
|
75
|
-
end
|
53
|
+
out["type"] = "string"
|
54
|
+
end
|
55
|
+
end
|
76
56
|
|
77
|
-
|
78
|
-
|
79
|
-
|
57
|
+
# convert an yaml item with type: array to json schema
|
58
|
+
def self.build_json_array item, out
|
59
|
+
required = item.select { |k,v| v['optional'] != true }.keys.sort
|
60
|
+
out.merge!({
|
61
|
+
"type" => "array",
|
62
|
+
"items" => {
|
63
|
+
"type" => "object",
|
64
|
+
"required" => required,
|
65
|
+
"additionalProperties": false
|
66
|
+
}
|
67
|
+
})
|
68
|
+
out["items"]["properties"] = {}
|
69
|
+
item.each_pair do |key,v|
|
70
|
+
out["items"]["properties"][key] = build_value(v)
|
80
71
|
end
|
72
|
+
out
|
73
|
+
end
|
81
74
|
|
82
|
-
|
83
|
-
|
84
|
-
|
75
|
+
# with draft-07 and older, using a $ref mean all other properties are ignored.
|
76
|
+
# to avoid this we need to use an allOf.
|
77
|
+
# this is changed from draft-08, but unfortunately, there is still no Ruby validator for that
|
78
|
+
def self.wrap_refs out
|
85
79
|
if out.keys.include? '$ref'
|
86
80
|
ref = out.delete '$ref'
|
87
81
|
{ "allOf" => [out,{"$ref"=>ref}]}
|
@@ -90,6 +84,47 @@ module RSMP
|
|
90
84
|
end
|
91
85
|
end
|
92
86
|
|
87
|
+
# convert a yaml item with list: true to json schema
|
88
|
+
def self.handle_string_list item, out
|
89
|
+
case item['type']
|
90
|
+
when "boolean_list"
|
91
|
+
out["$ref"] = "../../../core/3.1.1/definitions.json#/boolean_list"
|
92
|
+
when "integer_list"
|
93
|
+
out["$ref"] = "../../../core/3.1.1/definitions.json#/integer_list"
|
94
|
+
when "string_list"
|
95
|
+
out["$ref"] = "../../../core/3.1.1/definitions.json#/string_list"
|
96
|
+
else
|
97
|
+
raise "Error: List of #{item['type']} is not supported: #{item.inspect}"
|
98
|
+
end
|
99
|
+
|
100
|
+
if item["values"]
|
101
|
+
value_list = item["values"].keys.join('|')
|
102
|
+
out['pattern'] = /(?-mix:^(#{value_list})(?:,(#{value_list}))*$)/
|
103
|
+
end
|
104
|
+
|
105
|
+
puts "Warning: Pattern not support for lists: #{item.inspect}" if item["pattern"]
|
106
|
+
end
|
107
|
+
|
108
|
+
# convert yaml values to jsons schema enum
|
109
|
+
def self.handle_enum item, out
|
110
|
+
if item["values"]
|
111
|
+
case item["values"]
|
112
|
+
when Hash
|
113
|
+
out["enum"] = item["values"].keys.sort
|
114
|
+
when Array
|
115
|
+
out["enum"] = item["values"].sort
|
116
|
+
else
|
117
|
+
raise "Error: Values must be specified as either a Hash or an Array"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# convert yaml pattern to jsons schema
|
123
|
+
def self.handle_pattern item, out
|
124
|
+
out["pattern"] = item["pattern"] if item["pattern"]
|
125
|
+
end
|
126
|
+
|
127
|
+
# convert yaml alarm/status/command item to corresponding jsons schema
|
93
128
|
def self.build_item item, property_key: 'v'
|
94
129
|
json = { "allOf" => [ { "description" => item['description'] } ] }
|
95
130
|
if item['arguments']
|
@@ -104,6 +139,7 @@ module RSMP
|
|
104
139
|
json
|
105
140
|
end
|
106
141
|
|
142
|
+
# convert alarms to json schema
|
107
143
|
def self.output_alarms out, items
|
108
144
|
list = items.keys.sort.map do |key|
|
109
145
|
{
|
@@ -121,11 +157,13 @@ module RSMP
|
|
121
157
|
items.each_pair { |key,item| output_alarm out, key, item }
|
122
158
|
end
|
123
159
|
|
160
|
+
# convert an alarm to json schema
|
124
161
|
def self.output_alarm out, key, item
|
125
162
|
json = build_item item
|
126
163
|
out["alarms/#{key}.json"] = output_json json
|
127
164
|
end
|
128
165
|
|
166
|
+
# convert statuses to json schema
|
129
167
|
def self.output_statuses out, items
|
130
168
|
list = [ { "properties" => { "sCI" => { "enum"=> items.keys.sort }}} ]
|
131
169
|
items.keys.sort.each do |key|
|
@@ -139,11 +177,13 @@ module RSMP
|
|
139
177
|
items.each_pair { |key,item| output_status out, key, item }
|
140
178
|
end
|
141
179
|
|
180
|
+
# convert a status to json schema
|
142
181
|
def self.output_status out, key, item
|
143
182
|
json = build_item item, property_key:'s'
|
144
183
|
out["statuses/#{key}.json"] = output_json json
|
145
184
|
end
|
146
185
|
|
186
|
+
# convert commands to json schema
|
147
187
|
def self.output_commands out, items
|
148
188
|
list = [ { "properties" => { "cCI" => { "enum"=> items.keys.sort }}} ]
|
149
189
|
items.keys.sort.each do |key|
|
@@ -164,12 +204,14 @@ module RSMP
|
|
164
204
|
items.each_pair { |key,item| output_command out, key, item }
|
165
205
|
end
|
166
206
|
|
207
|
+
# convert a command to json schema
|
167
208
|
def self.output_command out, key, item
|
168
209
|
json = build_item item
|
169
210
|
json["allOf"].first["properties"]['cO'] = { "const" => item['command'] }
|
170
211
|
out["commands/#{key}.json"] = output_json json
|
171
212
|
end
|
172
213
|
|
214
|
+
# output the json schema root
|
173
215
|
def self.output_root out, meta
|
174
216
|
json = {
|
175
217
|
"name"=> meta['name'],
|
@@ -197,6 +239,7 @@ module RSMP
|
|
197
239
|
out["sxl.json"] = output_json json
|
198
240
|
end
|
199
241
|
|
242
|
+
# generate the json schema from a string containing yaml
|
200
243
|
def self.generate sxl
|
201
244
|
out = {}
|
202
245
|
output_root out, sxl[:meta]
|
@@ -206,6 +249,7 @@ module RSMP
|
|
206
249
|
out
|
207
250
|
end
|
208
251
|
|
252
|
+
# convert yaml to json schema and write files to a folder
|
209
253
|
def self.write sxl, folder
|
210
254
|
out = generate sxl
|
211
255
|
out.each_pair do |relative_path,str|
|
@@ -215,9 +259,7 @@ module RSMP
|
|
215
259
|
file.puts str
|
216
260
|
end
|
217
261
|
end
|
218
|
-
|
219
262
|
end
|
220
|
-
|
221
263
|
end
|
222
264
|
end
|
223
265
|
end
|
data/lib/rsmp_schema/schema.rb
CHANGED
@@ -6,32 +6,66 @@ end
|
|
6
6
|
module RSMP::Schema
|
7
7
|
@@schemas = nil
|
8
8
|
|
9
|
-
def self.
|
10
|
-
|
9
|
+
def self.setup
|
10
|
+
@@schemas = {}
|
11
11
|
schemas_path = File.expand_path( File.join(__dir__,'..','..','schemas') )
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
12
|
+
Dir.glob("#{schemas_path}/*").select {|f| File.directory? f}.each do |type_path|
|
13
|
+
type = File.basename(type_path).to_sym
|
14
|
+
@@schemas[type] = {}
|
15
|
+
Dir.glob("#{type_path}/*").select {|f| File.directory? f}.each do |schema_path|
|
16
|
+
version = File.basename(schema_path)
|
17
|
+
if type == :core
|
18
|
+
file = 'rsmp.json'
|
19
|
+
else
|
20
|
+
file = 'sxl.json'
|
21
|
+
end
|
22
|
+
@@schemas[type][version] = JSONSchemer.schema(
|
23
|
+
Pathname.new(File.join(schema_path,file))
|
24
|
+
)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# get all schemas, oganized by type and version
|
30
|
+
def self.schemas
|
31
|
+
raise RuntimeError.new("No schemas available, perhaps Schema.setup was never called?") unless @@schemas
|
32
|
+
@@schemas
|
33
|
+
end
|
34
|
+
|
35
|
+
# get array of core schema versions
|
36
|
+
def self.core_versions
|
37
|
+
versions :core
|
38
|
+
end
|
39
|
+
|
40
|
+
# get earliest core schema version
|
41
|
+
def self.earliest_core_version
|
42
|
+
earliest_version :core
|
33
43
|
end
|
34
44
|
|
45
|
+
# get latesty core schema version
|
46
|
+
def self.latest_core_version
|
47
|
+
latest_version :core
|
48
|
+
end
|
49
|
+
|
50
|
+
# get array of schema versions for a particular schema type
|
51
|
+
def self.versions type
|
52
|
+
schemas = find_schemas!(type).keys
|
53
|
+
sort_versions(schemas)
|
54
|
+
end
|
55
|
+
|
56
|
+
# get earliest schema version for a particular schema type
|
57
|
+
def self.earliest_version type
|
58
|
+
schemas = find_schemas!(type).keys
|
59
|
+
sort_versions(schemas).first
|
60
|
+
end
|
61
|
+
|
62
|
+
# get latest schema version for a particular schema type
|
63
|
+
def self.latest_version type
|
64
|
+
schemas = find_schemas!(type).keys
|
65
|
+
sort_versions(schemas).last
|
66
|
+
end
|
67
|
+
|
68
|
+
# validate an rsmp messages using a schema object
|
35
69
|
def self.validate_using_schema message, schema
|
36
70
|
raise ArgumentError.new("message missing") unless message
|
37
71
|
raise ArgumentError.new("schema missing") unless schema
|
@@ -44,17 +78,28 @@ module RSMP::Schema
|
|
44
78
|
end
|
45
79
|
end
|
46
80
|
|
81
|
+
# sort version strings
|
82
|
+
def self.sort_versions versions
|
83
|
+
versions.sort_by { |k| Gem::Version.new(k) }
|
84
|
+
end
|
85
|
+
|
86
|
+
# find schemas versions for particular schema type
|
87
|
+
# return nil if type not found
|
47
88
|
def self.find_schemas type
|
48
89
|
raise ArgumentError.new("type missing") unless type
|
49
|
-
schemas[type.to_sym]
|
90
|
+
schemas = @@schemas[type.to_sym]
|
50
91
|
end
|
51
92
|
|
93
|
+
# find schemas versions for particular schema type
|
94
|
+
# raise error if not found
|
52
95
|
def self.find_schemas! type
|
53
96
|
schemas = find_schemas type
|
54
97
|
raise UnknownSchemaTypeError.new("Unknown schema type #{type}") unless schemas
|
55
98
|
schemas
|
56
99
|
end
|
57
100
|
|
101
|
+
# find schema for a particular schema and version
|
102
|
+
# return nil if not found
|
58
103
|
def self.find_schema type, version, options={}
|
59
104
|
raise ArgumentError.new("version missing") unless version
|
60
105
|
version = sanitize_version version if options[:lenient]
|
@@ -65,11 +110,18 @@ module RSMP::Schema
|
|
65
110
|
nil
|
66
111
|
end
|
67
112
|
|
113
|
+
# get major.minor.patch part of a version string, where patch is optional
|
114
|
+
# ignore trailing characters, e.g.
|
115
|
+
# 3.1.3.32A => 3.1.3
|
116
|
+
# 3.1A3r3 >= 3.1
|
117
|
+
# return nil if string doesn't match
|
68
118
|
def self.sanitize_version version
|
69
119
|
matched = /^\d+\.\d+(\.\d+)?/.match version
|
70
120
|
matched.to_s if matched
|
71
121
|
end
|
72
122
|
|
123
|
+
# find schema for a particular schema and version
|
124
|
+
# raise error if not found
|
73
125
|
def self.find_schema! type, version, options={}
|
74
126
|
schema = find_schema type, version, options
|
75
127
|
raise ArgumentError.new("version missing") unless version
|
@@ -82,10 +134,14 @@ module RSMP::Schema
|
|
82
134
|
raise UnknownSchemaVersionError.new("Unknown schema version #{type} #{version}")
|
83
135
|
end
|
84
136
|
|
137
|
+
# true if a particular schema type and version found
|
85
138
|
def self.has_schema? type, version, options={}
|
86
139
|
find_schema(type,version, options) != nil
|
87
140
|
end
|
88
141
|
|
142
|
+
# validate using a particular schema and version
|
143
|
+
# raises error if schema is not found
|
144
|
+
# return nil if validation succeds, otherwise returns an array of errors
|
89
145
|
def self.validate message, schemas, options={}
|
90
146
|
raise ArgumentError.new("message missing") unless message
|
91
147
|
raise ArgumentError.new("schemas missing") unless schemas
|
data/lib/rsmp_schema/version.rb
CHANGED