couchbase 4.2.5 → 4.2.6-dev

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. package/deps/couchbase-cxx-client/CMakeLists.txt +9 -1
  2. package/deps/couchbase-cxx-client/bin/api.rb +234 -0
  3. package/deps/couchbase-cxx-client/bin/create-search-index +18 -135
  4. package/deps/couchbase-cxx-client/bin/init-cluster +17 -139
  5. package/deps/couchbase-cxx-client/bin/load-sample-buckets +54 -0
  6. package/deps/couchbase-cxx-client/core/cluster.hxx +33 -12
  7. package/deps/couchbase-cxx-client/core/cluster_options.hxx +3 -0
  8. package/deps/couchbase-cxx-client/core/crud_component.cxx +51 -22
  9. package/deps/couchbase-cxx-client/core/impl/build_deferred_query_indexes.cxx +115 -50
  10. package/deps/couchbase-cxx-client/core/impl/cluster.cxx +6 -0
  11. package/deps/couchbase-cxx-client/core/impl/create_bucket.cxx +155 -0
  12. package/deps/couchbase-cxx-client/core/impl/create_query_index.cxx +172 -59
  13. package/deps/couchbase-cxx-client/core/impl/dns_srv_tracker.cxx +2 -1
  14. package/deps/couchbase-cxx-client/core/impl/drop_bucket.cxx +66 -0
  15. package/deps/couchbase-cxx-client/core/impl/drop_query_index.cxx +138 -59
  16. package/deps/couchbase-cxx-client/core/impl/flush_bucket.cxx +66 -0
  17. package/deps/couchbase-cxx-client/core/impl/get_all_buckets.cxx +163 -0
  18. package/deps/couchbase-cxx-client/core/impl/get_all_query_indexes.cxx +67 -37
  19. package/deps/couchbase-cxx-client/core/impl/get_bucket.cxx +153 -0
  20. package/deps/couchbase-cxx-client/core/impl/internal_manager_error_context.cxx +113 -0
  21. package/deps/couchbase-cxx-client/core/impl/internal_manager_error_context.hxx +60 -0
  22. package/deps/couchbase-cxx-client/core/impl/key_value_error_category.cxx +2 -4
  23. package/deps/couchbase-cxx-client/core/impl/manager_error_context.cxx +100 -0
  24. package/deps/couchbase-cxx-client/core/impl/query.cxx +1 -0
  25. package/deps/couchbase-cxx-client/core/impl/update_bucket.cxx +130 -0
  26. package/deps/couchbase-cxx-client/core/impl/watch_query_indexes.cxx +53 -29
  27. package/deps/couchbase-cxx-client/core/io/dns_client.cxx +71 -38
  28. package/deps/couchbase-cxx-client/core/io/dns_config.cxx +5 -4
  29. package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +5 -6
  30. package/deps/couchbase-cxx-client/core/meta/features.hxx +6 -0
  31. package/deps/couchbase-cxx-client/core/operations/document_query.cxx +11 -0
  32. package/deps/couchbase-cxx-client/core/operations/document_query.hxx +1 -0
  33. package/deps/couchbase-cxx-client/core/origin.cxx +270 -0
  34. package/deps/couchbase-cxx-client/core/origin.hxx +2 -0
  35. package/deps/couchbase-cxx-client/core/protocol/status.cxx +2 -2
  36. package/deps/couchbase-cxx-client/core/range_scan_options.cxx +3 -27
  37. package/deps/couchbase-cxx-client/core/range_scan_options.hxx +13 -17
  38. package/deps/couchbase-cxx-client/core/range_scan_orchestrator.cxx +367 -170
  39. package/deps/couchbase-cxx-client/core/range_scan_orchestrator.hxx +13 -2
  40. package/deps/couchbase-cxx-client/core/range_scan_orchestrator_options.hxx +5 -3
  41. package/deps/couchbase-cxx-client/core/scan_options.hxx +0 -19
  42. package/deps/couchbase-cxx-client/core/scan_result.cxx +19 -5
  43. package/deps/couchbase-cxx-client/core/scan_result.hxx +5 -2
  44. package/deps/couchbase-cxx-client/core/timeout_defaults.hxx +2 -3
  45. package/deps/couchbase-cxx-client/core/topology/capabilities.hxx +1 -0
  46. package/deps/couchbase-cxx-client/core/topology/capabilities_fmt.hxx +2 -0
  47. package/deps/couchbase-cxx-client/core/topology/collections_manifest_fmt.hxx +1 -1
  48. package/deps/couchbase-cxx-client/core/topology/configuration.hxx +5 -0
  49. package/deps/couchbase-cxx-client/core/topology/configuration_json.hxx +2 -0
  50. package/deps/couchbase-cxx-client/core/utils/connection_string.cxx +4 -0
  51. package/deps/couchbase-cxx-client/couchbase/behavior_options.hxx +19 -2
  52. package/deps/couchbase-cxx-client/couchbase/bucket_manager.hxx +135 -0
  53. package/deps/couchbase-cxx-client/couchbase/build_query_index_options.hxx +0 -30
  54. package/deps/couchbase-cxx-client/couchbase/cluster.hxx +14 -0
  55. package/deps/couchbase-cxx-client/couchbase/collection_query_index_manager.hxx +7 -48
  56. package/deps/couchbase-cxx-client/couchbase/create_bucket_options.hxx +41 -0
  57. package/deps/couchbase-cxx-client/couchbase/create_primary_query_index_options.hxx +0 -29
  58. package/deps/couchbase-cxx-client/couchbase/create_query_index_options.hxx +0 -33
  59. package/deps/couchbase-cxx-client/couchbase/drop_bucket_options.hxx +41 -0
  60. package/deps/couchbase-cxx-client/couchbase/drop_primary_query_index_options.hxx +0 -30
  61. package/deps/couchbase-cxx-client/couchbase/drop_query_index_options.hxx +0 -31
  62. package/deps/couchbase-cxx-client/couchbase/error_codes.hxx +1 -2
  63. package/deps/couchbase-cxx-client/couchbase/flush_bucket_options.hxx +41 -0
  64. package/deps/couchbase-cxx-client/couchbase/get_all_buckets_options.hxx +44 -0
  65. package/deps/couchbase-cxx-client/couchbase/get_all_query_indexes_options.hxx +0 -30
  66. package/deps/couchbase-cxx-client/couchbase/get_bucket_options.hxx +43 -0
  67. package/deps/couchbase-cxx-client/couchbase/management/bucket_settings.hxx +116 -0
  68. package/deps/couchbase-cxx-client/couchbase/manager_error_context.hxx +29 -53
  69. package/deps/couchbase-cxx-client/couchbase/query_index_manager.hxx +16 -83
  70. package/deps/couchbase-cxx-client/couchbase/query_options.hxx +18 -0
  71. package/deps/couchbase-cxx-client/couchbase/security_options.hxx +15 -0
  72. package/deps/couchbase-cxx-client/couchbase/update_bucket_options.hxx +41 -0
  73. package/deps/couchbase-cxx-client/couchbase/watch_query_indexes_options.hxx +0 -31
  74. package/deps/couchbase-cxx-client/docs/cbc-analytics.md +1 -0
  75. package/deps/couchbase-cxx-client/docs/cbc-get.md +1 -0
  76. package/deps/couchbase-cxx-client/docs/cbc-pillowfight.md +1 -0
  77. package/deps/couchbase-cxx-client/docs/cbc-query.md +1 -0
  78. package/deps/couchbase-cxx-client/docs/cbc.md +10 -0
  79. package/deps/couchbase-cxx-client/test/CMakeLists.txt +1 -0
  80. package/deps/couchbase-cxx-client/test/test_integration_collections.cxx +6 -0
  81. package/deps/couchbase-cxx-client/test/test_integration_crud.cxx +5 -0
  82. package/deps/couchbase-cxx-client/test/test_integration_examples.cxx +137 -1
  83. package/deps/couchbase-cxx-client/test/test_integration_management.cxx +709 -266
  84. package/deps/couchbase-cxx-client/test/test_integration_query.cxx +19 -7
  85. package/deps/couchbase-cxx-client/test/test_integration_range_scan.cxx +351 -112
  86. package/deps/couchbase-cxx-client/test/test_integration_search.cxx +10 -1
  87. package/deps/couchbase-cxx-client/test/test_transaction_public_async_api.cxx +13 -12
  88. package/deps/couchbase-cxx-client/test/test_transaction_public_blocking_api.cxx +27 -21
  89. package/deps/couchbase-cxx-client/test/test_unit_query.cxx +75 -0
  90. package/deps/couchbase-cxx-client/test/utils/server_version.hxx +5 -0
  91. package/deps/couchbase-cxx-client/test/utils/wait_until.cxx +29 -10
  92. package/deps/couchbase-cxx-client/test/utils/wait_until.hxx +3 -1
  93. package/deps/couchbase-cxx-client/tools/utils.cxx +4 -1
  94. package/dist/binding.d.ts +21 -16
  95. package/dist/binding.js +1 -4
  96. package/dist/bindingutilities.d.ts +6 -1
  97. package/dist/bindingutilities.js +36 -1
  98. package/dist/collection.d.ts +65 -3
  99. package/dist/collection.js +107 -0
  100. package/dist/crudoptypes.d.ts +34 -0
  101. package/dist/crudoptypes.js +18 -1
  102. package/dist/queryexecutor.js +1 -0
  103. package/dist/querytypes.d.ts +7 -0
  104. package/dist/rangeScan.d.ts +107 -0
  105. package/dist/rangeScan.js +91 -0
  106. package/dist/streamablepromises.d.ts +6 -0
  107. package/dist/streamablepromises.js +25 -1
  108. package/package.json +12 -13
  109. package/src/addondata.hpp +1 -0
  110. package/src/binding.cpp +5 -2
  111. package/src/connection.cpp +108 -2
  112. package/src/connection.hpp +1 -0
  113. package/src/constants.cpp +2 -12
  114. package/src/jstocbpp_autogen.hpp +49 -22
  115. package/src/jstocbpp_basic.hpp +2 -8
  116. package/src/mutationtoken.cpp +13 -0
  117. package/src/scan_iterator.cpp +90 -0
  118. package/src/scan_iterator.hpp +30 -0
  119. package/tools/gen-bindings-json.py +9 -8
  120. package/deps/couchbase-cxx-client/core/impl/collection_query_index_manager.cxx +0 -93
@@ -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))
@@ -17,13 +17,8 @@
17
17
  require "set"
18
18
  require "timeout"
19
19
  require "optparse"
20
- require "openssl"
21
20
 
22
- class Object
23
- def to_b
24
- ![nil, false, 0, "", "0", "f", "F", "false", "FALSE", "off", "OFF", "no", "NO"].include?(self)
25
- end
26
- end
21
+ require_relative "api"
27
22
 
28
23
  options = {
29
24
  verbose: ENV.fetch("CB_VERBOSE", true).to_b,
@@ -49,106 +44,6 @@ options[:port] = ENV.fetch("CB_PORT", default_port).to_i
49
44
  options[:sample_buckets] << "beer-sample" if ENV.fetch("CB_BEER_SAMPLE", false).to_b
50
45
  options[:sample_buckets] << "travel-sample" if ENV.fetch("CB_TRAVEL_SAMPLE", false).to_b
51
46
 
52
- require "net/http"
53
- require "json"
54
-
55
- class API
56
- def initialize(options)
57
- @options = options
58
- connect
59
- end
60
-
61
- def connect
62
- @client = Net::HTTP.start(@options[:host], @options[:port],
63
- use_ssl: @options[:strict_encryption],
64
- verify_mode: OpenSSL::SSL::VERIFY_NONE)
65
- end
66
-
67
- def url(path)
68
- "#{@client.use_ssl? ? 'https' : 'http'}://#{@options[:username]}@#{@options[:host]}:#{@options[:port]}#{path}"
69
- end
70
-
71
- def decode_response(response)
72
- payload =
73
- if /application\/json/.match?(response['content-type'])
74
- JSON.parse(response.body)
75
- else
76
- response.body
77
- end
78
- p payload if @options[:verbose]
79
- payload
80
- end
81
-
82
- def setup_request(request)
83
- request.basic_auth(@options[:username], @options[:password])
84
- request['accept'] = "application/json"
85
- end
86
-
87
- def get(path)
88
- puts "# GET #{url(path)}"
89
- req = Net::HTTP::Get.new(path)
90
- setup_request(req)
91
- res = @client.request(req)
92
- decode_response(res)
93
- rescue EOFError
94
- connect
95
- retry
96
- rescue => ex
97
- puts "#{__method__}: #{ex}, sleep for 1 second and retry"
98
- sleep(1)
99
- retry
100
- end
101
-
102
- def post_form(path, fields = {})
103
- puts "# POST #{url(path)} #{fields}"
104
- req = Net::HTTP::Post.new(path)
105
- setup_request(req)
106
- req.form_data = fields
107
- res = @client.request(req)
108
- decode_response(res)
109
- rescue EOFError
110
- connect
111
- retry
112
- rescue => ex
113
- puts "#{__method__}: #{ex}, sleep for 1 second and retry"
114
- sleep(1)
115
- retry
116
- end
117
-
118
- def post_json(path, object)
119
- data = JSON.generate(object)
120
- puts "# POST #{url(path)} #{data}"
121
- req = Net::HTTP::Post.new(path)
122
- req['content-type'] = "application/json"
123
- setup_request(req)
124
- res = @client.request(req, data)
125
- decode_response(res)
126
- rescue EOFError
127
- connect
128
- retry
129
- rescue => ex
130
- puts "#{__method__}: #{ex}, sleep for 1 second and retry"
131
- sleep(1)
132
- retry
133
- end
134
-
135
- def put_json(path, object)
136
- data = JSON.generate(object)
137
- puts "# PUT #{url(path)} #{data}"
138
- req = Net::HTTP::Put.new(path)
139
- req['content-type'] = "application/json"
140
- setup_request(req)
141
- res = @client.request(req, data)
142
- decode_response(res)
143
- rescue EOFError
144
- connect
145
- retry
146
- rescue => ex
147
- puts "#{__method__}: #{ex}, sleep for 1 second and retry"
148
- sleep(1)
149
- retry
150
- end
151
- end
152
47
 
153
48
  api =
154
49
  begin
@@ -180,7 +75,10 @@ api.post_form("/settings/web",
180
75
  password: options[:password],
181
76
  username: options[:username],
182
77
  port: "SAME")
183
- api.post_form("/settings/indexes", storageMode: "plasma")
78
+ res = api.post_form("/settings/indexes", storageMode: "plasma")
79
+ if res["errors"]
80
+ res = api.post_form("/settings/indexes", storageMode: "forestdb")
81
+ end
184
82
 
185
83
  if options[:cluster_run_nodes] > 1
186
84
  known_nodes = []
@@ -235,50 +133,30 @@ if options[:sec_bucket].to_b
235
133
  name: options[:sec_bucket])
236
134
  end
237
135
 
238
- api.post_json("/sampleBuckets/install", options[:sample_buckets].to_a) if options[:sample_buckets].any?
239
-
240
136
  api.post_form("/settings/developerPreview", enabled: true) if options[:enable_developer_preview]
241
137
 
242
- def service_port_for_bucket(api, service, bucket, options)
243
- port_key = options[:strict_encryption] ? "#{service}SSL" : service
244
- port = 0
245
- while port.zero?
246
- config = api.get("/pools/default/b/#{bucket}")
247
- port = config["nodesExt"].find{|n| n["services"].key?(port_key)}["services"][port_key].to_i rescue 0
248
- sleep 1
249
- end
250
- port
251
- end
138
+ service_address = service_address_for_bucket(api, "n1ql", options[:bucket], options)
139
+ puts query_service: service_address
252
140
 
253
- query_api = API.new(options.merge(port: service_port_for_bucket(api, "n1ql", options[:bucket], options)))
141
+ query_api = API.new(options.merge(service_address))
254
142
  query_api.post_form("/query/service", statement: "CREATE PRIMARY INDEX ON `#{options[:bucket]}` USING GSI")
143
+
144
+ expected_counts = {
145
+ "travel-sample" => 30_000,
146
+ "beer-sample" => 7_000,
147
+ }
255
148
  options[:sample_buckets].each do |bucket|
256
- service_port_for_bucket(api, "n1ql", bucket, options)
257
- query_api.post_form("/query/service", statement: "CREATE PRIMARY INDEX ON `#{bucket}` USING GSI")
149
+ ensure_sample_bucket_loaded(api, expected_counts[bucket], options.merge(bucket: bucket))
258
150
  end
259
151
 
260
- puts service_port_for_bucket(api, "fts", options[:bucket], options)
261
-
262
152
  if options[:sample_buckets].include?("travel-sample") && services.include?("fts")
263
- search_api = API.new(options.merge(port: service_port_for_bucket(api, "fts", options[:bucket], options)))
153
+ service_address = service_address_for_bucket(api, "fts", options[:bucket], options)
154
+ puts search_service: service_address
264
155
 
265
156
  has_v6_nodes =
266
157
  api.get("/pools/default")["nodes"]
267
158
  .any? { |node| node["version"] =~ /^6\./ && node["services"].include?("fts") }
268
-
269
159
  index_definition_path = File.join(__dir__, "travel-sample-index#{"-v6" if has_v6_nodes}.json")
270
- puts "using index definition: #{File.basename(index_definition_path)}"
271
- index_definition = JSON.load(File.read(index_definition_path))
272
- search_api.put_json("/api/index/travel-sample-index", index_definition)
273
-
274
- expected_number_of_the_documents = 1000
275
- indexed_documents = 0
276
- Timeout.timeout(10 * 60) do # give it 10 minutes to index
277
- while indexed_documents < expected_number_of_the_documents
278
- resp = search_api.get("/api/index/travel-sample-index/count")
279
- indexed_documents = resp['count'].to_i
280
- sleep 1
281
- end
282
- end
160
+ ensure_search_index_created(index_definition_path, options.merge(service_address))
283
161
  end
284
162