alexdrenea/CosmosDb.Net

Unable to change ConnectionMode on CosmosClient

andrewdmoreno opened this issue · 4 comments

I am in an enterprise environment and often am unable (especially during local development) to use ConnectionMode.Direct for Cosmos and have to use ConnectionMode.Gateway to get past firewall issues. Due to the way CosmosClientSql and CosmosClientGraph must be instantiated (via the static methods), I am unable to customize that setting. There is also not a ctor that I can use and even so the init properties have private setters.

Would it be possible to allow for some flexibility in instantiating these client objects in the event we need to customize the CosmosClient further? Either that or at least the ability to set the ConnectionMode?

If one of these approaches is acceptable, please let me know and I would be more than happy to submit a PR for it if need be.

Thank you for the feedback. You are correct, I think I need to add a bit more flexibility into setting those options in the ctor. I will try and get an update in soon.

@andrewdmoreno I pushed some new code and generated a new release and NuGet package. Check it out and let me know if it helps.

Essentially you're able to pass in a CosmosClientOptons instance in the CreateOptions

 var sqlClient = await CosmosClientSql.GetByConnectionString(connectionString, databaseId, containerId, 
				new CreateOptions(databaseId, containerId, "/pk") 
				{ 
					ClientOptions = new CosmosClientOptions
					{
						ConnectionMode = ConnectionMode.Gateway
					}
                                 });

That should do the trick. I will update and let you know if I run across any issues.

@alexdrenea Thanks for making this update! I was able to override the ConnectionMode as desired. I did have one observation though that I'd like to get your thoughts on.

I was wondering if CreateOptions was really the best place for the CosmosClientOptions from a user's perspective. The reason I mention this is because I noticed that behind the scenes it is actually causing the code to go down a completely different path from a branching logic perspective when this is not really desired, we just want to adjust connection settings. See the below from GetCosmosDbClientInternal method:

            if (createOptions != null)
            {
                database = await client.CreateDatabaseIfNotExistsAsync(databaseId, createOptions.DatabaseThrouhput);
                container = await database.CreateContainerIfNotExistsAsync(createOptions.Container, createOptions.ContainerThroughput);
            }
            else
            {
                database = client.GetDatabase(databaseId);
                var ensureDbExists = await database.ReadAsync();
                if (ensureDbExists.StatusCode == System.Net.HttpStatusCode.NotFound)
                    throw new Exception($"Database '{databaseId}' not found. Use forceCreate:true if you want the database to be created for you.");

                container = database.GetContainer(containerId);
                var ensureExists = await container.ReadContainerAsync();
                if (ensureExists.StatusCode == System.Net.HttpStatusCode.NotFound)
                    throw new Exception($"Container '{containerId}' not found. Use forceCreate:true if you want a collection to be created for you.");
            }

As you can see here - this now means that the code will go down the path of CreateDatabaseIfNotExistsAsync and CreateContainerIfNotExists which is a subtle change under the covers that the user may not desire. The CosmosClientOptions are not really settings that impact creation per se so I was wondering if that was the best place for them. Would love to get your thoughts?