Class: ForestAdminAgent::Http::Router

Inherits:
Object
  • Object
show all
Includes:
Routes
Defined in:
lib/forest_admin_agent/http/router.rb,
sig/forest_admin_agent/http/router.rbs

Class Method Summary collapse

Class Method Details

.actions_routesArray[String]

Returns:

  • (Array[String])


93
94
95
96
97
98
99
100
101
102
# File 'lib/forest_admin_agent/http/router.rb', line 93

def self.actions_routes
  routes = {}
  Facades::Container.datasource.collections.each_value do |collection|
    collection.schema[:actions].each_key do |action_name|
      routes.merge!(Action::Actions.new(collection, action_name).routes)
    end
  end

  routes
end

.api_charts_routesArray[String]

Returns:

  • (Array[String])


104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/forest_admin_agent/http/router.rb', line 104

def self.api_charts_routes
  routes = {}
  Facades::Container.datasource.collections.each_value do |collection|
    collection.schema[:charts].each do |chart_name|
      routes.merge!(Charts::ApiChartCollection.new(collection, chart_name).routes)
    end
  end

  Facades::Container.datasource.schema[:charts].each do |chart_name|
    routes.merge!(Charts::ApiChartDatasource.new(chart_name).routes)
  end

  routes
end

.cache_disabled?Boolean

Returns:

  • (Boolean)


29
30
31
32
33
34
35
# File 'lib/forest_admin_agent/http/router.rb', line 29

def self.cache_disabled?
  config = ForestAdminAgent::Facades::Container.config_from_cache
  config&.dig(:disable_route_cache) == true
rescue StandardError
  # If config is not available or an error occurs, default to caching enabled
  false
end

.cached_routesObject



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/forest_admin_agent/http/router.rb', line 9

def self.cached_routes
  return routes.freeze if cache_disabled?

  return @cached_routes if @cached_routes

  @mutex.synchronize do
    @cached_routes ||= begin
      start_time = Time.now
      computed_routes = routes
      elapsed = ((Time.now - start_time) * 1000).round(2)

      log_message = "[ForestAdmin] Computed #{computed_routes.size} routes " \
                    "in #{elapsed}ms (caching enabled)"
      ForestAdminAgent::Facades::Container.logger.log('Info', log_message)

      computed_routes.freeze
    end
  end
end

.reset_cached_routes!Object



37
38
39
40
41
# File 'lib/forest_admin_agent/http/router.rb', line 37

def self.reset_cached_routes!
  @mutex.synchronize do
    @cached_routes = nil
  end
end

.routesArray[String]

Returns:

  • (Array[String])


43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/forest_admin_agent/http/router.rb', line 43

def self.routes
  route_sources = [
    { name: 'actions', handler: -> { actions_routes } },
    { name: 'api_charts', handler: -> { api_charts_routes } },
    { name: 'health_check', handler: -> { System::HealthCheck.new.routes } },
    { name: 'authentication', handler: -> { Security::Authentication.new.routes } },
    { name: 'scope_invalidation', handler: -> { Security::ScopeInvalidation.new.routes } },
    { name: 'charts', handler: -> { Charts::Charts.new.routes } },
    { name: 'collections', handler: -> { Capabilities::Collections.new.routes } },
    { name: 'native_query', handler: -> { Resources::NativeQuery.new.routes } },
    # Both must come before the routes matching on `:collection_name`: Rails matches in
    # definition order, so `/_audit-trail/correlations` would otherwise be read as
    # `/:collection_name/:id` and 404 on a collection named `_audit-trail`. Correlation first, so
    # `/_audit-trail/correlations` wins over the per-record `/_audit-trail/:collection_name/:id`.
    { name: 'audit_trail_correlation', handler: -> { Resources::AuditTrailCorrelation.new.routes } },
    { name: 'audit_trail', handler: -> { Resources::AuditTrail.new.routes } },
    { name: 'count', handler: -> { Resources::Count.new.routes } },
    { name: 'delete', handler: -> { Resources::Delete.new.routes } },
    { name: 'csv', handler: -> { Resources::Csv.new.routes } },
    { name: 'list', handler: -> { Resources::List.new.routes } },
    { name: 'show', handler: -> { Resources::Show.new.routes } },
    { name: 'store', handler: -> { Resources::Store.new.routes } },
    { name: 'update', handler: -> { Resources::Update.new.routes } },
    { name: 'csv_related', handler: -> { Resources::Related::CsvRelated.new.routes } },
    { name: 'list_related', handler: -> { Resources::Related::ListRelated.new.routes } },
    { name: 'count_related', handler: -> { Resources::Related::CountRelated.new.routes } },
    { name: 'associate_related', handler: -> { Resources::Related::AssociateRelated.new.routes } },
    { name: 'dissociate_related', handler: -> { Resources::Related::DissociateRelated.new.routes } },
    { name: 'update_related', handler: -> { Resources::Related::UpdateRelated.new.routes } },
    { name: 'update_field', handler: -> { Resources::UpdateField.new.routes } },
    { name: 'workflow_executor_proxy', handler: -> { Workflow::WorkflowExecutorProxy.new.routes } }
  ]

  all_routes = {}

  route_sources.each do |source|
    routes = source[:handler].call

    unless routes.is_a?(Hash)
      raise TypeError, "Route handler '#{source[:name]}' returned #{routes.class} instead of Hash"
    end

    all_routes.merge!(routes)
  rescue StandardError => e
    raise e.class, "Failed to load routes from '#{source[:name]}' handler: #{e.message}"
  end

  all_routes
end