sequence-sdk 2.1 → 2.2.rc.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/lib/sequence/action.rb +11 -0
- data/lib/sequence/client.rb +22 -27
- data/lib/sequence/hello.rb +15 -0
- data/lib/sequence/index.rb +76 -0
- data/lib/sequence/session.rb +58 -9
- data/lib/sequence/version.rb +1 -1
- metadata +6 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6246691bbc9fe8915c626d2013e33c0dbb4950606d3a56a505365889e26c1660
|
4
|
+
data.tar.gz: 18be34a81476f9cb75855aef2126f68e2fa36f8849ea727e1bef278b40a442c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 88bbd9ececed4673dd0dc2547ca3e1feb1a02bcb5e23366dbe906f5106832f6da18c2c0114e2cd3de15bb50911569b929df56c75de597db773e39c329090a821
|
7
|
+
data.tar.gz: b4a4340dd743d635d52a17c6977e5ed589ed38b344026054337273fdb2d00f2d21aeeb7a0217aff0b12deedc10ef1e8f4c62fad5f69c55e4e0c4ff9b0d263e32
|
data/lib/sequence/action.rb
CHANGED
@@ -87,6 +87,17 @@ module Sequence
|
|
87
87
|
ListQuery.new(client, filter: filter, filter_params: filter_params)
|
88
88
|
end
|
89
89
|
|
90
|
+
# Update an action's tags.
|
91
|
+
# @param id [String]
|
92
|
+
# The ID of the action.
|
93
|
+
# @param tags [Hash]
|
94
|
+
# A new set of tags, which will replace the existing tags.
|
95
|
+
# @return [void]
|
96
|
+
def update_tags(id:, tags: nil)
|
97
|
+
raise ArgumentError, ':id cannot be blank' if id == ''
|
98
|
+
client.session.request('update-action-tags', id: id, tags: tags)
|
99
|
+
end
|
100
|
+
|
90
101
|
# Execute a query, returning an enumerable over sums of actions.
|
91
102
|
# @param filter [String]
|
92
103
|
# A filter expression.
|
data/lib/sequence/client.rb
CHANGED
@@ -6,6 +6,7 @@ require_relative './dev_utils'
|
|
6
6
|
require_relative './feed'
|
7
7
|
require_relative './flavor'
|
8
8
|
require_relative './http_wrapper'
|
9
|
+
require_relative './index'
|
9
10
|
require_relative './key'
|
10
11
|
require_relative './stats'
|
11
12
|
require_relative './token'
|
@@ -28,14 +29,11 @@ module Sequence
|
|
28
29
|
raise ArgumentError, ':credential cannot be blank'
|
29
30
|
end
|
30
31
|
|
31
|
-
addr = ENV['SEQADDR'] || 'api.seq.com'
|
32
|
-
api = HttpWrapper.new('https://' + addr, credential)
|
33
32
|
@opts = {
|
34
|
-
addr: addr,
|
35
33
|
credential: credential,
|
36
34
|
ledger_name: ledger_name,
|
37
|
-
team_name: team_name(api),
|
38
35
|
}
|
36
|
+
@session = Session.new(@opts)
|
39
37
|
end
|
40
38
|
|
41
39
|
# @private
|
@@ -45,23 +43,31 @@ module Sequence
|
|
45
43
|
|
46
44
|
# @private
|
47
45
|
# @return [Session]
|
48
|
-
|
49
|
-
@session ||= Session.new(@opts)
|
50
|
-
end
|
46
|
+
attr_reader :session
|
51
47
|
|
52
48
|
# @return [Account::ClientModule]
|
53
49
|
def accounts
|
54
50
|
@accounts ||= Account::ClientModule.new(self)
|
55
51
|
end
|
56
52
|
|
53
|
+
# @return [Action::ClientModule]
|
54
|
+
def actions
|
55
|
+
@actions ||= Action::ClientModule.new(self)
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [Feed::ClientModule]
|
59
|
+
def feeds
|
60
|
+
@feeds ||= Feed::ClientModule.new(self)
|
61
|
+
end
|
62
|
+
|
57
63
|
# @return [Flavor::ClientModule]
|
58
64
|
def flavors
|
59
65
|
@flavors ||= Flavor::ClientModule.new(self)
|
60
66
|
end
|
61
67
|
|
62
|
-
# @return [
|
63
|
-
def
|
64
|
-
@
|
68
|
+
# @return [Index::ClientModule]
|
69
|
+
def indexes
|
70
|
+
@indexes ||= Index::ClientModule.new(self)
|
65
71
|
end
|
66
72
|
|
67
73
|
# @return [Key::ClientModule]
|
@@ -69,6 +75,12 @@ module Sequence
|
|
69
75
|
@keys ||= Key::ClientModule.new(self)
|
70
76
|
end
|
71
77
|
|
78
|
+
# @private
|
79
|
+
# @return [Stats::ClientModule]
|
80
|
+
def stats
|
81
|
+
@stats ||= Stats::ClientModule.new(self)
|
82
|
+
end
|
83
|
+
|
72
84
|
# @return [Token::ClientModule]
|
73
85
|
def tokens
|
74
86
|
@tokens ||= Token::ClientModule.new(self)
|
@@ -79,26 +91,9 @@ module Sequence
|
|
79
91
|
@transactions ||= Transaction::ClientModule.new(self)
|
80
92
|
end
|
81
93
|
|
82
|
-
# @return [Feed::ClientModule]
|
83
|
-
def feeds
|
84
|
-
@feeds ||= Feed::ClientModule.new(self)
|
85
|
-
end
|
86
|
-
|
87
|
-
# @private
|
88
|
-
# @return [Stats::ClientModule]
|
89
|
-
def stats
|
90
|
-
@stats ||= Stats::ClientModule.new(self)
|
91
|
-
end
|
92
|
-
|
93
94
|
# @return [DevUtils::ClientModule]
|
94
95
|
def dev_utils
|
95
96
|
@dev_utils ||= DevUtils::ClientModule.new(self)
|
96
97
|
end
|
97
|
-
|
98
|
-
private
|
99
|
-
|
100
|
-
def team_name(api)
|
101
|
-
api.post(SecureRandom.hex(10), '/hello', {})[:parsed_body]['team_name']
|
102
|
-
end
|
103
98
|
end
|
104
99
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sequence
|
4
|
+
# @private
|
5
|
+
class Hello
|
6
|
+
def initialize(api)
|
7
|
+
@api = api
|
8
|
+
end
|
9
|
+
|
10
|
+
def call
|
11
|
+
b = @api.post(SecureRandom.hex(10), '/hello', {})[:parsed_body]
|
12
|
+
[b['team_name'], b['addr'], b['addr_ttl_seconds'].to_i]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './client_module'
|
4
|
+
require_relative './session'
|
5
|
+
require_relative './query'
|
6
|
+
require_relative './response_object'
|
7
|
+
|
8
|
+
module Sequence
|
9
|
+
# Indexes are used to precompute queries that could
|
10
|
+
# potentially be slow. When an application submits a
|
11
|
+
# query where the filter and group-by params match
|
12
|
+
# one of the defined indexes, the results can be
|
13
|
+
# returned from quickly from precomputed storage.
|
14
|
+
class Index < ResponseObject
|
15
|
+
# @!attribute [r] id
|
16
|
+
# Unique identifier of the index
|
17
|
+
# @return [String]
|
18
|
+
attrib :id
|
19
|
+
|
20
|
+
# @!attribute [r] type
|
21
|
+
# Type of index, "action" or "token".
|
22
|
+
# @return [String]
|
23
|
+
attrib :type
|
24
|
+
|
25
|
+
# @!attribute [r] filter
|
26
|
+
# The query filter used to select matching items.
|
27
|
+
# @return [String]
|
28
|
+
attrib :filter
|
29
|
+
|
30
|
+
# @!attribute [r] group_by
|
31
|
+
# Token/Action object fields to group by.
|
32
|
+
# @return [String]
|
33
|
+
attrib :group_by
|
34
|
+
|
35
|
+
class ClientModule < Sequence::ClientModule
|
36
|
+
# Create an index.
|
37
|
+
# @param id [String]
|
38
|
+
# Unique identifier. Auto-generated if not specified.
|
39
|
+
# @return [Index]
|
40
|
+
def create(id: nil, type:, filter:, group_by: [])
|
41
|
+
Index.new(client.session.request(
|
42
|
+
'create-index',
|
43
|
+
id: id,
|
44
|
+
type: type,
|
45
|
+
filter: filter,
|
46
|
+
group_by: group_by,
|
47
|
+
))
|
48
|
+
end
|
49
|
+
|
50
|
+
# Delete index by id.
|
51
|
+
# @option id [String] The unique ID of an index.
|
52
|
+
# @return [void]
|
53
|
+
def delete(id:)
|
54
|
+
client.session.request('delete-index', id: id)
|
55
|
+
nil
|
56
|
+
end
|
57
|
+
|
58
|
+
# List all indexes.
|
59
|
+
# Executes a query, returning an enumerable over individual indexes.
|
60
|
+
# @return [Query]
|
61
|
+
def list
|
62
|
+
Query.new(client)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class Query < Sequence::Query
|
67
|
+
def fetch(query)
|
68
|
+
client.session.request('list-indexes', query)
|
69
|
+
end
|
70
|
+
|
71
|
+
def translate(obj)
|
72
|
+
Index.new(obj)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/sequence/session.rb
CHANGED
@@ -5,6 +5,7 @@ require 'json'
|
|
5
5
|
require_relative './http_wrapper'
|
6
6
|
require_relative './errors'
|
7
7
|
require_relative './version'
|
8
|
+
require_relative './hello'
|
8
9
|
|
9
10
|
module Sequence
|
10
11
|
# @private
|
@@ -19,11 +20,11 @@ module Sequence
|
|
19
20
|
ArgumentError,
|
20
21
|
'missing credential',
|
21
22
|
)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
)
|
26
|
-
@
|
23
|
+
|
24
|
+
@lock = Mutex.new # protects the following instance variables
|
25
|
+
@team_name, @addr, ttl_seconds = hello.call
|
26
|
+
@api = api(@addr)
|
27
|
+
@deadline = now + ttl_seconds
|
27
28
|
end
|
28
29
|
|
29
30
|
def dup
|
@@ -36,7 +37,20 @@ module Sequence
|
|
36
37
|
|
37
38
|
def request_full_resp(id, path, body = {})
|
38
39
|
id ||= SecureRandom.hex(10)
|
39
|
-
|
40
|
+
deadline = nil
|
41
|
+
api = nil
|
42
|
+
|
43
|
+
@lock.synchronize do
|
44
|
+
deadline = @deadline
|
45
|
+
api = @api
|
46
|
+
path = "/#{@team_name}/#{@ledger}/#{path}".gsub('//', '/')
|
47
|
+
end
|
48
|
+
|
49
|
+
if now >= deadline
|
50
|
+
refresh
|
51
|
+
end
|
52
|
+
|
53
|
+
api.post(id, path, body) do |response|
|
40
54
|
# require that the response contains the Chain-Request-ID
|
41
55
|
# http header. Since the Sequence API will always set this
|
42
56
|
# header, its absence indicates that the request stopped at
|
@@ -52,9 +66,44 @@ module Sequence
|
|
52
66
|
|
53
67
|
private
|
54
68
|
|
55
|
-
def
|
56
|
-
|
57
|
-
|
69
|
+
def refresh
|
70
|
+
Thread.new do
|
71
|
+
# extend the deadline long enough to get a fresh addr
|
72
|
+
@lock.synchronize do
|
73
|
+
@deadline = now + HttpWrapper::RETRY_TIMEOUT_SECS
|
74
|
+
end
|
75
|
+
|
76
|
+
begin
|
77
|
+
new_team_name, new_addr, ttl_seconds = hello.call
|
78
|
+
rescue StandardError # rubocop:disable Lint/HandleExceptions
|
79
|
+
# use existing values while trying for a successful /hello
|
80
|
+
else
|
81
|
+
@lock.synchronize do
|
82
|
+
@deadline = now + ttl_seconds
|
83
|
+
|
84
|
+
# unless addr changed, use existing API client
|
85
|
+
# in order to re-use the TLS connection
|
86
|
+
if @addr != new_addr
|
87
|
+
@addr = new_addr
|
88
|
+
@api = api(new_addr)
|
89
|
+
end
|
90
|
+
|
91
|
+
@team_name = new_team_name
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def now
|
98
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC).to_i
|
99
|
+
end
|
100
|
+
|
101
|
+
def hello
|
102
|
+
Sequence::Hello.new(api(ENV['SEQADDR'] || 'api.seq.com'))
|
103
|
+
end
|
104
|
+
|
105
|
+
def api(addr)
|
106
|
+
HttpWrapper.new('https://' + addr, @credential, @opts)
|
58
107
|
end
|
59
108
|
end
|
60
109
|
end
|
data/lib/sequence/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequence-sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.2.rc.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chain Engineering
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-07-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -86,20 +86,6 @@ dependencies:
|
|
86
86
|
- - "~>"
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: 0.14.1
|
89
|
-
- !ruby/object:Gem::Dependency
|
90
|
-
name: webmock
|
91
|
-
requirement: !ruby/object:Gem::Requirement
|
92
|
-
requirements:
|
93
|
-
- - "~>"
|
94
|
-
- !ruby/object:Gem::Version
|
95
|
-
version: 2.3.2
|
96
|
-
type: :development
|
97
|
-
prerelease: false
|
98
|
-
version_requirements: !ruby/object:Gem::Requirement
|
99
|
-
requirements:
|
100
|
-
- - "~>"
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
version: 2.3.2
|
103
89
|
- !ruby/object:Gem::Dependency
|
104
90
|
name: yard
|
105
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -137,7 +123,9 @@ files:
|
|
137
123
|
- lib/sequence/errors.rb
|
138
124
|
- lib/sequence/feed.rb
|
139
125
|
- lib/sequence/flavor.rb
|
126
|
+
- lib/sequence/hello.rb
|
140
127
|
- lib/sequence/http_wrapper.rb
|
128
|
+
- lib/sequence/index.rb
|
141
129
|
- lib/sequence/key.rb
|
142
130
|
- lib/sequence/page.rb
|
143
131
|
- lib/sequence/query.rb
|
@@ -162,9 +150,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
162
150
|
version: '2.3'
|
163
151
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
164
152
|
requirements:
|
165
|
-
- - "
|
153
|
+
- - ">"
|
166
154
|
- !ruby/object:Gem::Version
|
167
|
-
version:
|
155
|
+
version: 1.3.1
|
168
156
|
requirements: []
|
169
157
|
rubyforge_project:
|
170
158
|
rubygems_version: 2.7.6
|