Skip to content

Commit

Permalink
Client Telemetry : Refactors code to compute hash of VM ID and Proces…
Browse files Browse the repository at this point in the history
…s Name information (#3376)

* hashed vmid and processname

* appended hashedvmid

* dummycommit

* use string format

* renamed util class name

* fix refrence

Co-authored-by: Sourabh Jain <sourabhjain@microsoft.com>
  • Loading branch information
sourabh1007 and sourabh1007 committed Aug 17, 2022
1 parent 83d9f70 commit 1151f55
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 35 deletions.
3 changes: 2 additions & 1 deletion Microsoft.Azure.Cosmos/src/Telemetry/ClientTelemetry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace Microsoft.Azure.Cosmos.Telemetry
using Microsoft.Azure.Documents.Collections;
using Microsoft.Azure.Documents.Rntbd;
using Newtonsoft.Json;
using Util;

/// <summary>
/// This class collects and send all the telemetry information.
Expand Down Expand Up @@ -99,7 +100,7 @@ private ClientTelemetry(

this.clientTelemetryInfo = new ClientTelemetryProperties(
clientId: clientId,
processId: System.Diagnostics.Process.GetCurrentProcess().ProcessName,
processId: HashingExtension.ComputeHash(System.Diagnostics.Process.GetCurrentProcess().ProcessName),
userAgent: userAgent,
connectionMode: connectionMode,
preferredRegions: preferredRegions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace Microsoft.Azure.Cosmos.Telemetry
using Microsoft.Azure.Cosmos.Core.Trace;
using Microsoft.Azure.Documents;
using Newtonsoft.Json;
using Util;

internal static class ClientTelemetryOptions
{
Expand Down
3 changes: 2 additions & 1 deletion Microsoft.Azure.Cosmos/src/Telemetry/Compute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace Microsoft.Azure.Cosmos.Telemetry
{
using System;
using Newtonsoft.Json;
using Util;

[Serializable]
internal sealed class Compute
Expand All @@ -24,7 +25,7 @@ public Compute(
this.AzEnvironment = azEnvironment;
this.OSType = oSType;
this.VMSize = vMSize;
this.VMId = "vmId:" + vMId;
this.VMId = $"{VmMetadataApiHandler.HashedVmIdPrefix}{HashingExtension.ComputeHash(vMId)}";
}

[JsonProperty(PropertyName = "location")]
Expand Down
34 changes: 8 additions & 26 deletions Microsoft.Azure.Cosmos/src/Telemetry/VmMetadataApiHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Microsoft.Azure.Cosmos.Telemetry
using Microsoft.Azure.Cosmos.Core.Trace;
using Microsoft.Azure.Documents;
using Newtonsoft.Json.Linq;
using Util;

/// <summary>
/// Task to collect virtual machine metadata information. using instance metedata service API.
Expand All @@ -20,7 +21,12 @@ namespace Microsoft.Azure.Cosmos.Telemetry
/// </summary>
internal static class VmMetadataApiHandler
{
internal const string HashedMachineNamePrefix = "hashedMachineName:";
internal const string HashedVmIdPrefix = "hashedVmId:";
internal const string UuidPrefix = "uuid:";

internal static readonly Uri vmMetadataEndpointUrl = new ("http://169.254.169.254/metadata/instance?api-version=2020-06-01");

private static readonly string nonAzureCloud = "NonAzureVM";

private static readonly object lockObject = new object();
Expand Down Expand Up @@ -139,42 +145,18 @@ internal static string GetCloudInformation()
return VmMetadataApiHandler.azMetadata?.Compute?.AzEnvironment ?? VmMetadataApiHandler.nonAzureCloud;
}

/// <summary>
/// Hash a passed Value
/// </summary>
/// <param name="rawData"></param>
/// <returns>hashed Value</returns>
internal static string ComputeHash(string rawData)
{
if (string.IsNullOrEmpty(rawData))
{
throw new ArgumentNullException(nameof(rawData));
}

// Create a SHA256
using (SHA256 sha256Hash = SHA256.Create())
{
// ComputeHash - returns byte array
byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData));
Array.Resize(ref bytes, 16);

// Convert byte array to a string
return new Guid(bytes).ToString();
}
}

private static readonly Lazy<string> uniqueId = new Lazy<string>(() =>
{
try
{
return "hashedMachineName:" + VmMetadataApiHandler.ComputeHash(Environment.MachineName);
return $"{VmMetadataApiHandler.HashedMachineNamePrefix}{HashingExtension.ComputeHash(Environment.MachineName)}";
}
catch (Exception ex)
{
DefaultTrace.TraceWarning("Error while generating hashed machine name " + ex.Message);
}
return "uuid:" + Guid.NewGuid().ToString();
return $"{VmMetadataApiHandler.UuidPrefix}{Guid.NewGuid()}";
});

}
Expand Down
38 changes: 38 additions & 0 deletions Microsoft.Azure.Cosmos/src/Util/HashingExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------

namespace Microsoft.Azure.Cosmos.Util
{
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;

internal class HashingExtension
{
/// <summary>
/// Hash a passed Value
/// </summary>
/// <param name="rawData"></param>
/// <returns>hashed Value</returns>
internal static string ComputeHash(string rawData)
{
if (string.IsNullOrEmpty(rawData))
{
throw new ArgumentNullException(nameof(rawData));
}

// Create a SHA256
using (SHA256 sha256Hash = SHA256.Create())
{
// ComputeHash - returns byte array
byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData));
Array.Resize(ref bytes, 16);

// Convert byte array to a string
return new Guid(bytes).ToString();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests
using Documents.Rntbd;
using System.Globalization;
using System.Linq;
using Cosmos.Util;

[TestClass]
public class ClientTelemetryTests : BaseCosmosClientHelper
Expand Down Expand Up @@ -935,6 +936,7 @@ private static void AssertAccountLevelInformation(
Assert.IsNull(telemetryInfo.AcceleratedNetworking);
Assert.IsNotNull(telemetryInfo.ClientId);
Assert.IsNotNull(telemetryInfo.ProcessId);
Assert.AreEqual(HashingExtension.ComputeHash(System.Diagnostics.Process.GetCurrentProcess().ProcessName), telemetryInfo.ProcessId);
Assert.IsNotNull(telemetryInfo.UserAgent);
Assert.IsNotNull(telemetryInfo.ConnectionMode);

Expand All @@ -948,15 +950,14 @@ private static void AssertAccountLevelInformation(
{
if (isAzureInstance.Value)
{
Assert.AreEqual("vmId:d0cb93eb-214b-4c2b-bd3d-cc93e90d9efd", machineId.First(), $"Generated Machine id is : {machineId.First()}");
Assert.AreEqual($"{VmMetadataApiHandler.HashedVmIdPrefix}{HashingExtension.ComputeHash("d0cb93eb-214b-4c2b-bd3d-cc93e90d9efd")}", machineId.First(), $"Generated Machine id is : {machineId.First()}");
}
else
{
Assert.AreNotEqual("vmId:d0cb93eb-214b-4c2b-bd3d-cc93e90d9efd", machineId.First(), $"Generated Machine id is : {machineId.First()}");
Assert.AreNotEqual($"{VmMetadataApiHandler.HashedVmIdPrefix}{HashingExtension.ComputeHash("d0cb93eb-214b-4c2b-bd3d-cc93e90d9efd")}", machineId.First(), $"Generated Machine id is : {machineId.First()}");
Assert.AreEqual(1, machineId.Count, $"Multiple Machine Id has been generated i.e {JsonConvert.SerializeObject(machineId)}");
}
}

}

[TestMethod]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace Microsoft.Azure.Cosmos
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Newtonsoft.Json;
using Util;

[TestClass]
public class VmMetadataApiHandlerTest
Expand Down Expand Up @@ -56,7 +57,7 @@ static Task<HttpResponseMessage> sendFunc(HttpRequestMessage request, Cancellati
VmMetadataApiHandler.TryInitialize(cosmoshttpClient);

await Task.Delay(2000);
Assert.AreEqual("vmId:d0cb93eb-214b-4c2b-bd3d-cc93e90d9efd", VmMetadataApiHandler.GetMachineId());
Assert.AreEqual($"{VmMetadataApiHandler.HashedVmIdPrefix}{HashingExtension.ComputeHash("d0cb93eb-214b-4c2b-bd3d-cc93e90d9efd")}", VmMetadataApiHandler.GetMachineId());
Assert.AreEqual(VmMetadataApiHandler.GetMachineRegion(), "eastus");
}

Expand Down Expand Up @@ -88,7 +89,7 @@ static Task<HttpResponseMessage> sendFunc(HttpRequestMessage request, Cancellati
[TestMethod]
public async Task GetHashedMachineNameAsMachineIdTest()
{
string expectedMachineId = "hashedMachineName:" + VmMetadataApiHandler.ComputeHash(Environment.MachineName);
string expectedMachineId = VmMetadataApiHandler.HashedMachineNamePrefix + HashingExtension.ComputeHash(Environment.MachineName);

static Task<HttpResponseMessage> sendFunc(HttpRequestMessage request, CancellationToken cancellationToken) { throw new Exception("error while making API call"); };

Expand All @@ -105,7 +106,7 @@ public async Task GetHashedMachineNameAsMachineIdTest()
[TestMethod]
public void ComputeHashTest()
{
string hashedValue = VmMetadataApiHandler.ComputeHash("abc");
string hashedValue = HashingExtension.ComputeHash("abc");
Assert.AreEqual("bf1678ba-018f-eacf-4141-40de5dae2223", hashedValue);
}

Expand All @@ -128,7 +129,7 @@ public async Task ParseAzureVMMetadataTest()
Assert.AreEqual("AzurePublicCloud", metadata.Compute.AzEnvironment);
Assert.AreEqual("Linux", metadata.Compute.OSType);
Assert.AreEqual("Standard_D2s_v3", metadata.Compute.VMSize);
Assert.AreEqual("vmId:d0cb93eb-214b-4c2b-bd3d-cc93e90d9efd", metadata.Compute.VMId);
Assert.AreEqual($"{VmMetadataApiHandler.HashedVmIdPrefix}{HashingExtension.ComputeHash("d0cb93eb-214b-4c2b-bd3d-cc93e90d9efd")}", metadata.Compute.VMId);
}

[TestMethod]
Expand Down

0 comments on commit 1151f55

Please sign in to comment.