From c2d53a32153b5557c680b7b62f6cbf40871feee5 Mon Sep 17 00:00:00 2001 From: Barbara Valdez <34872381+barbaravaldez@users.noreply.github.com> Date: Wed, 28 Jun 2023 16:39:37 -0700 Subject: [PATCH] Get server general properties (#2117) * add server handler * get server general properties --- .../ObjectManagementService.cs | 1 + .../ObjectTypes/Database/DatabaseHandler.cs | 6 +- .../ObjectTypes/Server/ServerHandler.cs | 95 +++++++++++++++++++ .../ObjectTypes/Server/ServerInfo.cs | 34 +++++++ .../ObjectTypes/Server/ServerViewContext.cs | 22 +++++ .../ObjectTypes/Server/ServerViewInfo.cs | 13 +++ .../ObjectManagement/SqlObjectType.cs | 4 +- .../ServerConfigService.cs | 8 +- .../Utility/ByteConverter.cs | 32 +++++++ .../Utility/DatabaseUtils.cs | 10 -- .../ObjectManagement/ServerHandlerTests.cs | 51 ++++++++++ 11 files changed, 259 insertions(+), 17 deletions(-) create mode 100644 src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Server/ServerHandler.cs create mode 100644 src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Server/ServerInfo.cs create mode 100644 src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Server/ServerViewContext.cs create mode 100644 src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Server/ServerViewInfo.cs create mode 100644 src/Microsoft.SqlTools.ServiceLayer/Utility/ByteConverter.cs create mode 100644 test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectManagement/ServerHandlerTests.cs diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectManagementService.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectManagementService.cs index 979b9457..08ad2ea1 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectManagementService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectManagementService.cs @@ -40,6 +40,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement this.objectTypeHandlers.Add(new DatabaseRoleHandler(ConnectionService.Instance)); this.objectTypeHandlers.Add(new ServerRoleHandler(ConnectionService.Instance)); this.objectTypeHandlers.Add(new DatabaseHandler(ConnectionService.Instance)); + this.objectTypeHandlers.Add(new ServerHandler(ConnectionService.Instance)); } /// diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Database/DatabaseHandler.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Database/DatabaseHandler.cs index ffd27eb4..d6589ca2 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Database/DatabaseHandler.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Database/DatabaseHandler.cs @@ -135,12 +135,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement DateCreated = smoDatabase.CreateDate.ToString(), LastDatabaseBackup = smoDatabase.LastBackupDate == DateTime.MinValue ? SR.databaseBackupDate_None : smoDatabase.LastBackupDate.ToString(), LastDatabaseLogBackup = smoDatabase.LastLogBackupDate == DateTime.MinValue ? SR.databaseBackupDate_None : smoDatabase.LastLogBackupDate.ToString(), - MemoryAllocatedToMemoryOptimizedObjectsInMb = DatabaseUtils.ConvertKbtoMb(smoDatabase.MemoryAllocatedToMemoryOptimizedObjectsInKB), - MemoryUsedByMemoryOptimizedObjectsInMb = DatabaseUtils.ConvertKbtoMb(smoDatabase.MemoryUsedByMemoryOptimizedObjectsInKB), + MemoryAllocatedToMemoryOptimizedObjectsInMb = ByteConverter.ConvertKbtoMb(smoDatabase.MemoryAllocatedToMemoryOptimizedObjectsInKB), + MemoryUsedByMemoryOptimizedObjectsInMb = ByteConverter.ConvertKbtoMb(smoDatabase.MemoryUsedByMemoryOptimizedObjectsInKB), NumberOfUsers = smoDatabase.Users.Count, Owner = smoDatabase.Owner, SizeInMb = smoDatabase.Size, - SpaceAvailableInMb = DatabaseUtils.ConvertKbtoMb(smoDatabase.SpaceAvailable), + SpaceAvailableInMb = ByteConverter.ConvertKbtoMb(smoDatabase.SpaceAvailable), Status = smoDatabase.Status.ToString() }; } diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Server/ServerHandler.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Server/ServerHandler.cs new file mode 100644 index 00000000..f3df457f --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Server/ServerHandler.cs @@ -0,0 +1,95 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System; +using System.Threading.Tasks; +using Microsoft.SqlServer.Management.Common; +using Microsoft.SqlServer.Management.Smo; +using Microsoft.SqlTools.ServiceLayer.Connection; +using Microsoft.SqlTools.ServiceLayer.ObjectManagement.Contracts; +using Microsoft.SqlTools.ServiceLayer.ObjectManagement.ObjectTypes.Server; +using Microsoft.SqlTools.ServiceLayer.ServerConfigurations; +using Microsoft.SqlTools.ServiceLayer.Utility; + +namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement +{ + /// + /// Server object type handler + /// + public class ServerHandler : ObjectTypeHandler + { + private ServerViewInfo serverViewInfo = new ServerViewInfo(); + private ServerConfigService configService = new ServerConfigService(); + private Server server = null; + + public ServerHandler(ConnectionService connectionService) : base(connectionService) + { + } + + public override bool CanHandleType(SqlObjectType objectType) + { + return objectType == SqlObjectType.Server; + } + + public override Task InitializeObjectView(InitializeViewRequestParams requestParams) + { + ConnectionInfo connInfo = this.GetConnectionInfo(requestParams.ConnectionUri); + ServerConnection serverConnection = ConnectionService.OpenServerConnection(connInfo, ObjectManagementService.ApplicationName); + + using (var context = new ServerViewContext(requestParams, serverConnection)) + { + this.server = new Server(context.Connection); + if (this.server != null) + { + this.serverViewInfo.ObjectInfo = new ServerInfo() + { + Name = server.Name, + HardwareGeneration = server.HardwareGeneration, + Language = server.Language, + MemoryInMB = server.PhysicalMemory, + OperatingSystem = server.HostDistribution, + Platform = server.HostPlatform, + Processors = server.Processors, + IsClustered = server.IsClustered, + IsHadrEnabled = server.IsHadrEnabled, + IsPolyBaseInstalled = server.IsPolyBaseInstalled, + IsXTPSupported = server.IsXTPSupported, + Product = server.Product, + ReservedStorageSizeMB = server.ReservedStorageSizeMB, + RootDirectory = server.RootDirectory, + ServerCollation = server.Collation, + ServiceTier = server.ServiceTier, + StorageSpaceUsageInGB = (int)ByteConverter.ConvertMbtoGb(server.UsedStorageSizeMB), + Version = server.Version.ToString(), + MinServerMemory = GetServerMinMemory(), + MaxServerMemory = GetServerMaxMemory() + }; + } + + return Task.FromResult(new InitializeViewResult { ViewInfo = this.serverViewInfo, Context = context }); + } + } + + public override Task Save(ServerViewContext context, ServerInfo serverInfo) + { + throw new NotSupportedException("ServerHandler does not support Save method"); + } + + public override Task Script(ServerViewContext context, ServerInfo obj) + { + throw new NotSupportedException("ServerHandler does not support Script method"); + } + + private int GetServerMaxMemory() + { + return configService.GetServerSmoConfig(server, configService.MaxServerMemoryPropertyNumber).ConfigValue; + } + + private int GetServerMinMemory() + { + return configService.GetServerSmoConfig(server, configService.MinServerMemoryPropertyNumber).ConfigValue; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Server/ServerInfo.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Server/ServerInfo.cs new file mode 100644 index 00000000..ecd2d432 --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Server/ServerInfo.cs @@ -0,0 +1,34 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// +#nullable disable + +namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement +{ + /// + /// A class for storing various properties needed for Saving & Scripting a server + /// + public class ServerInfo : SqlObject + { + public string? HardwareGeneration { get; set; } + public string Language { get; set; } + public int MemoryInMB { get; set; } + public string OperatingSystem { get; set; } + public string Platform { get; set; } + public int Processors { get; set; } + public bool IsClustered { get; set; } + public bool IsHadrEnabled { get; set; } + public bool IsPolyBaseInstalled { get; set; } + public bool? IsXTPSupported { get; set; } + public string Product { get; set; } + public int? ReservedStorageSizeMB { get; set; } + public string RootDirectory { get; set; } + public string ServerCollation { get; set; } + public string? ServiceTier { get; set; } + public int? StorageSpaceUsageInGB { get; set; } + public string Version { get; set; } + public int MaxServerMemory { get; set; } + public int MinServerMemory { get; set; } + } +} \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Server/ServerViewContext.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Server/ServerViewContext.cs new file mode 100644 index 00000000..c4205f2d --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Server/ServerViewContext.cs @@ -0,0 +1,22 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using Microsoft.SqlServer.Management.Common; + +namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement +{ + public class ServerViewContext : SqlObjectViewContext + { + public ServerConnection Connection { get; } + public ServerViewContext(Contracts.InitializeViewRequestParams parameters, ServerConnection connection) : base(parameters) + { + this.Connection = connection; + } + + public override void Dispose() + { + } + } +} \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Server/ServerViewInfo.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Server/ServerViewInfo.cs new file mode 100644 index 00000000..0b2f23a1 --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectTypes/Server/ServerViewInfo.cs @@ -0,0 +1,13 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + + +namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement.ObjectTypes.Server +{ + public class ServerViewInfo : SqlObjectViewInfo + { + public ServerViewInfo() { } + } +} diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/SqlObjectType.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/SqlObjectType.cs index 518ea376..c6b11425 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/SqlObjectType.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/SqlObjectType.cs @@ -31,6 +31,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement [EnumMember(Value = "View")] View, [EnumMember(Value = "Database")] - Database + Database, + [EnumMember(Value = "Server")] + Server } } \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/ServerConfigurations/ServerConfigService.cs b/src/Microsoft.SqlTools.ServiceLayer/ServerConfigurations/ServerConfigService.cs index 7f62f7a9..566fcefa 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ServerConfigurations/ServerConfigService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ServerConfigurations/ServerConfigService.cs @@ -23,6 +23,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ServerConfigurations { private ConnectionService connectionService = null; private static readonly Lazy instance = new Lazy(() => new ServerConfigService()); + public readonly int MaxServerMemoryPropertyNumber = 1544; + public readonly int MinServerMemoryPropertyNumber = 1543; /// /// Gets the singleton instance object @@ -175,7 +177,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ServerConfigurations public void UpdateConfig(ServerConnection serverConnection, int configNumber, int configValue) { Server server = new Server(serverConnection); - ConfigProperty serverConfig = GetSmoConfig(server, configNumber); + ConfigProperty serverConfig = GetServerSmoConfig(server, configNumber); if (serverConfig != null) { @@ -203,7 +205,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ServerConfigurations private ServerConfigProperty GetConfig(ServerConnection serverConnection, int configNumber) { Server server = new Server(serverConnection); - ConfigProperty serverConfig = GetSmoConfig(server, configNumber); + ConfigProperty serverConfig = GetServerSmoConfig(server, configNumber); return serverConfig != null ? ServerConfigProperty.ToServerConfigProperty(serverConfig) : null; } @@ -218,7 +220,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ServerConfigurations return list; } - private ConfigProperty GetSmoConfig(Server server, int configNumber) + public ConfigProperty GetServerSmoConfig(Server server, int configNumber) { try { diff --git a/src/Microsoft.SqlTools.ServiceLayer/Utility/ByteConverter.cs b/src/Microsoft.SqlTools.ServiceLayer/Utility/ByteConverter.cs new file mode 100644 index 00000000..08613087 --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/Utility/ByteConverter.cs @@ -0,0 +1,32 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System; + +namespace Microsoft.SqlTools.ServiceLayer.Utility +{ + public static class ByteConverter + { + /// + /// Converts value in KBs to MBs + /// + /// value in kilo bytes + /// Returns as double type + public static double ConvertKbtoMb(double valueInKb) + { + return (Math.Round(valueInKb / 1024, 2)); + } + + /// + /// Converts value in MBs to GBs + /// + /// value in mega bytes + /// Returns as double type + public static double ConvertMbtoGb(double valueInMb) + { + return (Math.Round(valueInMb / 1024, 2)); + } + } +} diff --git a/src/Microsoft.SqlTools.ServiceLayer/Utility/DatabaseUtils.cs b/src/Microsoft.SqlTools.ServiceLayer/Utility/DatabaseUtils.cs index 12435d5c..f02cd27d 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Utility/DatabaseUtils.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Utility/DatabaseUtils.cs @@ -345,15 +345,5 @@ namespace Microsoft.SqlTools.ServiceLayer.Utility return new string(nameChars); } private static readonly HashSet illegalFilenameCharacters = new HashSet(new char[] { '\\', '/', ':', '*', '?', '"', '<', '>', '|' }); - - /// - /// Converts value in KBs to MBs - /// - /// value in kilo bytes - /// Returns as double type - public static double ConvertKbtoMb(double valueInKb) - { - return (Math.Round(valueInKb / 1024, 2)); - } } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectManagement/ServerHandlerTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectManagement/ServerHandlerTests.cs new file mode 100644 index 00000000..1a856b99 --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/ObjectManagement/ServerHandlerTests.cs @@ -0,0 +1,51 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System.Threading.Tasks; +using Microsoft.Data.SqlClient; +using Microsoft.SqlServer.Management.Common; +using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility; +using Microsoft.SqlTools.ServiceLayer.ObjectManagement; +using Microsoft.SqlTools.ServiceLayer.Connection; +using Microsoft.SqlServer.Management.Smo; + +using NUnit.Framework; +using Microsoft.SqlTools.ServiceLayer.Test.Common; + +namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectManagement +{ + /// + /// Tests for the Login management component + /// + public class ServerHandlerTests + { + /// + /// Test GetServerProperties for Sql Server + /// + [Test] + public async Task GetServerProperties() + { + var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", serverType: TestServerType.OnPrem); + using (SqlConnection sqlConn = ConnectionService.OpenSqlConnection(connectionResult.ConnectionInfo)) + { + var server = new Server(new ServerConnection(sqlConn)); + var serverHandler = new ServerHandler(ConnectionService.Instance); + + var requestParams = ObjectManagementTestUtils.GetInitializeViewRequestParams(connectionResult.ConnectionInfo.OwnerUri, "master", true, SqlObjectType.Server, "", ""); + var result = await serverHandler.InitializeObjectView(requestParams); + Assert.That(result.ViewInfo.ObjectInfo, Is.Not.Null, $"Expected result should not be empty"); + Assert.That(result.ViewInfo.ObjectInfo.Name, Is.EqualTo(server.Name), $"Server name should not be empty"); + Assert.That(((ServerInfo)result.ViewInfo.ObjectInfo).Language, Is.Not.Null, $"Server language should not be null"); + Assert.That(((ServerInfo)result.ViewInfo.ObjectInfo).MemoryInMB, Is.GreaterThan(0), $"Server physical memory should be greater than 0"); + Assert.That(((ServerInfo)result.ViewInfo.ObjectInfo).Platform, Is.Not.Null, $"Server platform should not be null"); + Assert.That(((ServerInfo)result.ViewInfo.ObjectInfo).OperatingSystem, Is.Not.Null, $"Server operating system should not be null"); + Assert.That(((ServerInfo)result.ViewInfo.ObjectInfo).Processors, Is.Not.Null, $"Server processors should not be null"); + Assert.That(((ServerInfo)result.ViewInfo.ObjectInfo).IsClustered, Is.Not.Null, $"Server isClustered property should not be null"); + Assert.That(((ServerInfo)result.ViewInfo.ObjectInfo).IsHadrEnabled, Is.Not.Null, $"Server isHadrEnabled property should not be null"); + Assert.That(((ServerInfo)result.ViewInfo.ObjectInfo).IsPolyBaseInstalled, Is.Not.Null, $"Server isPolyBaseInstalled property should not be null"); + } + } + } +}