Skip to content

Commit

Permalink
Set correct Json value in gNMI simulator
Browse files Browse the repository at this point in the history
Utilizing Gson to convert key values from
NodeIdentifierWithPredicates may produce unexpected outcomes
if the key value is not parsable by Gson's default behavior.
For instance, the result for Uint8(10) would be {"value":10}
instead of simply 10.

Ensure custom ODL types are correctly parsed by Gson.

JIRA: LIGHTY-285
Signed-off-by: Peter Suna <peter.suna@pantheon.tech>
  • Loading branch information
PeterSuna committed Feb 15, 2024
1 parent ae0539e commit 7010d05
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.Set;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;

public final class JsonUtils {

Expand All @@ -28,10 +29,29 @@ private JsonUtils() {
}

public static String wrapJsonWithArray(final String jsonString, final String wrapper, final Gson gson,
final NodeIdentifierWithPredicates predicates) {
final NodeIdentifierWithPredicates predicates, final EffectiveModelContext context) {
final JsonObject innerJson = JsonParser.parseString(jsonString).getAsJsonObject();
for (final Entry<QName, Object> key : predicates.entrySet()) {
innerJson.add(key.getKey().getLocalName(), gson.toJsonTree(key.getValue()));
final var keyValue = key.getValue();
// InstanceIdentifier for identityref is stored as a QName, value should be in format MODULE:IDENTITY_NAME.
if (keyValue instanceof QName qnameValue) {
final var module = context.findModule(qnameValue.getModule()).orElseThrow();
final var value = String.format("%s:%s", module.getName(), qnameValue.getLocalName());
innerJson.add(key.getKey().getLocalName(), gson.toJsonTree(value));
// Custom ODL Number types are not correctly parsed by Gson.
} else if (keyValue instanceof Number numberValue) {
final var longValue = numberValue.longValue();
final var doubleValue = numberValue.doubleValue();
// If this is not equal, Number contains decimal numbers.
if (longValue == doubleValue) {
innerJson.add(key.getKey().getLocalName(), gson.toJsonTree(longValue));
} else {
innerJson.add(key.getKey().getLocalName(), gson.toJsonTree(doubleValue));
}
// Other parse-able types.
} else {
innerJson.add(key.getKey().getLocalName(), gson.toJsonTree(keyValue));
}
}

final JsonObject result = new JsonObject();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ private Gnmi.UpdateResult processUpdateListNonSimpleValue(final Gnmi.Update upda
String.format("%s:%s",
module.getName(),
Iterables.getLast(identifier.getPathArguments()).getNodeType().getLocalName()), gson,
lastPathArgument);
lastPathArgument, context);
node = DataConverter.nodeFromJsonString(identifier, json, context);
// In case of list entry, point to the list itself
resultingIdentifier = identifier.getParent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ private NormalizedNode updateToNormalizedNode(final Update update, final YangIns
if (identifier.getLastPathArgument() instanceof NodeIdentifierWithPredicates) {
final NodeIdentifierWithPredicates lastPathArgument
= (NodeIdentifierWithPredicates) identifier.getLastPathArgument();
responseJson = JsonUtils.wrapJsonWithArray(responseJson, wrapWith, gson, lastPathArgument);
responseJson = JsonUtils.wrapJsonWithArray(responseJson, wrapWith, gson, lastPathArgument,
schemaContextProvider.getSchemaContext());
} else {
responseJson = JsonUtils.wrapJsonWithObject(responseJson, wrapWith, gson);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,39 @@ public void setContainerWithMultipleListKeyInPathTest() throws Exception {
assertEquals("UPDATE", setResponse.getResponse(1).getOp().toString());
}

@Test
public void setMultipleKeyListAsLastElementInPathTest() throws Exception {
final var multipleKeyPath = Gnmi.Path.newBuilder()
.addElem(Gnmi.PathElem.newBuilder()
.setName("gnmi-test-model:test-data")
.build())
.addElem(Gnmi.PathElem.newBuilder()
.setName("multiple-key-list")
.putKey("number", "10")
.putKey("leafref-key", "15")
.putKey("identityref-key", "openconfig-aaa-types:SYSTEM_DEFINED_ROLES")
.putKey("union-key", "5")
.build())
.build();
final var innerContainerUpdate = Gnmi.Update.newBuilder()
.setPath(multipleKeyPath)
.setVal(Gnmi.TypedValue.newBuilder()
.setJsonIetfVal(ByteString.copyFromUtf8("""
{
"inner-container": {
"inner-data": "data"
}
}
"""))
.build())
.build();
final var setRequest = Gnmi.SetRequest.newBuilder().addUpdate(innerContainerUpdate).build();
LOG.info("Sending set request:\n{}", setRequest);

final var setResponse = sessionProvider.getGnmiSession().set(setRequest).get();
assertEquals("UPDATE", setResponse.getResponse(0).getOp().toString());
}

@Test
public void crudComplexValueTest() throws ExecutionException, InterruptedException, IOException, JSONException {
final Gnmi.Path path = Gnmi.Path.newBuilder()
Expand Down

0 comments on commit 7010d05

Please sign in to comment.