govuk-registers-api-client 1.0.0 → 1.0.1
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.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE.md +5 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +7 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +3 -0
- data/.version +1 -0
- data/Gemfile.lock +56 -0
- data/README.md +1 -1
- data/Rakefile +21 -0
- data/govuk-registers-api-client.gemspec +33 -0
- data/lib/data_store.rb +37 -0
- data/lib/entry.rb +51 -0
- data/lib/entry_collection.rb +25 -0
- data/lib/exceptions/invalid_hash_value_error.rb +5 -0
- data/lib/exceptions/invalid_register_error.rb +2 -0
- data/lib/in_memory_data_store.rb +106 -0
- data/lib/item.rb +47 -0
- data/lib/item_collection.rb +25 -0
- data/lib/record.rb +16 -0
- data/lib/record_collection.rb +25 -0
- data/lib/record_map_collection.rb +25 -0
- data/lib/register_client.rb +177 -0
- data/lib/register_client_manager.rb +1 -1
- metadata +22 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab771bc838779644bbd8763beea0c5a4c1138a298011af39a4ac4121068c3d40
|
4
|
+
data.tar.gz: ae34e34c99dc13883a2865393b54aa386fa04cf0174f835bfd60fa1dae582699
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cbe860777cef29b1ad7ba40fd47dcc3b10319eff06623637ad03deb83fd8e6771dd60c694acd92642c676270b78c9cfd631e4bda8e62d415bc232d858ea998ee
|
7
|
+
data.tar.gz: 735d24e0805542891a4cd14a0504b40455ad8e2d77921e267775abefbf07bb4b4d284c78146ee239b608e182e5f5ce569b5b09ec9fb1eb5b697d560c142257fe
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.5.0
|
data/.travis.yml
ADDED
data/.version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.1
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
addressable (2.5.2)
|
5
|
+
public_suffix (>= 2.0.2, < 4.0)
|
6
|
+
crack (0.4.3)
|
7
|
+
safe_yaml (~> 1.0.0)
|
8
|
+
diff-lcs (1.3)
|
9
|
+
domain_name (0.5.20170404)
|
10
|
+
unf (>= 0.0.5, < 1.0.0)
|
11
|
+
hashdiff (0.3.7)
|
12
|
+
http-cookie (1.0.3)
|
13
|
+
domain_name (~> 0.5)
|
14
|
+
mime-types (3.1)
|
15
|
+
mime-types-data (~> 3.2015)
|
16
|
+
mime-types-data (3.2016.0521)
|
17
|
+
netrc (0.11.0)
|
18
|
+
public_suffix (3.0.1)
|
19
|
+
rake (12.3.0)
|
20
|
+
rest-client (2.0.2)
|
21
|
+
http-cookie (>= 1.0.2, < 2.0)
|
22
|
+
mime-types (>= 1.16, < 4.0)
|
23
|
+
netrc (~> 0.8)
|
24
|
+
rspec (3.7.0)
|
25
|
+
rspec-core (~> 3.7.0)
|
26
|
+
rspec-expectations (~> 3.7.0)
|
27
|
+
rspec-mocks (~> 3.7.0)
|
28
|
+
rspec-core (3.7.0)
|
29
|
+
rspec-support (~> 3.7.0)
|
30
|
+
rspec-expectations (3.7.0)
|
31
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
32
|
+
rspec-support (~> 3.7.0)
|
33
|
+
rspec-mocks (3.7.0)
|
34
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
35
|
+
rspec-support (~> 3.7.0)
|
36
|
+
rspec-support (3.7.0)
|
37
|
+
safe_yaml (1.0.4)
|
38
|
+
unf (0.1.4)
|
39
|
+
unf_ext
|
40
|
+
unf_ext (0.0.7.4)
|
41
|
+
webmock (3.1.1)
|
42
|
+
addressable (>= 2.3.6)
|
43
|
+
crack (>= 0.3.2)
|
44
|
+
hashdiff
|
45
|
+
|
46
|
+
PLATFORMS
|
47
|
+
ruby
|
48
|
+
|
49
|
+
DEPENDENCIES
|
50
|
+
rake
|
51
|
+
rest-client (>= 2.0.1)
|
52
|
+
rspec (~> 3.7)
|
53
|
+
webmock
|
54
|
+
|
55
|
+
BUNDLED WITH
|
56
|
+
1.16.0
|
data/README.md
CHANGED
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rspec/core/rake_task'
|
8
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
9
|
+
t.rspec_opts = %w(--format documentation --colour)
|
10
|
+
end
|
11
|
+
|
12
|
+
task default: :spec
|
13
|
+
|
14
|
+
require 'rdoc/task'
|
15
|
+
RDoc::Task.new(:rdoc) do |rd|
|
16
|
+
rd.main = 'README.md'
|
17
|
+
rd.rdoc_files.include('README.md', 'lib/**/*.rb')
|
18
|
+
rd.rdoc_dir = 'rdoc'
|
19
|
+
end
|
20
|
+
|
21
|
+
Bundler::GemHelper.install_tasks
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# stub: govuk-registers-api-client 1.0.1 ruby lib
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "govuk-registers-api-client".freeze
|
6
|
+
s.version = File.read('.version').chomp
|
7
|
+
|
8
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
9
|
+
s.require_paths = ["lib".freeze]
|
10
|
+
s.authors = ["GOV.UK Registers Team (Government Digital Service)".freeze]
|
11
|
+
s.date = "2017-11-06"
|
12
|
+
s.email = "registers ~@nospam@~ digital.cabinet-office.gov.uk".freeze
|
13
|
+
s.extra_rdoc_files = ["README.md".freeze]
|
14
|
+
s.files = `git ls-files -z`.split("\x0").reject do |f|
|
15
|
+
f.match(%r{^(test|spec|features)/})
|
16
|
+
end
|
17
|
+
s.homepage = "https://github.com/openregister/govuk-registers-api-client".freeze
|
18
|
+
s.licenses = ["MIT".freeze]
|
19
|
+
s.rdoc_options = ["--main".freeze, "README.md".freeze]
|
20
|
+
s.rubygems_version = "2.6.12".freeze
|
21
|
+
s.summary = "Client library for GOV.UK Registers".freeze
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
s.specification_version = 4
|
25
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
26
|
+
s.add_runtime_dependency(%q<rest-client>.freeze, ["~> 2"])
|
27
|
+
else
|
28
|
+
s.add_dependency(%q<rest-client>.freeze, ["~> 2"])
|
29
|
+
end
|
30
|
+
else
|
31
|
+
s.add_dependency(%q<rest-client>.freeze, ["~> 2"])
|
32
|
+
end
|
33
|
+
end
|
data/lib/data_store.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module DataStore
|
2
|
+
def add_item(item)
|
3
|
+
end
|
4
|
+
|
5
|
+
def append_entry(entry)
|
6
|
+
end
|
7
|
+
|
8
|
+
def get_item(item_hash)
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_items
|
12
|
+
end
|
13
|
+
|
14
|
+
def get_entry(entry_type, entry_number)
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_entries(entry_type)
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_record(entry_type, key)
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_records(entry_type)
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_latest_entry_number(entry_type)
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_root_hash
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_root_hash(root_hash)
|
33
|
+
end
|
34
|
+
|
35
|
+
def after_load
|
36
|
+
end
|
37
|
+
end
|
data/lib/entry.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
module RegistersClient
|
2
|
+
class Entry
|
3
|
+
def initialize(rsf_line, entry_number, entry_type)
|
4
|
+
@rsf_line = rsf_line
|
5
|
+
@entry_number = entry_number
|
6
|
+
@entry_type = entry_type
|
7
|
+
|
8
|
+
@parsed_entry = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def entry_number
|
12
|
+
@entry_number
|
13
|
+
end
|
14
|
+
|
15
|
+
def key
|
16
|
+
get_entry[:key]
|
17
|
+
end
|
18
|
+
|
19
|
+
def timestamp
|
20
|
+
get_entry[:timestamp]
|
21
|
+
end
|
22
|
+
|
23
|
+
def item_hash
|
24
|
+
get_entry[:item_hash]
|
25
|
+
end
|
26
|
+
|
27
|
+
def entry_type
|
28
|
+
@entry_type
|
29
|
+
end
|
30
|
+
|
31
|
+
def value
|
32
|
+
get_entry
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def get_entry
|
38
|
+
@parsed_entry ||= parse_entry
|
39
|
+
@parsed_entry
|
40
|
+
end
|
41
|
+
|
42
|
+
def parse_entry
|
43
|
+
params = @rsf_line.split("\t")
|
44
|
+
|
45
|
+
# Deallocate rsf line
|
46
|
+
@rsf_line = nil
|
47
|
+
|
48
|
+
{ key: params[2], timestamp: params[3], item_hash: params[4] }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module RegistersClient
|
2
|
+
class EntryCollection
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize(data, page_size = 100)
|
6
|
+
@data = data
|
7
|
+
@page_size = page_size
|
8
|
+
end
|
9
|
+
|
10
|
+
def each
|
11
|
+
@data.each do |entry|
|
12
|
+
yield entry
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def page(page = 1)
|
17
|
+
if @data.length <= @page_size
|
18
|
+
@data
|
19
|
+
else
|
20
|
+
start_index = (page - 1) * @page_size
|
21
|
+
@data.slice(start_index, @page_size)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'data_store'
|
2
|
+
require 'date'
|
3
|
+
require 'record_collection'
|
4
|
+
require 'record_map_collection'
|
5
|
+
require 'entry_collection'
|
6
|
+
require 'item_collection'
|
7
|
+
require 'entry'
|
8
|
+
require 'item'
|
9
|
+
require 'record'
|
10
|
+
|
11
|
+
module RegistersClient
|
12
|
+
class InMemoryDataStore
|
13
|
+
include DataStore
|
14
|
+
|
15
|
+
EMPTY_ROOT_HASH = 'sha-256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
16
|
+
|
17
|
+
def initialize(config_options)
|
18
|
+
@config_options = config_options
|
19
|
+
|
20
|
+
@data = {
|
21
|
+
records: { user: {}, system: {} },
|
22
|
+
entries: { user: [], system: [] },
|
23
|
+
items: {},
|
24
|
+
root_hash: EMPTY_ROOT_HASH
|
25
|
+
}
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
def add_item(item)
|
30
|
+
@data[:items][item.hash.to_s] = item
|
31
|
+
end
|
32
|
+
|
33
|
+
def append_entry(entry)
|
34
|
+
entry_type = entry.entry_type == 'user' ? :user : :system
|
35
|
+
|
36
|
+
@data[:entries][entry_type] << entry
|
37
|
+
|
38
|
+
if !@data[:records][entry_type].key?(entry.key)
|
39
|
+
@data[:records][entry_type][entry.key] = []
|
40
|
+
end
|
41
|
+
|
42
|
+
@data[:records][entry_type][entry.key] << entry.entry_number
|
43
|
+
end
|
44
|
+
|
45
|
+
def get_item(item_hash)
|
46
|
+
@data[:items].has_key?(item_hash) ? @data[:items][item_hash] : nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_items
|
50
|
+
ItemCollection.new(@data[:items].values)
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_entry(entry_type, entry_number)
|
54
|
+
if (entry_number < 1 || entry_number > @data[:entries][entry_type].count)
|
55
|
+
nil
|
56
|
+
else
|
57
|
+
@data[:entries][entry_type][entry_number - 1]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_record(entry_type, key)
|
62
|
+
if (@data[:records][entry_type].has_key?(key))
|
63
|
+
record_entry_numbers = @data[:records][entry_type][key]
|
64
|
+
entry = get_data[:entries][entry_type][record_entry_numbers.last - 1]
|
65
|
+
|
66
|
+
Record.new(entry, get_data[:items][entry.item_hash])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def get_entries(entry_type)
|
71
|
+
EntryCollection.new(get_data[:entries][entry_type], @config_options.fetch(:page_size))
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_records(entry_type)
|
75
|
+
RecordCollection.new(get_data[:records][entry_type].map do |_k, record_entry_numbers|
|
76
|
+
entry = get_data[:entries][entry_type][record_entry_numbers.last - 1]
|
77
|
+
item = get_data[:items][entry.item_hash]
|
78
|
+
|
79
|
+
Record.new(entry, item)
|
80
|
+
end, @config_options.fetch(:page_size))
|
81
|
+
end
|
82
|
+
|
83
|
+
def get_latest_entry_number(entry_type)
|
84
|
+
entries = @data[:entries][entry_type]
|
85
|
+
entry = entries.any? ? entries.last : nil
|
86
|
+
entry.nil? ? 0 : entry.entry_number
|
87
|
+
end
|
88
|
+
|
89
|
+
def get_root_hash
|
90
|
+
@data[:root_hash]
|
91
|
+
end
|
92
|
+
|
93
|
+
def set_root_hash(root_hash)
|
94
|
+
@data[:root_hash] = root_hash
|
95
|
+
end
|
96
|
+
|
97
|
+
def after_load
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
def get_data
|
103
|
+
@data
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
data/lib/item.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module RegistersClient
|
4
|
+
class Item
|
5
|
+
def initialize(rsf_line)
|
6
|
+
@item_json = rsf_line.split("\t")[1]
|
7
|
+
@item_hash = 'sha-256:' + Digest::SHA256.hexdigest(@item_json)
|
8
|
+
|
9
|
+
@parsed_item = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def hash
|
13
|
+
@item_hash
|
14
|
+
end
|
15
|
+
|
16
|
+
def value
|
17
|
+
get_item
|
18
|
+
end
|
19
|
+
|
20
|
+
def has_end_date
|
21
|
+
if !@item_json.nil?
|
22
|
+
!@item_json.index("end-date").nil?
|
23
|
+
else
|
24
|
+
!@parsed_item['end-date'].nil?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def get_item
|
31
|
+
if @parsed_item.nil?
|
32
|
+
@parsed_item = parse_item
|
33
|
+
end
|
34
|
+
|
35
|
+
@parsed_item
|
36
|
+
end
|
37
|
+
|
38
|
+
def parse_item
|
39
|
+
parsed_item = JSON.parse(@item_json)
|
40
|
+
|
41
|
+
# Deallocate item JSON
|
42
|
+
@item_json = nil
|
43
|
+
|
44
|
+
parsed_item
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module RegistersClient
|
2
|
+
class ItemCollection
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize(data, page_size = 100)
|
6
|
+
@data = data
|
7
|
+
@page_size = page_size
|
8
|
+
end
|
9
|
+
|
10
|
+
def each
|
11
|
+
@data.each do |item|
|
12
|
+
yield item
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def page(page = 1)
|
17
|
+
if @data.length <= @page_size
|
18
|
+
@data
|
19
|
+
else
|
20
|
+
start_index = (page - 1) * @page_size
|
21
|
+
@data.slice(start_index, @page_size)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/record.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module RegistersClient
|
2
|
+
class RecordCollection
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize(data, page_size = 100)
|
6
|
+
@data = data
|
7
|
+
@page_size = page_size
|
8
|
+
end
|
9
|
+
|
10
|
+
def each
|
11
|
+
@data.each do |record|
|
12
|
+
yield record
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def page(page = 1)
|
17
|
+
if @data.length <= @page_size
|
18
|
+
@data
|
19
|
+
else
|
20
|
+
start_index = (page - 1) * @page_size
|
21
|
+
@data.slice(start_index, @page_size)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module RegistersClient
|
2
|
+
class RecordMapCollection
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize(data, page_size = 100)
|
6
|
+
@data = data
|
7
|
+
@page_size = page_size
|
8
|
+
end
|
9
|
+
|
10
|
+
def each
|
11
|
+
@data.each do |key,val|
|
12
|
+
result = {key: key, records: val}
|
13
|
+
yield result
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_records_for_key(key)
|
18
|
+
@data.fetch(key)
|
19
|
+
end
|
20
|
+
|
21
|
+
def paginator
|
22
|
+
@data.each_slice(@page_size)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
require 'json'
|
3
|
+
require 'exceptions/invalid_register_error'
|
4
|
+
require 'exceptions/invalid_hash_value_error'
|
5
|
+
|
6
|
+
module RegistersClient
|
7
|
+
class RegisterClient
|
8
|
+
def initialize(register_url, data_store, page_size)
|
9
|
+
@register_url = register_url
|
10
|
+
@data_store = data_store
|
11
|
+
@page_size = page_size
|
12
|
+
|
13
|
+
refresh_data
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_item(item_hash)
|
17
|
+
@data_store.get_item(item_hash)
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_items
|
21
|
+
@data_store.get_items
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_entry(entry_number)
|
25
|
+
@data_store.get_entry(:user, entry_number)
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_entries(since_entry_number = 0)
|
29
|
+
EntryCollection.new(get_entries_subset_for_entry_type(since_entry_number, :user), @page_size)
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_record(key)
|
33
|
+
@data_store.get_record(:user, key)
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_records
|
37
|
+
@data_store.get_records(:user)
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_metadata_records
|
41
|
+
@data_store.get_records(:system)
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_field_definitions
|
45
|
+
ordered_fields = get_register_definition.item.value['fields']
|
46
|
+
ordered_records = ordered_fields.map { |f| get_metadata_records.find { |record| record.entry.key == "field:#{f}" } }
|
47
|
+
@field_definitions ||= RecordCollection.new(ordered_records, @page_size)
|
48
|
+
@field_definitions
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_register_definition
|
52
|
+
get_metadata_records.select { |record| record.entry.key.start_with?('register:') }.first
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_custodian
|
56
|
+
get_metadata_records.select { |record| record.entry.key == 'custodian'}.first
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_records_with_history(since_entry_number = 0)
|
60
|
+
records_with_history = get_records_with_history_for_entry_type(since_entry_number, :user)
|
61
|
+
|
62
|
+
RecordMapCollection.new(records_with_history, @page_size)
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_metadata_records_with_history(since_entry_number = 0)
|
66
|
+
metadata_records_with_history = get_records_with_history_for_entry_type(since_entry_number, :system)
|
67
|
+
|
68
|
+
RecordMapCollection.new(metadata_records_with_history, @page_size)
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_current_records
|
72
|
+
RecordCollection.new(get_records.select { |record| !record.item.has_end_date }, @page_size)
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_expired_records
|
76
|
+
RecordCollection.new(get_records.select { |record| record.item.has_end_date }, @page_size)
|
77
|
+
end
|
78
|
+
|
79
|
+
def get_root_hash
|
80
|
+
root_hash = @data_store.get_root_hash
|
81
|
+
if !is_valid_hash_value(root_hash)
|
82
|
+
raise InvalidHashValueError
|
83
|
+
end
|
84
|
+
return root_hash
|
85
|
+
end
|
86
|
+
|
87
|
+
def refresh_data
|
88
|
+
user_entry_number = @data_store.get_latest_entry_number(:user)
|
89
|
+
rsf = download_rsf(user_entry_number)
|
90
|
+
|
91
|
+
validate_register_integrity(rsf, user_entry_number)
|
92
|
+
update_data_from_rsf(rsf, user_entry_number, @data_store)
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def get_entries_subset_for_entry_type(since_entry_number, entry_type)
|
98
|
+
start_index = !since_entry_number.nil? && since_entry_number > 0 ? since_entry_number : 0
|
99
|
+
current_entry_number = @data_store.get_latest_entry_number(entry_type)
|
100
|
+
length = current_entry_number - start_index
|
101
|
+
|
102
|
+
@data_store.get_entries(entry_type).to_a.slice(start_index, length)
|
103
|
+
end
|
104
|
+
|
105
|
+
def get_records_with_history_for_entry_type(since_entry_number, entry_type)
|
106
|
+
records_with_history = {}
|
107
|
+
|
108
|
+
get_entries_subset_for_entry_type(since_entry_number, entry_type).each do |entry|
|
109
|
+
if (!records_with_history.key?(entry.key))
|
110
|
+
records_with_history[entry.key] = []
|
111
|
+
end
|
112
|
+
|
113
|
+
item = @data_store.get_item(entry.item_hash)
|
114
|
+
records_with_history[entry.key] << Record.new(entry, item)
|
115
|
+
end
|
116
|
+
|
117
|
+
records_with_history
|
118
|
+
end
|
119
|
+
|
120
|
+
def get_register_proof
|
121
|
+
@register_proof = JSON.parse(register_http_request('proof/register/merkle:sha-256'))
|
122
|
+
end
|
123
|
+
|
124
|
+
def validate_register_integrity(rsf, current_entry_number)
|
125
|
+
rsf_lines = rsf.split("\n")
|
126
|
+
expected_root_hash = rsf_lines[0].split("\t")[1]
|
127
|
+
local_root_hash = @data_store.get_root_hash
|
128
|
+
|
129
|
+
if (local_root_hash != expected_root_hash)
|
130
|
+
raise InvalidRegisterError, 'Register has been reloaded with different data - root hashes do not match'
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def download_rsf(start_entry_number)
|
135
|
+
register_http_request("download-rsf/#{start_entry_number}")
|
136
|
+
end
|
137
|
+
|
138
|
+
def update_data_from_rsf(rsf, user_entry_number, data_store)
|
139
|
+
system_entry_number = @data_store.get_latest_entry_number(:system)
|
140
|
+
|
141
|
+
rsf.each_line do |line|
|
142
|
+
line.slice!("\n")
|
143
|
+
params = line.split("\t")
|
144
|
+
command = params[0]
|
145
|
+
|
146
|
+
if command == 'add-item'
|
147
|
+
data_store.add_item(RegistersClient::Item.new(line))
|
148
|
+
elsif command == 'append-entry'
|
149
|
+
if params[1] == 'user'
|
150
|
+
user_entry_number += 1
|
151
|
+
|
152
|
+
entry = Entry.new(line, user_entry_number, params[1])
|
153
|
+
else
|
154
|
+
system_entry_number += 1
|
155
|
+
|
156
|
+
entry = Entry.new(line, system_entry_number, params[1])
|
157
|
+
end
|
158
|
+
|
159
|
+
data_store.append_entry(entry)
|
160
|
+
elsif command == 'assert-root-hash'
|
161
|
+
root_hash = line.split("\t")[1]
|
162
|
+
data_store.set_root_hash(root_hash)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
data_store.after_load
|
167
|
+
end
|
168
|
+
|
169
|
+
def register_http_request(path)
|
170
|
+
RestClient.get(@register_url.merge(path).to_s)
|
171
|
+
end
|
172
|
+
|
173
|
+
def is_valid_hash_value(hash_value)
|
174
|
+
(/sha-256:+\h{64}/) === hash_value
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: govuk-registers-api-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GOV.UK Registers Team (Government Digital Service)
|
@@ -31,9 +31,30 @@ extensions: []
|
|
31
31
|
extra_rdoc_files:
|
32
32
|
- README.md
|
33
33
|
files:
|
34
|
+
- ".github/ISSUE_TEMPLATE.md"
|
35
|
+
- ".github/PULL_REQUEST_TEMPLATE.md"
|
36
|
+
- ".rspec"
|
37
|
+
- ".ruby-version"
|
38
|
+
- ".travis.yml"
|
39
|
+
- ".version"
|
34
40
|
- Gemfile
|
41
|
+
- Gemfile.lock
|
35
42
|
- LICENSE
|
36
43
|
- README.md
|
44
|
+
- Rakefile
|
45
|
+
- govuk-registers-api-client.gemspec
|
46
|
+
- lib/data_store.rb
|
47
|
+
- lib/entry.rb
|
48
|
+
- lib/entry_collection.rb
|
49
|
+
- lib/exceptions/invalid_hash_value_error.rb
|
50
|
+
- lib/exceptions/invalid_register_error.rb
|
51
|
+
- lib/in_memory_data_store.rb
|
52
|
+
- lib/item.rb
|
53
|
+
- lib/item_collection.rb
|
54
|
+
- lib/record.rb
|
55
|
+
- lib/record_collection.rb
|
56
|
+
- lib/record_map_collection.rb
|
57
|
+
- lib/register_client.rb
|
37
58
|
- lib/register_client_manager.rb
|
38
59
|
homepage: https://github.com/openregister/govuk-registers-api-client
|
39
60
|
licenses:
|