Skip to content

Commit

Permalink
feat: add GetObjects for root of the tree
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelgwelch committed Aug 3, 2024
1 parent 2555d90 commit 5e2c4f0
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 5 deletions.
57 changes: 57 additions & 0 deletions MetasysServices.Tests/MetasysClientTests.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -1692,6 +1693,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<object>)[
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()
{
Expand Down
4 changes: 2 additions & 2 deletions MetasysServices.Tests/MetasysServices.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>

<LangVersion>12</LangVersion>
<IsPackable>false</IsPackable>

<Version>6.0.4</Version>
Expand All @@ -28,4 +28,4 @@
<ProjectReference Include="..\MetasysServices\MetasysServices.csproj" />
</ItemGroup>

</Project>
</Project>
14 changes: 12 additions & 2 deletions MetasysServices/BasicServiceProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ protected List<NetworkDevice> ToNetworkDevice(List<JToken> items, ApiVersion ver
/// If <paramref name="id"/> is specified then this method returns the children of the specified object (and any of their children if level > 1).
/// If <c>id</d> is <c>null</c> then this method returns the root object (and it's children; unless level is 0).

Check warning on line 180 in MetasysServices/BasicServiceProvider.cs

View workflow job for this annotation

GitHub Actions / build

XML comment has badly formed XML -- 'End tag 'd' does not match the start tag 'c'.'

Check warning on line 180 in MetasysServices/BasicServiceProvider.cs

View workflow job for this annotation

GitHub Actions / build

XML comment has badly formed XML -- 'End tag 'd' does not match the start tag 'c'.'
/// </returns>
protected async Task<List<MetasysObject>> GetObjectsAsync(Guid? id, Dictionary<string, string> parameters = null)
protected async Task<IEnumerable<MetasysObject>> GetObjectsAsync(Guid? id, Dictionary<string, string> parameters = null)
{
if (Version <= ApiVersion.v3)
{
Expand All @@ -197,7 +197,7 @@ protected async Task<List<MetasysObject>> GetObjectsAsync(Guid? id, Dictionary<s
{
return [rootObject];
}
return rootObject.Children.ToList();
return rootObject.Children;
}


Expand All @@ -206,6 +206,8 @@ protected async Task<List<MetasysObject>> GetObjectsAsync(Guid? id, Dictionary<s
/// Level indicates how deep to retrieve objects.
/// </summary>
/// <remarks>
/// This should only be called when version is 3 or less. Starting with v4 we support depth directly.
/// <para>
/// A level of 1 only retrieves immediate children of the parent object.
/// <para> 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</para>
Expand Down Expand Up @@ -338,6 +340,7 @@ public async Task<IEnumerable<MetasysObjectType>> GetResourceTypesAsync(string r
}

/// <summary>
/// Gets the type from a token retrieved from a typeUrl
/// </summary>
/// <param name="typeToken"></param>
/// <exception cref="MetasysHttpException"></exception>
Expand Down Expand Up @@ -545,6 +548,7 @@ protected async Task<JToken> GetRequestAsync(string resource, Dictionary<string,
JToken response = null;
// Create URL with base resource
Url url = new Url(resource);
// Concatenate segments with base resource url
url.AppendPathSegments(pathSegments);
// Set query parameters according to the input dictionary
if (parameters != null)
Expand All @@ -570,6 +574,7 @@ protected async Task<JToken> GetRequestAsync(string resource, Dictionary<string,
}

/// <summary>
/// Get typed items for the given resource asynchronously.
/// </summary>
/// <remarks>Optionally accepts query string parameters and additional path segments.</remarks>
/// <typeparam name="T"></typeparam>
Expand All @@ -585,6 +590,7 @@ protected async Task<PagedResult<T>> GetPagedResultsAsync<T>(string resource, Di


/// <summary>
/// Gets all items for the given resource asynchronously by requesting each available page.
/// </summary>
/// <param name="resource">The main resource to read.</param>
/// <param name="parameters">Query string parameters in Key Value format.</param>
Expand Down Expand Up @@ -715,6 +721,7 @@ protected async Task<JToken> GetBatchRequestAsync(string endpoint, IEnumerable<G
// Concatenate batch segment to use batch request and prepare the list of requests
url.AppendPathSegments("batch");
var objectsRequests = new List<ObjectRequest>();
// Concatenate batch segment to use batch request and prepare the list of requests
foreach (var id in ids)
{
foreach (var r in resources)
Expand Down Expand Up @@ -756,6 +763,7 @@ protected async Task<JToken> PostBatchRequestAsync(string endpoint, IEnumerable<
// Concatenate batch segment to use batch request and prepare the list of requests
url.AppendPathSegments("batch");
var objectsRequests = new List<ObjectRequest>();
// Concatenate batch segment to use batch request and prepare the list of requests
foreach (var r in requests)
{
Url relativeUrl = new Url(r.ObjectId.ToString());
Expand Down Expand Up @@ -817,6 +825,7 @@ protected async Task<JToken> PutBatchRequestAsync(string endpoint, IEnumerable<B
// Concatenate batch segment to use batch request and prepare the list of requests
url.AppendPathSegments("batch");
var objectsRequests = new List<ObjectRequest>();
// Concatenate batch segment to use batch request and prepare the list of requests
foreach (var r in requests)
{
Url relativeUrl = new Url(r.ObjectId.ToString());
Expand Down Expand Up @@ -889,6 +898,7 @@ protected async Task<JToken> PatchBatchRequestAsync(string endpoint, IEnumerable
// Concatenate batch segment to use batch request and prepare the list of requests
url.AppendPathSegments("batch");
var objectsRequests = new List<ObjectRequest>();
// Concatenate batch segment to use batch request and prepare the list of requests
foreach (var r in requests)
{
string activityManagementStatus = "";
Expand Down
20 changes: 20 additions & 0 deletions MetasysServices/Interfaces/IMetasysClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,26 @@ public interface IMetasysClient : IBasicService
/// <inheritdoc cref="IMetasysClient.GetNetworkDeviceTypes()"/>
Task<IEnumerable<MetasysObjectType>> GetNetworkDeviceTypesAsync();

/// <summary>
/// Gets the root object and its direct children
/// </summary>
/// <remarks>
/// This method only works if the site supports Version 4 of the Metasys REST API or later.
/// </remarks>
/// <param name="includeExtensions">Set it to true to get also the extensions of the object.</param>
/// <param name="includeInternal">Set it to true to get the internal objects</param>
/// <param name="levels">
/// 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.<param>
/// <returns>The root object. If <paramref name="levels"/> is set to 1 the <see cref="MetasysObject.Children"/>
/// property of the root object will contain the children.</returns>
MetasysObject GetObjects(bool includeExtensions = false, bool includeInternal = false, int levels = 1);

Check warning on line 315 in MetasysServices/Interfaces/IMetasysClient.cs

View workflow job for this annotation

GitHub Actions / build

XML comment has badly formed XML -- 'Expected an end tag for element 'param'.'

Check warning on line 315 in MetasysServices/Interfaces/IMetasysClient.cs

View workflow job for this annotation

GitHub Actions / build

XML comment has badly formed XML -- 'Expected an end tag for element 'param'.'
/// <inheritdoc cref="GetObjects(bool, bool, int)"/>
Task<MetasysObject> GetObjectsAsync(bool includeExtensions = false, bool includeInternal = false, int levels = 1);


/// <summary>
/// Gets all child objects given a parent Guid.
Expand Down
23 changes: 22 additions & 1 deletion MetasysServices/MetasysClient.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Flurl;
using Flurl.Http;
using Flurl.Util;
using JohnsonControls.Metasys.BasicServices.Utils;
using Newtonsoft.Json.Linq;
using System;
Expand Down Expand Up @@ -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;
}
}

Expand Down Expand Up @@ -490,6 +492,25 @@ public async Task<IEnumerable<MetasysObjectType>> GetNetworkDeviceTypesAsync()

#region "OBJECTS" // ========================================================================================================
// GetObjects ---------------------------------------------------------------------------------------------------------------

/// <inheritdoc/>
public MetasysObject GetObjects(bool includeExtensions = false, bool includeInternal = false, int levels = 1)
{
return GetObjectsAsync(includeExtensions, includeInternal, levels).GetAwaiter().GetResult();
}
/// <inheritdoc/>
public async Task<MetasysObject> GetObjectsAsync(bool includeExtensions = false, bool includeInternal = false, int levels = 1)
{
Dictionary<string, string> parameters = new Dictionary<string, string>
{
["includeExtensions"] = includeExtensions.ToInvariantString().ToLower(),
["includeInternal"] = includeInternal.ToInvariantString().ToLower(),
["depth"] = levels.ToInvariantString()
};
return (await base.GetObjectsAsync(null, parameters)).First();
}


/// <inheritdoc/>
public IEnumerable<MetasysObject> GetObjects(Guid id, int levels = 1, bool includeInternalObjects = false, bool includeExtensions = false)
{
Expand Down

0 comments on commit 5e2c4f0

Please sign in to comment.