sequence-sdk 2.1 → 2.2.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|