From 2c5d8776cd26c78dfc54bbc826dc4b11826f04d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ozan=20G=C3=B6ktan?= <72358629+ozangoktan@users.noreply.github.com> Date: Fri, 6 Sep 2024 16:32:18 +0100 Subject: [PATCH] Fix CDM types (#399) --- CogniteSdk.Types/Alpha/Common/Identity.cs | 2 +- .../Beta/DataModels/Core/Timeseries.cs | 60 +++++++++++--- CogniteSdk.Types/Common/Converters.cs | 81 +++++++++++++++++++ CogniteSdk/test/fsharp/Alpha/DataPoints.fs | 35 +++++++- Oryx.Cognite/src/Common.fs | 2 + version | 2 +- 6 files changed, 166 insertions(+), 16 deletions(-) diff --git a/CogniteSdk.Types/Alpha/Common/Identity.cs b/CogniteSdk.Types/Alpha/Common/Identity.cs index eb5beba5..638d2c47 100644 --- a/CogniteSdk.Types/Alpha/Common/Identity.cs +++ b/CogniteSdk.Types/Alpha/Common/Identity.cs @@ -148,7 +148,7 @@ public override string ToString() } else { - return $"{{{InstanceId}}}"; + return InstanceId.ToString(); } } diff --git a/CogniteSdk.Types/Beta/DataModels/Core/Timeseries.cs b/CogniteSdk.Types/Beta/DataModels/Core/Timeseries.cs index 2bc3c9e2..1ba17307 100644 --- a/CogniteSdk.Types/Beta/DataModels/Core/Timeseries.cs +++ b/CogniteSdk.Types/Beta/DataModels/Core/Timeseries.cs @@ -3,6 +3,8 @@ using System; using System.Collections.Generic; +using System.Text.Json.Serialization; +using System.Text.Json; namespace CogniteSdk.Beta.DataModels.Core { @@ -15,13 +17,10 @@ public class CogniteTimeSeriesBase : CogniteCoreInstanceBase /// Defines whether the time series is a step series or not. /// public bool? IsStep { get; set; } - - private readonly TimeSeriesType? _type; /// /// Type of datapoints the time series contains. /// - public string Type { get { return _type == null ? null : Enum.GetName(typeof(TimeSeriesType), _type).ToLower(); } } - + public TimeSeriesType? Type { get; set; } /// /// The physical unit of the time series as described in the source. /// @@ -46,18 +45,11 @@ public class CogniteTimeSeriesBase : CogniteCoreInstanceBase /// - /// Empty constructor. For partial updates only. + /// Empty constructor. /// public CogniteTimeSeriesBase() { } - /// - /// Constructor. - /// - public CogniteTimeSeriesBase(TimeSeriesType type) - { - _type = type; - } } /// @@ -74,4 +66,48 @@ public enum TimeSeriesType /// Numeric, } + + /// + /// Converts string to TimeSeriesType + /// + public class ObjectToTimeSeriesTypeConverter : JsonConverter + { + /// + /// Reads string into an TimeSeriesType + /// + public override TimeSeriesType? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Null) + { + return null; + } + if (reader.TokenType != JsonTokenType.String) + { + throw new JsonException($"JsonTokenType was of type {reader.TokenType}, must be a string"); + } + + var typeVal = reader.GetString().ToLower(); + + switch (typeVal) + { + case "numeric": + return TimeSeriesType.Numeric; + case "string": + return TimeSeriesType.String; + default: + throw new ArgumentOutOfRangeException(nameof(CogniteTimeSeriesBase.Type), "TimeSeries type can either be numeric or string"); + } + } + + /// + /// Writes a TimeSeriesType to string. + /// + public override void Write(Utf8JsonWriter writer, TimeSeriesType? value, JsonSerializerOptions options) + { + if (value == null) + writer.WriteNullValue(); + else + writer.WriteStringValue(Enum.GetName(typeof(TimeSeriesType), value).ToLower()); + } + } } \ No newline at end of file diff --git a/CogniteSdk.Types/Common/Converters.cs b/CogniteSdk.Types/Common/Converters.cs index 227d865a..43037d7b 100644 --- a/CogniteSdk.Types/Common/Converters.cs +++ b/CogniteSdk.Types/Common/Converters.cs @@ -5,6 +5,7 @@ using System.Text.Json; using System.Text.Json.Serialization; using System.Collections.Generic; +using CogniteSdk.Beta.DataModels; namespace CogniteSdk { @@ -32,6 +33,8 @@ public override MultiValue Read(ref Utf8JsonReader reader, Type typeToConvert, J return MultiValue.Create(reader.GetDouble()); case JsonTokenType.Null: return MultiValue.Create(); + case JsonTokenType.StartObject: + return MultiValue.Create(new ObjectToInstanceIdJsonConverter().Read(ref reader, typeToConvert, options)); default: throw new JsonException($"Unable to parse value of type: {reader.TokenType}"); } @@ -67,6 +70,84 @@ public override void Write(Utf8JsonWriter writer, MultiValue value, JsonSerializ } } + /// + /// Converts JSON to .NET type + /// + public class ObjectToInstanceIdJsonConverter : JsonConverter + { + /// + /// Reads JSON into an InstanceIdentifier + /// + public override InstanceIdentifier Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartObject) + { + throw new JsonException($"JsonTokenType was of type {reader.TokenType}, must be StartObject"); + } + + var instanceId = new InstanceIdentifier(); + var keys = new Dictionary>() { + { nameof(InstanceIdentifier.Space).ToLower(), (x, y) => {x.Space = y; return x; } }, + { nameof(InstanceIdentifier.ExternalId).ToLower(), (x, y) => {x.ExternalId = y; return x; } } + }; + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndObject) + { + return instanceId; + } + + if (reader.TokenType != JsonTokenType.PropertyName) + { + throw new JsonException($"JsonTokenType must be of type PropertyName, was {reader.TokenType}"); + } + + var propertyName = reader.GetString(); + + if (string.IsNullOrWhiteSpace(propertyName)) + { + throw new JsonException("Failed to get property name"); + } + + reader.Read(); + + if (keys.TryGetValue(propertyName.ToLower(), out var method)) + { + method(instanceId, ReadValue(ref reader, options)); + } + } + + return instanceId; + } + + /// + /// Writes an InstanceIdentifier to string. + /// + public override void Write(Utf8JsonWriter writer, InstanceIdentifier value, JsonSerializerOptions options) + { + writer.WriteStringValue(value.ToString()); + } + + private string ReadValue(ref Utf8JsonReader reader, JsonSerializerOptions options) + { + switch (reader.TokenType) + { + case JsonTokenType.String: + return reader.GetString(); + case JsonTokenType.Null: + return null; + case JsonTokenType.Number: + if (reader.TryGetInt64(out var number)) + { + return number.ToString(); + } + return reader.GetDouble().ToString(); + default: + throw new JsonException($"'{reader.TokenType}' is not supported"); + } + } + } + /// /// Converts JSON to .NET type /// diff --git a/CogniteSdk/test/fsharp/Alpha/DataPoints.fs b/CogniteSdk/test/fsharp/Alpha/DataPoints.fs index 71c149b4..f7f4333f 100644 --- a/CogniteSdk/test/fsharp/Alpha/DataPoints.fs +++ b/CogniteSdk/test/fsharp/Alpha/DataPoints.fs @@ -15,6 +15,8 @@ open CogniteSdk.Beta.DataModels.Core let testSpace = "dotnet-sdk-integration-test-space" module Fixtures = + open System.Text.Json.Nodes + type DMFixture() = do writeClient.Beta.DataModels @@ -25,6 +27,35 @@ module Fixtures = interface IDisposable with member __.Dispose() = + let nodes = + writeClient.Beta.DataModels + .FilterInstances( + InstancesFilter( + Filter = + EqualsFilter( + Property = [ "node"; "space" ], + Value = RawPropertyValue(Value = testSpace) + ), + Limit = 1000, + InstanceType = InstanceType.node + ) + ) + .GetAwaiter() + .GetResult() + + if not <| Seq.isEmpty (nodes.Items) then + writeClient.Beta.DataModels + .DeleteInstances( + nodes.Items + |> Seq.map (fun x -> + let item = new InstanceIdentifierWithType(InstanceType.node, x.Space, x.ExternalId) + + item) + ) + .GetAwaiter() + .GetResult() + |> ignore + writeClient.Beta.DataModels.DeleteSpaces([ testSpace ]).GetAwaiter().GetResult() |> ignore @@ -44,7 +75,7 @@ module DataPointsTests = ExternalId = externalIdString, Properties = CogniteTimeSeriesBase( - TimeSeriesType.Numeric, + Type = TimeSeriesType.Numeric, Name = "Insert datapoints test", Description = "dotnet sdk test" ) @@ -92,7 +123,7 @@ module DataPointsTests = ExternalId = externalIdString, Properties = CogniteTimeSeriesBase( - TimeSeriesType.Numeric, + Type = TimeSeriesType.Numeric, Name = "Delete datapoints test", Description = "dotnet sdk test" ) diff --git a/Oryx.Cognite/src/Common.fs b/Oryx.Cognite/src/Common.fs index b69e30ea..55876920 100644 --- a/Oryx.Cognite/src/Common.fs +++ b/Oryx.Cognite/src/Common.fs @@ -10,6 +10,7 @@ open CogniteSdk open CogniteSdk.Alpha open CogniteSdk.Beta open CogniteSdk.Beta.DataModels +open CogniteSdk.Beta.DataModels.Core open System.Text.Json.Serialization @@ -71,6 +72,7 @@ module Common = options.DefaultIgnoreCondition <- JsonIgnoreCondition.WhenWritingNull options.Converters.Add(MultiValueConverter()) + options.Converters.Add(ObjectToTimeSeriesTypeConverter()) options.Converters.Add(ObjectToDictionaryJsonConverter()) options.Converters.Add(AclConverter()) options.Converters.Add(TransformationSchemaConverter()) diff --git a/version b/version index ae153944..28446a5e 100644 --- a/version +++ b/version @@ -1 +1 @@ -4.5.0 \ No newline at end of file +4.6.0 \ No newline at end of file