diff --git a/MetasysServices.Tests/MetasysClientTests.cs b/MetasysServices.Tests/MetasysClientTests.cs index 66ccf50..01098dd 100644 --- a/MetasysServices.Tests/MetasysClientTests.cs +++ b/MetasysServices.Tests/MetasysClientTests.cs @@ -1,6 +1,7 @@ using Flurl.Http; using JohnsonControls.Metasys.BasicServices; using JohnsonControls.Metasys.BasicServices.Enums; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Nito.AsyncEx; using NUnit.Framework; @@ -1679,6 +1680,62 @@ public void TestGetNetworkDeviceTypesUnauthorizedThrowsException() #region GetObjects Tests + readonly string RootObjects = JsonConvert.SerializeObject(new + { + self = "https://welch12.go.johnsoncontrols.com/api/v6/objects/0352a3d7-baa2-5eae-b4ab-f20d485045d2/objects?flatten=true&includeExtensions=true&includeInternal=false&depth=1&includeModificationConstraints=false", + items = (List)[ + new + { + name = "Site", + label = "Site", + id = "0352a3d7-baa2-5eae-b4ab-f20d485045d2", + itemReference = "welch12:welch12/$site", + parentUrl = (string) null, + items = new[] { + new + { + name = "User Views", + label = "UserTrees", + id = "f0900868-3b53-57b1-987b-f12dd92d7a2d", + itemReference = "welch12:welch12/$site.UserTrees", + parentUrl = "/objects/0352a3d7-baa2-5eae-b4ab-f20d485045d2" + } + } + } + + ] + + }); + + + [Test] + public void TestGetObjectsRoot() + { + httpTest.RespondWith(RootObjects); + + var originalApiVersion = client.Version; + client.Version = ApiVersion.v4; + + try + { + var rootObject = client.GetObjects(); + + httpTest.ShouldHaveCalled("https://hostname/api/v4/objects") + .WithoutQueryParamValue("flatten", true) + .WithoutQueryParamValue("includeExtensions", false) + .WithVerb(HttpMethod.Get) + .Times(1); + + Assert.That(rootObject.ItemReference, Is.EqualTo("welch12:welch12/$site")); + Assert.That(rootObject.ChildrenCount, Is.EqualTo(1)); + } + finally + { + client.Version = originalApiVersion; + } + } + + [Test] public void TestGetObjectsNone() { diff --git a/MetasysServices.Tests/MetasysServices.Tests.csproj b/MetasysServices.Tests/MetasysServices.Tests.csproj index bf25914..27b9dcd 100644 --- a/MetasysServices.Tests/MetasysServices.Tests.csproj +++ b/MetasysServices.Tests/MetasysServices.Tests.csproj @@ -2,7 +2,7 @@ net6.0 - + 12 false 6.0.4 @@ -28,4 +28,4 @@ - \ No newline at end of file + diff --git a/MetasysServices/BasicServiceProvider.cs b/MetasysServices/BasicServiceProvider.cs index cd0eb79..e93d9ce 100644 --- a/MetasysServices/BasicServiceProvider.cs +++ b/MetasysServices/BasicServiceProvider.cs @@ -174,12 +174,12 @@ protected List ToNetworkDevice(List items, ApiVersion ver /// /// /// - /// If is less than + /// If is less than /// /// If is specified then this method returns the children of the specified object (and any of their children if level > 1). /// If id is null then this method returns the root object (and it's children; unless level is 0). /// - protected async Task> GetObjectsAsync(Guid? id, Dictionary parameters = null) + protected async Task> GetObjectsAsync(Guid? id, Dictionary parameters = null) { if (Version <= ApiVersion.v3) { @@ -197,7 +197,7 @@ protected async Task> GetObjectsAsync(Guid? id, Dictionary> GetObjectsAsync(Guid? id, Dictionary /// + /// This should only be called when version is 3 or less. Starting with v4 we support depth directly. + /// /// A level of 1 only retrieves immediate children of the parent object. + /// /// This should not be called on a site that supports REST API 4 or later as it makes a series of recursive calls that can /// be handled in one call to the api /// diff --git a/MetasysServices/Interfaces/IMetasysClient.cs b/MetasysServices/Interfaces/IMetasysClient.cs index 5253652..7749735 100644 --- a/MetasysServices/Interfaces/IMetasysClient.cs +++ b/MetasysServices/Interfaces/IMetasysClient.cs @@ -297,6 +297,27 @@ public interface IMetasysClient : IBasicService /// Task> GetNetworkDeviceTypesAsync(); + /// + /// Gets the root object and its direct children + /// + /// + /// This method only works if the site supports Version 4 of the Metasys REST API or later. + /// + /// Set it to true to get also the extensions of the object. + /// Set it to true to get the internal objects + /// + /// The number of levels to retrieve. This can only be 0 or 1. It defaults to 1. + /// + /// A value of 0 returns the root object only. + /// + /// A value of 1 returns the root and its children. + /// + /// The root object. If is set to 1 the + /// property of the root object will contain the children. + MetasysObject GetObjects(bool includeExtensions = false, bool includeInternal = false, int levels = 1); + /// + Task GetObjectsAsync(bool includeExtensions = false, bool includeInternal = false, int levels = 1); + /// /// Gets all child objects given a parent id. diff --git a/MetasysServices/MetasysClient.cs b/MetasysServices/MetasysClient.cs index 69d2f74..85f9cbb 100644 --- a/MetasysServices/MetasysClient.cs +++ b/MetasysServices/MetasysClient.cs @@ -1,5 +1,6 @@ using Flurl; using Flurl.Http; +using Flurl.Util; using JohnsonControls.Metasys.BasicServices.Utils; using Newtonsoft.Json.Linq; using System; @@ -124,7 +125,8 @@ public int Timeout if (Spaces != null) { Spaces.Version = version.Value; } if (Streams != null) { Streams.Version = version.Value; } if (Trends != null) { Trends.Version = version.Value; } - base.Version = value; + // override the base version as well + base.Version = version.Value; } } @@ -491,6 +493,26 @@ public async Task> GetNetworkDeviceTypesAsync() #region "OBJECTS" // ======================================================================================================== // GetObjects --------------------------------------------------------------------------------------------------------------- + + /// + public MetasysObject GetObjects(bool includeExtensions = false, bool includeInternal = false, int levels = 1) + { + return GetObjectsAsync(includeExtensions, includeInternal, levels).GetAwaiter().GetResult(); + } + /// + public async Task GetObjectsAsync(bool includeExtensions = false, bool includeInternal = false, int levels = 1) + { + if (levels > 1 || levels < 0) throw new ArgumentOutOfRangeException(nameof(levels), "The only supported values are 0 and 1."); + Dictionary parameters = new Dictionary + { + ["includeExtensions"] = includeExtensions.ToInvariantString().ToLower(), + ["includeInternal"] = includeInternal.ToInvariantString().ToLower(), + ["depth"] = levels.ToInvariantString() + }; + return (await base.GetObjectsAsync(null, parameters)).First(); + } + + /// public IEnumerable GetObjects(ObjectId id, int levels = 1, bool includeInternalObjects = false, bool includeExtensions = false) {