Sha256: f70ee764384a8621f388982096a661d925f52b4e8e70c8aeb25f6bd0a0868056

Contents?: true

Size: 1.77 KB

Versions: 1

Compression:

Stored size: 1.77 KB

Contents

require 'taketo/config_visitor'
require 'taketo/config_traverser'

module Taketo
  class AmbiguousDestinationError < StandardError; end
  class NonExistentDestinationError < StandardError; end

  class DestinationResolver
    def initialize(config, path)
      @config = config
      if String(path).empty? && !String(config.default_destination).empty?
        path = config.default_destination
      end
      @path = path
      @traverser = ConfigTraverser.new(@config)
    end

    def servers
      @servers ||= begin
        collector = SimpleCollector(Taketo::Constructs::Server).new
        @traverser.visit_depth_first(collector)
        collector.result
      end
    end

    def resolve
      resolve_by_global_alias || resolve_by_path
    end

    def resolve_by_global_alias
      unless @path.to_s.empty?
        servers.select(&:global_alias).detect { |s| s.global_alias == @path.to_sym }
      end
    end

    def resolve_by_path
      matching_servers = servers.select { |s| s.path =~ /^#@path/ }
      disambiguate(matching_servers)
    end

    def get_node
      matching_nodes = nodes.select { |n| n.path == @path }
      disambiguate(matching_nodes)
    end

    def nodes
      @nodes ||= begin
        collector = SimpleCollector(Taketo::Constructs::BaseConstruct).new
        @traverser.visit_depth_first(collector)
        collector.result
      end
    end

    def disambiguate(results)
      case results.length
      when 0
        raise NonExistentDestinationError, "Can't find server for path #@path"
      when 1
        results.first
      else
        exact_match = results.detect { |n| n.path == @path }
        exact_match or raise AmbiguousDestinationError,
          "There are multiple possible destinations: #{results.map(&:path).join(", ")}"
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
taketo-0.1.1 lib/taketo/destination_resolver.rb