Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Sources/CLibMongoC/include/CLibMongoC_mongoc-uri.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#define MONGOC_URI_CANONICALIZEHOSTNAME "canonicalizehostname"
#define MONGOC_URI_CONNECTTIMEOUTMS "connecttimeoutms"
#define MONGOC_URI_COMPRESSORS "compressors"
#define MONGOC_URI_DIRECTCONNECTION "directconnection"
#define MONGOC_URI_GSSAPISERVICENAME "gssapiservicename"
#define MONGOC_URI_HEARTBEATFREQUENCYMS "heartbeatfrequencyms"
#define MONGOC_URI_JOURNAL "journal"
Expand Down Expand Up @@ -117,6 +118,8 @@ mongoc_uri_get_password (const mongoc_uri_t *uri);
MONGOC_EXPORT (bool)
mongoc_uri_set_password (mongoc_uri_t *uri, const char *password);
MONGOC_EXPORT (bool)
mongoc_uri_has_option (const mongoc_uri_t *uri, const char *key);
MONGOC_EXPORT (bool)
mongoc_uri_option_is_int32 (const char *key);
MONGOC_EXPORT (bool)
mongoc_uri_option_is_int64 (const char *key);
Expand Down
6 changes: 5 additions & 1 deletion Sources/CLibMongoC/mongoc/mongoc-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -2670,7 +2670,11 @@ _mongoc_client_set_apm_callbacks_private (mongoc_client_t *client,
}

client->apm_context = context;
mongoc_topology_set_apm_callbacks (client->topology, callbacks, context);

/* A client pool sets APM callbacks for the entire pool. */
if (client->topology->single_threaded) {
mongoc_topology_set_apm_callbacks (client->topology, callbacks, context);
}

return true;
}
Expand Down
31 changes: 28 additions & 3 deletions Sources/CLibMongoC/mongoc/mongoc-topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded)
uint32_t id;
const mongoc_host_list_t *hl;
mongoc_rr_data_t rr_data;
bool has_directconnection;
bool directconnection;

BSON_ASSERT (uri);

Expand Down Expand Up @@ -328,12 +330,35 @@ mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded)

/*
* Set topology type from URI:
* - if we've got a replicaSet name, initialize to RS_NO_PRIMARY
* - otherwise, if the seed list has a single host, initialize to SINGLE
* + if directConnection=true
* - whether or not we have a replicaSet name, initialize to SINGLE
* (directConnect with SRV or multiple hosts triggers a URI parse error)
* + if directConnection=false
* - if we've got a replicaSet name, initialize to RS_NO_PRIMARY
* - otherwise, initialize to UNKNOWN
* + if directConnection was not specified in the URI (old behavior)
* - if we've got a replicaSet name, initialize to RS_NO_PRIMARY
* - otherwise, if the seed list has a single host, initialize to SINGLE
* - everything else gets initialized to UNKNOWN
*/
has_directconnection = mongoc_uri_has_option (
uri, MONGOC_URI_DIRECTCONNECTION);
directconnection = has_directconnection &&
mongoc_uri_get_option_as_bool (uri, MONGOC_URI_DIRECTCONNECTION, false);
hl = mongoc_uri_get_hosts (topology->uri);
if (mongoc_uri_get_replica_set (topology->uri)) {
if (service && !has_directconnection) {
init_type = MONGOC_TOPOLOGY_UNKNOWN;
} else if (has_directconnection) {
if (directconnection) {
init_type = MONGOC_TOPOLOGY_SINGLE;
} else {
if (mongoc_uri_get_replica_set (topology->uri)) {
init_type = MONGOC_TOPOLOGY_RS_NO_PRIMARY;
} else {
init_type = MONGOC_TOPOLOGY_UNKNOWN;
}
}
} else if (mongoc_uri_get_replica_set (topology->uri)) {
init_type = MONGOC_TOPOLOGY_RS_NO_PRIMARY;
} else {
if (hl && hl->next) {
Expand Down
48 changes: 48 additions & 0 deletions Sources/CLibMongoC/mongoc/mongoc-uri.c
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,14 @@ mongoc_uri_bson_append_or_replace_key (bson_t *options,
}


bool
mongoc_uri_has_option (const mongoc_uri_t *uri, const char *key)
{
bson_iter_t iter;

return bson_iter_init_find_case (&iter, &uri->options, key);
}

bool
mongoc_uri_option_is_int32 (const char *key)
{
Expand Down Expand Up @@ -731,6 +739,7 @@ bool
mongoc_uri_option_is_bool (const char *key)
{
return !strcasecmp (key, MONGOC_URI_CANONICALIZEHOSTNAME) ||
!strcasecmp (key, MONGOC_URI_DIRECTCONNECTION) ||
!strcasecmp (key, MONGOC_URI_JOURNAL) ||
!strcasecmp (key, MONGOC_URI_RETRYREADS) ||
!strcasecmp (key, MONGOC_URI_RETRYWRITES) ||
Expand Down Expand Up @@ -1335,6 +1344,41 @@ mongoc_uri_finalize_auth (mongoc_uri_t *uri,
return true;
}

static bool
mongoc_uri_finalize_directconnection (mongoc_uri_t *uri, bson_error_t *error)
{
bool directconnection = false;

directconnection =
mongoc_uri_get_option_as_bool (uri, MONGOC_URI_DIRECTCONNECTION, false);
if (!directconnection) {
return true;
}

/* URI options spec: "The driver MUST report an error if the
* directConnection=true URI option is specified with an SRV URI, because
* the URI may resolve to multiple hosts. The driver MUST allow specifying
* directConnection=false URI option with an SRV URI." */
if (uri->is_srv) {
MONGOC_URI_ERROR (
error, "%s", "SRV URI not allowed with directConnection option");
return false;
}

/* URI options spec: "The driver MUST report an error if the
* directConnection=true URI option is specified with multiple seeds." */
if (uri->hosts && uri->hosts->next) {
MONGOC_URI_ERROR (
error,
"%s",
"Multiple seeds not allowed with directConnection option");
return false;
}

return true;

}

static bool
mongoc_uri_parse_before_slash (mongoc_uri_t *uri,
const char *before_slash,
Expand Down Expand Up @@ -1447,6 +1491,10 @@ mongoc_uri_parse (mongoc_uri_t *uri, const char *str, bson_error_t *error)
goto error;
}

if (!mongoc_uri_finalize_directconnection (uri, error)) {
goto error;
}

bson_free (before_slash);
return true;

Expand Down
153 changes: 153 additions & 0 deletions etc/CDRIVER-3532-directConnection.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
diff --git a/Sources/CLibMongoC/mongoc/mongoc-topology.c b/Sources/CLibMongoC/mongoc/mongoc-topology.c
index 987f98e4e..7b9136bfc 100644
--- a/Sources/CLibMongoC/mongoc/mongoc-topology.c
+++ a/Sources/CLibMongoC/mongoc/mongoc-topology.c
@@ -210,6 +210,8 @@ mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded)
uint32_t id;
const mongoc_host_list_t *hl;
mongoc_rr_data_t rr_data;
+ bool has_directconnection;
+ bool directconnection;

BSON_ASSERT (uri);

@@ -328,12 +330,35 @@ mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded)

/*
* Set topology type from URI:
- * - if we've got a replicaSet name, initialize to RS_NO_PRIMARY
- * - otherwise, if the seed list has a single host, initialize to SINGLE
+ * + if directConnection=true
+ * - whether or not we have a replicaSet name, initialize to SINGLE
+ * (directConnect with SRV or multiple hosts triggers a URI parse error)
+ * + if directConnection=false
+ * - if we've got a replicaSet name, initialize to RS_NO_PRIMARY
+ * - otherwise, initialize to UNKNOWN
+ * + if directConnection was not specified in the URI (old behavior)
+ * - if we've got a replicaSet name, initialize to RS_NO_PRIMARY
+ * - otherwise, if the seed list has a single host, initialize to SINGLE
* - everything else gets initialized to UNKNOWN
*/
+ has_directconnection = mongoc_uri_has_option (
+ uri, MONGOC_URI_DIRECTCONNECTION);
+ directconnection = has_directconnection &&
+ mongoc_uri_get_option_as_bool (uri, MONGOC_URI_DIRECTCONNECTION, false);
hl = mongoc_uri_get_hosts (topology->uri);
- if (mongoc_uri_get_replica_set (topology->uri)) {
+ if (service && !has_directconnection) {
+ init_type = MONGOC_TOPOLOGY_UNKNOWN;
+ } else if (has_directconnection) {
+ if (directconnection) {
+ init_type = MONGOC_TOPOLOGY_SINGLE;
+ } else {
+ if (mongoc_uri_get_replica_set (topology->uri)) {
+ init_type = MONGOC_TOPOLOGY_RS_NO_PRIMARY;
+ } else {
+ init_type = MONGOC_TOPOLOGY_UNKNOWN;
+ }
+ }
+ } else if (mongoc_uri_get_replica_set (topology->uri)) {
init_type = MONGOC_TOPOLOGY_RS_NO_PRIMARY;
} else {
if (hl && hl->next) {
diff --git a/Sources/CLibMongoC/mongoc/mongoc-uri.c b/Sources/CLibMongoC/mongoc/mongoc-uri.c
index 8e6fa149e..31ac05272 100644
--- a/Sources/CLibMongoC/mongoc/mongoc-uri.c
+++ b/Sources/CLibMongoC/mongoc/mongoc-uri.c
@@ -702,6 +702,14 @@ mongoc_uri_bson_append_or_replace_key (bson_t *options,
}


+bool
+mongoc_uri_has_option (const mongoc_uri_t *uri, const char *key)
+{
+ bson_iter_t iter;
+
+ return bson_iter_init_find_case (&iter, &uri->options, key);
+}
+
bool
mongoc_uri_option_is_int32 (const char *key)
{
@@ -731,6 +739,7 @@ bool
mongoc_uri_option_is_bool (const char *key)
{
return !strcasecmp (key, MONGOC_URI_CANONICALIZEHOSTNAME) ||
+ !strcasecmp (key, MONGOC_URI_DIRECTCONNECTION) ||
!strcasecmp (key, MONGOC_URI_JOURNAL) ||
!strcasecmp (key, MONGOC_URI_RETRYREADS) ||
!strcasecmp (key, MONGOC_URI_RETRYWRITES) ||
@@ -1390,6 +1399,41 @@ mongoc_uri_finalize_auth (mongoc_uri_t *uri,
return true;
}

+static bool
+mongoc_uri_finalize_directconnection (mongoc_uri_t *uri, bson_error_t *error)
+{
+ bool directconnection = false;
+
+ directconnection =
+ mongoc_uri_get_option_as_bool (uri, MONGOC_URI_DIRECTCONNECTION, false);
+ if (!directconnection) {
+ return true;
+ }
+
+ /* URI options spec: "The driver MUST report an error if the
+ * directConnection=true URI option is specified with an SRV URI, because
+ * the URI may resolve to multiple hosts. The driver MUST allow specifying
+ * directConnection=false URI option with an SRV URI." */
+ if (uri->is_srv) {
+ MONGOC_URI_ERROR (
+ error, "%s", "SRV URI not allowed with directConnection option");
+ return false;
+ }
+
+ /* URI options spec: "The driver MUST report an error if the
+ * directConnection=true URI option is specified with multiple seeds." */
+ if (uri->hosts && uri->hosts->next) {
+ MONGOC_URI_ERROR (
+ error,
+ "%s",
+ "Multiple seeds not allowed with directConnection option");
+ return false;
+ }
+
+ return true;
+
+}
+
static bool
mongoc_uri_parse_before_slash (mongoc_uri_t *uri,
const char *before_slash,
@@ -1502,6 +1546,10 @@ mongoc_uri_parse (mongoc_uri_t *uri, const char *str, bson_error_t *error)
goto error;
}

+ if (!mongoc_uri_finalize_directconnection (uri, error)) {
+ goto error;
+ }
+
bson_free (before_slash);
return true;

diff --git a/Sources/CLibMongoC/include/CLibMongoC_mongoc-uri.h b/Sources/CLibMongoC/include/CLibMongoC_mongoc-uri.h
index a190b1f71..e08b7d43f 100644
--- a/Sources/CLibMongoC/include/CLibMongoC_mongoc-uri.h
+++ b/Sources/CLibMongoC/include/CLibMongoC_mongoc-uri.h
@@ -40,6 +40,7 @@
#define MONGOC_URI_CANONICALIZEHOSTNAME "canonicalizehostname"
#define MONGOC_URI_CONNECTTIMEOUTMS "connecttimeoutms"
#define MONGOC_URI_COMPRESSORS "compressors"
+#define MONGOC_URI_DIRECTCONNECTION "directconnection"
#define MONGOC_URI_GSSAPISERVICENAME "gssapiservicename"
#define MONGOC_URI_HEARTBEATFREQUENCYMS "heartbeatfrequencyms"
#define MONGOC_URI_JOURNAL "journal"
@@ -120,6 +121,8 @@ mongoc_uri_get_password (const mongoc_uri_t *uri);
MONGOC_EXPORT (bool)
mongoc_uri_set_password (mongoc_uri_t *uri, const char *password);
MONGOC_EXPORT (bool)
+mongoc_uri_has_option (const mongoc_uri_t *uri, const char *key);
+MONGOC_EXPORT (bool)
mongoc_uri_option_is_int32 (const char *key);
MONGOC_EXPORT (bool)
mongoc_uri_option_is_int64 (const char *key);
17 changes: 17 additions & 0 deletions etc/CDRIVER-3623-fix-setting-apm-in-pooled-client.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
diff --git a/Sources/CLibMongoC/mongoc/mongoc-client.c b/Sources/CLibMongoC/mongoc/mongoc-client.c
index ea17e356c..77abca8e0 100644
--- a/Sources/CLibMongoC/mongoc/mongoc-client.c
+++ b/Sources/CLibMongoC/mongoc/mongoc-client.c
@@ -2689,7 +2689,11 @@ _mongoc_client_set_apm_callbacks_private (mongoc_client_t *client,
}

client->apm_context = context;
- mongoc_topology_set_apm_callbacks (client->topology, callbacks, context);
+
+ /* A client pool sets APM callbacks for the entire pool. */
+ if (client->topology->single_threaded) {
+ mongoc_topology_set_apm_callbacks (client->topology, callbacks, context);
+ }

return true;
}
5 changes: 5 additions & 0 deletions etc/vendor-libmongoc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ echo "RENAMING header files"
echo "PATCHING libmongoc"
git apply "${ETC_DIR}/inttypes-non-modular-header-workaround.diff"

# These patches are temporary workarounds to give us early access to the directConnection URI option and a bug fix.
# This should be removed from the script when we update our vendored libmongoc to 1.17 via SWIFT-766.
git apply "${ETC_DIR}/CDRIVER-3532-directConnection.diff"
git apply "${ETC_DIR}/CDRIVER-3623-fix-setting-apm-in-pooled-client.diff"

# Clang modules are build by a conventional structure with an `include` folder for public
# includes, and an umbrella header used as the primary entry point. As part of the vendoring
# process, we copy in our own handwritten umbrella file. Currently, there is no generated
Expand Down