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 <[email protected]>
(cherry picked from commit fe6b307)
  • Loading branch information
PeterSuna authored and ihrasko committed Mar 21, 2024
1 parent d67a8e6 commit 98e6317
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.opendaylight.yangtools.yang.common.Decimal64;
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 +30,26 @@ 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) {
if (numberValue instanceof Decimal64) {
innerJson.add(key.getKey().getLocalName(), gson.toJsonTree(numberValue.doubleValue()));
} else {
innerJson.add(key.getKey().getLocalName(), gson.toJsonTree(numberValue.longValue()));
}
// 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 @@ -221,7 +221,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 @@ -105,7 +105,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 98e6317

Please sign in to comment.