rsmp_schema 0.1.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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