Skip to content

Commit 8f2c153

Browse files
authored
feat: 540 configurable dataverse list (#551)
* refactor(dataverse): update DataverseHub to use InstallationsParser * feat(dataverse): add services for Dataverse installations * refactor(dataverse): rename dataverse_hub to dataverse_installation_service * test(dataverse): add fixture for partial installations response * docs(configuration): update Dataverse Hub URL instructions * chore: update .gitignore and remove obsolete files
1 parent 442ca46 commit 8f2c153

File tree

15 files changed

+1523
-36
lines changed

15 files changed

+1523
-36
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,10 @@ application/vendor/bundle
4343
/data
4444

4545
.DS_Store
46+
47+
# Deployment
48+
application/DEPLOYMENT
49+
50+
# Agents
51+
AGENTS.md
52+

application/app/connectors/dataverse/handlers/landing.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ def params_schema
1515

1616
def show(request_params)
1717
begin
18-
hub = ::Configuration.dataverse_hub
19-
installations = hub.installations
18+
installation_service = ::Configuration.dataverse_installation_service
19+
installations = installation_service.installations
2020
page = request_params[:page] ? request_params[:page].to_i : 1
2121
installations_page = Page.new(installations, page, ::Configuration.default_pagination_items,
2222
query: request_params[:query], filter_by: :name)
@@ -37,4 +37,3 @@ def show(request_params)
3737
end
3838
end
3939
end
40-

application/app/services/dataverse/dataverse_hub.rb

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
module Dataverse
22
class DataverseHub
33
include LoggingCommon
4+
include Dataverse::InstallationsParser
5+
46
DEFAULT_CACHE_EXPIRY = 24.hours.freeze
57

68
def initialize(
@@ -34,25 +36,10 @@ def cache_expired?
3436
@last_fetched_at.nil? || Time.current - @last_fetched_at > @expires_in
3537
end
3638

37-
private
38-
3939
def fetch_installations
4040
response = @http_client.get(@url)
4141
if response.success?
42-
json = JSON.parse(response.body)
43-
installations = json.map do |entry|
44-
{
45-
id: entry['dvHubId'],
46-
name: entry['name'],
47-
hostname: entry['hostname'],
48-
active: entry.fetch('isActive', true),
49-
}
50-
end.compact
51-
52-
active, inactive = installations.partition { |item| item[:active] }
53-
54-
log_info('Completed loading Dataverse installations', {active: active.size, inactive: inactive.size})
55-
active
42+
parse_installations(response.body, source: @url)
5643
else
5744
log_error('Failed to fetch Dataverse Hub data', {url: @url, response: response.status}, nil)
5845
[]
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
module Dataverse
2+
class DataverseInstallationFile
3+
include LoggingCommon
4+
include Dataverse::InstallationsParser
5+
6+
def initialize(path:, expires_in: Dataverse::DataverseHub::DEFAULT_CACHE_EXPIRY)
7+
@path = path
8+
@expires_in = expires_in
9+
@installations = []
10+
@last_loaded_at = nil
11+
end
12+
13+
def installations
14+
if cache_expired?
15+
log_info('Loading Dataverse installations from file', { path: @path })
16+
result = load_installations
17+
if result.present?
18+
@installations = result
19+
@last_loaded_at = Time.current
20+
end
21+
end
22+
23+
@installations
24+
end
25+
26+
private
27+
28+
def cache_expired?
29+
@last_loaded_at.nil? || Time.current - @last_loaded_at > @expires_in
30+
end
31+
32+
def load_installations
33+
raise ArgumentError, 'Missing dataverse installations file path' if @path.blank?
34+
35+
payload = File.read(@path)
36+
parse_installations(payload, source: @path)
37+
rescue => e
38+
log_error('Failed to read Dataverse Hub file data', { path: @path }, e)
39+
[]
40+
end
41+
end
42+
end
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
module Dataverse
2+
class DataverseInstallationService
3+
SUPPORTED_SCHEMES = %w[http https file].freeze
4+
5+
def initialize(url:, http_client: Common::HttpClient.new, expires_in: Dataverse::DataverseHub::DEFAULT_CACHE_EXPIRY)
6+
@url = url
7+
@http_client = http_client
8+
@expires_in = expires_in
9+
end
10+
11+
def installations
12+
provider.installations
13+
end
14+
15+
private
16+
17+
def provider
18+
@provider ||= begin
19+
uri = URI.parse(@url)
20+
scheme = uri.scheme&.downcase
21+
raise ArgumentError, "Unsupported Dataverse installations URI: #{@url}" if scheme.present? && !SUPPORTED_SCHEMES.include?(scheme)
22+
23+
if scheme == 'file'
24+
Dataverse::DataverseInstallationFile.new(path: uri.path, expires_in: @expires_in)
25+
else
26+
Dataverse::DataverseHub.new(url: @url, http_client: @http_client, expires_in: @expires_in)
27+
end
28+
end
29+
end
30+
end
31+
end
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
module Dataverse
2+
module InstallationsParser
3+
private
4+
5+
def parse_installations(payload, source:)
6+
json = JSON.parse(payload)
7+
installations = json.map do |entry|
8+
{
9+
id: entry['dvHubId'],
10+
name: entry['name'],
11+
hostname: entry['hostname'],
12+
active: entry.fetch('isActive', true),
13+
}
14+
end.compact
15+
16+
active, inactive = installations.partition { |item| item[:active] }
17+
log_info('Completed loading Dataverse installations', {source: source, active: active.size, inactive: inactive.size})
18+
active
19+
end
20+
end
21+
end

application/config/configuration_singleton.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,10 @@ def connector_config(connector_type)
8181
config.fetch(connector_type.to_sym, {})
8282
end
8383

84-
def dataverse_hub
85-
@dataverse_hub ||= begin
86-
LoggingCommon.log_info('[Configuration] Created Dataverse::DataverseHub', {dataverse_hub_url: dataverse_hub_url})
87-
Dataverse::DataverseHub.new(url: dataverse_hub_url)
84+
def dataverse_installation_service
85+
@dataverse_installation_service ||= begin
86+
LoggingCommon.log_info('[Configuration] Created Dataverse::DataverseInstallationService', {dataverse_hub_url: dataverse_hub_url})
87+
Dataverse::DataverseInstallationService.new(url: dataverse_hub_url)
8888
end
8989
end
9090

application/test/config/configuration_singleton_test.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,13 @@ def setup
205205
assert_same first_call, second_call
206206
end
207207

208-
test 'dataverse_hub memoizes and logs creation' do
209-
hub = mock('hub')
210-
Dataverse::DataverseHub.expects(:new).once.returns(hub)
208+
test 'dataverse_installation_service memoizes and logs creation' do
209+
service = mock('dataverse_installations_service')
210+
Dataverse::DataverseInstallationService.expects(:new).once.returns(service)
211211

212212
config = ConfigurationSingleton.new
213-
assert_same hub, config.dataverse_hub
214-
assert_same hub, config.dataverse_hub
213+
assert_same service, config.dataverse_installation_service
214+
assert_same service, config.dataverse_installation_service
215215
end
216216

217217
test 'repo_db memoizes and logs creation' do

application/test/connectors/dataverse/handlers/landing_test.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def setup
1616
{ id: 'dv-test-02', name: 'DV Test 02', hostname: 'https://dv-02.org' }
1717
]
1818
hub = mock('hub'); hub.stubs(:installations).returns(dvs)
19-
::Configuration.stubs(:dataverse_hub).returns(hub)
19+
::Configuration.stubs(:dataverse_installation_service).returns(hub)
2020
res = @action.show({})
2121
assert res.success?
2222
assert_equal 2, res.locals[:installations_page].page_items.size
@@ -28,7 +28,7 @@ def setup
2828
{ id: 'dv-test-02', name: 'Another DV', hostname: 'https://dv-02.org' }
2929
]
3030
hub = mock('hub'); hub.stubs(:installations).returns(dvs)
31-
::Configuration.stubs(:dataverse_hub).returns(hub)
31+
::Configuration.stubs(:dataverse_installation_service).returns(hub)
3232
res = @action.show(query: 'Test 01')
3333
assert res.success?
3434
items = res.locals[:installations_page].page_items
@@ -37,7 +37,7 @@ def setup
3737
end
3838

3939
test 'show returns error on service failure' do
40-
::Configuration.stubs(:dataverse_hub).raises(StandardError.new('boom'))
40+
::Configuration.stubs(:dataverse_installation_service).raises(StandardError.new('boom'))
4141
res = @action.show({})
4242
assert_not res.success?
4343
assert_equal I18n.t('dataverse.landing.index.dataverse_installations_service_error'), res.message[:alert]

0 commit comments

Comments
 (0)