gi_cat_driver 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +5 -1
- data/Rakefile +8 -1
- data/gi_cat_driver.gemspec +1 -0
- data/lib/gi_cat_driver/version.rb +1 -1
- data/lib/gi_cat_driver.rb +82 -89
- data/spec/gi_cat_driver_spec.rb +9 -9
- metadata +53 -12
data/README.md
CHANGED
@@ -44,6 +44,9 @@ Rubydoc API documentation is available at http://rubydoc.info/gems/gi_cat_driver
|
|
44
44
|
|
45
45
|
## Version History
|
46
46
|
|
47
|
+
* 0.1.2
|
48
|
+
* Additional harvesting output
|
49
|
+
* Harvester resources now handled dynamically
|
47
50
|
* 0.1.1
|
48
51
|
* Added parameter to ESIP OpenSearch query builder
|
49
52
|
* Added log output for GI-Cat harvest procedures
|
@@ -71,7 +74,8 @@ This gem follows the principles of [Semantic Versioning 2.0.0](http://semver.org
|
|
71
74
|
## Releasing
|
72
75
|
|
73
76
|
1. Make sure to increment the version number (See the section about versioning above) and append a description of your changes to the Version History section above.
|
74
|
-
2.
|
77
|
+
2. Generate the documentation with 'rake rocco'. To update the gh-pages branch on GitHub I suggest cloning that branch as a new project, then copy the generated docs to that new project and push.
|
78
|
+
3. Commit changes into the master branch of the repo on 'sourcecontrol.nsidc.org'. This will trigger a Jenkins job to run the tests.
|
75
79
|
4. Assuming the change is merged with the master branch and you are ready to release them to GitHub run 'git push https://github.com/nsidc/gi_cat_driver.git master'
|
76
80
|
* There is a Jenkins job that can push master to GitHub if you are confident you wont have merge conflicts.
|
77
81
|
* Note: You must have permissions on the GitHub repository through the NSIDC organization.
|
data/Rakefile
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
-
|
2
|
+
require "rocco/tasks"
|
3
3
|
require 'rspec/core/rake_task'
|
4
|
+
|
4
5
|
RSpec::Core::RakeTask.new('spec')
|
5
6
|
task :default => :spec # to make it default
|
7
|
+
|
8
|
+
desc "Generate Rocco Documentation"
|
9
|
+
Rocco::make 'doc/', 'lib/**/*.rb', {
|
10
|
+
:language => 'ruby',
|
11
|
+
:stylesheet => 'docco.css'
|
12
|
+
}
|
data/gi_cat_driver.gemspec
CHANGED
data/lib/gi_cat_driver.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# The GI-Cat Driver controls GI-Cat configurations and actions using HTTP requests.
|
2
|
+
#
|
1
3
|
require "gi_cat_driver/version"
|
2
4
|
require "gi_cat_driver/esip_opensearch_query_builder"
|
3
5
|
require "open-uri"
|
@@ -6,34 +8,32 @@ require "base64"
|
|
6
8
|
require 'nokogiri'
|
7
9
|
require 'timeout'
|
8
10
|
|
9
|
-
|
11
|
+
#### Public Interface
|
12
|
+
|
13
|
+
# 'GiCatDriver::GiCat.new' creates a new GiCat object that provides an interface to many configuration options and controls available in GI-Cat.
|
14
|
+
#
|
10
15
|
module GiCatDriver
|
11
16
|
class GiCat
|
12
17
|
|
13
18
|
ATOM_NAMESPACE = { "atom" => "http://www.w3.org/2005/Atom" }
|
14
19
|
RELEVANCE_NAMESPACE = { "relevance" => "http://a9.com/-/opensearch/extensions/relevance/1.0/" }
|
15
|
-
attr_accessor :base_url
|
20
|
+
attr_accessor :base_url
|
16
21
|
|
17
22
|
def initialize( url, username, password )
|
18
23
|
@base_url = url.sub(/\/+$/, '')
|
19
24
|
@admin_username = username
|
20
25
|
@admin_password = password
|
21
|
-
|
22
|
-
|
26
|
+
|
27
|
+
# Set up a constant containing the standard request headers
|
28
|
+
self.class.const_set("STANDARD_HEADERS",{ :content_type => "application/xml", :Authorization => self.basic_auth_string })
|
23
29
|
end
|
24
30
|
|
31
|
+
# Basic Authorization used in the request headers
|
25
32
|
def basic_auth_string
|
26
33
|
"Basic " + Base64.encode64("#{@admin_username}:#{@admin_password}").rstrip
|
27
34
|
end
|
28
35
|
|
29
|
-
|
30
|
-
{
|
31
|
-
:content_type => "application/xml",
|
32
|
-
:Authorization => basic_auth_string
|
33
|
-
}
|
34
|
-
end
|
35
|
-
|
36
|
-
# Check whether the URL is accessible
|
36
|
+
# Check whether GI-Cat is accessible
|
37
37
|
def is_running?
|
38
38
|
open(@base_url).status[0] == "200"
|
39
39
|
end
|
@@ -42,7 +42,7 @@ module GiCatDriver
|
|
42
42
|
# Returns an integer ID reference to the profile
|
43
43
|
def find_profile_id( profile_name )
|
44
44
|
get_profiles_request = "#{@base_url}/services/conf/brokerConfigurations?nameRepository=gicat"
|
45
|
-
modified_headers =
|
45
|
+
modified_headers = STANDARD_HEADERS.merge({
|
46
46
|
:content_type => "*/*",
|
47
47
|
:Accept => 'application/xml'
|
48
48
|
})
|
@@ -58,26 +58,14 @@ module GiCatDriver
|
|
58
58
|
raise "The specified profile could not be found." if profile_id.nil?
|
59
59
|
activate_profile_request = "#{@base_url}/services/conf/brokerConfigurations/#{profile_id}?opts=active"
|
60
60
|
|
61
|
-
RestClient.get(activate_profile_request,
|
61
|
+
RestClient.get(activate_profile_request, STANDARD_HEADERS)
|
62
62
|
end
|
63
63
|
|
64
|
-
# Given a profile id, put all the associated resource id and title into harvest info array
|
65
|
-
def get_harvest_resources(profile_id)
|
66
|
-
id = get_active_profile_distributor_id(profile_id)
|
67
|
-
harvest_resource_request = "#{@base_url}/services/conf/brokerConfigurations/#{profile_id}/distributors/#{id}"
|
68
|
-
response = RestClient.get(harvest_resource_request, standard_headers)
|
69
|
-
doc = Nokogiri::XML(response)
|
70
|
-
doc.css("component").each do |component|
|
71
|
-
@harvestersinfo_array[component.css("id").text.to_sym] = component.css("title").text
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
# Retrieve the ID for the active profile
|
76
64
|
# Returns an integer ID reference to the active profile
|
77
65
|
def get_active_profile_id
|
78
66
|
active_profile_request = "#{@base_url}/services/conf/giconf/configuration"
|
79
67
|
|
80
|
-
return RestClient.get(active_profile_request,
|
68
|
+
return RestClient.get(active_profile_request, STANDARD_HEADERS)
|
81
69
|
end
|
82
70
|
|
83
71
|
# Enable Lucene indexes for GI-Cat search results
|
@@ -104,42 +92,31 @@ module GiCatDriver
|
|
104
92
|
return result_scores.count > 0
|
105
93
|
end
|
106
94
|
|
107
|
-
# Build the harvester resource id
|
108
|
-
def add_harvester_resource_id(resource_id)
|
109
|
-
@harvestersid_array.push(resource_id)
|
110
|
-
@harvestersinfo_array[resource_id.to_sym] = "default"
|
111
|
-
end
|
112
|
-
|
113
|
-
# Remove the harvester resourceinfo array
|
114
|
-
def clear_resource
|
115
|
-
@harvestersinfo_array.clear
|
116
|
-
end
|
117
|
-
|
118
95
|
# Harvest all resource in the active profile
|
119
96
|
def harvest_all_resources_for_active_configuration
|
120
|
-
get_harvest_resources(get_active_profile_id)
|
121
|
-
|
97
|
+
harvestersinfo_array = get_harvest_resources(get_active_profile_id)
|
98
|
+
harvestersinfo_array.each do |harvester_id, harvester_title|
|
122
99
|
harvest_resource_for_active_configuration(harvester_id.to_s, harvester_title)
|
123
100
|
end
|
101
|
+
confirm_harvest_done(harvestersinfo_array)
|
124
102
|
end
|
125
103
|
|
126
|
-
|
127
|
-
# The default timeout is 300 seconds (5 minutes)
|
128
|
-
def confirm_harvest_done(waitmax=300)
|
129
|
-
begin
|
130
|
-
puts "Info: Max wait time (timeout) for current profile is set to #{waitmax} seconds"
|
131
|
-
Timeout::timeout(waitmax) do
|
132
|
-
@harvestersinfo_array.each do |harvester_id, harvester_title|
|
133
|
-
havest_request_is_done(harvester_id.to_s, harvester_title)
|
134
|
-
end
|
135
|
-
end
|
136
|
-
rescue Timeout::Error
|
137
|
-
puts "Warning: re-harvest is time out(#{waitmax} seconds, we are going to reuse the previous harvest results"
|
138
|
-
end
|
139
|
-
end
|
104
|
+
#### Private Methods
|
140
105
|
|
141
106
|
private
|
142
107
|
|
108
|
+
# Toggle lucene indexes on when enabled is true, off when false
|
109
|
+
def set_lucene_enabled( enabled )
|
110
|
+
enable_lucene_request = "#{@base_url}/services/conf/brokerConfigurations/#{get_active_profile_id}/luceneEnabled"
|
111
|
+
RestClient.put(enable_lucene_request,
|
112
|
+
enabled.to_s,
|
113
|
+
STANDARD_HEADERS)
|
114
|
+
|
115
|
+
activate_profile_request = "#{@base_url}/services/conf/brokerConfigurations/#{get_active_profile_id}?opts=active"
|
116
|
+
RestClient.get(activate_profile_request,
|
117
|
+
STANDARD_HEADERS)
|
118
|
+
end
|
119
|
+
|
143
120
|
# Retrieve the profile element using the name
|
144
121
|
def parse_profile_element( profile_name, xml_doc )
|
145
122
|
configs = Nokogiri.XML(xml_doc)
|
@@ -150,63 +127,63 @@ module GiCatDriver
|
|
150
127
|
# Retrive the distributor id given a profile id
|
151
128
|
def get_active_profile_distributor_id(id)
|
152
129
|
active_profile_request = "#{@base_url}/services/conf/brokerConfigurations/#{id}"
|
153
|
-
response = RestClient.get(active_profile_request,
|
130
|
+
response = RestClient.get(active_profile_request, STANDARD_HEADERS)
|
154
131
|
id = Nokogiri::XML(response).css("component id").text
|
155
132
|
return id
|
156
133
|
end
|
157
134
|
|
158
|
-
#
|
159
|
-
def
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
135
|
+
# Given a profile id, put all the associated resource id and title into harvest info array
|
136
|
+
def get_harvest_resources(profile_id)
|
137
|
+
id = get_active_profile_distributor_id(profile_id)
|
138
|
+
harvest_resource_request = "#{@base_url}/services/conf/brokerConfigurations/#{profile_id}/distributors/#{id}"
|
139
|
+
response = RestClient.get(harvest_resource_request, STANDARD_HEADERS)
|
140
|
+
doc = Nokogiri::XML(response)
|
141
|
+
doc.css("component").each do |component|
|
142
|
+
harvestersinfo_array[component.css("id").text.to_sym] = component.css("title").text
|
143
|
+
end
|
144
|
+
return harvestersinfo_array
|
168
145
|
end
|
169
146
|
|
170
147
|
# Harvest from specified resource
|
171
148
|
def harvest_resource_for_active_configuration(harvesterid, harvestername = "n/a")
|
172
149
|
RestClient.get(
|
173
150
|
"#{@base_url}/services/conf/brokerConfigurations/#{self.get_active_profile_id}/harvesters/#{harvesterid}/start",
|
174
|
-
|
151
|
+
STANDARD_HEADERS) do |response, request, result, &block|
|
175
152
|
case response.code
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
153
|
+
when 200
|
154
|
+
puts "#{Time.now}: Initiate harvesting GI-Cat resource #{harvestername}. Please wait a couple minutes for the process to complete."
|
155
|
+
else
|
156
|
+
raise "Failed to initiate harvesting GI-Cat resource #{harvestername}."
|
157
|
+
response.return!(request, result, &block)
|
158
|
+
end
|
159
|
+
end
|
183
160
|
end
|
184
161
|
|
185
162
|
# Parsing and handle the harvest status
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
163
|
+
def harvest_status(status, harvestername="default")
|
164
|
+
timestamp = Time.now
|
165
|
+
puts "#{Time.now}: Harvest #{harvestername} status: #{status}"
|
166
|
+
case status
|
167
|
+
when /completed/
|
168
|
+
return :completed
|
169
|
+
when /error/
|
170
|
+
return :error
|
171
|
+
else
|
172
|
+
return :pending
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
199
176
|
# Run till the harvest of a resource is completed
|
200
177
|
def havest_request_is_done(harvesterid, harvestername="n/a")
|
201
178
|
while(1) do
|
202
179
|
rnum=rand
|
203
180
|
request = @base_url + "/services/conf/giconf/status?id=#{harvesterid}&rand=#{rnum}"
|
204
181
|
response = RestClient.get request
|
205
|
-
|
182
|
+
|
206
183
|
responsexml = Nokogiri::XML::Reader(response)
|
207
184
|
responsexml.each do |node|
|
208
|
-
if node.name == "status" && !node.inner_xml.empty?
|
209
|
-
case
|
185
|
+
if node.name == "status" && !node.inner_xml.empty?
|
186
|
+
case harvest_status(node.inner_xml, harvestername)
|
210
187
|
when :error
|
211
188
|
fail "Error harvesting the resource #{harvestername}: #{harvest_status}"
|
212
189
|
when :completed
|
@@ -217,5 +194,21 @@ module GiCatDriver
|
|
217
194
|
end
|
218
195
|
end
|
219
196
|
end
|
197
|
+
|
198
|
+
# Run till harvest all the resources are completed or time out
|
199
|
+
# The default timeout is 300 seconds (5 minutes)
|
200
|
+
def confirm_harvest_done(waitmax=300, harvestersinfo_array)
|
201
|
+
begin
|
202
|
+
puts "Info: Max wait time (timeout) for current profile is set to #{waitmax} seconds"
|
203
|
+
Timeout::timeout(waitmax) do
|
204
|
+
harvestersinfo_array.each do |harvester_id, harvester_title|
|
205
|
+
havest_request_is_done(harvester_id.to_s, harvester_title)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
rescue Timeout::Error
|
209
|
+
puts "Warning: re-harvest is time out(#{waitmax} seconds, we are going to reuse the previous harvest results"
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
220
213
|
end
|
221
214
|
end
|
data/spec/gi_cat_driver_spec.rb
CHANGED
@@ -7,19 +7,19 @@ describe GiCatDriver do
|
|
7
7
|
@gi_cat = GiCatDriver::GiCat.new(@base_url, "admin", "abcd123$")
|
8
8
|
end
|
9
9
|
|
10
|
-
describe "Standard requests" do
|
10
|
+
# describe "Standard requests" do
|
11
11
|
#it "Is able to send requests to GI-Cat" do
|
12
12
|
#@gi_cat.is_running?.should be_true
|
13
13
|
#end
|
14
14
|
|
15
|
-
it "Sends requests with basic header information" do
|
16
|
-
@gi_cat.standard_headers[:content_type].should eq "application/xml"
|
17
|
-
end
|
18
|
-
|
19
|
-
it "Can authorize access using the Authorization header" do
|
20
|
-
@gi_cat.standard_headers[:Authorization].should eq "Basic YWRtaW46YWJjZDEyMyQ="
|
21
|
-
end
|
22
|
-
end
|
15
|
+
# it "Sends requests with basic header information" do
|
16
|
+
# @gi_cat.standard_headers[:content_type].should eq "application/xml"
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# it "Can authorize access using the Authorization header" do
|
20
|
+
# @gi_cat.standard_headers[:Authorization].should eq "Basic YWRtaW46YWJjZDEyMyQ="
|
21
|
+
# end
|
22
|
+
# end
|
23
23
|
|
24
24
|
#describe "Profile management" do
|
25
25
|
#it "Retrieves a profile id given the name" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gi_cat_driver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -14,7 +14,7 @@ date: 2013-04-12 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rest-client
|
17
|
-
requirement:
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ~>
|
@@ -22,10 +22,15 @@ dependencies:
|
|
22
22
|
version: 1.6.7
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements:
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: 1.6.7
|
26
31
|
- !ruby/object:Gem::Dependency
|
27
32
|
name: nokogiri
|
28
|
-
requirement:
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
29
34
|
none: false
|
30
35
|
requirements:
|
31
36
|
- - ~>
|
@@ -33,10 +38,15 @@ dependencies:
|
|
33
38
|
version: 1.5.6
|
34
39
|
type: :runtime
|
35
40
|
prerelease: false
|
36
|
-
version_requirements:
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 1.5.6
|
37
47
|
- !ruby/object:Gem::Dependency
|
38
48
|
name: bundler
|
39
|
-
requirement:
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
40
50
|
none: false
|
41
51
|
requirements:
|
42
52
|
- - ~>
|
@@ -44,10 +54,15 @@ dependencies:
|
|
44
54
|
version: '1.3'
|
45
55
|
type: :development
|
46
56
|
prerelease: false
|
47
|
-
version_requirements:
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '1.3'
|
48
63
|
- !ruby/object:Gem::Dependency
|
49
64
|
name: rake
|
50
|
-
requirement:
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
51
66
|
none: false
|
52
67
|
requirements:
|
53
68
|
- - ~>
|
@@ -55,18 +70,44 @@ dependencies:
|
|
55
70
|
version: 10.0.3
|
56
71
|
type: :development
|
57
72
|
prerelease: false
|
58
|
-
version_requirements:
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ~>
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 10.0.3
|
59
79
|
- !ruby/object:Gem::Dependency
|
60
80
|
name: rspec
|
61
|
-
requirement:
|
81
|
+
requirement: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ~>
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: 2.13.0
|
87
|
+
type: :development
|
88
|
+
prerelease: false
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
62
90
|
none: false
|
63
91
|
requirements:
|
64
92
|
- - ~>
|
65
93
|
- !ruby/object:Gem::Version
|
66
94
|
version: 2.13.0
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: rocco
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ~>
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 0.8.1
|
67
103
|
type: :development
|
68
104
|
prerelease: false
|
69
|
-
version_requirements:
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.8.1
|
70
111
|
description: Configure and control deployed instances of GI-Cat.
|
71
112
|
email:
|
72
113
|
- stuart.reed@nsidc.org
|
@@ -110,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
151
|
version: '0'
|
111
152
|
requirements: []
|
112
153
|
rubyforge_project:
|
113
|
-
rubygems_version: 1.8.
|
154
|
+
rubygems_version: 1.8.23
|
114
155
|
signing_key:
|
115
156
|
specification_version: 3
|
116
157
|
summary: Configure and control deployed instances of GI-Cat.
|