Skip to content

Commit 9eece2a

Browse files
author
Aditya Abhishek
committed
deserialize to Metrics
1 parent 43db628 commit 9eece2a

5 files changed

Lines changed: 83 additions & 104 deletions

File tree

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,46 @@
11
[
22
{
3-
"metricName": "metric1",
4-
"metricValue": 0,
5-
"metricUnit": "unit1",
6-
"metricMetadata": {
7-
"metadata1": "m1",
3+
"Name": "metric1",
4+
"Value": 0,
5+
"Unit": "unit1",
6+
"MetaData": {
7+
"metadata1": 0.1,
88
"metadata2": "m2"
99
}
1010
},
1111
{
12-
"metricName": "metric2",
13-
"metricValue": -1,
14-
"metricUnit": "unit2",
15-
"metricMetadata": {
12+
"Name": "metric2",
13+
"Value": -1,
14+
"Unit": "unit2",
15+
"MetaData": {
1616
"metadata1": "m3",
17-
"metadata2": "m4"
17+
"metadata2": true
1818
}
1919
},
2020
{
21-
"metricName": "metric3",
22-
"metricValue": 1.2,
23-
"metricUnit": "unit3",
24-
"metricMetadata": {
21+
"Name": "metric3",
22+
"Value": 1.2,
23+
"Unit": "unit3",
24+
"MetaData": {
2525
"metadata1": "m5",
26-
"metadata2": "m6"
26+
"metadata2": -2
2727
}
2828
},
2929
{
30-
"metricName": "metric4",
31-
"metricValue": 1.0,
32-
"metricMetadata": {
30+
"Name": "metric4",
31+
"Value": 1.0,
32+
"MetaData": {
3333
"metadata1": "m7",
3434
"metadata2": "m8"
3535
}
3636
},
3737
{
38-
"metricName": "metric5",
39-
"metricValue": "1.24",
40-
"metricUnit": "unit5"
38+
"Name": "metric5",
39+
"Value": "1.24",
40+
"Unit": "unit5"
4141
},
4242
{
43-
"metricName": "metric6",
44-
"metricValue": "-5.8"
43+
"Name": "metric6",
44+
"Value": "-5.8"
4545
}
4646
]

src/VirtualClient/VirtualClient.Actions.UnitTests/ScriptExecutor/JsonMetricsParserTests.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public void JsonMetricsParserVerifyMetricsForPassResults_Format1()
3434
}
3535

3636
[Test]
37-
public void JsonMetricsParserVerifyMetricsForPassResults_Format2()
37+
public void JsonMetricsParserVerifyMetricsForPassResults_ArrayFormat()
3838
{
3939
string resultsPath = MockFixture.GetDirectory(typeof(JsonMetricsParserTests), "Examples", "ScriptExecutor", "validJsonExample_array.json");
4040
string rawText = File.ReadAllText(resultsPath);
@@ -50,6 +50,24 @@ public void JsonMetricsParserVerifyMetricsForPassResults_Format2()
5050
MetricAssert.Exists(metrics, "metric6", -5.8);
5151
}
5252

53+
[Test]
54+
public void JsonMetricsParserThrowsIfTheJsonArrayResultsHaveInvalidMetrics()
55+
{
56+
string rawText = "[\r\n\t{\r\n\t\t\"Name\": \"metric3\",\r\n\t\t\"Value\": \"a1\",\r\n\t\t\"Unit\": \"unit3\",\r\n\t\t\"MetaData\": {\r\n\t\t\t\"metadata1\": \"m5\",\r\n\t\t\t\"metadata2\": \"m6\"\r\n\t\t}\r\n\t},\r\n\t{\r\n\t\t\"Name\": \"metric4\",\r\n\t\t\"Value\": 1.0,\r\n\t\t\"MetaData\": {\r\n\t\t\t\"metadata1\": \"m7\"\r\n\t\t}\r\n\t}\r\n]";
57+
58+
this.testParser = new JsonMetricsParser(rawText, new InMemoryLogger(), EventContext.None);
59+
Assert.Throws<WorkloadResultsException>(() => this.testParser.Parse());
60+
}
61+
62+
[Test]
63+
public void JsonMetricsParserThrowsIfTheJsonArrayResultsHaveMisingMetricName()
64+
{
65+
string rawText = "[\r\n\t{\r\n\t\t\"Value\": 0,\r\n\t\t\"Unit\": \"unit3\",\r\n\t\t\"MetaData\": {\r\n\t\t\t\"metadata1\": \"m5\",\r\n\t\t\t\"metadata2\": \"m6\"\r\n\t\t}\r\n\t},\r\n\t{\r\n\t\t\"Name\": \"metric4\",\r\n\t\t\"Value\": 1.0,\r\n\t\t\"MetaData\": {\r\n\t\t\t\"metadata1\": \"m7\"\r\n\t\t}\r\n\t}\r\n]";
66+
67+
this.testParser = new JsonMetricsParser(rawText, new InMemoryLogger(), EventContext.None);
68+
Assert.Throws<WorkloadResultsException>(() => this.testParser.Parse());
69+
}
70+
5371
[Test]
5472
public void JsonMetricsParserThrowsIfTheJsonResultsHaveInvalidMetrics()
5573
{

src/VirtualClient/VirtualClient.Actions/ScriptExecutor/JsonMetricsParser.cs

Lines changed: 17 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -69,58 +69,31 @@ public override IList<Metric> Parse()
6969
/* Format 2:
7070
[
7171
{
72-
"metricName": "metric1",
73-
"metricValue": "value1",
74-
"metricUnit": "unit1",
75-
"metricMetadata": {
72+
"Nmae": "metric1",
73+
"Value": 0,
74+
"Unit": "unit1",
75+
"MetaData": {
7676
"metadata1": "m1",
7777
"metadata2": "m2"
7878
}
7979
}
8080
]
8181
*/
82-
var metricList = JsonConvert.DeserializeObject<List<CustomMetric>>(this.RawText);
83-
84-
foreach (var customMetric in metricList)
82+
try
8583
{
86-
if (string.IsNullOrWhiteSpace(customMetric.Name))
87-
{
88-
throw new WorkloadResultsException(
89-
$"Invalid JSON metrics content formatting. 'metricName' is a required property.",
90-
ErrorReason.InvalidResults);
91-
}
92-
93-
if (customMetric.Value == null || !double.TryParse(customMetric.Value.ToString(), out double metricValue))
94-
{
95-
throw new WorkloadResultsException(
96-
$"Invalid JSON metrics content formatting. 'metricValue' for '{customMetric.Name}' is not a valid numeric data type. Provided metric value is '{customMetric.Value}'",
97-
ErrorReason.InvalidResults);
98-
}
99-
100-
// Robustly handle metricMetadata
101-
IDictionary<string, IConvertible> metricMetadata = null;
102-
if (customMetric.MetadataRaw != null && customMetric.MetadataRaw.Type != JTokenType.Null)
103-
{
104-
if (customMetric.MetadataRaw.Type == JTokenType.Object)
105-
{
106-
metricMetadata = new Dictionary<string, IConvertible>(StringComparer.OrdinalIgnoreCase);
107-
foreach (var prop in customMetric.MetadataRaw.Children<JProperty>())
108-
{
109-
metricMetadata[prop.Name] = prop.Value.ToString();
110-
}
111-
}
112-
else
113-
{
114-
throw new WorkloadResultsException(
115-
$"Invalid JSON metrics content formatting. 'metricMetadata' for '{customMetric.Name}' must be a JSON object.",
116-
ErrorReason.InvalidResults);
117-
}
118-
}
84+
metrics = JsonConvert.DeserializeObject<List<Metric>>(this.RawText);
85+
}
86+
catch (Exception exc)
87+
{
88+
throw new WorkloadResultsException(
89+
"Invalid JSON metrics content formatting. Failed to deserialze the Array JSON Contents into Metrics format.", exc, ErrorReason.InvalidResults);
90+
}
11991

120-
metrics.Add(
121-
customMetric.Unit != null
122-
? new Metric(customMetric.Name, metricValue, customMetric.Unit, MetricRelativity.Undefined, tags: null, description: null, metadata: metricMetadata)
123-
: new Metric(customMetric.Name, metricValue, MetricRelativity.Undefined, tags: null, description: null, metadata: metricMetadata));
92+
if (metrics.Any(m => string.IsNullOrWhiteSpace(m.Name)))
93+
{
94+
throw new WorkloadResultsException(
95+
"Invalid JSON metrics content formatting. 'Name' is a required property for each metric, it can't be null or whitespace.",
96+
ErrorReason.InvalidResults);
12497
}
12598
}
12699
else
@@ -145,21 +118,5 @@ public override IList<Metric> Parse()
145118

146119
return metrics;
147120
}
148-
149-
internal class CustomMetric
150-
{
151-
[JsonProperty("metricName")]
152-
public string Name { get; set; }
153-
154-
[JsonProperty("metricValue")]
155-
public object Value { get; set; }
156-
157-
[JsonProperty("metricUnit")]
158-
public string Unit { get; set; }
159-
160-
// Use JToken to allow robust handling
161-
[JsonProperty("metricMetadata")]
162-
public JToken MetadataRaw { get; set; }
163-
}
164121
}
165122
}

src/VirtualClient/VirtualClient.Contracts/Metric.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ namespace VirtualClient.Contracts
88
using System.Diagnostics;
99
using System.Linq;
1010
using System.Text;
11+
using Newtonsoft.Json;
12+
using VirtualClient.Common.Contracts;
1113

1214
/// <summary>
1315
/// Represents the result of a single metric
@@ -18,6 +20,7 @@ public class Metric : IEquatable<Metric>
1820
/// <summary>
1921
/// Creates a metric
2022
/// </summary>
23+
[JsonConstructor]
2124
public Metric(string name, double value)
2225
{
2326
this.Name = name;
@@ -133,6 +136,7 @@ public Metric(string name, double value, string unit, MetricRelativity relativit
133136
/// <summary>
134137
/// Telemetry context for metric.
135138
/// </summary>
139+
[JsonConverter(typeof(ParameterDictionaryJsonConverter))]
136140
public IDictionary<string, IConvertible> Metadata { get; }
137141

138142
/// <summary>

website/docs/guides/0221-usage-extensions.md

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -502,48 +502,48 @@ and requirements.
502502

503503
[
504504
{
505-
"metricName": "metric1",
506-
"metricValue": 0,
507-
"metricUnit": "unit1",
508-
"metricMetadata": {
505+
"Name": "metric1",
506+
"Value": 0,
507+
"Unit": "unit1",
508+
"MetaData": {
509509
"metadata1": "m1",
510510
"metadata2": "m2"
511511
}
512512
},
513513
{
514-
"metricName": "metric2",
515-
"metricValue": -1,
516-
"metricUnit": "unit2",
517-
"metricMetadata": {
514+
"Name": "metric2",
515+
"Value": -1,
516+
"Unit": "unit2",
517+
"MetaData": {
518518
"metadata1": "m3",
519519
"metadata2": "m4"
520520
}
521521
},
522522
{
523-
"metricName": "metric3",
524-
"metricValue": 1.2,
525-
"metricUnit": "unit3",
526-
"metricMetadata": {
523+
"Name": "metric3",
524+
"Value": 1.2,
525+
"Unit": "unit3",
526+
"MetaData": {
527527
"metadata1": "m5",
528528
"metadata2": "m6"
529529
}
530530
},
531531
{
532-
"metricName": "metric4",
533-
"metricValue": 1.0,
534-
"metricMetadata": {
532+
"Name": "metric4",
533+
"Value": 1.0,
534+
"MetaData": {
535535
"metadata1": "m7",
536536
"metadata2": "m8"
537537
}
538538
},
539539
{
540-
"metricName": "metric5",
541-
"metricValue": "1.24",
542-
"metricUnit": "unit5"
540+
"Name": "metric5",
541+
"Value": "1.24",
542+
"Unit": "unit5"
543543
},
544544
{
545-
"metricName": "metric6",
546-
"metricValue": "-5.8"
545+
"Name": "metric6",
546+
"Value": "-5.8"
547547
}
548548
]
549549
```

0 commit comments

Comments
 (0)