Module: ElasticGraph::Support::Config

Defined in:
elasticgraph-support/lib/elastic_graph/support/config.rb

Overview

Provides a standard way to define an ElasticGraph configuration class.

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

EXTENSION_MODULE_SCHEMA =

JSON schema for an extension_modules config setting, for use by ElasticGraph components (such as elasticgraph-graphql and elasticgraph-indexer) that support extension modules being extended onto their component instances.

{
  description: "Array of modules that will be extended onto the component instance to support extension libraries.",
  type: "array",
  items: {
    type: "object",
    properties: {
      name: {
        type: "string",
        minLength: 1,
        description: "The name of the extension module class to load.",
        examples: ["MyExtensionModule", "ElasticGraph::MyExtension"]
      },
      require_path: {
        type: "string",
        minLength: 1,
        description: "The path to require to load the extension module.",
        examples: ["./my_extension_module", "elastic_graph/my_extension"]
      }
    },
    required: ["name", "require_path"]
  },
  default: [], # : untyped
  examples: [
    [], # : untyped
    [
      {
        "name" => "MyExtensionModule",
        "require_path" => "./my_extension_module"
      }
    ]
  ]
}

Class Method Summary collapse

Class Method Details

.define(*attrs) {|::Data| ... } ⇒ ::Class

Defines a configuration class with the given attributes.

Examples:

Define a configuration class

require "elastic_graph/support/config"

ExampleConfigClass = ElasticGraph::Support::Config.define(:size, :name) do
  json_schema at: "example", optional: false,
    properties: {
      size: {
        description: "Determines the size.",
        examples: [10, 100],
        type: "integer",
        minimum: 1,
      },
      name: {
        description: "Determines the name.",
        examples: ["widget"],
        type: "string",
        minLength: 1
      }
    },
    required: ["size", "name"]
end

Parameters:

  • attrs (::Symbol)

    attribute names

Yields:

  • (::Data)

    the body of the class (similar to ::Data.define)

Returns:

  • (::Class)

    the defined configuration class



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'elasticgraph-support/lib/elastic_graph/support/config.rb', line 81

def self.define(*attrs, &block)
  ::Data.define(*attrs) do
    # @implements ConfigData
    alias_method :__data_initialize, :initialize
    extend ClassMethods

    # On JRuby 10.0.4.0, `include`-ing a module in a Data.define block causes
    # subclass instances to have nil fields in certain call patterns. Define the
    # instance methods directly instead of using `include InstanceMethods`.
    # See: https://github.com/jruby/jruby/issues/9327

    # Overrides `initialize` to apply JSON schema validation.
    def initialize(**config)
      klass = (_ = self.class) # : ClassMethods[::Data]
      validator = klass.validator
      config = validator.merge_defaults(config)

      if (error = validator.validate_with_error_message(config))
        klass.raise_invalid_config(error)
      end

      config = config.transform_keys(&:to_sym)
      __skip__ = super(**convert_values(**config))
    end

    # Overrides `#with` to bypass the normal JSON schema validation that applies in `#initialize`.
    # This is required so that `config.with(...)` can be used on config classes that use the
    # `convert_values` hook to convert JSON data to some custom Ruby type. The custom Ruby type
    # won't pass JSON schema validation, and if we didn't override `with` then we'd get validation
    # failures due to the converted values failing validation.
    def with(**updates)
      (_ = self.class).new_without_validation(**to_h.merge(updates))
    end

    private

    # Default implementation of a hook that allows config values to be converted during initialization.
    def convert_values(**values)
      values
    end

    public

    class_exec(&(_ = block)) if block
  end
end