couchbase 4.2.5-dev.3 → 4.2.6-dev

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.
Files changed (122) hide show
  1. package/README.md +81 -9
  2. package/deps/couchbase-cxx-client/CMakeLists.txt +9 -1
  3. package/deps/couchbase-cxx-client/bin/api.rb +234 -0
  4. package/deps/couchbase-cxx-client/bin/create-search-index +18 -135
  5. package/deps/couchbase-cxx-client/bin/init-cluster +17 -139
  6. package/deps/couchbase-cxx-client/bin/load-sample-buckets +54 -0
  7. package/deps/couchbase-cxx-client/core/cluster.hxx +33 -12
  8. package/deps/couchbase-cxx-client/core/cluster_options.hxx +3 -0
  9. package/deps/couchbase-cxx-client/core/crud_component.cxx +51 -22
  10. package/deps/couchbase-cxx-client/core/impl/build_deferred_query_indexes.cxx +115 -50
  11. package/deps/couchbase-cxx-client/core/impl/cluster.cxx +6 -0
  12. package/deps/couchbase-cxx-client/core/impl/create_bucket.cxx +155 -0
  13. package/deps/couchbase-cxx-client/core/impl/create_query_index.cxx +172 -59
  14. package/deps/couchbase-cxx-client/core/impl/dns_srv_tracker.cxx +2 -1
  15. package/deps/couchbase-cxx-client/core/impl/drop_bucket.cxx +66 -0
  16. package/deps/couchbase-cxx-client/core/impl/drop_query_index.cxx +138 -59
  17. package/deps/couchbase-cxx-client/core/impl/flush_bucket.cxx +66 -0
  18. package/deps/couchbase-cxx-client/core/impl/get_all_buckets.cxx +163 -0
  19. package/deps/couchbase-cxx-client/core/impl/get_all_query_indexes.cxx +67 -37
  20. package/deps/couchbase-cxx-client/core/impl/get_bucket.cxx +153 -0
  21. package/deps/couchbase-cxx-client/core/impl/internal_manager_error_context.cxx +113 -0
  22. package/deps/couchbase-cxx-client/core/impl/internal_manager_error_context.hxx +60 -0
  23. package/deps/couchbase-cxx-client/core/impl/key_value_error_category.cxx +2 -4
  24. package/deps/couchbase-cxx-client/core/impl/manager_error_context.cxx +100 -0
  25. package/deps/couchbase-cxx-client/core/impl/query.cxx +1 -0
  26. package/deps/couchbase-cxx-client/core/impl/update_bucket.cxx +130 -0
  27. package/deps/couchbase-cxx-client/core/impl/watch_query_indexes.cxx +53 -29
  28. package/deps/couchbase-cxx-client/core/io/dns_client.cxx +71 -38
  29. package/deps/couchbase-cxx-client/core/io/dns_config.cxx +5 -4
  30. package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +5 -6
  31. package/deps/couchbase-cxx-client/core/meta/features.hxx +6 -0
  32. package/deps/couchbase-cxx-client/core/operations/document_query.cxx +11 -0
  33. package/deps/couchbase-cxx-client/core/operations/document_query.hxx +1 -0
  34. package/deps/couchbase-cxx-client/core/origin.cxx +270 -0
  35. package/deps/couchbase-cxx-client/core/origin.hxx +2 -0
  36. package/deps/couchbase-cxx-client/core/protocol/status.cxx +2 -2
  37. package/deps/couchbase-cxx-client/core/range_scan_options.cxx +3 -27
  38. package/deps/couchbase-cxx-client/core/range_scan_options.hxx +13 -17
  39. package/deps/couchbase-cxx-client/core/range_scan_orchestrator.cxx +367 -170
  40. package/deps/couchbase-cxx-client/core/range_scan_orchestrator.hxx +13 -2
  41. package/deps/couchbase-cxx-client/core/range_scan_orchestrator_options.hxx +5 -3
  42. package/deps/couchbase-cxx-client/core/scan_options.hxx +0 -19
  43. package/deps/couchbase-cxx-client/core/scan_result.cxx +19 -5
  44. package/deps/couchbase-cxx-client/core/scan_result.hxx +5 -2
  45. package/deps/couchbase-cxx-client/core/timeout_defaults.hxx +2 -3
  46. package/deps/couchbase-cxx-client/core/topology/capabilities.hxx +1 -0
  47. package/deps/couchbase-cxx-client/core/topology/capabilities_fmt.hxx +2 -0
  48. package/deps/couchbase-cxx-client/core/topology/collections_manifest_fmt.hxx +1 -1
  49. package/deps/couchbase-cxx-client/core/topology/configuration.hxx +5 -0
  50. package/deps/couchbase-cxx-client/core/topology/configuration_json.hxx +2 -0
  51. package/deps/couchbase-cxx-client/core/utils/connection_string.cxx +4 -0
  52. package/deps/couchbase-cxx-client/couchbase/behavior_options.hxx +19 -2
  53. package/deps/couchbase-cxx-client/couchbase/bucket_manager.hxx +135 -0
  54. package/deps/couchbase-cxx-client/couchbase/build_query_index_options.hxx +0 -30
  55. package/deps/couchbase-cxx-client/couchbase/cluster.hxx +14 -0
  56. package/deps/couchbase-cxx-client/couchbase/collection_query_index_manager.hxx +7 -48
  57. package/deps/couchbase-cxx-client/couchbase/create_bucket_options.hxx +41 -0
  58. package/deps/couchbase-cxx-client/couchbase/create_primary_query_index_options.hxx +0 -29
  59. package/deps/couchbase-cxx-client/couchbase/create_query_index_options.hxx +0 -33
  60. package/deps/couchbase-cxx-client/couchbase/drop_bucket_options.hxx +41 -0
  61. package/deps/couchbase-cxx-client/couchbase/drop_primary_query_index_options.hxx +0 -30
  62. package/deps/couchbase-cxx-client/couchbase/drop_query_index_options.hxx +0 -31
  63. package/deps/couchbase-cxx-client/couchbase/error_codes.hxx +1 -2
  64. package/deps/couchbase-cxx-client/couchbase/flush_bucket_options.hxx +41 -0
  65. package/deps/couchbase-cxx-client/couchbase/get_all_buckets_options.hxx +44 -0
  66. package/deps/couchbase-cxx-client/couchbase/get_all_query_indexes_options.hxx +0 -30
  67. package/deps/couchbase-cxx-client/couchbase/get_bucket_options.hxx +43 -0
  68. package/deps/couchbase-cxx-client/couchbase/management/bucket_settings.hxx +116 -0
  69. package/deps/couchbase-cxx-client/couchbase/manager_error_context.hxx +29 -53
  70. package/deps/couchbase-cxx-client/couchbase/query_index_manager.hxx +16 -83
  71. package/deps/couchbase-cxx-client/couchbase/query_options.hxx +18 -0
  72. package/deps/couchbase-cxx-client/couchbase/security_options.hxx +15 -0
  73. package/deps/couchbase-cxx-client/couchbase/update_bucket_options.hxx +41 -0
  74. package/deps/couchbase-cxx-client/couchbase/watch_query_indexes_options.hxx +0 -31
  75. package/deps/couchbase-cxx-client/docs/cbc-analytics.md +1 -0
  76. package/deps/couchbase-cxx-client/docs/cbc-get.md +1 -0
  77. package/deps/couchbase-cxx-client/docs/cbc-pillowfight.md +1 -0
  78. package/deps/couchbase-cxx-client/docs/cbc-query.md +1 -0
  79. package/deps/couchbase-cxx-client/docs/cbc.md +10 -0
  80. package/deps/couchbase-cxx-client/test/CMakeLists.txt +1 -0
  81. package/deps/couchbase-cxx-client/test/test_integration_collections.cxx +6 -0
  82. package/deps/couchbase-cxx-client/test/test_integration_crud.cxx +5 -0
  83. package/deps/couchbase-cxx-client/test/test_integration_examples.cxx +137 -1
  84. package/deps/couchbase-cxx-client/test/test_integration_management.cxx +709 -266
  85. package/deps/couchbase-cxx-client/test/test_integration_query.cxx +19 -7
  86. package/deps/couchbase-cxx-client/test/test_integration_range_scan.cxx +351 -112
  87. package/deps/couchbase-cxx-client/test/test_integration_search.cxx +10 -1
  88. package/deps/couchbase-cxx-client/test/test_transaction_public_async_api.cxx +13 -12
  89. package/deps/couchbase-cxx-client/test/test_transaction_public_blocking_api.cxx +27 -21
  90. package/deps/couchbase-cxx-client/test/test_unit_query.cxx +75 -0
  91. package/deps/couchbase-cxx-client/test/utils/server_version.hxx +5 -0
  92. package/deps/couchbase-cxx-client/test/utils/wait_until.cxx +29 -10
  93. package/deps/couchbase-cxx-client/test/utils/wait_until.hxx +3 -1
  94. package/deps/couchbase-cxx-client/tools/utils.cxx +4 -1
  95. package/dist/binding.d.ts +21 -16
  96. package/dist/binding.js +1 -4
  97. package/dist/bindingutilities.d.ts +6 -1
  98. package/dist/bindingutilities.js +36 -1
  99. package/dist/collection.d.ts +65 -3
  100. package/dist/collection.js +107 -0
  101. package/dist/crudoptypes.d.ts +34 -0
  102. package/dist/crudoptypes.js +18 -1
  103. package/dist/queryexecutor.js +1 -0
  104. package/dist/querytypes.d.ts +7 -0
  105. package/dist/rangeScan.d.ts +107 -0
  106. package/dist/rangeScan.js +91 -0
  107. package/dist/streamablepromises.d.ts +6 -0
  108. package/dist/streamablepromises.js +25 -1
  109. package/package.json +13 -14
  110. package/scripts/createPlatformPackages.js +1 -4
  111. package/src/addondata.hpp +1 -0
  112. package/src/binding.cpp +5 -2
  113. package/src/connection.cpp +108 -2
  114. package/src/connection.hpp +1 -0
  115. package/src/constants.cpp +2 -12
  116. package/src/jstocbpp_autogen.hpp +49 -22
  117. package/src/jstocbpp_basic.hpp +2 -8
  118. package/src/mutationtoken.cpp +13 -0
  119. package/src/scan_iterator.cpp +90 -0
  120. package/src/scan_iterator.hpp +30 -0
  121. package/tools/gen-bindings-json.py +9 -8
  122. package/deps/couchbase-cxx-client/core/impl/collection_query_index_manager.cxx +0 -93
package/README.md CHANGED
@@ -41,20 +41,92 @@ successfully established.
41
41
  Here is a simple example of instantiating a connection, adding a new document
42
42
  into the bucket and then retrieving its contents:
43
43
 
44
+ **Javascript:**
44
45
  ```javascript
45
- import { Cluster } from 'couchbase'
46
+ const couchbase = require('couchbase')
47
+
48
+ async function main() {
49
+ const cluster = await couchbase.connect(
50
+ 'couchbase://127.0.0.1',
51
+ {
52
+ username: 'username',
53
+ password: 'password',
54
+ })
55
+
56
+ const bucket = cluster.bucket('default')
57
+ const coll = bucket.defaultCollection()
58
+ await coll.upsert('testdoc', { foo: 'bar' })
59
+
60
+ const res = await coll.get('testdoc')
61
+ console.log(res.content)
62
+ }
63
+
64
+ // Run the main function
65
+ main()
66
+ .then((_) => {
67
+ console.log ('Success!')
68
+ })
69
+ .catch((err) => {
70
+ console.log('ERR:', err)
71
+ })
72
+ ```
46
73
 
47
- const cluster = await couchbase.connect(
48
- 'couchbase://127.0.0.1',
49
- {
50
- username: 'username',
51
- password: 'password',
74
+ **Typescript:**
75
+ ```javascript
76
+ import {
77
+ Bucket,
78
+ Cluster,
79
+ Collection,
80
+ connect,
81
+ GetResult,
82
+ } from 'couchbase'
83
+
84
+ async function main() {
85
+ const cluster: Cluster = await connect(
86
+ 'couchbase://127.0.0.1',
87
+ {
88
+ username: 'username',
89
+ password: 'password',
90
+ })
91
+
92
+ const bucket: Bucket = cluster.bucket('default')
93
+ const coll: Collection = bucket.defaultCollection()
94
+ await coll.upsert('testdoc', { foo: 'bar' })
95
+
96
+ const res: GetResult = await coll.get('testdoc')
97
+ console.log(res.content)
98
+ }
99
+
100
+ // Run the main function
101
+ main()
102
+ .then((_) => {
103
+ console.log ('Success!')
52
104
  })
105
+ .catch((err) => {
106
+ console.log('ERR:', err)
107
+ })
108
+ ```
109
+
110
+ ## AWS Lambda
111
+
112
+ Version 4.2.5 of the SDK significantly reduces the size of the prebuilt binary provided with the SDK on supported platforms. The reduction
113
+ enables the SDK to meet the [minimum size requirements](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html) for an AWS lambda deployment package without extra steps for reducing the size of the package. However, if further size reduction is desired, the SDK provides a script to provide recommendations for size reduction.
114
+
115
+ **Script:**
116
+ ```bash
117
+ npm explore couchbase -- npm run help-prune
118
+ ```
119
+
120
+ **Example output:**
121
+ ```bash
122
+ Checking for platform packages in /tmp/couchnode-test/node_modules/@couchbase that do not match the expected platform package (couchbase-linux-x64-openssl1).
123
+ Found mismatch: Path=/tmp/couchnode-test/node_modules/@couchbase/couchbase-linuxmusl-x64-openssl1
53
124
 
54
- await coll.upsert('testdoc', { name: 'Frank' })
125
+ Recommendations for pruning:
55
126
 
56
- const res = await coll.get('testdoc')
57
- console.log(res.content)
127
+ Removing mismatched platform=couchbase-linuxmusl-x64-openssl1 (path=/tmp/couchnode-test/node_modules/@couchbase/couchbase-linuxmusl-x64-openssl1) saves ~13.31 MB on disk.
128
+ Removing Couchbase deps/ (path=/tmp/couchnode-test/node_modules/couchbase/deps) saves ~45.51 MB on disk.
129
+ Removing Couchbase src/ (path=/tmp/couchnode-test/node_modules/couchbase/src) saves ~0.61 MB on disk.
58
130
  ```
59
131
 
60
132
  ## Documentation
@@ -100,6 +100,7 @@ set(couchbase_cxx_client_FILES
100
100
  core/free_form_http_request.cxx
101
101
  core/key_value_config.cxx
102
102
  core/n1ql_query_options.cxx
103
+ core/origin.cxx
103
104
  core/range_scan_options.cxx
104
105
  core/range_scan_orchestrator.cxx
105
106
  core/retry_orchestrator.cxx
@@ -265,10 +266,10 @@ set(couchbase_cxx_client_FILES
265
266
  core/impl/boolean_query.cxx
266
267
  core/impl/build_deferred_query_indexes.cxx
267
268
  core/impl/cluster.cxx
268
- core/impl/collection_query_index_manager.cxx
269
269
  core/impl/common_error_category.cxx
270
270
  core/impl/configuration_profiles_registry.cxx
271
271
  core/impl/conjunction_query.cxx
272
+ core/impl/create_bucket.cxx
272
273
  core/impl/create_query_index.cxx
273
274
  core/impl/date_range.cxx
274
275
  core/impl/date_range_facet.cxx
@@ -277,24 +278,29 @@ set(couchbase_cxx_client_FILES
277
278
  core/impl/decrement.cxx
278
279
  core/impl/disjunction_query.cxx
279
280
  core/impl/dns_srv_tracker.cxx
281
+ core/impl/drop_bucket.cxx
280
282
  core/impl/drop_query_index.cxx
281
283
  core/impl/exists.cxx
282
284
  core/impl/expiry.cxx
283
285
  core/impl/fail_fast_retry_strategy.cxx
284
286
  core/impl/field_level_encryption_error_category.cxx
287
+ core/impl/flush_bucket.cxx
285
288
  core/impl/geo_bounding_box_query.cxx
286
289
  core/impl/geo_distance_query.cxx
287
290
  core/impl/geo_polygon_query.cxx
288
291
  core/impl/get.cxx
292
+ core/impl/get_all_buckets.cxx
289
293
  core/impl/get_all_query_indexes.cxx
290
294
  core/impl/get_all_replicas.cxx
291
295
  core/impl/get_and_lock.cxx
292
296
  core/impl/get_and_touch.cxx
293
297
  core/impl/get_any_replica.cxx
298
+ core/impl/get_bucket.cxx
294
299
  core/impl/get_replica.cxx
295
300
  core/impl/increment.cxx
296
301
  core/impl/insert.cxx
297
302
  core/impl/internal_date_range_facet_result.cxx
303
+ core/impl/internal_manager_error_context.cxx
298
304
  core/impl/internal_numeric_range_facet_result.cxx
299
305
  core/impl/internal_search_error_context.cxx
300
306
  core/impl/internal_search_meta_data.cxx
@@ -306,6 +312,7 @@ set(couchbase_cxx_client_FILES
306
312
  core/impl/key_value_error_context.cxx
307
313
  core/impl/lookup_in.cxx
308
314
  core/impl/management_error_category.cxx
315
+ core/impl/manager_error_context.cxx
309
316
  core/impl/match_all_query.cxx
310
317
  core/impl/match_none_query.cxx
311
318
  core/impl/match_phrase_query.cxx
@@ -368,6 +375,7 @@ set(couchbase_cxx_client_FILES
368
375
  core/impl/transaction_get_result.cxx
369
376
  core/impl/transaction_op_error_category.cxx
370
377
  core/impl/unlock.cxx
378
+ core/impl/update_bucket.cxx
371
379
  core/impl/upsert.cxx
372
380
  core/impl/view_error_category.cxx
373
381
  core/impl/watch_query_indexes.cxx
@@ -0,0 +1,234 @@
1
+ # Copyright 2020-2021 Couchbase, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require "openssl"
16
+ require "net/http"
17
+ require "json"
18
+
19
+ class Object
20
+ def to_b
21
+ ![nil, false, 0, "", "0", "f", "F", "false", "FALSE", "off", "OFF", "no", "NO"].include?(self)
22
+ end
23
+ end
24
+
25
+
26
+ class API
27
+ def initialize(options)
28
+ @options = options
29
+ connect
30
+ end
31
+
32
+ def connect
33
+ puts "# CONNECT #{@options}"
34
+ @client = Net::HTTP.start(@options[:host], @options[:port],
35
+ use_ssl: @options[:strict_encryption],
36
+ verify_mode: OpenSSL::SSL::VERIFY_NONE)
37
+ end
38
+
39
+ def url(path)
40
+ "#{@client.use_ssl? ? 'https' : 'http'}://#{@options[:username]}@#{@options[:host]}:#{@options[:port]}#{path}"
41
+ end
42
+
43
+ def decode_response(response)
44
+ payload =
45
+ if response['content-type'] =~ /application\/json/
46
+ JSON.parse(response.body)
47
+ else
48
+ response.body
49
+ end
50
+ if @options[:verbose]
51
+ p status: response.code, payload: payload
52
+ end
53
+ payload
54
+ end
55
+
56
+ def setup_request(request)
57
+ request.basic_auth(@options[:username], @options[:password])
58
+ request['accept'] = "application/json"
59
+ end
60
+
61
+ def get(path)
62
+ puts "# GET #{url(path)}"
63
+ req = Net::HTTP::Get.new(path)
64
+ setup_request(req)
65
+ res = @client.request(req)
66
+ decode_response(res)
67
+ rescue EOFError
68
+ connect
69
+ retry
70
+ rescue => ex
71
+ puts "#{__method__}: #{ex}, sleep for 1 second and retry"
72
+ sleep(1)
73
+ retry
74
+ end
75
+
76
+ def post_form(path, fields = {})
77
+ puts "# POST #{url(path)} #{fields}"
78
+ req = Net::HTTP::Post.new(path)
79
+ setup_request(req)
80
+ req.form_data = fields
81
+ res = @client.request(req)
82
+ decode_response(res)
83
+ rescue EOFError
84
+ connect
85
+ retry
86
+ rescue => ex
87
+ puts "#{__method__}: #{ex}, sleep for 1 second and retry"
88
+ sleep(1)
89
+ retry
90
+ end
91
+
92
+ def post_json(path, object)
93
+ data = JSON.generate(object)
94
+ puts "# POST #{url(path)} #{data}"
95
+ req = Net::HTTP::Post.new(path)
96
+ req['content-type'] = "application/json"
97
+ setup_request(req)
98
+ res = @client.request(req, data)
99
+ decode_response(res)
100
+ rescue EOFError
101
+ connect
102
+ retry
103
+ rescue => ex
104
+ puts "#{__method__}: #{ex}, sleep for 1 second and retry"
105
+ sleep(1)
106
+ retry
107
+ end
108
+
109
+ def put_json(path, object)
110
+ data = JSON.generate(object)
111
+ puts "# PUT #{url(path)} #{data}"
112
+ req = Net::HTTP::Put.new(path)
113
+ req['content-type'] = "application/json"
114
+ setup_request(req)
115
+ res = @client.request(req, data)
116
+ decode_response(res)
117
+ rescue EOFError
118
+ connect
119
+ retry
120
+ rescue => ex
121
+ puts "#{__method__}: #{ex}, sleep for 1 second and retry"
122
+ sleep(1)
123
+ retry
124
+ end
125
+
126
+ def delete(path)
127
+ puts "# DELETE #{url(path)}"
128
+ req = Net::HTTP::Delete.new(path)
129
+ setup_request(req)
130
+ res = @client.request(req)
131
+ decode_response(res)
132
+ rescue EOFError
133
+ connect
134
+ retry
135
+ rescue => ex
136
+ puts "#{__method__}: #{ex}, sleep for 1 second and retry"
137
+ sleep(1)
138
+ retry
139
+ end
140
+ end
141
+
142
+ def service_address_for_bucket(api, service, bucket, options)
143
+ port_key = options[:strict_encryption] ? "#{service}SSL" : service
144
+ host = nil
145
+ port = 0
146
+ while port.zero?
147
+ config = api.get("/pools/default/b/#{bucket}")
148
+ node_with_service = config["nodesExt"].find{|n| n["services"].key?(port_key)} rescue nil
149
+ if node_with_service
150
+ host = node_with_service["hostname"]
151
+ port = node_with_service["services"][port_key].to_i rescue 0
152
+ end
153
+ sleep 1
154
+ end
155
+ {host: host || options[:host], port: port}
156
+ end
157
+
158
+ def ensure_search_index_created(index_definition_path, options)
159
+ loop do
160
+ catch :retry do
161
+ search_api = API.new(options)
162
+
163
+ puts "using index definition: #{File.basename(index_definition_path)}"
164
+ index_definition = JSON.load(File.read(index_definition_path))
165
+ search_api.put_json("/api/index/travel-sample-index", index_definition)
166
+
167
+ expected_number_of_the_documents = 1000
168
+ indexed_documents = 0
169
+ times_zero_documents_has_been_seen = 0
170
+ Timeout.timeout(10 * 60) do # give it 10 minutes to index
171
+ while indexed_documents < expected_number_of_the_documents
172
+ resp = search_api.get("/api/index/travel-sample-index/count")
173
+ indexed_documents = resp['count'].to_i
174
+ times_zero_documents_has_been_seen += 1 if indexed_documents.zero?
175
+ if times_zero_documents_has_been_seen >= 60
176
+ # lets not tolerate 60 seconds of not getting data indexed
177
+ search_api.delete("/api/index/travel-sample-index")
178
+ throw :retry
179
+ end
180
+ sleep 1
181
+ end
182
+ end
183
+ return
184
+ end
185
+ end
186
+ end
187
+
188
+ def ensure_sample_bucket_loaded(management_api, expected_number_of_the_documents, options)
189
+ loop do
190
+ catch :retry do
191
+ management_api.post_json("/sampleBuckets/install", [options[:bucket]])
192
+
193
+ service_address = nil
194
+ begin
195
+ Timeout.timeout(60) do # a minute for bucket creation
196
+ service_address = service_address_for_bucket(management_api, "n1ql", options[:bucket], options)
197
+ end
198
+ rescue Timeout::Error
199
+ management_api.delete("/pools/default/buckets/#{options[:bucket]}")
200
+ sleep 1
201
+ throw :retry
202
+ end
203
+ puts query_service: service_address
204
+
205
+ query_api = API.new(options.merge(service_address))
206
+ puts "create index for bucket \"#{options[:bucket]}\""
207
+
208
+ query_api.post_form("/query/service", statement: "CREATE PRIMARY INDEX ON `#{options[:bucket]}` USING GSI", timeout: "300s")
209
+
210
+ indexed_documents = 0
211
+ times_zero_documents_has_been_seen = 0
212
+ Timeout.timeout(10 * 60) do # give it 10 minutes to index
213
+ while indexed_documents < expected_number_of_the_documents
214
+ resp = query_api.post_form("/query/service", statement: "SELECT RAW COUNT(*) FROM `#{options[:bucket]}`")
215
+ indexed_documents = resp["results"][0].to_i rescue 0
216
+
217
+ if indexed_documents.zero?
218
+ times_zero_documents_has_been_seen += 1
219
+ puts times_zero_documents_has_been_seen: times_zero_documents_has_been_seen
220
+ end
221
+ if times_zero_documents_has_been_seen >= 60
222
+ # lets not tolerate 60 seconds of not getting data indexed
223
+ query_api.post_form("/query/service", statement: "DROP PRIMARY INDEX ON `#{options[:bucket]}`")
224
+ management_api.delete("/pools/default/buckets/#{options[:bucket]}")
225
+ sleep 1
226
+ throw :retry
227
+ end
228
+ sleep 1
229
+ end
230
+ end
231
+ return
232
+ end
233
+ end
234
+ end
@@ -15,150 +15,33 @@
15
15
  # limitations under the License.
16
16
 
17
17
  require "timeout"
18
- require "net/http"
19
- require "json"
20
- require "openssl"
21
18
 
22
- class API
23
- def initialize(options)
24
- @options = options
25
- connect
26
- end
27
-
28
- def connect
29
- puts "# CONNECT #{@options}"
30
- @client = Net::HTTP.start(@options[:host], @options[:port],
31
- use_ssl: @options[:strict_encryption],
32
- verify_mode: OpenSSL::SSL::VERIFY_NONE)
33
- end
34
-
35
- def url(path)
36
- "#{@client.use_ssl? ? 'https' : 'http'}://#{@options[:username]}@#{@options[:host]}:#{@options[:port]}#{path}"
37
- end
38
-
39
- def decode_response(response)
40
- payload =
41
- if response['content-type'] =~ /application\/json/
42
- JSON.parse(response.body)
43
- else
44
- response.body
45
- end
46
- p payload if @options[:verbose]
47
- payload
48
- end
49
-
50
- def setup_request(request)
51
- request.basic_auth(@options[:username], @options[:password])
52
- request['accept'] = "application/json"
53
- end
54
-
55
- def get(path)
56
- puts "# GET #{url(path)}"
57
- req = Net::HTTP::Get.new(path)
58
- setup_request(req)
59
- res = @client.request(req)
60
- decode_response(res)
61
- rescue EOFError
62
- connect
63
- retry
64
- rescue => ex
65
- puts "#{__method__}: #{ex}, sleep for 1 second and retry"
66
- sleep(1)
67
- retry
68
- end
69
-
70
- def post_form(path, fields = {})
71
- puts "# POST #{url(path)} #{fields}"
72
- req = Net::HTTP::Post.new(path)
73
- setup_request(req)
74
- req.form_data = fields
75
- res = @client.request(req)
76
- decode_response(res)
77
- rescue EOFError
78
- connect
79
- retry
80
- rescue => ex
81
- puts "#{__method__}: #{ex}, sleep for 1 second and retry"
82
- sleep(1)
83
- retry
84
- end
85
-
86
- def post_json(path, object)
87
- data = JSON.generate(object)
88
- puts "# POST #{url(path)} #{data}"
89
- req = Net::HTTP::Post.new(path)
90
- req['content-type'] = "application/json"
91
- setup_request(req)
92
- res = @client.request(req, data)
93
- decode_response(res)
94
- rescue EOFError
95
- connect
96
- retry
97
- rescue => ex
98
- puts "#{__method__}: #{ex}, sleep for 1 second and retry"
99
- sleep(1)
100
- retry
101
- end
102
-
103
- def put_json(path, object)
104
- data = JSON.generate(object)
105
- puts "# PUT #{url(path)} #{data}"
106
- req = Net::HTTP::Put.new(path)
107
- req['content-type'] = "application/json"
108
- setup_request(req)
109
- res = @client.request(req, data)
110
- decode_response(res)
111
- rescue EOFError
112
- connect
113
- retry
114
- rescue => ex
115
- puts "#{__method__}: #{ex}, sleep for 1 second and retry"
116
- sleep(1)
117
- retry
118
- end
119
- end
120
-
121
- def service_port_for_bucket(api, service, bucket, options)
122
- port_key = options[:strict_encryption] ? "#{service}SSL" : service
123
- port = 0
124
- while port.zero?
125
- config = api.get("/pools/default/b/#{bucket}")
126
- port = config["nodesExt"].find{|n| n["services"].key?(port_key)}["services"][port_key].to_i rescue 0
127
- sleep 1
128
- end
129
- port
130
- end
19
+ require_relative "api"
131
20
 
132
21
  options = {
133
- host: ARGV[0] || "127.0.0.1",
134
- strict_encryption: ARGV[1] == "true" || ARGV[1] == "1",
135
- username: ARGV[2] || "Administrator",
136
- password: ARGV[3] || "password",
22
+ host: ENV.fetch("CB_HOST", ARGV[0] || "127.0.0.1"),
23
+ strict_encryption: ENV.fetch("CB_STRICT_ENCRYPTION", ARGV[1]).to_b,
24
+ username: ENV.fetch("CB_USERNAME", ARGV[2] || "Administrator"),
25
+ password: ENV.fetch("CB_PASSWORD", ARGV[3] || "password"),
26
+ verbose: ENV.fetch("CB_VERBOSE", true).to_b,
137
27
  bucket: "travel-sample",
138
- verbose: true,
139
28
  }
140
29
  p options: options
141
30
 
142
- management_api = API.new(options.merge(port: options[:strict_encryption] ? 18091 : 8091))
143
- search_service_port = service_port_for_bucket(management_api, "fts", options[:bucket], options)
31
+ management_api =
32
+ begin
33
+ API.new(options.merge(port: options[:strict_encryption] ? 18091 : 8091))
34
+ rescue => ex
35
+ puts "#{ex}, sleep for 1 second and retry"
36
+ sleep(1)
37
+ retry
38
+ end
39
+ service_address = service_address_for_bucket(management_api, "fts", options[:bucket], options)
40
+ p search_service: service_address
144
41
 
145
- has_v6_nodes =
42
+ has_v6_nodes =
146
43
  management_api.get("/pools/default")["nodes"]
147
44
  .any? { |node| node["version"] =~ /^6\./ && node["services"].include?("fts") }
148
45
 
149
- search_api = API.new(options.merge(port: search_service_port))
150
46
  index_definition_path = File.join(__dir__, "travel-sample-index#{"-v6" if has_v6_nodes}.json")
151
- puts "using index definition: #{File.basename(index_definition_path)}"
152
- index_definition = JSON.load(File.read(index_definition_path))
153
- search_api.put_json("/api/index/travel-sample-index", index_definition)
154
-
155
- expected_number_of_the_documents = 1000
156
- indexed_documents = 0
157
-
158
- Timeout.timeout(10 * 60) do # give it 10 minutes to index
159
- while indexed_documents < expected_number_of_the_documents
160
- resp = search_api.get("/api/index/travel-sample-index/count")
161
- indexed_documents = resp['count'].to_i
162
- sleep 1
163
- end
164
- end
47
+ ensure_search_index_created(index_definition_path, options.merge(service_address))