Module: RSMP::Schema

Defined in:
lib/rsmp_schema/schema.rb,
lib/rsmp_schema/version.rb,
lib/rsmp_schema/error.rb,
lib/rsmp_schema/cli.rb

Defined Under Namespace

Classes: CLI, Error, UnknownSchemaError, UnknownSchemaTypeError, UnknownSchemaVersionError

Constant Summary collapse

VERSION =
"0.8.5"
@@schemas =
nil

Class Method Summary collapse

Class Method Details

.core_versionsObject

get array of core schema versions



59
60
61
# File 'lib/rsmp_schema/schema.rb', line 59

def self.core_versions
  versions :core
end

.earliest_core_versionObject

get earliest core schema version



64
65
66
# File 'lib/rsmp_schema/schema.rb', line 64

def self.earliest_core_version
  earliest_version :core
end

.earliest_version(type) ⇒ Object

get earliest schema version for a particular schema type



80
81
82
83
# File 'lib/rsmp_schema/schema.rb', line 80

def self.earliest_version type
  schemas = find_schemas!(type).keys
  sort_versions(schemas).first
end

.find_schema(type, version, options = {}) ⇒ Object

find schema for a particular schema and version return nil if not found

Raises:

  • (ArgumentError)


126
127
128
129
130
131
132
133
134
# File 'lib/rsmp_schema/schema.rb', line 126

def self.find_schema type, version, options={}
  raise ArgumentError.new("version missing") unless version
  version = sanitize_version version if options[:lenient]
  if version
    schemas = find_schemas type
    return schemas[version] if schemas
  end
  nil
end

.find_schema!(type, version, options = {}) ⇒ Object

find schema for a particular schema and version raise error if not found

Raises:

  • (ArgumentError)


153
154
155
156
157
158
159
160
161
162
163
# File 'lib/rsmp_schema/schema.rb', line 153

def self.find_schema! type, version, options={}
  schema = find_schema type, version, options
  raise ArgumentError.new("version missing") unless version
  version = sanitize_version version if options[:lenient]
  if version
    schemas = find_schemas! type
    schema = schemas[version]
    return schema if schema
  end
  raise UnknownSchemaVersionError.new("Unknown schema version #{type} #{version}")
end

.find_schemas(type) ⇒ Object

find schemas versions for particular schema type return nil if type not found

Raises:

  • (ArgumentError)


111
112
113
114
# File 'lib/rsmp_schema/schema.rb', line 111

def self.find_schemas type
  raise ArgumentError.new("type missing") unless type
  schemas = @@schemas[type.to_sym]
end

.find_schemas!(type) ⇒ Object

find schemas versions for particular schema type raise error if not found



118
119
120
121
122
# File 'lib/rsmp_schema/schema.rb', line 118

def self.find_schemas! type
  schemas = find_schemas type
  raise UnknownSchemaTypeError.new("Unknown schema type #{type}") unless schemas
  schemas
end

.has_schema?(type, version, options = {}) ⇒ Boolean

true if a particular schema type and version found

Returns:

  • (Boolean)


166
167
168
# File 'lib/rsmp_schema/schema.rb', line 166

def self.has_schema? type, version, options={}
  find_schema(type,version, options) != nil
end

.latest_core_versionObject

get latesty core schema version



69
70
71
# File 'lib/rsmp_schema/schema.rb', line 69

def self.latest_core_version
  latest_version :core
end

.latest_version(type) ⇒ Object

get latest schema version for a particular schema type



86
87
88
89
# File 'lib/rsmp_schema/schema.rb', line 86

def self.latest_version type
  schemas = find_schemas!(type).keys
  sort_versions(schemas).last
end

.load_schema_type(type, type_path, force: false) ⇒ Object

load an schema from a folder. schemas are organized by version, and contain json schema files, with the entry point being rsmp.jspon, eg: tlc

 1.0.7
   rsmp.json
   other jon schema files...
 1.0.8
 ...

an error is raised if the schema type already exists, and force is not set to true

Raises:

  • (RuntimeError)


28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/rsmp_schema/schema.rb', line 28

def self.load_schema_type type, type_path, force:false
  raise RuntimeError.new("Schema type #{type} already loaded") if @@schemas[type] && force!=true
  @@schemas[type] = {}
  Dir.glob("#{type_path}/*").select {|f| File.directory? f}.each do |schema_path|
    version = File.basename(schema_path)
    file_path = File.join(schema_path,'rsmp.json')
    if File.exist? file_path
      @@schemas[type][version] = JSONSchemer.schema(
        Pathname.new(File.join(schema_path,'rsmp.json'))
      )
    end
  end
end

.remove_schema_type(type) ⇒ Object

remove a schema type



43
44
45
# File 'lib/rsmp_schema/schema.rb', line 43

def self.remove_schema_type type
  schemas.delete type
end

.sanitize_version(version) ⇒ Object

get major.minor.patch part of a version string, where patch is optional ignore trailing characters, e.g.

3.1.3.32A => 3.1.3
3.1A3r3 >= 3.1

return nil if string doesn’t match



141
142
143
144
145
146
147
148
149
# File 'lib/rsmp_schema/schema.rb', line 141

def self.sanitize_version version
  # match normal semver z.y.z format
  if matched = /^\d+\.\d+\.\d+/.match(version)
    matched.to_s
  # match x.y format, and add patch version zero to get z.y.0
  elsif matched = /^\d+\.\d+/.match(version)
    "#{matched.to_s}.0"
  end
end

.schema_typesObject

get schemas types



48
49
50
# File 'lib/rsmp_schema/schema.rb', line 48

def self.schema_types
  schemas.keys
end

.schemasObject

get all schemas, oganized by type and version

Raises:

  • (RuntimeError)


53
54
55
56
# File 'lib/rsmp_schema/schema.rb', line 53

def self.schemas
  raise RuntimeError.new("No schemas available, perhaps Schema.setup was never called?") unless @@schemas
  @@schemas
end

.setupObject



9
10
11
12
13
14
15
16
# File 'lib/rsmp_schema/schema.rb', line 9

def self.setup
  @@schemas = {}
  schemas_path = File.expand_path( File.join(__dir__,'..','..','schemas') )
  Dir.glob("#{schemas_path}/*").select {|f| File.directory? f}.each do |type_path|
    type = File.basename(type_path).to_sym
    load_schema_type type, type_path
  end
end

.sort_versions(versions) ⇒ Object

sort version strings



105
106
107
# File 'lib/rsmp_schema/schema.rb', line 105

def self.sort_versions versions
  versions.sort_by { |k| Gem::Version.new(k) }
end

.validate(message, schemas, options = {}) ⇒ Object

validate using a particular schema and version raises error if schema is not found return nil if validation succeds, otherwise returns an array of errors

Raises:

  • (ArgumentError)


173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/rsmp_schema/schema.rb', line 173

def self.validate message, schemas, options={}
  raise ArgumentError.new("message missing") unless message
  raise ArgumentError.new("schemas missing") unless schemas
  raise ArgumentError.new("schemas must be a Hash") unless schemas.is_a?(Hash)
  raise ArgumentError.new("schemas cannot be empty") unless schemas.any?
  errors = schemas.flat_map do |type, version|
    schema = find_schema! type, version, options
    validate_using_schema(message, schema)
  end
  return nil if errors.empty?
  errors
end

.validate_using_schema(message, schema) ⇒ Object

validate an rsmp messages using a schema object

Raises:

  • (ArgumentError)


92
93
94
95
96
97
98
99
100
101
102
# File 'lib/rsmp_schema/schema.rb', line 92

def self.validate_using_schema message, schema
  raise ArgumentError.new("message missing") unless message
  raise ArgumentError.new("schema missing") unless schema
  unless schema.valid? message
    schema.validate(message).map do |item|
      [item['data_pointer'],item['type'],item['details']]
    end
  else
    []
  end
end

.versions(type) ⇒ Object

get array of schema versions for a particular schema type



74
75
76
77
# File 'lib/rsmp_schema/schema.rb', line 74

def self.versions type
  schemas = find_schemas!(type).keys
  sort_versions(schemas)
end