govuk-registers-api-client 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|