qa_server 0.1.99
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +71 -0
- data/Gemfile +55 -0
- data/Gemfile.lock +411 -0
- data/LICENSE +201 -0
- data/README.md +187 -0
- data/Rakefile +18 -0
- data/app/assets/images/qa_server/LD4L-bg.png +0 -0
- data/app/assets/images/qa_server/cornell-reduced-white.svg +160 -0
- data/app/assets/images/qa_server/iowa-logo.png +0 -0
- data/app/assets/images/qa_server/samvera-fall-font1-1000w-light.png +0 -0
- data/app/assets/javascripts/qa_server.js +0 -0
- data/app/assets/stylesheets/qa_server/_authorities.scss +0 -0
- data/app/assets/stylesheets/qa_server/_check-status.scss +72 -0
- data/app/assets/stylesheets/qa_server/_footer.scss +20 -0
- data/app/assets/stylesheets/qa_server/_header.scss +51 -0
- data/app/assets/stylesheets/qa_server/_home-page.scss +15 -0
- data/app/assets/stylesheets/qa_server/_monitor-status.scss +13 -0
- data/app/assets/stylesheets/qa_server/_qa_server.scss +36 -0
- data/app/assets/stylesheets/qa_server/_styles.scss +27 -0
- data/app/assets/stylesheets/qa_server/_usage.scss +0 -0
- data/app/controllers/qa_server/authority_list_controller.rb +14 -0
- data/app/controllers/qa_server/authority_validation_controller.rb +77 -0
- data/app/controllers/qa_server/check_status_controller.rb +38 -0
- data/app/controllers/qa_server/homepage_controller.rb +8 -0
- data/app/controllers/qa_server/monitor_status_controller.rb +79 -0
- data/app/controllers/qa_server/usage_controller.rb +8 -0
- data/app/loggers/qa_server/scenario_logger.rb +84 -0
- data/app/models/qa_server/authority_scenario.rb +35 -0
- data/app/models/qa_server/authority_status.rb +18 -0
- data/app/models/qa_server/authority_status_failure.rb +7 -0
- data/app/models/qa_server/scenarios.rb +71 -0
- data/app/models/qa_server/search_scenario.rb +58 -0
- data/app/models/qa_server/term_scenario.rb +50 -0
- data/app/presenters/qa_server/authority_list_presenter.rb +22 -0
- data/app/presenters/qa_server/check_status_presenter.rb +96 -0
- data/app/presenters/qa_server/monitor_status_presenter.rb +108 -0
- data/app/services/qa_server/authority_lister_service.rb +31 -0
- data/app/services/qa_server/authority_loader_service.rb +38 -0
- data/app/services/qa_server/authority_validator_service.rb +41 -0
- data/app/services/qa_server/database_migrator.rb +70 -0
- data/app/services/qa_server/scenarios_loader_service.rb +57 -0
- data/app/validators/qa_server/scenario_validator.rb +134 -0
- data/app/validators/qa_server/search_scenario_validator.rb +84 -0
- data/app/validators/qa_server/term_scenario_validator.rb +42 -0
- data/app/views/layouts/qa_server.html.erb +65 -0
- data/app/views/qa_server/authority_list/index.html.erb +27 -0
- data/app/views/qa_server/check_status/index.html.erb +104 -0
- data/app/views/qa_server/homepage/index.html.erb +10 -0
- data/app/views/qa_server/monitor_status/index.html.erb +78 -0
- data/app/views/qa_server/usage/index.html.erb +106 -0
- data/app/views/shared/_footer.html.erb +24 -0
- data/config/locales/qa_server.en.yml +68 -0
- data/config/routes.rb +12 -0
- data/lib/generators/qa_server/assets_generator.rb +35 -0
- data/lib/generators/qa_server/config_generator.rb +31 -0
- data/lib/generators/qa_server/install_generator.rb +60 -0
- data/lib/generators/qa_server/models_generator.rb +18 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/agrovoc_direct.json +69 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/agrovoc_ld4l_cache.json +85 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/dbpedia_direct.json +36 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/dbpedia_ld4l_cache.json +83 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/geonames_direct.json +68 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/geonames_ld4l_cache.json +102 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/getty_aat_ld4l_cache.json +109 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/getty_tgn_ld4l_cache.json +72 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/getty_ulan_ld4l_cache.json +81 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/loc_direct.json +47 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/locgenres_ld4l_cache.json +99 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/locnames_ld4l_cache.json +89 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/locsubjects_ld4l_cache.json +82 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/mesh_ld4l_cache.json +70 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/nalt_direct.json +32 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/nalt_ld4l_cache.json +84 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/oclcfast_direct.json +81 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/oclcfast_ld4l_cache.json +86 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/agrovoc_direct_validation.yml +9 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/agrovoc_ld4l_cache_validation.yml +9 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/agrovoc_validation.yml +9 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/dbpedia_direct_validation.yml +6 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/dbpedia_ld4l_cache_validation.yml +9 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/geonames_direct_validation.yml +9 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/geonames_ld4l_cache_validation.yml +41 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/getty_aat_ld4l_cache_validation.yml +115 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/getty_tgn_ld4l_cache_validation.yml +9 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/getty_ulan_ld4l_cache_validation.yml +15 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/loc_direct_validation.yml +25 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/loc_validation.yml +22 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locgenres_ld4l_cache_validation.yml +99 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locnames_ld4l_cache_validation.yml +27 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locsubjects_ld4l_cache_validation.yml +27 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/mesh_ld4l_cache_validation.yml +9 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/nalt_direct_validation.yml +6 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/nalt_ld4l_cache_validation.yml +9 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/oclc_fast_validation.yml +58 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/oclcfast_direct_validation.yml +58 -0
- data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/oclcfast_ld4l_cache_validation.yml +30 -0
- data/lib/generators/qa_server/templates/config/locales/qa_server.en.yml +9 -0
- data/lib/generators/qa_server/templates/db/migrate/20180313045551_create_cron_authority_status.rb.erb +9 -0
- data/lib/generators/qa_server/templates/db/migrate/20180508045549_rename_cron_authority_status_to_authority_status.rb.erb +5 -0
- data/lib/generators/qa_server/templates/db/migrate/20180508045551_create_authority_status_failure.rb.erb +15 -0
- data/lib/generators/qa_server/templates/qa_server.scss +5 -0
- data/lib/qa_server/engine.rb +19 -0
- data/lib/qa_server/version.rb +3 -0
- data/lib/qa_server.rb +6 -0
- data/lib/tasks/install.rake +8 -0
- data/lib/tasks/qa_server_tasks.rake +4 -0
- data/qa_server.gemspec +39 -0
- data/spec/.gitignore +1 -0
- data/spec/rails_helper.rb +2 -0
- data/spec/spec_helper.rb +283 -0
- data/spec/test_app_templates/Gemfile.extra +5 -0
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +15 -0
- data/tasks/qa_server_dev.rake +16 -0
- metadata +275 -0
@@ -0,0 +1,134 @@
|
|
1
|
+
# ABSTRACT class providing common methods for running a scenario of any type.
|
2
|
+
module QaServer
|
3
|
+
class ScenarioValidator
|
4
|
+
PASS = :good
|
5
|
+
FAIL = :bad
|
6
|
+
UNKNOWN = :unknown
|
7
|
+
|
8
|
+
VALIDATE_CONNECTION = :connection
|
9
|
+
VALIDATE_ACCURACY = :accuracy
|
10
|
+
ALL_VALIDATIONS = :all_validations
|
11
|
+
DEFAULT_VALIDATION_TYPE = VALIDATE_CONNECTION
|
12
|
+
|
13
|
+
# @param scenario [SearchScenario | TermScenario] the scenario to run
|
14
|
+
# @param status_log [ScenarioLogger] logger for recording test results
|
15
|
+
# @param validation_type [Symbol] the type of scenarios to run (e.g. VALIDATE_CONNECTION, VALIDATE_ACCURACY, ALL_VALIDATIONS)
|
16
|
+
def initialize(scenario:, status_log:, validation_type: DEFAULT_VALIDATION_TYPE)
|
17
|
+
@status_log = status_log
|
18
|
+
@scenario = scenario
|
19
|
+
@validation_type = validation_type
|
20
|
+
end
|
21
|
+
|
22
|
+
# Run a search scenario and log results.
|
23
|
+
def run
|
24
|
+
run_accuracy_scenario if accuracy_scenario? && validating_accuracy?
|
25
|
+
run_connection_scenario if connection_scenario? && validating_connections?
|
26
|
+
end
|
27
|
+
|
28
|
+
# Log the structure of the scenario without running the scenario test.
|
29
|
+
def log_without_running
|
30
|
+
log
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# Log the structure of the scenario and status of a test run.
|
36
|
+
def log(status: nil, errmsg: nil, expected: nil, actual: nil, target: nil)
|
37
|
+
status_log.add(authority_name: authority_name,
|
38
|
+
status: status,
|
39
|
+
validation_type: scenario_validation_type,
|
40
|
+
subauth: subauthority_name,
|
41
|
+
service: service,
|
42
|
+
action: action,
|
43
|
+
url: url,
|
44
|
+
error_message: errmsg,
|
45
|
+
expected: expected,
|
46
|
+
actual: actual,
|
47
|
+
target: target)
|
48
|
+
end
|
49
|
+
|
50
|
+
def run_accuracy_scenario
|
51
|
+
# ABSTRACT - must be implemented by scenario validator for specific types
|
52
|
+
end
|
53
|
+
|
54
|
+
def run_connection_scenario
|
55
|
+
# ABSTRACT - must be implemented by scenario validator for specific types
|
56
|
+
end
|
57
|
+
|
58
|
+
# Runs the test in the block passed by the specific scenario type.
|
59
|
+
# @return [Symbol] :good (PASS) or :unknown (UNKNOWN) based on whether enough results were returned
|
60
|
+
def test_connection(min_expected_size: MIN_EXPECTED_SIZE, scenario_type_name:)
|
61
|
+
begin
|
62
|
+
results = yield if block_given?
|
63
|
+
actual_size = results.to_s.length
|
64
|
+
status = actual_size > min_expected_size ? PASS : UNKNOWN
|
65
|
+
errmsg = (status == PASS) ? '' : "#{scenario_type_name.capitalize} scenario unknown status; cause: Results actual size (#{actual_size} < expected size (#{min_expected_size})"
|
66
|
+
log(status: status, errmsg: errmsg)
|
67
|
+
rescue Exception => e
|
68
|
+
log(status: FAIL, errmsg: "Exception executing #{scenario_type_name} scenario; cause: #{e.message}")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def authority
|
73
|
+
scenario.authority
|
74
|
+
end
|
75
|
+
|
76
|
+
def authority_name
|
77
|
+
scenario.authority_name.upcase
|
78
|
+
end
|
79
|
+
|
80
|
+
def subauthority_name
|
81
|
+
scenario.subauthority_name
|
82
|
+
end
|
83
|
+
|
84
|
+
def service
|
85
|
+
scenario.service
|
86
|
+
end
|
87
|
+
|
88
|
+
def url
|
89
|
+
scenario.url
|
90
|
+
end
|
91
|
+
|
92
|
+
def action
|
93
|
+
# ABSTRACT - must be implemented by scenario validator for specific types
|
94
|
+
end
|
95
|
+
|
96
|
+
def status_log
|
97
|
+
@status_log
|
98
|
+
end
|
99
|
+
|
100
|
+
def scenario
|
101
|
+
@scenario
|
102
|
+
end
|
103
|
+
|
104
|
+
def validation_type
|
105
|
+
@validation_type
|
106
|
+
end
|
107
|
+
|
108
|
+
def scenario_validation_type
|
109
|
+
return VALIDATE_CONNECTION if connection_scenario?
|
110
|
+
return VALIDATE_ACCURACY if accuracy_scenario?
|
111
|
+
nil
|
112
|
+
end
|
113
|
+
|
114
|
+
def validating_connections?
|
115
|
+
return true if validation_type == VALIDATE_CONNECTION || validation_type == ALL_VALIDATIONS
|
116
|
+
false
|
117
|
+
end
|
118
|
+
|
119
|
+
def validating_accuracy?
|
120
|
+
return true if validation_type == VALIDATE_ACCURACY || validation_type == ALL_VALIDATIONS
|
121
|
+
false
|
122
|
+
end
|
123
|
+
|
124
|
+
def accuracy_scenario?
|
125
|
+
# ABSTRACT define in specific scenario type validator (i.e. TermScenarioValidator, SearchScenarioValidator)
|
126
|
+
false
|
127
|
+
end
|
128
|
+
|
129
|
+
def connection_scenario?
|
130
|
+
# ABSTRACT define in specific scenario type validator (i.e. TermScenarioValidator, SearchScenarioValidator)
|
131
|
+
false
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
# This class runs a single search scenario and logs the results.
|
4
|
+
module QaServer
|
5
|
+
class SearchScenarioValidator < ScenarioValidator
|
6
|
+
SEARCH_ACTION = 'search'.freeze
|
7
|
+
|
8
|
+
# @param scenario [SearchScenario] the scenario to run
|
9
|
+
# @param status_log [ScenarioLogger] logger for recording test results
|
10
|
+
# @param validation_type [Symbol] the type of scenarios to run (e.g. VALIDATE_CONNECTION, VALIDATE_ACCURACY, ALL_VALIDATIONS)
|
11
|
+
def initialize(scenario:, status_log:, validation_type: DEFAULT_VALIDATION_TYPE)
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def action
|
18
|
+
SEARCH_ACTION
|
19
|
+
end
|
20
|
+
|
21
|
+
# Run the connection test and log results
|
22
|
+
def run_connection_scenario
|
23
|
+
test_connection(min_expected_size: scenario.min_result_size, scenario_type_name: 'search') do
|
24
|
+
authority.search(scenario.query,
|
25
|
+
subauth: scenario.subauthority_name,
|
26
|
+
replacements: scenario.replacements)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Run the accuracy test and log results
|
31
|
+
def run_accuracy_scenario
|
32
|
+
test_accuracy(subject_uri: scenario.subject_uri, expected_by_position: scenario.expected_by_position) do
|
33
|
+
authority.search(scenario.query,
|
34
|
+
subauth: scenario.subauthority_name,
|
35
|
+
replacements: scenario.replacements)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Runs the accuracy test and log results
|
40
|
+
def test_accuracy(subject_uri:, expected_by_position:)
|
41
|
+
begin
|
42
|
+
results = yield if block_given?
|
43
|
+
if results.blank?
|
44
|
+
log(status: UNKNOWN, errmsg: "Search position scenario failed; cause: no results found", expected: expected_by_position, target: subject_uri)
|
45
|
+
return
|
46
|
+
end
|
47
|
+
|
48
|
+
check_position(results, subject_uri, expected_by_position)
|
49
|
+
rescue Exception => e
|
50
|
+
log(status: FAIL, errmsg: "Exception executing search position scenario; cause: #{e.message}", expected: expected_by_position, target: subject_uri)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def accuracy_scenario?
|
55
|
+
return false if scenario.expected_by_position.blank? || scenario.subject_uri.blank?
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
59
|
+
def connection_scenario?
|
60
|
+
# There are only two types of tests, so if this isn't an accuracy scenario, it must be a connection scenario.
|
61
|
+
!accuracy_scenario?
|
62
|
+
end
|
63
|
+
|
64
|
+
def check_position(results, subject_uri, expected_by_position)
|
65
|
+
actual_position = subject_position(results, subject_uri)
|
66
|
+
return if actual_position.blank?
|
67
|
+
|
68
|
+
actual_position += 1
|
69
|
+
if actual_position <= expected_by_position
|
70
|
+
log(status: PASS, expected: expected_by_position, actual: actual_position, target: subject_uri)
|
71
|
+
else
|
72
|
+
log(status: UNKNOWN, errmsg: 'Subject URI not found by the expected position.', expected: expected_by_position, actual: actual_position, target: subject_uri)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def subject_position(results, subject_uri)
|
77
|
+
0.upto(results.size - 1) do |position|
|
78
|
+
return position if results[position][:uri] == subject_uri
|
79
|
+
end
|
80
|
+
log(status: UNKNOWN, errmsg: "Search position scenario failed; cause: subject uri (#{subject_uri}) not found in results", expected: scenario.expected_by_position, target: subject_uri)
|
81
|
+
return nil
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# This class runs a single term scenario and logs the results.
|
2
|
+
module QaServer
|
3
|
+
class TermScenarioValidator < ScenarioValidator
|
4
|
+
TERM_ACTION = 'term'.freeze
|
5
|
+
|
6
|
+
# @param scenario [TermScenario] the scenario to run
|
7
|
+
# @param status_log [ScenarioLogger] logger for recording test results
|
8
|
+
# @param validation_type [Symbol] the type of scenarios to run (e.g. VALIDATE_CONNECTION, VALIDATE_ACCURACY, ALL_VALIDATIONS)
|
9
|
+
def initialize(scenario:, status_log:, validation_type: DEFAULT_VALIDATION_TYPE)
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
# Run a term scenario and log results.
|
14
|
+
def run_connection_scenario
|
15
|
+
test_connection(min_expected_size: scenario.min_result_size, scenario_type_name: 'term') do
|
16
|
+
authority.find(scenario.identifier,
|
17
|
+
subauth: scenario.subauthority_name)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Run a term scenario and log results.
|
22
|
+
def run_accuracy_scenario
|
23
|
+
# no accuracy scenarios defined for terms at this time
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def action
|
29
|
+
TERM_ACTION
|
30
|
+
end
|
31
|
+
|
32
|
+
def accuracy_scenario?
|
33
|
+
# At this time, all scenarios are connection scenarios for terms.
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
def connection_scenario?
|
38
|
+
# At this time, all scenarios are connection scenarios for terms.
|
39
|
+
true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Authority Lookup Server</title>
|
5
|
+
|
6
|
+
<!-- Latest compiled and minified CSS -->
|
7
|
+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
|
8
|
+
<!-- jQuery library -->
|
9
|
+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
10
|
+
<!-- Latest compiled JavaScript -->
|
11
|
+
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
12
|
+
|
13
|
+
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
14
|
+
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
|
15
|
+
|
16
|
+
<%= csrf_meta_tags %>
|
17
|
+
|
18
|
+
</head>
|
19
|
+
|
20
|
+
<body>
|
21
|
+
<section class="ld4l-identity" aria-label="Cornell" role="banner">
|
22
|
+
<div id="skiptocontent"><a href="#maincontent">skip to main content</a></div>
|
23
|
+
<div class="container">
|
24
|
+
<a href="<%= main_app.root_path %>"><img src="<%= image_url('qa_server/LD4L-bg.png') %>" class="header-logo"></a>
|
25
|
+
<a id="logo" class="navbar-brand" href="<%= main_app.root_path %>" data-no-turbolink="true">
|
26
|
+
<span class="institution-name"><%= t("qa_server.application_name") %></span>
|
27
|
+
</a>
|
28
|
+
</div> <!-- /container -->
|
29
|
+
</section>
|
30
|
+
|
31
|
+
<div class="container">
|
32
|
+
<nav id="masthead" class="navbar navbar-inverse navbar-static-top" role="navigation">
|
33
|
+
<div class="container-fluid">
|
34
|
+
<div class="navbar-header">
|
35
|
+
<ul class="nav-menu">
|
36
|
+
<li class="left-menu"><%= link_to t("qa_server.menu.home"), main_app.root_path %></li>
|
37
|
+
<li class="left-menu"><%= link_to t("qa_server.menu.usage"), qa_server.usage_index_path %></li>
|
38
|
+
<li class="left-menu"><%= link_to t("qa_server.menu.authorities"), qa_server.authority_list_index_path %></li>
|
39
|
+
<li class="left-menu"><%= link_to t("qa_server.menu.check_status"), qa_server.check_status_index_path %></li>
|
40
|
+
<li class="left-menu"><%= link_to t("qa_server.menu.monitor_status"), qa_server.monitor_status_index_path %></li>
|
41
|
+
<li class="right-menu"><%= link_to "LD4L Gateway", "http://ld4l.org/" %></li>
|
42
|
+
</ul>
|
43
|
+
</div>
|
44
|
+
</div>
|
45
|
+
</nav>
|
46
|
+
</div>
|
47
|
+
</div>
|
48
|
+
|
49
|
+
<div id="content-wrapper" class="container" role="main">
|
50
|
+
<a name="skip_to_content"></a>
|
51
|
+
<%# = render '/flash_msg' %>
|
52
|
+
<% if content_for?(:page_header) %>
|
53
|
+
<div class="row">
|
54
|
+
<div class="col-xs-12 main-header">
|
55
|
+
<%= yield(:page_header) %>
|
56
|
+
</div>
|
57
|
+
</div>
|
58
|
+
<% end %>
|
59
|
+
|
60
|
+
<%= content_for?(:content) ? yield(:content) : yield %>
|
61
|
+
</div><!-- /#content-wrapper -->
|
62
|
+
<%= render 'shared/footer' %>
|
63
|
+
<%# = render 'shared/ajax_modal' %>
|
64
|
+
</body>
|
65
|
+
</html>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<div class="page-description">
|
2
|
+
|
3
|
+
<h2><%= t('qa_server.authority_list.title') %></h2>
|
4
|
+
<p><%= t('qa_server.authority_list.see_check_status_html', href: "#{main_app.root_path}check_status") %></p>
|
5
|
+
|
6
|
+
<div id="status-section" class="status-section">
|
7
|
+
<p><b><%= t('qa_server.warning.chrome_unencoding_msg') %></b></p>
|
8
|
+
<table class="status">
|
9
|
+
<tr>
|
10
|
+
<th><%= t('qa_server.authority_list.data.authority') %></th>
|
11
|
+
<th><%= t('qa_server.authority_list.data.subauthority') %></th>
|
12
|
+
<th><%= t('qa_server.authority_list.data.service') %></th>
|
13
|
+
<th><%= t('qa_server.authority_list.data.action') %></th>
|
14
|
+
<th><%= t('qa_server.authority_list.data.url') %></th>
|
15
|
+
</tr>
|
16
|
+
<% @presenter.urls_data.each do |entry| %>
|
17
|
+
<tr>
|
18
|
+
<td><%= entry[:authority_name] %></td>
|
19
|
+
<td><%= entry[:subauthority_name] %></td>
|
20
|
+
<td><%= entry[:service] %></td>
|
21
|
+
<td><%= entry[:action] %></td>
|
22
|
+
<td><a href="<%= entry[:url] %>"><%= entry[:url] %></a></td>
|
23
|
+
</tr>
|
24
|
+
<% end %>
|
25
|
+
</table>
|
26
|
+
</div>
|
27
|
+
</div>
|
@@ -0,0 +1,104 @@
|
|
1
|
+
<script>
|
2
|
+
function validate_authority(form) {
|
3
|
+
form.submit();
|
4
|
+
document.getElementById('status-loading-message').style.display = 'block';
|
5
|
+
document.getElementById('connection-status-section').style.display = 'none';
|
6
|
+
document.getElementById('accuracy-status-section').style.display = 'none';
|
7
|
+
document.getElementById('example-url-warning').style.display = 'none';
|
8
|
+
}
|
9
|
+
</script>
|
10
|
+
|
11
|
+
<div class="page-description">
|
12
|
+
|
13
|
+
<h2><%= t('qa_server.check_status.title') %></h2>
|
14
|
+
|
15
|
+
<%= form_tag({ action: 'index' }, { method: :get }) do %>
|
16
|
+
<select name="authority" id="authority" class="string multi-value optional form-control form-control multi-text-field" value="" aria-labelledby="authority" onchange="validate_authority(this.form)">
|
17
|
+
<option value=""><%= t('qa_server.check_status.select_authority') %></option>
|
18
|
+
<option disabled>──────────</option>
|
19
|
+
<option value="<%= @presenter.value_all_collections %>"><%= t('qa_server.check_status.show_all') %></option>
|
20
|
+
<option disabled>──────────</option>
|
21
|
+
<% @authorities_list.each do |auth_name| %>
|
22
|
+
<option value="<%= auth_name %>"><%= auth_name.upcase %></option>
|
23
|
+
<% end %>
|
24
|
+
</select>
|
25
|
+
<div class="validation-types">
|
26
|
+
<%= radio_button_tag(@presenter.value_check_param, @presenter.value_check_connections, :selected) %>
|
27
|
+
<%= label_tag(@presenter.label_check_connections, t('qa_server.check_status.connections'), class: 'horizontal-list') %>
|
28
|
+
<%= radio_button_tag(@presenter.value_check_param, @presenter.value_check_accuracy) %>
|
29
|
+
<%= label_tag(@presenter.label_check_accuracy, t('qa_server.check_status.accuracy'), class: 'horizontal-list') %>
|
30
|
+
<%= radio_button_tag(@presenter.value_check_param, @presenter.value_all_checks) %>
|
31
|
+
<%= label_tag(@presenter.label_all_checks, t('qa_server.check_status.all_checks'), class: 'horizontal-list') %>
|
32
|
+
</div>
|
33
|
+
<% end %>
|
34
|
+
|
35
|
+
|
36
|
+
<div id="status-loading-message" class="wait-message"><%= t('qa_server.check_status.wait_message') %></div>
|
37
|
+
|
38
|
+
<% if @presenter.connection_status_data? || @presenter.accuracy_status_data? %>
|
39
|
+
<div id="example-url-warning">
|
40
|
+
<p><b><%= t('qa_server.warning.chrome_unencoding_msg') %></b></p>
|
41
|
+
</div>
|
42
|
+
<% end %>
|
43
|
+
|
44
|
+
<% if @presenter.connection_status_data? %>
|
45
|
+
<div id="connection-status-section" class="status-section">
|
46
|
+
<h3><%= t('qa_server.check_status.connection_checks') %></h3>
|
47
|
+
<table class="status">
|
48
|
+
<tr>
|
49
|
+
<th><%= t('qa_server.check_status.status_table.status') %></th>
|
50
|
+
<th><%= t('qa_server.check_status.status_table.authority') %></th>
|
51
|
+
<th><%= t('qa_server.check_status.status_table.subauthority') %></th>
|
52
|
+
<th><%= t('qa_server.check_status.status_table.service') %></th>
|
53
|
+
<th><%= t('qa_server.check_status.status_table.action') %></th>
|
54
|
+
<th><%= t('qa_server.check_status.status_table.url') %></th>
|
55
|
+
<th><%= t('qa_server.check_status.status_table.errmsg') %></th>
|
56
|
+
</tr>
|
57
|
+
<% @presenter.connection_status_data.each do |status| %>
|
58
|
+
<tr>
|
59
|
+
<td class="<%= @presenter.status_style_class(status) %>"><%= status[:status_label] %></td>
|
60
|
+
<td><%= status[:authority_name] %></td>
|
61
|
+
<td><%= status[:subauthority_name] %></td>
|
62
|
+
<td><%= status[:service] %></td>
|
63
|
+
<td><%= status[:action] %></td>
|
64
|
+
<td><a href="<%= status[:url] %>"><%= status[:url] %></a></td>
|
65
|
+
<td><%= status[:err_message] %></td>
|
66
|
+
</tr>
|
67
|
+
<% end %>
|
68
|
+
</table>
|
69
|
+
</div>
|
70
|
+
<% end %>
|
71
|
+
|
72
|
+
<% if @presenter.accuracy_status_data? %>
|
73
|
+
<div id="accuracy-status-section" class="status-section">
|
74
|
+
<h3><%= t('qa_server.check_status.accuracy_checks') %></h3>
|
75
|
+
<table class="status">
|
76
|
+
<tr>
|
77
|
+
<th><%= t('qa_server.check_status.status_table.expected_by_position') %></th>
|
78
|
+
<th><%= t('qa_server.check_status.status_table.actual_position') %></th>
|
79
|
+
<th><%= t('qa_server.check_status.status_table.subject_uri') %></th>
|
80
|
+
<th><%= t('qa_server.check_status.status_table.authority') %></th>
|
81
|
+
<th><%= t('qa_server.check_status.status_table.subauthority') %></th>
|
82
|
+
<th><%= t('qa_server.check_status.status_table.service') %></th>
|
83
|
+
<th><%= t('qa_server.check_status.status_table.action') %></th>
|
84
|
+
<th><%= t('qa_server.check_status.status_table.url') %></th>
|
85
|
+
<th><%= t('qa_server.check_status.status_table.errmsg') %></th>
|
86
|
+
</tr>
|
87
|
+
<% @presenter.accuracy_status_data.each do |status| %>
|
88
|
+
<tr>
|
89
|
+
<td class="position <%= @presenter.status_style_class(status) %>"><%= status[:expected] %></td>
|
90
|
+
<td class="position <%= @presenter.status_style_class(status) %>"><%= status[:actual] %></td>
|
91
|
+
<td><a href="<%= status[:target] %>"><%= status[:target] %></a></td>
|
92
|
+
<td><%= status[:authority_name] %></td>
|
93
|
+
<td><%= status[:subauthority_name] %></td>
|
94
|
+
<td><%= status[:service] %></td>
|
95
|
+
<td><%= status[:action] %></td>
|
96
|
+
<td><a href="<%= status[:url] %>"><%= status[:url] %></a></td>
|
97
|
+
<td><%= status[:err_message] %></td>
|
98
|
+
</tr>
|
99
|
+
<% end %>
|
100
|
+
</table>
|
101
|
+
</div>
|
102
|
+
<% end %>
|
103
|
+
|
104
|
+
</div>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<div class="page-description">
|
2
|
+
<p class="welcome">This service provides authority <b>lookup for single terms</b> and <b>search for terms</b> matching a query.
|
3
|
+
See <a href="<%= "#{main_app.root_path}usage" %>">Usage</a> for more information.</p>
|
4
|
+
<p class="welcome2">It has been created as part of the
|
5
|
+
<a href="http://ld4l.org" target="_blank">LD4L Labs project</a>, and is operated by
|
6
|
+
<a href="http://www.library.cornell.edu/" target="_blank">Cornell University Library</a>
|
7
|
+
in collaboration with the
|
8
|
+
<a href="https://www.slis.uiowa.edu/" target="_blank">School of Library and Information Science, University of Iowa</a>.
|
9
|
+
This work was funded through a grant from the <a href="https://mellon.org/" target="_blank">Andrew W. Mellon Foundation</a>.</p>
|
10
|
+
</div>
|
@@ -0,0 +1,78 @@
|
|
1
|
+
<div class="page-description">
|
2
|
+
<h2><%= t('qa_server.monitor_status.summary.title') %></h2>
|
3
|
+
|
4
|
+
<table class="monitor-status-status">
|
5
|
+
<tr>
|
6
|
+
<th><%= t('qa_server.monitor_status.summary.authorities') %></th>
|
7
|
+
<th><%= t('qa_server.monitor_status.summary.authorities_with_failures') %></th>
|
8
|
+
<th><%= t('qa_server.monitor_status.summary.passing_tests') %></th>
|
9
|
+
<th><%= t('qa_server.monitor_status.summary.failing_tests') %></th>
|
10
|
+
<th><%= t('qa_server.monitor_status.summary.total_tests') %></th>
|
11
|
+
</tr>
|
12
|
+
<tr>
|
13
|
+
<td><%= @presenter.authorities_count %></td>
|
14
|
+
<td class="<%= @presenter.authorities_count_style %>"><%= @presenter.failing_authorities_count %></td>
|
15
|
+
<td><%= @presenter.passing_tests_count%></td>
|
16
|
+
<td class="<%= @presenter.failing_tests_style %>"><%= @presenter.failing_tests_count %></td>
|
17
|
+
<td><%= @presenter.tests_count %></td>
|
18
|
+
</tr>
|
19
|
+
</table>
|
20
|
+
<p class="status-update-dtstamp"><%= t('qa_server.monitor_status.summary.last_updated', date: @presenter.last_updated) %></p>
|
21
|
+
|
22
|
+
<% if @presenter.failures? %>
|
23
|
+
<div id="status-section" class="status-section">
|
24
|
+
<h2><%= t('qa_server.monitor_status.failures.title') %></h2>
|
25
|
+
|
26
|
+
<p><b><%= t('qa_server.warning.chrome_unencoding_msg') %></b></p>
|
27
|
+
<table class="status">
|
28
|
+
<tr>
|
29
|
+
<th><%= t('qa_server.monitor_status.failures.status') %></th>
|
30
|
+
<th><%= t('qa_server.monitor_status.failures.authority') %></th>
|
31
|
+
<th><%= t('qa_server.monitor_status.failures.subauthority') %></th>
|
32
|
+
<th><%= t('qa_server.monitor_status.failures.service') %></th>
|
33
|
+
<th><%= t('qa_server.monitor_status.failures.action') %></th>
|
34
|
+
<th><%= t('qa_server.monitor_status.failures.url') %></th>
|
35
|
+
<th><%= t('qa_server.monitor_status.failures.errmsg') %></th>
|
36
|
+
</tr>
|
37
|
+
<% @status_data.each do |status| %>
|
38
|
+
<tr>
|
39
|
+
<td class="<%= "status-#{status[:status].to_s}" %>"><%= status[:status_label] %></td>
|
40
|
+
<td><%= status[:authority_name] %></td>
|
41
|
+
<td><%= status[:subauthority_name] %></td>
|
42
|
+
<td><%= status[:service] %></td>
|
43
|
+
<td><%= status[:action] %></td>
|
44
|
+
<td><a href="<%= status[:url] %>"><%= status[:url] %></a></td>
|
45
|
+
<td><%= status[:err_message] %></td>
|
46
|
+
</tr>
|
47
|
+
<% end %>
|
48
|
+
</table>
|
49
|
+
</div>
|
50
|
+
<% end %>
|
51
|
+
|
52
|
+
<% if @presenter.history? %>
|
53
|
+
<div id="status-section" class="status-section">
|
54
|
+
<h2><%= t('qa_server.monitor_status.history.title') %></h2>
|
55
|
+
|
56
|
+
<h3><%= t('qa_server.monitor_status.history.since', date: @presenter.first_updated) %></h3>
|
57
|
+
|
58
|
+
<table class="status">
|
59
|
+
<tr>
|
60
|
+
<th><%= t('qa_server.monitor_status.history.days_failing') %></th>
|
61
|
+
<th><%= t('qa_server.monitor_status.history.authority') %></th>
|
62
|
+
<th><%= t('qa_server.monitor_status.history.subauthority') %></th>
|
63
|
+
<th><%= t('qa_server.monitor_status.history.service') %></th>
|
64
|
+
<th><%= t('qa_server.monitor_status.history.action') %></th>
|
65
|
+
</tr>
|
66
|
+
<% @presenter.history.each do |entry| %>
|
67
|
+
<tr>
|
68
|
+
<td><%= entry[:days_failing] %></td>
|
69
|
+
<td><%= entry[:authority_name] %></td>
|
70
|
+
<td><%= entry[:subauthority_name] %></td>
|
71
|
+
<td><%= entry[:service] %></td>
|
72
|
+
<td><%= entry[:action] %></td>
|
73
|
+
</tr>
|
74
|
+
<% end %>
|
75
|
+
</table>
|
76
|
+
</div>
|
77
|
+
<% end %>
|
78
|
+
</div>
|
@@ -0,0 +1,106 @@
|
|
1
|
+
<div class="page-description">
|
2
|
+
|
3
|
+
<h2>Usage:</h2>
|
4
|
+
<h3>To search for matching terms:</h3>
|
5
|
+
|
6
|
+
<p>The query parameter <b>q</b> is required. All other parameters are optional. Some authorities support different
|
7
|
+
optional parameters, but attempts were made to keep optional parameter names consistent between authorities.</p>
|
8
|
+
|
9
|
+
<h4>Without subauthority:</h4>
|
10
|
+
<pre>/<%= QaServer::QA_ENGINE_MOUNT %>/search/linked_data/locnames_ld4l_cache?q=mark%20twain&maxRecords=4&lang=en</pre>
|
11
|
+
|
12
|
+
where,
|
13
|
+
<ul>
|
14
|
+
<li>search (required) - indicates this is a query for terms</li>
|
15
|
+
<li>locnames_ld4l_cache (required) - the name of the authority</li>
|
16
|
+
<li>q=mark twain (required) - the query for which to search</li>
|
17
|
+
<li>maxRecords=4 (optional) - the number of results to return</li>
|
18
|
+
<li>lang=en (optional) - if the authority returns language encoded literals, results will be filtered for English
|
19
|
+
</ul>
|
20
|
+
|
21
|
+
<h4>With subauthority</h4>
|
22
|
+
<pre>/<%= QaServer::QA_ENGINE_MOUNT %>/search/linked_data/locnames_ld4l_cache/person?q=mark%20twain&maxRecords=4&lang=en</pre>
|
23
|
+
|
24
|
+
where,
|
25
|
+
<ul>
|
26
|
+
<li>search (required) - indicates this is a query for terms</li>
|
27
|
+
<li>locnames_ld4l_cache (required) - the name of the authority</li>
|
28
|
+
<li>person (optional) - limits results to this subauthority (meaning of subauthoritites is authority dependent)</li>
|
29
|
+
<li>q=mark twain (required) - the query for which to search</li>
|
30
|
+
<li>maxRecords=4 (optional) - the number of results to return</li>
|
31
|
+
<li>lang=en (optional) - if the authority returns language encoded literals, results will be filtered for the specified language
|
32
|
+
</ul>
|
33
|
+
|
34
|
+
<h4>Results format:</h4>
|
35
|
+
<p>The results minimally contain the uri, id, and label for each result found. The uri and id may be the same, but not
|
36
|
+
in all cases.</p>
|
37
|
+
|
38
|
+
<p>Example of results with two terms found:</p>
|
39
|
+
<pre>
|
40
|
+
[
|
41
|
+
{
|
42
|
+
"uri":"http://id.loc.gov/authorities/names/n92016188",
|
43
|
+
"id":"http://id.loc.gov/authorities/names/n92016188",
|
44
|
+
"label":"Twain, Mark, 1835-1910. Mark Twain papers"
|
45
|
+
},
|
46
|
+
{
|
47
|
+
"uri":"http://id.loc.gov/authorities/names/n42025440",
|
48
|
+
"id":"http://id.loc.gov/authorities/names/n42025440",
|
49
|
+
"label":"Twain, Mark, 1835-1910. Mark Twain library"
|
50
|
+
}
|
51
|
+
]</pre>
|
52
|
+
|
53
|
+
<hr>
|
54
|
+
<h3>To fetch a single term:</h3>
|
55
|
+
|
56
|
+
<p>The data after the authority name is required and should be the URI or the ID of the term being retrieved.
|
57
|
+
Which value to use depends on the authority configuration. All other parameters are optional. Some
|
58
|
+
authorities support different optional parameters, but attempts were made to keep optional parameter names
|
59
|
+
consistent between authorities.</p>
|
60
|
+
|
61
|
+
<h4>Fetch by URI</h4>
|
62
|
+
<pre>/<%= QaServer::QA_ENGINE_MOUNT %>/show/linked_data/locnames_ld4l_cache/http%3A%2F%2Fid%2Eloc%2Egov%2Fauthorities%2Fnames%2Fn92016188</pre>
|
63
|
+
<p><b><%= t('qa_server.warning.chrome_unencoding_msg') %></b></p>
|
64
|
+
|
65
|
+
where,
|
66
|
+
<ul>
|
67
|
+
<li>show (required) - indicates this is a fetch of a single term</li>
|
68
|
+
<li>locnames_ld4l_cache (required) - the name of the authority</li>
|
69
|
+
<li>http%3A%2F%2Fid%2Eloc%2Egov%2Fauthorities%2Fnames%2Fn92016188 (required) - the encoded uri of the term to fetch</li>
|
70
|
+
<li>lang=en (optional) - if the authority returns language encoded literals, results will be filtered for the specified language</li>
|
71
|
+
</ul>
|
72
|
+
|
73
|
+
<h4>Fetch by ID</h4>
|
74
|
+
<pre>/<%= QaServer::QA_ENGINE_MOUNT %>/show/linked_data/oclcfast_ld4l_cache/1914919?lang=en</pre>
|
75
|
+
|
76
|
+
where,
|
77
|
+
<ul>
|
78
|
+
<li>show (required) - indicates this is a fetch of a single term</li>
|
79
|
+
<li>oclcfast_ld4l_cache (required) - the name of the authority</li>
|
80
|
+
<li>1914919 (required) - the id of the term to fetch</li>
|
81
|
+
<li>lang=en (optional) - if the authority returns language encoded literals, results will be filtered for the specified language
|
82
|
+
</ul>
|
83
|
+
|
84
|
+
<h4>Results format:</h4>
|
85
|
+
<p>The results minimally contain the uri, id, and label of the term. The uri and id may be the same, but not
|
86
|
+
in all cases. All predicate and object values where the term is the subject are also returned in the predicates list.</p>
|
87
|
+
|
88
|
+
<p>Example results for a fetch of a term:</p>
|
89
|
+
<pre>
|
90
|
+
{
|
91
|
+
"uri":"http://id.worldcat.org/fast/530369",
|
92
|
+
"id":"530369",
|
93
|
+
"label":"Cornell University",
|
94
|
+
"altlabel":["Ithaca (N.Y.). Cornell University"],
|
95
|
+
"sameas":["http://id.loc.gov/authorities/names/n79021621","https://viaf.org/viaf/126293486"],
|
96
|
+
"predicates":{
|
97
|
+
"http://purl.org/dc/terms/identifier":"530369",
|
98
|
+
"http://www.w3.org/2004/02/skos/core#inScheme":["http://id.worldcat.org/fast/ontology/1.0/#fast","http://id.worldcat.org/fast/ontology/1.0/#facet-Corporate"],
|
99
|
+
"http://www.w3.org/1999/02/22-rdf-syntax-ns#type":"http://schema.org/Organization",
|
100
|
+
"http://www.w3.org/2004/02/skos/core#prefLabel":"Cornell University",
|
101
|
+
"http://schema.org/name":["Cornell University","Ithaca (N.Y.). Cornell University"],
|
102
|
+
"http://www.w3.org/2004/02/skos/core#altLabel":["Ithaca (N.Y.). Cornell University"],
|
103
|
+
"http://schema.org/sameAs":["http://id.loc.gov/authorities/names/n79021621","https://viaf.org/viaf/126293486"]
|
104
|
+
}
|
105
|
+
}</pre>
|
106
|
+
</div>
|