From 9c66b3d5f30a25870aec502275f237cf45be7225 Mon Sep 17 00:00:00 2001 From: Trevor Pering Date: Mon, 16 Oct 2023 08:03:23 -0700 Subject: [PATCH 1/9] Semantic mapping --- .../daq/mqtt/sequencer/SequenceBase.java | 4 ++ .../sequences/PointsetSequences.java | 3 +- .../daq/mqtt/util/ObjectDiffEngine.java | 44 +++++++++++++------ 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/validator/src/main/java/com/google/daq/mqtt/sequencer/SequenceBase.java b/validator/src/main/java/com/google/daq/mqtt/sequencer/SequenceBase.java index d94a0f93d6..09edd0399e 100644 --- a/validator/src/main/java/com/google/daq/mqtt/sequencer/SequenceBase.java +++ b/validator/src/main/java/com/google/daq/mqtt/sequencer/SequenceBase.java @@ -1812,6 +1812,10 @@ protected T ifCatchNullSkipTest(Supplier evaluator, String reason) { } + protected void mapSemanticKey(String keyPath, String description) { + SENT_CONFIG_DIFFERNATOR.mapSemanticKey(keyPath, description); + } + /** * Special exception to indicate that catching-loops should be terminated. */ diff --git a/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java b/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java index 42d88433fb..ecf03f5ba5 100644 --- a/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java +++ b/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java @@ -23,7 +23,6 @@ import java.util.Date; import java.util.List; import java.util.Map.Entry; -import java.util.Objects; import java.util.stream.Collectors; import org.junit.Test; import udmi.schema.Level; @@ -98,6 +97,7 @@ public void pointset_remove_point() { String name = candidatePoints.get((int) Math.floor(Math.random() * candidatePoints.size())); debug("Removing randomly selected test point " + name); + mapSemanticKey("pointset.points." + name, "Random point"); PointPointsetConfig removed = requireNonNull(deviceConfig.pointset.points.remove(name)); try { @@ -114,7 +114,6 @@ public void pointset_remove_point() { untilPointsetSanity(); } - /** * Simple check that device publishes pointset events. */ diff --git a/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java b/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java index 75783e4872..42ec90ae18 100644 --- a/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java +++ b/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -19,6 +20,7 @@ public class ObjectDiffEngine { private Map previous; + private final Map descriptions = new HashMap<>(); private boolean ignoreSemantics; public ObjectDiffEngine() { @@ -46,18 +48,19 @@ public List computeChanges(Object updatedObject) { * @param updatedObject new object state */ public void resetState(Object updatedObject) { + descriptions.clear(); previous = extractDefinitions(updatedObject); } private Map extractValues(Object thing) { - return traverseExtract(thing, true); + return traverseExtract(thing, true, ""); } private Map extractDefinitions(Object thing) { - return traverseExtract(thing, false); + return traverseExtract(thing, false, ""); } - private Map traverseExtract(Object thing, boolean asValues) { + private Map traverseExtract(Object thing, boolean asValues, String keyPath) { if (thing == null) { return ImmutableMap.of(); } @@ -65,21 +68,27 @@ private Map traverseExtract(Object thing, boolean asValues) { @SuppressWarnings("unchecked") Map asMap = (Map) thing; return asMap.keySet().stream() - .collect(Collectors.toMap(key -> key, key -> traverseExtract(asMap.get(key), asValues))); + .collect(Collectors.toMap(key -> key, + key -> traverseExtract(asMap.get(key), asValues, keyPath + "." + key))); } return Arrays.stream(thing.getClass().getFields()) .filter(field -> isNotNull(thing, field)).collect( - Collectors.toMap(Field::getName, field -> extractField(thing, field, asValues))); + Collectors.toMap(Field::getName, + field -> extractField(thing, field, asValues, keyPath))); } - private Object extractField(Object thing, Field field, boolean asValue) { + private Object extractField(Object thing, Field field, boolean asValue, String keyPath) { try { Object result = field.get(thing); - if (isBaseType(field) || isBaseType(result)) { + String fieldName = field.getName(); + String newPath = keyPath + "." + fieldName; + if (descriptions.containsKey(newPath)) { + return descriptions.get(newPath); + } else if (isBaseType(field) || isBaseType(result)) { boolean useValue = asValue || !SemanticValue.isSemanticValue(result); return useValue ? SemanticValue.getValue(result) : SemanticValue.getDescription(result); } else { - return traverseExtract(result, asValue); + return traverseExtract(result, asValue, newPath); } } catch (Exception e) { throw new RuntimeException("While converting field " + field.getName(), e); @@ -108,26 +117,31 @@ private boolean isBaseType(Object value) { void accumulateDifference(String prefix, Map left, Map right, List updates) { right.forEach((key, value) -> { + String fullKey = prefix + key; + String describedKey = + descriptions.containsKey(fullKey) ? (prefix + descriptions.get(fullKey)) : fullKey; if (left != null && left.containsKey(key)) { Object leftValue = left.get(key); if (SemanticValue.equals(value, leftValue)) { return; } if (isBaseType(value)) { - updates.add(String.format("Set `%s%s` = %s", prefix, key, semanticValue(value))); + updates.add(String.format("Set `%s` = %s", describedKey, semanticValue(value))); } else { - String newPrefix = prefix + key + "."; - accumulateDifference(newPrefix, (Map) leftValue, + accumulateDifference(fullKey + ".", (Map) leftValue, (Map) value, updates); } } else { - updates.add(String.format("Add `%s%s` = %s", prefix, key, semanticValue(value))); + updates.add(String.format("Add `%s` = %s", describedKey, semanticValue(value))); } }); if (left != null) { left.forEach((key, value) -> { if (!right.containsKey(key)) { - updates.add(String.format("Remove `%s%s`", prefix, key)); + String fullKey = prefix + key; + String describedKey = + descriptions.containsKey(fullKey) ? (prefix + descriptions.get(fullKey)) : fullKey; + updates.add(String.format("Remove `%s`", describedKey)); } }); } @@ -193,4 +207,8 @@ public List diff(Object startObject, Object endObject) { accumulateDifference("", left, right, updates); return updates; } + + public void mapSemanticKey(String keyPath, String description) { + descriptions.put(keyPath, description); + } } \ No newline at end of file From 6871744d0cafbd981271bffe677710936b36b849 Mon Sep 17 00:00:00 2001 From: Trevor Pering Date: Mon, 16 Oct 2023 09:10:49 -0700 Subject: [PATCH 2/9] Adding point substitution --- .../sequencer/sequences/PointsetSequences.java | 2 +- .../com/google/daq/mqtt/util/ObjectDiffEngine.java | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java b/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java index 482cb5b061..d470bcd9b8 100644 --- a/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java +++ b/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java @@ -97,7 +97,7 @@ public void pointset_remove_point() { String name = candidatePoints.get((int) Math.floor(Math.random() * candidatePoints.size())); debug("Removing randomly selected test point " + name); - mapSemanticKey("pointset.points." + name, "Random point"); + mapSemanticKey("pointset.points." + name, "random_point"); PointPointsetConfig removed = requireNonNull(deviceConfig.pointset.points.remove(name)); try { diff --git a/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java b/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java index 060e1845c9..249f6ea922 100644 --- a/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java +++ b/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java @@ -117,9 +117,7 @@ private boolean isBaseType(Object value) { void accumulateDifference(String prefix, Map left, Map right, List updates) { right.forEach((key, value) -> { - String fullKey = prefix + key; - String describedKey = - descriptions.containsKey(fullKey) ? (prefix + descriptions.get(fullKey)) : fullKey; + String describedKey = keyDescription(prefix, prefix + key); if (left != null && left.containsKey(key)) { Object leftValue = left.get(key); if (SemanticValue.equals(value, leftValue)) { @@ -128,7 +126,7 @@ void accumulateDifference(String prefix, Map left, Map) leftValue, + accumulateDifference((prefix + key) + ".", (Map) leftValue, (Map) value, updates); } } else { @@ -139,14 +137,18 @@ void accumulateDifference(String prefix, Map left, Map { if (!right.containsKey(key)) { String fullKey = prefix + key; - String describedKey = - descriptions.containsKey(fullKey) ? (prefix + descriptions.get(fullKey)) : fullKey; + String describedKey = keyDescription(prefix, fullKey); updates.add(String.format("Remove `%s`", describedKey)); } }); } } + private String keyDescription(String prefix, String fullKey) { + String formattedKey = String.format("%s[%s]", prefix, descriptions.get(fullKey)); + return descriptions.containsKey(fullKey) ? formattedKey : fullKey; + } + private String singleLine(String toJsonString) { return Joiner.on(' ').join( Arrays.stream(toJsonString.split("\n")).map(String::trim).collect(Collectors.toList())); From 34a4d17433728a134a0261b227dc651e86ff954e Mon Sep 17 00:00:00 2001 From: Trevor Pering Date: Mon, 16 Oct 2023 09:24:36 -0700 Subject: [PATCH 3/9] Adding more mapping --- docs/specs/sequences/endpoint_reconfiguration.md | 2 +- .../google/daq/mqtt/sequencer/sequences/PointsetSequences.java | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/specs/sequences/endpoint_reconfiguration.md b/docs/specs/sequences/endpoint_reconfiguration.md index 7185afc717..54aa786129 100644 --- a/docs/specs/sequences/endpoint_reconfiguration.md +++ b/docs/specs/sequences/endpoint_reconfiguration.md @@ -84,7 +84,7 @@ Config message to initiate Reconfiguration (sequence #1 in diagrams above) "_iot_endpoint_config": { "phase": "final", "url": "data:application/json;base64,ewogICJwcm90b2NvbCI6ICJtcXR0IiwKICAiY2xpZW50X2lkIjogInByb2plY3RzL2Jvcy1zbm9yay1kZXYvbG9jYXRpb25zL3VzLWNlbnRyYWwxL3JlZ2lzdHJpZXMvWlotVFJJLUZFQ1RBL2RldmljZXMvQUhVLTEiLAogICJob3N0bmFtZSI6ICJtcXR0Lmdvb2dsZWFwaXMuY29tIgp9", - "sha256": "c8a25e6ecf487f0a2ff85845c9bc59fb81e1dd4eaa08d7ff7d55bd924447e015", + "sha256": "9c8423ac2e707a40c239fce4ce52b8c05ae8c32b163927b9350c97d0f64a8cf7", "generation": "2022-07-13T12:00:00.000Z" } } diff --git a/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java b/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java index d470bcd9b8..6dfb0b4925 100644 --- a/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java +++ b/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java @@ -68,6 +68,8 @@ private boolean validPointEntry(Entry point) { public void pointset_request_extraneous() { untilPointsetSanity(); + mapSemanticKey("pointset.points." + EXTRANEOUS_POINT, "extranious_point"); + deviceConfig.pointset.points.put(EXTRANEOUS_POINT, new PointPointsetConfig()); try { From f257d4452f5baf8b20716cfcb89fb586ba2f1c91 Mon Sep 17 00:00:00 2001 From: Trevor Pering Date: Mon, 16 Oct 2023 09:29:24 -0700 Subject: [PATCH 4/9] Fix up semantic mapping --- .../java/com/google/daq/mqtt/sequencer/SequenceBase.java | 4 ++-- .../daq/mqtt/sequencer/sequences/PointsetSequences.java | 5 +++-- .../main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/validator/src/main/java/com/google/daq/mqtt/sequencer/SequenceBase.java b/validator/src/main/java/com/google/daq/mqtt/sequencer/SequenceBase.java index 1618bac83e..b8e03743c6 100644 --- a/validator/src/main/java/com/google/daq/mqtt/sequencer/SequenceBase.java +++ b/validator/src/main/java/com/google/daq/mqtt/sequencer/SequenceBase.java @@ -1865,8 +1865,8 @@ protected T ifCatchNullSkipTest(Supplier evaluator, String reason) { return ifNullSkipTest(evaluatorResult, reason); } - protected void mapSemanticKey(String keyPath, String description) { - SENT_CONFIG_DIFFERNATOR.mapSemanticKey(keyPath, description); + protected void mapSemanticKey(String keyPath, String keyName, String description) { + SENT_CONFIG_DIFFERNATOR.mapSemanticKey(keyPath, keyName, description); } /** diff --git a/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java b/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java index 6dfb0b4925..52c4c94d4f 100644 --- a/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java +++ b/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java @@ -38,6 +38,7 @@ public class PointsetSequences extends PointsetBase { public static final String EXTRANEOUS_POINT = "extraneous_point"; private static final int DEFAULT_SAMPLE_RATE_SEC = 10; + public static final String POINTS_MAP_PATH = "pointset.points"; private boolean isErrorState(PointPointsetState pointState) { return ofNullable(catchToNull(() -> pointState.status.level)).orElse(Level.INFO.value()) @@ -68,7 +69,7 @@ private boolean validPointEntry(Entry point) { public void pointset_request_extraneous() { untilPointsetSanity(); - mapSemanticKey("pointset.points." + EXTRANEOUS_POINT, "extranious_point"); + mapSemanticKey(POINTS_MAP_PATH, EXTRANEOUS_POINT, "extraneous_point"); deviceConfig.pointset.points.put(EXTRANEOUS_POINT, new PointPointsetConfig()); @@ -99,7 +100,7 @@ public void pointset_remove_point() { String name = candidatePoints.get((int) Math.floor(Math.random() * candidatePoints.size())); debug("Removing randomly selected test point " + name); - mapSemanticKey("pointset.points." + name, "random_point"); + mapSemanticKey(POINTS_MAP_PATH, name, "random_point"); PointPointsetConfig removed = requireNonNull(deviceConfig.pointset.points.remove(name)); try { diff --git a/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java b/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java index 249f6ea922..77312f7e2f 100644 --- a/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java +++ b/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java @@ -210,8 +210,8 @@ public List diff(Object startObject, Object endObject) { return updates; } - public void mapSemanticKey(String keyPath, String description) { - descriptions.put(keyPath, description); + public void mapSemanticKey(String keyPath, String keyName, String description) { + descriptions.put(keyPath + "." + keyName, description); } public boolean isInitialized() { From 428e2ca6fa9d2e84a03183827616a8a07db04442 Mon Sep 17 00:00:00 2001 From: Trevor Pering Date: Mon, 16 Oct 2023 09:35:07 -0700 Subject: [PATCH 5/9] Removing old hacks --- .../daq/mqtt/util/ObjectDiffEngine.java | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java b/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java index 77312f7e2f..a925c54617 100644 --- a/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java +++ b/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java @@ -53,14 +53,14 @@ public void resetState(Object updatedObject) { } private Map extractValues(Object thing) { - return traverseExtract(thing, true, ""); + return traverseExtract(thing, true); } private Map extractDefinitions(Object thing) { - return traverseExtract(thing, false, ""); + return traverseExtract(thing, false); } - private Map traverseExtract(Object thing, boolean asValues, String keyPath) { + private Map traverseExtract(Object thing, boolean asValues) { if (thing == null) { return ImmutableMap.of(); } @@ -69,26 +69,22 @@ private Map traverseExtract(Object thing, boolean asValues, Stri Map asMap = (Map) thing; return asMap.keySet().stream() .collect(Collectors.toMap(key -> key, - key -> traverseExtract(asMap.get(key), asValues, keyPath + "." + key))); + key -> traverseExtract(asMap.get(key), asValues))); } return Arrays.stream(thing.getClass().getFields()) .filter(field -> isNotNull(thing, field)).collect( Collectors.toMap(Field::getName, - field -> extractField(thing, field, asValues, keyPath))); + field -> extractField(thing, field, asValues))); } - private Object extractField(Object thing, Field field, boolean asValue, String keyPath) { + private Object extractField(Object thing, Field field, boolean asValue) { try { Object result = field.get(thing); - String fieldName = field.getName(); - String newPath = keyPath + "." + fieldName; - if (descriptions.containsKey(newPath)) { - return descriptions.get(newPath); - } else if (isBaseType(field) || isBaseType(result)) { + if (isBaseType(field) || isBaseType(result)) { boolean useValue = asValue || !SemanticValue.isSemanticValue(result); return useValue ? SemanticValue.getValue(result) : SemanticValue.getDescription(result); } else { - return traverseExtract(result, asValue, newPath); + return traverseExtract(result, asValue); } } catch (Exception e) { throw new RuntimeException("While converting field " + field.getName(), e); From e075c58b4f89c58c6a638ea69afba9350a650675 Mon Sep 17 00:00:00 2001 From: Trevor Pering Date: Mon, 16 Oct 2023 10:23:06 -0700 Subject: [PATCH 6/9] Fix path generator --- .../main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java b/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java index a925c54617..c881045b37 100644 --- a/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java +++ b/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java @@ -141,7 +141,8 @@ void accumulateDifference(String prefix, Map left, Map Date: Mon, 16 Oct 2023 11:20:18 -0700 Subject: [PATCH 7/9] Add value mapping --- .../daq/mqtt/sequencer/SequenceBase.java | 5 ++-- .../sequences/PointsetSequences.java | 4 +-- .../daq/mqtt/util/ObjectDiffEngine.java | 27 +++++++++++++------ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/validator/src/main/java/com/google/daq/mqtt/sequencer/SequenceBase.java b/validator/src/main/java/com/google/daq/mqtt/sequencer/SequenceBase.java index b8e03743c6..7094e8bd1e 100644 --- a/validator/src/main/java/com/google/daq/mqtt/sequencer/SequenceBase.java +++ b/validator/src/main/java/com/google/daq/mqtt/sequencer/SequenceBase.java @@ -1865,8 +1865,9 @@ protected T ifCatchNullSkipTest(Supplier evaluator, String reason) { return ifNullSkipTest(evaluatorResult, reason); } - protected void mapSemanticKey(String keyPath, String keyName, String description) { - SENT_CONFIG_DIFFERNATOR.mapSemanticKey(keyPath, keyName, description); + protected void mapSemanticKey(String keyPath, String keyName, String description, + String describedValue) { + SENT_CONFIG_DIFFERNATOR.mapSemanticKey(keyPath, keyName, description, describedValue); } /** diff --git a/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java b/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java index 52c4c94d4f..00a3285b3b 100644 --- a/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java +++ b/validator/src/main/java/com/google/daq/mqtt/sequencer/sequences/PointsetSequences.java @@ -69,7 +69,7 @@ private boolean validPointEntry(Entry point) { public void pointset_request_extraneous() { untilPointsetSanity(); - mapSemanticKey(POINTS_MAP_PATH, EXTRANEOUS_POINT, "extraneous_point"); + mapSemanticKey(POINTS_MAP_PATH, EXTRANEOUS_POINT, "extraneous_point", "point configuration"); deviceConfig.pointset.points.put(EXTRANEOUS_POINT, new PointPointsetConfig()); @@ -100,7 +100,7 @@ public void pointset_remove_point() { String name = candidatePoints.get((int) Math.floor(Math.random() * candidatePoints.size())); debug("Removing randomly selected test point " + name); - mapSemanticKey(POINTS_MAP_PATH, name, "random_point"); + mapSemanticKey(POINTS_MAP_PATH, name, "random_point", "point configuration"); PointPointsetConfig removed = requireNonNull(deviceConfig.pointset.points.remove(name)); try { diff --git a/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java b/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java index c881045b37..0f2af26b84 100644 --- a/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java +++ b/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java @@ -21,6 +21,7 @@ public class ObjectDiffEngine { private Map previous; private final Map descriptions = new HashMap<>(); + private final Map describedValues = new HashMap<>(); private boolean ignoreSemantics; public ObjectDiffEngine() { @@ -49,6 +50,7 @@ public List computeChanges(Object updatedObject) { */ public void resetState(Object updatedObject) { descriptions.clear(); + describedValues.clear(); previous = extractDefinitions(updatedObject); } @@ -113,34 +115,40 @@ private boolean isBaseType(Object value) { void accumulateDifference(String prefix, Map left, Map right, List updates) { right.forEach((key, value) -> { - String describedKey = keyDescription(prefix, prefix + key); + String describedKey = describedKey(prefix, key); + String describedValue = describeValue(prefix, key, semanticValue(value)); if (left != null && left.containsKey(key)) { Object leftValue = left.get(key); if (SemanticValue.equals(value, leftValue)) { return; } if (isBaseType(value)) { - updates.add(String.format("Set `%s` = %s", describedKey, semanticValue(value))); + updates.add(String.format("Set `%s` = %s", describedKey, describedValue)); } else { accumulateDifference((prefix + key) + ".", (Map) leftValue, (Map) value, updates); } } else { - updates.add(String.format("Add `%s` = %s", describedKey, semanticValue(value))); + updates.add(String.format("Add `%s` = %s", describedKey, describedValue)); } }); if (left != null) { left.forEach((key, value) -> { if (!right.containsKey(key)) { - String fullKey = prefix + key; - String describedKey = keyDescription(prefix, fullKey); + String describedKey = describedKey(prefix, key); updates.add(String.format("Remove `%s`", describedKey)); } }); } } - private String keyDescription(String prefix, String fullKey) { + private String describeValue(String prefix, String key, String value) { + String fullKey = prefix + key; + return descriptions.containsKey(fullKey) ? describedValues.get(fullKey) : value; + } + + private String describedKey(String prefix, String key) { + String fullKey = prefix + key; String keyPath = prefix.endsWith(".") ? prefix.substring(0, prefix.length() - 1) : prefix; String formattedKey = String.format("%s[%s]", keyPath, descriptions.get(fullKey)); return descriptions.containsKey(fullKey) ? formattedKey : fullKey; @@ -207,8 +215,11 @@ public List diff(Object startObject, Object endObject) { return updates; } - public void mapSemanticKey(String keyPath, String keyName, String description) { - descriptions.put(keyPath + "." + keyName, description); + public void mapSemanticKey(String keyPath, String keyName, String description, + String describedValue) { + String fullKey = keyPath + "." + keyName; + descriptions.put(fullKey, description); + describedValies.put(fullKey, describedValue); } public boolean isInitialized() { From b6648cd8a2140249767dcd6e5b91d48590df27b7 Mon Sep 17 00:00:00 2001 From: Trevor Pering Date: Mon, 16 Oct 2023 12:06:08 -0700 Subject: [PATCH 8/9] FIx typo --- .../main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java b/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java index 0f2af26b84..e741750961 100644 --- a/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java +++ b/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java @@ -219,7 +219,7 @@ public void mapSemanticKey(String keyPath, String keyName, String description, String describedValue) { String fullKey = keyPath + "." + keyName; descriptions.put(fullKey, description); - describedValies.put(fullKey, describedValue); + describedValues.put(fullKey, describedValue); } public boolean isInitialized() { From d43a91fa4cef4557c2f2323e7709670cd0f19719 Mon Sep 17 00:00:00 2001 From: Trevor Pering Date: Mon, 16 Oct 2023 13:45:22 -0700 Subject: [PATCH 9/9] Cleanup javadoc --- .../com/google/daq/mqtt/util/ObjectDiffEngine.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java b/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java index e741750961..13a9aac4f3 100644 --- a/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java +++ b/validator/src/main/java/com/google/daq/mqtt/util/ObjectDiffEngine.java @@ -19,9 +19,9 @@ */ public class ObjectDiffEngine { - private Map previous; private final Map descriptions = new HashMap<>(); private final Map describedValues = new HashMap<>(); + private Map previous; private boolean ignoreSemantics; public ObjectDiffEngine() { @@ -215,6 +215,14 @@ public List diff(Object startObject, Object endObject) { return updates; } + /** + * Set up a semantic mapping for a key/value pair. + * + * @param keyPath path to container + * @param keyName key name + * @param description semantic description of key + * @param describedValue semantic description of value + */ public void mapSemanticKey(String keyPath, String keyName, String description, String describedValue) { String fullKey = keyPath + "." + keyName;