statelydb 0.1.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 +7 -0
- data/lib/api/db/continue_list_pb.rb +18 -0
- data/lib/api/db/delete_pb.rb +20 -0
- data/lib/api/db/get_pb.rb +21 -0
- data/lib/api/db/item_pb.rb +19 -0
- data/lib/api/db/item_property_pb.rb +17 -0
- data/lib/api/db/list_pb.rb +25 -0
- data/lib/api/db/list_token_pb.rb +17 -0
- data/lib/api/db/put_pb.rb +21 -0
- data/lib/api/db/scan_root_paths_pb.rb +19 -0
- data/lib/api/db/service_pb.rb +25 -0
- data/lib/api/db/service_services_pb.rb +101 -0
- data/lib/api/db/sync_list_pb.rb +24 -0
- data/lib/api/db/transaction_pb.rb +38 -0
- data/lib/api/errors/error_details_pb.rb +17 -0
- data/lib/common/auth/auth0_token_provider.rb +124 -0
- data/lib/common/auth/interceptor.rb +82 -0
- data/lib/common/auth/token_provider.rb +18 -0
- data/lib/common/error_interceptor.rb +39 -0
- data/lib/common/net/conn.rb +26 -0
- data/lib/error.rb +62 -0
- data/lib/key_path.rb +67 -0
- data/lib/statelydb.rb +333 -0
- data/lib/token.rb +34 -0
- data/lib/transaction/queue.rb +44 -0
- data/lib/transaction/transaction.rb +398 -0
- data/lib/uuid.rb +68 -0
- metadata +111 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5716a868b12a20de48e33bddf16396bac216172edc29ee5302eb3477380c7943
|
4
|
+
data.tar.gz: 98ca1b24cd5bdaa79409de8bf36e10bc573bc6c0b80bf8194bb08eeddc91cf0a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 13a52d97a5ac5c309a3249dcbd1f5cb15392edc40c87a65a34064be54dfc44e5d6dd5ed6bff63fd4793f6e85297dbff92660fdc50a490d994c4af41e4ed9159c
|
7
|
+
data.tar.gz: cb8ce77af551b2c015c06ab75114517fe05376c26f1d8b228dde017b25da3685d7d8ee551bc140b50dc15fe06982618d485aab43dc88e7f63ebd47bdbd04769c
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
# source: db/continue_list.proto
|
4
|
+
|
5
|
+
require 'google/protobuf'
|
6
|
+
|
7
|
+
|
8
|
+
descriptor_data = "\n\x16\x64\x62/continue_list.proto\x12\nstately.db\"u\n\x13\x43ontinueListRequest\x12\x1d\n\ntoken_data\x18\x01 \x01(\x0cR\ttokenData\x12?\n\tdirection\x18\x02 \x01(\x0e\x32!.stately.db.ContinueListDirectionR\tdirection*N\n\x15\x43ontinueListDirection\x12\x19\n\x15\x43ONTINUE_LIST_FORWARD\x10\x00\x12\x1a\n\x16\x43ONTINUE_LIST_BACKWARD\x10\x01\x42l\n\x0e\x63om.stately.dbB\x11\x43ontinueListProtoP\x01\xa2\x02\x03SDX\xaa\x02\nStately.Db\xca\x02\nStately\\Db\xe2\x02\x16Stately\\Db\\GPBMetadata\xea\x02\x0bStately::Dbb\x06proto3"
|
9
|
+
|
10
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
11
|
+
pool.add_serialized_file(descriptor_data)
|
12
|
+
|
13
|
+
module Stately
|
14
|
+
module Db
|
15
|
+
ContinueListRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.ContinueListRequest").msgclass
|
16
|
+
ContinueListDirection = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.ContinueListDirection").enummodule
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
# source: db/delete.proto
|
4
|
+
|
5
|
+
require 'google/protobuf'
|
6
|
+
|
7
|
+
|
8
|
+
descriptor_data = "\n\x0f\x64\x62/delete.proto\x12\nstately.db\"b\n\rDeleteRequest\x12\x19\n\x08store_id\x18\x01 \x01(\x04R\x07storeId\x12\x30\n\x07\x64\x65letes\x18\x03 \x03(\x0b\x32\x16.stately.db.DeleteItemR\x07\x64\x65letesJ\x04\x08\x04\x10\x05\"\'\n\nDeleteItem\x12\x19\n\x08key_path\x18\x01 \x01(\tR\x07keyPath\"/\n\x0c\x44\x65leteResult\x12\x19\n\x08key_path\x18\x01 \x01(\tR\x07keyPathJ\x04\x08\x02\x10\x03\"D\n\x0e\x44\x65leteResponse\x12\x32\n\x07results\x18\x01 \x03(\x0b\x32\x18.stately.db.DeleteResultR\x07resultsBf\n\x0e\x63om.stately.dbB\x0b\x44\x65leteProtoP\x01\xa2\x02\x03SDX\xaa\x02\nStately.Db\xca\x02\nStately\\Db\xe2\x02\x16Stately\\Db\\GPBMetadata\xea\x02\x0bStately::Dbb\x06proto3"
|
9
|
+
|
10
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
11
|
+
pool.add_serialized_file(descriptor_data)
|
12
|
+
|
13
|
+
module Stately
|
14
|
+
module Db
|
15
|
+
DeleteRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.DeleteRequest").msgclass
|
16
|
+
DeleteItem = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.DeleteItem").msgclass
|
17
|
+
DeleteResult = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.DeleteResult").msgclass
|
18
|
+
DeleteResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.DeleteResponse").msgclass
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
# source: db/get.proto
|
4
|
+
|
5
|
+
require 'google/protobuf'
|
6
|
+
|
7
|
+
require 'db/item_pb'
|
8
|
+
|
9
|
+
|
10
|
+
descriptor_data = "\n\x0c\x64\x62/get.proto\x12\nstately.db\x1a\rdb/item.proto\"w\n\nGetRequest\x12\x19\n\x08store_id\x18\x01 \x01(\x04R\x07storeId\x12\'\n\x04gets\x18\x02 \x03(\x0b\x32\x13.stately.db.GetItemR\x04gets\x12\x1f\n\x0b\x61llow_stale\x18\x03 \x01(\x08R\nallowStaleJ\x04\x08\x04\x10\x05\"$\n\x07GetItem\x12\x19\n\x08key_path\x18\x01 \x01(\tR\x07keyPath\"5\n\x0bGetResponse\x12&\n\x05items\x18\x01 \x03(\x0b\x32\x10.stately.db.ItemR\x05itemsBc\n\x0e\x63om.stately.dbB\x08GetProtoP\x01\xa2\x02\x03SDX\xaa\x02\nStately.Db\xca\x02\nStately\\Db\xe2\x02\x16Stately\\Db\\GPBMetadata\xea\x02\x0bStately::Dbb\x06proto3"
|
11
|
+
|
12
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
13
|
+
pool.add_serialized_file(descriptor_data)
|
14
|
+
|
15
|
+
module Stately
|
16
|
+
module Db
|
17
|
+
GetRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.GetRequest").msgclass
|
18
|
+
GetItem = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.GetItem").msgclass
|
19
|
+
GetResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.GetResponse").msgclass
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
# source: db/item.proto
|
4
|
+
|
5
|
+
require 'google/protobuf'
|
6
|
+
|
7
|
+
require 'google/protobuf/struct_pb'
|
8
|
+
|
9
|
+
|
10
|
+
descriptor_data = "\n\rdb/item.proto\x12\nstately.db\x1a\x1cgoogle/protobuf/struct.proto\"u\n\x04Item\x12\x1b\n\titem_type\x18\x01 \x01(\tR\x08itemType\x12\x16\n\x05proto\x18\x02 \x01(\x0cH\x00R\x05proto\x12-\n\x04json\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructH\x00R\x04jsonB\t\n\x07payloadBd\n\x0e\x63om.stately.dbB\tItemProtoP\x01\xa2\x02\x03SDX\xaa\x02\nStately.Db\xca\x02\nStately\\Db\xe2\x02\x16Stately\\Db\\GPBMetadata\xea\x02\x0bStately::Dbb\x06proto3"
|
11
|
+
|
12
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
13
|
+
pool.add_serialized_file(descriptor_data)
|
14
|
+
|
15
|
+
module Stately
|
16
|
+
module Db
|
17
|
+
Item = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.Item").msgclass
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
# source: db/item_property.proto
|
4
|
+
|
5
|
+
require 'google/protobuf'
|
6
|
+
|
7
|
+
|
8
|
+
descriptor_data = "\n\x16\x64\x62/item_property.proto\x12\nstately.db*\x8b\x02\n\x10SortableProperty\x12\x1e\n\x1aSORTABLE_PROPERTY_KEY_PATH\x10\x00\x12+\n\'SORTABLE_PROPERTY_LAST_MODIFIED_VERSION\x10\x01\x12)\n%SORTABLE_PROPERTY_GROUP_LOCAL_INDEX_1\x10\x08\x12)\n%SORTABLE_PROPERTY_GROUP_LOCAL_INDEX_2\x10\t\x12)\n%SORTABLE_PROPERTY_GROUP_LOCAL_INDEX_3\x10\n\x12)\n%SORTABLE_PROPERTY_GROUP_LOCAL_INDEX_4\x10\x0b\x42l\n\x0e\x63om.stately.dbB\x11ItemPropertyProtoP\x01\xa2\x02\x03SDX\xaa\x02\nStately.Db\xca\x02\nStately\\Db\xe2\x02\x16Stately\\Db\\GPBMetadata\xea\x02\x0bStately::Dbb\x06proto3"
|
9
|
+
|
10
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
11
|
+
pool.add_serialized_file(descriptor_data)
|
12
|
+
|
13
|
+
module Stately
|
14
|
+
module Db
|
15
|
+
SortableProperty = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.SortableProperty").enummodule
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
# source: db/list.proto
|
4
|
+
|
5
|
+
require 'google/protobuf'
|
6
|
+
|
7
|
+
require 'db/item_pb'
|
8
|
+
require 'db/item_property_pb'
|
9
|
+
require 'db/list_token_pb'
|
10
|
+
|
11
|
+
|
12
|
+
descriptor_data = "\n\rdb/list.proto\x12\nstately.db\x1a\rdb/item.proto\x1a\x16\x64\x62/item_property.proto\x1a\x13\x64\x62/list_token.proto\"\x91\x02\n\x10\x42\x65ginListRequest\x12\x19\n\x08store_id\x18\x01 \x01(\x04R\x07storeId\x12&\n\x0fkey_path_prefix\x18\x02 \x01(\tR\rkeyPathPrefix\x12\x14\n\x05limit\x18\x03 \x01(\rR\x05limit\x12\x1f\n\x0b\x61llow_stale\x18\x04 \x01(\x08R\nallowStale\x12\x41\n\rsort_property\x18\x05 \x01(\x0e\x32\x1c.stately.db.SortablePropertyR\x0csortProperty\x12@\n\x0esort_direction\x18\x06 \x01(\x0e\x32\x19.stately.db.SortDirectionR\rsortDirection\"\x8b\x01\n\x0cListResponse\x12\x37\n\x06result\x18\x01 \x01(\x0b\x32\x1d.stately.db.ListPartialResultH\x00R\x06result\x12\x36\n\x08\x66inished\x18\x02 \x01(\x0b\x32\x18.stately.db.ListFinishedH\x00R\x08\x66inishedB\n\n\x08response\";\n\x11ListPartialResult\x12&\n\x05items\x18\x01 \x03(\x0b\x32\x10.stately.db.ItemR\x05items\";\n\x0cListFinished\x12+\n\x05token\x18\x01 \x01(\x0b\x32\x15.stately.db.ListTokenR\x05token*8\n\rSortDirection\x12\x12\n\x0eSORT_ASCENDING\x10\x00\x12\x13\n\x0fSORT_DESCENDING\x10\x01\x42\x64\n\x0e\x63om.stately.dbB\tListProtoP\x01\xa2\x02\x03SDX\xaa\x02\nStately.Db\xca\x02\nStately\\Db\xe2\x02\x16Stately\\Db\\GPBMetadata\xea\x02\x0bStately::Dbb\x06proto3"
|
13
|
+
|
14
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
15
|
+
pool.add_serialized_file(descriptor_data)
|
16
|
+
|
17
|
+
module Stately
|
18
|
+
module Db
|
19
|
+
BeginListRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.BeginListRequest").msgclass
|
20
|
+
ListResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.ListResponse").msgclass
|
21
|
+
ListPartialResult = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.ListPartialResult").msgclass
|
22
|
+
ListFinished = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.ListFinished").msgclass
|
23
|
+
SortDirection = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.SortDirection").enummodule
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
# source: db/list_token.proto
|
4
|
+
|
5
|
+
require 'google/protobuf'
|
6
|
+
|
7
|
+
|
8
|
+
descriptor_data = "\n\x13\x64\x62/list_token.proto\x12\nstately.db\"h\n\tListToken\x12\x1d\n\ntoken_data\x18\x01 \x01(\x0cR\ttokenData\x12!\n\x0c\x63\x61n_continue\x18\x02 \x01(\x08R\x0b\x63\x61nContinue\x12\x19\n\x08\x63\x61n_sync\x18\x03 \x01(\x08R\x07\x63\x61nSyncBi\n\x0e\x63om.stately.dbB\x0eListTokenProtoP\x01\xa2\x02\x03SDX\xaa\x02\nStately.Db\xca\x02\nStately\\Db\xe2\x02\x16Stately\\Db\\GPBMetadata\xea\x02\x0bStately::Dbb\x06proto3"
|
9
|
+
|
10
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
11
|
+
pool.add_serialized_file(descriptor_data)
|
12
|
+
|
13
|
+
module Stately
|
14
|
+
module Db
|
15
|
+
ListToken = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.ListToken").msgclass
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
# source: db/put.proto
|
4
|
+
|
5
|
+
require 'google/protobuf'
|
6
|
+
|
7
|
+
require 'db/item_pb'
|
8
|
+
|
9
|
+
|
10
|
+
descriptor_data = "\n\x0c\x64\x62/put.proto\x12\nstately.db\x1a\rdb/item.proto\"P\n\nPutRequest\x12\x19\n\x08store_id\x18\x01 \x01(\x04R\x07storeId\x12\'\n\x04puts\x18\x02 \x03(\x0b\x32\x13.stately.db.PutItemR\x04puts\"/\n\x07PutItem\x12$\n\x04item\x18\x01 \x01(\x0b\x32\x10.stately.db.ItemR\x04item\"5\n\x0bPutResponse\x12&\n\x05items\x18\x01 \x03(\x0b\x32\x10.stately.db.ItemR\x05itemsBc\n\x0e\x63om.stately.dbB\x08PutProtoP\x01\xa2\x02\x03SDX\xaa\x02\nStately.Db\xca\x02\nStately\\Db\xe2\x02\x16Stately\\Db\\GPBMetadata\xea\x02\x0bStately::Dbb\x06proto3"
|
11
|
+
|
12
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
13
|
+
pool.add_serialized_file(descriptor_data)
|
14
|
+
|
15
|
+
module Stately
|
16
|
+
module Db
|
17
|
+
PutRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.PutRequest").msgclass
|
18
|
+
PutItem = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.PutItem").msgclass
|
19
|
+
PutResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.PutResponse").msgclass
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
# source: db/scan_root_paths.proto
|
4
|
+
|
5
|
+
require 'google/protobuf'
|
6
|
+
|
7
|
+
|
8
|
+
descriptor_data = "\n\x18\x64\x62/scan_root_paths.proto\x12\nstately.db\"r\n\x14ScanRootPathsRequest\x12\x19\n\x08store_id\x18\x01 \x01(\x04R\x07storeId\x12\x14\n\x05limit\x18\x02 \x01(\rR\x05limit\x12)\n\x10pagination_token\x18\x03 \x01(\x0cR\x0fpaginationToken\"|\n\x15ScanRootPathsResponse\x12\x38\n\x07results\x18\x01 \x03(\x0b\x32\x1e.stately.db.ScanRootPathResultR\x07results\x12)\n\x10pagination_token\x18\x02 \x01(\x0cR\x0fpaginationToken\"/\n\x12ScanRootPathResult\x12\x19\n\x08key_path\x18\x01 \x01(\tR\x07keyPathBm\n\x0e\x63om.stately.dbB\x12ScanRootPathsProtoP\x01\xa2\x02\x03SDX\xaa\x02\nStately.Db\xca\x02\nStately\\Db\xe2\x02\x16Stately\\Db\\GPBMetadata\xea\x02\x0bStately::Dbb\x06proto3"
|
9
|
+
|
10
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
11
|
+
pool.add_serialized_file(descriptor_data)
|
12
|
+
|
13
|
+
module Stately
|
14
|
+
module Db
|
15
|
+
ScanRootPathsRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.ScanRootPathsRequest").msgclass
|
16
|
+
ScanRootPathsResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.ScanRootPathsResponse").msgclass
|
17
|
+
ScanRootPathResult = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.ScanRootPathResult").msgclass
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
# source: db/service.proto
|
4
|
+
|
5
|
+
require 'google/protobuf'
|
6
|
+
|
7
|
+
require 'db/continue_list_pb'
|
8
|
+
require 'db/delete_pb'
|
9
|
+
require 'db/get_pb'
|
10
|
+
require 'db/list_pb'
|
11
|
+
require 'db/put_pb'
|
12
|
+
require 'db/scan_root_paths_pb'
|
13
|
+
require 'db/sync_list_pb'
|
14
|
+
require 'db/transaction_pb'
|
15
|
+
|
16
|
+
|
17
|
+
descriptor_data = "\n\x10\x64\x62/service.proto\x12\nstately.db\x1a\x16\x64\x62/continue_list.proto\x1a\x0f\x64\x62/delete.proto\x1a\x0c\x64\x62/get.proto\x1a\rdb/list.proto\x1a\x0c\x64\x62/put.proto\x1a\x18\x64\x62/scan_root_paths.proto\x1a\x12\x64\x62/sync_list.proto\x1a\x14\x64\x62/transaction.proto2\xee\x04\n\x0f\x44\x61tabaseService\x12;\n\x03Put\x12\x16.stately.db.PutRequest\x1a\x17.stately.db.PutResponse\"\x03\x90\x02\x02\x12;\n\x03Get\x12\x16.stately.db.GetRequest\x1a\x17.stately.db.GetResponse\"\x03\x90\x02\x01\x12\x44\n\x06\x44\x65lete\x12\x19.stately.db.DeleteRequest\x1a\x1a.stately.db.DeleteResponse\"\x03\x90\x02\x02\x12J\n\tBeginList\x12\x1c.stately.db.BeginListRequest\x1a\x18.stately.db.ListResponse\"\x03\x90\x02\x01\x30\x01\x12P\n\x0c\x43ontinueList\x12\x1f.stately.db.ContinueListRequest\x1a\x18.stately.db.ListResponse\"\x03\x90\x02\x01\x30\x01\x12L\n\x08SyncList\x12\x1b.stately.db.SyncListRequest\x1a\x1c.stately.db.SyncListResponse\"\x03\x90\x02\x01\x30\x01\x12T\n\x0bTransaction\x12\x1e.stately.db.TransactionRequest\x1a\x1f.stately.db.TransactionResponse\"\x00(\x01\x30\x01\x12Y\n\rScanRootPaths\x12 .stately.db.ScanRootPathsRequest\x1a!.stately.db.ScanRootPathsResponse\"\x03\x90\x02\x01\x42g\n\x0e\x63om.stately.dbB\x0cServiceProtoP\x01\xa2\x02\x03SDX\xaa\x02\nStately.Db\xca\x02\nStately\\Db\xe2\x02\x16Stately\\Db\\GPBMetadata\xea\x02\x0bStately::Dbb\x06proto3"
|
18
|
+
|
19
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
20
|
+
pool.add_serialized_file(descriptor_data)
|
21
|
+
|
22
|
+
module Stately
|
23
|
+
module Db
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
2
|
+
# Source: db/service.proto for package 'Stately.Db'
|
3
|
+
|
4
|
+
require 'grpc'
|
5
|
+
require 'db/service_pb'
|
6
|
+
|
7
|
+
module Stately
|
8
|
+
module Db
|
9
|
+
module DatabaseService
|
10
|
+
# DatabaseService is the service for creating, reading, updating and deleting data
|
11
|
+
# in a StatelyDB Store. Creating and modifying Stores is done by
|
12
|
+
# stately.dbmanagement.ManagementService.
|
13
|
+
class Service
|
14
|
+
|
15
|
+
include ::GRPC::GenericService
|
16
|
+
|
17
|
+
self.marshal_class_method = :encode
|
18
|
+
self.unmarshal_class_method = :decode
|
19
|
+
self.service_name = 'stately.db.DatabaseService'
|
20
|
+
|
21
|
+
# Put adds one or more Items to the Store, or replaces the Items if they
|
22
|
+
# already exist. This will fail if the caller does not have permission to
|
23
|
+
# create or update Items, if there is no schema registered for the provided
|
24
|
+
# item type, or if an item is invalid. All puts are applied atomically;
|
25
|
+
# either all will fail or all will succeed. If an item's schema specifies an
|
26
|
+
# `initialValue` for one or more properties used in its key paths, and the
|
27
|
+
# item is new, you should not provide those values - the database will choose
|
28
|
+
# them for you, and Data must be provided as either serialized binary
|
29
|
+
# protobuf or JSON.
|
30
|
+
rpc :Put, ::Stately::Db::PutRequest, ::Stately::Db::PutResponse
|
31
|
+
# Get retrieves one or more Items by their key paths. This will return any of
|
32
|
+
# the Items that exist. It will fail if the caller does not have permission
|
33
|
+
# to read Items. Use the List APIs if you want to retrieve multiple items but
|
34
|
+
# don't already know the full key paths of the items you want to get.
|
35
|
+
rpc :Get, ::Stately::Db::GetRequest, ::Stately::Db::GetResponse
|
36
|
+
# Delete removes one or more Items from the Store by their key paths. This
|
37
|
+
# will fail if the caller does not have permission to delete Items.
|
38
|
+
# Tombstones will be saved for deleted items for time, so
|
39
|
+
# that SyncList can return information about deleted items. Deletes are
|
40
|
+
# always applied atomically; all will fail or all will succeed.
|
41
|
+
rpc :Delete, ::Stately::Db::DeleteRequest, ::Stately::Db::DeleteResponse
|
42
|
+
# BeginList retrieves Items that start with a specified key path prefix. The
|
43
|
+
# key path prefix must minimally contain a Group Key (an item type and an
|
44
|
+
# item ID). BeginList will return an empty result set if there are no items
|
45
|
+
# matching that key prefix. This API returns a token that you can pass to
|
46
|
+
# ContinueList to expand the result set, or to SyncList to get updates within
|
47
|
+
# the result set. This can fail if the caller does not have permission to
|
48
|
+
# read Items.
|
49
|
+
# buf:lint:ignore RPC_RESPONSE_STANDARD_NAME
|
50
|
+
rpc :BeginList, ::Stately::Db::BeginListRequest, stream(::Stately::Db::ListResponse)
|
51
|
+
# ContinueList takes the token from a BeginList call and returns more results
|
52
|
+
# based on the original query parameters and pagination options. It has very
|
53
|
+
# few options of its own because it is a continuation of a previous list
|
54
|
+
# operation. It will return a new token which can be used for another
|
55
|
+
# ContinueList call, and so on. The token is the same one used by SyncList -
|
56
|
+
# each time you call either ContinueList or SyncList, you should pass the
|
57
|
+
# latest version of the token, and then use the new token from the result in
|
58
|
+
# subsequent calls. You may interleave ContinueList and SyncList calls
|
59
|
+
# however you like, but it does not make sense to make both calls in
|
60
|
+
# parallel. Calls to ContinueList are tied to the authorization of the
|
61
|
+
# original BeginList call, so if the original BeginList call was allowed,
|
62
|
+
# ContinueList with its token should also be allowed.
|
63
|
+
# buf:lint:ignore RPC_RESPONSE_STANDARD_NAME
|
64
|
+
rpc :ContinueList, ::Stately::Db::ContinueListRequest, stream(::Stately::Db::ListResponse)
|
65
|
+
# SyncList returns all changes to Items within the result set of a previous
|
66
|
+
# List operation. For all Items within the result set that were modified, it
|
67
|
+
# returns the full Item at in its current state. It also returns a list of
|
68
|
+
# Item key paths that were deleted since the last SyncList, which you should
|
69
|
+
# reconcile with your view of items returned from previous
|
70
|
+
# BeginList/ContinueList calls. Using this API, you can start with an initial
|
71
|
+
# set of items from BeginList, and then stay up to date on any changes via
|
72
|
+
# repeated SyncList requests over time. The token is the same one used by
|
73
|
+
# ContinueList - each time you call either ContinueList or SyncList, you
|
74
|
+
# should pass the latest version of the token, and then use the new token
|
75
|
+
# from the result in subsequent calls. Note that if the result set has
|
76
|
+
# already been expanded to the end (in the direction of the original
|
77
|
+
# BeginList request), SyncList will return newly created Items. You may
|
78
|
+
# interleave ContinueList and SyncList calls however you like, but it does
|
79
|
+
# not make sense to make both calls in parallel. Calls to SyncList are tied
|
80
|
+
# to the authorization of the original BeginList call, so if the original
|
81
|
+
# BeginList call was allowed, SyncList with its token should also be allowed.
|
82
|
+
rpc :SyncList, ::Stately::Db::SyncListRequest, stream(::Stately::Db::SyncListResponse)
|
83
|
+
# Transaction performs a transaction, within which you can issue writes
|
84
|
+
# (Put/Delete) and reads (Get/List) in any order, followed by a commit
|
85
|
+
# message. Reads are guaranteed to reflect the state as of when the
|
86
|
+
# transaction started, and writes are committed atomically. This method may
|
87
|
+
# fail if another transaction commits before this one finishes - in that
|
88
|
+
# case, you should retry your transaction.
|
89
|
+
rpc :Transaction, stream(::Stately::Db::TransactionRequest), stream(::Stately::Db::TransactionResponse)
|
90
|
+
# ScanRootPaths lists root paths (Groups) in the Store. This is a very
|
91
|
+
# expensive operation, as it must consult multiple partitions and it reads
|
92
|
+
# and ignores a lot of data. It is provided for use in the web console's data
|
93
|
+
# browser and is not exposed to customers. This operation will fail if the
|
94
|
+
# caller does not have permission to read Items.
|
95
|
+
rpc :ScanRootPaths, ::Stately::Db::ScanRootPathsRequest, ::Stately::Db::ScanRootPathsResponse
|
96
|
+
end
|
97
|
+
|
98
|
+
Stub = Service.rpc_stub_class
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
# source: db/sync_list.proto
|
4
|
+
|
5
|
+
require 'google/protobuf'
|
6
|
+
|
7
|
+
require 'db/item_pb'
|
8
|
+
require 'db/list_pb'
|
9
|
+
|
10
|
+
|
11
|
+
descriptor_data = "\n\x12\x64\x62/sync_list.proto\x12\nstately.db\x1a\rdb/item.proto\x1a\rdb/list.proto\"0\n\x0fSyncListRequest\x12\x1d\n\ntoken_data\x18\x01 \x01(\x0cR\ttokenData\"\xc8\x01\n\x10SyncListResponse\x12\x31\n\x05reset\x18\x01 \x01(\x0b\x32\x19.stately.db.SyncListResetH\x00R\x05reset\x12=\n\x06result\x18\x02 \x01(\x0b\x32#.stately.db.SyncListPartialResponseH\x00R\x06result\x12\x36\n\x08\x66inished\x18\x03 \x01(\x0b\x32\x18.stately.db.ListFinishedH\x00R\x08\x66inishedB\n\n\x08response\"\x0f\n\rSyncListReset\"\xdf\x01\n\x17SyncListPartialResponse\x12\x35\n\rchanged_items\x18\x01 \x03(\x0b\x32\x10.stately.db.ItemR\x0c\x63hangedItems\x12<\n\rdeleted_items\x18\x02 \x03(\x0b\x32\x17.stately.db.DeletedItemR\x0c\x64\x65letedItems\x12O\n%updated_item_keys_outside_list_window\x18\x03 \x03(\tR updatedItemKeysOutsideListWindow\"(\n\x0b\x44\x65letedItem\x12\x19\n\x08key_path\x18\x01 \x01(\tR\x07keyPathBh\n\x0e\x63om.stately.dbB\rSyncListProtoP\x01\xa2\x02\x03SDX\xaa\x02\nStately.Db\xca\x02\nStately\\Db\xe2\x02\x16Stately\\Db\\GPBMetadata\xea\x02\x0bStately::Dbb\x06proto3"
|
12
|
+
|
13
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
14
|
+
pool.add_serialized_file(descriptor_data)
|
15
|
+
|
16
|
+
module Stately
|
17
|
+
module Db
|
18
|
+
SyncListRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.SyncListRequest").msgclass
|
19
|
+
SyncListResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.SyncListResponse").msgclass
|
20
|
+
SyncListReset = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.SyncListReset").msgclass
|
21
|
+
SyncListPartialResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.SyncListPartialResponse").msgclass
|
22
|
+
DeletedItem = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.DeletedItem").msgclass
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
# source: db/transaction.proto
|
4
|
+
|
5
|
+
require 'google/protobuf'
|
6
|
+
|
7
|
+
require 'db/continue_list_pb'
|
8
|
+
require 'db/delete_pb'
|
9
|
+
require 'db/get_pb'
|
10
|
+
require 'db/item_pb'
|
11
|
+
require 'db/item_property_pb'
|
12
|
+
require 'db/list_pb'
|
13
|
+
require 'db/put_pb'
|
14
|
+
require 'google/protobuf/empty_pb'
|
15
|
+
|
16
|
+
|
17
|
+
descriptor_data = "\n\x14\x64\x62/transaction.proto\x12\nstately.db\x1a\x16\x64\x62/continue_list.proto\x1a\x0f\x64\x62/delete.proto\x1a\x0c\x64\x62/get.proto\x1a\rdb/item.proto\x1a\x16\x64\x62/item_property.proto\x1a\rdb/list.proto\x1a\x0c\x64\x62/put.proto\x1a\x1bgoogle/protobuf/empty.proto\"\x9f\x04\n\x12TransactionRequest\x12\x1d\n\nmessage_id\x18\x01 \x01(\rR\tmessageId\x12\x34\n\x05\x62\x65gin\x18\x02 \x01(\x0b\x32\x1c.stately.db.TransactionBeginH\x00R\x05\x62\x65gin\x12\x39\n\tget_items\x18\x03 \x01(\x0b\x32\x1a.stately.db.TransactionGetH\x00R\x08getItems\x12\x41\n\nbegin_list\x18\x04 \x01(\x0b\x32 .stately.db.TransactionBeginListH\x00R\tbeginList\x12J\n\rcontinue_list\x18\x05 \x01(\x0b\x32#.stately.db.TransactionContinueListH\x00R\x0c\x63ontinueList\x12\x39\n\tput_items\x18\x06 \x01(\x0b\x32\x1a.stately.db.TransactionPutH\x00R\x08putItems\x12\x42\n\x0c\x64\x65lete_items\x18\x07 \x01(\x0b\x32\x1d.stately.db.TransactionDeleteH\x00R\x0b\x64\x65leteItems\x12\x30\n\x06\x63ommit\x18\x08 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00R\x06\x63ommit\x12.\n\x05\x61\x62ort\x18\t \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00R\x05\x61\x62ortB\t\n\x07\x63ommand\"\xc8\x02\n\x13TransactionResponse\x12\x1d\n\nmessage_id\x18\x01 \x01(\rR\tmessageId\x12\x45\n\x0bget_results\x18\x02 \x01(\x0b\x32\".stately.db.TransactionGetResponseH\x00R\ngetResults\x12\x38\n\x07put_ack\x18\x03 \x01(\x0b\x32\x1d.stately.db.TransactionPutAckH\x00R\x06putAck\x12H\n\x0clist_results\x18\x04 \x01(\x0b\x32#.stately.db.TransactionListResponseH\x00R\x0blistResults\x12=\n\x08\x66inished\x18\x05 \x01(\x0b\x32\x1f.stately.db.TransactionFinishedH\x00R\x08\x66inishedB\x08\n\x06result\"-\n\x10TransactionBegin\x12\x19\n\x08store_id\x18\x01 \x01(\x04R\x07storeId\"9\n\x0eTransactionGet\x12\'\n\x04gets\x18\x01 \x03(\x0b\x32\x13.stately.db.GetItemR\x04gets\"\xd9\x01\n\x14TransactionBeginList\x12&\n\x0fkey_path_prefix\x18\x01 \x01(\tR\rkeyPathPrefix\x12\x14\n\x05limit\x18\x02 \x01(\rR\x05limit\x12\x41\n\rsort_property\x18\x03 \x01(\x0e\x32\x1c.stately.db.SortablePropertyR\x0csortProperty\x12@\n\x0esort_direction\x18\x04 \x01(\x0e\x32\x19.stately.db.SortDirectionR\rsortDirection\"y\n\x17TransactionContinueList\x12\x1d\n\ntoken_data\x18\x01 \x01(\x0cR\ttokenData\x12?\n\tdirection\x18\x04 \x01(\x0e\x32!.stately.db.ContinueListDirectionR\tdirection\"9\n\x0eTransactionPut\x12\'\n\x04puts\x18\x01 \x03(\x0b\x32\x13.stately.db.PutItemR\x04puts\"E\n\x11TransactionDelete\x12\x30\n\x07\x64\x65letes\x18\x01 \x03(\x0b\x32\x16.stately.db.DeleteItemR\x07\x64\x65letes\"@\n\x16TransactionGetResponse\x12&\n\x05items\x18\x01 \x03(\x0b\x32\x10.stately.db.ItemR\x05items\"D\n\x0bGeneratedID\x12\x14\n\x04uint\x18\x01 \x01(\x04H\x00R\x04uint\x12\x16\n\x05\x62ytes\x18\x02 \x01(\x0cH\x00R\x05\x62ytesB\x07\n\x05value\"Q\n\x11TransactionPutAck\x12<\n\rgenerated_ids\x18\x01 \x03(\x0b\x32\x17.stately.db.GeneratedIDR\x0cgeneratedIds\"\x96\x01\n\x17TransactionListResponse\x12\x37\n\x06result\x18\x01 \x01(\x0b\x32\x1d.stately.db.ListPartialResultH\x00R\x06result\x12\x36\n\x08\x66inished\x18\x02 \x01(\x0b\x32\x18.stately.db.ListFinishedH\x00R\x08\x66inishedB\n\n\x08response\"\xa7\x01\n\x13TransactionFinished\x12\x1c\n\tcommitted\x18\x01 \x01(\x08R\tcommitted\x12\x31\n\x0bput_results\x18\x02 \x03(\x0b\x32\x10.stately.db.ItemR\nputResults\x12?\n\x0e\x64\x65lete_results\x18\x03 \x03(\x0b\x32\x18.stately.db.DeleteResultR\rdeleteResultsBk\n\x0e\x63om.stately.dbB\x10TransactionProtoP\x01\xa2\x02\x03SDX\xaa\x02\nStately.Db\xca\x02\nStately\\Db\xe2\x02\x16Stately\\Db\\GPBMetadata\xea\x02\x0bStately::Dbb\x06proto3"
|
18
|
+
|
19
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
20
|
+
pool.add_serialized_file(descriptor_data)
|
21
|
+
|
22
|
+
module Stately
|
23
|
+
module Db
|
24
|
+
TransactionRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.TransactionRequest").msgclass
|
25
|
+
TransactionResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.TransactionResponse").msgclass
|
26
|
+
TransactionBegin = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.TransactionBegin").msgclass
|
27
|
+
TransactionGet = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.TransactionGet").msgclass
|
28
|
+
TransactionBeginList = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.TransactionBeginList").msgclass
|
29
|
+
TransactionContinueList = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.TransactionContinueList").msgclass
|
30
|
+
TransactionPut = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.TransactionPut").msgclass
|
31
|
+
TransactionDelete = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.TransactionDelete").msgclass
|
32
|
+
TransactionGetResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.TransactionGetResponse").msgclass
|
33
|
+
GeneratedID = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.GeneratedID").msgclass
|
34
|
+
TransactionPutAck = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.TransactionPutAck").msgclass
|
35
|
+
TransactionListResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.TransactionListResponse").msgclass
|
36
|
+
TransactionFinished = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.db.TransactionFinished").msgclass
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
# source: errors/error_details.proto
|
4
|
+
|
5
|
+
require 'google/protobuf'
|
6
|
+
|
7
|
+
|
8
|
+
descriptor_data = "\n\x1a\x65rrors/error_details.proto\x12\x0estately.errors\"y\n\x13StatelyErrorDetails\x12!\n\x0cstately_code\x18\x01 \x01(\tR\x0bstatelyCode\x12\x18\n\x07message\x18\x02 \x01(\tR\x07message\x12%\n\x0eupstream_cause\x18\x03 \x01(\tR\rupstreamCauseB\x80\x01\n\x12\x63om.stately.errorsB\x11\x45rrorDetailsProtoP\x01\xa2\x02\x03SEX\xaa\x02\x0eStately.Errors\xca\x02\x0eStately\\Errors\xe2\x02\x1aStately\\Errors\\GPBMetadata\xea\x02\x0fStately::Errorsb\x06proto3"
|
9
|
+
|
10
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
11
|
+
pool.add_serialized_file(descriptor_data)
|
12
|
+
|
13
|
+
module Stately
|
14
|
+
module Errors
|
15
|
+
StatelyErrorDetails = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("stately.errors.StatelyErrorDetails").msgclass
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "async"
|
4
|
+
require "async/http/internet"
|
5
|
+
require "async/semaphore"
|
6
|
+
require "json"
|
7
|
+
require "logger"
|
8
|
+
require "weakref"
|
9
|
+
require_relative "token_provider"
|
10
|
+
|
11
|
+
LOGGER = Logger.new($stdout)
|
12
|
+
LOGGER.level = Logger::WARN
|
13
|
+
DEFAULT_GRANT_TYPE = "client_credentials"
|
14
|
+
|
15
|
+
module StatelyDB
|
16
|
+
module Common
|
17
|
+
# A module for Stately Cloud auth code
|
18
|
+
module Auth
|
19
|
+
# Auth0TokenProvider is an implementation of the TokenProvider abstract base class
|
20
|
+
# which vends tokens from auth0 with the given client_id and client_secret.
|
21
|
+
# It will default to using the values of `STATELY_CLIENT_ID` and `STATELY_CLIENT_SECRET` if
|
22
|
+
# no credentials are explicitly passed and will throw an error if none are found.
|
23
|
+
class Auth0TokenProvider < TokenProvider
|
24
|
+
# @param [String] auth_url The URL of the OAuth server
|
25
|
+
# @param [String] audience The OAuth Audience for the token
|
26
|
+
# @param [String] client_secret The StatelyDB client secret credential
|
27
|
+
# @param [String] client_id The StatelyDB client ID credential
|
28
|
+
def initialize(
|
29
|
+
auth_url: "https://oauth.stately.cloud",
|
30
|
+
audience: "api.stately.cloud",
|
31
|
+
client_secret: ENV.fetch("STATELY_CLIENT_SECRET"),
|
32
|
+
client_id: ENV.fetch("STATELY_CLIENT_ID")
|
33
|
+
)
|
34
|
+
super()
|
35
|
+
@client_id = client_id
|
36
|
+
@client_secret = client_secret
|
37
|
+
@audience = audience
|
38
|
+
@auth_url = "#{auth_url}/oauth/token"
|
39
|
+
@access_token = nil
|
40
|
+
@pending_refresh = nil
|
41
|
+
@timer = nil
|
42
|
+
|
43
|
+
Async do |_task|
|
44
|
+
refresh_token
|
45
|
+
end
|
46
|
+
|
47
|
+
# need a weak ref to ourself or the GC will never run the finalizer
|
48
|
+
ObjectSpace.define_finalizer(WeakRef.new(self), finalize)
|
49
|
+
end
|
50
|
+
|
51
|
+
# finalizer kills the thread running the timer if one exists
|
52
|
+
# @return [Proc] The finalizer proc
|
53
|
+
def finalize
|
54
|
+
proc {
|
55
|
+
Thread.kill(@timer) unless @timer.nil?
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
# Get the current access token
|
60
|
+
# @return [String] The current access token
|
61
|
+
def access_token
|
62
|
+
# TODO: - check whether or not the GIL is enough to make this threadsafe
|
63
|
+
@access_token || refresh_token
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# Refresh the access token
|
69
|
+
# @return [void]
|
70
|
+
def refresh_token
|
71
|
+
# never run more than one at a time.
|
72
|
+
@pending_refresh ||= refresh_token_impl
|
73
|
+
# many threads all wait on the same task here.
|
74
|
+
# I wrote a test to check this is possible
|
75
|
+
@pending_refresh.wait
|
76
|
+
# multiple people will all set this to nil after
|
77
|
+
# they are done waiting but I don't think i can put this inside
|
78
|
+
# refresh_token_impl. It seems harmless because of the GIL?
|
79
|
+
@pending_refresh = nil
|
80
|
+
end
|
81
|
+
|
82
|
+
# Refresh the access token implementation
|
83
|
+
# @return [String] The new access token
|
84
|
+
def refresh_token_impl
|
85
|
+
Async do
|
86
|
+
client = Async::HTTP::Internet.new
|
87
|
+
headers = [["content-type", "application/json"]]
|
88
|
+
data = { "client_id" => @client_id, client_secret: @client_secret, audience: @audience,
|
89
|
+
grant_type: DEFAULT_GRANT_TYPE }
|
90
|
+
body = [JSON.dump(data)]
|
91
|
+
|
92
|
+
resp = client.post(@auth_url, headers, body)
|
93
|
+
resp_data = JSON.parse(resp.read)
|
94
|
+
raise "Auth request failed: #{resp_data}" if resp.status != 200
|
95
|
+
|
96
|
+
@access_token = resp_data["access_token"]
|
97
|
+
|
98
|
+
# do this on a thread or else the sleep
|
99
|
+
# will block the event loop.
|
100
|
+
# there is no non-blocking sleep in ruby.
|
101
|
+
# skip this if we have a pending timer thread already
|
102
|
+
@timer = Thread.new do
|
103
|
+
# TODO: - add some random jitter to stop clients getting a cycle after
|
104
|
+
# some event like an outage
|
105
|
+
# Also, don't let this be less than 1sec
|
106
|
+
delay = [resp_data["expires_in"] - 10, 1].max
|
107
|
+
sleep(delay)
|
108
|
+
refresh_token
|
109
|
+
end
|
110
|
+
@pending_refresh = nil
|
111
|
+
resp_data["access_token"]
|
112
|
+
rescue StandardError => e
|
113
|
+
# set the token to nil so that it will
|
114
|
+
# be refreshed on the next get
|
115
|
+
@access_token = nil
|
116
|
+
LOGGER.warn(e)
|
117
|
+
ensure
|
118
|
+
client.close
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "grpc"
|
4
|
+
require "common/auth/token_provider"
|
5
|
+
|
6
|
+
module StatelyDB
|
7
|
+
module Common
|
8
|
+
# A module for Stately Cloud auth code
|
9
|
+
module Auth
|
10
|
+
# GRPC interceptor to authenticate against Stately and append bearer tokens to outgoing requests
|
11
|
+
class Interceptor < GRPC::ClientInterceptor
|
12
|
+
# @param [TokenProvider] token_provider The token provider to use for authentication
|
13
|
+
def initialize(
|
14
|
+
token_provider: Auth0TokenProvider.new
|
15
|
+
)
|
16
|
+
super()
|
17
|
+
@token_provider = token_provider
|
18
|
+
end
|
19
|
+
|
20
|
+
# gRPC client unary interceptor
|
21
|
+
#
|
22
|
+
# @param [Object] request The request object
|
23
|
+
# @param [GRPC::ActiveCall] call The active call object
|
24
|
+
# @param [Symbol] method The method being called
|
25
|
+
# @param [Hash] metadata The metadata hash
|
26
|
+
# @return [Object] The response object
|
27
|
+
# @api private
|
28
|
+
def request_response(request:, call:, method:, metadata:) # rubocop:disable Lint/UnusedMethodArgument
|
29
|
+
add_jwt_to_grpc_request(metadata:)
|
30
|
+
yield
|
31
|
+
end
|
32
|
+
|
33
|
+
# gRPC client streaming interceptor
|
34
|
+
#
|
35
|
+
# @param [Enumerable] requests The list of requests
|
36
|
+
# @param [GRPC::ActiveCall] call The active call object
|
37
|
+
# @param [Symbol] method The method being called
|
38
|
+
# @param [Hash] metadata The metadata hash
|
39
|
+
# @return [Enumerator] The response enumerator
|
40
|
+
# @api private
|
41
|
+
def client_streamer(requests:, call:, method:, metadata:) # rubocop:disable Lint/UnusedMethodArgument
|
42
|
+
add_jwt_to_grpc_request(metadata:)
|
43
|
+
yield
|
44
|
+
end
|
45
|
+
|
46
|
+
# gRPC server streaming interceptor
|
47
|
+
#
|
48
|
+
# @param [Object] request The request object
|
49
|
+
# @param [GRPC::ActiveCall] call The active call object
|
50
|
+
# @param [Symbol] method The method being called
|
51
|
+
# @param [Hash] metadata The metadata hash
|
52
|
+
# @return [Enumerator] The response enumerator
|
53
|
+
# @api private
|
54
|
+
def server_streamer(request:, call:, method:, metadata:) # rubocop:disable Lint/UnusedMethodArgument
|
55
|
+
add_jwt_to_grpc_request(metadata:)
|
56
|
+
yield
|
57
|
+
end
|
58
|
+
|
59
|
+
# gRPC bidirectional streaming interceptor
|
60
|
+
#
|
61
|
+
# @param [Enumerable] requests The list of requests
|
62
|
+
# @param [GRPC::ActiveCall] call The active call object
|
63
|
+
# @param [Symbol] method The method being called
|
64
|
+
# @param [Hash] metadata The metadata hash
|
65
|
+
# @return [Enumerator] The response enumerator
|
66
|
+
# @api private
|
67
|
+
def bidi_streamer(requests:, call:, method:, metadata:) # rubocop:disable Lint/UnusedMethodArgument
|
68
|
+
add_jwt_to_grpc_request(metadata:)
|
69
|
+
yield
|
70
|
+
end
|
71
|
+
|
72
|
+
# Adds a JWT to the metadata hash
|
73
|
+
# @param [Hash] metadata The metadata hash
|
74
|
+
# @return [void]
|
75
|
+
# @api private
|
76
|
+
def add_jwt_to_grpc_request(metadata:)
|
77
|
+
metadata["authorization"] = "Bearer #{@token_provider.access_token}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StatelyDB
|
4
|
+
module Common
|
5
|
+
# A module for Stately Cloud auth code
|
6
|
+
module Auth
|
7
|
+
# TokenProvider is an abstract base class that should be extended
|
8
|
+
# for individual token provider implementations
|
9
|
+
class TokenProvider
|
10
|
+
# Get the current access token
|
11
|
+
# @return [String] The current access token
|
12
|
+
def access_token
|
13
|
+
raise "Not Implemented"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|