1 /*
2   Copyright (c) DataStax, Inc.
3 
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7 
8   http://www.apache.org/licenses/LICENSE-2.0
9 
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15 */
16 
17 #include "cluster_config.hpp"
18 
19 using namespace datastax;
20 using namespace datastax::internal;
21 using namespace datastax::internal::core;
22 
23 extern "C" {
24 
cass_cluster_new()25 CassCluster* cass_cluster_new() { return CassCluster::to(new ClusterConfig()); }
26 
cass_cluster_set_port(CassCluster * cluster,int port)27 CassError cass_cluster_set_port(CassCluster* cluster, int port) {
28   if (port <= 0) {
29     return CASS_ERROR_LIB_BAD_PARAMS;
30   } else if (cluster->config().cloud_secure_connection_config().is_loaded()) {
31     LOG_ERROR("Port cannot be overridden with cloud secure connection bundle");
32     return CASS_ERROR_LIB_BAD_PARAMS;
33   }
34 
35   cluster->config().set_port(port);
36   return CASS_OK;
37 }
38 
cass_cluster_set_ssl(CassCluster * cluster,CassSsl * ssl)39 void cass_cluster_set_ssl(CassCluster* cluster, CassSsl* ssl) {
40   if (cluster->config().cloud_secure_connection_config().is_loaded()) {
41     LOG_ERROR("SSL context cannot be overridden with cloud secure connection bundle");
42   } else {
43     cluster->config().set_ssl_context(ssl->from());
44   }
45 }
46 
cass_cluster_set_protocol_version(CassCluster * cluster,int protocol_version)47 CassError cass_cluster_set_protocol_version(CassCluster* cluster, int protocol_version) {
48   if (cluster->config().use_beta_protocol_version()) {
49     LOG_ERROR("The protocol version is already set to the newest beta version %s "
50               "and cannot be explicitly set.",
51               ProtocolVersion::newest_beta().to_string().c_str());
52     return CASS_ERROR_LIB_BAD_PARAMS;
53   } else {
54     ProtocolVersion version(protocol_version);
55     if (version < ProtocolVersion::lowest_supported()) {
56       LOG_ERROR("Protocol version %s is lower than the lowest supported "
57                 "protocol version %s",
58                 version.to_string().c_str(),
59                 ProtocolVersion::lowest_supported().to_string().c_str());
60       return CASS_ERROR_LIB_BAD_PARAMS;
61     } else if (version > ProtocolVersion::highest_supported(version.is_dse())) {
62       LOG_ERROR("Protocol version %s is higher than the highest supported "
63                 "protocol version %s (consider using the newest beta protocol version).",
64                 version.to_string().c_str(),
65                 ProtocolVersion::highest_supported(version.is_dse()).to_string().c_str());
66       return CASS_ERROR_LIB_BAD_PARAMS;
67     }
68     cluster->config().set_protocol_version(version);
69     return CASS_OK;
70   }
71 }
72 
cass_cluster_set_use_beta_protocol_version(CassCluster * cluster,cass_bool_t enable)73 CassError cass_cluster_set_use_beta_protocol_version(CassCluster* cluster, cass_bool_t enable) {
74   cluster->config().set_use_beta_protocol_version(enable == cass_true);
75   cluster->config().set_protocol_version(enable ? ProtocolVersion::newest_beta()
76                                                 : ProtocolVersion::highest_supported());
77   return CASS_OK;
78 }
79 
cass_cluster_set_consistency(CassCluster * cluster,CassConsistency consistency)80 CassError cass_cluster_set_consistency(CassCluster* cluster, CassConsistency consistency) {
81   if (consistency == CASS_CONSISTENCY_UNKNOWN) {
82     return CASS_ERROR_LIB_BAD_PARAMS;
83   }
84   cluster->config().set_consistency(consistency);
85   return CASS_OK;
86 }
87 
cass_cluster_set_serial_consistency(CassCluster * cluster,CassConsistency consistency)88 CassError cass_cluster_set_serial_consistency(CassCluster* cluster, CassConsistency consistency) {
89   if (consistency == CASS_CONSISTENCY_UNKNOWN) {
90     return CASS_ERROR_LIB_BAD_PARAMS;
91   }
92   cluster->config().set_serial_consistency(consistency);
93   return CASS_OK;
94 }
95 
cass_cluster_set_num_threads_io(CassCluster * cluster,unsigned num_threads)96 CassError cass_cluster_set_num_threads_io(CassCluster* cluster, unsigned num_threads) {
97   if (num_threads == 0) {
98     return CASS_ERROR_LIB_BAD_PARAMS;
99   }
100   cluster->config().set_thread_count_io(num_threads);
101   return CASS_OK;
102 }
103 
cass_cluster_set_queue_size_io(CassCluster * cluster,unsigned queue_size)104 CassError cass_cluster_set_queue_size_io(CassCluster* cluster, unsigned queue_size) {
105   if (queue_size == 0) {
106     return CASS_ERROR_LIB_BAD_PARAMS;
107   }
108   cluster->config().set_queue_size_io(queue_size);
109   return CASS_OK;
110 }
111 
cass_cluster_set_queue_size_event(CassCluster * cluster,unsigned queue_size)112 CassError cass_cluster_set_queue_size_event(CassCluster* cluster, unsigned queue_size) {
113   return CASS_OK;
114 }
115 
cass_cluster_set_contact_points(CassCluster * cluster,const char * contact_points)116 CassError cass_cluster_set_contact_points(CassCluster* cluster, const char* contact_points) {
117   return cass_cluster_set_contact_points_n(cluster, contact_points, SAFE_STRLEN(contact_points));
118 }
119 
cass_cluster_set_contact_points_n(CassCluster * cluster,const char * contact_points,size_t contact_points_length)120 CassError cass_cluster_set_contact_points_n(CassCluster* cluster, const char* contact_points,
121                                             size_t contact_points_length) {
122   if (cluster->config().cloud_secure_connection_config().is_loaded()) {
123     LOG_ERROR("Contact points cannot be overridden with cloud secure connection bundle");
124     return CASS_ERROR_LIB_BAD_PARAMS;
125   }
126 
127   if (contact_points_length == 0) {
128     cluster->config().contact_points().clear();
129   } else {
130     Vector<String> exploded;
131     explode(String(contact_points, contact_points_length), exploded);
132     for (Vector<String>::const_iterator it = exploded.begin(), end = exploded.end(); it != end;
133          ++it) {
134       cluster->config().contact_points().push_back(Address(*it, -1));
135     }
136   }
137   return CASS_OK;
138 }
139 
cass_cluster_set_core_connections_per_host(CassCluster * cluster,unsigned num_connections)140 CassError cass_cluster_set_core_connections_per_host(CassCluster* cluster,
141                                                      unsigned num_connections) {
142   if (num_connections == 0) {
143     return CASS_ERROR_LIB_BAD_PARAMS;
144   }
145   cluster->config().set_core_connections_per_host(num_connections);
146   return CASS_OK;
147 }
148 
cass_cluster_set_max_connections_per_host(CassCluster * cluster,unsigned num_connections)149 CassError cass_cluster_set_max_connections_per_host(CassCluster* cluster,
150                                                     unsigned num_connections) {
151   return CASS_OK;
152 }
153 
cass_cluster_set_reconnect_wait_time(CassCluster * cluster,unsigned wait_time_ms)154 void cass_cluster_set_reconnect_wait_time(CassCluster* cluster, unsigned wait_time_ms) {
155   cass_cluster_set_constant_reconnect(cluster, wait_time_ms);
156 }
157 
cass_cluster_set_constant_reconnect(CassCluster * cluster,cass_uint64_t delay_ms)158 void cass_cluster_set_constant_reconnect(CassCluster* cluster, cass_uint64_t delay_ms) {
159   cluster->config().set_constant_reconnect(delay_ms);
160 }
161 
cass_cluster_set_exponential_reconnect(CassCluster * cluster,cass_uint64_t base_delay_ms,cass_uint64_t max_delay_ms)162 CassError cass_cluster_set_exponential_reconnect(CassCluster* cluster, cass_uint64_t base_delay_ms,
163                                                  cass_uint64_t max_delay_ms) {
164   if (base_delay_ms <= 1) {
165     LOG_ERROR("Base delay must be greater than 1");
166     return CASS_ERROR_LIB_BAD_PARAMS;
167   }
168 
169   if (max_delay_ms <= 1) {
170     LOG_ERROR("Max delay must be greater than 1");
171     return CASS_ERROR_LIB_BAD_PARAMS;
172   }
173 
174   if (max_delay_ms < base_delay_ms) {
175     LOG_ERROR("Max delay cannot be less than base delay");
176     return CASS_ERROR_LIB_BAD_PARAMS;
177   }
178   cluster->config().set_exponential_reconnect(base_delay_ms, max_delay_ms);
179   return CASS_OK;
180 }
181 
cass_cluster_set_coalesce_delay(CassCluster * cluster,cass_int64_t delay_us)182 CassError cass_cluster_set_coalesce_delay(CassCluster* cluster, cass_int64_t delay_us) {
183   if (delay_us < 0) {
184     return CASS_ERROR_LIB_BAD_PARAMS;
185   }
186   cluster->config().set_coalesce_delay_us(delay_us);
187   return CASS_OK;
188 }
189 
cass_cluster_set_new_request_ratio(CassCluster * cluster,cass_int32_t ratio)190 CassError cass_cluster_set_new_request_ratio(CassCluster* cluster, cass_int32_t ratio) {
191   if (ratio <= 0 || ratio > 100) {
192     return CASS_ERROR_LIB_BAD_PARAMS;
193   }
194   cluster->config().set_new_request_ratio(ratio);
195   return CASS_OK;
196 }
197 
cass_cluster_set_max_concurrent_creation(CassCluster * cluster,unsigned num_connections)198 CassError cass_cluster_set_max_concurrent_creation(CassCluster* cluster, unsigned num_connections) {
199   // Deprecated
200   return CASS_OK;
201 }
202 
cass_cluster_set_max_concurrent_requests_threshold(CassCluster * cluster,unsigned num_requests)203 CassError cass_cluster_set_max_concurrent_requests_threshold(CassCluster* cluster,
204                                                              unsigned num_requests) {
205   // Deprecated
206   return CASS_OK;
207 }
208 
cass_cluster_set_max_requests_per_flush(CassCluster * cluster,unsigned num_requests)209 CassError cass_cluster_set_max_requests_per_flush(CassCluster* cluster, unsigned num_requests) {
210   // Deprecated
211   return CASS_OK;
212 }
213 
cass_cluster_set_write_bytes_high_water_mark(CassCluster * cluster,unsigned num_bytes)214 CassError cass_cluster_set_write_bytes_high_water_mark(CassCluster* cluster, unsigned num_bytes) {
215   // Deprecated
216   return CASS_OK;
217 }
218 
cass_cluster_set_write_bytes_low_water_mark(CassCluster * cluster,unsigned num_bytes)219 CassError cass_cluster_set_write_bytes_low_water_mark(CassCluster* cluster, unsigned num_bytes) {
220   // Deprecated
221   return CASS_OK;
222 }
223 
cass_cluster_set_pending_requests_high_water_mark(CassCluster * cluster,unsigned num_requests)224 CassError cass_cluster_set_pending_requests_high_water_mark(CassCluster* cluster,
225                                                             unsigned num_requests) {
226   // Deprecated
227   return CASS_OK;
228 }
229 
cass_cluster_set_pending_requests_low_water_mark(CassCluster * cluster,unsigned num_requests)230 CassError cass_cluster_set_pending_requests_low_water_mark(CassCluster* cluster,
231                                                            unsigned num_requests) {
232   // Deprecated
233   return CASS_OK;
234 }
235 
cass_cluster_set_connect_timeout(CassCluster * cluster,unsigned timeout_ms)236 void cass_cluster_set_connect_timeout(CassCluster* cluster, unsigned timeout_ms) {
237   cluster->config().set_connect_timeout(timeout_ms);
238 }
239 
cass_cluster_set_request_timeout(CassCluster * cluster,unsigned timeout_ms)240 void cass_cluster_set_request_timeout(CassCluster* cluster, unsigned timeout_ms) {
241   cluster->config().set_request_timeout(timeout_ms);
242 }
243 
cass_cluster_set_resolve_timeout(CassCluster * cluster,unsigned timeout_ms)244 void cass_cluster_set_resolve_timeout(CassCluster* cluster, unsigned timeout_ms) {
245   cluster->config().set_resolve_timeout(timeout_ms);
246 }
247 
cass_cluster_set_max_schema_wait_time(CassCluster * cluster,unsigned wait_time_ms)248 void cass_cluster_set_max_schema_wait_time(CassCluster* cluster, unsigned wait_time_ms) {
249   cluster->config().set_max_schema_wait_time_ms(wait_time_ms);
250 }
251 
cass_cluster_set_tracing_max_wait_time(CassCluster * cluster,unsigned wait_time_ms)252 void cass_cluster_set_tracing_max_wait_time(CassCluster* cluster, unsigned wait_time_ms) {
253   cluster->config().set_max_tracing_wait_time_ms(wait_time_ms);
254 }
255 
cass_cluster_set_tracing_retry_wait_time(CassCluster * cluster,unsigned wait_time_ms)256 void cass_cluster_set_tracing_retry_wait_time(CassCluster* cluster, unsigned wait_time_ms) {
257   cluster->config().set_retry_tracing_wait_time_ms(wait_time_ms);
258 }
259 
cass_cluster_set_tracing_consistency(CassCluster * cluster,CassConsistency consistency)260 void cass_cluster_set_tracing_consistency(CassCluster* cluster, CassConsistency consistency) {
261   cluster->config().set_tracing_consistency(consistency);
262 }
263 
cass_cluster_set_credentials(CassCluster * cluster,const char * username,const char * password)264 void cass_cluster_set_credentials(CassCluster* cluster, const char* username,
265                                   const char* password) {
266   return cass_cluster_set_credentials_n(cluster, username, SAFE_STRLEN(username), password,
267                                         SAFE_STRLEN(password));
268 }
269 
cass_cluster_set_credentials_n(CassCluster * cluster,const char * username,size_t username_length,const char * password,size_t password_length)270 void cass_cluster_set_credentials_n(CassCluster* cluster, const char* username,
271                                     size_t username_length, const char* password,
272                                     size_t password_length) {
273   cluster->config().set_credentials(String(username, username_length),
274                                     String(password, password_length));
275 }
276 
cass_cluster_set_load_balance_round_robin(CassCluster * cluster)277 void cass_cluster_set_load_balance_round_robin(CassCluster* cluster) {
278   cluster->config().set_load_balancing_policy(new RoundRobinPolicy());
279 }
280 
cass_cluster_set_load_balance_dc_aware(CassCluster * cluster,const char * local_dc,unsigned used_hosts_per_remote_dc,cass_bool_t allow_remote_dcs_for_local_cl)281 CassError cass_cluster_set_load_balance_dc_aware(CassCluster* cluster, const char* local_dc,
282                                                  unsigned used_hosts_per_remote_dc,
283                                                  cass_bool_t allow_remote_dcs_for_local_cl) {
284   if (local_dc == NULL) {
285     return CASS_ERROR_LIB_BAD_PARAMS;
286   }
287   return cass_cluster_set_load_balance_dc_aware_n(cluster, local_dc, SAFE_STRLEN(local_dc),
288                                                   used_hosts_per_remote_dc,
289                                                   allow_remote_dcs_for_local_cl);
290 }
291 
cass_cluster_set_load_balance_dc_aware_n(CassCluster * cluster,const char * local_dc,size_t local_dc_length,unsigned used_hosts_per_remote_dc,cass_bool_t allow_remote_dcs_for_local_cl)292 CassError cass_cluster_set_load_balance_dc_aware_n(CassCluster* cluster, const char* local_dc,
293                                                    size_t local_dc_length,
294                                                    unsigned used_hosts_per_remote_dc,
295                                                    cass_bool_t allow_remote_dcs_for_local_cl) {
296   if (local_dc == NULL || local_dc_length == 0) {
297     return CASS_ERROR_LIB_BAD_PARAMS;
298   }
299   cluster->config().set_load_balancing_policy(new DCAwarePolicy(
300       String(local_dc, local_dc_length), used_hosts_per_remote_dc, !allow_remote_dcs_for_local_cl));
301   return CASS_OK;
302 }
303 
cass_cluster_set_token_aware_routing(CassCluster * cluster,cass_bool_t enabled)304 void cass_cluster_set_token_aware_routing(CassCluster* cluster, cass_bool_t enabled) {
305   cluster->config().set_token_aware_routing(enabled == cass_true);
306 }
307 
cass_cluster_set_token_aware_routing_shuffle_replicas(CassCluster * cluster,cass_bool_t enabled)308 void cass_cluster_set_token_aware_routing_shuffle_replicas(CassCluster* cluster,
309                                                            cass_bool_t enabled) {
310   cluster->config().set_token_aware_routing_shuffle_replicas(enabled == cass_true);
311 }
312 
cass_cluster_set_latency_aware_routing(CassCluster * cluster,cass_bool_t enabled)313 void cass_cluster_set_latency_aware_routing(CassCluster* cluster, cass_bool_t enabled) {
314   cluster->config().set_latency_aware_routing(enabled == cass_true);
315 }
316 
cass_cluster_set_latency_aware_routing_settings(CassCluster * cluster,cass_double_t exclusion_threshold,cass_uint64_t scale_ms,cass_uint64_t retry_period_ms,cass_uint64_t update_rate_ms,cass_uint64_t min_measured)317 void cass_cluster_set_latency_aware_routing_settings(
318     CassCluster* cluster, cass_double_t exclusion_threshold, cass_uint64_t scale_ms,
319     cass_uint64_t retry_period_ms, cass_uint64_t update_rate_ms, cass_uint64_t min_measured) {
320   LatencyAwarePolicy::Settings settings;
321   settings.exclusion_threshold = exclusion_threshold;
322   settings.scale_ns = scale_ms * 1000 * 1000;
323   settings.retry_period_ns = retry_period_ms * 1000 * 1000;
324   settings.update_rate_ms = update_rate_ms;
325   settings.min_measured = min_measured;
326   cluster->config().set_latency_aware_routing_settings(settings);
327 }
328 
cass_cluster_set_whitelist_filtering(CassCluster * cluster,const char * hosts)329 void cass_cluster_set_whitelist_filtering(CassCluster* cluster, const char* hosts) {
330   cass_cluster_set_whitelist_filtering_n(cluster, hosts, SAFE_STRLEN(hosts));
331 }
332 
cass_cluster_set_whitelist_filtering_n(CassCluster * cluster,const char * hosts,size_t hosts_length)333 void cass_cluster_set_whitelist_filtering_n(CassCluster* cluster, const char* hosts,
334                                             size_t hosts_length) {
335   if (hosts_length == 0) {
336     cluster->config().default_profile().whitelist().clear();
337   } else {
338     explode(String(hosts, hosts_length), cluster->config().default_profile().whitelist());
339   }
340 }
341 
cass_cluster_set_blacklist_filtering(CassCluster * cluster,const char * hosts)342 void cass_cluster_set_blacklist_filtering(CassCluster* cluster, const char* hosts) {
343   cass_cluster_set_blacklist_filtering_n(cluster, hosts, SAFE_STRLEN(hosts));
344 }
345 
cass_cluster_set_blacklist_filtering_n(CassCluster * cluster,const char * hosts,size_t hosts_length)346 void cass_cluster_set_blacklist_filtering_n(CassCluster* cluster, const char* hosts,
347                                             size_t hosts_length) {
348   if (hosts_length == 0) {
349     cluster->config().default_profile().blacklist().clear();
350   } else {
351     explode(String(hosts, hosts_length), cluster->config().default_profile().blacklist());
352   }
353 }
354 
cass_cluster_set_whitelist_dc_filtering(CassCluster * cluster,const char * dcs)355 void cass_cluster_set_whitelist_dc_filtering(CassCluster* cluster, const char* dcs) {
356   cass_cluster_set_whitelist_dc_filtering_n(cluster, dcs, SAFE_STRLEN(dcs));
357 }
358 
cass_cluster_set_whitelist_dc_filtering_n(CassCluster * cluster,const char * dcs,size_t dcs_length)359 void cass_cluster_set_whitelist_dc_filtering_n(CassCluster* cluster, const char* dcs,
360                                                size_t dcs_length) {
361   if (dcs_length == 0) {
362     cluster->config().default_profile().whitelist_dc().clear();
363   } else {
364     explode(String(dcs, dcs_length), cluster->config().default_profile().whitelist_dc());
365   }
366 }
367 
cass_cluster_set_blacklist_dc_filtering(CassCluster * cluster,const char * dcs)368 void cass_cluster_set_blacklist_dc_filtering(CassCluster* cluster, const char* dcs) {
369   cass_cluster_set_blacklist_dc_filtering_n(cluster, dcs, SAFE_STRLEN(dcs));
370 }
371 
cass_cluster_set_blacklist_dc_filtering_n(CassCluster * cluster,const char * dcs,size_t dcs_length)372 void cass_cluster_set_blacklist_dc_filtering_n(CassCluster* cluster, const char* dcs,
373                                                size_t dcs_length) {
374   if (dcs_length == 0) {
375     cluster->config().default_profile().blacklist_dc().clear();
376   } else {
377     explode(String(dcs, dcs_length), cluster->config().default_profile().blacklist_dc());
378   }
379 }
380 
cass_cluster_set_tcp_nodelay(CassCluster * cluster,cass_bool_t enabled)381 void cass_cluster_set_tcp_nodelay(CassCluster* cluster, cass_bool_t enabled) {
382   cluster->config().set_tcp_nodelay(enabled == cass_true);
383 }
384 
cass_cluster_set_tcp_keepalive(CassCluster * cluster,cass_bool_t enabled,unsigned delay_secs)385 void cass_cluster_set_tcp_keepalive(CassCluster* cluster, cass_bool_t enabled,
386                                     unsigned delay_secs) {
387   cluster->config().set_tcp_keepalive(enabled == cass_true, delay_secs);
388 }
389 
cass_cluster_set_authenticator_callbacks(CassCluster * cluster,const CassAuthenticatorCallbacks * exchange_callbacks,CassAuthenticatorDataCleanupCallback cleanup_callback,void * data)390 CassError cass_cluster_set_authenticator_callbacks(
391     CassCluster* cluster, const CassAuthenticatorCallbacks* exchange_callbacks,
392     CassAuthenticatorDataCleanupCallback cleanup_callback, void* data) {
393   cluster->config().set_auth_provider(
394       AuthProvider::Ptr(new ExternalAuthProvider(exchange_callbacks, cleanup_callback, data)));
395   return CASS_OK;
396 }
397 
cass_cluster_set_connection_heartbeat_interval(CassCluster * cluster,unsigned interval_secs)398 void cass_cluster_set_connection_heartbeat_interval(CassCluster* cluster, unsigned interval_secs) {
399   cluster->config().set_connection_heartbeat_interval_secs(interval_secs);
400 }
401 
cass_cluster_set_connection_idle_timeout(CassCluster * cluster,unsigned timeout_secs)402 void cass_cluster_set_connection_idle_timeout(CassCluster* cluster, unsigned timeout_secs) {
403   cluster->config().set_connection_idle_timeout_secs(timeout_secs);
404 }
405 
cass_cluster_set_retry_policy(CassCluster * cluster,CassRetryPolicy * retry_policy)406 void cass_cluster_set_retry_policy(CassCluster* cluster, CassRetryPolicy* retry_policy) {
407   cluster->config().set_retry_policy(retry_policy);
408 }
409 
cass_cluster_set_timestamp_gen(CassCluster * cluster,CassTimestampGen * timestamp_gen)410 void cass_cluster_set_timestamp_gen(CassCluster* cluster, CassTimestampGen* timestamp_gen) {
411   cluster->config().set_timestamp_gen(timestamp_gen);
412 }
413 
cass_cluster_set_use_schema(CassCluster * cluster,cass_bool_t enabled)414 void cass_cluster_set_use_schema(CassCluster* cluster, cass_bool_t enabled) {
415   cluster->config().set_use_schema(enabled == cass_true);
416 }
417 
cass_cluster_set_use_hostname_resolution(CassCluster * cluster,cass_bool_t enabled)418 CassError cass_cluster_set_use_hostname_resolution(CassCluster* cluster, cass_bool_t enabled) {
419   cluster->config().set_use_hostname_resolution(enabled == cass_true);
420   return CASS_OK;
421 }
422 
cass_cluster_set_use_randomized_contact_points(CassCluster * cluster,cass_bool_t enabled)423 CassError cass_cluster_set_use_randomized_contact_points(CassCluster* cluster,
424                                                          cass_bool_t enabled) {
425   cluster->config().set_use_randomized_contact_points(enabled == cass_true);
426   return CASS_OK;
427 }
428 
cass_cluster_set_constant_speculative_execution_policy(CassCluster * cluster,cass_int64_t constant_delay_ms,int max_speculative_executions)429 CassError cass_cluster_set_constant_speculative_execution_policy(CassCluster* cluster,
430                                                                  cass_int64_t constant_delay_ms,
431                                                                  int max_speculative_executions) {
432   if (constant_delay_ms < 0 || max_speculative_executions < 0) {
433     return CASS_ERROR_LIB_BAD_PARAMS;
434   }
435   cluster->config().set_speculative_execution_policy(
436       new ConstantSpeculativeExecutionPolicy(constant_delay_ms, max_speculative_executions));
437   return CASS_OK;
438 }
439 
cass_cluster_set_no_speculative_execution_policy(CassCluster * cluster)440 CassError cass_cluster_set_no_speculative_execution_policy(CassCluster* cluster) {
441   cluster->config().set_speculative_execution_policy(new NoSpeculativeExecutionPolicy());
442   return CASS_OK;
443 }
444 
cass_cluster_set_max_reusable_write_objects(CassCluster * cluster,unsigned num_objects)445 CassError cass_cluster_set_max_reusable_write_objects(CassCluster* cluster, unsigned num_objects) {
446   cluster->config().set_max_reusable_write_objects(num_objects);
447   return CASS_OK;
448 }
449 
cass_cluster_set_execution_profile(CassCluster * cluster,const char * name,CassExecProfile * profile)450 CassError cass_cluster_set_execution_profile(CassCluster* cluster, const char* name,
451                                              CassExecProfile* profile) {
452   return cass_cluster_set_execution_profile_n(cluster, name, SAFE_STRLEN(name), profile);
453 }
454 
cass_cluster_set_execution_profile_n(CassCluster * cluster,const char * name,size_t name_length,CassExecProfile * profile)455 CassError cass_cluster_set_execution_profile_n(CassCluster* cluster, const char* name,
456                                                size_t name_length, CassExecProfile* profile) {
457   if (name_length == 0 || !profile) {
458     return CASS_ERROR_LIB_BAD_PARAMS;
459   }
460   cluster->config().set_execution_profile(String(name, name_length), profile);
461   return CASS_OK;
462 }
463 
cass_cluster_set_prepare_on_all_hosts(CassCluster * cluster,cass_bool_t enabled)464 CassError cass_cluster_set_prepare_on_all_hosts(CassCluster* cluster, cass_bool_t enabled) {
465   cluster->config().set_prepare_on_all_hosts(enabled == cass_true);
466   return CASS_OK;
467 }
468 
cass_cluster_set_prepare_on_up_or_add_host(CassCluster * cluster,cass_bool_t enabled)469 CassError cass_cluster_set_prepare_on_up_or_add_host(CassCluster* cluster, cass_bool_t enabled) {
470   cluster->config().set_prepare_on_up_or_add_host(enabled == cass_true);
471   return CASS_OK;
472 }
473 
cass_cluster_set_local_address(CassCluster * cluster,const char * name)474 CassError cass_cluster_set_local_address(CassCluster* cluster, const char* name) {
475   return cass_cluster_set_local_address_n(cluster, name, SAFE_STRLEN(name));
476 }
477 
cass_cluster_set_local_address_n(CassCluster * cluster,const char * name,size_t name_length)478 CassError cass_cluster_set_local_address_n(CassCluster* cluster, const char* name,
479                                            size_t name_length) {
480   if (name_length == 0 || name == NULL) {
481     cluster->config().set_local_address(Address());
482   } else {
483     Address address(String(name, name_length), 0);
484     if (address.is_valid_and_resolved()) {
485       cluster->config().set_local_address(address);
486     } else {
487       return CASS_ERROR_LIB_HOST_RESOLUTION;
488     }
489   }
490   return CASS_OK;
491 }
492 
cass_cluster_set_no_compact(CassCluster * cluster,cass_bool_t enabled)493 CassError cass_cluster_set_no_compact(CassCluster* cluster, cass_bool_t enabled) {
494   cluster->config().set_no_compact(enabled == cass_true);
495   return CASS_OK;
496 }
497 
cass_cluster_set_host_listener_callback(CassCluster * cluster,CassHostListenerCallback callback,void * data)498 CassError cass_cluster_set_host_listener_callback(CassCluster* cluster,
499                                                   CassHostListenerCallback callback, void* data) {
500   cluster->config().set_host_listener(
501       DefaultHostListener::Ptr(new ExternalHostListener(callback, data)));
502   return CASS_OK;
503 }
504 
cass_cluster_set_cloud_secure_connection_bundle(CassCluster * cluster,const char * path)505 CassError cass_cluster_set_cloud_secure_connection_bundle(CassCluster* cluster, const char* path) {
506   return cass_cluster_set_cloud_secure_connection_bundle_n(cluster, path, SAFE_STRLEN(path));
507 }
508 
cass_cluster_set_cloud_secure_connection_bundle_n(CassCluster * cluster,const char * path,size_t path_length)509 CassError cass_cluster_set_cloud_secure_connection_bundle_n(CassCluster* cluster, const char* path,
510                                                             size_t path_length) {
511   if (cluster->config().contact_points().empty() && !cluster->config().ssl_context()) {
512     SslContextFactory::init_once();
513   }
514   return cass_cluster_set_cloud_secure_connection_bundle_no_ssl_lib_init_n(cluster, path,
515                                                                            path_length);
516 }
517 
cass_cluster_set_cloud_secure_connection_bundle_no_ssl_lib_init(CassCluster * cluster,const char * path)518 CassError cass_cluster_set_cloud_secure_connection_bundle_no_ssl_lib_init(CassCluster* cluster,
519                                                                           const char* path) {
520   return cass_cluster_set_cloud_secure_connection_bundle_no_ssl_lib_init_n(cluster, path,
521                                                                            SAFE_STRLEN(path));
522 }
523 
cass_cluster_set_cloud_secure_connection_bundle_no_ssl_lib_init_n(CassCluster * cluster,const char * path,size_t path_length)524 CassError cass_cluster_set_cloud_secure_connection_bundle_no_ssl_lib_init_n(CassCluster* cluster,
525                                                                             const char* path,
526                                                                             size_t path_length) {
527   const AddressVec& contact_points = cluster->config().contact_points();
528   const SslContext::Ptr& ssl_context = cluster->config().ssl_context();
529   if (!contact_points.empty() || ssl_context) {
530     String message;
531     if (!cluster->config().contact_points().empty()) {
532       message.append("Contact points");
533     }
534     if (cluster->config().ssl_context()) {
535       if (!message.empty()) {
536         message.append(" and ");
537       }
538       message.append("SSL context");
539     }
540     message.append(" must not be specified with cloud secure connection bundle");
541     LOG_ERROR("%s", message.c_str());
542 
543     return CASS_ERROR_LIB_BAD_PARAMS;
544   }
545 
546   if (!cluster->config().set_cloud_secure_connection_bundle(String(path, path_length))) {
547     return CASS_ERROR_LIB_BAD_PARAMS;
548   }
549   return CASS_OK;
550 }
551 
cass_cluster_set_application_name(CassCluster * cluster,const char * application_name)552 void cass_cluster_set_application_name(CassCluster* cluster, const char* application_name) {
553   cass_cluster_set_application_name_n(cluster, application_name, SAFE_STRLEN(application_name));
554 }
555 
cass_cluster_set_application_name_n(CassCluster * cluster,const char * application_name,size_t application_name_length)556 void cass_cluster_set_application_name_n(CassCluster* cluster, const char* application_name,
557                                          size_t application_name_length) {
558   cluster->config().set_application_name(String(application_name, application_name_length));
559 }
560 
cass_cluster_set_application_version(CassCluster * cluster,const char * application_version)561 void cass_cluster_set_application_version(CassCluster* cluster, const char* application_version) {
562   cass_cluster_set_application_version_n(cluster, application_version,
563                                          SAFE_STRLEN(application_version));
564 }
565 
cass_cluster_set_application_version_n(CassCluster * cluster,const char * application_version,size_t application_version_length)566 void cass_cluster_set_application_version_n(CassCluster* cluster, const char* application_version,
567                                             size_t application_version_length) {
568   cluster->config().set_application_version(
569       String(application_version, application_version_length));
570 }
571 
cass_cluster_set_client_id(CassCluster * cluster,CassUuid client_id)572 void cass_cluster_set_client_id(CassCluster* cluster, CassUuid client_id) {
573   cluster->config().set_client_id(client_id);
574 }
575 
cass_cluster_set_monitor_reporting_interval(CassCluster * cluster,unsigned interval_secs)576 void cass_cluster_set_monitor_reporting_interval(CassCluster* cluster, unsigned interval_secs) {
577   cluster->config().set_monitor_reporting_interval_secs(interval_secs);
578 }
579 
cass_cluster_free(CassCluster * cluster)580 void cass_cluster_free(CassCluster* cluster) { delete cluster->from(); }
581 
582 } // extern "C"
583