diff --git a/Src/StackifyLib/Models/AzureConfig.cs b/Src/StackifyLib/Models/AzureConfig.cs
index 8dad9a0..7f1eefa 100644
--- a/Src/StackifyLib/Models/AzureConfig.cs
+++ b/Src/StackifyLib/Models/AzureConfig.cs
@@ -1,10 +1,8 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using System.Text.RegularExpressions;
+// Copyright (c) 2024-2025 BMC Software, Inc.
+// Copyright (c) 2021-2024 Netreo
+// Copyright (c) 2019 Stackify
+using System;
using StackifyLib.Utils;
-using System.Linq;
#if NETFULL
using Microsoft.Win32;
#endif
@@ -13,22 +11,26 @@ namespace StackifyLib.Models
{
public class AzureConfig
{
- private static bool? _inAzure;
- private static AzureRoleType _azureRoleType = AzureRoleType.Unknown;
- private static string _azureRoleName;
- private static string _azureInstanceName;
- private static string _entryPoint;
+ private static AzureConfig _instance = new AzureConfig();
+ public static AzureConfig Instance => _instance;
- private static readonly DateTime AppStarted = DateTime.UtcNow;
+ private bool? _inAzure;
+ private AzureRoleType _azureRoleType = AzureRoleType.Unknown;
+ private string _azureRoleName;
+ private string _azureInstanceName;
+ private string _entryPoint;
- private static readonly object Locker = new object();
+ private readonly DateTime AppStarted = DateTime.UtcNow;
+ private readonly object Locker = new object();
+ public const string ProductionEnvName = "Production";
- public static string AzureAppWebConfigEnvironment { get; set; }
- public static string AzureAppWebConfigApiKey { get; set; }
- public static string AzureDriveLetter { get; set; }
- public static string AzureInstanceName
+ public string AzureAppWebConfigEnvironment { get; set; }
+ public string AzureAppWebConfigApiKey { get; set; }
+ public string AzureDriveLetter { get; set; }
+
+ public string AzureInstanceName
{
get
{
@@ -37,7 +39,7 @@ public static string AzureInstanceName
}
}
- public static bool InAzure
+ public bool InAzure
{
get
{
@@ -62,7 +64,7 @@ public static bool InAzure
}
}
- public static bool IsWebsite
+ public bool IsWebsite
{
get
{
@@ -75,12 +77,24 @@ public static bool IsWebsite
}
}
- private static void EnsureInAzureRan()
+ private EnvironmentDetail _environmentDetail = null;
+
+ public AzureConfig()
+ {
+
+ }
+
+ public AzureConfig(EnvironmentDetail environmentDetail)
+ {
+ _environmentDetail = environmentDetail;
+ }
+
+ private void EnsureInAzureRan()
{
bool ensureTestHasBeenDone = InAzure;
}
- public static void LoadAzureSettings()
+ public void LoadAzureSettings()
{
if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME")) == false && string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WEBSITE_INSTANCE_ID")) == false)
{
@@ -90,13 +104,13 @@ public static void LoadAzureSettings()
var slotId = GetDeploymentSlotId() ?? "0000";
_azureRoleName = Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME");
- _azureInstanceName = $"{Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME")} {ServerConfigHelper.GetEnvironment()} [{slotId}-{Environment.GetEnvironmentVariable("WEBSITE_INSTANCE_ID").Left(6)}]";
+ _azureInstanceName = $"{Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME")} {GetEnvironment()} [{slotId}-{Environment.GetEnvironmentVariable("WEBSITE_INSTANCE_ID").Left(6)}]";
return;
}
}
- public static string GetDeploymentSlotId()
+ public string GetDeploymentSlotId()
{
try
{
@@ -113,6 +127,32 @@ public static string GetDeploymentSlotId()
return null;
}
+
+ public string GetEnvironment()
+ {
+ if (IsWebsite)
+ {
+ if (_environmentDetail == null)
+ {
+ _environmentDetail = EnvironmentDetail.Get();
+ }
+
+ var key = Environment.GetEnvironmentVariable("Stackify.Environment");
+ if (string.IsNullOrEmpty(key))
+ {
+ key = _environmentDetail.ConfiguredEnvironmentName;
+ }
+
+ if (string.IsNullOrEmpty(key) == false)
+ {
+ return key;
+ }
+
+ return ProductionEnvName;
+ }
+
+ return string.Empty;
+ }
}
public enum AzureRoleType : short
diff --git a/Src/StackifyLib/Models/EnvironmentDetail.cs b/Src/StackifyLib/Models/EnvironmentDetail.cs
index 9ed9954..9fbbd04 100644
--- a/Src/StackifyLib/Models/EnvironmentDetail.cs
+++ b/Src/StackifyLib/Models/EnvironmentDetail.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2024 BMC Software, Inc.
+// Copyright (c) 2024-2025 BMC Software, Inc.
// Copyright (c) 2021-2024 Netreo
// Copyright (c) 2019 Stackify
@@ -41,9 +41,9 @@ private void GetAzureInfo()
{
//IsAzureWorkerRole is set when instantiating EnvironmentDetail
//Useful in other parts directly referencing AzureInstanceName
- if(!IsAzureWorkerRole && AzureConfig.InAzure && AzureConfig.IsWebsite)
+ if(!IsAzureWorkerRole && AzureConfig.Instance.InAzure && AzureConfig.Instance.IsWebsite)
{
- AzureInstanceName = AzureConfig.AzureInstanceName;
+ AzureInstanceName = AzureConfig.Instance.AzureInstanceName;
}
diff --git a/Src/StackifyLib/StackifyLib.csproj b/Src/StackifyLib/StackifyLib.csproj
index 36c165e..10eb0d0 100644
--- a/Src/StackifyLib/StackifyLib.csproj
+++ b/Src/StackifyLib/StackifyLib.csproj
@@ -2,8 +2,8 @@
Stackify API
- 2.2.16
-
+ 2.2.17
+ beta1
netstandard2.0;net40;net45;net451;net452;net46;net461;net462
StackifyLib
StackifyLib
@@ -14,15 +14,15 @@
false
false
false
- 2.2.16
+ 2.2.17-beta1
StackifyLib
https://github.com/stackify/stackify-api-dotnet
https://github.com/stackify/stackify-api-dotnet/blob/master/LICENSE
https://github.com/stackify/stackify-api-dotnet
git
https://stackify.com/wp-content/uploads/2017/02/stk.png
- 2.2.16.0
- 2.2.16.0
+ 2.2.17.0
+ 2.2.17.0
Remove default internal file logger
false
diff --git a/Src/StackifyLib/Utils/HttpClient.cs b/Src/StackifyLib/Utils/HttpClient.cs
index c8619d2..937fdae 100644
--- a/Src/StackifyLib/Utils/HttpClient.cs
+++ b/Src/StackifyLib/Utils/HttpClient.cs
@@ -1,4 +1,7 @@
-using System;
+// Copyright (c) 2024-2025 BMC Software, Inc.
+// Copyright (c) 2021-2024 Netreo
+// Copyright (c) 2019 Stackify
+using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
@@ -313,9 +316,9 @@ public bool IdentifyApp()
}
//Applicable only for Azure AppService
- if(AzureConfig.InAzure && AzureConfig.IsWebsite)
+ if(AzureConfig.Instance.InAzure && AzureConfig.Instance.IsWebsite)
{
- env.DeviceName = AzureConfig.AzureInstanceName;
+ env.DeviceName = AzureConfig.Instance.AzureInstanceName;
}
string jsonData = JsonConvert.SerializeObject(env, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });
diff --git a/Src/StackifyLib/Utils/ServerConfigHelper.cs b/Src/StackifyLib/Utils/ServerConfigHelper.cs
deleted file mode 100644
index 67834c6..0000000
--- a/Src/StackifyLib/Utils/ServerConfigHelper.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using StackifyLib.Models;
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace StackifyLib.Utils
-{
- public class ServerConfigHelper
- {
- public const string ProductionEnvName = "Production";
-
- public static string GetEnvironment()
- {
- if (AzureConfig.IsWebsite)
- {
- var key = Environment.GetEnvironmentVariable("Stackify.Environment");
-
- if (string.IsNullOrEmpty(key) == false)
- {
- return key;
- }
-
- if (string.IsNullOrEmpty(AzureConfig.AzureAppWebConfigEnvironment) == false)
- {
- return AzureConfig.AzureAppWebConfigEnvironment;
- }
-
- return ProductionEnvName;
- }
-
- return string.Empty;
- }
- }
-}
diff --git a/test/StackifyLib.UnitTests/Models/AzureConfig_Tests.cs b/test/StackifyLib.UnitTests/Models/AzureConfig_Tests.cs
new file mode 100644
index 0000000..7ef334e
--- /dev/null
+++ b/test/StackifyLib.UnitTests/Models/AzureConfig_Tests.cs
@@ -0,0 +1,319 @@
+// Copyright (c) 2024-2025 BMC Software, Inc.
+using StackifyLib.Models;
+using System;
+using System.Collections.Generic;
+using Xunit;
+using Moq;
+#if NETCORE || NETCOREX
+using Microsoft.Extensions.Configuration;
+#endif
+
+namespace StackifyLib.UnitTests.Models
+{
+ public class AzureConfig_Tests
+ {
+ private readonly MockRepository _mockRepository;
+ private readonly Dictionary _originalEnvironment = new Dictionary();
+
+ public AzureConfig_Tests()
+ {
+ _mockRepository = new MockRepository(MockBehavior.Strict);
+ BackupEnvironmentVariables();
+ }
+
+ public void Dispose()
+ {
+ RestoreEnvironmentVariables();
+ }
+
+ private void BackupEnvironmentVariables()
+ {
+ _originalEnvironment["WEBSITE_SITE_NAME"] = Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME");
+ _originalEnvironment["WEBSITE_INSTANCE_ID"] = Environment.GetEnvironmentVariable("WEBSITE_INSTANCE_ID");
+ _originalEnvironment["WEBSITE_IIS_SITE_NAME"] = Environment.GetEnvironmentVariable("WEBSITE_IIS_SITE_NAME");
+ _originalEnvironment["Stackify.Environment"] = Environment.GetEnvironmentVariable("Stackify.Environment");
+ }
+
+ private void RestoreEnvironmentVariables()
+ {
+ foreach (var kvp in _originalEnvironment)
+ {
+ Environment.SetEnvironmentVariable(kvp.Key, kvp.Value);
+ }
+ }
+
+ private void ResetAzureConfig()
+ {
+ var instanceField = typeof(AzureConfig).GetField("_instance", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
+ instanceField.SetValue(null, new AzureConfig());
+#if NETCORE || NETCOREX
+ Config.SetConfiguration(null);
+#endif
+ }
+
+ private void SetEnvironmentVariables(string siteName, string instanceId, string iisSiteName = null)
+ {
+ Environment.SetEnvironmentVariable("WEBSITE_SITE_NAME", siteName);
+ Environment.SetEnvironmentVariable("WEBSITE_INSTANCE_ID", instanceId);
+ Environment.SetEnvironmentVariable("WEBSITE_IIS_SITE_NAME", iisSiteName);
+ }
+
+ [Fact]
+ public void InAzure_ReturnsTrue_WhenAzureEnvironmentDetected()
+ {
+ SetEnvironmentVariables("my-site", "instance-id");
+ ResetAzureConfig();
+
+ var result = new AzureConfig(new EnvironmentDetail()).InAzure;
+ Assert.True(result);
+ }
+
+ [Fact]
+ public void InAzure_ReturnsFalse_WhenNotInAzure()
+ {
+ SetEnvironmentVariables(null, null);
+ ResetAzureConfig();
+
+ var result = new AzureConfig(new EnvironmentDetail()).InAzure;
+ Assert.False(result);
+ }
+
+ [Fact]
+ public void IsWebsite_ReturnsTrue_WhenWebAppDetected()
+ {
+ SetEnvironmentVariables("my-site", "instance-id");
+ ResetAzureConfig();
+
+ var result = new AzureConfig(new EnvironmentDetail()).IsWebsite;
+ Assert.True(result);
+ }
+
+ [Fact]
+ public void AzureInstanceName_CorrectFormat_WhenInWebApp()
+ {
+ SetEnvironmentVariables("my-site", "full-instance-id-12345", "site__1234");
+ ResetAzureConfig();
+
+ var instanceName = new AzureConfig(new EnvironmentDetail()).AzureInstanceName;
+ Assert.Equal("my-site Production [1234-full-i]", instanceName);
+ }
+
+ [Fact]
+ public void GetDeploymentSlotId_ReturnsLast4Chars_WhenSlotPresent()
+ {
+ SetEnvironmentVariables(null, null, "site-name__abcd");
+ ResetAzureConfig();
+
+ var slotId = new AzureConfig(new EnvironmentDetail()).GetDeploymentSlotId();
+ Assert.Equal("abcd", slotId);
+ }
+
+ [Fact]
+ public void GetDeploymentSlotId_ReturnsNull_WhenNoSlotPresent()
+ {
+ SetEnvironmentVariables(null, null, "site-name");
+ ResetAzureConfig();
+
+ var slotId = new AzureConfig(new EnvironmentDetail()).GetDeploymentSlotId();
+ Assert.Null(slotId);
+ }
+
+ [Fact(Skip = "Environment set is dynamic. Skip and run manually")]
+ public void GetEnvironment_ReturnsConfiguredEnvironment_WhenSet()
+ {
+ SetEnvironmentVariables("site", "instance");
+ Environment.SetEnvironmentVariable("Stackify.Environment", "Staging");
+ ResetAzureConfig();
+
+ var env = new AzureConfig(new EnvironmentDetail()).GetEnvironment();
+ Assert.Equal("Staging", env);
+ }
+
+ [Fact(Skip = "Environment set is dynamic. Skip and run manually")]
+ public void AzureInstanceName_CorrectFormat_WhenEnvStagingTestSet()
+ {
+ Environment.SetEnvironmentVariable("Stackify.Environment", "StagingTest");
+ SetEnvironmentVariables("my-site", "full-instance-id-12345", "site__1234");
+ ResetAzureConfig();
+
+ var instanceName = new AzureConfig(new EnvironmentDetail()).AzureInstanceName;
+ Assert.Equal("my-site StagingTest [1234-full-i]", instanceName);
+ }
+
+ [Fact]
+ public void GetEnvironment_ReturnsProduction_WhenNoConfigurationSet()
+ {
+ SetEnvironmentVariables("site", "instance");
+ ResetAzureConfig();
+ Config.LoadSettings();
+
+ var env = new AzureConfig(new EnvironmentDetail()).GetEnvironment();
+ Assert.Equal("Production", env);
+ }
+
+ [Fact]
+ public void GetEnvironment_ReturnsEmptyString_WhenNotWebsite()
+ {
+ SetEnvironmentVariables(null, null); // Not in Azure
+ ResetAzureConfig();
+
+ var env = new AzureConfig().GetEnvironment();
+ Assert.Equal(string.Empty, env);
+ }
+
+#if NETFULL
+ [Fact(Skip = "Environment set is dynamic. Skip and run manually")]
+ public void GetEnvironment_ReturnsTest_WhenAppSettingsSet()
+ {
+ Environment.SetEnvironmentVariable("Stackify.Environment", "");
+ System.Configuration.ConfigurationManager.AppSettings["Stackify.Environment"] = "Test";
+ SetEnvironmentVariables("site", "instance");
+ ResetAzureConfig();
+
+ var env = new AzureConfig(new EnvironmentDetail()).GetEnvironment();
+ Assert.Equal("Test", env);
+ }
+
+ [Fact(Skip = "Environment set is dynamic. Skip and run manually")]
+ public void GetEnvironment_ReturnsTest_WhenEnvSetFirst_AppSettingsSet()
+ {
+ Environment.SetEnvironmentVariable("Stackify.Environment", "StagingFirstApp");
+ System.Configuration.ConfigurationManager.AppSettings["Stackify.Environment"] = "Test";
+ SetEnvironmentVariables("site", "instance");
+ ResetAzureConfig();
+
+ var env = new AzureConfig(new EnvironmentDetail()).GetEnvironment();
+ Assert.Equal("StagingFirstApp", env);
+ }
+
+ [Fact(Skip = "Environment set is dynamic. Skip and run manually")]
+ public void AzureInstanceName_CorrectFormat_WhenAppSettingsEnvStagingAppSet()
+ {
+ Environment.SetEnvironmentVariable("Stackify.Environment", "");
+ System.Configuration.ConfigurationManager.AppSettings["Stackify.Environment"] = "StagingApp";
+ SetEnvironmentVariables("my-site", "full-instance-id-12345", "site__1234");
+ ResetAzureConfig();
+
+ var instanceName = new AzureConfig(new EnvironmentDetail()).AzureInstanceName;
+ Assert.Equal("my-site StagingApp [1234-full-i]", instanceName);
+ }
+
+ [Fact(Skip = "Environment set is dynamic. Skip and run manually")]
+ public void AzureInstanceName_CorrectFormat_WhenEnvSetFirst_AppSettings()
+ {
+ Environment.SetEnvironmentVariable("Stackify.Environment", "StagingFirst");
+ System.Configuration.ConfigurationManager.AppSettings["Stackify.Environment"] = "StagingApp";
+ SetEnvironmentVariables("my-site", "full-instance-id-12345", "site__1234");
+ ResetAzureConfig();
+
+ var instanceName = new AzureConfig(new EnvironmentDetail()).AzureInstanceName;
+ Assert.Equal("my-site StagingFirst [1234-full-i]", instanceName);
+ }
+#endif
+
+#if NETCORE || NETCOREX
+ [Fact(Skip = "Environment set is dynamic. Skip and run manually")]
+ public void GetEnvironment_ReturnsTestCore_WhenIConfigurationSet()
+ {
+ Environment.SetEnvironmentVariable("Stackify.Environment", "");
+ SetEnvironmentVariables("site", "instance");
+ ResetAzureConfig();
+
+ var iconfig = new ConfigurationBuilder()
+ .AddInMemoryCollection(new Dictionary
+ {
+ ["Stackify:Environment"] = "TestCore"
+ })
+ .Build();
+ Config.SetConfiguration(iconfig);
+ Config.LoadSettings();
+
+ var env = new AzureConfig(new EnvironmentDetail()).GetEnvironment();
+ Assert.Equal("TestCore", env);
+ }
+
+ [Fact(Skip = "Environment set is dynamic. Skip and run manually")]
+ public void GetEnvironment_ReturnsTestCore_WhenEnvFirst_IConfigurationSet()
+ {
+ Environment.SetEnvironmentVariable("Stackify.Environment", "TestCoreFirst");
+ SetEnvironmentVariables("site", "instance");
+ ResetAzureConfig();
+
+ var iconfig = new ConfigurationBuilder()
+ .AddInMemoryCollection(new Dictionary
+ {
+ ["Stackify:Environment"] = "TestCore"
+ })
+ .Build();
+ Config.SetConfiguration(iconfig);
+ Config.LoadSettings();
+
+ var env = new AzureConfig(new EnvironmentDetail()).GetEnvironment();
+ Assert.Equal("TestCoreFirst", env);
+ }
+
+ [Fact(Skip = "Environment set is dynamic. Skip and run manually")]
+ public void AzureInstanceName_CorrectFormat_WhenEnvSetFirst_IConfigurationEnvStagingConfigSet()
+ {
+ Environment.SetEnvironmentVariable("Stackify.Environment", "StagingConfigFirst");
+ SetEnvironmentVariables("my-site", "full-instance-id-12345", "site__1234");
+ ResetAzureConfig();
+
+ var iconfig = new ConfigurationBuilder()
+ .AddInMemoryCollection(new Dictionary
+ {
+ ["Stackify:Environment"] = "StagingConfig"
+ })
+ .Build();
+ Config.SetConfiguration(iconfig);
+ Config.LoadSettings();
+
+ var instanceName = new AzureConfig(new EnvironmentDetail()).AzureInstanceName;
+ Assert.Equal("my-site StagingConfigFirst [1234-full-i]", instanceName);
+ }
+
+ [Fact(Skip = "Environment set is dynamic. Skip and run manually")]
+ public void AzureInstanceName_CorrectFormat_WhenIConfigurationEnvStagingConfigSet()
+ {
+ Environment.SetEnvironmentVariable("Stackify.Environment", "");
+ SetEnvironmentVariables("my-site", "full-instance-id-12345", "site__1234");
+ ResetAzureConfig();
+
+ var iconfig = new ConfigurationBuilder()
+ .AddInMemoryCollection(new Dictionary
+ {
+ ["Stackify:Environment"] = "StagingConfig"
+ })
+ .Build();
+ Config.SetConfiguration(iconfig);
+ Config.LoadSettings();
+
+ var instanceName = new AzureConfig(new EnvironmentDetail()).AzureInstanceName;
+ Assert.Equal("my-site StagingConfig [1234-full-i]", instanceName);
+ }
+#endif
+
+ [Fact]
+ public void AzureRoleType_SetToWebApp_WhenWebsiteDetected()
+ {
+ // Arrange
+ SetEnvironmentVariables("site", "instance");
+ ResetAzureConfig();
+
+ // Act
+ bool _ = AzureConfig.Instance.InAzure; // Force initialization
+ var roleType = GetPrivateField("_azureRoleType");
+
+ // Assert
+ Assert.Equal(AzureRoleType.WebApp, roleType);
+ }
+
+ // Helper to access private fields
+ private T GetPrivateField(string fieldName)
+ {
+ var field = typeof(AzureConfig).GetField(fieldName,
+ System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
+ return (T)field.GetValue(AzureConfig.Instance);
+ }
+ }
+}