lib/sitehub/route_builder.rb in sitehub-0.5.0.alpha3 vs lib/sitehub/route_builder.rb in sitehub-0.5.0.alpha4

- old
+ new

@@ -1,7 +1,9 @@ require 'uuid' require 'sitehub/equality' +require 'sitehub/nil_route' +require 'sitehub/identifier' require 'sitehub/getter_setter_methods' require_relative 'collection/split_route_collection' require_relative 'rules' require_relative 'resolver' require_relative 'collection/route_collection' @@ -12,20 +14,22 @@ class SiteHub class RouteBuilder class InvalidDefinitionException < Exception end - INVALID_SPLIT_MSG = 'url must be defined if not supplying a block'.freeze ROUTES_WITH_SPLITS_MSG = 'you cant register routes and splits at the same level'.freeze - INVALID_ROUTE_DEF_MSG = 'rule must be specified when supplying a block'.freeze - IGNORING_URL_LABEL_MSG = 'Block supplied, ignoring URL and Label parameters'.freeze + INVALID_SPLIT_MSG = 'url must be defined if not supplying a block'.freeze + RULE_NOT_SPECIFIED_MSG = 'rule must be specified when supplying a block'.freeze + IGNORING_URL_MSG = 'Block supplied, ignoring URL parameter'.freeze URL_REQUIRED_MSG = 'URL must be supplied for splits and routes'.freeze class << self # TODO: support nest splits and routes def from_hash(hash, sitehub_cookie_name) - new(sitehub_cookie_name: sitehub_cookie_name, sitehub_cookie_path: hash[:sitehub_cookie_path], mapped_path: hash[:path]) do + new(sitehub_cookie_name: sitehub_cookie_name, + sitehub_cookie_path: hash[:sitehub_cookie_path], + mapped_path: hash[:path]) do extend CollectionMethods collection(hash, :splits).each do |split| split(percentage: split[:percentage], url: split[:url], label: split[:label]) end @@ -42,15 +46,15 @@ extend GetterSetterMethods include Rules, Equality, Middleware transient :id - getter_setters :default_proxy, :sitehub_cookie_path, :sitehub_cookie_name + getter_setters :sitehub_cookie_path, :sitehub_cookie_name attr_reader :mapped_path, :id - def initialize(sitehub_cookie_name:, sitehub_cookie_path: nil, mapped_path:, rule: nil, &block) - @id = UUID.generate(:compact) + def initialize(id: nil, sitehub_cookie_name:, sitehub_cookie_path: nil, mapped_path:, rule: nil, &block) + @id = Identifier.new(id) @mapped_path = mapped_path @sitehub_cookie_name = sitehub_cookie_name @sitehub_cookie_path = sitehub_cookie_path @splits = Collection::SplitRouteCollection.new @routes = Collection::RouteCollection.new @@ -60,75 +64,81 @@ instance_eval(&block) raise InvalidDefinitionException unless valid? end - def build - if middleware? - build_with_middleware - build_default_with_middleware if default_proxy - end + def add_route(label:, rule: nil, percentage: nil, url: nil, &block) + label = id.child_label(label) + route = if block + raise InvalidDefinitionException, RULE_NOT_SPECIFIED_MSG unless percentage || rule + warn(IGNORING_URL_MSG) if url + new(rule: rule, id: label, &block).build + else + raise InvalidDefinitionException, RULE_NOT_SPECIFIED_MSG unless url + forward_proxy(url: url, label: label, rule: rule) + end - self + routes.add(label, route, percentage) end - def default(url:) - default_proxy(forward_proxy(label: :default, url: url)) + def default_route + routes.default end - def endpoints(collection = nil) - return @endpoints || Collection::RouteCollection.new unless collection + def default_route? + !default_route.nil? + end - raise InvalidDefinitionException, ROUTES_WITH_SPLITS_MSG if @endpoints && @endpoints != collection - @endpoints = collection + def build + build_with_middleware if middleware? + self end + def default(url:) + routes.default = forward_proxy(label: :default, url: url) + end + def forward_proxy(label:, url:, rule: nil) proxy = ForwardProxy.new(mapped_url: url, mapped_path: mapped_path) - id = (label || UUID.generate(:compact)).to_sym Route.new(proxy, - id: id, + id: label, sitehub_cookie_path: sitehub_cookie_path, sitehub_cookie_name: sitehub_cookie_name).tap do |wrapper| wrapper.rule(rule) end end def resolve(id: nil, env:) - id = id.to_s.to_sym - endpoints[id] || endpoints.resolve(id: id, env: env) || default_proxy + id = Identifier.new(id) + if id.valid? && (route = routes[id.root]) + route.resolve(id: id.sub_id, env: env) + else + routes.resolve(env: env) || default_route + end end - def route(url: nil, label: nil, rule: nil, &block) - endpoint = if block - raise InvalidDefinitionException, INVALID_ROUTE_DEF_MSG unless rule - warn(IGNORING_URL_LABEL_MSG) if url || label - new(rule: rule, &block).build - else - forward_proxy(url: url, label: label, rule: rule) - end - - routes.add(endpoint.id, endpoint) + def route(url: nil, label:, rule: nil, &block) + routes(@routes) + add_route(label: label, rule: rule, url: url, &block) end - def split(percentage:, url: nil, label: nil, &block) - raise InvalidDefinitionException, INVALID_SPLIT_MSG unless block || url + def routes(collection = nil) + return @endpoints ||= Collection::RouteCollection.new unless collection - proxy = if block - warn(IGNORING_URL_LABEL_MSG) if url || label - new(&block).build - else - forward_proxy(label: label, url: url) - end + raise InvalidDefinitionException, ROUTES_WITH_SPLITS_MSG if @endpoints && !@endpoints.equal?(collection) + @endpoints = collection + end - splits.add proxy.id, proxy, percentage + def split(percentage:, url: nil, label:, &block) + routes(@splits) + add_route(label: label, percentage: percentage, url: url, &block) end def valid? - return true if default_proxy - endpoints.valid? + return true if default_route? + routes.valid? end private def add_middleware_to_proxy(proxy) @@ -136,36 +146,26 @@ middleware_class, args, block = middleware_args_and_block proxy.use middleware_class, *args, &block end end - def build_default_with_middleware - add_middleware_to_proxy(default_proxy) - default_proxy.init - end - def build_with_middleware - endpoints.values.each do |proxy| - add_middleware_to_proxy(proxy) - proxy.init + routes = routes().values.find_all { |route| route.is_a?(Route) } + + routes << default_route if default_route? + + routes.each do |route| + add_middleware_to_proxy(route) + route.init end end - def new(rule: nil, &block) - self.class.new(sitehub_cookie_name: sitehub_cookie_name, + def new(id:, rule: nil, &block) + self.class.new(id: id, + sitehub_cookie_name: sitehub_cookie_name, + sitehub_cookie_path: sitehub_cookie_path, mapped_path: mapped_path, rule: rule, - &block).tap do |builder| - builder.sitehub_cookie_name sitehub_cookie_name - builder.sitehub_cookie_path sitehub_cookie_path - end - end - - def splits - endpoints(@splits) - end - - def routes - endpoints(@routes) + &block) end end end