Class: AvroTurf::SchemaStore

Inherits:
Object
  • Object
show all
Defined in:
lib/avro_turf/schema_store.rb

Instance Method Summary collapse

Constructor Details

#initialize(path: nil) ⇒ SchemaStore

Returns a new instance of SchemaStore.



2
3
4
5
# File 'lib/avro_turf/schema_store.rb', line 2

def initialize(path: nil)
  @path = path or raise "Please specify a schema path"
  @schemas = Hash.new
end

Instance Method Details

#find(name, namespace = nil) ⇒ Object

Resolves and returns a schema.

schema_name - The String name of the schema to resolve.

Returns an Avro::Schema.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/avro_turf/schema_store.rb', line 12

def find(name, namespace = nil)
  fullname = Avro::Name.make_fullname(name, namespace)

  return @schemas[fullname] if @schemas.key?(fullname)

  *namespace, schema_name = fullname.split(".")
  schema_path = File.join(@path, *namespace, schema_name + ".avsc")
  schema_json = JSON.parse(File.read(schema_path))
  schema = Avro::Schema.real_parse(schema_json, @schemas)

  if schema.respond_to?(:fullname) && schema.fullname != fullname
    raise AvroTurf::SchemaError, "expected schema `#{schema_path}' to define type `#{fullname}'"
  end

  schema
rescue ::Avro::SchemaParseError => e
  # This is a hack in order to figure out exactly which type was missing. The
  # Avro gem ought to provide this data directly.
  if e.to_s =~ /"([\w\.]+)" is not a schema we know about/
    find($1)

    # Re-resolve the original schema now that the dependency has been resolved.
    @schemas.delete(fullname)
    find(fullname)
  else
    raise
  end
rescue Errno::ENOENT, Errno::ENAMETOOLONG
  raise AvroTurf::SchemaNotFoundError, "could not find Avro schema at `#{schema_path}'"
end

#load_schemas!Object

Loads all schema definition files in the ‘schemas_dir`.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/avro_turf/schema_store.rb', line 44

def load_schemas!
  pattern = [@path, "**", "*.avsc"].join("/")

  Dir.glob(pattern) do |schema_path|
    # Remove the path prefix.
    schema_path.sub!(/^\/?#{@path}\//, "")

    # Replace `/` with `.` and chop off the file extension.
    schema_name = File.basename(schema_path.tr("/", "."), ".avsc")

    # Load and cache the schema.
    find(schema_name)
  end
end