Skip to content

Commit

Permalink
Implemented Suggestions
Browse files Browse the repository at this point in the history
+ Moved key one layer up
+ Added "GraphiteMetricData" Converter
+ Fixed MetricDatapointConverter crashing on NULL
+ Added Unit Test to cover invalid JSON objects
  • Loading branch information
bartimaeusnek committed Aug 12, 2020
1 parent 46dea4d commit cd35d0e
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 28 deletions.
2 changes: 1 addition & 1 deletion Graphite.Test/Graphite.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<RootNamespace>ahd.Graphite.Test</RootNamespace>
<AssemblyName>ahd.Graphite.Test</AssemblyName>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>graphite.snk</AssemblyOriginatorKeyFile>
<AssemblyOriginatorKeyFile>..\graphite.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
Expand Down
23 changes: 23 additions & 0 deletions Graphite.Test/GraphiteClientTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,29 @@ public void CanDeserializeMetrics()
Assert.True(metric.Expandable);
}

[Fact]
public void CanDeserializeMetricDatapoint()
{
var json = "[3.5, 1474716420]";
var dp = JsonSerializer.Deserialize<MetricDatapoint>(json);
Assert.Equal(3.5D, dp.Value);
Assert.Equal(1474716420L, dp.UnixTimestamp);

json = "[null, 1474716424]";
dp = JsonSerializer.Deserialize<MetricDatapoint>(json);
Assert.Null(dp.Value);
Assert.Equal(1474716424, dp.UnixTimestamp);
}

[Fact]
public void DeserializationThrowsOnIllegalJson()
{
var json = "{Test: 24, Array: [3.5, null]}";
Assert.Throws<JsonException>(() => JsonSerializer.Deserialize<MetricDatapoint>(json));
Assert.Throws<JsonException>(() => JsonSerializer.Deserialize<GraphiteMetric>(json));
Assert.Throws<JsonException>(() => JsonSerializer.Deserialize<GraphiteMetricData>(json));
}

[Fact]
public void CanDeserializeMetricsData()
{
Expand Down
4 changes: 2 additions & 2 deletions Graphite/Graphite.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<Description>client implementation for sending and retrieving values from and to any graphite server.</Description>
<Product>Graphite</Product>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>graphite.snk</AssemblyOriginatorKeyFile>
<AssemblyOriginatorKeyFile>..\graphite.snk</AssemblyOriginatorKeyFile>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
Expand Down Expand Up @@ -79,7 +79,7 @@

<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>ahd.$(MSBuildProjectName).Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f5a0c6d7f18a890e7c76bf85cef11fbde4769fc7f5c41f1e436245c97b6fd7c5dd4947b216c0107f56f621f396b88f5dd13aa3dc7958d99de286011beaea2ef423ed897012af252276705efe81d17268e4e09b1909985c8b65e2cc874e7c1df59178e03dfed26701d1d45f6b1d0ab467f6d753cacb3a5a2a27024284c83beecc</_Parameter1>
<_Parameter1>ahd.Graphite.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f5a0c6d7f18a890e7c76bf85cef11fbde4769fc7f5c41f1e436245c97b6fd7c5dd4947b216c0107f56f621f396b88f5dd13aa3dc7958d99de286011beaea2ef423ed897012af252276705efe81d17268e4e09b1909985c8b65e2cc874e7c1df59178e03dfed26701d1d45f6b1d0ab467f6d753cacb3a5a2a27024284c83beecc</_Parameter1>
</AssemblyAttribute>
</ItemGroup>

Expand Down
3 changes: 1 addition & 2 deletions Graphite/GraphiteMetric.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,8 @@ internal class GraphiteMetricConverter : JsonConverter<GraphiteMetric>
{
public override GraphiteMetric Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var exception = new JsonException("Cannot deserialize GraphiteMetric");
if (reader.TokenType != JsonTokenType.StartObject)
throw exception;
throw new JsonException($"Can not deserialize {nameof(GraphiteMetric)}");

var path = "";
var is_leaf = "";
Expand Down
69 changes: 57 additions & 12 deletions Graphite/GraphiteMetricData.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
using System.Text.Json.Serialization;
using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace ahd.Graphite
{
/// <summary>
/// Metric result
/// </summary>
[JsonConverter(typeof(GraphiteMetricConverter))]
public class GraphiteMetricData
{
/// <summary>
Expand All @@ -18,23 +21,65 @@ public GraphiteMetricData(string target, MetricDatapoint[] datapoints)
Datapoints = datapoints;
}

/// <summary>
/// JSON Constructor
/// </summary>
public GraphiteMetricData()
{
}

/// <summary>
/// Target name, as returned from graphite
/// </summary>
[JsonPropertyName("target")]
public string Target { get; set; }
public string Target { get; }

/// <summary>
/// List of timestamped values as returned from graphite
/// </summary>
[JsonPropertyName("datapoints")]
public MetricDatapoint[] Datapoints { get; set; }
public MetricDatapoint[] Datapoints { get; }

internal class GraphiteMetricConverter : JsonConverter<GraphiteMetricData>
{
public override GraphiteMetricData Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
throw new JsonException($"Can not deserialize {nameof(GraphiteMetricData)}");
var target = "";
var datapoints = new MetricDatapoint[0];
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.PropertyName)
{
var propertyName = reader.GetString();
reader.Read();

switch (propertyName)
{
case nameof(target):
target = reader.GetString();
break;
case nameof(datapoints):
datapoints = JsonSerializer.Deserialize<MetricDatapoint[]>(ref reader);
break;
default:
throw new JsonException($"Unexpected Property Name: {propertyName}");
}
}
}
return new GraphiteMetricData(target,datapoints);
}

public override void Write(Utf8JsonWriter writer, GraphiteMetricData value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteString("target", value.Target);
writer.WriteStartArray("datapoints");
foreach (var datapoint in value.Datapoints)
{
writer.WriteStartArray();
if (!datapoint.Value.HasValue)
writer.WriteNullValue();
else
writer.WriteNumberValue(datapoint.Value.Value);
writer.WriteNumberValue(datapoint.UnixTimestamp);
writer.WriteEndArray();
}
writer.WriteEndArray();
writer.WriteEndObject();
}
}
}
}
24 changes: 13 additions & 11 deletions Graphite/MetricDatapoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,24 +47,26 @@ internal class MetricDatapointConverter : JsonConverter<MetricDatapoint>
{
public override MetricDatapoint Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var exception = new JsonException("Cannot deserialize MetricDatapoint");
if (reader.TokenType != JsonTokenType.StartArray || !reader.Read())
throw exception;
throw new JsonException($"Can not deserialize {nameof(MetricDatapoint)}, {nameof(JsonTokenType.StartArray)} not found!");

double? value = null;
if (reader.TokenType != JsonTokenType.Number && reader.TokenType != JsonTokenType.Null)
{

throw new JsonException($"Unexpected Token {reader.TokenType}");
}

if (reader.TryGetDouble(out var current))
if (reader.TokenType != JsonTokenType.Number && reader.TokenType != JsonTokenType.Null)
throw new JsonException($"Can not deserialize {nameof(MetricDatapoint)}, unexpected token {reader.TokenType}");

if (reader.TokenType == JsonTokenType.Number && reader.TryGetDouble(out var current))
value = current;
else if (reader.TokenType != JsonTokenType.Null)
throw new JsonException($"Can not deserialize {nameof(MetricDatapoint)}, unexpected token {reader.TokenType}");

if (!reader.Read() || !reader.TryGetDouble(out var timestamp) || !reader.Read() || reader.TokenType != JsonTokenType.EndArray)
throw exception;
if (!reader.Read() || !reader.TryGetInt64(out var timestamp))
throw new JsonException($"Can not deserialize {nameof(MetricDatapoint)}, {nameof(timestamp)} not found!");

if (!reader.Read() || reader.TokenType != JsonTokenType.EndArray)
throw new JsonException($"Can not deserialize {nameof(MetricDatapoint)}, {nameof(JsonTokenType.EndArray)} not found!");

return new MetricDatapoint(value, (long) timestamp);
return new MetricDatapoint(value, timestamp);
}

public override void Write(Utf8JsonWriter writer, MetricDatapoint datapoint, JsonSerializerOptions options)
Expand Down
Binary file removed Graphite/graphite.snk
Binary file not shown.
File renamed without changes.

0 comments on commit cd35d0e

Please sign in to comment.