Skip to content

Commit

Permalink
CSHARP-4718: Enable Container and kubernetes awareness (#1295)
Browse files Browse the repository at this point in the history
  • Loading branch information
adelinowona committed Apr 2, 2024
1 parent 43fb293 commit 5f7fc33
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 1 deletion.
36 changes: 35 additions & 1 deletion src/MongoDB.Driver.Core/Core/Connections/ClientDocumentHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using System.Text.RegularExpressions;
using MongoDB.Bson;
using MongoDB.Driver.Core.Configuration;
using MongoDB.Driver.Core.Misc;

namespace MongoDB.Driver.Core.Connections
{
Expand All @@ -30,17 +31,31 @@ internal class ClientDocumentHelper
private static Lazy<BsonDocument> __envDocument;
private static Lazy<BsonDocument> __osDocument;
private static Lazy<string> __platformString;
private static IEnvironmentVariableProvider __environmentVariableProvider;
private static IFileSystemProvider __fileSystemProvider;

private static void Initialize()
{
__driverDocument = new Lazy<BsonDocument>(CreateDriverDocument);
__envDocument = new Lazy<BsonDocument>(CreateEnvDocument);
__osDocument = new Lazy<BsonDocument>(CreateOSDocument);
__platformString = new Lazy<string>(GetPlatformString);
__environmentVariableProvider = EnvironmentVariableProvider.Instance;
__fileSystemProvider = FileSystemProvider.Instance;
}

static ClientDocumentHelper() => Initialize();

internal static void SetEnvironmentVariableProvider(IEnvironmentVariableProvider environmentVariableProvider)
{
__environmentVariableProvider = environmentVariableProvider;
}

internal static void SetFileSystemProvider(IFileSystemProvider fileSystemProvider)
{
__fileSystemProvider = fileSystemProvider;
}

// private static methods
internal static BsonDocument CreateClientDocument(string applicationName, LibraryInfo libraryInfo)
{
Expand Down Expand Up @@ -107,13 +122,15 @@ internal static BsonDocument CreateEnvDocument()
var timeout = GetTimeoutSec(name);
var memoryDb = GetMemoryMb(name);
var region = GetRegion(name);
var container = GetContainerDocument();

return new BsonDocument
{
{ "name", name },
{ "timeout_sec", timeout, timeout.HasValue },
{ "memory_mb", memoryDb, memoryDb.HasValue },
{ "region", region, region != null }
{ "region", region, region != null },
{ "container", container, container != null }
};
}
else
Expand Down Expand Up @@ -176,6 +193,23 @@ name switch
_ => null,
};

BsonDocument GetContainerDocument()
{
var isExecutionContainerDocker = __fileSystemProvider.File.Exists("/.dockerenv");
var isOrchestratorKubernetes = __environmentVariableProvider.GetEnvironmentVariable("KUBERNETES_SERVICE_HOST") != null;

if (isExecutionContainerDocker || isOrchestratorKubernetes)
{
return new()
{
{ "runtime", "docker", isExecutionContainerDocker },
{ "orchestrator", "kubernetes", isOrchestratorKubernetes }
};
}

return null;
}

int? GetIntValue(string environmentVariable) =>
int.TryParse(Environment.GetEnvironmentVariable(environmentVariable), out var value) ? value : null;
}
Expand Down
31 changes: 31 additions & 0 deletions src/MongoDB.Driver.Core/Core/Misc/FileSystemProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* Copyright 2010-present MongoDB Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace MongoDB.Driver.Core.Misc
{
/// <summary>
/// Abstractions of the file system.
/// </summary>
internal interface IFileSystemProvider
{
IFile File { get; }
}

internal class FileSystemProvider : IFileSystemProvider
{
public static IFileSystemProvider Instance { get; } = new FileSystemProvider();
public IFile File { get; } = new FileWrapper();
}
}
35 changes: 35 additions & 0 deletions src/MongoDB.Driver.Core/Core/Misc/FileWrapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* Copyright 2010-present MongoDB Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

using System.IO;

namespace MongoDB.Driver.Core.Misc
{
/// <summary>
/// Abstraction for static methods in <see cref="System.IO.File" />.
/// </summary>
internal interface IFile
{
bool Exists(string name);
}

internal sealed class FileWrapper : IFile
{
public bool Exists(string name)
{
return File.Exists(name);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
using MongoDB.Bson;
using MongoDB.Driver.Core.TestHelpers;
using MongoDB.Driver.Core.Configuration;
using MongoDB.Driver.Core.Misc;
using MongoDB.TestHelpers.XunitExtensions;
using Moq;
using Xunit;

namespace MongoDB.Driver.Core.Connections
Expand Down Expand Up @@ -132,6 +134,44 @@ public void CreateDriverDocument_should_return_expected_result()
result.Should().Be($"{{ name : 'mongo-csharp-driver', version : '{driverVersion}' }}");
}

[Theory]
[InlineData(true, true, "{ name : 'vercel', container : { \"runtime\" : \"docker\", \"orchestrator\" : \"kubernetes\" }}")]
[InlineData(false, true, "{ name : 'vercel', container : { \"orchestrator\" : \"kubernetes\" }}")]
[InlineData(true, false, "{ name : 'vercel', container : { \"runtime\" : \"docker\" }}")]
[InlineData(false, false, "{ name : 'vercel' }")]
public void CreateEnvDocument_should_return_expected_result(bool isDockerToBeDetected, bool isKubernetesToBeDetected, string expected)
{
var fileSystemProviderMock = new Mock<IFileSystemProvider>();
var environmentVariableProviderMock = new Mock<IEnvironmentVariableProvider>();

if (isKubernetesToBeDetected)
{
environmentVariableProviderMock.Setup(p => p.GetEnvironmentVariable("KUBERNETES_SERVICE_HOST")).Returns("dummy");
}
else
{
environmentVariableProviderMock.Setup(p => p.GetEnvironmentVariable("KUBERNETES_SERVICE_HOST")).Returns(null as string);
}

if (isDockerToBeDetected)
{
fileSystemProviderMock.Setup(p => p.File.Exists("/.dockerenv")).Returns(true);
}
else
{
fileSystemProviderMock.Setup(p => p.File.Exists("/.dockerenv")).Returns(false);

}

ClientDocumentHelper.SetEnvironmentVariableProvider(environmentVariableProviderMock.Object);
ClientDocumentHelper.SetFileSystemProvider(fileSystemProviderMock.Object);
using (new DisposableEnvironmentVariable("VERCEL"))
{
var result = ClientDocumentHelper.CreateEnvDocument();
result.Should().Be(expected);
}
}

[Fact]
public void CreateOSDocument_should_return_expected_result()
{
Expand Down

0 comments on commit 5f7fc33

Please sign in to comment.