Module: ElasticGraph::SchemaArtifacts::RuntimeMetadata::InterfaceVerifier

Defined in:
lib/elastic_graph/schema_artifacts/runtime_metadata/interface_verifier.rb

Overview

Responsible for verifying extensions. This requires an interface definition (a class or module with empty method definitions that just serves to define what loaded extensions must implement). That allows us to verify the extension implements the interface correctly ahead of time, rather than deferring exceptions to when the extension is later used.

Note, however, that this does not guarantee no runtime exceptions from the use of the extension: the extension may return invalid return values, or throw exceptions when called. But this verifies the interface to the extent that we can.

Class Method Summary collapse

Class Method Details

.verify(extension, against:, constant_name:) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/elastic_graph/schema_artifacts/runtime_metadata/interface_verifier.rb', line 37

def verify(extension, against:, constant_name:)
  problems = [] # : ::Array[::String]
  problems.concat(verify_methods("class", extension.singleton_class, against.singleton_class))

  if extension.is_a?(::Module)
    problems.concat(verify_methods("instance", extension, against))

    # We care about the name exactly matching so that we can dump the extension name in a schema
    # artifact w/o having to pass around the original constant name.
    if extension.name != constant_name.delete_prefix("::")
      problems << "- Exposes a name (`#{extension.name}`) that differs from the provided extension name (`#{constant_name}`)"
    end
  else
    problems << "- Is not a class or module as expected"
  end

  problems
end

.verify!(extension, against:, constant_name:) ⇒ Object



27
28
29
30
31
32
33
34
35
# File 'lib/elastic_graph/schema_artifacts/runtime_metadata/interface_verifier.rb', line 27

def verify!(extension, against:, constant_name:)
  problems = verify(extension, against:, constant_name:)

  if problems.any?
    raise Errors::InvalidExtensionError,
      "Extension `#{constant_name}` does not implement the expected interface correctly. Problems:\n\n" \
      "#{problems.join("\n")}"
  end
end