couchbase 3.1.1-universal-darwin-20 → 3.2.0-universal-darwin-20

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 (221) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/ext/CMakeLists.txt +3 -1
  4. data/ext/build_version.hxx.in +1 -1
  5. data/ext/cmake/Testing.cmake +1 -0
  6. data/ext/cmake/ThirdPartyDependencies.cmake +6 -0
  7. data/ext/cmake/VersionInfo.cmake +3 -0
  8. data/ext/couchbase/bucket.hxx +47 -28
  9. data/ext/couchbase/cbsasl/client.h +1 -1
  10. data/ext/couchbase/cbsasl/context.cc +1 -1
  11. data/ext/couchbase/cbsasl/context.h +3 -3
  12. data/ext/couchbase/cbsasl/mechanism.cc +5 -8
  13. data/ext/couchbase/cbsasl/mechanism.h +1 -4
  14. data/ext/couchbase/cbsasl/plain/plain.cc +1 -1
  15. data/ext/couchbase/cbsasl/scram-sha/scram-sha.cc +30 -36
  16. data/ext/couchbase/cluster.hxx +40 -22
  17. data/ext/couchbase/cluster_options.hxx +7 -1
  18. data/ext/couchbase/configuration.hxx +37 -16
  19. data/ext/couchbase/couchbase.cxx +1145 -291
  20. data/ext/couchbase/error_map.hxx +1 -1
  21. data/ext/couchbase/errors.hxx +25 -17
  22. data/ext/couchbase/io/dns_client.hxx +3 -3
  23. data/ext/couchbase/io/dns_codec.hxx +4 -5
  24. data/ext/couchbase/io/dns_config.hxx +5 -6
  25. data/ext/couchbase/io/dns_message.hxx +3 -3
  26. data/ext/couchbase/io/http_command.hxx +70 -35
  27. data/ext/couchbase/io/http_session.hxx +4 -3
  28. data/ext/couchbase/io/http_session_manager.hxx +28 -19
  29. data/ext/couchbase/io/mcbp_command.hxx +51 -19
  30. data/ext/couchbase/io/mcbp_context.hxx +1 -1
  31. data/ext/couchbase/io/mcbp_parser.hxx +4 -4
  32. data/ext/couchbase/io/mcbp_session.hxx +91 -101
  33. data/ext/couchbase/io/query_cache.hxx +2 -2
  34. data/ext/couchbase/io/retry_orchestrator.hxx +2 -4
  35. data/ext/couchbase/io/retry_reason.hxx +2 -2
  36. data/ext/couchbase/io/retry_strategy.hxx +1 -6
  37. data/ext/couchbase/io/streams.hxx +7 -7
  38. data/ext/couchbase/metrics/logging_meter.hxx +228 -0
  39. data/ext/couchbase/metrics/logging_meter_options.hxx +28 -0
  40. data/ext/couchbase/metrics/meter.hxx +49 -0
  41. data/ext/couchbase/metrics/noop_meter.hxx +43 -0
  42. data/ext/couchbase/operations.hxx +4 -0
  43. data/ext/couchbase/operations/analytics_dataset_create.hxx +16 -12
  44. data/ext/couchbase/operations/analytics_dataset_drop.hxx +11 -11
  45. data/ext/couchbase/operations/analytics_dataset_get_all.hxx +6 -6
  46. data/ext/couchbase/operations/analytics_dataverse_create.hxx +10 -11
  47. data/ext/couchbase/operations/analytics_dataverse_drop.hxx +10 -11
  48. data/ext/couchbase/operations/analytics_get_pending_mutations.hxx +9 -11
  49. data/ext/couchbase/operations/analytics_index_create.hxx +14 -13
  50. data/ext/couchbase/operations/analytics_index_drop.hxx +18 -12
  51. data/ext/couchbase/operations/analytics_index_get_all.hxx +8 -6
  52. data/ext/couchbase/operations/analytics_link.hxx +39 -0
  53. data/ext/couchbase/operations/analytics_link_azure_blob_external.hxx +145 -0
  54. data/ext/couchbase/operations/analytics_link_connect.hxx +14 -12
  55. data/ext/couchbase/operations/analytics_link_couchbase_remote.hxx +220 -0
  56. data/ext/couchbase/operations/analytics_link_create.hxx +128 -0
  57. data/ext/couchbase/operations/analytics_link_disconnect.hxx +11 -12
  58. data/ext/couchbase/operations/analytics_link_drop.hxx +130 -0
  59. data/ext/couchbase/operations/analytics_link_get_all.hxx +160 -0
  60. data/ext/couchbase/operations/analytics_link_replace.hxx +128 -0
  61. data/ext/couchbase/operations/analytics_link_s3_external.hxx +122 -0
  62. data/ext/couchbase/operations/bucket_create.hxx +8 -8
  63. data/ext/couchbase/operations/bucket_drop.hxx +5 -5
  64. data/ext/couchbase/operations/bucket_flush.hxx +5 -5
  65. data/ext/couchbase/operations/bucket_get.hxx +7 -7
  66. data/ext/couchbase/operations/bucket_get_all.hxx +7 -5
  67. data/ext/couchbase/operations/bucket_settings.hxx +40 -49
  68. data/ext/couchbase/operations/bucket_update.hxx +8 -8
  69. data/ext/couchbase/operations/cluster_developer_preview_enable.hxx +7 -7
  70. data/ext/couchbase/operations/collection_create.hxx +11 -11
  71. data/ext/couchbase/operations/collection_drop.hxx +12 -10
  72. data/ext/couchbase/operations/collections_manifest_get.hxx +3 -3
  73. data/ext/couchbase/operations/design_document.hxx +2 -2
  74. data/ext/couchbase/operations/document_analytics.hxx +29 -36
  75. data/ext/couchbase/operations/document_append.hxx +3 -3
  76. data/ext/couchbase/operations/document_decrement.hxx +3 -3
  77. data/ext/couchbase/operations/document_exists.hxx +2 -2
  78. data/ext/couchbase/operations/document_get.hxx +3 -3
  79. data/ext/couchbase/operations/document_get_and_lock.hxx +5 -3
  80. data/ext/couchbase/operations/document_get_and_touch.hxx +5 -3
  81. data/ext/couchbase/operations/document_get_projected.hxx +10 -11
  82. data/ext/couchbase/operations/document_increment.hxx +3 -3
  83. data/ext/couchbase/operations/document_insert.hxx +3 -3
  84. data/ext/couchbase/operations/document_lookup_in.hxx +12 -18
  85. data/ext/couchbase/operations/document_mutate_in.hxx +13 -18
  86. data/ext/couchbase/operations/document_prepend.hxx +3 -3
  87. data/ext/couchbase/operations/document_query.hxx +39 -41
  88. data/ext/couchbase/operations/document_remove.hxx +3 -3
  89. data/ext/couchbase/operations/document_replace.hxx +3 -3
  90. data/ext/couchbase/operations/document_search.hxx +56 -61
  91. data/ext/couchbase/operations/document_touch.hxx +3 -3
  92. data/ext/couchbase/operations/document_unlock.hxx +3 -3
  93. data/ext/couchbase/operations/document_upsert.hxx +3 -3
  94. data/ext/couchbase/operations/document_view.hxx +23 -23
  95. data/ext/couchbase/operations/group_drop.hxx +5 -5
  96. data/ext/couchbase/operations/group_get.hxx +7 -7
  97. data/ext/couchbase/operations/group_get_all.hxx +6 -6
  98. data/ext/couchbase/operations/group_upsert.hxx +11 -11
  99. data/ext/couchbase/operations/http_noop.hxx +6 -6
  100. data/ext/couchbase/operations/mcbp_noop.hxx +3 -3
  101. data/ext/couchbase/operations/query_index_build_deferred.hxx +6 -6
  102. data/ext/couchbase/operations/query_index_create.hxx +10 -8
  103. data/ext/couchbase/operations/query_index_drop.hxx +8 -8
  104. data/ext/couchbase/operations/query_index_get_all.hxx +43 -39
  105. data/ext/couchbase/operations/rbac.hxx +40 -63
  106. data/ext/couchbase/operations/role_get_all.hxx +6 -6
  107. data/ext/couchbase/operations/scope_create.hxx +10 -10
  108. data/ext/couchbase/operations/scope_drop.hxx +9 -9
  109. data/ext/couchbase/operations/scope_get_all.hxx +8 -8
  110. data/ext/couchbase/operations/search_get_stats.hxx +5 -3
  111. data/ext/couchbase/operations/search_index.hxx +6 -15
  112. data/ext/couchbase/operations/search_index_analyze_document.hxx +11 -11
  113. data/ext/couchbase/operations/search_index_control_ingest.hxx +9 -9
  114. data/ext/couchbase/operations/search_index_control_plan_freeze.hxx +9 -9
  115. data/ext/couchbase/operations/search_index_control_query.hxx +9 -9
  116. data/ext/couchbase/operations/search_index_drop.hxx +11 -9
  117. data/ext/couchbase/operations/search_index_get.hxx +11 -9
  118. data/ext/couchbase/operations/search_index_get_all.hxx +11 -11
  119. data/ext/couchbase/operations/search_index_get_documents_count.hxx +10 -10
  120. data/ext/couchbase/operations/search_index_get_stats.hxx +10 -8
  121. data/ext/couchbase/operations/search_index_upsert.hxx +12 -10
  122. data/ext/couchbase/operations/user_drop.hxx +5 -5
  123. data/ext/couchbase/operations/user_get.hxx +7 -7
  124. data/ext/couchbase/operations/user_get_all.hxx +6 -6
  125. data/ext/couchbase/operations/user_upsert.hxx +9 -9
  126. data/ext/couchbase/operations/view_index_drop.hxx +10 -10
  127. data/ext/couchbase/operations/view_index_get.hxx +13 -15
  128. data/ext/couchbase/operations/view_index_get_all.hxx +17 -20
  129. data/ext/couchbase/operations/view_index_upsert.hxx +9 -7
  130. data/ext/couchbase/origin.hxx +14 -10
  131. data/ext/couchbase/platform/backtrace.c +1 -1
  132. data/ext/couchbase/platform/base64.cc +5 -5
  133. data/ext/couchbase/platform/base64.h +2 -5
  134. data/ext/couchbase/protocol/client_opcode.hxx +7 -4
  135. data/ext/couchbase/protocol/client_request.hxx +2 -2
  136. data/ext/couchbase/protocol/client_response.hxx +41 -16
  137. data/ext/couchbase/protocol/cmd_append.hxx +17 -16
  138. data/ext/couchbase/protocol/cmd_cluster_map_change_notification.hxx +4 -4
  139. data/ext/couchbase/protocol/cmd_decrement.hxx +10 -11
  140. data/ext/couchbase/protocol/cmd_exists.hxx +12 -15
  141. data/ext/couchbase/protocol/cmd_get.hxx +11 -14
  142. data/ext/couchbase/protocol/cmd_get_and_lock.hxx +10 -12
  143. data/ext/couchbase/protocol/cmd_get_and_touch.hxx +10 -12
  144. data/ext/couchbase/protocol/cmd_get_cluster_config.hxx +13 -18
  145. data/ext/couchbase/protocol/cmd_get_collection_id.hxx +12 -15
  146. data/ext/couchbase/protocol/cmd_get_collections_manifest.hxx +12 -16
  147. data/ext/couchbase/protocol/cmd_get_error_map.hxx +14 -17
  148. data/ext/couchbase/protocol/cmd_hello.hxx +8 -10
  149. data/ext/couchbase/protocol/cmd_increment.hxx +9 -10
  150. data/ext/couchbase/protocol/cmd_insert.hxx +9 -9
  151. data/ext/couchbase/protocol/cmd_lookup_in.hxx +12 -13
  152. data/ext/couchbase/protocol/cmd_mutate_in.hxx +11 -11
  153. data/ext/couchbase/protocol/cmd_noop.hxx +16 -20
  154. data/ext/couchbase/protocol/cmd_prepend.hxx +9 -10
  155. data/ext/couchbase/protocol/cmd_remove.hxx +10 -13
  156. data/ext/couchbase/protocol/cmd_replace.hxx +7 -7
  157. data/ext/couchbase/protocol/cmd_sasl_auth.hxx +8 -10
  158. data/ext/couchbase/protocol/cmd_sasl_list_mechs.hxx +10 -15
  159. data/ext/couchbase/protocol/cmd_sasl_step.hxx +10 -12
  160. data/ext/couchbase/protocol/cmd_select_bucket.hxx +14 -18
  161. data/ext/couchbase/protocol/cmd_touch.hxx +8 -11
  162. data/ext/couchbase/protocol/cmd_unlock.hxx +10 -14
  163. data/ext/couchbase/protocol/cmd_upsert.hxx +8 -8
  164. data/ext/couchbase/protocol/datatype.hxx +3 -3
  165. data/ext/couchbase/protocol/durability_level.hxx +2 -2
  166. data/ext/couchbase/protocol/frame_info_id.hxx +4 -4
  167. data/ext/couchbase/protocol/hello_feature.hxx +2 -2
  168. data/ext/couchbase/protocol/magic.hxx +2 -2
  169. data/ext/couchbase/protocol/server_opcode.hxx +2 -2
  170. data/ext/couchbase/protocol/server_request.hxx +1 -1
  171. data/ext/couchbase/protocol/status.hxx +4 -7
  172. data/ext/couchbase/protocol/unsigned_leb128.h +5 -20
  173. data/ext/couchbase/service_type.hxx +4 -4
  174. data/ext/couchbase/tracing/constants.hxx +261 -0
  175. data/ext/couchbase/tracing/noop_tracer.hxx +50 -0
  176. data/ext/couchbase/tracing/request_tracer.hxx +77 -0
  177. data/ext/couchbase/tracing/threshold_logging_options.hxx +64 -0
  178. data/ext/couchbase/tracing/threshold_logging_tracer.hxx +366 -0
  179. data/ext/couchbase/utils/byteswap.hxx +1 -1
  180. data/ext/couchbase/utils/connection_string.hxx +21 -1
  181. data/ext/couchbase/utils/name_codec.hxx +41 -0
  182. data/ext/couchbase/utils/url_codec.hxx +236 -0
  183. data/ext/couchbase/version.hxx +1 -1
  184. data/ext/test/CMakeLists.txt +1 -0
  185. data/ext/test/test_native_trivial_query.cxx +60 -0
  186. data/ext/third_party/hdr_histogram_c/CMakeLists.txt +84 -0
  187. data/ext/third_party/hdr_histogram_c/COPYING.txt +121 -0
  188. data/ext/third_party/hdr_histogram_c/LICENSE.txt +41 -0
  189. data/ext/third_party/hdr_histogram_c/config.cmake.in +6 -0
  190. data/ext/third_party/hdr_histogram_c/src/CMakeLists.txt +83 -0
  191. data/ext/third_party/hdr_histogram_c/src/hdr_atomic.h +146 -0
  192. data/ext/third_party/hdr_histogram_c/src/hdr_encoding.c +322 -0
  193. data/ext/third_party/hdr_histogram_c/src/hdr_encoding.h +79 -0
  194. data/ext/third_party/hdr_histogram_c/src/hdr_endian.h +116 -0
  195. data/ext/third_party/hdr_histogram_c/src/hdr_histogram.c +1196 -0
  196. data/ext/third_party/hdr_histogram_c/src/hdr_histogram.h +516 -0
  197. data/ext/third_party/hdr_histogram_c/src/hdr_histogram_log.c +1290 -0
  198. data/ext/third_party/hdr_histogram_c/src/hdr_histogram_log.h +236 -0
  199. data/ext/third_party/hdr_histogram_c/src/hdr_histogram_log_no_op.c +171 -0
  200. data/ext/third_party/hdr_histogram_c/src/hdr_interval_recorder.c +227 -0
  201. data/ext/third_party/hdr_histogram_c/src/hdr_interval_recorder.h +109 -0
  202. data/ext/third_party/hdr_histogram_c/src/hdr_malloc.h +19 -0
  203. data/ext/third_party/hdr_histogram_c/src/hdr_tests.h +22 -0
  204. data/ext/third_party/hdr_histogram_c/src/hdr_thread.c +108 -0
  205. data/ext/third_party/hdr_histogram_c/src/hdr_thread.h +55 -0
  206. data/ext/third_party/hdr_histogram_c/src/hdr_time.c +98 -0
  207. data/ext/third_party/hdr_histogram_c/src/hdr_time.h +49 -0
  208. data/ext/third_party/hdr_histogram_c/src/hdr_writer_reader_phaser.c +143 -0
  209. data/ext/third_party/hdr_histogram_c/src/hdr_writer_reader_phaser.h +51 -0
  210. data/lib/couchbase/cluster.rb +1 -0
  211. data/lib/couchbase/errors.rb +3 -0
  212. data/lib/couchbase/libcouchbase.bundle +0 -0
  213. data/lib/couchbase/management/analytics_index_manager.rb +920 -226
  214. data/lib/couchbase/management/bucket_manager.rb +207 -69
  215. data/lib/couchbase/management/collection_manager.rb +173 -61
  216. data/lib/couchbase/management/query_index_manager.rb +357 -169
  217. data/lib/couchbase/options.rb +75 -3
  218. data/lib/couchbase/scope.rb +102 -0
  219. data/lib/couchbase/utils/time.rb +4 -0
  220. data/lib/couchbase/version.rb +6 -6
  221. metadata +48 -5
@@ -53,7 +53,7 @@ struct analytics_index_get_all_request {
53
53
  std::string client_context_id{ uuid::to_string(uuid::random()) };
54
54
  std::chrono::milliseconds timeout{ timeout_defaults::management_timeout };
55
55
 
56
- [[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, http_context&)
56
+ [[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, http_context& /* context */) const
57
57
  {
58
58
  tao::json::value body{
59
59
  { "statement", "SELECT d.* FROM Metadata.`Index` d WHERE d.DataverseName <> \"Metadata\"" },
@@ -68,16 +68,18 @@ struct analytics_index_get_all_request {
68
68
  };
69
69
 
70
70
  analytics_index_get_all_response
71
- make_response(error_context::http&& ctx, analytics_index_get_all_request&, analytics_index_get_all_request::encoded_response_type&& encoded)
71
+ make_response(error_context::http&& ctx,
72
+ const analytics_index_get_all_request& /* request */,
73
+ analytics_index_get_all_request::encoded_response_type&& encoded)
72
74
  {
73
- analytics_index_get_all_response response{ ctx };
75
+ analytics_index_get_all_response response{ std::move(ctx) };
74
76
 
75
77
  if (!response.ctx.ec) {
76
78
  tao::json::value payload{};
77
79
  try {
78
80
  payload = tao::json::from_string(encoded.body);
79
- } catch (tao::json::pegtl::parse_error& e) {
80
- response.ctx.ec = std::make_error_code(error::common_errc::parsing_failure);
81
+ } catch (const tao::json::pegtl::parse_error& e) {
82
+ response.ctx.ec = error::common_errc::parsing_failure;
81
83
  return response;
82
84
  }
83
85
  response.status = payload.at("status").get_string();
@@ -104,7 +106,7 @@ make_response(error_context::http&& ctx, analytics_index_get_all_request&, analy
104
106
  response.errors.emplace_back(err);
105
107
  }
106
108
  }
107
- response.ctx.ec = std::make_error_code(error::common_errc::internal_server_failure);
109
+ response.ctx.ec = error::common_errc::internal_server_failure;
108
110
  }
109
111
  }
110
112
  return response;
@@ -0,0 +1,39 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2020-2021 Couchbase, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #pragma once
19
+
20
+ #include <optional>
21
+ #include <sstream>
22
+ #include <string>
23
+
24
+ #include <operations/analytics_link_azure_blob_external.hxx>
25
+ #include <operations/analytics_link_couchbase_remote.hxx>
26
+ #include <operations/analytics_link_s3_external.hxx>
27
+
28
+ namespace couchbase::operations::analytics_link
29
+ {
30
+ template<typename analytics_link_type>
31
+ std::string
32
+ endpoint_from_link(const analytics_link_type& link)
33
+ {
34
+ if (std::count(link.dataverse.begin(), link.dataverse.end(), '/') > 0) {
35
+ return fmt::format("/analytics/link/{}/{}", utils::string_codec::v2::path_escape(link.dataverse), link.link_name);
36
+ }
37
+ return "/analytics/link";
38
+ }
39
+ } // namespace couchbase::operations::analytics_link
@@ -0,0 +1,145 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2020-2021 Couchbase, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #pragma once
19
+
20
+ #include <optional>
21
+ #include <map>
22
+ #include <string>
23
+
24
+ #include <errors.hxx>
25
+ #include <utils/url_codec.hxx>
26
+
27
+ namespace couchbase::operations::analytics_link
28
+ {
29
+ /**
30
+ * An external analytics link which uses the Microsoft Azure Blob Storage service.
31
+ * Only available as of 7.0 Developer Preview.
32
+ */
33
+ struct azure_blob_external {
34
+ /**
35
+ * The name of this link.
36
+ */
37
+ std::string link_name{};
38
+
39
+ /**
40
+ * The dataverse that this link belongs to.
41
+ */
42
+ std::string dataverse{};
43
+
44
+ /**
45
+ * The connection string can be used as an authentication method, connectionString contains other authentication methods embedded inside
46
+ * the string. Only a single authentication method can be used. (e.g. "AccountName=myAccountName;AccountKey=myAccountKey").
47
+ */
48
+ std::optional<std::string> connection_string{};
49
+
50
+ /**
51
+ * Azure blob storage account name
52
+ */
53
+ std::optional<std::string> account_name{};
54
+
55
+ /**
56
+ * Azure blob storage account key
57
+ */
58
+ std::optional<std::string> account_key{};
59
+
60
+ /**
61
+ * Token that can be used for authentication
62
+ */
63
+ std::optional<std::string> shared_access_signature{};
64
+
65
+ /**
66
+ * Azure blob storage endpoint
67
+ */
68
+ std::optional<std::string> blob_endpoint{};
69
+
70
+ /**
71
+ * Azure blob endpoint suffix
72
+ */
73
+ std::optional<std::string> endpoint_suffix{};
74
+
75
+ [[nodiscard]] std::error_code validate() const
76
+ {
77
+ if (dataverse.empty() || link_name.empty()) {
78
+ return error::common_errc::invalid_argument;
79
+ }
80
+ if (connection_string.has_value() ||
81
+ (account_name.has_value() && (account_key.has_value() || shared_access_signature.has_value()))) {
82
+ return {};
83
+ }
84
+ return error::common_errc::invalid_argument;
85
+ }
86
+
87
+ [[nodiscard]] std::string encode() const
88
+ {
89
+ std::map<std::string, std::string> values{
90
+ { "type", "azureblob" },
91
+ };
92
+ if (std::count(dataverse.begin(), dataverse.end(), '/') == 0) {
93
+ values["dataverse"] = dataverse;
94
+ values["name"] = link_name;
95
+ }
96
+ if (connection_string) {
97
+ values["connectionString"] = connection_string.value();
98
+ } else if (account_name) {
99
+ values["accountName"] = account_name.value();
100
+ if (account_key) {
101
+ values["accountKey"] = account_key.value();
102
+ } else if (shared_access_signature) {
103
+ values["sharedAccessSignature"] = shared_access_signature.value();
104
+ }
105
+ }
106
+ if (blob_endpoint) {
107
+ values["blobEndpoint"] = blob_endpoint.value();
108
+ }
109
+ if (endpoint_suffix) {
110
+ values["endpointSuffix"] = endpoint_suffix.value();
111
+ }
112
+ return utils::string_codec::v2::form_encode(values);
113
+ }
114
+ };
115
+ } // namespace couchbase::operations::analytics_link
116
+
117
+ namespace tao::json
118
+ {
119
+ template<>
120
+ struct traits<couchbase::operations::analytics_link::azure_blob_external> {
121
+ template<template<typename...> class Traits>
122
+ static couchbase::operations::analytics_link::azure_blob_external as(const tao::json::basic_value<Traits>& v)
123
+ {
124
+ couchbase::operations::analytics_link::azure_blob_external result{};
125
+
126
+ result.link_name = v.at("name").get_string();
127
+ if (const auto* dataverse = v.find("dataverse"); dataverse != nullptr) {
128
+ result.dataverse = dataverse->get_string();
129
+ } else {
130
+ result.dataverse = v.at("scope").get_string();
131
+ }
132
+
133
+ if (const auto* account_name = v.find("accountName"); account_name != nullptr && account_name->is_string()) {
134
+ result.account_name.emplace(account_name->get_string());
135
+ }
136
+ if (const auto* blob_endpoint = v.find("blobEndpoint"); blob_endpoint != nullptr && blob_endpoint->is_string()) {
137
+ result.blob_endpoint.emplace(blob_endpoint->get_string());
138
+ }
139
+ if (const auto* endpoint_suffix = v.find("endpointSuffix"); endpoint_suffix != nullptr && endpoint_suffix->is_string()) {
140
+ result.endpoint_suffix.emplace(endpoint_suffix->get_string());
141
+ }
142
+ return result;
143
+ }
144
+ };
145
+ } // namespace tao::json
@@ -19,7 +19,7 @@
19
19
 
20
20
  #include <tao/json.hpp>
21
21
 
22
- #include <version.hxx>
22
+ #include <utils/name_codec.hxx>
23
23
 
24
24
  namespace couchbase::operations
25
25
  {
@@ -46,15 +46,16 @@ struct analytics_link_connect_request {
46
46
  std::chrono::milliseconds timeout{ timeout_defaults::management_timeout };
47
47
 
48
48
  std::string dataverse_name{ "Default" };
49
- std::string link_name;
49
+ std::string link_name{ "Local" };
50
50
  bool force{ false };
51
51
 
52
- [[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, http_context&)
52
+ [[nodiscard]] std::error_code encode_to(encoded_request_type& encoded, http_context& /* context */) const
53
53
  {
54
54
  std::string with_clause = force ? "WITH {\"force\": true}" : "";
55
55
 
56
56
  tao::json::value body{
57
- { "statement", fmt::format("CONNECT LINK `{}`.`{}` {}", dataverse_name, link_name, with_clause) },
57
+ { "statement",
58
+ fmt::format("CONNECT LINK {}.`{}` {}", utils::analytics::uncompound_name(dataverse_name), link_name, with_clause) },
58
59
  };
59
60
  encoded.headers["content-type"] = "application/json";
60
61
  encoded.method = "POST";
@@ -65,15 +66,17 @@ struct analytics_link_connect_request {
65
66
  };
66
67
 
67
68
  analytics_link_connect_response
68
- make_response(error_context::http&& ctx, analytics_link_connect_request&, analytics_link_connect_request::encoded_response_type&& encoded)
69
+ make_response(error_context::http&& ctx,
70
+ const analytics_link_connect_request& /* request */,
71
+ analytics_link_connect_request::encoded_response_type&& encoded)
69
72
  {
70
- analytics_link_connect_response response{ ctx };
73
+ analytics_link_connect_response response{ std::move(ctx) };
71
74
  if (!response.ctx.ec) {
72
75
  tao::json::value payload{};
73
76
  try {
74
77
  payload = tao::json::from_string(encoded.body);
75
- } catch (tao::json::pegtl::parse_error& e) {
76
- response.ctx.ec = std::make_error_code(error::common_errc::parsing_failure);
78
+ } catch (const tao::json::pegtl::parse_error& e) {
79
+ response.ctx.ec = error::common_errc::parsing_failure;
77
80
  return response;
78
81
  }
79
82
  response.status = payload.at("status").get_string();
@@ -81,8 +84,7 @@ make_response(error_context::http&& ctx, analytics_link_connect_request&, analyt
81
84
  if (response.status != "success") {
82
85
  bool link_not_found = false;
83
86
 
84
- auto* errors = payload.find("errors");
85
- if (errors != nullptr && errors->is_array()) {
87
+ if (auto* errors = payload.find("errors"); errors != nullptr && errors->is_array()) {
86
88
  for (const auto& error : errors->get_array()) {
87
89
  analytics_link_connect_response::problem err{
88
90
  error.at("code").as<std::uint32_t>(),
@@ -97,9 +99,9 @@ make_response(error_context::http&& ctx, analytics_link_connect_request&, analyt
97
99
  }
98
100
  }
99
101
  if (link_not_found) {
100
- response.ctx.ec = std::make_error_code(error::analytics_errc::link_not_found);
102
+ response.ctx.ec = error::analytics_errc::link_not_found;
101
103
  } else {
102
- response.ctx.ec = std::make_error_code(error::common_errc::internal_server_failure);
104
+ response.ctx.ec = error::common_errc::internal_server_failure;
103
105
  }
104
106
  }
105
107
  }
@@ -0,0 +1,220 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2020-2021 Couchbase, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #pragma once
19
+
20
+ #include <optional>
21
+ #include <map>
22
+ #include <string>
23
+
24
+ #include <errors.hxx>
25
+ #include <utils/url_codec.hxx>
26
+
27
+ namespace couchbase::operations::analytics_link
28
+ {
29
+ enum class encryption_level {
30
+ /**
31
+ * Connect to the remote Couchbase cluster using an unsecured channel. Send the password in plaintext.
32
+ */
33
+ none,
34
+
35
+ /**
36
+ * Connect to the remote Couchbase cluster using an unsecured channel. Send the password securely using SASL.
37
+ */
38
+ half,
39
+
40
+ /**
41
+ * Connect to the remote Couchbase cluster using a channel secured by TLS. If a password is used, it is sent over the secure channel.
42
+ *
43
+ * Requires specifying the certificate to trust.
44
+ */
45
+ full,
46
+ };
47
+
48
+ std::string
49
+ to_string(encryption_level level)
50
+ {
51
+ switch (level) {
52
+ case encryption_level::none:
53
+ return "none";
54
+
55
+ case encryption_level::half:
56
+ return "half";
57
+
58
+ case encryption_level::full:
59
+ return "full";
60
+ }
61
+ return "none";
62
+ }
63
+
64
+ struct encryption_settings {
65
+ /**
66
+ * Specifies what level of encryption should be used.
67
+ */
68
+ encryption_level level{ encryption_level::none };
69
+
70
+ /**
71
+ * Provides a certificate to use for connecting when encryption level is set to 'full'. Required when 'encryption_level' is set to
72
+ * 'full'.
73
+ */
74
+ std::optional<std::string> certificate{};
75
+
76
+ /**
77
+ * Provides a client certificate to use for connecting when encryption level is set to 'full'. Cannot be set if a username/password are
78
+ * used.
79
+ */
80
+ std::optional<std::string> client_certificate{};
81
+
82
+ /**
83
+ * Provides a client key to use for connecting when encryption level is set to 'full'. Cannot be set if a username/password are used.
84
+ */
85
+ std::optional<std::string> client_key{};
86
+ };
87
+
88
+ /**
89
+ * A remote analytics link which uses a Couchbase data service that is not part of the same cluster as the Analytics Service.
90
+ */
91
+ struct couchbase_remote {
92
+ /**
93
+ * The name of this link.
94
+ */
95
+ std::string link_name{};
96
+
97
+ /**
98
+ * The dataverse that this link belongs to.
99
+ */
100
+ std::string dataverse{};
101
+
102
+ /**
103
+ * The hostname of the target Couchbase cluster.
104
+ */
105
+ std::string hostname{};
106
+
107
+ /**
108
+ * The username to use for authentication with the remote cluster. Optional if client-certificate authentication is being used.
109
+ */
110
+ std::optional<std::string> username{};
111
+
112
+ /**
113
+ * The password to use for authentication with the remote cluster. Optional if client-certificate authentication is being used.
114
+ */
115
+ std::optional<std::string> password{};
116
+
117
+ encryption_settings encryption{};
118
+
119
+ [[nodiscard]] std::error_code validate() const
120
+ {
121
+ if (dataverse.empty() || link_name.empty() || hostname.empty()) {
122
+ return error::common_errc::invalid_argument;
123
+ }
124
+ switch (encryption.level) {
125
+ case encryption_level::none:
126
+ case encryption_level::half:
127
+ if (/* username and password must be provided */ username.has_value() && password.has_value() &&
128
+ /* and client certificate and key must be empty */
129
+ (!encryption.client_certificate.has_value() && !encryption.client_key.has_value())) {
130
+
131
+ return {};
132
+ }
133
+ return error::common_errc::invalid_argument;
134
+
135
+ case encryption_level::full:
136
+ if (/* certificate must be provided and */ encryption.certificate.has_value() &&
137
+ (/* either username/password must be set */ (username.has_value() && password.has_value() &&
138
+ !encryption.client_certificate.has_value() &&
139
+ !encryption.client_key.has_value()) ||
140
+ /* or client certificate/key must be set */ (!username.has_value() && !password.has_value() &&
141
+ encryption.client_certificate.has_value() &&
142
+ encryption.client_key.has_value()))) {
143
+ return {};
144
+ }
145
+ return error::common_errc::invalid_argument;
146
+ }
147
+ return {};
148
+ }
149
+
150
+ [[nodiscard]] std::string encode() const
151
+ {
152
+ std::map<std::string, std::string> values{
153
+ { "type", "couchbase" },
154
+ { "hostname", hostname },
155
+ { "encryption", to_string(encryption.level) },
156
+ };
157
+ if (std::count(dataverse.begin(), dataverse.end(), '/') == 0) {
158
+ values["dataverse"] = dataverse;
159
+ values["name"] = link_name;
160
+ }
161
+ if (username) {
162
+ values["username"] = username.value();
163
+ }
164
+ if (password) {
165
+ values["password"] = password.value();
166
+ }
167
+ if (encryption.certificate) {
168
+ values["certificate"] = encryption.certificate.value();
169
+ }
170
+ if (encryption.client_certificate) {
171
+ values["clientCertificate"] = encryption.client_certificate.value();
172
+ }
173
+ if (encryption.client_key) {
174
+ values["clientKey"] = encryption.client_key.value();
175
+ }
176
+ return utils::string_codec::v2::form_encode(values);
177
+ }
178
+ };
179
+ } // namespace couchbase::operations::analytics_link
180
+
181
+ namespace tao::json
182
+ {
183
+ template<>
184
+ struct traits<couchbase::operations::analytics_link::couchbase_remote> {
185
+ template<template<typename...> class Traits>
186
+ static couchbase::operations::analytics_link::couchbase_remote as(const tao::json::basic_value<Traits>& v)
187
+ {
188
+ couchbase::operations::analytics_link::couchbase_remote result{};
189
+
190
+ result.link_name = v.at("name").get_string();
191
+ if (const auto* dataverse = v.find("dataverse"); dataverse != nullptr) {
192
+ result.dataverse = dataverse->get_string();
193
+ } else {
194
+ result.dataverse = v.at("scope").get_string();
195
+ }
196
+ result.hostname = v.at("activeHostname").get_string();
197
+ if (const auto* encryption = v.find("encryption"); encryption != nullptr && encryption->is_string()) {
198
+ const auto& level = encryption->get_string();
199
+ if (level == "none") {
200
+ result.encryption.level = couchbase::operations::analytics_link::encryption_level::none;
201
+ } else if (level == "half") {
202
+ result.encryption.level = couchbase::operations::analytics_link::encryption_level::half;
203
+ } else if (level == "full") {
204
+ result.encryption.level = couchbase::operations::analytics_link::encryption_level::full;
205
+ }
206
+ }
207
+ if (const auto* username = v.find("username"); username != nullptr && username->is_string()) {
208
+ result.username.emplace(username->get_string());
209
+ }
210
+ if (const auto* certificate = v.find("certificate"); certificate != nullptr && certificate->is_string()) {
211
+ result.encryption.certificate.emplace(certificate->get_string());
212
+ }
213
+ if (const auto* client_certificate = v.find("clientCertificate");
214
+ client_certificate != nullptr && client_certificate->is_string()) {
215
+ result.encryption.client_certificate.emplace(client_certificate->get_string());
216
+ }
217
+ return result;
218
+ }
219
+ };
220
+ } // namespace tao::json